diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-18 12:09:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-18 12:09:31 +0300 |
commit | 6763d2787670bc03a36a8eb601703e88fc70dece (patch) | |
tree | edc653ffd3052e3f9898c4fa8a07621d51574767 /spec | |
parent | ed9165c2abda1dca048a8d3cb8030d906c0bbb0c (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
32 files changed, 418 insertions, 51 deletions
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index c6c842ce1a1..08e4920b020 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -132,6 +132,7 @@ describe 'Database schema' do 'Ci::Build' => %w[failure_reason], 'Ci::BuildMetadata' => %w[timeout_source], 'Ci::BuildTraceChunk' => %w[data_store], + 'Ci::DailyReportResult' => %w[param_type], 'Ci::JobArtifact' => %w[file_type], 'Ci::Pipeline' => %w[source config_source failure_reason], 'Ci::Processable' => %w[failure_reason], diff --git a/spec/factories/ci/daily_report_results.rb b/spec/factories/ci/daily_report_results.rb new file mode 100644 index 00000000000..e2255e8a134 --- /dev/null +++ b/spec/factories/ci/daily_report_results.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :ci_daily_report_result, class: 'Ci::DailyReportResult' do + ref_path { Gitlab::Git::BRANCH_REF_PREFIX + 'master' } + date { Time.zone.now.to_date } + project + last_pipeline factory: :ci_pipeline + param_type { Ci::DailyReportResult.param_types[:coverage] } + title { 'rspec' } + value { 77.0 } + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 34f6da682b6..0ce567e11fe 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -24,7 +24,7 @@ FactoryBot.define do end trait :bot do - bot_type { User.bot_types[:alert_bot] } + user_type { :alert_bot } end trait :external do diff --git a/spec/frontend/error_tracking/components/error_tracking_actions_spec.js b/spec/frontend/error_tracking/components/error_tracking_actions_spec.js new file mode 100644 index 00000000000..b22805f5227 --- /dev/null +++ b/spec/frontend/error_tracking/components/error_tracking_actions_spec.js @@ -0,0 +1,93 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlButton } from '@gitlab/ui'; +import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue'; + +describe('Error Tracking Actions', () => { + let wrapper; + + function mountComponent(props) { + wrapper = shallowMount(ErrorTrackingActions, { + propsData: { + error: { + id: '1', + title: 'PG::ConnectionBad: FATAL', + type: 'error', + userCount: 0, + count: '52', + firstSeen: '2019-05-30T07:21:46Z', + lastSeen: '2019-11-06T03:21:39Z', + status: 'unresolved', + }, + ...props, + }, + stubs: { GlButton }, + }); + } + + beforeEach(() => { + mountComponent(); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + }); + + const findButtons = () => wrapper.findAll(GlButton); + + describe('when error status is unresolved', () => { + it('renders the correct actions buttons to allow ignore and resolve', () => { + expect(findButtons().exists()).toBe(true); + + return wrapper.vm.$nextTick().then(() => { + expect( + findButtons() + .at(0) + .attributes('title'), + ).toBe('Ignore'); + expect( + findButtons() + .at(1) + .attributes('title'), + ).toBe('Resolve'); + }); + }); + }); + + describe('when error status is ignored', () => { + beforeEach(() => { + mountComponent({ error: { status: 'ignored' } }); + }); + + it('renders the correct action button to undo ignore', () => { + expect(findButtons().exists()).toBe(true); + + return wrapper.vm.$nextTick().then(() => { + expect( + findButtons() + .at(0) + .attributes('title'), + ).toBe('Undo Ignore'); + }); + }); + }); + + describe('when error status is resolved', () => { + beforeEach(() => { + mountComponent({ error: { status: 'resolved' } }); + }); + + it('renders the correct action button to undo unresolve', () => { + expect(findButtons().exists()).toBe(true); + + return wrapper.vm.$nextTick().then(() => { + expect( + findButtons() + .at(1) + .attributes('title'), + ).toBe('Unresolve'); + }); + }); + }); +}); diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js index cd6dd5c7519..3bea1d343be 100644 --- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js +++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js @@ -3,6 +3,7 @@ import Vuex from 'vuex'; import { GlEmptyState, GlLoadingIcon, GlFormInput, GlPagination, GlDropdown } from '@gitlab/ui'; import stubChildren from 'helpers/stub_children'; import ErrorTrackingList from '~/error_tracking/components/error_tracking_list.vue'; +import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue'; import errorsList from './list_mock.json'; const localVue = createLocalVue(); @@ -30,6 +31,7 @@ describe('ErrorTrackingList', () => { .find(GlDropdown); const findLoadingIcon = () => wrapper.find(GlLoadingIcon); const findPagination = () => wrapper.find(GlPagination); + const findErrorActions = () => wrapper.find(ErrorTrackingActions); function mountComponent({ errorTrackingEnabled = true, @@ -151,15 +153,9 @@ describe('ErrorTrackingList', () => { }); }); - it('each error in the list should have an ignore button', () => { + it('each error in the list should have an action button set', () => { findErrorListRows().wrappers.forEach(row => { - expect(row.contains('glicon-stub[name="eye-slash"]')).toBe(true); - }); - }); - - it('each error in the list should have a resolve button', () => { - findErrorListRows().wrappers.forEach(row => { - expect(row.contains('glicon-stub[name="check-circle"]')).toBe(true); + expect(row.contains(ErrorTrackingActions)).toBe(true); }); }); @@ -237,8 +233,6 @@ describe('ErrorTrackingList', () => { }); describe('When the ignore button on an error is clicked', () => { - const ignoreErrorButton = () => wrapper.find({ ref: 'ignoreError' }); - beforeEach(() => { store.state.list.loading = false; store.state.list.errors = errorsList; @@ -253,7 +247,10 @@ describe('ErrorTrackingList', () => { }); it('sends the "ignored" status and error ID', () => { - ignoreErrorButton().trigger('click'); + findErrorActions().vm.$emit('update-issue-status', { + errorId: errorsList[0].id, + status: 'ignored', + }); expect(actions.updateStatus).toHaveBeenCalledWith( expect.anything(), { @@ -265,7 +262,7 @@ describe('ErrorTrackingList', () => { }); it('calls an action to remove the item from the list', () => { - ignoreErrorButton().trigger('click'); + findErrorActions().vm.$emit('update-issue-status', { errorId: '1', status: undefined }); expect(actions.removeIgnoredResolvedErrors).toHaveBeenCalledWith( expect.anything(), '1', @@ -275,8 +272,6 @@ describe('ErrorTrackingList', () => { }); describe('When the resolve button on an error is clicked', () => { - const resolveErrorButton = () => wrapper.find({ ref: 'resolveError' }); - beforeEach(() => { store.state.list.loading = false; store.state.list.errors = errorsList; @@ -291,7 +286,10 @@ describe('ErrorTrackingList', () => { }); it('sends "resolved" status and error ID', () => { - resolveErrorButton().trigger('click'); + findErrorActions().vm.$emit('update-issue-status', { + errorId: errorsList[0].id, + status: 'resolved', + }); expect(actions.updateStatus).toHaveBeenCalledWith( expect.anything(), { @@ -303,7 +301,7 @@ describe('ErrorTrackingList', () => { }); it('calls an action to remove the item from the list', () => { - resolveErrorButton().trigger('click'); + findErrorActions().vm.$emit('update-issue-status', { errorId: '1', status: undefined }); expect(actions.removeIgnoredResolvedErrors).toHaveBeenCalledWith( expect.anything(), '1', diff --git a/spec/frontend/error_tracking/components/list_mock.json b/spec/frontend/error_tracking/components/list_mock.json index a6e94c1a026..54ae0a4c7cf 100644 --- a/spec/frontend/error_tracking/components/list_mock.json +++ b/spec/frontend/error_tracking/components/list_mock.json @@ -6,7 +6,8 @@ "userCount": 0, "count": "52", "firstSeen": "2019-05-30T07:21:46Z", - "lastSeen": "2019-11-06T03:21:39Z" + "lastSeen": "2019-11-06T03:21:39Z", + "status": "unresolved" }, { "id": "2", @@ -15,7 +16,8 @@ "userCount": 0, "count": "12", "firstSeen": "2019-10-19T03:53:56Z", - "lastSeen": "2019-11-05T03:51:54Z" + "lastSeen": "2019-11-05T03:51:54Z", + "status": "unresolved" }, { "id": "3", @@ -24,6 +26,7 @@ "userCount": 0, "count": "275", "firstSeen": "2019-02-12T07:22:36Z", - "lastSeen": "2019-10-22T03:20:48Z" + "lastSeen": "2019-10-22T03:20:48Z", + "status": "unresolved" } ]
\ No newline at end of file diff --git a/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb b/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb index a273dcf9e5c..ff8b9dd1005 100644 --- a/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb +++ b/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb @@ -12,6 +12,7 @@ describe Gitlab::BackgroundMigration::UserMentions::CreateResourceUserMention, s let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:notes) { table(:notes) } + let(:routes) { table(:routes) } let(:author) { users.create!(email: 'author@example.com', notification_email: 'author@example.com', name: 'author', username: 'author', projects_limit: 10, state: 'active') } let(:member) { users.create!(email: 'member@example.com', notification_email: 'member@example.com', name: 'member', username: 'member', projects_limit: 10, state: 'active') } @@ -32,13 +33,14 @@ describe Gitlab::BackgroundMigration::UserMentions::CreateResourceUserMention, s before do # build personal namespaces and routes for users - mentioned_users.each { |u| u.becomes(User).save! } + mentioned_users.each do |u| + namespace = namespaces.create!(path: u.username, name: u.name, runners_token: "my-token-u#{u.id}", owner_id: u.id, type: nil) + routes.create!(path: namespace.path, source_type: 'Namespace', source_id: namespace.id) + end # build namespaces and routes for groups mentioned_groups.each do |gr| - gr.name += '-org' - gr.path += '-org' - gr.becomes(Namespace).save! + routes.create!(path: gr.path, source_type: 'Namespace', source_id: gr.id) end end diff --git a/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb index b521ad0c6ea..326a41a3af7 100644 --- a/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::CodeEventFetcher do let(:stage_name) { :code } diff --git a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb index aa12bc21d22..9a4193b09f5 100644 --- a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::CodeStage do let(:stage_name) { :code } diff --git a/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb index afb7b6a13b0..a72e2952782 100644 --- a/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::IssueEventFetcher do let(:stage_name) { :issue } diff --git a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb index 497db88d850..021d31bf160 100644 --- a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::IssueStage do let(:stage_name) { :issue } diff --git a/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb index 17786cd02c6..587f185b970 100644 --- a/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::PlanEventFetcher do let(:stage_name) { :plan } diff --git a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb index 01a46f5ba65..e391fa6b999 100644 --- a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::PlanStage do let(:stage_name) { :plan } diff --git a/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb index 3ecfad49acd..aeca72e8c91 100644 --- a/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::ProductionEventFetcher do let(:stage_name) { :production } diff --git a/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb index eceea474988..aeeae291e2e 100644 --- a/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::ProductionStage do let(:stage_name) { 'Total' } diff --git a/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb index 2c2169be58c..3eb62b45e6f 100644 --- a/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::ReviewEventFetcher do let(:stage_name) { :review } diff --git a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb index 0f36a8c5c36..14100ee6f73 100644 --- a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::ReviewStage do let(:stage_name) { :review } diff --git a/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb index 016d2e8da5b..525f1608a70 100644 --- a/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::StagingEventFetcher do let(:stage_name) { :staging } diff --git a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb index 306b08a60e1..930892edd31 100644 --- a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::StagingStage do let(:stage_name) { :staging } diff --git a/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb index be7c0e9dd59..d550f083600 100644 --- a/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_event_spec' describe Gitlab::CycleAnalytics::TestEventFetcher do let(:stage_name) { :test } diff --git a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb index e347f36dfce..56e90520e72 100644 --- a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'spec_helper' -require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::TestStage do let(:stage_name) { :test } diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 37b3e4a4a22..eb28e730499 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -208,6 +208,7 @@ ci_pipelines: - vulnerability_findings - pipeline_config - security_scans +- daily_report_results pipeline_variables: - pipeline stages: @@ -470,6 +471,7 @@ project: - status_page_setting - requirements - export_jobs +- daily_report_results award_emoji: - awardable - user diff --git a/spec/migrations/migrate_bot_type_to_user_type_spec.rb b/spec/migrations/migrate_bot_type_to_user_type_spec.rb new file mode 100644 index 00000000000..9686aae0cd3 --- /dev/null +++ b/spec/migrations/migrate_bot_type_to_user_type_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require Rails.root.join('db', 'migrate', '20200311074438_migrate_bot_type_to_user_type.rb') + +describe MigrateBotTypeToUserType, :migration do + let(:users) { table(:users) } + + it 'updates bots & ignores humans' do + users.create!(email: 'human', bot_type: nil, projects_limit: 0) + users.create!(email: 'support_bot', bot_type: 1, projects_limit: 0) + users.create!(email: 'alert_bot', bot_type: 2, projects_limit: 0) + users.create!(email: 'visual_review_bot', bot_type: 3, projects_limit: 0) + + migrate! + + expect(users.where('user_type IS NOT NULL').map(&:user_type)).to match_array([1, 2, 3]) + end +end diff --git a/spec/models/ci/daily_report_result_spec.rb b/spec/models/ci/daily_report_result_spec.rb new file mode 100644 index 00000000000..61aa58c6692 --- /dev/null +++ b/spec/models/ci/daily_report_result_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::DailyReportResult do + describe '.upsert_reports' do + let!(:rspec_coverage) do + create( + :ci_daily_report_result, + title: 'rspec', + date: '2020-03-09', + value: 71.2 + ) + end + let!(:new_pipeline) { create(:ci_pipeline) } + + it 'creates or updates matching report results' do + described_class.upsert_reports([ + { + project_id: rspec_coverage.project_id, + ref_path: rspec_coverage.ref_path, + param_type: described_class.param_types[rspec_coverage.param_type], + last_pipeline_id: new_pipeline.id, + date: rspec_coverage.date, + title: 'rspec', + value: 81.0 + }, + { + project_id: rspec_coverage.project_id, + ref_path: rspec_coverage.ref_path, + param_type: described_class.param_types[rspec_coverage.param_type], + last_pipeline_id: new_pipeline.id, + date: rspec_coverage.date, + title: 'karma', + value: 87.0 + } + ]) + + rspec_coverage.reload + + expect(rspec_coverage).to have_attributes( + last_pipeline_id: new_pipeline.id, + value: 81.0 + ) + + expect(described_class.find_by_title('karma')).to have_attributes( + project_id: rspec_coverage.project_id, + ref_path: rspec_coverage.ref_path, + param_type: rspec_coverage.param_type, + last_pipeline_id: new_pipeline.id, + date: rspec_coverage.date, + value: 87.0 + ) + end + + context 'when given data is empty' do + it 'does nothing' do + expect { described_class.upsert_reports([]) }.not_to raise_error + end + end + end +end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index f18c77988c8..c3f2e3aebdd 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1120,7 +1120,7 @@ describe Ci::Pipeline, :mailer do let(:from_status) { status } it 'schedules pipeline success worker' do - expect(PipelineSuccessWorker).to receive(:perform_async).with(pipeline.id) + expect(Ci::DailyReportResultsWorker).to receive(:perform_in).with(10.minutes, pipeline.id) pipeline.succeed end @@ -3114,4 +3114,25 @@ describe Ci::Pipeline, :mailer do end end end + + describe '#source_ref_path' do + subject { pipeline.source_ref_path } + + context 'when pipeline is for a branch' do + it { is_expected.to eq(Gitlab::Git::BRANCH_REF_PREFIX + pipeline.source_ref.to_s) } + end + + context 'when pipeline is for a merge request' do + let(:merge_request) { create(:merge_request, source_project: project) } + let(:pipeline) { create(:ci_pipeline, project: project, head_pipeline_of: merge_request) } + + it { is_expected.to eq(Gitlab::Git::BRANCH_REF_PREFIX + pipeline.source_ref.to_s) } + end + + context 'when pipeline is for a tag' do + let(:pipeline) { create(:ci_pipeline, project: project, tag: true) } + + it { is_expected.to eq(Gitlab::Git::TAG_REF_PREFIX + pipeline.source_ref.to_s) } + end + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 849494e7cd4..c87272b2309 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -4244,12 +4244,12 @@ describe User, :do_not_mock_admin_mode do let!(:non_internal) { [user] } let!(:internal) { [ghost, alert_bot] } - it 'returns non internal users' do + it 'returns internal users' do expect(described_class.internal).to eq(internal) expect(internal.all?(&:internal?)).to eq(true) end - it 'returns internal users' do + it 'returns non internal users' do expect(described_class.non_internal).to eq(non_internal) expect(non_internal.all?(&:internal?)).to eq(false) end diff --git a/spec/services/ci/daily_report_result_service_spec.rb b/spec/services/ci/daily_report_result_service_spec.rb new file mode 100644 index 00000000000..793fc956acb --- /dev/null +++ b/spec/services/ci/daily_report_result_service_spec.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::DailyReportResultService, '#execute' do + let!(:pipeline) { create(:ci_pipeline, created_at: '2020-02-06 00:01:10') } + let!(:rspec_job) { create(:ci_build, pipeline: pipeline, name: '3/3 rspec', coverage: 80) } + let!(:karma_job) { create(:ci_build, pipeline: pipeline, name: '2/2 karma', coverage: 90) } + let!(:extra_job) { create(:ci_build, pipeline: pipeline, name: 'extra', coverage: nil) } + + it 'creates daily code coverage record for each job in the pipeline that has coverage value' do + described_class.new.execute(pipeline) + + Ci::DailyReportResult.find_by(title: 'rspec').tap do |coverage| + expect(coverage).to have_attributes( + project_id: pipeline.project.id, + last_pipeline_id: pipeline.id, + ref_path: pipeline.source_ref_path, + param_type: 'coverage', + title: rspec_job.group_name, + value: rspec_job.coverage, + date: pipeline.created_at.to_date + ) + end + + Ci::DailyReportResult.find_by(title: 'karma').tap do |coverage| + expect(coverage).to have_attributes( + project_id: pipeline.project.id, + last_pipeline_id: pipeline.id, + ref_path: pipeline.source_ref_path, + param_type: 'coverage', + title: karma_job.group_name, + value: karma_job.coverage, + date: pipeline.created_at.to_date + ) + end + + expect(Ci::DailyReportResult.find_by(title: 'extra')).to be_nil + end + + context 'when there is an existing daily code coverage for the matching date, project, ref_path, and group name' do + let!(:new_pipeline) do + create( + :ci_pipeline, + project: pipeline.project, + ref: pipeline.ref, + created_at: '2020-02-06 00:02:20' + ) + end + let!(:new_rspec_job) { create(:ci_build, pipeline: new_pipeline, name: '4/4 rspec', coverage: 84) } + let!(:new_karma_job) { create(:ci_build, pipeline: new_pipeline, name: '3/3 karma', coverage: 92) } + + before do + # Create the existing daily code coverage records + described_class.new.execute(pipeline) + end + + it "updates the existing record's coverage value and last_pipeline_id" do + rspec_coverage = Ci::DailyReportResult.find_by(title: 'rspec') + karma_coverage = Ci::DailyReportResult.find_by(title: 'karma') + + # Bump up the coverage values + described_class.new.execute(new_pipeline) + + rspec_coverage.reload + karma_coverage.reload + + expect(rspec_coverage).to have_attributes( + last_pipeline_id: new_pipeline.id, + value: new_rspec_job.coverage + ) + + expect(karma_coverage).to have_attributes( + last_pipeline_id: new_pipeline.id, + value: new_karma_job.coverage + ) + end + end + + context 'when the ID of the pipeline is older than the last_pipeline_id' do + let!(:new_pipeline) do + create( + :ci_pipeline, + project: pipeline.project, + ref: pipeline.ref, + created_at: '2020-02-06 00:02:20' + ) + end + let!(:new_rspec_job) { create(:ci_build, pipeline: new_pipeline, name: '4/4 rspec', coverage: 84) } + let!(:new_karma_job) { create(:ci_build, pipeline: new_pipeline, name: '3/3 karma', coverage: 92) } + + before do + # Create the existing daily code coverage records + # but in this case, for the newer pipeline first. + described_class.new.execute(new_pipeline) + end + + it 'updates the existing daily code coverage records' do + rspec_coverage = Ci::DailyReportResult.find_by(title: 'rspec') + karma_coverage = Ci::DailyReportResult.find_by(title: 'karma') + + # Run another one but for the older pipeline. + # This simulates the scenario wherein the success worker + # of an older pipeline, for some network hiccup, was delayed + # and only got executed right after the newer pipeline's success worker. + # Ideally, we don't want to bump the coverage value with an older one + # but given this can be a rare edge case and can be remedied by re-running + # the pipeline we'll just let it be for now. In return, we are able to use + # Rails 6 shiny new method, upsert_all, and simplify the code a lot. + described_class.new.execute(pipeline) + + rspec_coverage.reload + karma_coverage.reload + + expect(rspec_coverage).to have_attributes( + last_pipeline_id: pipeline.id, + value: rspec_job.coverage + ) + + expect(karma_coverage).to have_attributes( + last_pipeline_id: pipeline.id, + value: karma_job.coverage + ) + end + end + + context 'when pipeline has no builds with coverage' do + let!(:new_pipeline) do + create( + :ci_pipeline, + created_at: '2020-02-06 00:02:20' + ) + end + let!(:some_job) { create(:ci_build, pipeline: new_pipeline, name: 'foo') } + + it 'does nothing' do + expect { described_class.new.execute(new_pipeline) }.not_to raise_error + end + end +end diff --git a/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb index a3f0c84bd1f..a40c38106e2 100644 --- a/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb @@ -22,14 +22,6 @@ shared_examples 'resource mentions migration' do |migration_class, resource_clas end shared_examples 'resource notes mentions migration' do |migration_class, resource_class| - before do - note1.becomes(Note).save! - note2.becomes(Note).save! - note3.becomes(Note).save! - note4.becomes(Note).save! - note5.becomes(Note).save(validate: false) - end - it 'migrates mentions from note' do join = migration_class::JOIN conditions = migration_class::QUERY_CONDITIONS diff --git a/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb b/spec/support/shared_examples/lib/gitlab/cycle_analytics/base_stage_shared_examples.rb index 9c16fb6f6dc..851ed9c65a3 100644 --- a/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb +++ b/spec/support/shared_examples/lib/gitlab/cycle_analytics/base_stage_shared_examples.rb @@ -2,9 +2,9 @@ require 'spec_helper' -shared_examples 'base stage' do - ISSUES_MEDIAN = 30.minutes.to_i +ISSUES_MEDIAN = 30.minutes.to_i +shared_examples 'base stage' do let(:stage) { described_class.new(options: { project: double }) } before do diff --git a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb b/spec/support/shared_examples/lib/gitlab/cycle_analytics/default_query_config_shared_examples.rb index c053af010b3..c053af010b3 100644 --- a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb +++ b/spec/support/shared_examples/lib/gitlab/cycle_analytics/default_query_config_shared_examples.rb diff --git a/spec/support/shared_examples/lib/gitlab/cycle_analytics_event_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb index a00359ce979..a00359ce979 100644 --- a/spec/support/shared_examples/lib/gitlab/cycle_analytics_event_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb diff --git a/spec/workers/ci/daily_report_results_worker_spec.rb b/spec/workers/ci/daily_report_results_worker_spec.rb new file mode 100644 index 00000000000..b6543b32b09 --- /dev/null +++ b/spec/workers/ci/daily_report_results_worker_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::DailyReportResultsWorker do + describe '#perform' do + let!(:pipeline) { create(:ci_pipeline) } + + subject { described_class.new.perform(pipeline_id) } + + context 'when pipeline is found' do + let(:pipeline_id) { pipeline.id } + + it 'executes service' do + expect_any_instance_of(Ci::DailyReportResultService) + .to receive(:execute).with(pipeline) + + subject + end + end + + context 'when pipeline is not found' do + let(:pipeline_id) { 123 } + + it 'does not execute service' do + expect_any_instance_of(Ci::DailyReportResultService) + .not_to receive(:execute) + + expect { subject } + .not_to raise_error + end + end + end +end |