diff options
Diffstat (limited to 'spec')
11 files changed, 141 insertions, 85 deletions
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb index c18da56f3ee..d068cb219f1 100644 --- a/spec/features/projects/settings/service_desk_setting_spec.rb +++ b/spec/features/projects/settings/service_desk_setting_spec.rb @@ -2,18 +2,20 @@ require 'spec_helper' -RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_category: :groups_and_projects do - let(:project) { create(:project_empty_repo, :private, service_desk_enabled: false) } +RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_category: :service_desk do + let_it_be_with_reload(:project) { create(:project_empty_repo, :private, service_desk_enabled: false) } let(:presenter) { project.present(current_user: user) } - let(:user) { create(:user) } + let_it_be_with_reload(:user) { create(:user) } before do project.add_maintainer(user) sign_in(user) - allow_any_instance_of(Project).to receive(:present).with(current_user: user).and_return(presenter) - allow(::Gitlab::Email::IncomingEmail).to receive(:enabled?) { true } - allow(::Gitlab::Email::IncomingEmail).to receive(:supports_wildcard?) { true } + allow_next_instance_of(Project) do |project| + allow(project).to receive(:present).with(current_user: user).and_return(presenter) + end + allow(::Gitlab::Email::IncomingEmail).to receive(:enabled?).and_return(true) + allow(::Gitlab::Email::IncomingEmail).to receive(:supports_wildcard?).and_return(true) end it 'shows activation checkbox' do @@ -43,8 +45,8 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_c context 'when service_desk_email is enabled' do before do - allow(::Gitlab::Email::ServiceDeskEmail).to receive(:enabled?) { true } - allow(::Gitlab::Email::ServiceDeskEmail).to receive(:address_for_key) { 'address-suffix@example.com' } + allow(::Gitlab::Email::ServiceDeskEmail).to receive(:enabled?).and_return(true) + allow(::Gitlab::Email::ServiceDeskEmail).to receive(:address_for_key).and_return('address-suffix@example.com') visit edit_project_path(project) end @@ -66,7 +68,7 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_c expect(find('[data-testid="incoming-email"]').value).to eq('address-suffix@example.com') end - context 'issue description templates' do + describe 'issue description templates' do let_it_be(:issuable_project_template_files) do { '.gitlab/issue_templates/project-issue-bar.md' => 'Project Issue Template Bar', @@ -82,8 +84,13 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_c end let_it_be_with_reload(:group) { create(:group) } - let_it_be_with_reload(:project) { create(:project, :custom_repo, group: group, files: issuable_project_template_files) } - let_it_be(:group_template_repo) { create(:project, :custom_repo, group: group, files: issuable_group_template_files) } + let_it_be_with_reload(:project) do + create(:project, :custom_repo, group: group, files: issuable_project_template_files) + end + + let_it_be(:group_template_repo) do + create(:project, :custom_repo, group: group, files: issuable_group_template_files) + end before do stub_licensed_features(custom_file_templates_for_namespace: false, custom_file_templates: false) @@ -94,4 +101,10 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_c it_behaves_like 'issue description templates from current project only' end end + + it 'pushes service_desk_custom_email feature flag to frontend' do + visit edit_project_path(project) + + expect(page).to have_pushed_frontend_feature_flags(serviceDeskCustomEmail: true) + end end diff --git a/spec/frontend/analytics/usage_trends/components/users_chart_spec.js b/spec/frontend/analytics/usage_trends/components/users_chart_spec.js index 20836d7cc70..8638d82ae3c 100644 --- a/spec/frontend/analytics/usage_trends/components/users_chart_spec.js +++ b/spec/frontend/analytics/usage_trends/components/users_chart_spec.js @@ -22,23 +22,19 @@ describe('UsersChart', () => { let queryHandler; const createComponent = ({ - loadingError = false, - loading = false, users = [], additionalData = [], + handler = mockQueryResponse({ key: 'users', data: users, additionalData }), } = {}) => { - queryHandler = mockQueryResponse({ key: 'users', data: users, loading, additionalData }); + queryHandler = handler; - return shallowMount(UsersChart, { + wrapper = shallowMount(UsersChart, { + apolloProvider: createMockApollo([[usersQuery, queryHandler]]), props: { startDate: new Date(2020, 9, 26), endDate: new Date(2020, 10, 1), totalDataPoints: mockCountsData2.length, }, - apolloProvider: createMockApollo([[usersQuery, queryHandler]]), - data() { - return { loadingError }; - }, }); }; @@ -48,7 +44,7 @@ describe('UsersChart', () => { describe('while loading', () => { beforeEach(() => { - wrapper = createComponent({ loading: true }); + createComponent({ loading: true }); }); it('displays the skeleton loader', () => { @@ -62,7 +58,7 @@ describe('UsersChart', () => { describe('without data', () => { beforeEach(async () => { - wrapper = createComponent({ users: [] }); + createComponent({ users: [] }); await nextTick(); }); @@ -81,7 +77,7 @@ describe('UsersChart', () => { describe('with data', () => { beforeEach(async () => { - wrapper = createComponent({ users: mockCountsData2 }); + createComponent({ users: mockCountsData2 }); await waitForPromises(); }); @@ -102,11 +98,17 @@ describe('UsersChart', () => { describe('with errors', () => { beforeEach(async () => { - wrapper = createComponent({ loadingError: true }); + createComponent(); await nextTick(); }); - it('renders an error message', () => { + it('renders an error message', async () => { + createComponent({ + handler: jest.fn().mockRejectedValue({}), + }); + + await waitForPromises(); + expect(findAlert().text()).toBe( 'Could not load the user chart. Please refresh the page to try again.', ); @@ -124,42 +126,37 @@ describe('UsersChart', () => { describe('when fetching more data', () => { describe('when the fetchMore query returns data', () => { beforeEach(async () => { - wrapper = createComponent({ + createComponent({ users: mockCountsData2, additionalData: mockCountsData1, }); - jest.spyOn(wrapper.vm.$apollo.queries.users, 'fetchMore'); await nextTick(); }); it('requests data twice', () => { expect(queryHandler).toHaveBeenCalledTimes(2); }); - - it('calls fetchMore', () => { - expect(wrapper.vm.$apollo.queries.users.fetchMore).toHaveBeenCalledTimes(1); - }); }); describe('when the fetchMore query throws an error', () => { beforeEach(async () => { - wrapper = createComponent({ + createComponent({ users: mockCountsData2, additionalData: mockCountsData1, }); - jest - .spyOn(wrapper.vm.$apollo.queries.users, 'fetchMore') - .mockImplementation(jest.fn().mockRejectedValue()); await waitForPromises(); }); it('calls fetchMore', () => { - expect(wrapper.vm.$apollo.queries.users.fetchMore).toHaveBeenCalledTimes(1); + expect(queryHandler).toHaveBeenCalledTimes(2); }); - it('renders an error message', () => { + it('renders an error message', async () => { + createComponent({ handler: jest.fn().mockRejectedValue({}) }); + await waitForPromises(); + expect(findAlert().text()).toBe( 'Could not load the user chart. Please refresh the page to try again.', ); diff --git a/spec/frontend/observability/observability_app_spec.js b/spec/frontend/observability/observability_app_spec.js index 4a9be71b880..392992a5962 100644 --- a/spec/frontend/observability/observability_app_spec.js +++ b/spec/frontend/observability/observability_app_spec.js @@ -1,4 +1,5 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { stubComponent } from 'helpers/stub_component'; import ObservabilityApp from '~/observability/components/observability_app.vue'; import ObservabilitySkeleton from '~/observability/components/skeleton/index.vue'; import { @@ -21,7 +22,7 @@ describe('ObservabilityApp', () => { query: { otherQuery: 100 }, }; - const mockHandleSkeleton = jest.fn(); + const mockSkeletonOnContentLoaded = jest.fn(); const findIframe = () => wrapper.findByTestId('observability-ui-iframe'); @@ -36,7 +37,9 @@ describe('ObservabilityApp', () => { ...props, }, stubs: { - 'observability-skeleton': ObservabilitySkeleton, + ObservabilitySkeleton: stubComponent(ObservabilitySkeleton, { + methods: { onContentLoaded: mockSkeletonOnContentLoaded }, + }), }, mocks: { $route, @@ -155,14 +158,14 @@ describe('ObservabilityApp', () => { describe('on GOUI_LOADED', () => { beforeEach(() => { mountComponent(); - wrapper.vm.$refs.observabilitySkeleton.onContentLoaded = mockHandleSkeleton; }); + it('should call onContentLoaded method', () => { dispatchMessageEvent({ data: { type: MESSAGE_EVENT_TYPE.GOUI_LOADED }, origin: 'https://observe.gitlab.com', }); - expect(mockHandleSkeleton).toHaveBeenCalled(); + expect(mockSkeletonOnContentLoaded).toHaveBeenCalled(); }); it('should not call onContentLoaded method if origin is different', () => { @@ -170,7 +173,7 @@ describe('ObservabilityApp', () => { data: { type: MESSAGE_EVENT_TYPE.GOUI_LOADED }, origin: 'https://example.com', }); - expect(mockHandleSkeleton).not.toHaveBeenCalled(); + expect(mockSkeletonOnContentLoaded).not.toHaveBeenCalled(); }); it('should not call onContentLoaded method if event type is different', () => { @@ -178,7 +181,7 @@ describe('ObservabilityApp', () => { data: { type: 'UNKNOWN_EVENT' }, origin: 'https://observe.gitlab.com', }); - expect(mockHandleSkeleton).not.toHaveBeenCalled(); + expect(mockSkeletonOnContentLoaded).not.toHaveBeenCalled(); }); }); diff --git a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb index ba83d979cad..50e20e4fbcf 100644 --- a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb @@ -66,7 +66,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue created actions' do - it_behaves_like 'tracked issuable snowplow and service ping events with project' do + it_behaves_like 'tracked issuable internal event with project' do let(:action) { described_class::ISSUE_CREATED } let(:original_params) { { namespace: project.project_namespace.reload } } diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb index 25c57aa00c6..53eee62b386 100644 --- a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb @@ -54,11 +54,6 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl let(:merge_request) { create(:merge_request) } let(:target_project) { merge_request.target_project } - let(:fake_tracker) { instance_spy(Gitlab::Tracking::Destinations::Snowplow) } - - before do - allow(Gitlab::Tracking).to receive(:tracker).and_return(fake_tracker) - end it_behaves_like 'a tracked merge request unique event' do let(:action) { described_class::MR_USER_CREATE_ACTION } @@ -68,36 +63,10 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl let(:action) { described_class::MR_CREATE_ACTION } end - it 'logs to Snowplow', :aggregate_failures do - # This logic should be extracted to shared_examples - namespace = target_project.namespace - - expect(Gitlab::Tracking::StandardContext) - .to receive(:new) - .with( - project_id: target_project.id, - user_id: user.id, - namespace_id: namespace.id, - plan_name: namespace.actual_plan_name - ) - .and_call_original - - expect(Gitlab::Tracking::ServicePingContext) - .to receive(:new) - .with(data_source: :redis_hll, event: described_class::MR_USER_CREATE_ACTION) - .and_call_original - - expect(fake_tracker).to receive(:event) - .with( - 'InternalEventTracking', - described_class::MR_USER_CREATE_ACTION, - context: [ - an_instance_of(SnowplowTracker::SelfDescribingJson), - an_instance_of(SnowplowTracker::SelfDescribingJson) - ] - ) - .exactly(:once) - subject + it_behaves_like 'internal event tracking' do + let(:action) { described_class::MR_USER_CREATE_ACTION } + let(:project) { target_project } + let(:namespace) { project.namespace } end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index ee47f90fb40..4cd73cd3fe6 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -338,11 +338,13 @@ RSpec.describe Issue, feature_category: :team_planning do create(:issue) end - it_behaves_like 'issue_edit snowplow tracking' do + it_behaves_like 'internal event tracking' do let(:issue) { create(:issue) } let(:project) { issue.project } - let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } let(:user) { issue.author } + let(:action) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } + let(:namespace) { project.namespace } + subject(:service_action) { issue } end end diff --git a/spec/models/work_item_spec.rb b/spec/models/work_item_spec.rb index e0ec54fd5ff..bf43a2032e7 100644 --- a/spec/models/work_item_spec.rb +++ b/spec/models/work_item_spec.rb @@ -212,11 +212,13 @@ RSpec.describe WorkItem, feature_category: :portfolio_management do create(:work_item) end - it_behaves_like 'issue_edit snowplow tracking' do + it_behaves_like 'internal event tracking' do let(:work_item) { create(:work_item) } - let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } + let(:action) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } let(:project) { work_item.project } let(:user) { work_item.author } + let(:namespace) { project.namespace } + subject(:service_action) { work_item } end end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index 4168820a2b3..adee31ca644 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -4151,7 +4151,6 @@ - './spec/features/projects/settings/registry_settings_spec.rb' - './spec/features/projects/settings/repository_settings_spec.rb' - './spec/features/projects/settings/secure_files_spec.rb' -- './spec/features/projects/settings/service_desk_setting_spec.rb' - './spec/features/projects/settings/user_archives_project_spec.rb' - './spec/features/projects/settings/user_changes_avatar_spec.rb' - './spec/features/projects/settings/user_changes_default_branch_spec.rb' diff --git a/spec/support/shared_examples/controllers/internal_event_tracking_examples.rb b/spec/support/shared_examples/controllers/internal_event_tracking_examples.rb new file mode 100644 index 00000000000..e2a4fb31361 --- /dev/null +++ b/spec/support/shared_examples/controllers/internal_event_tracking_examples.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# Requires a context containing: +# - subject +# - action +# - user +# Optionally, the context can contain: +# - project +# - namespace + +RSpec.shared_examples 'internal event tracking' do + let(:fake_tracker) { instance_spy(Gitlab::Tracking::Destinations::Snowplow) } + let(:namespace) { nil } + let(:proejct) { nil } + + before do + allow(Gitlab::Tracking).to receive(:tracker).and_return(fake_tracker) + + allow(Gitlab::Tracking::StandardContext).to receive(:new).and_call_original + allow(Gitlab::Tracking::ServicePingContext).to receive(:new).and_call_original + end + + it 'logs to Snowplow', :aggregate_failures do + subject + + expect(Gitlab::Tracking::StandardContext) + .to have_received(:new) + .with( + project_id: project&.id, + user_id: user.id, + namespace_id: namespace&.id, + plan_name: namespace&.actual_plan_name + ) + + expect(Gitlab::Tracking::ServicePingContext) + .to have_received(:new) + .with(data_source: :redis_hll, event: action) + + expect(fake_tracker).to have_received(:event) + .with( + 'InternalEventTracking', + action, + context: [ + an_instance_of(SnowplowTracker::SelfDescribingJson), + an_instance_of(SnowplowTracker::SelfDescribingJson) + ] + ) + .exactly(:once) + end +end diff --git a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb index ba00e3e0610..3d3b619451d 100644 --- a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb +++ b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb @@ -6,7 +6,7 @@ # - category # - action # - namespace -# Optionaly, the context can contain: +# Optionally, the context can contain: # - project # - property # - user diff --git a/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb index 169fceced7a..9dc18555340 100644 --- a/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'tracked issuable snowplow and service ping events for given event params' do +RSpec.shared_examples 'tracked issuable events' do before do stub_application_setting(usage_ping_enabled: true) end @@ -21,6 +21,10 @@ RSpec.shared_examples 'tracked issuable snowplow and service ping events for giv it 'does not track edit actions if author is not present' do expect(track_action({ author: nil }.merge(track_params))).to be_nil end +end + +RSpec.shared_examples 'tracked issuable snowplow and service ping events for given event params' do + it_behaves_like 'tracked issuable events' it 'emits snowplow event' do track_action({ author: user1 }.merge(track_params)) @@ -29,6 +33,23 @@ RSpec.shared_examples 'tracked issuable snowplow and service ping events for giv end end +RSpec.shared_examples 'tracked issuable internal event for given event params' do + it_behaves_like 'tracked issuable events' + + it_behaves_like 'internal event tracking' do + subject(:track_event) { track_action({ author: user1 }.merge(track_params)) } + + let(:user) { user1 } + let(:namespace) { project&.namespace } + end +end + +RSpec.shared_examples 'tracked issuable internal event with project' do + it_behaves_like 'tracked issuable internal event for given event params' do + let(:track_params) { original_params || { project: project } } + end +end + RSpec.shared_examples 'tracked issuable snowplow and service ping events with project' do it_behaves_like 'tracked issuable snowplow and service ping events for given event params' do let(:context) do |