diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-18 15:06:03 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-18 15:06:03 +0000 |
commit | 4584eb0e07d372d6014de16ab359965475184c99 (patch) | |
tree | 586f35b77fac7ddfb8a05aa57b4fb6aa3d98212e /spec | |
parent | bdbded586beb38e2ee4642c6a1e78ccbebc094dc (diff) | |
download | gitlab-ce-4584eb0e07d372d6014de16ab359965475184c99.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
15 files changed, 224 insertions, 8 deletions
diff --git a/spec/frontend/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_projects/components/import_projects_table_spec.js index 17a998d0174..708f2758083 100644 --- a/spec/frontend/import_projects/components/import_projects_table_spec.js +++ b/spec/frontend/import_projects/components/import_projects_table_spec.js @@ -93,7 +93,7 @@ describe('ImportProjectsTable', () => { return vm.$nextTick().then(() => { expect(vm.$el.querySelector('.js-loading-button-icon')).toBeNull(); expect(vm.$el.querySelector('.table')).toBeNull(); - expect(vm.$el.innerText).toMatch(`No ${providerTitle} repositories available to import`); + expect(vm.$el.innerText).toMatch(`No ${providerTitle} repositories found`); }); }); @@ -182,4 +182,10 @@ describe('ImportProjectsTable', () => { expect(vm.$el.querySelector(`.ic-status_${statusObject.icon}`)).not.toBeNull(); }); }); + + it('renders filtering input field', () => { + expect( + vm.$el.querySelector('input[data-qa-selector="githubish_import_filter_field"]'), + ).not.toBeNull(); + }); }); diff --git a/spec/frontend/import_projects/store/actions_spec.js b/spec/frontend/import_projects/store/actions_spec.js index 6a7b90788dd..340b6f02d93 100644 --- a/spec/frontend/import_projects/store/actions_spec.js +++ b/spec/frontend/import_projects/store/actions_spec.js @@ -97,6 +97,7 @@ describe('import_projects store actions', () => { describe('fetchRepos', () => { let mock; + const payload = { imported_projects: [{}], provider_repos: [{}], namespaces: [{}] }; beforeEach(() => { localState.reposPath = `${TEST_HOST}/endpoint.json`; @@ -105,8 +106,7 @@ describe('import_projects store actions', () => { afterEach(() => mock.restore()); - it('dispatches requestRepos and receiveReposSuccess actions on a successful request', done => { - const payload = { imported_projects: [{}], provider_repos: [{}], namespaces: [{}] }; + it('dispatches stopJobsPolling, requestRepos and receiveReposSuccess actions on a successful request', done => { mock.onGet(`${TEST_HOST}/endpoint.json`).reply(200, payload); testAction( @@ -115,6 +115,7 @@ describe('import_projects store actions', () => { localState, [], [ + { type: 'stopJobsPolling' }, { type: 'requestRepos' }, { type: 'receiveReposSuccess', @@ -128,7 +129,7 @@ describe('import_projects store actions', () => { ); }); - it('dispatches requestRepos and receiveReposSuccess actions on an unsuccessful request', done => { + it('dispatches stopJobsPolling, requestRepos and receiveReposError actions on an unsuccessful request', done => { mock.onGet(`${TEST_HOST}/endpoint.json`).reply(500); testAction( @@ -136,10 +137,39 @@ describe('import_projects store actions', () => { null, localState, [], - [{ type: 'requestRepos' }, { type: 'receiveReposError' }], + [{ type: 'stopJobsPolling' }, { type: 'requestRepos' }, { type: 'receiveReposError' }], done, ); }); + + describe('when filtered', () => { + beforeEach(() => { + localState.filter = 'filter'; + }); + + it('fetches repos with filter applied', done => { + mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(200, payload); + + testAction( + fetchRepos, + null, + localState, + [], + [ + { type: 'stopJobsPolling' }, + { type: 'requestRepos' }, + { + type: 'receiveReposSuccess', + payload: convertObjectPropsToCamelCase(payload, { deep: true }), + }, + { + type: 'fetchJobs', + }, + ], + done, + ); + }); + }); }); describe('requestImport', () => { @@ -249,6 +279,7 @@ describe('import_projects store actions', () => { describe('fetchJobs', () => { let mock; + const updatedProjects = [{ name: 'imported/project' }, { name: 'provider/repo' }]; beforeEach(() => { localState.jobsPath = `${TEST_HOST}/endpoint.json`; @@ -263,7 +294,6 @@ describe('import_projects store actions', () => { afterEach(() => mock.restore()); it('dispatches requestJobs and receiveJobsSuccess actions on a successful request', done => { - const updatedProjects = [{ name: 'imported/project' }, { name: 'provider/repo' }]; mock.onGet(`${TEST_HOST}/endpoint.json`).reply(200, updatedProjects); testAction( @@ -280,5 +310,29 @@ describe('import_projects store actions', () => { done, ); }); + + describe('when filtered', () => { + beforeEach(() => { + localState.filter = 'filter'; + }); + + it('fetches realtime changes with filter applied', done => { + mock.onGet(`${TEST_HOST}/endpoint.json?filter=filter`).reply(200, updatedProjects); + + testAction( + fetchJobs, + null, + localState, + [], + [ + { + type: 'receiveJobsSuccess', + payload: convertObjectPropsToCamelCase(updatedProjects, { deep: true }), + }, + ], + done, + ); + }); + }); }); }); diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb new file mode 100644 index 00000000000..29c8d548754 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::CodeStageStart do + let(:subject) { described_class.new({}) } + let(:project) { create(:project) } + + it_behaves_like 'cycle analytics event' + + it 'needs connection with an issue via merge_requests_closing_issues table' do + issue = create(:issue, project: project) + merge_request = create(:merge_request, source_project: project) + create(:merge_requests_closing_issues, issue: issue, merge_request: merge_request) + + other_merge_request = create(:merge_request, source_project: project, source_branch: 'a', target_branch: 'master') + + records = subject.apply_query_customization(MergeRequest.all) + expect(records).to eq([merge_request]) + expect(records).not_to include(other_merge_request) + end +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb new file mode 100644 index 00000000000..efdef91c5a2 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::IssueCreated do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb new file mode 100644 index 00000000000..50883e1c1e2 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::IssueFirstMentionedInCommit do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb new file mode 100644 index 00000000000..85062db370a --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::IssueStageEnd do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb new file mode 100644 index 00000000000..7858b810661 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestCreated do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb new file mode 100644 index 00000000000..ba9d8be5a2c --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestFirstDeployedToProduction do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb new file mode 100644 index 00000000000..8e83e10ef96 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestLastBuildFinished do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb new file mode 100644 index 00000000000..9f6b430a320 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestLastBuildStarted do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb new file mode 100644 index 00000000000..ce2aa0a60db --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestMerged do + it_behaves_like 'cycle analytics event' +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb new file mode 100644 index 00000000000..cb63139f0a8 --- /dev/null +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Analytics::CycleAnalytics::StageEvents::PlanStageStart do + let(:subject) { described_class.new({}) } + let(:project) { create(:project) } + + it_behaves_like 'cycle analytics event' + + it 'filters issues where first_associated_with_milestone_at or first_added_to_board_at is filled' do + issue1 = create(:issue, project: project) + issue1.metrics.update!(first_added_to_board_at: 1.month.ago, first_mentioned_in_commit_at: 2.months.ago) + + issue2 = create(:issue, project: project) + issue2.metrics.update!(first_associated_with_milestone_at: 1.month.ago, first_mentioned_in_commit_at: 2.months.ago) + + issue_without_metrics = create(:issue, project: project) + + records = subject.apply_query_customization(Issue.all) + expect(records).to match_array([issue1, issue2]) + expect(records).not_to include(issue_without_metrics) + end +end diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb index 29f4be76a65..b05faf5d813 100644 --- a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb +++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb @@ -3,8 +3,11 @@ require 'spec_helper' describe Gitlab::Analytics::CycleAnalytics::StageEvents::StageEvent do + let(:instance) { described_class.new({}) } + it { expect(described_class).to respond_to(:name) } it { expect(described_class).to respond_to(:identifier) } - - it { expect(described_class.new({})).to respond_to(:object_type) } + it { expect(instance).to respond_to(:object_type) } + it { expect(instance).to respond_to(:timestamp_projection) } + it { expect(instance).to respond_to(:apply_query_customization) } end diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index 718d9857b18..f23812e7149 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -139,6 +139,38 @@ shared_examples 'a GitHub-ish import controller: GET status' do expect { get :status, format: :json } .not_to exceed_all_query_limit(control_count) end + + context 'when filtering' do + let(:repo_2) { OpenStruct.new(login: 'emacs', full_name: 'asd/emacs', name: 'emacs', owner: { login: 'owner' }) } + let(:project) { create(:project, import_type: provider, namespace: user.namespace, import_status: :finished, import_source: 'example/repo') } + let(:group) { create(:group) } + + before do + group.add_owner(user) + stub_client(repos: [repo, repo_2, org_repo], orgs: [org], org_repos: [org_repo]) + end + + it 'filters list of repositories by name' do + get :status, params: { filter: 'emacs' }, format: :json + + expect(response).to have_gitlab_http_status(200) + expect(json_response.dig("imported_projects").count).to eq(0) + expect(json_response.dig("provider_repos").count).to eq(1) + expect(json_response.dig("provider_repos", 0, "id")).to eq(repo_2.id) + expect(json_response.dig("namespaces", 0, "id")).to eq(group.id) + end + + context 'when user input contains html' do + let(:expected_filter) { 'test' } + let(:filter) { "<html>#{expected_filter}</html>" } + + it 'sanitizes user input' do + get :status, params: { filter: filter }, format: :json + + expect(assigns(:filter)).to eq(expected_filter) + end + end + end end shared_examples 'a GitHub-ish import controller: POST create' do diff --git a/spec/support/shared_examples/cycle_analytics_event_shared_examples.rb b/spec/support/shared_examples/cycle_analytics_event_shared_examples.rb new file mode 100644 index 00000000000..dce1dbe1cd1 --- /dev/null +++ b/spec/support/shared_examples/cycle_analytics_event_shared_examples.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +shared_examples_for 'cycle analytics event' do + let(:instance) { described_class.new({}) } + + it { expect(described_class.name).to be_a_kind_of(String) } + it { expect(described_class.identifier).to be_a_kind_of(Symbol) } + it { expect(instance.object_type.ancestors).to include(ApplicationRecord) } + it { expect(instance).to respond_to(:timestamp_projection) } + + describe '#apply_query_customization' do + it 'expects an ActiveRecord::Relation object as argument and returns a modified version of it' do + input_query = instance.object_type.all + + output_query = instance.apply_query_customization(input_query) + expect(output_query).to be_a_kind_of(ActiveRecord::Relation) + end + end +end |