From d7a028e20d29b8c6d0e780ac168544dfbb712d3c Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 31 Mar 2020 15:07:53 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- spec/fixtures/api/schemas/entities/discussion.json | 2 +- .../registry/explorer/pages/details_spec.js | 62 +++++++- .../ci/pipeline/chain/config/content_spec.rb | 140 ----------------- spec/models/ci/build_dependencies_spec.rb | 173 +++++++++++++++++++++ spec/models/ci/processable/dependencies_spec.rb | 173 --------------------- .../graphql/mutations/jira_import/start_spec.rb | 130 ++++++++++++++++ spec/requests/api/project_clusters_spec.rb | 80 ++++------ spec/support/helpers/stub_gitlab_calls.rb | 8 +- 8 files changed, 394 insertions(+), 374 deletions(-) create mode 100644 spec/models/ci/build_dependencies_spec.rb delete mode 100644 spec/models/ci/processable/dependencies_spec.rb create mode 100644 spec/requests/api/graphql/mutations/jira_import/start_spec.rb (limited to 'spec') diff --git a/spec/fixtures/api/schemas/entities/discussion.json b/spec/fixtures/api/schemas/entities/discussion.json index 92863d2e084..9d7ca62435e 100644 --- a/spec/fixtures/api/schemas/entities/discussion.json +++ b/spec/fixtures/api/schemas/entities/discussion.json @@ -36,7 +36,7 @@ "updated_at": { "type": "date" }, "system": { "type": "boolean" }, "noteable_id": { "type": "integer" }, - "noteable_iid": { "type": "integer" }, + "noteable_iid": { "type": ["integer", "null"] }, "noteable_type": { "type": "string" }, "resolved": { "type": "boolean" }, "resolvable": { "type": "boolean" }, diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js index 60e509e4a88..15aa5008413 100644 --- a/spec/frontend/registry/explorer/pages/details_spec.js +++ b/spec/frontend/registry/explorer/pages/details_spec.js @@ -29,10 +29,11 @@ describe('Details Page', () => { const findAllDeleteButtons = () => wrapper.findAll('.js-delete-registry'); const findAllCheckboxes = () => wrapper.findAll('.js-row-checkbox'); const findCheckedCheckboxes = () => findAllCheckboxes().filter(c => c.attributes('checked')); + const findFirsTagColumn = () => wrapper.find('.js-tag-column'); const routeId = window.btoa(JSON.stringify({ name: 'foo', tags_path: 'bar' })); - beforeEach(() => { + const mountComponent = options => { wrapper = mount(component, { store, stubs: { @@ -49,7 +50,11 @@ describe('Details Page', () => { }, $toast, }, + ...options, }); + }; + + beforeEach(() => { dispatchSpy = jest.spyOn(store, 'dispatch'); store.dispatch('receiveTagsListSuccess', tagsListResponse); jest.spyOn(Tracking, 'event'); @@ -61,6 +66,7 @@ describe('Details Page', () => { describe('when isLoading is true', () => { beforeEach(() => { + mountComponent(); store.dispatch('receiveTagsListSuccess', { ...tagsListResponse, data: [] }); store.commit(SET_MAIN_LOADING, true); }); @@ -81,6 +87,10 @@ describe('Details Page', () => { }); describe('table', () => { + beforeEach(() => { + mountComponent(); + }); + it.each([ 'rowCheckbox', 'rowName', @@ -93,6 +103,10 @@ describe('Details Page', () => { }); describe('header checkbox', () => { + beforeEach(() => { + mountComponent(); + }); + it('exists', () => { expect(findMainCheckbox().exists()).toBe(true); }); @@ -116,6 +130,10 @@ describe('Details Page', () => { }); describe('row checkbox', () => { + beforeEach(() => { + mountComponent(); + }); + it('if selected adds item to selectedItems', () => { findFirstRowItem('rowCheckbox').vm.$emit('change'); return wrapper.vm.$nextTick().then(() => { @@ -135,6 +153,10 @@ describe('Details Page', () => { }); describe('header delete button', () => { + beforeEach(() => { + mountComponent(); + }); + it('exists', () => { expect(findBulkDeleteButton().exists()).toBe(true); }); @@ -182,6 +204,10 @@ describe('Details Page', () => { }); describe('row delete button', () => { + beforeEach(() => { + mountComponent(); + }); + it('exists', () => { expect( findAllDeleteButtons() @@ -213,9 +239,39 @@ describe('Details Page', () => { }); }); }); + + describe('tag cell', () => { + describe('on desktop viewport', () => { + beforeEach(() => { + mountComponent(); + }); + + it('has class w-25', () => { + expect(findFirsTagColumn().classes()).toContain('w-25'); + }); + }); + + describe('on mobile viewport', () => { + beforeEach(() => { + mountComponent({ + data() { + return { isDesktop: false }; + }, + }); + }); + + it('does not has class w-25', () => { + expect(findFirsTagColumn().classes()).not.toContain('w-25'); + }); + }); + }); }); describe('pagination', () => { + beforeEach(() => { + mountComponent(); + }); + it('exists', () => { expect(findPagination().exists()).toBe(true); }); @@ -238,6 +294,10 @@ describe('Details Page', () => { }); describe('modal', () => { + beforeEach(() => { + mountComponent(); + }); + it('exists', () => { expect(findDeleteModal().exists()).toBe(true); }); diff --git a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb index b5f0783cb42..fc95bb602c2 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb @@ -10,146 +10,6 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do subject { described_class.new(pipeline, command) } describe '#perform!' do - context 'when feature flag is disabled' do - before do - stub_feature_flags(ci_root_config_content: false) - end - - context 'when bridge job is passed in as parameter' do - let(:ci_config_path) { nil } - let(:bridge) { create(:ci_bridge) } - - before do - command.bridge = bridge - end - - context 'when bridge job has downstream yaml' do - before do - allow(bridge).to receive(:yaml_for_downstream).and_return('the-yaml') - end - - it 'returns the content already available in command' do - subject.perform! - - expect(pipeline.config_source).to eq 'bridge_source' - expect(command.config_content).to eq 'the-yaml' - end - end - - context 'when bridge job does not have downstream yaml' do - before do - allow(bridge).to receive(:yaml_for_downstream).and_return(nil) - end - - it 'returns the next available source' do - subject.perform! - - expect(pipeline.config_source).to eq 'auto_devops_source' - template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps') - expect(command.config_content).to eq(template.content) - end - end - end - - context 'when config is defined in a custom path in the repository' do - let(:ci_config_path) { 'path/to/config.yml' } - - before do - expect(project.repository) - .to receive(:gitlab_ci_yml_for) - .with(pipeline.sha, ci_config_path) - .and_return('the-content') - end - - it 'returns the content of the YAML file' do - subject.perform! - - expect(pipeline.config_source).to eq 'repository_source' - expect(pipeline.pipeline_config).to be_nil - expect(command.config_content).to eq('the-content') - end - end - - context 'when config is defined remotely' do - let(:ci_config_path) { 'http://example.com/path/to/ci/config.yml' } - - it 'does not support URLs and default to AutoDevops' do - subject.perform! - - expect(pipeline.config_source).to eq 'auto_devops_source' - expect(pipeline.pipeline_config).to be_nil - template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps') - expect(command.config_content).to eq(template.content) - end - end - - context 'when config is defined in a separate repository' do - let(:ci_config_path) { 'path/to/.gitlab-ci.yml@another-group/another-repo' } - - it 'does not support YAML from external repository and default to AutoDevops' do - subject.perform! - - expect(pipeline.config_source).to eq 'auto_devops_source' - expect(pipeline.pipeline_config).to be_nil - template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps') - expect(command.config_content).to eq(template.content) - end - end - - context 'when config is defined in the default .gitlab-ci.yml' do - let(:ci_config_path) { nil } - - before do - expect(project.repository) - .to receive(:gitlab_ci_yml_for) - .with(pipeline.sha, '.gitlab-ci.yml') - .and_return('the-content') - end - - it 'returns the content of the canonical config file' do - subject.perform! - - expect(pipeline.config_source).to eq 'repository_source' - expect(pipeline.pipeline_config).to be_nil - expect(command.config_content).to eq('the-content') - end - end - - context 'when config is the Auto-Devops template' do - let(:ci_config_path) { nil } - - before do - expect(project).to receive(:auto_devops_enabled?).and_return(true) - end - - it 'returns the content of AutoDevops template' do - subject.perform! - - expect(pipeline.config_source).to eq 'auto_devops_source' - expect(pipeline.pipeline_config).to be_nil - template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps') - expect(command.config_content).to eq(template.content) - end - end - - context 'when config is not defined anywhere' do - let(:ci_config_path) { nil } - - before do - expect(project).to receive(:auto_devops_enabled?).and_return(false) - end - - it 'builds root config including the auto-devops template' do - subject.perform! - - expect(pipeline.config_source).to eq('unknown_source') - expect(pipeline.pipeline_config).to be_nil - expect(command.config_content).to be_nil - expect(pipeline.errors.full_messages).to include('Missing CI config file') - end - end - end - context 'when bridge job is passed in as parameter' do let(:ci_config_path) { nil } let(:bridge) { create(:ci_bridge) } diff --git a/spec/models/ci/build_dependencies_spec.rb b/spec/models/ci/build_dependencies_spec.rb new file mode 100644 index 00000000000..6db69d0f34c --- /dev/null +++ b/spec/models/ci/build_dependencies_spec.rb @@ -0,0 +1,173 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::BuildDependencies do + let_it_be(:user) { create(:user) } + let_it_be(:project, reload: true) { create(:project, :repository) } + + let_it_be(:pipeline, reload: true) do + create(:ci_pipeline, project: project, + sha: project.commit.id, + ref: project.default_branch, + status: 'success') + end + + let!(:build) { create(:ci_build, pipeline: pipeline, name: 'build', stage_idx: 0, stage: 'build') } + let!(:rspec_test) { create(:ci_build, pipeline: pipeline, name: 'rspec', stage_idx: 1, stage: 'test') } + let!(:rubocop_test) { create(:ci_build, pipeline: pipeline, name: 'rubocop', stage_idx: 1, stage: 'test') } + let!(:staging) { create(:ci_build, pipeline: pipeline, name: 'staging', stage_idx: 2, stage: 'deploy') } + + describe '#local' do + subject { described_class.new(job).local } + + describe 'jobs from previous stages' do + context 'when job is in the first stage' do + let(:job) { build } + + it { is_expected.to be_empty } + end + + context 'when job is in the second stage' do + let(:job) { rspec_test } + + it 'contains all jobs from the first stage' do + is_expected.to contain_exactly(build) + end + end + + context 'when job is in the last stage' do + let(:job) { staging } + + it 'contains all jobs from all previous stages' do + is_expected.to contain_exactly(build, rspec_test, rubocop_test) + end + + context 'when a job is retried' do + before do + project.add_developer(user) + end + + let(:retried_job) { Ci::Build.retry(rspec_test, user) } + + it 'contains the retried job instead of the original one' do + is_expected.to contain_exactly(build, retried_job, rubocop_test) + end + end + end + end + + describe 'jobs from specified dependencies' do + let(:dependencies) { } + let(:needs) { } + + let!(:job) do + scheduling_type = needs.present? ? :dag : :stage + + create(:ci_build, + pipeline: pipeline, + name: 'final', + scheduling_type: scheduling_type, + stage_idx: 3, + stage: 'deploy', + options: { dependencies: dependencies } + ) + end + + before do + needs.to_a.each do |need| + create(:ci_build_need, build: job, **need) + end + end + + context 'when dependencies are defined' do + let(:dependencies) { %w(rspec staging) } + + it { is_expected.to contain_exactly(rspec_test, staging) } + end + + context 'when needs are defined' do + let(:needs) do + [ + { name: 'build', artifacts: true }, + { name: 'rspec', artifacts: true }, + { name: 'staging', artifacts: true } + ] + end + + it { is_expected.to contain_exactly(build, rspec_test, staging) } + + context 'when ci_dag_support is disabled' do + before do + stub_feature_flags(ci_dag_support: false) + end + + it { is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging) } + end + end + + context 'when need artifacts are defined' do + let(:needs) do + [ + { name: 'build', artifacts: true }, + { name: 'rspec', artifacts: false }, + { name: 'staging', artifacts: true } + ] + end + + it { is_expected.to contain_exactly(build, staging) } + end + + context 'when needs and dependencies are defined' do + let(:dependencies) { %w(rspec staging) } + let(:needs) do + [ + { name: 'build', artifacts: true }, + { name: 'rspec', artifacts: true }, + { name: 'staging', artifacts: true } + ] + end + + it { is_expected.to contain_exactly(rspec_test, staging) } + end + + context 'when needs and dependencies contradict' do + let(:dependencies) { %w(rspec staging) } + let(:needs) do + [ + { name: 'build', artifacts: true }, + { name: 'rspec', artifacts: false }, + { name: 'staging', artifacts: true } + ] + end + + it 'returns only the intersection' do + is_expected.to contain_exactly(staging) + end + end + + context 'when nor dependencies or needs are defined' do + it 'returns the jobs from previous stages' do + is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging) + end + end + end + end + + describe '#all' do + let!(:job) do + create(:ci_build, pipeline: pipeline, name: 'deploy', stage_idx: 3, stage: 'deploy') + end + + let(:dependencies) { described_class.new(job) } + + subject { dependencies.all } + + it 'returns the union of all local dependencies and any cross pipeline dependencies' do + expect(dependencies).to receive(:local).and_return([1, 2, 3]) + expect(dependencies).to receive(:cross_pipeline).and_return([3, 4]) + + expect(subject).to contain_exactly(1, 2, 3, 4) + end + end +end diff --git a/spec/models/ci/processable/dependencies_spec.rb b/spec/models/ci/processable/dependencies_spec.rb deleted file mode 100644 index f115ae51f9c..00000000000 --- a/spec/models/ci/processable/dependencies_spec.rb +++ /dev/null @@ -1,173 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Ci::Processable::Dependencies do - let_it_be(:user) { create(:user) } - let_it_be(:project, reload: true) { create(:project, :repository) } - - let_it_be(:pipeline, reload: true) do - create(:ci_pipeline, project: project, - sha: project.commit.id, - ref: project.default_branch, - status: 'success') - end - - let!(:build) { create(:ci_build, pipeline: pipeline, name: 'build', stage_idx: 0, stage: 'build') } - let!(:rspec_test) { create(:ci_build, pipeline: pipeline, name: 'rspec', stage_idx: 1, stage: 'test') } - let!(:rubocop_test) { create(:ci_build, pipeline: pipeline, name: 'rubocop', stage_idx: 1, stage: 'test') } - let!(:staging) { create(:ci_build, pipeline: pipeline, name: 'staging', stage_idx: 2, stage: 'deploy') } - - describe '#local' do - subject { described_class.new(job).local } - - describe 'jobs from previous stages' do - context 'when job is in the first stage' do - let(:job) { build } - - it { is_expected.to be_empty } - end - - context 'when job is in the second stage' do - let(:job) { rspec_test } - - it 'contains all jobs from the first stage' do - is_expected.to contain_exactly(build) - end - end - - context 'when job is in the last stage' do - let(:job) { staging } - - it 'contains all jobs from all previous stages' do - is_expected.to contain_exactly(build, rspec_test, rubocop_test) - end - - context 'when a job is retried' do - before do - project.add_developer(user) - end - - let(:retried_job) { Ci::Build.retry(rspec_test, user) } - - it 'contains the retried job instead of the original one' do - is_expected.to contain_exactly(build, retried_job, rubocop_test) - end - end - end - end - - describe 'jobs from specified dependencies' do - let(:dependencies) { } - let(:needs) { } - - let!(:job) do - scheduling_type = needs.present? ? :dag : :stage - - create(:ci_build, - pipeline: pipeline, - name: 'final', - scheduling_type: scheduling_type, - stage_idx: 3, - stage: 'deploy', - options: { dependencies: dependencies } - ) - end - - before do - needs.to_a.each do |need| - create(:ci_build_need, build: job, **need) - end - end - - context 'when dependencies are defined' do - let(:dependencies) { %w(rspec staging) } - - it { is_expected.to contain_exactly(rspec_test, staging) } - end - - context 'when needs are defined' do - let(:needs) do - [ - { name: 'build', artifacts: true }, - { name: 'rspec', artifacts: true }, - { name: 'staging', artifacts: true } - ] - end - - it { is_expected.to contain_exactly(build, rspec_test, staging) } - - context 'when ci_dag_support is disabled' do - before do - stub_feature_flags(ci_dag_support: false) - end - - it { is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging) } - end - end - - context 'when need artifacts are defined' do - let(:needs) do - [ - { name: 'build', artifacts: true }, - { name: 'rspec', artifacts: false }, - { name: 'staging', artifacts: true } - ] - end - - it { is_expected.to contain_exactly(build, staging) } - end - - context 'when needs and dependencies are defined' do - let(:dependencies) { %w(rspec staging) } - let(:needs) do - [ - { name: 'build', artifacts: true }, - { name: 'rspec', artifacts: true }, - { name: 'staging', artifacts: true } - ] - end - - it { is_expected.to contain_exactly(rspec_test, staging) } - end - - context 'when needs and dependencies contradict' do - let(:dependencies) { %w(rspec staging) } - let(:needs) do - [ - { name: 'build', artifacts: true }, - { name: 'rspec', artifacts: false }, - { name: 'staging', artifacts: true } - ] - end - - it 'returns only the intersection' do - is_expected.to contain_exactly(staging) - end - end - - context 'when nor dependencies or needs are defined' do - it 'returns the jobs from previous stages' do - is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging) - end - end - end - end - - describe '#all' do - let!(:job) do - create(:ci_build, pipeline: pipeline, name: 'deploy', stage_idx: 3, stage: 'deploy') - end - - let(:dependencies) { described_class.new(job) } - - subject { dependencies.all } - - it 'returns the union of all local dependencies and any cross pipeline dependencies' do - expect(dependencies).to receive(:local).and_return([1, 2, 3]) - expect(dependencies).to receive(:cross_pipeline).and_return([3, 4]) - - expect(subject).to contain_exactly(1, 2, 3, 4) - end - end -end diff --git a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb new file mode 100644 index 00000000000..3eb2ca6909b --- /dev/null +++ b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Starting a Jira Import' do + include GraphqlHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:project, reload: true) { create(:project) } + let(:jira_project_key) { 'AA' } + let(:project_path) { project.full_path } + + let(:mutation) do + variables = { + jira_project_key: jira_project_key, + project_path: project_path + } + + graphql_mutation(:jira_import_start, variables) + end + + def mutation_response + graphql_mutation_response(:jira_import_start) + end + + def jira_import + mutation_response['jiraImport'] + end + + context 'when the user does not have permission' do + before do + stub_feature_flags(jira_issue_import: true) + end + + shared_examples 'Jira import does not start' do + it 'does not start the Jira import' do + post_graphql_mutation(mutation, current_user: current_user) + + expect(project.reload.import_state).to be nil + expect(project.reload.import_data).to be nil + end + end + + context 'with anonymous user' do + let(:current_user) { nil } + + it_behaves_like 'Jira import does not start' + it_behaves_like 'a mutation that returns top-level errors', + errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR] + end + + context 'with user without permissions' do + let(:current_user) { user } + let(:project_path) { project.full_path } + + before do + project.add_developer(current_user) + end + + it_behaves_like 'Jira import does not start' + it_behaves_like 'a mutation that returns top-level errors', + errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR] + end + end + + context 'when the user has permission' do + let(:current_user) { user } + + before do + project.add_maintainer(current_user) + end + + context 'with project' do + context 'when the project path is invalid' do + let(:project_path) { 'foobar' } + + it 'returns an an error' do + post_graphql_mutation(mutation, current_user: current_user) + errors = json_response['errors'] + + expect(errors.first['message']).to eq(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR) + end + end + + context 'when feature jira_issue_import feature flag is disabled' do + before do + stub_feature_flags(jira_issue_import: false) + end + + it_behaves_like 'a mutation that returns errors in the response', errors: ['Jira import feature is disabled.'] + end + + context 'when feature jira_issue_import feature flag is enabled' do + before do + stub_feature_flags(jira_issue_import: true) + end + + context 'when project has no Jira service' do + it_behaves_like 'a mutation that returns errors in the response', errors: ['Jira integration not configured.'] + end + + context 'when when project has Jira service' do + let!(:service) { create(:jira_service, project: project) } + + before do + project.reload + end + + context 'when jira_project_key not provided' do + let(:jira_project_key) { '' } + + it_behaves_like 'a mutation that returns errors in the response', errors: ['Unable to find Jira project to import data from.'] + end + + context 'when jira import successfully scheduled' do + it 'schedules a Jira import' do + post_graphql_mutation(mutation, current_user: current_user) + + expect(jira_import['jiraProjectKey']).to eq 'AA' + expect(jira_import['scheduledBy']['username']).to eq current_user.username + expect(project.import_state).not_to be nil + expect(project.import_state.status).to eq 'scheduled' + expect(project.import_data.becomes(JiraImportData).projects.last.scheduled_by['user_id']).to eq current_user.id + end + end + end + end + end + end +end diff --git a/spec/requests/api/project_clusters_spec.rb b/spec/requests/api/project_clusters_spec.rb index 7cef40ff3b5..648577dce8d 100644 --- a/spec/requests/api/project_clusters_spec.rb +++ b/spec/requests/api/project_clusters_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' describe API::ProjectClusters do include KubernetesHelpers - let(:current_user) { create(:user) } - let(:developer_user) { create(:user) } - let(:project) { create(:project) } + let_it_be(:current_user) { create(:user) } + let_it_be(:developer_user) { create(:user) } + let_it_be(:project) { create(:project) } before do project.add_maintainer(current_user) @@ -15,10 +15,10 @@ describe API::ProjectClusters do end describe 'GET /projects/:id/clusters' do - let!(:extra_cluster) { create(:cluster, :provided_by_gcp, :project) } + let_it_be(:extra_cluster) { create(:cluster, :provided_by_gcp, :project) } - let!(:clusters) do - create_list(:cluster, 5, :provided_by_gcp, :project, :production_environment, + let_it_be(:clusters) do + create_list(:cluster, 2, :provided_by_gcp, :project, :production_environment, projects: [project]) end @@ -35,17 +35,15 @@ describe API::ProjectClusters do get api("/projects/#{project.id}/clusters", current_user) end - it 'responds with 200' do - expect(response).to have_gitlab_http_status(:ok) - end - it 'includes pagination headers' do + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers end it 'onlies include authorized clusters' do cluster_ids = json_response.map { |cluster| cluster['id'] } + expect(response).to have_gitlab_http_status(:ok) expect(cluster_ids).to match_array(clusters.pluck(:id)) expect(cluster_ids).not_to include(extra_cluster.id) end @@ -139,7 +137,7 @@ describe API::ProjectClusters do end context 'with non-existing cluster' do - let(:cluster_id) { 123 } + let(:cluster_id) { 0 } it 'returns 404' do expect(response).to have_gitlab_http_status(:not_found) @@ -185,14 +183,11 @@ describe API::ProjectClusters do end context 'with valid params' do - it 'responds with 201' do - expect(response).to have_gitlab_http_status(:created) - end - it 'creates a new Cluster::Cluster' do cluster_result = Clusters::Cluster.find(json_response["id"]) platform_kubernetes = cluster_result.platform + expect(response).to have_gitlab_http_status(:created) expect(cluster_result).to be_user expect(cluster_result).to be_kubernetes expect(cluster_result.project).to eq(project) @@ -235,15 +230,9 @@ describe API::ProjectClusters do context 'with invalid params' do let(:namespace) { 'invalid_namespace' } - it 'responds with 400' do - expect(response).to have_gitlab_http_status(:bad_request) - end - it 'does not create a new Clusters::Cluster' do + expect(response).to have_gitlab_http_status(:bad_request) expect(project.reload.clusters).to be_empty - end - - it 'returns validation errors' do expect(json_response['message']['platform_kubernetes.namespace'].first).to be_present end end @@ -259,8 +248,8 @@ describe API::ProjectClusters do it 'responds with 400' do expect(response).to have_gitlab_http_status(:bad_request) - - expect(json_response['message']['base'].first).to eq(_('Instance does not support multiple Kubernetes clusters')) + expect(json_response['message']['base'].first) + .to eq(_('Instance does not support multiple Kubernetes clusters')) end end @@ -271,7 +260,6 @@ describe API::ProjectClusters do it 'responds with 403' do expect(response).to have_gitlab_http_status(:forbidden) - expect(json_response['message']).to eq('403 Forbidden') end end @@ -281,7 +269,7 @@ describe API::ProjectClusters do let(:api_url) { 'https://kubernetes.example.com' } let(:namespace) { 'new-namespace' } let(:platform_kubernetes_attributes) { { namespace: namespace } } - let(:management_project) { create(:project, namespace: project.namespace) } + let_it_be(:management_project) { create(:project, namespace: project.namespace) } let(:management_project_id) { management_project.id } let(:update_params) do @@ -321,11 +309,8 @@ describe API::ProjectClusters do end context 'with valid params' do - it 'responds with 200' do - expect(response).to have_gitlab_http_status(:ok) - end - it 'updates cluster attributes' do + expect(response).to have_gitlab_http_status(:ok) expect(cluster.domain).to eq('new-domain.com') expect(cluster.platform_kubernetes.namespace).to eq('new-namespace') expect(cluster.management_project).to eq(management_project) @@ -335,29 +320,24 @@ describe API::ProjectClusters do context 'with invalid params' do let(:namespace) { 'invalid_namespace' } - it 'responds with 400' do - expect(response).to have_gitlab_http_status(:bad_request) - end - it 'does not update cluster attributes' do + expect(response).to have_gitlab_http_status(:bad_request) expect(cluster.domain).not_to eq('new_domain.com') expect(cluster.platform_kubernetes.namespace).not_to eq('invalid_namespace') expect(cluster.management_project).not_to eq(management_project) end it 'returns validation errors' do - expect(json_response['message']['platform_kubernetes.namespace'].first).to match('can contain only lowercase letters') + expect(json_response['message']['platform_kubernetes.namespace'].first) + .to match('can contain only lowercase letters') end end context 'current user does not have access to management_project_id' do - let(:management_project_id) { create(:project).id } - - it 'responds with 400' do - expect(response).to have_gitlab_http_status(:bad_request) - end + let_it_be(:management_project_id) { create(:project).id } it 'returns validation errors' do + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']['management_project_id'].first).to match('don\'t have permission') end end @@ -371,12 +351,10 @@ describe API::ProjectClusters do } end - it 'responds with 400' do - expect(response).to have_gitlab_http_status(:bad_request) - end - it 'returns validation error' do - expect(json_response['message']['platform_kubernetes.base'].first).to eq(_('Cannot modify managed Kubernetes cluster')) + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']['platform_kubernetes.base'].first) + .to eq(_('Cannot modify managed Kubernetes cluster')) end end @@ -412,13 +390,10 @@ describe API::ProjectClusters do } end - it 'responds with 200' do - expect(response).to have_gitlab_http_status(:ok) - end - it 'updates platform kubernetes attributes' do platform_kubernetes = cluster.platform_kubernetes + expect(response).to have_gitlab_http_status(:ok) expect(cluster.name).to eq('new-name') expect(platform_kubernetes.namespace).to eq('new-namespace') expect(platform_kubernetes.api_url).to eq('https://new-api-url.com') @@ -439,7 +414,7 @@ describe API::ProjectClusters do describe 'DELETE /projects/:id/clusters/:cluster_id' do let(:cluster_params) { { cluster_id: cluster.id } } - let(:cluster) do + let_it_be(:cluster) do create(:cluster, :project, :provided_by_gcp, projects: [project]) end @@ -457,11 +432,8 @@ describe API::ProjectClusters do delete api("/projects/#{project.id}/clusters/#{cluster.id}", current_user), params: cluster_params end - it 'responds with 204' do - expect(response).to have_gitlab_http_status(:no_content) - end - it 'deletes the cluster' do + expect(response).to have_gitlab_http_status(:no_content) expect(Clusters::Cluster.exists?(id: cluster.id)).to be_falsy end diff --git a/spec/support/helpers/stub_gitlab_calls.rb b/spec/support/helpers/stub_gitlab_calls.rb index ff4b9db8ad9..40f4151c0fb 100644 --- a/spec/support/helpers/stub_gitlab_calls.rb +++ b/spec/support/helpers/stub_gitlab_calls.rb @@ -30,11 +30,9 @@ module StubGitlabCalls # Stub the first call to `include:[local: .gitlab-ci.yml]` when # evaluating the CI root config content. - if Feature.enabled?(:ci_root_config_content, default_enabled: true) - allow_any_instance_of(Gitlab::Ci::Config::External::File::Local) - .to receive(:content) - .and_return(ci_yaml_content) - end + allow_any_instance_of(Gitlab::Ci::Config::External::File::Local) + .to receive(:content) + .and_return(ci_yaml_content) end def stub_pipeline_modified_paths(pipeline, modified_paths) -- cgit v1.2.1