summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-15 09:09:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-15 09:09:46 +0000
commit221b529789f4090341a825695aeb49b8df6dd11d (patch)
treec8843e4ca5ef1034752eb68712fcf338b24950db /spec
parent00a8c64ffd18e74df4b1cdeda7776b5221fddafe (diff)
downloadgitlab-ce-221b529789f4090341a825695aeb49b8df6dd11d.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/groups/registry/repositories_controller_spec.rb119
-rw-r--r--spec/controllers/projects/static_site_editor_controller_spec.rb16
-rw-r--r--spec/frontend/static_site_editor/components/edit_header_spec.js38
-rw-r--r--spec/frontend/static_site_editor/components/publish_toolbar_spec.js14
-rw-r--r--spec/frontend/static_site_editor/components/static_site_editor_spec.js21
-rw-r--r--spec/frontend/static_site_editor/mock_data.js2
-rw-r--r--spec/lib/container_registry/client_spec.rb67
-rw-r--r--spec/lib/gitlab/static_site_editor/config_spec.rb35
-rw-r--r--spec/requests/api/users_spec.rb12
-rw-r--r--spec/support/shared_examples/requests/response_status_shared_examples.rb9
-rw-r--r--spec/uploaders/object_storage_spec.rb24
11 files changed, 277 insertions, 80 deletions
diff --git a/spec/controllers/groups/registry/repositories_controller_spec.rb b/spec/controllers/groups/registry/repositories_controller_spec.rb
index eadc3a7f739..a84664c6c04 100644
--- a/spec/controllers/groups/registry/repositories_controller_spec.rb
+++ b/spec/controllers/groups/registry/repositories_controller_spec.rb
@@ -7,6 +7,13 @@ describe Groups::Registry::RepositoriesController do
let_it_be(:guest) { create(:user) }
let_it_be(:group, reload: true) { create(:group) }
+ subject do
+ get :index, params: {
+ group_id: group,
+ format: format
+ }
+ end
+
before do
stub_container_registry_config(enabled: true)
group.add_owner(user)
@@ -15,51 +22,67 @@ describe Groups::Registry::RepositoriesController do
end
shared_examples 'renders a list of repositories' do
+ let_it_be(:repo) { create_project_with_repo(test_group) }
+
+ it 'returns a list of projects for json format' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.first).to include(
+ 'id' => repo.id,
+ 'name' => repo.name
+ )
+ end
+ end
+
+ shared_examples 'renders correctly' do
context 'when user has access to registry' do
- it 'show index page' do
- expect(Gitlab::Tracking).not_to receive(:event)
+ let_it_be(:test_group) { group }
- get :index, params: {
- group_id: group
- }
+ context 'html format' do
+ let(:format) { :html }
- expect(response).to have_gitlab_http_status(:ok)
- end
+ it 'show index page' do
+ expect(Gitlab::Tracking).not_to receive(:event)
- it 'has the correct response schema' do
- get :index, params: {
- group_id: group,
- format: :json
- }
+ subject
- expect(response).to match_response_schema('registry/repositories')
- expect(response).to include_pagination_headers
+ expect(response).to have_gitlab_http_status(:ok)
+ end
end
- it 'returns a list of projects for json format' do
- project = create(:project, group: group)
- repo = create(:container_repository, project: project)
-
- get :index, params: {
- group_id: group,
- format: :json
- }
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response).to be_kind_of(Array)
- expect(json_response.first).to include(
- 'id' => repo.id,
- 'name' => repo.name
- )
- end
+ context 'json format' do
+ let(:format) { :json }
+
+ it 'has the correct response schema' do
+ subject
+
+ expect(response).to match_response_schema('registry/repositories')
+ expect(response).to include_pagination_headers
+ end
- it 'tracks the event' do
- expect(Gitlab::Tracking).to receive(:event).with(anything, 'list_repositories', {})
+ it_behaves_like 'renders a list of repositories'
- get :index, params: {
- group_id: group,
- format: :json
- }
+ it_behaves_like 'a gitlab tracking event', described_class.name, 'list_repositories'
+
+ context 'with project in subgroup' do
+ let_it_be(:test_group) { create(:group, parent: group ) }
+
+ it_behaves_like 'renders a list of repositories'
+
+ context 'with project in subgroup and group' do
+ let_it_be(:repo_in_test_group) { create_project_with_repo(test_group) }
+ let_it_be(:repo_in_group) { create_project_with_repo(group) }
+
+ it 'returns all the projects' do
+ subject
+
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.length).to eq 2
+ end
+ end
+ end
end
end
@@ -69,20 +92,30 @@ describe Groups::Registry::RepositoriesController do
sign_in(guest)
end
- it 'renders not found' do
- get :index, params: {
- group_id: group
- }
- expect(response).to have_gitlab_http_status(:not_found)
+ context 'json format' do
+ let(:format) { :json }
+
+ it_behaves_like 'returning response status', :not_found
+ end
+
+ context 'html format' do
+ let(:format) { :html }
+
+ it_behaves_like 'returning response status', :not_found
end
end
end
context 'GET #index' do
- it_behaves_like 'renders a list of repositories'
+ it_behaves_like 'renders correctly'
end
context 'GET #show' do
- it_behaves_like 'renders a list of repositories'
+ it_behaves_like 'renders correctly'
+ end
+
+ def create_project_with_repo(group)
+ project = create(:project, group: test_group)
+ create(:container_repository, project: project)
end
end
diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb
index d1224bb75c0..f7c8848b8cf 100644
--- a/spec/controllers/projects/static_site_editor_controller_spec.rb
+++ b/spec/controllers/projects/static_site_editor_controller_spec.rb
@@ -26,7 +26,21 @@ describe Projects::StaticSiteEditorController do
end
end
- %w[guest developer maintainer].each do |role|
+ context 'as guest' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_guest(user)
+ sign_in(user)
+ get :show, params: default_params
+ end
+
+ it 'responds with 404 page' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ %w[developer maintainer].each do |role|
context "as #{role}" do
let(:user) { create(:user) }
diff --git a/spec/frontend/static_site_editor/components/edit_header_spec.js b/spec/frontend/static_site_editor/components/edit_header_spec.js
new file mode 100644
index 00000000000..2b0fe226a0b
--- /dev/null
+++ b/spec/frontend/static_site_editor/components/edit_header_spec.js
@@ -0,0 +1,38 @@
+import { shallowMount } from '@vue/test-utils';
+
+import EditHeader from '~/static_site_editor/components/edit_header.vue';
+import { DEFAULT_HEADING } from '~/static_site_editor/constants';
+
+import { sourceContentTitle } from '../mock_data';
+
+describe('~/static_site_editor/components/edit_header.vue', () => {
+ let wrapper;
+
+ const buildWrapper = (propsData = {}) => {
+ wrapper = shallowMount(EditHeader, {
+ propsData: {
+ ...propsData,
+ },
+ });
+ };
+
+ const findHeading = () => wrapper.find({ ref: 'sseHeading' });
+
+ beforeEach(() => {
+ buildWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the default heading if there is no title prop', () => {
+ expect(findHeading().text()).toBe(DEFAULT_HEADING);
+ });
+
+ it('renders the title prop value in the heading', () => {
+ buildWrapper({ title: sourceContentTitle });
+
+ expect(findHeading().text()).toBe(sourceContentTitle);
+ });
+});
diff --git a/spec/frontend/static_site_editor/components/publish_toolbar_spec.js b/spec/frontend/static_site_editor/components/publish_toolbar_spec.js
index 0edc3f4c920..f00fc38430f 100644
--- a/spec/frontend/static_site_editor/components/publish_toolbar_spec.js
+++ b/spec/frontend/static_site_editor/components/publish_toolbar_spec.js
@@ -3,6 +3,8 @@ import { GlNewButton, GlLoadingIcon } from '@gitlab/ui';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
+import { returnUrl } from '../mock_data';
+
describe('Static Site Editor Toolbar', () => {
let wrapper;
@@ -15,6 +17,7 @@ describe('Static Site Editor Toolbar', () => {
});
};
+ const findReturnUrlLink = () => wrapper.find({ ref: 'returnUrlLink' });
const findSaveChangesButton = () => wrapper.find(GlNewButton);
const findLoadingIndicator = () => wrapper.find(GlLoadingIcon);
@@ -38,6 +41,17 @@ describe('Static Site Editor Toolbar', () => {
expect(findLoadingIndicator().classes()).toContain('invisible');
});
+ it('does not render returnUrl link', () => {
+ expect(findReturnUrlLink().exists()).toBe(false);
+ });
+
+ it('renders returnUrl link when returnUrl prop exists', () => {
+ buildWrapper({ returnUrl });
+
+ expect(findReturnUrlLink().exists()).toBe(true);
+ expect(findReturnUrlLink().attributes('href')).toBe(returnUrl);
+ });
+
describe('when saveable', () => {
it('enables Submit Changes button', () => {
buildWrapper({ saveable: true });
diff --git a/spec/frontend/static_site_editor/components/static_site_editor_spec.js b/spec/frontend/static_site_editor/components/static_site_editor_spec.js
index 2c4fa0e061a..d427df9bd4b 100644
--- a/spec/frontend/static_site_editor/components/static_site_editor_spec.js
+++ b/spec/frontend/static_site_editor/components/static_site_editor_spec.js
@@ -7,9 +7,10 @@ import createState from '~/static_site_editor/store/state';
import StaticSiteEditor from '~/static_site_editor/components/static_site_editor.vue';
import EditArea from '~/static_site_editor/components/edit_area.vue';
+import EditHeader from '~/static_site_editor/components/edit_header.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
-import { sourceContent } from '../mock_data';
+import { sourceContent, sourceContentTitle } from '../mock_data';
const localVue = createLocalVue();
@@ -60,6 +61,7 @@ describe('StaticSiteEditor', () => {
};
const findEditArea = () => wrapper.find(EditArea);
+ const findEditHeader = () => wrapper.find(EditHeader);
const findPublishToolbar = () => wrapper.find(PublishToolbar);
const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
@@ -77,16 +79,21 @@ describe('StaticSiteEditor', () => {
expect(findEditArea().exists()).toBe(false);
});
+ it('does not render edit header', () => {
+ expect(findEditHeader().exists()).toBe(false);
+ });
+
it('does not render toolbar', () => {
expect(findPublishToolbar().exists()).toBe(false);
});
});
describe('when content is loaded', () => {
- const content = 'edit area content';
+ const content = sourceContent;
+ const title = sourceContentTitle;
beforeEach(() => {
- buildContentLoadedStore({ initialState: { content } });
+ buildContentLoadedStore({ initialState: { content, title } });
buildWrapper();
});
@@ -94,6 +101,10 @@ describe('StaticSiteEditor', () => {
expect(findEditArea().exists()).toBe(true);
});
+ it('renders the edit header', () => {
+ expect(findEditHeader().exists()).toBe(true);
+ });
+
it('does not render skeleton loader', () => {
expect(findSkeletonLoader().exists()).toBe(false);
});
@@ -102,6 +113,10 @@ describe('StaticSiteEditor', () => {
expect(findEditArea().props('value')).toBe(content);
});
+ it('passes page title to edit header', () => {
+ expect(findEditHeader().props('title')).toBe(title);
+ });
+
it('renders toolbar', () => {
expect(findPublishToolbar().exists()).toBe(true);
});
diff --git a/spec/frontend/static_site_editor/mock_data.js b/spec/frontend/static_site_editor/mock_data.js
index 1993636ab12..345ae0ce6f6 100644
--- a/spec/frontend/static_site_editor/mock_data.js
+++ b/spec/frontend/static_site_editor/mock_data.js
@@ -11,11 +11,11 @@ twitter_image: '/images/tweets/handbook-gitlab.png'
- TOC
{:toc .hidden-md .hidden-lg}
`;
-
export const sourceContentTitle = 'Handbook';
export const username = 'gitlabuser';
export const projectId = '123456';
+export const returnUrl = 'https://www.gitlab.com';
export const sourcePath = 'foobar.md.html';
export const savedContentMeta = {
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index 5d2334a6d8f..0aad6568793 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -6,6 +6,21 @@ describe ContainerRegistry::Client do
let(:token) { '12345' }
let(:options) { { token: token } }
let(:client) { described_class.new("http://container-registry", options) }
+ let(:push_blob_headers) do
+ {
+ 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json',
+ 'Authorization' => "bearer #{token}",
+ 'Content-Type' => 'application/octet-stream',
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}"
+ }
+ end
+ let(:headers_with_accept_types) do
+ {
+ 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json',
+ 'Authorization' => "bearer #{token}",
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}"
+ }
+ end
shared_examples '#repository_manifest' do |manifest_type|
let(:manifest) do
@@ -25,14 +40,15 @@ describe ContainerRegistry::Client do
"size" => 2828661
}
]
- }
+ }
end
it 'GET /v2/:name/manifests/mytag' do
stub_request(:get, "http://container-registry/v2/group/test/manifests/mytag")
.with(headers: {
- 'Accept' => described_class::ACCEPTED_TYPES.join(', '),
- 'Authorization' => "bearer #{token}"
+ 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json',
+ 'Authorization' => "bearer #{token}",
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}"
})
.to_return(status: 200, body: manifest.to_json, headers: { content_type: manifest_type })
@@ -44,12 +60,23 @@ describe ContainerRegistry::Client do
it_behaves_like '#repository_manifest', described_class::OCI_MANIFEST_V1_TYPE
describe '#blob' do
+ let(:blob_headers) do
+ {
+ 'Accept' => 'application/octet-stream',
+ 'Authorization' => "bearer #{token}",
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}"
+ }
+ end
+
+ let(:redirect_header) do
+ {
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}"
+ }
+ end
+
it 'GET /v2/:name/blobs/:digest' do
stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345")
- .with(headers: {
- 'Accept' => 'application/octet-stream',
- 'Authorization' => "bearer #{token}"
- })
+ .with(headers: blob_headers)
.to_return(status: 200, body: "Blob")
expect(client.blob('group/test', 'sha256:0123456789012345')).to eq('Blob')
@@ -57,15 +84,14 @@ describe ContainerRegistry::Client do
it 'follows 307 redirect for GET /v2/:name/blobs/:digest' do
stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345")
- .with(headers: {
- 'Accept' => 'application/octet-stream',
- 'Authorization' => "bearer #{token}"
- })
+ .with(headers: blob_headers)
.to_return(status: 307, body: "", headers: { Location: 'http://redirected' })
# We should probably use hash_excluding here, but that requires an update to WebMock:
# https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb
stub_request(:get, "http://redirected/")
- .with { |request| !request.headers.include?('Authorization') }
+ .with(headers: redirect_header) do |request|
+ !request.headers.include?('Authorization')
+ end
.to_return(status: 200, body: "Successfully redirected")
response = client.blob('group/test', 'sha256:0123456789012345')
@@ -76,10 +102,11 @@ describe ContainerRegistry::Client do
def stub_upload(path, content, digest, status = 200)
stub_request(:post, "http://container-registry/v2/#{path}/blobs/uploads/")
+ .with(headers: headers_with_accept_types)
.to_return(status: status, body: "", headers: { 'location' => 'http://container-registry/next_upload?id=someid' })
stub_request(:put, "http://container-registry/next_upload?digest=#{digest}&id=someid")
- .with(body: content)
+ .with(body: content, headers: push_blob_headers)
.to_return(status: status, body: "", headers: {})
end
@@ -136,11 +163,20 @@ describe ContainerRegistry::Client do
end
describe '#put_tag' do
+ let(:manifest_headers) do
+ {
+ 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json',
+ 'Authorization' => "bearer #{token}",
+ 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json',
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}"
+ }
+ end
+
subject { client.put_tag('path', 'tagA', { foo: :bar }) }
it 'uploads the manifest and returns the digest' do
stub_request(:put, "http://container-registry/v2/path/manifests/tagA")
- .with(body: "{\n \"foo\": \"bar\"\n}")
+ .with(body: "{\n \"foo\": \"bar\"\n}", headers: manifest_headers)
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:123' })
expect(subject).to eq 'sha256:123'
@@ -153,6 +189,7 @@ describe ContainerRegistry::Client do
context 'when the tag exists' do
before do
stub_request(:delete, "http://container-registry/v2/group/test/tags/reference/a")
+ .with(headers: headers_with_accept_types)
.to_return(status: 200, body: "")
end
@@ -162,6 +199,7 @@ describe ContainerRegistry::Client do
context 'when the tag does not exist' do
before do
stub_request(:delete, "http://container-registry/v2/group/test/tags/reference/a")
+ .with(headers: headers_with_accept_types)
.to_return(status: 404, body: "")
end
@@ -171,6 +209,7 @@ describe ContainerRegistry::Client do
context 'when an error occurs' do
before do
stub_request(:delete, "http://container-registry/v2/group/test/tags/reference/a")
+ .with(headers: headers_with_accept_types)
.to_return(status: 500, body: "")
end
diff --git a/spec/lib/gitlab/static_site_editor/config_spec.rb b/spec/lib/gitlab/static_site_editor/config_spec.rb
index dea79fb0e92..8f61476722d 100644
--- a/spec/lib/gitlab/static_site_editor/config_spec.rb
+++ b/spec/lib/gitlab/static_site_editor/config_spec.rb
@@ -18,13 +18,44 @@ describe Gitlab::StaticSiteEditor::Config do
it 'returns data for the frontend component' do
is_expected.to eq(
branch: 'master',
- commit: repository.commit.id,
+ commit_id: repository.commit.id,
namespace: 'namespace',
path: 'README.md',
project: 'project',
project_id: project.id,
- return_url: 'http://example.com'
+ return_url: 'http://example.com',
+ is_supported_content: true
)
end
+
+ context 'when branch is not master' do
+ let(:ref) { 'my-branch' }
+
+ it { is_expected.to include(is_supported_content: false) }
+ end
+
+ context 'when file does not have a markdown extension' do
+ let(:file_path) { 'README.txt' }
+
+ it { is_expected.to include(is_supported_content: false) }
+ end
+
+ context 'when file does not have an extension' do
+ let(:file_path) { 'README' }
+
+ it { is_expected.to include(is_supported_content: false) }
+ end
+
+ context 'when file does not exist' do
+ let(:file_path) { 'UNKNOWN.md' }
+
+ it { is_expected.to include(is_supported_content: false) }
+ end
+
+ context 'when repository is empty' do
+ let(:project) { create(:project_empty_repo) }
+
+ it { is_expected.to include(is_supported_content: false) }
+ end
end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index ee0f7545adc..864f6f77f39 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -280,6 +280,18 @@ describe API::Users, :do_not_mock_admin_mode do
expect(json_response.first['id']).to eq(user_with_2fa.id)
end
+ it "returns users without projects" do
+ user_without_projects = create(:user)
+ create(:project, namespace: user.namespace)
+ create(:project, namespace: admin.namespace)
+
+ get api('/users', admin), params: { without_projects: true }
+
+ expect(response).to match_response_schema('public_api/v4/user/admins')
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['id']).to eq(user_without_projects.id)
+ end
+
it 'returns 400 when provided incorrect sort params' do
get api('/users', admin), params: { order_by: 'magic', sort: 'asc' }
diff --git a/spec/support/shared_examples/requests/response_status_shared_examples.rb b/spec/support/shared_examples/requests/response_status_shared_examples.rb
new file mode 100644
index 00000000000..6c450881efe
--- /dev/null
+++ b/spec/support/shared_examples/requests/response_status_shared_examples.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'returning response status' do |status|
+ it "returns #{status}" do
+ subject
+
+ expect(response).to have_gitlab_http_status(status)
+ end
+end
diff --git a/spec/uploaders/object_storage_spec.rb b/spec/uploaders/object_storage_spec.rb
index e844b0ad799..f42d581ece4 100644
--- a/spec/uploaders/object_storage_spec.rb
+++ b/spec/uploaders/object_storage_spec.rb
@@ -597,22 +597,6 @@ describe ObjectStorage do
end
context 'when local file is used' do
- context 'when valid file is used' do
- let(:uploaded_file) do
- fixture_file_upload('spec/fixtures/rails_sample.jpg', 'image/jpg')
- end
-
- it "properly caches the file" do
- subject
-
- expect(uploader).to be_exists
- expect(uploader.path).to start_with(uploader_class.root)
- expect(uploader.filename).to eq('rails_sample.jpg')
- end
- end
- end
-
- context 'when local file is used' do
let(:temp_file) { Tempfile.new("test") }
before do
@@ -627,6 +611,14 @@ describe ObjectStorage do
context 'when valid file is specified' do
let(:uploaded_file) { temp_file }
+ it 'properly caches the file' do
+ subject
+
+ expect(uploader).to be_exists
+ expect(uploader.path).to start_with(uploader_class.root)
+ expect(uploader.filename).to eq(File.basename(uploaded_file.path))
+ end
+
context 'when object storage and direct upload is specified' do
before do
stub_uploads_object_storage(uploader_class, enabled: true, direct_upload: true)