Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-18 12:09:31 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-18 12:09:31 +0300
commit6763d2787670bc03a36a8eb601703e88fc70dece (patch)
treeedc653ffd3052e3f9898c4fa8a07621d51574767 /spec
parented9165c2abda1dca048a8d3cb8030d906c0bbb0c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/db/schema_spec.rb1
-rw-r--r--spec/factories/ci/daily_report_results.rb13
-rw-r--r--spec/factories/users.rb2
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_actions_spec.js93
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js30
-rw-r--r--spec/frontend/error_tracking/components/list_mock.json9
-rw-r--r--spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb10
-rw-r--r--spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/code_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/production_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/review_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb1
-rw-r--r--spec/lib/gitlab/cycle_analytics/test_stage_spec.rb1
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/migrations/migrate_bot_type_to_user_type_spec.rb20
-rw-r--r--spec/models/ci/daily_report_result_spec.rb62
-rw-r--r--spec/models/ci/pipeline_spec.rb23
-rw-r--r--spec/models/user_spec.rb4
-rw-r--r--spec/services/ci/daily_report_result_service_spec.rb140
-rw-r--r--spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/lib/gitlab/cycle_analytics/base_stage_shared_examples.rb (renamed from spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb)4
-rw-r--r--spec/support/shared_examples/lib/gitlab/cycle_analytics/default_query_config_shared_examples.rb (renamed from spec/lib/gitlab/cycle_analytics/shared_event_spec.rb)0
-rw-r--r--spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb (renamed from spec/support/shared_examples/lib/gitlab/cycle_analytics_event_shared_examples.rb)0
-rw-r--r--spec/workers/ci/daily_report_results_worker_spec.rb34
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