summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-02 15:17:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-02 15:17:50 +0000
commit65c71039ebe065a6c97e226f5743bd637680a14e (patch)
treea0c7a9d7f1fd65f290318cc7465cd3d07354a908 /spec
parent292384904c9d821acca2f92d2de2f0b2ed5216df (diff)
downloadgitlab-ce-65c71039ebe065a6c97e226f5743bd637680a14e.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/commits_controller_spec.rb14
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb2
-rw-r--r--spec/features/merge_request/user_resolves_wip_mr_spec.rb4
-rw-r--r--spec/frontend/cycle_analytics/value_stream_metrics_spec.js37
-rw-r--r--spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_charts_spec.js43
-rw-r--r--spec/lib/extracts_path_spec.rb4
-rw-r--r--spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb7
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb35
-rw-r--r--spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb134
-rw-r--r--spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb20
-rw-r--r--spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb130
-rw-r--r--spec/lib/gitlab/database/migrations/instrumentation_spec.rb58
-rw-r--r--spec/lib/gitlab/database/migrations/observers/query_details_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/observers/query_log_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/importer/releases_importer_spec.rb24
-rw-r--r--spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb8
-rw-r--r--spec/models/merge_request_spec.rb33
-rw-r--r--spec/services/merge_requests/create_service_spec.rb10
-rw-r--r--spec/services/merge_requests/mergeability_check_service_spec.rb18
-rw-r--r--spec/services/merge_requests/update_service_spec.rb6
-rw-r--r--spec/services/notes/create_service_spec.rb4
22 files changed, 178 insertions, 419 deletions
diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb
index d84717f1124..c7f98406201 100644
--- a/spec/controllers/projects/commits_controller_spec.rb
+++ b/spec/controllers/projects/commits_controller_spec.rb
@@ -151,6 +151,20 @@ RSpec.describe Projects::CommitsController do
expect(response.media_type).to eq('text/html')
end
end
+
+ context 'when the ref does not exist' do
+ before do
+ get(:show, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ id: 'unknown.atom'
+ })
+ end
+
+ it 'returns 404 page' do
+ expect(response).to be_not_found
+ end
+ end
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 3ac59d8e43a..88e60a5352a 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -443,7 +443,7 @@ RSpec.describe Projects::MergeRequestsController do
context 'when the merge request is not mergeable' do
before do
- merge_request.update!(title: "WIP: #{merge_request.title}")
+ merge_request.update!(title: "Draft: #{merge_request.title}")
post :merge, params: base_params
end
diff --git a/spec/features/merge_request/user_resolves_wip_mr_spec.rb b/spec/features/merge_request/user_resolves_wip_mr_spec.rb
index fd405855cf8..92927b713f1 100644
--- a/spec/features/merge_request/user_resolves_wip_mr_spec.rb
+++ b/spec/features/merge_request/user_resolves_wip_mr_spec.rb
@@ -2,13 +2,13 @@
require 'spec_helper'
-RSpec.describe 'Merge request > User resolves Work in Progress', :js do
+RSpec.describe 'Merge request > User resolves Draft', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:merge_request) do
create(:merge_request_with_diffs, source_project: project,
author: user,
- title: 'WIP: Bug NS-04',
+ title: 'Draft: Bug NS-04',
merge_params: { force_remove_source_branch: '1' })
end
diff --git a/spec/frontend/cycle_analytics/value_stream_metrics_spec.js b/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
index a3a31ebc387..a2d37699387 100644
--- a/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
+++ b/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
@@ -5,6 +5,8 @@ import metricsData from 'test_fixtures/projects/analytics/value_stream_analytics
import waitForPromises from 'helpers/wait_for_promises';
import { METRIC_TYPE_SUMMARY } from '~/api/analytics_api';
import ValueStreamMetrics from '~/cycle_analytics/components/value_stream_metrics.vue';
+import { METRICS_POPOVER_CONTENT } from '~/cycle_analytics/constants';
+import { prepareTimeMetricsData } from '~/cycle_analytics/utils';
import MetricTile from '~/cycle_analytics/components/metric_tile.vue';
import createFlash from '~/flash';
import { group } from './mock_data';
@@ -14,6 +16,7 @@ jest.mock('~/flash');
describe('ValueStreamMetrics', () => {
let wrapper;
let mockGetValueStreamSummaryMetrics;
+ let mockFilterFn;
const { full_path: requestPath } = group;
const fakeReqName = 'Mock metrics';
@@ -23,12 +26,13 @@ describe('ValueStreamMetrics', () => {
name: fakeReqName,
});
- const createComponent = ({ requestParams = {} } = {}) => {
+ const createComponent = (props = {}) => {
return shallowMount(ValueStreamMetrics, {
propsData: {
requestPath,
- requestParams,
+ requestParams: {},
requests: [metricsRequestFactory()],
+ ...props,
},
});
};
@@ -104,6 +108,35 @@ describe('ValueStreamMetrics', () => {
expect(wrapper.find(GlSkeletonLoading).exists()).toBe(false);
});
+ describe('filterFn', () => {
+ const transferedMetricsData = prepareTimeMetricsData(metricsData, METRICS_POPOVER_CONTENT);
+
+ it('with a filter function, will call the function with the metrics data', async () => {
+ const filteredData = [
+ { identifier: 'issues', value: '3', title: 'New Issues', description: 'foo' },
+ ];
+ mockFilterFn = jest.fn(() => filteredData);
+
+ wrapper = createComponent({
+ filterFn: mockFilterFn,
+ });
+
+ await waitForPromises();
+
+ expect(mockFilterFn).toHaveBeenCalledWith(transferedMetricsData);
+ expect(wrapper.vm.metrics).toEqual(filteredData);
+ });
+
+ it('without a filter function, it will only update the metrics', async () => {
+ wrapper = createComponent();
+
+ await waitForPromises();
+
+ expect(mockFilterFn).not.toHaveBeenCalled();
+ expect(wrapper.vm.metrics).toEqual(transferedMetricsData);
+ });
+ });
+
describe('with additional params', () => {
beforeEach(async () => {
wrapper = createComponent({
diff --git a/spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_charts_spec.js b/spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_charts_spec.js
index 9adc6dba51e..cafb3f231bd 100644
--- a/spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_charts_spec.js
+++ b/spec/frontend/projects/pipelines/charts/components/ci_cd_analytics_charts_spec.js
@@ -1,6 +1,6 @@
-import { GlSegmentedControl } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { GlSegmentedControl } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import CiCdAnalyticsAreaChart from '~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_area_chart.vue';
import CiCdAnalyticsCharts from '~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue';
import { transformedAreaChartData, chartOptions } from '../mock_data';
@@ -29,12 +29,15 @@ const DEFAULT_PROPS = {
describe('~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue', () => {
let wrapper;
- const createWrapper = (props = {}) =>
- shallowMount(CiCdAnalyticsCharts, {
+ const createWrapper = (props = {}, slots = {}) =>
+ shallowMountExtended(CiCdAnalyticsCharts, {
propsData: {
...DEFAULT_PROPS,
...props,
},
+ scopedSlots: {
+ ...slots,
+ },
});
afterEach(() => {
@@ -44,20 +47,20 @@ describe('~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue', (
}
});
- describe('segmented control', () => {
- let segmentedControl;
+ const findMetricsSlot = () => wrapper.findByTestId('metrics-slot');
+ const findSegmentedControl = () => wrapper.findComponent(GlSegmentedControl);
+ describe('segmented control', () => {
beforeEach(() => {
wrapper = createWrapper();
- segmentedControl = wrapper.find(GlSegmentedControl);
});
it('should default to the first chart', () => {
- expect(segmentedControl.props('checked')).toBe(0);
+ expect(findSegmentedControl().props('checked')).toBe(0);
});
it('should use the title and index as values', () => {
- const options = segmentedControl.props('options');
+ const options = findSegmentedControl().props('options');
expect(options).toHaveLength(3);
expect(options).toEqual([
{
@@ -76,7 +79,7 @@ describe('~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue', (
});
it('should select a different chart on change', async () => {
- segmentedControl.vm.$emit('input', 1);
+ findSegmentedControl().vm.$emit('input', 1);
const chart = wrapper.find(CiCdAnalyticsAreaChart);
@@ -91,4 +94,24 @@ describe('~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue', (
wrapper = createWrapper({ charts: [] });
expect(wrapper.find(CiCdAnalyticsAreaChart).exists()).toBe(false);
});
+
+ describe('slots', () => {
+ beforeEach(() => {
+ wrapper = createWrapper(
+ {},
+ {
+ metrics: '<div data-testid="metrics-slot">selected chart: {{props.selectedChart}}</div>',
+ },
+ );
+ });
+
+ it('renders a metrics slot', async () => {
+ const selectedChart = 1;
+ findSegmentedControl().vm.$emit('input', selectedChart);
+
+ await nextTick();
+
+ expect(findMetricsSlot().text()).toBe(`selected chart: ${selectedChart}`);
+ });
+ });
});
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 9b2bb024fa6..13b607452e1 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -209,8 +209,8 @@ RSpec.describe ExtractsPath do
expect(extract_ref_without_atom('release/app/v1.0.0.atom')).to eq('release/app/v1.0.0')
end
- it 'returns nil if there are no matching refs' do
- expect(extract_ref_without_atom('foo.atom')).to eq(nil)
+ it 'raises an error if there are no matching refs' do
+ expect { extract_ref_without_atom('foo.atom') }.to raise_error(ExtractsRef::InvalidPathError)
end
end
end
diff --git a/spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb
deleted file mode 100644
index c4013d002b2..00000000000
--- a/spec/lib/gitlab/background_migration/backfill_legacy_project_repositories_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::BackfillLegacyProjectRepositories do
- it_behaves_like 'backfill migration for project repositories', :legacy
-end
diff --git a/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb
deleted file mode 100644
index ed44b819a97..00000000000
--- a/spec/lib/gitlab/background_migration/backfill_project_updated_at_after_repository_storage_move_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::BackfillProjectUpdatedAtAfterRepositoryStorageMove, :migration, schema: 20210301200959 do
- let(:projects) { table(:projects) }
- let(:project_repository_storage_moves) { table(:project_repository_storage_moves) }
- let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
-
- subject { described_class.new }
-
- describe '#perform' do
- it 'updates project updated_at column if they were moved to a different repository storage' do
- freeze_time do
- project_1 = projects.create!(id: 1, namespace_id: namespace.id, updated_at: 1.day.ago)
- project_2 = projects.create!(id: 2, namespace_id: namespace.id, updated_at: Time.current)
- original_project_3_updated_at = 2.minutes.from_now
- project_3 = projects.create!(id: 3, namespace_id: namespace.id, updated_at: original_project_3_updated_at)
- original_project_4_updated_at = 10.days.ago
- project_4 = projects.create!(id: 4, namespace_id: namespace.id, updated_at: original_project_4_updated_at)
-
- repository_storage_move_1 = project_repository_storage_moves.create!(project_id: project_1.id, updated_at: 2.hours.ago, source_storage_name: 'default', destination_storage_name: 'default')
- repository_storage_move_2 = project_repository_storage_moves.create!(project_id: project_2.id, updated_at: Time.current, source_storage_name: 'default', destination_storage_name: 'default')
- project_repository_storage_moves.create!(project_id: project_3.id, updated_at: Time.current, source_storage_name: 'default', destination_storage_name: 'default')
-
- subject.perform([1, 2, 3, 4, non_existing_record_id])
-
- expect(project_1.reload.updated_at).to eq(repository_storage_move_1.updated_at + 1.second)
- expect(project_2.reload.updated_at).to eq(repository_storage_move_2.updated_at + 1.second)
- expect(project_3.reload.updated_at).to eq(original_project_3_updated_at)
- expect(project_4.reload.updated_at).to eq(original_project_4_updated_at)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
deleted file mode 100644
index 68fe8f39f59..00000000000
--- a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
+++ /dev/null
@@ -1,134 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityFeedback, schema: 20210301200959 do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:users) { table(:users) }
- let(:scanners) { table(:vulnerability_scanners) }
- let(:identifiers) { table(:vulnerability_identifiers) }
- let(:findings) { table(:vulnerability_occurrences) }
- let(:vulnerability_feedback) { table(:vulnerability_feedback) }
-
- let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
- let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') }
- let(:user) { users.create!(username: 'john.doe', projects_limit: 5) }
- let(:scanner) { scanners.create!(project_id: project.id, external_id: 'foo', name: 'bar') }
- let(:identifier) { identifiers.create!(project_id: project.id, fingerprint: 'foo', external_type: 'bar', external_id: 'zoo', name: 'baz') }
- let(:sast_report) { 0 }
- let(:dependency_scanning_report) { 1 }
- let(:dast_report) { 3 }
- let(:secret_detection_report) { 4 }
- let(:project_fingerprint) { Digest::SHA1.hexdigest(SecureRandom.uuid) }
- let(:location_fingerprint_1) { Digest::SHA1.hexdigest(SecureRandom.uuid) }
- let(:location_fingerprint_2) { Digest::SHA1.hexdigest(SecureRandom.uuid) }
- let(:location_fingerprint_3) { Digest::SHA1.hexdigest(SecureRandom.uuid) }
- let(:finding_1) { finding_creator.call(sast_report, location_fingerprint_1) }
- let(:finding_2) { finding_creator.call(dast_report, location_fingerprint_2) }
- let(:finding_3) { finding_creator.call(secret_detection_report, location_fingerprint_3) }
- let(:expected_uuid_1) do
- Security::VulnerabilityUUID.generate(
- report_type: 'sast',
- primary_identifier_fingerprint: identifier.fingerprint,
- location_fingerprint: location_fingerprint_1,
- project_id: project.id
- )
- end
-
- let(:expected_uuid_2) do
- Security::VulnerabilityUUID.generate(
- report_type: 'dast',
- primary_identifier_fingerprint: identifier.fingerprint,
- location_fingerprint: location_fingerprint_2,
- project_id: project.id
- )
- end
-
- let(:expected_uuid_3) do
- Security::VulnerabilityUUID.generate(
- report_type: 'secret_detection',
- primary_identifier_fingerprint: identifier.fingerprint,
- location_fingerprint: location_fingerprint_3,
- project_id: project.id
- )
- end
-
- let(:finding_creator) do
- -> (report_type, location_fingerprint) do
- findings.create!(
- project_id: project.id,
- primary_identifier_id: identifier.id,
- scanner_id: scanner.id,
- report_type: report_type,
- uuid: SecureRandom.uuid,
- name: 'Foo',
- location_fingerprint: Gitlab::Database::ShaAttribute.serialize(location_fingerprint),
- project_fingerprint: Gitlab::Database::ShaAttribute.serialize(project_fingerprint),
- metadata_version: '1',
- severity: 0,
- confidence: 5,
- raw_metadata: '{}'
- )
- end
- end
-
- let(:feedback_creator) do
- -> (category, project_fingerprint) do
- vulnerability_feedback.create!(
- project_id: project.id,
- author_id: user.id,
- feedback_type: 0,
- category: category,
- project_fingerprint: project_fingerprint
- )
- end
- end
-
- let!(:feedback_1) { feedback_creator.call(finding_1.report_type, project_fingerprint) }
- let!(:feedback_2) { feedback_creator.call(finding_2.report_type, project_fingerprint) }
- let!(:feedback_3) { feedback_creator.call(finding_3.report_type, project_fingerprint) }
- let!(:feedback_4) { feedback_creator.call(finding_1.report_type, 'foo') }
- let!(:feedback_5) { feedback_creator.call(dependency_scanning_report, project_fingerprint) }
-
- subject(:populate_finding_uuids) { described_class.new.perform(feedback_1.id, feedback_5.id) }
-
- before do
- allow(Gitlab::BackgroundMigration::Logger).to receive(:info)
- end
-
- describe '#perform' do
- it 'updates the `finding_uuid` attributes of the feedback records' do
- expect { populate_finding_uuids }.to change { feedback_1.reload.finding_uuid }.from(nil).to(expected_uuid_1)
- .and change { feedback_2.reload.finding_uuid }.from(nil).to(expected_uuid_2)
- .and change { feedback_3.reload.finding_uuid }.from(nil).to(expected_uuid_3)
- .and not_change { feedback_4.reload.finding_uuid }
- .and not_change { feedback_5.reload.finding_uuid }
-
- expect(Gitlab::BackgroundMigration::Logger).to have_received(:info).once
- end
-
- it 'preloads the finding and identifier records to prevent N+1 queries' do
- # Load feedback records(1), load findings(2), load identifiers(3) and finally update feedback records one by one(6)
- expect { populate_finding_uuids }.not_to exceed_query_limit(6)
- end
-
- context 'when setting the `finding_uuid` attribute of a feedback record fails' do
- let(:expected_error) { RuntimeError.new }
-
- before do
- allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
-
- allow_next_found_instance_of(described_class::VulnerabilityFeedback) do |feedback|
- allow(feedback).to receive(:update_column).and_raise(expected_error)
- end
- end
-
- it 'captures the errors and does not crash entirely' do
- expect { populate_finding_uuids }.not_to raise_error
-
- expect(Gitlab::ErrorTracking).to have_received(:track_and_raise_for_dev_exception).with(expected_error).exactly(3).times
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb b/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
deleted file mode 100644
index b00eb185b34..00000000000
--- a/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::PopulateIssueEmailParticipants, schema: 20210301200959 do
- let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
- let!(:project) { table(:projects).create!(id: 1, namespace_id: namespace.id) }
- let!(:issue1) { table(:issues).create!(id: 1, project_id: project.id, service_desk_reply_to: "a@gitlab.com") }
- let!(:issue2) { table(:issues).create!(id: 2, project_id: project.id, service_desk_reply_to: "b@gitlab.com") }
- let(:issue_email_participants) { table(:issue_email_participants) }
-
- describe '#perform' do
- it 'migrates email addresses from service desk issues', :aggregate_failures do
- expect { subject.perform(1, 2) }.to change { issue_email_participants.count }.by(2)
-
- expect(issue_email_participants.find_by(issue_id: 1).email).to eq("a@gitlab.com")
- expect(issue_email_participants.find_by(issue_id: 2).email).to eq("b@gitlab.com")
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb b/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
deleted file mode 100644
index 17fe25c7f71..00000000000
--- a/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::WrongfullyConfirmedEmailUnconfirmer, schema: 20210301200959 do
- let(:users) { table(:users) }
- let(:emails) { table(:emails) }
- let(:user_synced_attributes_metadata) { table(:user_synced_attributes_metadata) }
- let(:confirmed_at_2_days_ago) { 2.days.ago }
- let(:confirmed_at_3_days_ago) { 3.days.ago }
- let(:one_year_ago) { 1.year.ago }
-
- let!(:user_needs_migration_1) { users.create!(name: 'user1', email: 'test1@test.com', state: 'active', projects_limit: 1, confirmed_at: confirmed_at_2_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:user_needs_migration_2) { users.create!(name: 'user2', email: 'test2@test.com', unconfirmed_email: 'unconfirmed@test.com', state: 'active', projects_limit: 1, confirmed_at: confirmed_at_3_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:user_does_not_need_migration) { users.create!(name: 'user3', email: 'test3@test.com', state: 'active', projects_limit: 1) }
- let!(:inactive_user) { users.create!(name: 'user4', email: 'test4@test.com', state: 'blocked', projects_limit: 1, confirmed_at: confirmed_at_3_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:alert_bot_user) { users.create!(name: 'user5', email: 'test5@test.com', state: 'active', user_type: 2, projects_limit: 1, confirmed_at: confirmed_at_3_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:user_has_synced_email) { users.create!(name: 'user6', email: 'test6@test.com', state: 'active', projects_limit: 1, confirmed_at: confirmed_at_2_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:synced_attributes_metadata_for_user) { user_synced_attributes_metadata.create!(user_id: user_has_synced_email.id, email_synced: true) }
-
- let!(:bad_email_1) { emails.create!(user_id: user_needs_migration_1.id, email: 'other1@test.com', confirmed_at: confirmed_at_2_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:bad_email_2) { emails.create!(user_id: user_needs_migration_2.id, email: 'other2@test.com', confirmed_at: confirmed_at_3_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:bad_email_3_inactive_user) { emails.create!(user_id: inactive_user.id, email: 'other-inactive@test.com', confirmed_at: confirmed_at_3_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:bad_email_4_bot_user) { emails.create!(user_id: alert_bot_user.id, email: 'other-bot@test.com', confirmed_at: confirmed_at_3_days_ago, confirmation_sent_at: one_year_ago) }
-
- let!(:good_email_1) { emails.create!(user_id: user_needs_migration_2.id, email: 'other3@test.com', confirmed_at: confirmed_at_2_days_ago, confirmation_sent_at: one_year_ago) }
- let!(:good_email_2) { emails.create!(user_id: user_needs_migration_2.id, email: 'other4@test.com', confirmed_at: nil) }
- let!(:good_email_3) { emails.create!(user_id: user_does_not_need_migration.id, email: 'other5@test.com', confirmed_at: confirmed_at_2_days_ago, confirmation_sent_at: one_year_ago) }
-
- let!(:second_email_for_user_with_synced_email) { emails.create!(user_id: user_has_synced_email.id, email: 'other6@test.com', confirmed_at: confirmed_at_2_days_ago, confirmation_sent_at: one_year_ago) }
-
- subject do
- email_ids = [bad_email_1, bad_email_2, good_email_1, good_email_2, good_email_3, second_email_for_user_with_synced_email].map(&:id)
-
- described_class.new.perform(email_ids.min, email_ids.max)
- end
-
- it 'does not change irrelevant email records' do
- subject
-
- expect(good_email_1.reload.confirmed_at).to be_within(1.second).of(confirmed_at_2_days_ago)
- expect(good_email_2.reload.confirmed_at).to be_nil
- expect(good_email_3.reload.confirmed_at).to be_within(1.second).of(confirmed_at_2_days_ago)
-
- expect(bad_email_3_inactive_user.reload.confirmed_at).to be_within(1.second).of(confirmed_at_3_days_ago)
- expect(bad_email_4_bot_user.reload.confirmed_at).to be_within(1.second).of(confirmed_at_3_days_ago)
-
- expect(good_email_1.reload.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
- expect(good_email_2.reload.confirmation_sent_at).to be_nil
- expect(good_email_3.reload.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
-
- expect(bad_email_3_inactive_user.reload.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
- expect(bad_email_4_bot_user.reload.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
- end
-
- it 'clears the `unconfirmed_email` field' do
- subject
-
- user_needs_migration_2.reload
- expect(user_needs_migration_2.unconfirmed_email).to be_nil
- end
-
- it 'does not change irrelevant user records' do
- subject
-
- expect(user_does_not_need_migration.reload.confirmed_at).to be_nil
- expect(inactive_user.reload.confirmed_at).to be_within(1.second).of(confirmed_at_3_days_ago)
- expect(alert_bot_user.reload.confirmed_at).to be_within(1.second).of(confirmed_at_3_days_ago)
- expect(user_has_synced_email.reload.confirmed_at).to be_within(1.second).of(confirmed_at_2_days_ago)
-
- expect(user_does_not_need_migration.reload.confirmation_sent_at).to be_nil
- expect(inactive_user.reload.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
- expect(alert_bot_user.reload.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
- expect(user_has_synced_email.confirmation_sent_at).to be_within(1.second).of(one_year_ago)
- end
-
- it 'updates confirmation_sent_at column' do
- subject
-
- expect(user_needs_migration_1.reload.confirmation_sent_at).to be_within(1.minute).of(Time.now)
- expect(user_needs_migration_2.reload.confirmation_sent_at).to be_within(1.minute).of(Time.now)
-
- expect(bad_email_1.reload.confirmation_sent_at).to be_within(1.minute).of(Time.now)
- expect(bad_email_2.reload.confirmation_sent_at).to be_within(1.minute).of(Time.now)
- end
-
- it 'unconfirms bad email records' do
- subject
-
- expect(bad_email_1.reload.confirmed_at).to be_nil
- expect(bad_email_2.reload.confirmed_at).to be_nil
-
- expect(bad_email_1.reload.confirmation_token).not_to be_nil
- expect(bad_email_2.reload.confirmation_token).not_to be_nil
- end
-
- it 'unconfirms user records' do
- subject
-
- expect(user_needs_migration_1.reload.confirmed_at).to be_nil
- expect(user_needs_migration_2.reload.confirmed_at).to be_nil
-
- expect(user_needs_migration_1.reload.confirmation_token).not_to be_nil
- expect(user_needs_migration_2.reload.confirmation_token).not_to be_nil
- end
-
- context 'enqueued jobs' do
- let(:user_1) { User.find(user_needs_migration_1.id) }
- let(:user_2) { User.find(user_needs_migration_2.id) }
-
- let(:email_1) { Email.find(bad_email_1.id) }
- let(:email_2) { Email.find(bad_email_2.id) }
-
- it 'enqueues the email confirmation and the unconfirm notification mailer jobs' do
- allow(DeviseMailer).to receive(:confirmation_instructions).and_call_original
- allow(Gitlab::BackgroundMigration::Mailers::UnconfirmMailer).to receive(:unconfirm_notification_email).and_call_original
-
- subject
-
- expect(DeviseMailer).to have_received(:confirmation_instructions).with(email_1, email_1.confirmation_token)
- expect(DeviseMailer).to have_received(:confirmation_instructions).with(email_2, email_2.confirmation_token)
-
- expect(Gitlab::BackgroundMigration::Mailers::UnconfirmMailer).to have_received(:unconfirm_notification_email).with(user_1)
- expect(DeviseMailer).to have_received(:confirmation_instructions).with(user_1, user_1.confirmation_token)
-
- expect(Gitlab::BackgroundMigration::Mailers::UnconfirmMailer).to have_received(:unconfirm_notification_email).with(user_2)
- expect(DeviseMailer).to have_received(:confirmation_instructions).with(user_2, user_2.confirmation_token)
- end
- end
-end
diff --git a/spec/lib/gitlab/database/migrations/instrumentation_spec.rb b/spec/lib/gitlab/database/migrations/instrumentation_spec.rb
index 902d8e13a63..fd8303c379c 100644
--- a/spec/lib/gitlab/database/migrations/instrumentation_spec.rb
+++ b/spec/lib/gitlab/database/migrations/instrumentation_spec.rb
@@ -66,55 +66,43 @@ RSpec.describe Gitlab::Database::Migrations::Instrumentation do
context 'on successful execution' do
subject { described_class.new(result_dir: result_dir).observe(version: migration_version, name: migration_name, connection: connection) {} }
- it 'records walltime' do
+ it 'records a valid observation', :aggregate_failures do
expect(subject.walltime).not_to be_nil
- end
-
- it 'records success' do
expect(subject.success).to be_truthy
- end
-
- it 'records the migration version' do
expect(subject.version).to eq(migration_version)
- end
-
- it 'records the migration name' do
expect(subject.name).to eq(migration_name)
end
end
context 'upon failure' do
- subject { described_class.new(result_dir: result_dir).observe(version: migration_version, name: migration_name, connection: connection) { raise 'something went wrong' } }
-
- it 'raises the exception' do
- expect { subject }.to raise_error(/something went wrong/)
- end
-
- context 'retrieving observations' do
- subject { instance.observations.first }
-
- before do
- instance.observe(version: migration_version, name: migration_name, connection: connection) { raise 'something went wrong' }
- rescue StandardError
- # ignore
- end
+ where(exception: ['something went wrong', SystemStackError, Interrupt])
+ with_them do
let(:instance) { described_class.new(result_dir: result_dir) }
- it 'records walltime' do
- expect(subject.walltime).not_to be_nil
- end
-
- it 'records failure' do
- expect(subject.success).to be_falsey
- end
+ subject(:observe) { instance.observe(version: migration_version, name: migration_name, connection: connection) { raise exception } }
- it 'records the migration version' do
- expect(subject.version).to eq(migration_version)
+ it 'raises the exception' do
+ expect { observe }.to raise_error(exception)
end
- it 'records the migration name' do
- expect(subject.name).to eq(migration_name)
+ context 'retrieving observations' do
+ subject { instance.observations.first }
+
+ before do
+ observe
+ # rubocop:disable Lint/RescueException
+ rescue Exception
+ # rubocop:enable Lint/RescueException
+ # ignore (we expect this exception)
+ end
+
+ it 'records a valid observation', :aggregate_failures do
+ expect(subject.walltime).not_to be_nil
+ expect(subject.success).to be_falsey
+ expect(subject.version).to eq(migration_version)
+ expect(subject.name).to eq(migration_name)
+ end
end
end
end
diff --git a/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb b/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb
index 5a19ae6581d..a757cac0a2a 100644
--- a/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb
+++ b/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe Gitlab::Database::Migrations::Observers::QueryDetails do
subject { described_class.new(observation, directory_path, connection) }
let(:connection) { ActiveRecord::Migration.connection }
- let(:observation) { Gitlab::Database::Migrations::Observation.new(migration_version, migration_name) }
+ let(:observation) { Gitlab::Database::Migrations::Observation.new(version: migration_version, name: migration_name) }
let(:query) { "select date_trunc('day', $1::timestamptz) + $2 * (interval '1 hour')" }
let(:query_binds) { [Time.current, 3] }
let(:directory_path) { Dir.mktmpdir }
diff --git a/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb b/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb
index 7b01e39f5f1..eb66972e5ab 100644
--- a/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb
+++ b/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::Migrations::Observers::QueryLog do
subject { described_class.new(observation, directory_path, connection) }
- let(:observation) { Gitlab::Database::Migrations::Observation.new(migration_version, migration_name) }
+ let(:observation) { Gitlab::Database::Migrations::Observation.new(version: migration_version, name: migration_name) }
let(:connection) { ActiveRecord::Migration.connection }
let(:query) { 'select 1' }
let(:directory_path) { Dir.mktmpdir }
diff --git a/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb b/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb
index b26bb8fbe41..f433e25b2ba 100644
--- a/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb
+++ b/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe Gitlab::Database::Migrations::Observers::TransactionDuration do
subject(:transaction_duration_observer) { described_class.new(observation, directory_path, connection) }
let(:connection) { ActiveRecord::Migration.connection }
- let(:observation) { Gitlab::Database::Migrations::Observation.new(migration_version, migration_name) }
+ let(:observation) { Gitlab::Database::Migrations::Observation.new(version: migration_version, name: migration_name) }
let(:directory_path) { Dir.mktmpdir }
let(:log_file) { "#{directory_path}/#{migration_version}_#{migration_name}-transaction-duration.json" }
let(:transaction_duration) { Gitlab::Json.parse(File.read(log_file)) }
diff --git a/spec/lib/gitlab/github_import/importer/releases_importer_spec.rb b/spec/lib/gitlab/github_import/importer/releases_importer_spec.rb
index 1a25824bc8a..6b3d18f20e9 100644
--- a/spec/lib/gitlab/github_import/importer/releases_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/releases_importer_spec.rb
@@ -52,6 +52,12 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
expect { importer.execute }.to change { Release.count }.by(1)
end
+
+ it 'is idempotent' do
+ allow(importer).to receive(:each_release).and_return([github_release])
+ expect { importer.execute }.to change { Release.count }.by(1)
+ expect { importer.execute }.to change { Release.count }.by(0) # Idempotency check
+ end
end
describe '#build_releases' do
@@ -79,6 +85,24 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
expect(release[:description]).to eq('Release for tag 1.0')
end
+
+ it 'does not create releases that have a NULL tag' do
+ null_tag_release = double(
+ name: 'NULL Test',
+ tag_name: nil
+ )
+
+ expect(importer).to receive(:each_release).and_return([null_tag_release])
+ expect(importer.build_releases).to be_empty
+ end
+
+ it 'does not create duplicate release tags' do
+ expect(importer).to receive(:each_release).and_return([github_release, github_release])
+
+ releases = importer.build_releases
+ expect(releases.length).to eq(1)
+ expect(releases[0][:description]).to eq('This is my release')
+ end
end
describe '#build' do
diff --git a/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
index 73b35d3a4e7..cbd1a30c417 100644
--- a/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
@@ -63,5 +63,13 @@ RSpec.describe Gitlab::LegacyGithubImport::ReleaseFormatter do
expect(release.valid?).to eq false
end
end
+
+ context 'when release has NULL tag' do
+ let(:raw_data) { double(base_data.merge(tag_name: '')) }
+
+ it 'returns false' do
+ expect(release.valid?).to eq false
+ end
+ end
end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 9da22e15a12..e1f3b36a2ba 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1369,17 +1369,17 @@ RSpec.describe MergeRequest, factory_default: :keep do
subject { build_stubbed(:merge_request) }
[
- 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', ' [WIP] WIP: [WIP] WIP:',
'draft:', 'Draft: ', '[Draft]', '[DRAFT] '
- ].each do |wip_prefix|
- it "detects the '#{wip_prefix}' prefix" do
- subject.title = "#{wip_prefix}#{subject.title}"
+ ].each do |draft_prefix|
+ it "detects the '#{draft_prefix}' prefix" do
+ subject.title = "#{draft_prefix}#{subject.title}"
expect(subject.work_in_progress?).to eq true
end
end
[
+ 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', ' [WIP] WIP: [WIP] WIP:',
"WIP ", "(WIP)",
"draft", "Draft", "Draft -", "draft - ", "Draft ", "draft "
].each do |draft_prefix|
@@ -1390,10 +1390,10 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
- it "detects merge request title just saying 'wip'" do
+ it "doesn't detect merge request title just saying 'wip'" do
subject.title = "wip"
- expect(subject.work_in_progress?).to eq true
+ expect(subject.work_in_progress?).to eq false
end
it "does not detect merge request title just saying 'draft'" do
@@ -1459,29 +1459,30 @@ RSpec.describe MergeRequest, factory_default: :keep do
describe "#wipless_title" do
subject { build_stubbed(:merge_request) }
- [
- 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', '[WIP] WIP: [WIP] WIP:',
- 'draft:', 'Draft: ', '[Draft]', '[DRAFT] '
- ].each do |wip_prefix|
- it "removes the '#{wip_prefix}' prefix" do
+ ['draft:', 'Draft: ', '[Draft]', '[DRAFT] '].each do |draft_prefix|
+ it "removes a '#{draft_prefix}' prefix" do
wipless_title = subject.title
- subject.title = "#{wip_prefix}#{subject.title}"
+ subject.title = "#{draft_prefix}#{subject.title}"
expect(subject.wipless_title).to eq wipless_title
end
it "is satisfies the #work_in_progress? method" do
- subject.title = "#{wip_prefix}#{subject.title}"
+ subject.title = "#{draft_prefix}#{subject.title}"
subject.title = subject.wipless_title
expect(subject.work_in_progress?).to eq false
end
end
- it 'removes only WIP prefix from the MR title' do
- subject.title = 'WIP: Implement feature called WIP'
+ [
+ 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', '[WIP] WIP: [WIP] WIP:'
+ ].each do |wip_prefix|
+ it "doesn't remove a '#{wip_prefix}' prefix" do
+ subject.title = "#{wip_prefix}#{subject.title}"
- expect(subject.wipless_title).to eq 'Implement feature called WIP'
+ expect(subject.wipless_title).to eq subject.title
+ end
end
it 'removes only draft prefix from the MR title' do
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index da547716e1e..a196c944eda 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -61,19 +61,19 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
expect(merge_request.reload).to be_preparing
end
- describe 'when marked with /wip' do
+ describe 'when marked with /draft' do
context 'in title and in description' do
let(:opts) do
{
- title: 'WIP: Awesome merge_request',
- description: "well this is not done yet\n/wip",
+ title: 'Draft: Awesome merge_request',
+ description: "well this is not done yet\n/draft",
source_branch: 'feature',
target_branch: 'master',
assignees: [user2]
}
end
- it 'sets MR to WIP' do
+ it 'sets MR to draft' do
expect(merge_request.work_in_progress?).to be(true)
end
end
@@ -89,7 +89,7 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
}
end
- it 'sets MR to WIP' do
+ it 'sets MR to draft' do
expect(merge_request.work_in_progress?).to be(true)
end
end
diff --git a/spec/services/merge_requests/mergeability_check_service_spec.rb b/spec/services/merge_requests/mergeability_check_service_spec.rb
index 65599b7e046..c24b83e21a6 100644
--- a/spec/services/merge_requests/mergeability_check_service_spec.rb
+++ b/spec/services/merge_requests/mergeability_check_service_spec.rb
@@ -73,12 +73,10 @@ RSpec.describe MergeRequests::MergeabilityCheckService, :clean_gitlab_redis_shar
let(:merge_request) { create(:merge_request, merge_status: :unchecked, source_project: project, target_project: project) }
describe '#async_execute' do
- shared_examples_for 'no job is enqueued' do
- it 'does not enqueue MergeRequestMergeabilityCheckWorker' do
- expect(MergeRequestMergeabilityCheckWorker).not_to receive(:perform_async)
+ it 'updates merge status to checking' do
+ described_class.new(merge_request).async_execute
- described_class.new(merge_request).async_execute
- end
+ expect(merge_request).to be_checking
end
it 'enqueues MergeRequestMergeabilityCheckWorker' do
@@ -92,15 +90,11 @@ RSpec.describe MergeRequests::MergeabilityCheckService, :clean_gitlab_redis_shar
allow(Gitlab::Database).to receive(:read_only?) { true }
end
- it_behaves_like 'no job is enqueued'
- end
+ it 'does not enqueue MergeRequestMergeabilityCheckWorker' do
+ expect(MergeRequestMergeabilityCheckWorker).not_to receive(:perform_async)
- context 'when merge_status is already checking' do
- before do
- merge_request.mark_as_checking
+ described_class.new(merge_request).async_execute
end
-
- it_behaves_like 'no job is enqueued'
end
end
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 2925dad7f6b..48d9f019274 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -102,16 +102,16 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
MergeRequests::UpdateService.new(project: project, current_user: user, params: opts).execute(merge_request2)
end
- it 'tracks Draft/WIP marking' do
+ it 'tracks Draft marking' do
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_marked_as_draft_action).once.with(user: user)
- opts[:title] = "WIP: #{opts[:title]}"
+ opts[:title] = "Draft: #{opts[:title]}"
MergeRequests::UpdateService.new(project: project, current_user: user, params: opts).execute(merge_request2)
end
- it 'tracks Draft/WIP un-marking' do
+ it 'tracks Draft un-marking' do
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_unmarked_as_draft_action).once.with(user: user)
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index 1fb50b07b3b..babbd44a9f1 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -325,11 +325,11 @@ RSpec.describe Notes::CreateService do
expect(issuable.work_in_progress?).to eq(can_use_quick_action)
}
),
- # Remove WIP status
+ # Remove draft status
QuickAction.new(
action_text: "/draft",
before_action: -> {
- issuable.reload.update!(title: "WIP: title")
+ issuable.reload.update!(title: "Draft: title")
},
expectation: ->(noteable, can_use_quick_action) {
expect(noteable.work_in_progress?).not_to eq(can_use_quick_action)