diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-13 15:14:38 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-13 15:14:38 +0300 |
commit | a00537e412e4ef6761ad35cc7148637ad75434a1 (patch) | |
tree | b128cf232074c364fce70e36f1d458247128c820 /spec | |
parent | 5d0c43f60d96dfa436edd9a248100b935c05edf1 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
21 files changed, 230 insertions, 113 deletions
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index e970e5c0916..08fb12c375e 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -31,7 +31,16 @@ RSpec.describe Admin::RunnersController do create(:ci_build, runner: runner, project: project) end - it 'redirects to the runner edit page' do + it 'shows a runner show page' do + get :show, params: { id: runner.id } + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template(:show) + end + + it 'when runner_read_only_admin_view is off, redirects to the runner edit page' do + stub_feature_flags(runner_read_only_admin_view: false) + get :show, params: { id: runner.id } expect(response).to have_gitlab_http_status(:redirect) diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb index 214a893f0fa..e41ae406d13 100644 --- a/spec/controllers/profiles/emails_controller_spec.rb +++ b/spec/controllers/profiles/emails_controller_spec.rb @@ -49,7 +49,7 @@ RSpec.describe Profiles::EmailsController do end context 'when email address is invalid' do - let(:email) { 'invalid.@example.com' } + let(:email) { 'invalid@@example.com' } it 'does not send an email confirmation' do expect { subject }.not_to change { ActionMailer::Base.deliveries.size } diff --git a/spec/controllers/projects/security/configuration_controller_spec.rb b/spec/controllers/projects/security/configuration_controller_spec.rb index 848db16fb02..1ce0fcd85db 100644 --- a/spec/controllers/projects/security/configuration_controller_spec.rb +++ b/spec/controllers/projects/security/configuration_controller_spec.rb @@ -36,6 +36,31 @@ RSpec.describe Projects::Security::ConfigurationController do expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template(:show) end + + it 'responds with configuration data json' do + get :show, params: { namespace_id: project.namespace, project_id: project, format: :json } + + features = json_response['features'] + sast_feature = features.find { |feature| feature['type'] == 'sast' } + dast_feature = features.find { |feature| feature['type'] == 'dast' } + + expect(response).to have_gitlab_http_status(:ok) + expect(sast_feature['available']).to be_truthy + expect(dast_feature['available']).to be_falsey + end + + context 'with feature flag unify_security_configuration turned off' do + before do + stub_feature_flags(unify_security_configuration: false) + end + + it 'responds with empty configuration data json' do + get :show, params: { namespace_id: project.namespace, project_id: project, format: :json } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to be_empty + end + end end end end diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 15ccb096328..c53948ee6f3 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -480,7 +480,8 @@ RSpec.describe "Admin Runners" do describe 'runner page breadcrumbs' do it 'contains the current runner id and token' do page.within '[data-testid="breadcrumb-links"]' do - expect(page.find('h2')).to have_content("##{runner.id} (#{runner.short_sha})") + expect(page).to have_link("##{runner.id} (#{runner.short_sha})") + expect(page.find('h2')).to have_content("Edit") end end end diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb index 25e474bb676..49375e4b37b 100644 --- a/spec/features/boards/board_filters_spec.rb +++ b/spec/features/boards/board_filters_spec.rb @@ -34,7 +34,9 @@ RSpec.describe 'Issue board filters', :js do it 'and submit one as filter', :aggregate_failures do expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) - expect_filtered_search_dropdown_results(filter_dropdown, 3) + wait_for_requests + + expect_filtered_search_dropdown_results(filter_dropdown, 4) click_on user.username filter_submit.click diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb index 8f05de60be9..24917412826 100644 --- a/spec/features/profiles/emails_spec.rb +++ b/spec/features/profiles/emails_spec.rb @@ -44,7 +44,7 @@ RSpec.describe 'Profile > Emails' do end it 'does not add an invalid email' do - fill_in('Email', with: 'test.@example.com') + fill_in('Email', with: 'test@@example.com') click_button('Add email address') email = user.emails.find_by(email: email) diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js index ea551e94f2f..a8398a138ba 100644 --- a/spec/frontend/boards/components/board_filtered_search_spec.js +++ b/spec/frontend/boards/components/board_filtered_search_spec.js @@ -118,6 +118,7 @@ describe('BoardFilteredSearch', () => { it('sets the url params to the correct results', async () => { const mockFilters = [ { type: 'author', value: { data: 'root', operator: '=' } }, + { type: 'assignee', value: { data: 'root', operator: '=' } }, { type: 'label', value: { data: 'label', operator: '=' } }, { type: 'label', value: { data: 'label2', operator: '=' } }, { type: 'milestone', value: { data: 'New Milestone', operator: '=' } }, @@ -133,7 +134,26 @@ describe('BoardFilteredSearch', () => { title: '', replace: true, url: - 'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2&milestone_title=New+Milestone&iteration_id=3341&types=INCIDENT&weight=2&release_tag=v1.0.0', + 'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2&assignee_username=root&milestone_title=New+Milestone&iteration_id=3341&types=INCIDENT&weight=2&release_tag=v1.0.0', + }); + }); + + describe('when assignee is passed a wildcard value', () => { + const url = (arg) => `http://test.host/?assignee_id=${arg}`; + + it.each([ + ['None', url('None')], + ['Any', url('Any')], + ])('sets the url param %s', (assigneeParam, expected) => { + const mockFilters = [{ type: 'assignee', value: { data: assigneeParam, operator: '=' } }]; + jest.spyOn(urlUtility, 'updateHistory'); + findFilteredSearch().vm.$emit('onFilter', mockFilters); + + expect(urlUtility.updateHistory).toHaveBeenCalledWith({ + title: '', + replace: true, + url: expected, + }); }); }); }); diff --git a/spec/frontend/jobs/bridge/components/sidebar_spec.js b/spec/frontend/jobs/bridge/components/sidebar_spec.js index 03f5a15f288..5006d4f08a6 100644 --- a/spec/frontend/jobs/bridge/components/sidebar_spec.js +++ b/spec/frontend/jobs/bridge/components/sidebar_spec.js @@ -7,6 +7,14 @@ import { mockCommit, mockJob } from '../mock_data'; describe('Bridge Sidebar', () => { let wrapper; + const MockHeaderEl = { + getBoundingClientRect() { + return { + bottom: '40', + }; + }, + }; + const createComponent = ({ featureFlag } = {}) => { wrapper = shallowMount(BridgeSidebar, { provide: { @@ -44,6 +52,17 @@ describe('Bridge Sidebar', () => { }); }); + describe('styles', () => { + beforeEach(async () => { + jest.spyOn(document, 'querySelector').mockReturnValue(MockHeaderEl); + createComponent(); + }); + + it('calculates root styles correctly', () => { + expect(wrapper.attributes('style')).toBe('width: 290px; top: 40px;'); + }); + }); + describe('sidebar expansion', () => { beforeEach(() => { createComponent(); diff --git a/spec/frontend/runner/runner_detail/runner_details_app_spec.js b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js index 64b2d3c30e2..ad0bce5c9af 100644 --- a/spec/frontend/runner/runner_detail/runner_details_app_spec.js +++ b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js @@ -7,7 +7,7 @@ import { createAlert } from '~/flash'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import RunnerHeader from '~/runner/components/runner_header.vue'; import getRunnerQuery from '~/runner/graphql/get_runner.query.graphql'; -import RunnerDetailsApp from '~/runner/runner_details/runner_details_app.vue'; +import AdminRunnerEditApp from '~//runner/admin_runner_edit/admin_runner_edit_app.vue'; import { captureException } from '~/runner/sentry_utils'; import { runnerData } from '../mock_data'; @@ -21,14 +21,14 @@ const mockRunnerId = `${getIdFromGraphQLId(mockRunnerGraphqlId)}`; const localVue = createLocalVue(); localVue.use(VueApollo); -describe('RunnerDetailsApp', () => { +describe('AdminRunnerEditApp', () => { let wrapper; let mockRunnerQuery; const findRunnerHeader = () => wrapper.findComponent(RunnerHeader); const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => { - wrapper = mountFn(RunnerDetailsApp, { + wrapper = mountFn(AdminRunnerEditApp, { localVue, apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]), propsData: { @@ -77,7 +77,7 @@ describe('RunnerDetailsApp', () => { it('error is reported to sentry', () => { expect(captureException).toHaveBeenCalledWith({ error: new Error('Network error: Error!'), - component: 'RunnerDetailsApp', + component: 'AdminRunnerEditApp', }); }); diff --git a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js index ec42782ab15..4233d86c24c 100644 --- a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js +++ b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js @@ -47,7 +47,7 @@ describe('RunnerTypeCell', () => { runner: { id: mockRunner.id, shortSha: mockRunner.shortSha, - adminUrl: mockRunner.adminUrl, + editAdminUrl: mockRunner.editAdminUrl, userPermissions: mockRunner.userPermissions, active: mockRunner.active, ...runner, @@ -103,7 +103,7 @@ describe('RunnerTypeCell', () => { it('Displays the runner edit link with the correct href', () => { createComponent(); - expect(findEditBtn().attributes('href')).toBe(mockRunner.adminUrl); + expect(findEditBtn().attributes('href')).toBe(mockRunner.editAdminUrl); }); it('Does not render the runner edit link when user cannot update', () => { @@ -117,9 +117,9 @@ describe('RunnerTypeCell', () => { expect(findEditBtn().exists()).toBe(false); }); - it('Does not render the runner edit link when adminUrl is not provided', () => { + it('Does not render the runner edit link when editAdminUrl is not provided', () => { createComponent({ - adminUrl: null, + editAdminUrl: null, }); expect(findEditBtn().exists()).toBe(false); diff --git a/spec/frontend/runner/runner_detail/runner_update_form_utils_spec.js b/spec/frontend/runner/runner_update_form_utils_spec.js index 510b4e604ac..a633aee92f7 100644 --- a/spec/frontend/runner/runner_detail/runner_update_form_utils_spec.js +++ b/spec/frontend/runner/runner_update_form_utils_spec.js @@ -1,8 +1,5 @@ import { ACCESS_LEVEL_NOT_PROTECTED } from '~/runner/constants'; -import { - modelToUpdateMutationVariables, - runnerToModel, -} from '~/runner/runner_details/runner_update_form_utils'; +import { modelToUpdateMutationVariables, runnerToModel } from '~/runner/runner_update_form_utils'; const mockId = 'gid://gitlab/Ci::Runner/1'; const mockDescription = 'Runner Desc.'; @@ -23,7 +20,7 @@ const mockModel = { tagList: 'tag-1, tag-2', }; -describe('~/runner/runner_details/runner_update_form_utils', () => { +describe('~/runner/runner_update_form_utils', () => { describe('runnerToModel', () => { it('collects all model data', () => { expect(runnerToModel(mockRunner)).toEqual(mockModel); diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js index 3ed5e2c0518..5865c6a41b8 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js @@ -10,10 +10,7 @@ import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; -import { - DEFAULT_LABEL_ANY, - DEFAULT_NONE_ANY, -} from '~/vue_shared/components/filtered_search_bar/constants'; +import { DEFAULT_NONE_ANY } from '~/vue_shared/components/filtered_search_bar/constants'; import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue'; import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue'; @@ -276,7 +273,7 @@ describe('AuthorToken', () => { expect(wrapper.find(GlDropdownDivider).exists()).toBe(false); }); - it('renders `DEFAULT_LABEL_ANY` as default suggestions', async () => { + it('renders `DEFAULT_NONE_ANY` as default suggestions', async () => { wrapper = createComponent({ active: true, config: { ...mockAuthorToken, preloadedAuthors: mockPreloadedAuthors }, @@ -287,8 +284,9 @@ describe('AuthorToken', () => { const suggestions = wrapper.findAll(GlFilteredSearchSuggestion); - expect(suggestions).toHaveLength(1 + currentUserLength); - expect(suggestions.at(0).text()).toBe(DEFAULT_LABEL_ANY.text); + expect(suggestions).toHaveLength(2 + currentUserLength); + expect(suggestions.at(0).text()).toBe(DEFAULT_NONE_ANY[0].text); + expect(suggestions.at(1).text()).toBe(DEFAULT_NONE_ANY[1].text); }); it('emits listeners in the base-token', () => { diff --git a/spec/lib/gitlab/email/failure_handler_spec.rb b/spec/lib/gitlab/email/failure_handler_spec.rb new file mode 100644 index 00000000000..a912996e8f2 --- /dev/null +++ b/spec/lib/gitlab/email/failure_handler_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Email::FailureHandler do + let(:raw_message) { fixture_file('emails/valid_reply.eml') } + let(:receiver) { Gitlab::Email::Receiver.new(raw_message) } + + context 'email processing errors' do + where(:error, :message, :can_retry) do + [ + [Gitlab::Email::UnknownIncomingEmail, "We couldn't figure out what the email is for", false], + [Gitlab::Email::SentNotificationNotFoundError, "We couldn't figure out what the email is in reply to", false], + [Gitlab::Email::ProjectNotFound, "We couldn't find the project", false], + [Gitlab::Email::EmptyEmailError, "It appears that the email is blank", true], + [Gitlab::Email::UserNotFoundError, "We couldn't figure out what user corresponds to the email", false], + [Gitlab::Email::UserBlockedError, "Your account has been blocked", false], + [Gitlab::Email::UserNotAuthorizedError, "You are not allowed to perform this action", false], + [Gitlab::Email::NoteableNotFoundError, "The thread you are replying to no longer exists", false], + [Gitlab::Email::InvalidAttachment, "Could not deal with that", false], + [Gitlab::Email::InvalidRecordError, "The note could not be created for the following reasons", true], + [Gitlab::Email::EmailTooLarge, "it is too large", false] + ] + end + + with_them do + it "sends out a rejection email for #{params[:error]}" do + perform_enqueued_jobs do + described_class.handle(receiver, error.new(message)) + end + + email = ActionMailer::Base.deliveries.last + expect(email).not_to be_nil + expect(email.to).to match_array(["jake@adventuretime.ooo"]) + expect(email.subject).to include("Rejected") + expect(email.body.parts.last.to_s).to include(message) + end + + it 'strips out the body before passing to EmailRejectionMailer' do + mail = Mail.new(raw_message) + mail.body = nil + + expect(EmailRejectionMailer).to receive(:rejection).with(match(message), mail.encoded, can_retry).and_call_original + + described_class.handle(receiver, error.new(message)) + end + end + end + + context 'non-processing errors' do + where(:error) do + [ + [Gitlab::Email::AutoGeneratedEmailError.new("")], + [ActiveRecord::StatementTimeout.new("StatementTimeout")], + [RateLimitedService::RateLimitedError.new(key: :issues_create, rate_limiter: nil)] + ] + end + + with_them do + it "does not send a rejection email for #{params[:error]}" do + perform_enqueued_jobs do + described_class.handle(receiver, error) + end + + expect(ActionMailer::Base.deliveries).to be_empty + end + end + end +end diff --git a/spec/models/ci/job_token/project_scope_link_spec.rb b/spec/models/ci/job_token/project_scope_link_spec.rb index dd6a75dfd89..8d7bb44bd16 100644 --- a/spec/models/ci/job_token/project_scope_link_spec.rb +++ b/spec/models/ci/job_token/project_scope_link_spec.rb @@ -9,6 +9,11 @@ RSpec.describe Ci::JobToken::ProjectScopeLink do let_it_be(:project) { create(:project) } + it_behaves_like 'cleanup by a loose foreign key' do + let!(:parent) { create(:user) } + let!(:model) { create(:ci_job_token_project_scope_link, added_by: parent) } + end + describe 'unique index' do let!(:link) { create(:ci_job_token_project_scope_link) } diff --git a/spec/models/ci/pending_build_spec.rb b/spec/models/ci/pending_build_spec.rb index 3cc922371ec..5692444339f 100644 --- a/spec/models/ci/pending_build_spec.rb +++ b/spec/models/ci/pending_build_spec.rb @@ -228,4 +228,9 @@ RSpec.describe Ci::PendingBuild do let!(:parent) { create(:namespace) } let!(:model) { create(:ci_pending_build, namespace: parent) } end + + it_behaves_like 'cleanup by a loose foreign key' do + let!(:parent) { create(:project) } + let!(:model) { create(:ci_pending_build, project: parent) } + end end diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb index fee74f8f674..0f1cb721e95 100644 --- a/spec/models/ci/pipeline_schedule_spec.rb +++ b/spec/models/ci/pipeline_schedule_spec.rb @@ -23,6 +23,11 @@ RSpec.describe Ci::PipelineSchedule do subject { build(:ci_pipeline_schedule, project: project) } end + it_behaves_like 'cleanup by a loose foreign key' do + let!(:parent) { create(:user) } + let!(:model) { create(:ci_pipeline_schedule, owner: parent) } + end + describe 'validations' do it 'does not allow invalid cron patterns' do pipeline_schedule = build(:ci_pipeline_schedule, cron: '0 0 0 * *') diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index 2330147b376..cf66ba83e87 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -141,6 +141,11 @@ RSpec.describe Group, 'Routable', :with_clean_rails_cache do end end + it 'creates route with namespace referencing group' do + expect(group.route).not_to be_nil + expect(group.route.namespace).to eq(group) + end + describe '.where_full_path_in' do context 'without any paths' do it 'returns an empty relation' do @@ -208,30 +213,20 @@ RSpec.describe Project, 'Routable', :with_clean_rails_cache do it_behaves_like 'routable resource with parent' do let_it_be(:record) { project } end + + it 'creates route with namespace referencing project namespace' do + expect(project.route).not_to be_nil + expect(project.route.namespace).to eq(project.project_namespace) + end end RSpec.describe Namespaces::ProjectNamespace, 'Routable', :with_clean_rails_cache do let_it_be(:group) { create(:group) } - let_it_be(:project_namespace) do - # For now we create only project namespace w/o project, otherwise same path - # would be used for project and project namespace. - # This can be removed when route is created automatically for project namespaces. - # https://gitlab.com/gitlab-org/gitlab/-/issues/346448 - create(:project_namespace, project: nil, parent: group, - visibility_level: Gitlab::VisibilityLevel::PUBLIC, - path: 'foo', name: 'foo').tap do |project_namespace| - Route.create!(source: project_namespace, path: project_namespace.full_path, - name: project_namespace.full_name) - end - end - - # we have couple of places where we use generic Namespace, in that case - # we don't want to include ProjectNamespace routes yet - it 'ignores project namespace when searching for generic namespace' do - redirect_route = create(:redirect_route, source: project_namespace) - expect(Namespace.find_by_full_path(project_namespace.full_path)).to be_nil - expect(Namespace.find_by_full_path(redirect_route.path, follow_redirects: true)).to be_nil + it 'skips route creation for the resource' do + expect do + described_class.create!(project: nil, parent: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC, path: 'foo', name: 'foo') + end.not_to change { Route.count } end end diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index d1fe988f294..b76063bfa1a 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Email do end describe 'validations' do - it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :email do + it_behaves_like 'an object with email-formatted attributes', :email do subject { build(:email) } end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 674aca0a37b..b523f60d045 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -436,7 +436,7 @@ RSpec.describe User do subject { build(:user) } end - it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :public_email, :notification_email do + it_behaves_like 'an object with email-formatted attributes', :public_email, :notification_email do subject { create(:user).tap { |user| user.emails << build(:email, email: email_value, confirmed_at: Time.current) } } end diff --git a/spec/requests/api/internal/mail_room_spec.rb b/spec/requests/api/internal/mail_room_spec.rb index 51abe92a125..f3ca3708c0c 100644 --- a/spec/requests/api/internal/mail_room_spec.rb +++ b/spec/requests/api/internal/mail_room_spec.rb @@ -100,17 +100,26 @@ RSpec.describe API::Internal::MailRoom do ) end - it 'responds with 400 bad request' do - Sidekiq::Testing.fake! do - expect do - post api("/internal/mail_room/incoming_email"), headers: auth_headers, params: email_content - end.not_to change { EmailReceiverWorker.jobs.size } + it 'responds with 400 bad request and replies with a failure message' do + perform_enqueued_jobs do + Sidekiq::Testing.fake! do + expect do + post api("/internal/mail_room/incoming_email"), headers: auth_headers, params: email_content + end.not_to change { EmailReceiverWorker.jobs.size } + end end expect(response).to have_gitlab_http_status(:bad_request) expect(Gitlab::Json.parse(response.body)).to match a_hash_including( - { "success" => false, "message" => "EmailReceiverWorker job exceeds payload size limit" } + "success" => false, + "message" => "We couldn't process your email because it is too large. Please create your issue or comment through the web interface." ) + + email = ActionMailer::Base.deliveries.last + expect(email).not_to be_nil + expect(email.to).to match_array(["jake@adventuretime.ooo"]) + expect(email.subject).to include("Rejected") + expect(email.body.parts.last.to_s).to include("We couldn't process your email") end end diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb index 83720ee132b..dba535654a1 100644 --- a/spec/workers/email_receiver_worker_spec.rb +++ b/spec/workers/email_receiver_worker_spec.rb @@ -21,87 +21,45 @@ RSpec.describe EmailReceiverWorker, :mailer do context "when an error occurs" do before do allow_any_instance_of(Gitlab::Email::Receiver).to receive(:execute).and_raise(error) - expect(Sidekiq.logger).to receive(:error).with(hash_including('exception.class' => error.class.name)).and_call_original end - context 'when the error is Gitlab::Email::EmptyEmailError' do + context 'when error is a processing error' do let(:error) { Gitlab::Email::EmptyEmailError.new } - it 'sends out a rejection email' do - perform_enqueued_jobs do - described_class.new.perform(raw_message) + it 'triggers email failure handler' do + expect(Gitlab::Email::FailureHandler).to receive(:handle) do |receiver, received_error| + expect(receiver).to be_a(Gitlab::Email::Receiver) + expect(receiver.mail.encoded).to eql(Mail::Message.new(raw_message).encoded) + expect(received_error).to be(error) end - email = ActionMailer::Base.deliveries.last - expect(email).not_to be_nil - expect(email.to).to eq(["jake@adventuretime.ooo"]) - expect(email.subject).to include("Rejected") - end - - it 'strips out the body before passing to EmailRejectionMailer' do - mail = Mail.new(raw_message) - mail.body = nil - - expect(EmailRejectionMailer).to receive(:rejection).with(anything, mail.encoded, anything).and_call_original - described_class.new.perform(raw_message) end - end - - context 'when the error is Gitlab::Email::AutoGeneratedEmailError' do - let(:error) { Gitlab::Email::AutoGeneratedEmailError.new } - - it 'does not send out any rejection email' do - perform_enqueued_jobs do - described_class.new.perform(raw_message) - end - - should_not_email_anyone - end - end - context 'when the error is Gitlab::Email::InvalidAttachment' do - let(:error) { Gitlab::Email::InvalidAttachment.new("Could not deal with that") } + it 'logs the error' do + expect(Sidekiq.logger).to receive(:error).with(hash_including('exception.class' => error.class.name)).and_call_original - it 'reports the error to the sender' do - perform_enqueued_jobs do - described_class.new.perform(raw_message) - end - - email = ActionMailer::Base.deliveries.last - expect(email).not_to be_nil - expect(email.to).to eq(["jake@adventuretime.ooo"]) - expect(email.body.parts.last.to_s).to include("Could not deal with that") + described_class.new.perform(raw_message) end end - context 'when the error is ActiveRecord::StatementTimeout' do + context 'when error is not a processing error' do let(:error) { ActiveRecord::StatementTimeout.new("Statement timeout") } - it 'does not report the error to the sender' do - expect(Gitlab::ErrorTracking).to receive(:track_exception).with(error).and_call_original - - perform_enqueued_jobs do - described_class.new.perform(raw_message) + it 'triggers email failure handler' do + expect(Gitlab::Email::FailureHandler).to receive(:handle) do |receiver, received_error| + expect(receiver).to be_a(Gitlab::Email::Receiver) + expect(receiver.mail.encoded).to eql(Mail::Message.new(raw_message).encoded) + expect(received_error).to be(error) end - email = ActionMailer::Base.deliveries.last - expect(email).to be_nil + described_class.new.perform(raw_message) end - end - - context 'when the error is RateLimitedService::RateLimitedError' do - let(:error) { RateLimitedService::RateLimitedError.new(key: :issues_create, rate_limiter: Gitlab::ApplicationRateLimiter) } - it 'does not report the error to the sender' do + it 'reports the error' do expect(Gitlab::ErrorTracking).to receive(:track_exception).with(error).and_call_original - perform_enqueued_jobs do - described_class.new.perform(raw_message) - end - - email = ActionMailer::Base.deliveries.last - expect(email).to be_nil + described_class.new.perform(raw_message) end end end |