diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 15:10:28 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 15:10:28 +0000 |
commit | 63324f9cfd863cda2f717835efc933cdd5ade792 (patch) | |
tree | 65717323c2d3f1f35ebff2441823f16aa9e27eb0 /spec | |
parent | 4944e9e5a9a3f57998c5033b10cdfa2975b71227 (diff) | |
download | gitlab-ce-63324f9cfd863cda2f717835efc933cdd5ade792.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
33 files changed, 297 insertions, 194 deletions
diff --git a/spec/features/merge_requests/user_filters_by_draft_spec.rb b/spec/features/merge_requests/user_filters_by_draft_spec.rb new file mode 100644 index 00000000000..de070805d96 --- /dev/null +++ b/spec/features/merge_requests/user_filters_by_draft_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Merge Requests > User filters by draft', :js do + include FilteredSearchHelpers + + let(:project) { create(:project, :public, :repository) } + let(:user) { project.creator } + + before do + create(:merge_request, title: 'Draft: Bugfix', source_project: project, target_project: project, source_branch: 'bugfix2') + + sign_in(user) + visit project_merge_requests_path(project) + end + + it 'filters results' do + input_filtered_search_keys('draft:=yes') + + expect(page).to have_content('Draft: Bugfix') + end + + it 'does not allow filtering by is not equal' do + find('#filtered-search-merge_requests').click + + click_button 'Draft' + + expect(page).not_to have_content('!=') + end +end diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 4326700bab1..5d3a00017f2 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -101,10 +101,10 @@ RSpec.describe 'Profile account page', :js do it 'changes my username' do fill_in 'username-change-input', with: 'new-username' - page.find('[data-target="#username-change-confirmation-modal"]').click + page.find('[data-testid="username-change-confirmation-modal"]').click page.within('.modal') do - find('.js-modal-primary-action').click + find('.js-modal-action-primary').click end expect(page).to have_content('new-username') diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb index 13ec12c50ea..62d8a96c1b2 100644 --- a/spec/features/profiles/account_spec.rb +++ b/spec/features/profiles/account_spec.rb @@ -128,10 +128,10 @@ def update_username(new_username) fill_in 'username-change-input', with: new_username - page.find('[data-target="#username-change-confirmation-modal"]').click + page.find('[data-testid="username-change-confirmation-modal"]').click page.within('.modal') do - find('.js-modal-primary-action').click + find('.js-modal-action-primary').click end wait_for_requests diff --git a/spec/frontend/profile/account/components/update_username_spec.js b/spec/frontend/profile/account/components/update_username_spec.js index be39a7f4d80..45e5e0f885f 100644 --- a/spec/frontend/profile/account/components/update_username_spec.js +++ b/spec/frontend/profile/account/components/update_username_spec.js @@ -1,173 +1,135 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import { GlModal } from '@gitlab/ui'; import MockAdapter from 'axios-mock-adapter'; import { TEST_HOST } from 'helpers/test_constants'; -import mountComponent from 'helpers/vue_mount_component_helper'; import axios from '~/lib/utils/axios_utils'; -import updateUsername from '~/profile/account/components/update_username.vue'; +import UpdateUsername from '~/profile/account/components/update_username.vue'; describe('UpdateUsername component', () => { const rootUrl = TEST_HOST; const actionUrl = `${TEST_HOST}/update/username`; - const username = 'hasnoname'; - const newUsername = 'new_username'; - let Component; - let vm; + const defaultProps = { + actionUrl, + rootUrl, + initialUsername: 'hasnoname', + }; + let wrapper; let axiosMock; + const createComponent = (props = {}) => { + wrapper = shallowMount(UpdateUsername, { + propsData: { + ...defaultProps, + ...props, + }, + stubs: { + GlModal, + }, + }); + }; + beforeEach(() => { axiosMock = new MockAdapter(axios); - Component = Vue.extend(updateUsername); - vm = mountComponent(Component, { - actionUrl, - rootUrl, - initialUsername: username, - }); + createComponent(); }); afterEach(() => { - vm.$destroy(); + wrapper.destroy(); axiosMock.restore(); }); const findElements = () => { - const modalSelector = `#${vm.$options.modalId}`; + const modal = wrapper.find(GlModal); return { - input: vm.$el.querySelector(`#${vm.$options.inputId}`), - openModalBtn: vm.$el.querySelector(`[data-target="${modalSelector}"]`), - modal: vm.$el.querySelector(modalSelector), - modalBody: vm.$el.querySelector(`${modalSelector} .modal-body`), - modalHeader: vm.$el.querySelector(`${modalSelector} .modal-title`), - confirmModalBtn: vm.$el.querySelector(`${modalSelector} .btn-warning`), + modal, + input: wrapper.find(`#${wrapper.vm.$options.inputId}`), + openModalBtn: wrapper.find('[data-testid="username-change-confirmation-modal"]'), + modalBody: modal.find('.modal-body'), + modalHeader: modal.find('.modal-title'), + confirmModalBtn: wrapper.find('.btn-warning'), }; }; - it('has a disabled button if the username was not changed', done => { - const { input, openModalBtn } = findElements(); - input.dispatchEvent(new Event('input')); - - Vue.nextTick() - .then(() => { - expect(vm.username).toBe(username); - expect(vm.newUsername).toBe(username); - expect(openModalBtn).toBeDisabled(); - }) - .then(done) - .catch(done.fail); + it('has a disabled button if the username was not changed', async () => { + const { openModalBtn } = findElements(); + + await wrapper.vm.$nextTick(); + + expect(openModalBtn.props('disabled')).toBe(true); }); - it('has an enabled button which if the username was changed', done => { + it('has an enabled button which if the username was changed', async () => { const { input, openModalBtn } = findElements(); - input.value = newUsername; - input.dispatchEvent(new Event('input')); - - Vue.nextTick() - .then(() => { - expect(vm.username).toBe(username); - expect(vm.newUsername).toBe(newUsername); - expect(openModalBtn).not.toBeDisabled(); - }) - .then(done) - .catch(done.fail); - }); - it('confirmation modal contains proper header and body', done => { - const { modalBody, modalHeader } = findElements(); + input.element.value = 'newUsername'; + input.trigger('input'); - vm.newUsername = newUsername; + await wrapper.vm.$nextTick(); - Vue.nextTick() - .then(() => { - expect(modalHeader.textContent).toContain('Change username?'); - expect(modalBody.textContent).toContain( - `You are going to change the username ${username} to ${newUsername}`, - ); - }) - .then(done) - .catch(done.fail); + expect(openModalBtn.props('disabled')).toBe(false); }); - it('confirmation modal should escape usernames properly', done => { - const { modalBody } = findElements(); + describe('changing username', () => { + const newUsername = 'new_username'; - vm.username = '<i>Italic</i>'; - vm.newUsername = vm.username; + beforeEach(async () => { + createComponent(); + wrapper.setData({ newUsername }); - Vue.nextTick() - .then(() => { - expect(modalBody.innerHTML).toContain('<i>Italic</i>'); - expect(modalBody.innerHTML).not.toContain(vm.username); - }) - .then(done) - .catch(done.fail); - }); + await wrapper.vm.$nextTick(); + }); - it('executes API call on confirmation button click', done => { - const { confirmModalBtn } = findElements(); + it('confirmation modal contains proper header and body', async () => { + const { modal } = findElements(); - axiosMock.onPut(actionUrl).replyOnce(() => [200, { message: 'Username changed' }]); - jest.spyOn(axios, 'put'); + expect(modal.attributes('title')).toBe('Change username?'); + expect(modal.text()).toContain( + `You are going to change the username ${defaultProps.initialUsername} to ${newUsername}`, + ); + }); - vm.newUsername = newUsername; + it('executes API call on confirmation button click', async () => { + axiosMock.onPut(actionUrl).replyOnce(() => [200, { message: 'Username changed' }]); + jest.spyOn(axios, 'put'); - Vue.nextTick() - .then(() => { - confirmModalBtn.click(); + await wrapper.vm.onConfirm(); + await wrapper.vm.$nextTick(); - expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } }); - }) - .then(done) - .catch(done.fail); - }); + expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } }); + }); - it('sets the username after a successful update', done => { - const { input, openModalBtn } = findElements(); + it('sets the username after a successful update', async () => { + const { input, openModalBtn } = findElements(); - axiosMock.onPut(actionUrl).replyOnce(() => { - expect(input).toBeDisabled(); - expect(openModalBtn).toBeDisabled(); + axiosMock.onPut(actionUrl).replyOnce(() => { + expect(input.attributes('disabled')).toBe('disabled'); + expect(openModalBtn.props('disabled')).toBe(true); - return [200, { message: 'Username changed' }]; + return [200, { message: 'Username changed' }]; + }); + + await wrapper.vm.onConfirm(); + await wrapper.vm.$nextTick(); + + expect(input.attributes('disabled')).toBe(undefined); + expect(openModalBtn.props('disabled')).toBe(true); }); - vm.newUsername = newUsername; - - vm.onConfirm() - .then(() => { - expect(vm.username).toBe(newUsername); - expect(vm.newUsername).toBe(newUsername); - expect(input).not.toBeDisabled(); - expect(input.value).toBe(newUsername); - expect(openModalBtn).toBeDisabled(); - }) - .then(done) - .catch(done.fail); - }); + it('does not set the username after a erroneous update', async () => { + const { input, openModalBtn } = findElements(); - it('does not set the username after a erroneous update', done => { - const { input, openModalBtn } = findElements(); + axiosMock.onPut(actionUrl).replyOnce(() => { + expect(input.attributes('disabled')).toBe('disabled'); + expect(openModalBtn.props('disabled')).toBe(true); - axiosMock.onPut(actionUrl).replyOnce(() => { - expect(input).toBeDisabled(); - expect(openModalBtn).toBeDisabled(); + return [400, { message: 'Invalid username' }]; + }); - return [400, { message: 'Invalid username' }]; + await expect(wrapper.vm.onConfirm()).rejects.toThrow(); + expect(input.attributes('disabled')).toBe(undefined); + expect(openModalBtn.props('disabled')).toBe(false); }); - - const invalidUsername = 'anything.git'; - vm.newUsername = invalidUsername; - - vm.onConfirm() - .then(() => done.fail('Expected onConfirm to throw!')) - .catch(() => { - expect(vm.username).toBe(username); - expect(vm.newUsername).toBe(invalidUsername); - expect(input).not.toBeDisabled(); - expect(input.value).toBe(invalidUsername); - expect(openModalBtn).not.toBeDisabled(); - }) - .then(done) - .catch(done.fail); }); }); diff --git a/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb new file mode 100644 index 00000000000..e6f76c8cd2d --- /dev/null +++ b/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::Ci::RunnerSetupResolver do + include GraphqlHelpers + + describe '#resolve' do + let(:user) { create(:user) } + + subject(:resolve_subject) { resolve(described_class, ctx: { current_user: user }, args: { platform: 'linux', architecture: 'amd64' }.merge(target_param)) } + + context 'without target parameter' do + let(:target_param) { {} } + + context 'when user is not admin' do + it 'returns access error' do + expect { resolve_subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + + context 'when user is admin' do + before do + user.update!(admin: true) + end + + it 'returns install and register instructions' do + expect(resolve_subject.keys).to contain_exactly(:install_instructions, :register_instructions) + expect(resolve_subject.values).not_to include(nil) + end + end + end + + context 'with project target parameter' do + let(:project) { create(:project) } + let(:target_param) { { project_id: project.to_global_id } } + + context 'when user has access to admin builds on project' do + before do + project.add_maintainer(user) + end + + it 'returns install and register instructions' do + expect(resolve_subject.keys).to contain_exactly(:install_instructions, :register_instructions) + expect(resolve_subject.values).not_to include(nil) + end + end + + context 'when user does not have access to admin builds on project' do + before do + project.add_developer(user) + end + + it 'returns access error' do + expect { resolve_subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + end + + context 'with group target parameter' do + let(:group) { create(:group) } + let(:target_param) { { group_id: group.to_global_id } } + + context 'when user has access to admin builds on group' do + before do + group.add_owner(user) + end + + it 'returns install and register instructions' do + expect(resolve_subject.keys).to contain_exactly(:install_instructions, :register_instructions) + expect(resolve_subject.values).not_to include(nil) + end + end + + context 'when user does not have access to admin builds on group' do + before do + group.add_developer(user) + end + + it 'returns access error' do + expect { resolve_subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) + end + end + end + end +end diff --git a/spec/graphql/types/ci/runner_setup_type_spec.rb b/spec/graphql/types/ci/runner_setup_type_spec.rb new file mode 100644 index 00000000000..197e717e964 --- /dev/null +++ b/spec/graphql/types/ci/runner_setup_type_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Types::Ci::RunnerSetupType do + specify { expect(described_class.graphql_name).to eq('RunnerSetup') } + + it 'exposes the expected fields' do + expected_fields = %i[ + install_instructions + register_instructions + ] + + expect(described_class).to have_graphql_fields(*expected_fields) + end +end diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb index 1d9ca8323f8..eee92fbb61d 100644 --- a/spec/graphql/types/query_type_spec.rb +++ b/spec/graphql/types/query_type_spec.rb @@ -80,4 +80,12 @@ RSpec.describe GitlabSchema.types['Query'] do is_expected.to have_graphql_type(Types::Ci::RunnerPlatformType.connection_type) end end + + describe 'runner_setup field' do + subject { described_class.fields['runnerSetup'] } + + it 'returns runner setup instructions' do + is_expected.to have_graphql_type(Types::Ci::RunnerSetupType) + end + end end diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb index f78cad74c5e..41c96c0989b 100644 --- a/spec/services/auth/container_registry_authentication_service_spec.rb +++ b/spec/services/auth/container_registry_authentication_service_spec.rb @@ -642,7 +642,7 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do let_it_be(:project) { create(:project, :public, container_registry_enabled: false) } before do - project.update(container_registry_enabled: false) + project.update!(container_registry_enabled: false) end context 'disallow when pulling' do diff --git a/spec/services/auto_merge/base_service_spec.rb b/spec/services/auto_merge/base_service_spec.rb index 98fa6012089..1d33dc15838 100644 --- a/spec/services/auto_merge/base_service_spec.rb +++ b/spec/services/auto_merge/base_service_spec.rb @@ -131,7 +131,7 @@ RSpec.describe AutoMerge::BaseService do end describe '#update' do - subject { service.update(merge_request) } + subject { service.update(merge_request) } # rubocop:disable Rails/SaveBang let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) } diff --git a/spec/services/auto_merge_service_spec.rb b/spec/services/auto_merge_service_spec.rb index eab95973e1b..3f7a26aa00e 100644 --- a/spec/services/auto_merge_service_spec.rb +++ b/spec/services/auto_merge_service_spec.rb @@ -148,7 +148,7 @@ RSpec.describe AutoMergeService do end describe '#update' do - subject { service.update(merge_request) } + subject { service.update(merge_request) } # rubocop:disable Rails/SaveBang context 'when auto merge is enabled' do let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) } diff --git a/spec/services/clusters/update_service_spec.rb b/spec/services/clusters/update_service_spec.rb index e496ccd5c23..9aead97f41c 100644 --- a/spec/services/clusters/update_service_spec.rb +++ b/spec/services/clusters/update_service_spec.rb @@ -197,7 +197,7 @@ RSpec.describe Clusters::UpdateService do context 'manangement_project is outside of the namespace scope' do before do - management_project.update(group: create(:group)) + management_project.update!(group: create(:group)) end let(:params) do @@ -224,7 +224,7 @@ RSpec.describe Clusters::UpdateService do context 'manangement_project is outside of the namespace scope' do before do - management_project.update(group: create(:group)) + management_project.update!(group: create(:group)) end let(:params) do diff --git a/spec/services/design_management/generate_image_versions_service_spec.rb b/spec/services/design_management/generate_image_versions_service_spec.rb index 749030af97d..e06b6fbf116 100644 --- a/spec/services/design_management/generate_image_versions_service_spec.rb +++ b/spec/services/design_management/generate_image_versions_service_spec.rb @@ -44,7 +44,7 @@ RSpec.describe DesignManagement::GenerateImageVersionsService do end it 'logs if the raw image cannot be found' do - version.designs.first.update(filename: 'foo.png') + version.designs.first.update!(filename: 'foo.png') expect(Gitlab::AppLogger).to receive(:error).with("No design file found for Action: #{action.id}") diff --git a/spec/services/discussions/resolve_service_spec.rb b/spec/services/discussions/resolve_service_spec.rb index 5ff0d535b46..42c4ef52741 100644 --- a/spec/services/discussions/resolve_service_spec.rb +++ b/spec/services/discussions/resolve_service_spec.rb @@ -40,11 +40,11 @@ RSpec.describe Discussions::ResolveService do context 'with a project that requires all discussion to be resolved' do before do - project.update(only_allow_merge_if_all_discussions_are_resolved: true) + project.update!(only_allow_merge_if_all_discussions_are_resolved: true) end after do - project.update(only_allow_merge_if_all_discussions_are_resolved: false) + project.update!(only_allow_merge_if_all_discussions_are_resolved: false) end let_it_be(:other_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion } diff --git a/spec/services/draft_notes/destroy_service_spec.rb b/spec/services/draft_notes/destroy_service_spec.rb index f725f08f3c7..1f246a56eb3 100644 --- a/spec/services/draft_notes/destroy_service_spec.rb +++ b/spec/services/draft_notes/destroy_service_spec.rb @@ -22,7 +22,7 @@ RSpec.describe DraftNotes::DestroyService do it 'destroys all draft notes for a user in a merge request' do create_list(:draft_note, 2, merge_request: merge_request, author: user) - expect { destroy }.to change { DraftNote.count }.by(-2) + expect { destroy }.to change { DraftNote.count }.by(-2) # rubocop:disable Rails/SaveBang expect(DraftNote.count).to eq(0) end @@ -45,7 +45,7 @@ RSpec.describe DraftNotes::DestroyService do allow_any_instance_of(DraftNote).to receive_message_chain(:diff_file, :unfolded?) { true } expect(merge_request).to receive_message_chain(:diffs, :clear_cache) - destroy + destroy # rubocop:disable Rails/SaveBang end end end diff --git a/spec/services/emails/confirm_service_spec.rb b/spec/services/emails/confirm_service_spec.rb index 935a673f548..d3a745bc744 100644 --- a/spec/services/emails/confirm_service_spec.rb +++ b/spec/services/emails/confirm_service_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Emails::ConfirmService do describe '#execute' do it 'enqueues a background job to send confirmation email again' do - email = user.emails.create(email: 'new@email.com') + email = user.emails.create!(email: 'new@email.com') expect { service.execute(email) }.to have_enqueued_job.on_queue('mailers') end diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb index 31afdba8192..e06f09d0463 100644 --- a/spec/services/groups/destroy_service_spec.rb +++ b/spec/services/groups/destroy_service_spec.rb @@ -95,7 +95,7 @@ RSpec.describe Groups::DestroyService do context 'projects in pending_delete' do before do project.pending_delete = true - project.save + project.save! end it_behaves_like 'group destruction', false diff --git a/spec/services/groups/import_export/import_service_spec.rb b/spec/services/groups/import_export/import_service_spec.rb index f284225e23a..f8cb55a9955 100644 --- a/spec/services/groups/import_export/import_service_spec.rb +++ b/spec/services/groups/import_export/import_service_spec.rb @@ -63,7 +63,7 @@ RSpec.describe Groups::ImportExport::ImportService do before do stub_feature_flags(group_import_ndjson: false) - ImportExportUpload.create(group: group, import_file: import_file) + ImportExportUpload.create!(group: group, import_file: import_file) allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger) allow(import_logger).to receive(:error) @@ -105,7 +105,7 @@ RSpec.describe Groups::ImportExport::ImportService do subject { service.execute } before do - ImportExportUpload.create(group: group, import_file: import_file) + ImportExportUpload.create!(group: group, import_file: import_file) allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger) allow(import_logger).to receive(:error) @@ -216,7 +216,7 @@ RSpec.describe Groups::ImportExport::ImportService do subject { service.execute } before do - ImportExportUpload.create(group: group, import_file: import_file) + ImportExportUpload.create!(group: group, import_file: import_file) allow(Gitlab::Import::Logger).to receive(:build).and_return(import_logger) allow(import_logger).to receive(:error) diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb index 7674ec36331..cc4be6720cc 100644 --- a/spec/services/labels/promote_service_spec.rb +++ b/spec/services/labels/promote_service_spec.rb @@ -89,10 +89,10 @@ RSpec.describe Labels::PromoteService do it 'keeps users\' subscriptions' do user2 = create(:user) - project_label_1_1.subscriptions.create(user: user, subscribed: true) - project_label_2_1.subscriptions.create(user: user, subscribed: true) - project_label_3_2.subscriptions.create(user: user, subscribed: true) - project_label_2_1.subscriptions.create(user: user2, subscribed: true) + project_label_1_1.subscriptions.create!(user: user, subscribed: true) + project_label_2_1.subscriptions.create!(user: user, subscribed: true) + project_label_3_2.subscriptions.create!(user: user, subscribed: true) + project_label_2_1.subscriptions.create!(user: user2, subscribed: true) expect { service.execute(project_label_1_1) }.to change { Subscription.count }.from(4).to(3) diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb index 1e5536a2d0b..70b5e70cab6 100644 --- a/spec/services/notes/create_service_spec.rb +++ b/spec/services/notes/create_service_spec.rb @@ -286,7 +286,7 @@ RSpec.describe Notes::CreateService do QuickAction.new( action_text: "/wip", before_action: -> { - issuable.reload.update(title: "title") + issuable.reload.update!(title: "title") }, expectation: ->(issuable, can_use_quick_action) { expect(issuable.work_in_progress?).to eq(can_use_quick_action) @@ -296,7 +296,7 @@ RSpec.describe Notes::CreateService do QuickAction.new( action_text: "/wip", before_action: -> { - issuable.reload.update(title: "WIP: title") + issuable.reload.update!(title: "WIP: title") }, expectation: ->(noteable, can_use_quick_action) { expect(noteable.work_in_progress?).not_to eq(can_use_quick_action) diff --git a/spec/services/notification_recipients/build_service_spec.rb b/spec/services/notification_recipients/build_service_spec.rb index 5c8add250c2..cc08f9fceff 100644 --- a/spec/services/notification_recipients/build_service_spec.rb +++ b/spec/services/notification_recipients/build_service_spec.rb @@ -44,7 +44,7 @@ RSpec.describe NotificationRecipients::BuildService do context 'when there are multiple subscribers' do def create_user subscriber = create(:user) - issue.subscriptions.create(user: subscriber, project: project, subscribed: true) + issue.subscriptions.create!(user: subscriber, project: project, subscribed: true) end include_examples 'no N+1 queries' @@ -96,7 +96,7 @@ RSpec.describe NotificationRecipients::BuildService do context 'when there are multiple subscribers' do def create_user subscriber = create(:user) - merge_request.subscriptions.create(user: subscriber, project: project, subscribed: true) + merge_request.subscriptions.create!(user: subscriber, project: project, subscribed: true) end include_examples 'no N+1 queries' diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index caa9961424e..99f52e01031 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -361,7 +361,7 @@ RSpec.describe NotificationService, :mailer do context 'where the project has disabled the feature' do before do - project.update(service_desk_enabled: false) + project.update!(service_desk_enabled: false) end it_should_not_email! @@ -453,7 +453,7 @@ RSpec.describe NotificationService, :mailer do context 'by note' do before do note.author = @u_lazy_participant - note.save + note.save! end it { expect { subject }.not_to have_enqueued_email(@u_lazy_participant.id, note.id, mail: "note_issue_email") } @@ -467,7 +467,7 @@ RSpec.describe NotificationService, :mailer do note.project.namespace_id = group.id group.add_user(@u_watcher, GroupMember::MAINTAINER) group.add_user(@u_custom_global, GroupMember::MAINTAINER) - note.project.save + note.project.save! @u_watcher.notification_settings_for(note.project).participating! @u_watcher.notification_settings_for(group).global! @@ -1719,7 +1719,7 @@ RSpec.describe NotificationService, :mailer do before do merge_request.author = participant - merge_request.save + merge_request.save! notification.new_merge_request(merge_request, @u_disabled) end @@ -1962,7 +1962,7 @@ RSpec.describe NotificationService, :mailer do describe 'when merge_when_pipeline_succeeds is true' do before do - merge_request.update( + merge_request.update!( merge_when_pipeline_succeeds: true, merge_user: create(:user) ) @@ -2725,7 +2725,7 @@ RSpec.describe NotificationService, :mailer do before do group = create(:group) - project.update(group: group) + project.update!(group: group) create(:email, :confirmed, user: u_custom_notification_enabled, email: group_notification_email) create(:notification_setting, user: u_custom_notification_enabled, source: group, notification_email: group_notification_email) @@ -2761,7 +2761,7 @@ RSpec.describe NotificationService, :mailer do before do group = create(:group) - project.update(group: group) + project.update!(group: group) create(:email, :confirmed, user: u_member, email: group_notification_email) create(:notification_setting, user: u_member, source: group, notification_email: group_notification_email) end @@ -2821,7 +2821,7 @@ RSpec.describe NotificationService, :mailer do context 'when the creator has no read_build access' do before do pipeline = create_pipeline(u_member, :failed) - project.update(public_builds: false) + project.update!(public_builds: false) project.team.truncate notification.pipeline_finished(pipeline) end @@ -2855,7 +2855,7 @@ RSpec.describe NotificationService, :mailer do before do group = create(:group) - project.update(group: group) + project.update!(group: group) create(:email, :confirmed, user: u_member, email: group_notification_email) create(:notification_setting, user: u_member, source: group, notification_email: group_notification_email) end @@ -3212,7 +3212,7 @@ RSpec.describe NotificationService, :mailer do # with different notification settings def build_group(project, visibility: :public) group = create_nested_group(visibility) - project.update(namespace_id: group.id) + project.update!(namespace_id: group.id) # Group member: global=disabled, group=watch @g_watcher ||= create_user_with_notification(:watch, 'group_watcher', project.group) @@ -3277,11 +3277,11 @@ RSpec.describe NotificationService, :mailer do end def add_user_subscriptions(issuable) - issuable.subscriptions.create(user: @unsubscribed_mentioned, project: project, subscribed: false) - issuable.subscriptions.create(user: @subscriber, project: project, subscribed: true) - issuable.subscriptions.create(user: @subscribed_participant, project: project, subscribed: true) - issuable.subscriptions.create(user: @unsubscriber, project: project, subscribed: false) + issuable.subscriptions.create!(user: @unsubscribed_mentioned, project: project, subscribed: false) + issuable.subscriptions.create!(user: @subscriber, project: project, subscribed: true) + issuable.subscriptions.create!(user: @subscribed_participant, project: project, subscribed: true) + issuable.subscriptions.create!(user: @unsubscriber, project: project, subscribed: false) # Make the watcher a subscriber to detect dupes - issuable.subscriptions.create(user: @watcher_and_subscriber, project: project, subscribed: true) + issuable.subscriptions.create!(user: @watcher_and_subscriber, project: project, subscribed: true) end end diff --git a/spec/services/packages/conan/create_package_file_service_spec.rb b/spec/services/packages/conan/create_package_file_service_spec.rb index 0e9cbba5fc1..bd6a91c883a 100644 --- a/spec/services/packages/conan/create_package_file_service_spec.rb +++ b/spec/services/packages/conan/create_package_file_service_spec.rb @@ -100,7 +100,7 @@ RSpec.describe Packages::Conan::CreatePackageFileService do end let(:tmp_object) do - fog_connection.directories.new(key: 'packages').files.create( + fog_connection.directories.new(key: 'packages').files.create( # rubocop:disable Rails/SaveBang key: "tmp/uploads/#{file_name}", body: 'content' ) diff --git a/spec/services/reset_project_cache_service_spec.rb b/spec/services/reset_project_cache_service_spec.rb index 3e79270da8d..165b38ee338 100644 --- a/spec/services/reset_project_cache_service_spec.rb +++ b/spec/services/reset_project_cache_service_spec.rb @@ -20,7 +20,7 @@ RSpec.describe ResetProjectCacheService do context 'when project cache_index is a numeric value' do before do - project.update(jobs_cache_index: 1) + project.update!(jobs_cache_index: 1) end it 'increments project cache index' do diff --git a/spec/services/resource_events/change_milestone_service_spec.rb b/spec/services/resource_events/change_milestone_service_spec.rb index 3a9dadbd40e..a2131c5c1b0 100644 --- a/spec/services/resource_events/change_milestone_service_spec.rb +++ b/spec/services/resource_events/change_milestone_service_spec.rb @@ -11,7 +11,7 @@ RSpec.describe ResourceEvents::ChangeMilestoneService do [:issue, :merge_request].each do |issuable| it_behaves_like 'timebox(milestone or iteration) resource events creator', ResourceMilestoneEvent do - let_it_be(:resource) { create(issuable) } + let_it_be(:resource) { create(issuable) } # rubocop:disable Rails/SaveBang end end end diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb index bdc40a92e91..b25837ca260 100644 --- a/spec/services/system_hooks_service_spec.rb +++ b/spec/services/system_hooks_service_spec.rb @@ -85,7 +85,7 @@ RSpec.describe SystemHooksService do end it 'handles nil datetime columns' do - user.update(created_at: nil, updated_at: nil) + user.update!(created_at: nil, updated_at: nil) data = event_data(user, :destroy) expect(data[:created_at]).to be(nil) diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 42e48b9ad81..abb0b79de84 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -378,13 +378,13 @@ RSpec.describe SystemNoteService do noteable_types.each do |type| context "when noteable is a #{type}" do it "blocks cross reference when #{type.underscore}_events is false" do - jira_tracker.update("#{type}_events" => false) + jira_tracker.update!("#{type}_events" => false) expect(cross_reference(type)).to eq(s_('JiraService|Events for %{noteable_model_name} are disabled.') % { noteable_model_name: type.pluralize.humanize.downcase }) end it "creates cross reference when #{type.underscore}_events is true" do - jira_tracker.update("#{type}_events" => true) + jira_tracker.update!("#{type}_events" => true) expect(cross_reference(type)).to eq(success_message) end diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb index e78b00fb67a..b70c5e899fc 100644 --- a/spec/services/system_notes/issuables_service_spec.rb +++ b/spec/services/system_notes/issuables_service_spec.rb @@ -373,7 +373,7 @@ RSpec.describe ::SystemNotes::IssuablesService do before do # Mention issue (noteable) from commit0 system_note = service.cross_reference(commit0) - system_note.update(note: system_note.note.capitalize) + system_note.update!(note: system_note.note.capitalize) end it 'is truthy when already mentioned' do @@ -407,7 +407,7 @@ RSpec.describe ::SystemNotes::IssuablesService do before do # Mention commit1 from commit0 system_note = service.cross_reference(commit1) - system_note.update(note: system_note.note.capitalize) + system_note.update!(note: system_note.note.capitalize) end it 'is truthy when already mentioned' do @@ -436,7 +436,7 @@ RSpec.describe ::SystemNotes::IssuablesService do context 'legacy capitalized cross reference' do before do system_note = service.cross_reference(commit0) - system_note.update(note: system_note.note.capitalize) + system_note.update!(note: system_note.note.capitalize) end it 'is true when a fork mentions an external issue' do @@ -582,7 +582,7 @@ RSpec.describe ::SystemNotes::IssuablesService do it 'creates the note text correctly' do [:issue, :merge_request].each do |type| - issuable = create(type) + issuable = create(type) # rubocop:disable Rails/SaveBang service = described_class.new(noteable: issuable, author: author) expect(service.discussion_lock.note) diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 60903f8f367..748003a26d1 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -145,7 +145,7 @@ RSpec.describe TodoService do end it 'creates correct todos for each valid user based on the type of mention' do - issue.update(description: directly_addressed_and_mentioned) + issue.update!(description: directly_addressed_and_mentioned) service.new_issue(issue, author) @@ -222,7 +222,7 @@ RSpec.describe TodoService do end it 'creates a todo for each valid user not included in skip_users based on the type of mention' do - issue.update(description: directly_addressed_and_mentioned) + issue.update!(description: directly_addressed_and_mentioned) service.update_issue(issue, author, skip_users) @@ -291,7 +291,7 @@ RSpec.describe TodoService do context 'issues with a task list' do it 'does not create todo when tasks are marked as completed' do - issue.update(description: "- [x] Task 1\n- [X] Task 2 #{mentions}") + issue.update!(description: "- [x] Task 1\n- [X] Task 2 #{mentions}") service.update_issue(issue, author) @@ -304,7 +304,7 @@ RSpec.describe TodoService do end it 'does not create directly addressed todo when tasks are marked as completed' do - addressed_issue.update(description: "#{directly_addressed}\n- [x] Task 1\n- [x] Task 2\n") + addressed_issue.update!(description: "#{directly_addressed}\n- [x] Task 1\n- [x] Task 2\n") service.update_issue(addressed_issue, author) @@ -317,7 +317,7 @@ RSpec.describe TodoService do end it 'does not raise an error when description not change' do - issue.update(title: 'Sample') + issue.update!(title: 'Sample') expect { service.update_issue(issue, author) }.not_to raise_error end @@ -427,7 +427,7 @@ RSpec.describe TodoService do end it 'creates a todo for each valid user based on the type of mention' do - note.update(note: directly_addressed_and_mentioned) + note.update!(note: directly_addressed_and_mentioned) service.new_note(note, john_doe) @@ -694,7 +694,7 @@ RSpec.describe TodoService do end it 'creates a todo for each valid user based on the type of mention' do - mr_assigned.update(description: directly_addressed_and_mentioned) + mr_assigned.update!(description: directly_addressed_and_mentioned) service.new_merge_request(mr_assigned, author) @@ -726,7 +726,7 @@ RSpec.describe TodoService do end it 'creates a todo for each valid user not included in skip_users based on the type of mention' do - mr_assigned.update(description: directly_addressed_and_mentioned) + mr_assigned.update!(description: directly_addressed_and_mentioned) service.update_merge_request(mr_assigned, author, skip_users) @@ -772,7 +772,7 @@ RSpec.describe TodoService do context 'with a task list' do it 'does not create todo when tasks are marked as completed' do - mr_assigned.update(description: "- [x] Task 1\n- [X] Task 2 #{mentions}") + mr_assigned.update!(description: "- [x] Task 1\n- [X] Task 2 #{mentions}") service.update_merge_request(mr_assigned, author) @@ -786,7 +786,7 @@ RSpec.describe TodoService do end it 'does not create directly addressed todo when tasks are marked as completed' do - addressed_mr_assigned.update(description: "#{directly_addressed}\n- [x] Task 1\n- [X] Task 2") + addressed_mr_assigned.update!(description: "#{directly_addressed}\n- [x] Task 1\n- [X] Task 2") service.update_merge_request(addressed_mr_assigned, author) @@ -800,7 +800,7 @@ RSpec.describe TodoService do end it 'does not raise an error when description not change' do - mr_assigned.update(title: 'Sample') + mr_assigned.update!(title: 'Sample') expect { service.update_merge_request(mr_assigned, author) }.not_to raise_error end @@ -883,7 +883,7 @@ RSpec.describe TodoService do end it 'creates a pending todo for each merge_participant' do - mr_unassigned.update(merge_when_pipeline_succeeds: true, merge_user: admin) + mr_unassigned.update!(merge_when_pipeline_succeeds: true, merge_user: admin) service.merge_request_became_unmergeable(mr_unassigned) merge_participants.each do |participant| @@ -991,7 +991,7 @@ RSpec.describe TodoService do end it 'creates a todo for each valid user not included in skip_users based on the type of mention' do - note.update(note: directly_addressed_and_mentioned) + note.update!(note: directly_addressed_and_mentioned) service.update_note(note, author, skip_users) diff --git a/spec/services/todos/destroy/confidential_issue_service_spec.rb b/spec/services/todos/destroy/confidential_issue_service_spec.rb index ddce45e7968..e3dcc2bae95 100644 --- a/spec/services/todos/destroy/confidential_issue_service_spec.rb +++ b/spec/services/todos/destroy/confidential_issue_service_spec.rb @@ -37,7 +37,7 @@ RSpec.describe Todos::Destroy::ConfidentialIssueService do context 'when provided issue is not confidential' do it 'does not remove any todos' do - issue_1.update(confidential: false) + issue_1.update!(confidential: false) expect { subject }.not_to change { Todo.count } end diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb index 6de685dd89a..3dafc896b00 100644 --- a/spec/services/users/destroy_service_spec.rb +++ b/spec/services/users/destroy_service_spec.rb @@ -108,7 +108,7 @@ RSpec.describe Users::DestroyService do context 'projects in pending_delete' do before do project.pending_delete = true - project.save + project.save! end it 'destroys a project in pending_delete' do @@ -310,7 +310,7 @@ RSpec.describe Users::DestroyService do it 'of group_members' do group_member = create(:group_member) - group_member.group.group_members.create(user: user, access_level: 40) + group_member.group.group_members.create!(user: user, access_level: 40) expect_any_instance_of(GroupMember).to receive(:run_callbacks).with(:find).once expect_any_instance_of(GroupMember).to receive(:run_callbacks).with(:initialize).once diff --git a/spec/services/users/repair_ldap_blocked_service_spec.rb b/spec/services/users/repair_ldap_blocked_service_spec.rb index b33dcb92f45..54540d68af2 100644 --- a/spec/services/users/repair_ldap_blocked_service_spec.rb +++ b/spec/services/users/repair_ldap_blocked_service_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Users::RepairLdapBlockedService do describe '#execute' do it 'changes to normal block after destroying last ldap identity' do - identity.destroy + identity.destroy! service.execute expect(user.reload).not_to be_ldap_blocked diff --git a/spec/services/verify_pages_domain_service_spec.rb b/spec/services/verify_pages_domain_service_spec.rb index 29ad85a16ce..ae079229891 100644 --- a/spec/services/verify_pages_domain_service_spec.rb +++ b/spec/services/verify_pages_domain_service_spec.rb @@ -189,7 +189,7 @@ RSpec.describe VerifyPagesDomainService do let(:domain) { build(:pages_domain, :expired, :with_missing_chain) } before do - domain.save(validate: false) + domain.save!(validate: false) end it 'can be disabled' do diff --git a/spec/sidekiq/cron/job_gem_dependency_spec.rb b/spec/sidekiq/cron/job_gem_dependency_spec.rb index 2924c86c8d0..38c658feba6 100644 --- a/spec/sidekiq/cron/job_gem_dependency_spec.rb +++ b/spec/sidekiq/cron/job_gem_dependency_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Sidekiq::Cron::Job do context 'when Fugit depends on ZoTime or EoTime' do before do described_class - .create(name: 'TestCronWorker', + .create(name: 'TestCronWorker', # rubocop:disable Rails/SaveBang cron: Settings.cron_jobs[:pipeline_schedule_worker]['cron'], class: Settings.cron_jobs[:pipeline_schedule_worker]['job_class']) end |