diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-12 15:35:06 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-12 15:35:06 +0000 |
commit | 012cbda407a30ab14e57ece581d720b22b47fe5a (patch) | |
tree | 62a559d2a0843d2d9700af1bb01a15cbfcee2190 /spec | |
parent | 92acfb1b8a9019b3fa3c817d251b2624d55da26d (diff) | |
download | gitlab-ce-012cbda407a30ab14e57ece581d720b22b47fe5a.tar.gz |
Add latest changes from gitlab-org/gitlab@14-3-stable-ee
Diffstat (limited to 'spec')
6 files changed, 123 insertions, 162 deletions
diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb index a0e2cf671af..ca63760d988 100644 --- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb +++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb @@ -37,11 +37,12 @@ RSpec.describe Profiles::TwoFactorAuthsController do shared_examples 'user must enter a valid current password' do let(:current_password) { '123' } + let(:redirect_path) { profile_two_factor_auth_path } it 'requires the current password', :aggregate_failures do go - expect(response).to redirect_to(profile_two_factor_auth_path) + expect(response).to redirect_to(redirect_path) expect(flash[:alert]).to eq(_('You must provide a valid current password')) end @@ -54,6 +55,19 @@ RSpec.describe Profiles::TwoFactorAuthsController do expect(user.reload).to be_access_locked end end + + context 'when user authenticates with an external service' do + before do + allow(user).to receive(:password_automatically_set?).and_return(true) + end + + it 'does not require the current password', :aggregate_failures do + go + + expect(response).not_to redirect_to(redirect_path) + expect(flash[:alert]).to be_nil + end + end end describe 'GET show' do @@ -194,7 +208,9 @@ RSpec.describe Profiles::TwoFactorAuthsController do end describe 'DELETE destroy' do - subject { delete :destroy, params: { current_password: current_password } } + def go + delete :destroy, params: { current_password: current_password } + end let(:current_password) { user.password } @@ -202,40 +218,38 @@ RSpec.describe Profiles::TwoFactorAuthsController do let_it_be_with_reload(:user) { create(:user, :two_factor) } it 'disables two factor' do - subject + go expect(user.reload.two_factor_enabled?).to eq(false) end it 'redirects to profile_account_path' do - subject + go expect(response).to redirect_to(profile_account_path) end it 'displays a notice on success' do - subject + go expect(flash[:notice]) .to eq _('Two-factor authentication has been disabled successfully!') end - it_behaves_like 'user must enter a valid current password' do - let(:go) { delete :destroy, params: { current_password: current_password } } - end + it_behaves_like 'user must enter a valid current password' end context 'for a user that does not have 2FA enabled' do let_it_be_with_reload(:user) { create(:user) } it 'redirects to profile_account_path' do - subject + go expect(response).to redirect_to(profile_account_path) end it 'displays an alert on failure' do - subject + go expect(flash[:alert]) .to eq _('Two-factor authentication is not enabled for this user') diff --git a/spec/features/profiles/two_factor_auths_spec.rb b/spec/features/profiles/two_factor_auths_spec.rb index e1feca5031a..7f3ce617846 100644 --- a/spec/features/profiles/two_factor_auths_spec.rb +++ b/spec/features/profiles/two_factor_auths_spec.rb @@ -5,20 +5,16 @@ require 'spec_helper' RSpec.describe 'Two factor auths' do context 'when signed in' do before do - allow(Gitlab).to receive(:com?) { true } + sign_in(user) end context 'when user has two-factor authentication disabled' do - let(:user) { create(:user ) } - - before do - sign_in(user) - end + let_it_be(:user) { create(:user ) } it 'requires the current password to set up two factor authentication', :js do visit profile_two_factor_auth_path - register_2fa(user.reload.current_otp, '123') + register_2fa(user.current_otp, '123') expect(page).to have_content('You must provide a valid current password') @@ -31,14 +27,28 @@ RSpec.describe 'Two factor auths' do expect(page).to have_content('Status: Enabled') end - end - context 'when user has two-factor authentication enabled' do - let(:user) { create(:user, :two_factor) } + context 'when user authenticates with an external service' do + let_it_be(:user) { create(:omniauth_user, password_automatically_set: true) } + + it 'does not require the current password to set up two factor authentication', :js do + visit profile_two_factor_auth_path - before do - sign_in(user) + fill_in 'pin_code', with: user.current_otp + click_button 'Register with two-factor app' + + expect(page).to have_content('Please copy, download, or print your recovery codes before proceeding.') + + click_button 'Copy codes' + click_link 'Proceed' + + expect(page).to have_content('Status: Enabled') + end end + end + + context 'when user has two-factor authentication enabled' do + let_it_be(:user) { create(:user, :two_factor) } it 'requires the current_password to disable two-factor authentication', :js do visit profile_two_factor_auth_path @@ -61,7 +71,7 @@ RSpec.describe 'Two factor auths' do expect(page).to have_content('Enable two-factor authentication') end - it 'requires the current_password to regernate recovery codes', :js do + it 'requires the current_password to regenerate recovery codes', :js do visit profile_two_factor_auth_path fill_in 'current_password', with: '123' @@ -76,6 +86,29 @@ RSpec.describe 'Two factor auths' do expect(page).to have_content('Please copy, download, or print your recovery codes before proceeding.') end + + context 'when user authenticates with an external service' do + let_it_be(:user) { create(:omniauth_user, :two_factor, password_automatically_set: true) } + + it 'does not require the current_password to disable two-factor authentication', :js do + visit profile_two_factor_auth_path + + click_button 'Disable two-factor authentication' + + page.accept_alert + + expect(page).to have_content('Two-factor authentication has been disabled successfully!') + expect(page).to have_content('Enable two-factor authentication') + end + + it 'does not require the current_password to regenerate recovery codes', :js do + visit profile_two_factor_auth_path + + click_button 'Regenerate recovery codes' + + expect(page).to have_content('Please copy, download, or print your recovery codes before proceeding.') + end + end end def register_2fa(pin, password) diff --git a/spec/frontend/authentication/two_factor_auth/components/__snapshots__/manage_two_factor_form_spec.js.snap b/spec/frontend/authentication/two_factor_auth/components/__snapshots__/manage_two_factor_form_spec.js.snap deleted file mode 100644 index 3fe0e570a54..00000000000 --- a/spec/frontend/authentication/two_factor_auth/components/__snapshots__/manage_two_factor_form_spec.js.snap +++ /dev/null @@ -1,99 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ManageTwoFactorForm Disable button renders the component correctly 1`] = ` -VueWrapper { - "_emitted": Object {}, - "_emittedByOrder": Array [], - "isFunctionalComponent": undefined, -} -`; - -exports[`ManageTwoFactorForm Disable button renders the component correctly 2`] = ` -<form - action="#" - class="gl-display-inline-block" - method="post" -> - <input - data-testid="test-2fa-method-field" - name="_method" - type="hidden" - /> - - <input - name="authenticity_token" - type="hidden" - /> - - <div - class="form-group gl-form-group" - id="__BVID__15" - role="group" - > - <label - class="d-block col-form-label" - for="current-password" - id="__BVID__15__BV_label_" - > - Current password - </label> - <div - class="bv-no-focus-ring" - > - <input - aria-required="true" - class="gl-form-input form-control" - data-qa-selector="current_password_field" - id="current-password" - name="current_password" - required="required" - type="password" - /> - <!----> - <!----> - <!----> - </div> - </div> - - <button - class="btn btn-danger gl-mr-3 gl-display-inline-block btn-danger btn-md gl-button" - data-confirm="Are you sure? This will invalidate your registered applications and U2F devices." - data-form-action="2fa_auth_path" - data-form-method="2fa_auth_method" - data-testid="test-2fa-disable-button" - type="submit" - > - <!----> - - <!----> - - <span - class="gl-button-text" - > - - Disable two-factor authentication - - </span> - </button> - - <button - class="btn gl-display-inline-block btn-default btn-md gl-button" - data-form-action="2fa_codes_path" - data-form-method="2fa_codes_method" - data-testid="test-2fa-regenerate-codes-button" - type="submit" - > - <!----> - - <!----> - - <span - class="gl-button-text" - > - - Regenerate recovery codes - - </span> - </button> -</form> -`; diff --git a/spec/frontend/authentication/two_factor_auth/components/manage_two_factor_form_spec.js b/spec/frontend/authentication/two_factor_auth/components/manage_two_factor_form_spec.js index 384579c6876..61c6a1dd167 100644 --- a/spec/frontend/authentication/two_factor_auth/components/manage_two_factor_form_spec.js +++ b/spec/frontend/authentication/two_factor_auth/components/manage_two_factor_form_spec.js @@ -1,3 +1,4 @@ +import { GlForm } from '@gitlab/ui'; import { within } from '@testing-library/dom'; import { mount } from '@vue/test-utils'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; @@ -5,6 +6,13 @@ import ManageTwoFactorForm, { i18n, } from '~/authentication/two_factor_auth/components/manage_two_factor_form.vue'; +const defaultProvide = { + profileTwoFactorAuthPath: '2fa_auth_path', + profileTwoFactorAuthMethod: '2fa_auth_method', + codesProfileTwoFactorAuthPath: '2fa_codes_path', + codesProfileTwoFactorAuthMethod: '2fa_codes_method', +}; + describe('ManageTwoFactorForm', () => { let wrapper; @@ -12,11 +20,9 @@ describe('ManageTwoFactorForm', () => { wrapper = extendedWrapper( mount(ManageTwoFactorForm, { provide: { - webauthnEnabled: options?.webauthnEnabled || false, - profileTwoFactorAuthPath: '2fa_auth_path', - profileTwoFactorAuthMethod: '2fa_auth_method', - codesProfileTwoFactorAuthPath: '2fa_codes_path', - codesProfileTwoFactorAuthMethod: '2fa_codes_method', + ...defaultProvide, + webauthnEnabled: options?.webauthnEnabled ?? false, + isCurrentPasswordRequired: options?.currentPasswordRequired ?? true, }, }), ); @@ -26,6 +32,11 @@ describe('ManageTwoFactorForm', () => { const queryByLabelText = (text, options) => within(wrapper.element).queryByLabelText(text, options); + const findForm = () => wrapper.findComponent(GlForm); + const findMethodInput = () => wrapper.findByTestId('test-2fa-method-field'); + const findDisableButton = () => wrapper.findByTestId('test-2fa-disable-button'); + const findRegenerateCodesButton = () => wrapper.findByTestId('test-2fa-regenerate-codes-button'); + beforeEach(() => { createComponent(); }); @@ -36,16 +47,30 @@ describe('ManageTwoFactorForm', () => { }); }); + describe('when current password is not required', () => { + beforeEach(() => { + createComponent({ + currentPasswordRequired: false, + }); + }); + + it('does not render the current password field', () => { + expect(queryByLabelText(i18n.currentPassword)).toBe(null); + }); + }); + describe('Disable button', () => { - it('renders the component correctly', () => { - expect(wrapper).toMatchSnapshot(); - expect(wrapper.element).toMatchSnapshot(); + it('renders the component with correct attributes', () => { + expect(findDisableButton().exists()).toBe(true); + expect(findDisableButton().attributes()).toMatchObject({ + 'data-confirm': i18n.confirm, + 'data-form-action': defaultProvide.profileTwoFactorAuthPath, + 'data-form-method': defaultProvide.profileTwoFactorAuthMethod, + }); }); it('has the right confirm text', () => { - expect(wrapper.findByTestId('test-2fa-disable-button').element.dataset.confirm).toEqual( - i18n.confirm, - ); + expect(findDisableButton().attributes('data-confirm')).toBe(i18n.confirm); }); describe('when webauthnEnabled', () => { @@ -56,23 +81,19 @@ describe('ManageTwoFactorForm', () => { }); it('has the right confirm text', () => { - expect(wrapper.findByTestId('test-2fa-disable-button').element.dataset.confirm).toEqual( - i18n.confirmWebAuthn, - ); + expect(findDisableButton().attributes('data-confirm')).toBe(i18n.confirmWebAuthn); }); }); it('modifies the form action and method when submitted through the button', async () => { - const form = wrapper.find('form'); - const disableButton = wrapper.findByTestId('test-2fa-disable-button').element; - const methodInput = wrapper.findByTestId('test-2fa-method-field').element; + const form = findForm(); + const disableButton = findDisableButton().element; + const methodInput = findMethodInput(); - form.trigger('submit', { submitter: disableButton }); + await form.vm.$emit('submit', { submitter: disableButton }); - await wrapper.vm.$nextTick(); - - expect(form.element.getAttribute('action')).toEqual('2fa_auth_path'); - expect(methodInput.getAttribute('value')).toEqual('2fa_auth_method'); + expect(form.attributes('action')).toBe(defaultProvide.profileTwoFactorAuthPath); + expect(methodInput.attributes('value')).toBe(defaultProvide.profileTwoFactorAuthMethod); }); }); @@ -82,17 +103,14 @@ describe('ManageTwoFactorForm', () => { }); it('modifies the form action and method when submitted through the button', async () => { - const form = wrapper.find('form'); - const regenerateCodesButton = wrapper.findByTestId('test-2fa-regenerate-codes-button') - .element; - const methodInput = wrapper.findByTestId('test-2fa-method-field').element; - - form.trigger('submit', { submitter: regenerateCodesButton }); + const form = findForm(); + const regenerateCodesButton = findRegenerateCodesButton().element; + const methodInput = findMethodInput(); - await wrapper.vm.$nextTick(); + await form.vm.$emit('submit', { submitter: regenerateCodesButton }); - expect(form.element.getAttribute('action')).toEqual('2fa_codes_path'); - expect(methodInput.getAttribute('value')).toEqual('2fa_codes_method'); + expect(form.attributes('action')).toBe(defaultProvide.codesProfileTwoFactorAuthPath); + expect(methodInput.attributes('value')).toBe(defaultProvide.codesProfileTwoFactorAuthMethod); }); }); }); diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index d536a0783bc..e8aebe35302 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -2743,6 +2743,10 @@ RSpec.describe Group do it 'removes the protocol' do expect(group.dependency_proxy_image_prefix).not_to include('http') end + + it 'does not include /groups' do + expect(group.dependency_proxy_image_prefix).not_to include('/groups') + end end describe '#dependency_proxy_image_ttl_policy' do diff --git a/spec/services/merge_requests/mergeability_check_service_spec.rb b/spec/services/merge_requests/mergeability_check_service_spec.rb index 4f7be0f5965..65599b7e046 100644 --- a/spec/services/merge_requests/mergeability_check_service_spec.rb +++ b/spec/services/merge_requests/mergeability_check_service_spec.rb @@ -132,15 +132,6 @@ RSpec.describe MergeRequests::MergeabilityCheckService, :clean_gitlab_redis_shar it_behaves_like 'mergeable merge request' - it 'calls MergeToRefService with cache parameter' do - service = instance_double(MergeRequests::MergeToRefService) - - expect(MergeRequests::MergeToRefService).to receive(:new).once { service } - expect(service).to receive(:execute).once.with(merge_request, true).and_return(success: true) - - described_class.new(merge_request).execute(recheck: true) - end - context 'when concurrent calls' do it 'waits first lock and returns "cached" result in subsequent calls' do threads = execute_within_threads(amount: 3) |