diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-05 15:13:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-05 15:13:17 +0300 |
commit | cd17aa65132de074aab9ae50ab7bbf7f16428546 (patch) | |
tree | 5a195a869320321aa9c3891e7ba5bbc9b9fc5d87 /spec | |
parent | 508f0c4ee719abb1294684eea4a63aa44cd23597 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
22 files changed, 352 insertions, 493 deletions
diff --git a/spec/factories/member_roles.rb b/spec/factories/member_roles.rb deleted file mode 100644 index 503438d2521..00000000000 --- a/spec/factories/member_roles.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :member_role do - namespace { association(:group) } - base_access_level { Gitlab::Access::DEVELOPER } - - trait(:developer) { base_access_level { Gitlab::Access::DEVELOPER } } - trait(:guest) { base_access_level { Gitlab::Access::GUEST } } - end -end diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb index 24e47dc43ae..da985c6dc07 100644 --- a/spec/features/dashboard/snippets_spec.rb +++ b/spec/features/dashboard/snippets_spec.rb @@ -44,7 +44,8 @@ RSpec.describe 'Dashboard snippets', feature_category: :source_code_management d element = page.find('.row.empty-state') expect(element).to have_content("Code snippets") - expect(element.find('.svg-content img.js-lazy-loaded')['src']).to have_content('illustrations/snippets_empty') + expect(element.find('.svg-content img.js-lazy-loaded')['src']) + .to have_content('illustrations/empty-state/empty-snippets-md') end it 'shows new snippet button in main content area' do diff --git a/spec/frontend/groups/components/empty_states/archived_projects_empty_state_spec.js b/spec/frontend/groups/components/empty_states/archived_projects_empty_state_spec.js index be61ffa92b4..bb3c0bc1526 100644 --- a/spec/frontend/groups/components/empty_states/archived_projects_empty_state_spec.js +++ b/spec/frontend/groups/components/empty_states/archived_projects_empty_state_spec.js @@ -6,7 +6,7 @@ import ArchivedProjectsEmptyState from '~/groups/components/empty_states/archive let wrapper; const defaultProvide = { - newProjectIllustration: '/assets/illustrations/project-create-new-sm.svg', + emptyProjectsIllustration: '/assets/llustrations/empty-state/empty-projects-md.svg', }; const createComponent = () => { @@ -21,7 +21,7 @@ describe('ArchivedProjectsEmptyState', () => { expect(wrapper.findComponent(GlEmptyState).props()).toMatchObject({ title: ArchivedProjectsEmptyState.i18n.title, - svgPath: defaultProvide.newProjectIllustration, + svgPath: defaultProvide.emptyProjectsIllustration, }); }); }); diff --git a/spec/frontend/groups/components/empty_states/shared_projects_empty_state_spec.js b/spec/frontend/groups/components/empty_states/shared_projects_empty_state_spec.js index c4ace1be1f3..8ba1c480d5e 100644 --- a/spec/frontend/groups/components/empty_states/shared_projects_empty_state_spec.js +++ b/spec/frontend/groups/components/empty_states/shared_projects_empty_state_spec.js @@ -6,7 +6,7 @@ import SharedProjectsEmptyState from '~/groups/components/empty_states/shared_pr let wrapper; const defaultProvide = { - newProjectIllustration: '/assets/illustrations/project-create-new-sm.svg', + emptyProjectsIllustration: '/assets/illustrations/empty-state/empty-projects-md.svg', }; const createComponent = () => { @@ -21,7 +21,7 @@ describe('SharedProjectsEmptyState', () => { expect(wrapper.findComponent(GlEmptyState).props()).toMatchObject({ title: SharedProjectsEmptyState.i18n.title, - svgPath: defaultProvide.newProjectIllustration, + svgPath: defaultProvide.emptyProjectsIllustration, }); }); }); diff --git a/spec/frontend/groups/components/empty_states/subgroups_and_projects_empty_state_spec.js b/spec/frontend/groups/components/empty_states/subgroups_and_projects_empty_state_spec.js index dc4271b98ee..5ae4d0be7d6 100644 --- a/spec/frontend/groups/components/empty_states/subgroups_and_projects_empty_state_spec.js +++ b/spec/frontend/groups/components/empty_states/subgroups_and_projects_empty_state_spec.js @@ -10,6 +10,7 @@ const defaultProvide = { newProjectPath: '/projects/new?namespace_id=231', newSubgroupIllustration: '/assets/illustrations/group-new.svg', newSubgroupPath: '/groups/new?parent_id=231', + emptyProjectsIllustration: '/assets/illustrations/empty-state/empty-projects-md.svg', emptySubgroupIllustration: '/assets/illustrations/empty-state/empty-subgroup-md.svg', canCreateSubgroups: true, canCreateProjects: true, diff --git a/spec/frontend/groups/components/overview_tabs_spec.js b/spec/frontend/groups/components/overview_tabs_spec.js index 906609c97f9..101dd06d578 100644 --- a/spec/frontend/groups/components/overview_tabs_spec.js +++ b/spec/frontend/groups/components/overview_tabs_spec.js @@ -39,6 +39,7 @@ describe('OverviewTabs', () => { newProjectPath: 'projects/new', newSubgroupIllustration: '', newProjectIllustration: '', + emptyProjectsIllustration: '', emptySubgroupIllustration: '', canCreateSubgroups: false, canCreateProjects: false, diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index bb1a4d57cc0..00d5308d552 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -706,4 +706,27 @@ RSpec.describe ApplicationHelper do expect(helper.stylesheet_link_tag_defer('test')).to eq( '<link rel="stylesheet" media="screen" href="/stylesheets/test.css" />') end end + + describe 'sign_in_with_redirect?' do + context 'when on the sign-in page that redirects afterwards' do + before do + allow(helper).to receive(:current_page?).and_return(true) + session[:user_return_to] = true + end + + it 'returns true' do + expect(helper.sign_in_with_redirect?).to be_truthy + end + end + + context 'when on a non sign-in page' do + before do + allow(helper).to receive(:current_page?).and_return(false) + end + + it 'returns false' do + expect(helper.sign_in_with_redirect?).to be_falsey + end + end + end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index ce439e5bcdd..f66f9a8a58e 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -497,6 +497,7 @@ RSpec.describe GroupsHelper do new_project_path: including("/projects/new?namespace_id=#{group.id}"), new_subgroup_illustration: including('illustrations/subgroup-create-new-sm'), new_project_illustration: including('illustrations/project-create-new-sm'), + empty_projects_illustration: including('illustrations/empty-state/empty-projects-md'), empty_subgroup_illustration: including('illustrations/empty-state/empty-subgroup-md'), render_empty_state: 'true', can_create_subgroups: 'true', diff --git a/spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb b/spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb deleted file mode 100644 index deddc7f5294..00000000000 --- a/spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Auth::U2fWebauthnConverter do - let_it_be(:u2f_registration) do - device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5)) - create(:u2f_registration, name: 'u2f_device', - certificate: Base64.strict_encode64(device.cert_raw), - key_handle: U2F.urlsafe_encode64(device.key_handle_raw), - public_key: Base64.strict_encode64(device.origin_public_key_raw)) - end - - it 'converts u2f registration' do - webauthn_credential = WebAuthn::U2fMigrator.new( - app_id: Gitlab.config.gitlab.url, - certificate: u2f_registration.certificate, - key_handle: u2f_registration.key_handle, - public_key: u2f_registration.public_key, - counter: u2f_registration.counter - ).credential - - converted_webauthn = described_class.new(u2f_registration).convert - - expect(converted_webauthn).to( - include(user_id: u2f_registration.user_id, - credential_xid: Base64.strict_encode64(webauthn_credential.id))) - end -end diff --git a/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb b/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb deleted file mode 100644 index 6554ee9d7b5..00000000000 --- a/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require 'webauthn/u2f_migrator' - -RSpec.describe Gitlab::BackgroundMigration::MigrateU2fWebauthn, :migration, schema: 20211202041233 do - let(:users) { table(:users) } - - let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) } - - let(:u2f_registrations) { table(:u2f_registrations) } - let(:webauthn_registrations) { table(:webauthn_registrations) } - - let!(:u2f_registration_not_migrated) { create_u2f_registration(1, 'reg1') } - let!(:u2f_registration_not_migrated_no_name) { create_u2f_registration(2, nil, 2) } - let!(:u2f_registration_migrated) { create_u2f_registration(3, 'reg3') } - - subject { described_class.new.perform(1, 3) } - - before do - converted_credential = convert_credential_for(u2f_registration_migrated) - webauthn_registrations.create!(converted_credential) - end - - it 'migrates all records' do - expect { subject }.to change { webauthn_registrations.count }.from(1).to(3) - - all_webauthn_registrations = webauthn_registrations.all.map(&:attributes) - - [u2f_registration_not_migrated, u2f_registration_not_migrated_no_name].each do |u2f_registration| - expected_credential = convert_credential_for(u2f_registration).except(:created_at).stringify_keys - expect(all_webauthn_registrations).to include(a_hash_including(expected_credential)) - end - end - - def create_u2f_registration(id, name, counter = 5) - device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5)) - u2f_registrations.create!({ id: id, - certificate: Base64.strict_encode64(device.cert_raw), - key_handle: U2F.urlsafe_encode64(device.key_handle_raw), - public_key: Base64.strict_encode64(device.origin_public_key_raw), - counter: counter, - name: name, - user_id: user.id }) - end - - def convert_credential_for(u2f_registration) - converted_credential = WebAuthn::U2fMigrator.new( - app_id: Gitlab.config.gitlab.url, - certificate: u2f_registration.certificate, - key_handle: u2f_registration.key_handle, - public_key: u2f_registration.public_key, - counter: u2f_registration.counter - ).credential - - { - credential_xid: Base64.strict_encode64(converted_credential.id), - public_key: Base64.strict_encode64(converted_credential.public_key), - counter: u2f_registration.counter, - name: u2f_registration.name || '', - user_id: u2f_registration.user_id, - u2f_registration_id: u2f_registration.id, - created_at: u2f_registration.created_at - } - end -end diff --git a/spec/lib/gitlab/tracking/destinations/database_events_snowplow_spec.rb b/spec/lib/gitlab/tracking/destinations/database_events_snowplow_spec.rb new file mode 100644 index 00000000000..0f2082c1f25 --- /dev/null +++ b/spec/lib/gitlab/tracking/destinations/database_events_snowplow_spec.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Tracking::Destinations::DatabaseEventsSnowplow, :do_not_stub_snowplow_by_default, feature_category: :application_instrumentation do + let(:emitter) { SnowplowTracker::Emitter.new(endpoint: 'localhost', options: { buffer_size: 1 }) } + + let(:tracker) do + SnowplowTracker::Tracker + .new( + emitters: [emitter], + subject: SnowplowTracker::Subject.new, + namespace: 'namespace', + app_id: 'app_id' + ) + end + + before do + stub_application_setting(snowplow_app_id: '_abc123_') + end + + around do |example| + freeze_time { example.run } + end + + context 'when snowplow is enabled' do + before do + allow(SnowplowTracker::AsyncEmitter) + .to receive(:new) + .with(endpoint: 'localhost:9091', + options: + { + protocol: 'https', + on_success: subject.method(:increment_successful_events_emissions), + on_failure: subject.method(:failure_callback) + } + ).and_return(emitter) + + allow(SnowplowTracker::Tracker) + .to receive(:new) + .with( + emitters: [emitter], + subject: an_instance_of(SnowplowTracker::Subject), + namespace: described_class::SNOWPLOW_NAMESPACE, + app_id: '_abc123_' + ).and_return(tracker) + end + + describe '#event' do + it 'sends event to tracker' do + allow(tracker).to receive(:track_struct_event).and_call_original + + subject.event('category', 'action', label: 'label', property: 'property', value: 1.5) + + expect(tracker) + .to have_received(:track_struct_event) + .with(category: 'category', action: 'action', label: 'label', property: 'property', value: 1.5, context: nil, + tstamp: (Time.now.to_f * 1000).to_i) + end + + it 'increase total snowplow events counter' do + counter = double + + expect(counter).to receive(:increment) + expect(Gitlab::Metrics).to receive(:counter) + .with(:gitlab_db_events_snowplow_events_total, 'Number of Snowplow events') + .and_return(counter) + + subject.event('category', 'action', label: 'label', property: 'property', value: 1.5) + end + end + end + + context 'for callbacks' do + describe 'on success' do + it 'increase gitlab_successful_snowplow_events_total counter' do + counter = double + + expect(counter).to receive(:increment).with({}, 2) + expect(Gitlab::Metrics).to receive(:counter) + .with( + :gitlab_db_events_snowplow_successful_events_total, + 'Number of successful Snowplow events emissions').and_return(counter) + + subject.method(:increment_successful_events_emissions).call(2) + end + end + + describe 'on failure' do + it 'increase gitlab_failed_snowplow_events_total counter and logs failures', :aggregate_failures do + counter = double + error_message = "Issue database_event_update failed to be reported to collector at localhost:9091" + failures = [{ "e" => "se", + "se_ca" => "Issue", + "se_la" => "issues", + "se_ac" => "database_event_update" }] + allow(Gitlab::Metrics).to receive(:counter) + .with( + :gitlab_db_events_snowplow_successful_events_total, + 'Number of successful Snowplow events emissions').and_call_original + + expect(Gitlab::AppLogger).to receive(:error).with(error_message) + expect(counter).to receive(:increment).with({}, 1) + expect(Gitlab::Metrics).to receive(:counter) + .with( + :gitlab_db_events_snowplow_failed_events_total, + 'Number of failed Snowplow events emissions').and_return(counter) + + subject.method(:failure_callback).call(2, failures) + end + end + end +end diff --git a/spec/lib/gitlab/tracking_spec.rb b/spec/lib/gitlab/tracking_spec.rb index e79bb2ef129..56be80678e9 100644 --- a/spec/lib/gitlab/tracking_spec.rb +++ b/spec/lib/gitlab/tracking_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -RSpec.describe Gitlab::Tracking do +RSpec.describe Gitlab::Tracking, feature_category: :application_instrumentation do include StubENV before do @@ -102,12 +102,28 @@ RSpec.describe Gitlab::Tracking do end end - describe '.event' do + context 'event tracking' do let(:namespace) { create(:namespace) } - shared_examples 'delegates to destination' do |klass| + shared_examples 'rescued error raised by destination class' do + it 'rescues error' do + error = StandardError.new("something went wrong") + allow_any_instance_of(destination_class).to receive(:event).and_raise(error) + + expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception) + .with( + error, + snowplow_category: category, + snowplow_action: action + ) + + expect { tracking_method }.not_to raise_error + end + end + + shared_examples 'delegates to destination' do |klass, method| before do - allow_any_instance_of(Gitlab::Tracking::Destinations::Snowplow).to receive(:event) + allow_any_instance_of(klass).to receive(:event) end it "delegates to #{klass} destination" do @@ -118,8 +134,8 @@ RSpec.describe Gitlab::Tracking do expect(Gitlab::Tracking::StandardContext) .to receive(:new) - .with(project: project, user: user, namespace: namespace, extra_key_1: 'extra value 1', extra_key_2: 'extra value 2') - .and_call_original + .with(project: project, user: user, namespace: namespace, extra_key_1: 'extra value 1', extra_key_2: 'extra value 2') + .and_call_original expect_any_instance_of(klass).to receive(:event) do |_, category, action, args| expect(category).to eq('category') @@ -132,7 +148,7 @@ RSpec.describe Gitlab::Tracking do expect(args[:context].last).to eq(other_context) end - described_class.event('category', 'action', + described_class.method(method).call('category', 'action', label: 'label', property: 'property', value: 1.5, @@ -141,44 +157,95 @@ RSpec.describe Gitlab::Tracking do user: user, namespace: namespace, extra_key_1: 'extra value 1', - extra_key_2: 'extra value 2') + extra_key_2: 'extra value 2' + ) end end - context 'when the action is not passed in as a string' do - it 'allows symbols' do - expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + describe '.database_event' do + context 'when the action is not passed in as a string' do + it 'allows symbols' do + expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) - described_class.event('category', :some_action) - end + described_class.database_event('category', :some_action) + end + + it 'allows nil' do + expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + + described_class.database_event('category', nil) + end - it 'allows nil' do - expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + it 'allows integers' do + expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) - described_class.event('category', nil) + described_class.database_event('category', 1) + end end - it 'allows integers' do - expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + it_behaves_like 'rescued error raised by destination class' do + let(:category) { 'Issue' } + let(:action) { 'created' } + let(:destination_class) { Gitlab::Tracking::Destinations::DatabaseEventsSnowplow } - described_class.event('category', 1) + subject(:tracking_method) { described_class.database_event(category, action) } end + + it_behaves_like 'delegates to destination', Gitlab::Tracking::Destinations::DatabaseEventsSnowplow, :database_event end - context 'when destination is Snowplow' do - before do - allow(Rails.env).to receive(:development?).and_return(true) + describe '.event' do + context 'when the action is not passed in as a string' do + it 'allows symbols' do + expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + + described_class.event('category', :some_action) + end + + it 'allows nil' do + expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + + described_class.event('category', nil) + end + + it 'allows integers' do + expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception) + + described_class.event('category', 1) + end end - it_behaves_like 'delegates to destination', Gitlab::Tracking::Destinations::Snowplow - end + context 'when destination is Snowplow' do + before do + allow(Rails.env).to receive(:development?).and_return(true) + end - context 'when destination is SnowplowMicro' do - before do - allow(Rails.env).to receive(:development?).and_return(true) + it_behaves_like 'rescued error raised by destination class' do + let(:category) { 'category' } + let(:action) { 'action' } + let(:destination_class) { Gitlab::Tracking::Destinations::Snowplow } + + subject(:tracking_method) { described_class.event(category, action) } + end + + it_behaves_like 'delegates to destination', Gitlab::Tracking::Destinations::Snowplow, :event end - it_behaves_like 'delegates to destination', Gitlab::Tracking::Destinations::SnowplowMicro + context 'when destination is SnowplowMicro' do + before do + allow(Rails.env).to receive(:development?).and_return(true) + end + + it_behaves_like 'rescued error raised by destination class' do + let(:category) { 'category' } + let(:action) { 'action' } + let(:destination_class) { Gitlab::Tracking::Destinations::Snowplow } + + subject(:tracking_method) { described_class.event(category, action) } + end + + it_behaves_like 'delegates to destination', Gitlab::Tracking::Destinations::SnowplowMicro, :event + end end end diff --git a/spec/mailers/emails/service_desk_spec.rb b/spec/mailers/emails/service_desk_spec.rb index 25afa8b48ce..b81c0ec8617 100644 --- a/spec/mailers/emails/service_desk_spec.rb +++ b/spec/mailers/emails/service_desk_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require 'email_spec' -RSpec.describe Emails::ServiceDesk do +RSpec.describe Emails::ServiceDesk, feature_category: :service_desk do include EmailSpec::Helpers include EmailSpec::Matchers include EmailHelpers @@ -16,6 +16,9 @@ RSpec.describe Emails::ServiceDesk do let_it_be(:issue) { create(:issue, project: project) } let_it_be(:email) { 'someone@gitlab.com' } let_it_be(:expected_unsubscribe_url) { unsubscribe_sent_notification_url('b7721fc7e8419911a8bea145236a0519') } + let_it_be(:credential) { create(:service_desk_custom_email_credential, project: project) } + let_it_be(:verification) { create(:service_desk_custom_email_verification, project: project) } + let_it_be(:service_desk_setting) { create(:service_desk_setting, project: project, custom_email: 'user@example.com') } let(:template) { double(content: template_content) } @@ -81,6 +84,24 @@ RSpec.describe Emails::ServiceDesk do end end + shared_examples 'a custom email verification process email' do + it 'contains custom email and project in subject' do + expect(subject.subject).to include(service_desk_setting.custom_email) + expect(subject.subject).to include(service_desk_setting.project.name) + end + end + + shared_examples 'a custom email verification process notification email' do + it 'has correct recipient' do + expect(subject.to).to eq(['owner@example.com']) + end + + it 'contains custom email and project in body' do + is_expected.to have_body_text(service_desk_setting.custom_email) + is_expected.to have_body_text(service_desk_setting.project.name) + end + end + describe '.service_desk_thank_you_email' do let_it_be(:reply_in_subject) { true } let_it_be(:default_text) do @@ -305,4 +326,20 @@ RSpec.describe Emails::ServiceDesk do end end end + + describe '.service_desk_verification_triggered_email' do + before do + service_desk_setting.custom_email_verification.triggerer = user + end + + subject { Notify.service_desk_verification_triggered_email(service_desk_setting, 'owner@example.com') } + + it_behaves_like 'an email sent from GitLab' + it_behaves_like 'a custom email verification process email' + it_behaves_like 'a custom email verification process notification email' + + it 'contains triggerer username' do + is_expected.to have_body_text("@#{user.username}") + end + end end diff --git a/spec/models/analytics/cycle_analytics/stage_spec.rb b/spec/models/analytics/cycle_analytics/stage_spec.rb index 57748f8942e..44c0be68fe3 100644 --- a/spec/models/analytics/cycle_analytics/stage_spec.rb +++ b/spec/models/analytics/cycle_analytics/stage_spec.rb @@ -105,30 +105,36 @@ RSpec.describe Analytics::CycleAnalytics::Stage, feature_category: :value_stream } end - describe '#create' do - it_behaves_like 'Snowplow event tracking' do - let(:property) { 'create' } - let(:extra) { record_tracked_attributes } + context 'with database event tracking' do + before do + allow(Gitlab::Tracking).to receive(:database_event).and_call_original + end + + describe '#create' do + it_behaves_like 'Snowplow event tracking', overrides: { tracking_method: :database_event } do + let(:property) { 'create' } + let(:extra) { record_tracked_attributes } - subject(:new_group_stage) { stage } + subject(:new_group_stage) { stage } + end end - end - describe '#update', :freeze_time do - it_behaves_like 'Snowplow event tracking' do - subject(:create_group_stage) { stage.update!(name: 'st 2') } + describe '#update', :freeze_time do + it_behaves_like 'Snowplow event tracking', overrides: { tracking_method: :database_event } do + subject(:create_group_stage) { stage.update!(name: 'st 2') } - let(:extra) { record_tracked_attributes.merge('name' => 'st 2') } - let(:property) { 'update' } + let(:extra) { record_tracked_attributes.merge('name' => 'st 2') } + let(:property) { 'update' } + end end - end - describe '#destroy' do - it_behaves_like 'Snowplow event tracking' do - subject(:delete_stage_group) { stage.destroy! } + describe '#destroy' do + it_behaves_like 'Snowplow event tracking', overrides: { tracking_method: :database_event } do + subject(:delete_stage_group) { stage.destroy! } - let(:extra) { record_tracked_attributes } - let(:property) { 'destroy' } + let(:extra) { record_tracked_attributes } + let(:property) { 'destroy' } + end end end end diff --git a/spec/models/concerns/database_event_tracking_spec.rb b/spec/models/concerns/database_event_tracking_spec.rb index 87aa8275635..cad82f971b3 100644 --- a/spec/models/concerns/database_event_tracking_spec.rb +++ b/spec/models/concerns/database_event_tracking_spec.rb @@ -3,6 +3,10 @@ require 'spec_helper' RSpec.describe DatabaseEventTracking, :snowplow do + before do + allow(Gitlab::Tracking).to receive(:database_event).and_call_original + end + let(:test_class) do Class.new(ActiveRecord::Base) do include DatabaseEventTracking @@ -17,7 +21,7 @@ RSpec.describe DatabaseEventTracking, :snowplow do context 'if event emmiter failed' do before do - allow(Gitlab::Tracking).to receive(:event).and_raise(StandardError) # rubocop:disable RSpec/ExpectGitlabTracking + allow(Gitlab::Tracking).to receive(:database_event).and_raise(StandardError) # rubocop:disable RSpec/ExpectGitlabTracking end it 'tracks the exception' do @@ -35,7 +39,7 @@ RSpec.describe DatabaseEventTracking, :snowplow do it 'does not track the event' do create_test_class_record - expect_no_snowplow_event + expect_no_snowplow_event(tracking_method: :database_event) end end @@ -47,6 +51,7 @@ RSpec.describe DatabaseEventTracking, :snowplow do create_test_class_record expect_snowplow_event( + tracking_method: :database_event, category: category, action: "#{event}_create", label: 'application_setting_terms', @@ -61,6 +66,7 @@ RSpec.describe DatabaseEventTracking, :snowplow do test_class.first.update!(id: 3) expect_snowplow_event( + tracking_method: :database_event, category: category, action: "#{event}_update", label: 'application_setting_terms', @@ -75,6 +81,7 @@ RSpec.describe DatabaseEventTracking, :snowplow do test_class.first.destroy! expect_snowplow_event( + tracking_method: :database_event, category: category, action: "#{event}_destroy", label: 'application_setting_terms', diff --git a/spec/models/u2f_registration_spec.rb b/spec/models/u2f_registration_spec.rb index 1fab3882c2a..9c8d786ecb1 100644 --- a/spec/models/u2f_registration_spec.rb +++ b/spec/models/u2f_registration_spec.rb @@ -62,72 +62,6 @@ RSpec.describe U2fRegistration do end end - describe 'callbacks' do - describe 'after create' do - shared_examples_for 'creates webauthn registration' do - it 'creates webauthn registration' do - u2f_registration = create_u2f_registration - webauthn_registration = WebauthnRegistration.where(u2f_registration_id: u2f_registration.id) - expect(webauthn_registration).to exist - end - end - - it_behaves_like 'creates webauthn registration' - - context 'when the u2f_registration has a blank name' do - let(:u2f_registration_name) { '' } - - it_behaves_like 'creates webauthn registration' - end - - context 'when the u2f_registration has the name as `nil`' do - let(:u2f_registration_name) { nil } - - it_behaves_like 'creates webauthn registration' - end - - it 'logs error' do - allow(Gitlab::Auth::U2fWebauthnConverter).to receive(:new).and_raise('boom!') - - allow_next_instance_of(U2fRegistration) do |u2f_registration| - allow(u2f_registration).to receive(:id).and_return(123) - end - - expect(Gitlab::ErrorTracking).to( - receive(:track_exception).with(kind_of(StandardError), - u2f_registration_id: 123)) - - create_u2f_registration - end - end - - describe 'after update' do - context 'when counter is updated' do - it 'updates the webauthn registration counter to be the same value' do - u2f_registration = create_u2f_registration - new_counter = u2f_registration.counter + 1 - webauthn_registration = WebauthnRegistration.find_by(u2f_registration_id: u2f_registration.id) - - u2f_registration.update!(counter: new_counter) - - expect(u2f_registration.reload.counter).to eq(new_counter) - expect(webauthn_registration.reload.counter).to eq(new_counter) - end - end - - context 'when sign count of registration is not updated' do - it 'does not update the counter' do - u2f_registration = create_u2f_registration - webauthn_registration = WebauthnRegistration.find_by(u2f_registration_id: u2f_registration.id) - - expect do - u2f_registration.update!(name: 'a new name') - end.not_to change { webauthn_registration.counter } - end - end - end - end - def create_u2f_registration create( :u2f_registration, diff --git a/spec/requests/api/npm_project_packages_spec.rb b/spec/requests/api/npm_project_packages_spec.rb index c738269fce0..c4e0d5ed27b 100644 --- a/spec/requests/api/npm_project_packages_spec.rb +++ b/spec/requests/api/npm_project_packages_spec.rb @@ -226,15 +226,7 @@ RSpec.describe API::NpmProjectPackages, feature_category: :package_registry do context 'with access token' do it_behaves_like 'a package tracking event', 'API::NpmPackages', 'push_package' - it 'creates npm package with file' do - expect { subject } - .to change { project.packages.count }.by(1) - .and change { Packages::PackageFile.count }.by(1) - .and change { Packages::Tag.count }.by(1) - .and change { Packages::Npm::Metadatum.count }.by(1) - - expect(response).to have_gitlab_http_status(:ok) - end + it_behaves_like 'a successful package creation' end it 'creates npm package with file with job token' do @@ -391,20 +383,35 @@ RSpec.describe API::NpmProjectPackages, feature_category: :package_registry do context 'with a too large metadata structure' do let(:package_name) { "@#{group.path}/my_package_name" } - let(:params) do - upload_params(package_name: package_name, package_version: '1.2.3').tap do |h| - h['versions']['1.2.3']['test'] = 'test' * 10000 + + ::Packages::Npm::CreatePackageService::PACKAGE_JSON_NOT_ALLOWED_FIELDS.each do |field| + context "when a large value for #{field} is set" do + let(:params) do + upload_params(package_name: package_name, package_version: '1.2.3').tap do |h| + h['versions']['1.2.3'][field] = 'test' * 10000 + end + end + + it_behaves_like 'a successful package creation' end end - it_behaves_like 'not a package tracking event' + context 'when the large field is not one of the ignored fields' do + let(:params) do + upload_params(package_name: package_name, package_version: '1.2.3').tap do |h| + h['versions']['1.2.3']['test'] = 'test' * 10000 + end + end - it 'returns an error' do - expect { upload_package_with_token } - .not_to change { project.packages.count } + it_behaves_like 'not a package tracking event' - expect(response).to have_gitlab_http_status(:bad_request) - expect(response.body).to include('Validation failed: Package json structure is too large') + it 'returns an error' do + expect { upload_package_with_token } + .not_to change { project.packages.count } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(response.body).to include('Validation failed: Package json structure is too large') + end end end end diff --git a/spec/scripts/create_pipeline_failure_incident_spec.rb b/spec/scripts/create_pipeline_failure_incident_spec.rb deleted file mode 100644 index efbd22ccb32..00000000000 --- a/spec/scripts/create_pipeline_failure_incident_spec.rb +++ /dev/null @@ -1,162 +0,0 @@ -# frozen_string_literal: true - -require 'fast_spec_helper' -require_relative '../../scripts/create-pipeline-failure-incident' -require_relative '../support/helpers/stub_env' - -RSpec.describe CreatePipelineFailureIncident, feature_category: :tooling do - include StubENV - - describe '#execute' do - let(:create_issue) { instance_double(CreateIssue) } - let(:issue) { double('Issue', iid: 1) } # rubocop:disable RSpec/VerifiedDoubles - let(:create_issue_discussion) { instance_double(CreateIssueDiscussion, execute: true) } - let(:failed_jobs) { instance_double(PipelineFailedJobs, execute: []) } - - let(:options) do - { - project: 'gitlab-org/gitlab-test-project', - api_token: 'asdf1234' - } - end - - let(:issue_params) do - { - issue_type: 'incident', - title: title, - description: description, - labels: incident_labels - } - end - - subject { described_class.new(options).execute } - - before do - stub_env( - 'CI_COMMIT_SHA' => 'bfcd2b9b5cad0b889494ce830697392c8ca11257', - 'CI_PROJECT_PATH' => 'gitlab.com/gitlab-org/gitlab', - 'CI_PROJECT_NAME' => 'gitlab', - 'GITLAB_USER_ID' => '1111', - 'CI_PROJECT_ID' => '13083', - 'CI_PIPELINE_ID' => '1234567', - 'CI_PIPELINE_URL' => 'https://gitlab.com/gitlab-org/gitlab/-/pipelines/1234567', - 'CI_PROJECT_URL' => 'https://gitlab.com/gitlab-org/gitlab', - 'CI_PIPELINE_CREATED_AT' => '2023-01-24 00:00:00', - 'CI_COMMIT_TITLE' => 'Commit title', - 'CI_PIPELINE_SOURCE' => 'push', - 'GITLAB_USER_NAME' => 'Foo User', - 'PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE' => 'asdf1234', - 'CI_SERVER_URL' => 'https://gitlab.com', - 'GITLAB_USER_LOGIN' => 'foo' - ) - end - - shared_examples 'creating an issue' do - it 'successfully creates an issue' do - allow(PipelineFailedJobs).to receive(:new) - .with(API::DEFAULT_OPTIONS.merge(exclude_allowed_to_fail_jobs: true)) - .and_return(failed_jobs) - - expect(CreateIssue).to receive(:new) - .with(project: options[:project], api_token: options[:api_token]) - .and_return(create_issue) - - expect(CreateIssueDiscussion).to receive(:new) - .with(project: options[:project], api_token: options[:api_token]) - .and_return(create_issue_discussion).twice - - expect(create_issue).to receive(:execute) - .with(issue_params).and_return(issue) - - expect(subject).to eq(issue) - end - end - - context 'when stable branch' do - let(:incident_labels) { ['release-blocker'] } - let(:title) { /broken `15-6-stable-ee`/ } - let(:description) { /A broken stable branch prevents patch releases/ } - - let(:commit_merge_request) do - { - 'author' => { - 'id' => '2' - }, - 'title' => 'foo', - 'web_url' => 'https://gitlab.com/test' - } - end - - let(:merge_request) { instance_double(CommitMergeRequests, execute: [commit_merge_request]) } - let(:issue_params) { super().merge(assignee_ids: [1111, 2]) } - - before do - stub_env( - 'CI_COMMIT_REF_NAME' => '15-6-stable-ee' - ) - - allow(CommitMergeRequests).to receive(:new) - .with(API::DEFAULT_OPTIONS.merge(sha: ENV['CI_COMMIT_SHA'])) - .and_return(merge_request) - end - - it_behaves_like 'creating an issue' - end - - context 'when other branch' do - let(:title) { /broken `master`/ } - let(:description) { /Follow the \[Broken `master` handbook guide\]/ } - - before do - stub_env( - 'CI_COMMIT_REF_NAME' => 'master' - ) - end - - context 'when GitLab FOSS' do - let(:incident_labels) { ['master:foss-broken', 'Engineering Productivity', 'master-broken::undetermined'] } - - before do - stub_env( - 'CI_PROJECT_NAME' => 'gitlab-foss' - ) - end - - it_behaves_like 'creating an issue' - end - - context 'when GitLab EE' do - let(:incident_labels) { ['master:broken', 'Engineering Productivity', 'master-broken::undetermined'] } - - before do - stub_env( - 'CI_PROJECT_NAME' => 'gitlab' - ) - end - - it_behaves_like 'creating an issue' - end - end - - context 'when review-apps' do - let(:options) do - { - project: 'gitlab-org/quality/engineering-productivity/review-apps-broken-incidents', - api_token: 'asdf1234' - } - end - - let(:incident_labels) { ["review-apps-broken", "Engineering Productivity", "ep::review-apps"] } - let(:title) { /broken `my-branch`/ } - let(:description) { /Please refer to \[the review-apps triaging process\]/ } - - before do - stub_env( - 'CI_COMMIT_REF_NAME' => 'my-branch' - ) - end - - it_behaves_like 'creating an issue' - end - end -end diff --git a/spec/scripts/generate_failed_pipeline_slack_message_spec.rb b/spec/scripts/generate_failed_pipeline_slack_message_spec.rb deleted file mode 100644 index 2418116e694..00000000000 --- a/spec/scripts/generate_failed_pipeline_slack_message_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -require 'fast_spec_helper' -require_relative '../../scripts/generate-failed-pipeline-slack-message' -require_relative '../support/helpers/stub_env' - -RSpec.describe GenerateFailedPipelineSlackMessage, feature_category: :tooling do - include StubENV - - describe '#execute' do - let(:create_issue) { instance_double(CreateIssue) } - let(:issue) { double('Issue', iid: 1) } # rubocop:disable RSpec/VerifiedDoubles - let(:create_issue_discussion) { instance_double(CreateIssueDiscussion, execute: true) } - let(:failed_jobs) { instance_double(PipelineFailedJobs, execute: []) } - - let(:project_path) { 'gitlab-org/gitlab-test-project' } - let(:options) do - { - project: project_path, - incident_json_file: 'incident_json_file_tests.json' - } - end - - subject { described_class.new(options).execute } - - before do - stub_env( - 'CI_COMMIT_REF_NAME' => 'my-branch', - 'CI_COMMIT_SHA' => 'bfcd2b9b5cad0b889494ce830697392c8ca11257', - 'CI_COMMIT_TITLE' => 'Commit title', - 'CI_PIPELINE_CREATED_AT' => '2023-01-24 00:00:00', - 'CI_PIPELINE_ID' => '1234567', - 'CI_PIPELINE_SOURCE' => 'push', - 'CI_PIPELINE_URL' => 'https://gitlab.com/gitlab-org/gitlab/-/pipelines/1234567', - 'CI_PROJECT_PATH' => 'gitlab.com/gitlab-org/gitlab', - 'CI_PROJECT_URL' => 'https://gitlab.com/gitlab-org/gitlab', - 'CI_SERVER_URL' => 'https://gitlab.com', - 'GITLAB_USER_ID' => '1111', - 'GITLAB_USER_LOGIN' => 'foo', - 'GITLAB_USER_NAME' => 'Foo User', - 'PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE' => 'asdf1234', - 'SLACK_CHANNEL' => '#a-slack-channel' - ) - - allow(PipelineFailedJobs).to receive(:new) - .with(API::DEFAULT_OPTIONS.merge(exclude_allowed_to_fail_jobs: true)) - .and_return(failed_jobs) - end - - it 'returns the correct keys' do - expect(subject.keys).to match_array([:channel, :username, :icon_emoji, :text, :blocks]) - end - - it 'returns the correct channel' do - expect(subject[:channel]).to eq('#a-slack-channel') - end - - it 'returns the correct username' do - expect(subject[:username]).to eq('Failed pipeline reporter') - end - - it 'returns the correct icon_emoji' do - expect(subject[:icon_emoji]).to eq(':boom:') - end - - it 'returns the correct text' do - expect(subject[:text]).to eq( - '*<https://gitlab.com/gitlab-org/gitlab|gitlab.com/gitlab-org/gitlab> pipeline ' \ - '<https://gitlab.com/gitlab-org/gitlab/-/pipelines/1234567|#1234567> failed*' - ) - end - - it 'returns the correct incident button link' do - block_with_incident_link = subject[:blocks].detect { |block| block.key?(:accessory) } - - expect(block_with_incident_link[:accessory][:url]).to eq( - "https://gitlab.com/#{project_path}/-/issues/new?issuable_template=incident&issue%5Bissue_type%5D=incident" - ) - end - end -end diff --git a/spec/support/helpers/snowplow_helpers.rb b/spec/support/helpers/snowplow_helpers.rb index 265e1c38b09..a04e5d46df9 100644 --- a/spec/support/helpers/snowplow_helpers.rb +++ b/spec/support/helpers/snowplow_helpers.rb @@ -46,7 +46,7 @@ module SnowplowHelpers # } # ] # ) - def expect_snowplow_event(category:, action:, context: nil, **kwargs) + def expect_snowplow_event(category:, action:, context: nil, tracking_method: :event, **kwargs) if context if context.is_a?(Array) kwargs[:context] = [] @@ -60,7 +60,7 @@ module SnowplowHelpers end end - expect(Gitlab::Tracking).to have_received(:event) # rubocop:disable RSpec/ExpectGitlabTracking + expect(Gitlab::Tracking).to have_received(tracking_method) # rubocop:disable RSpec/ExpectGitlabTracking .with(category, action, **kwargs).at_least(:once) end @@ -79,11 +79,11 @@ module SnowplowHelpers # expect_no_snowplow_event # end # end - def expect_no_snowplow_event(category: nil, action: nil, **kwargs) + def expect_no_snowplow_event(category: nil, action: nil, tracking_method: :event, **kwargs) if category && action - expect(Gitlab::Tracking).not_to have_received(:event).with(category, action, **kwargs) # rubocop:disable RSpec/ExpectGitlabTracking + expect(Gitlab::Tracking).not_to have_received(tracking_method).with(category, action, **kwargs) # rubocop:disable RSpec/ExpectGitlabTracking else - expect(Gitlab::Tracking).not_to have_received(:event) # rubocop:disable RSpec/ExpectGitlabTracking + expect(Gitlab::Tracking).not_to have_received(tracking_method) # rubocop:disable RSpec/ExpectGitlabTracking end end end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index 5c7d31190fd..2058eeef442 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -5728,7 +5728,6 @@ - './spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb' - './spec/lib/gitlab/background_migration/migrate_project_taggings_context_from_tags_to_topics_spec.rb' - './spec/lib/gitlab/background_migration/migrate_shimo_confluence_integration_category_spec.rb' -- './spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb' - './spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb' - './spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb' - './spec/lib/gitlab/background_migration/populate_container_repository_migration_plan_spec.rb' diff --git a/spec/support/shared_examples/requests/api/packages_shared_examples.rb b/spec/support/shared_examples/requests/api/packages_shared_examples.rb index b7f2805ed97..1f2450c864b 100644 --- a/spec/support/shared_examples/requests/api/packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/packages_shared_examples.rb @@ -175,3 +175,15 @@ RSpec.shared_examples 'bumping the package last downloaded at field' do .to change { package.reload.last_downloaded_at }.from(nil).to(instance_of(ActiveSupport::TimeWithZone)) end end + +RSpec.shared_examples 'a successful package creation' do + it 'creates npm package with file' do + expect { subject } + .to change { project.packages.count }.by(1) + .and change { Packages::PackageFile.count }.by(1) + .and change { Packages::Tag.count }.by(1) + .and change { Packages::Npm::Metadatum.count }.by(1) + + expect(response).to have_gitlab_http_status(:ok) + end +end |