Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-17 12:07:48 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-17 12:07:48 +0300
commit5bd24a54ef4ce3a38a860eb53b66d062c2382971 (patch)
tree5f5e65571dfcb2c62c27600ee7655dec4b44c923 /spec
parent74673d04d25ffed35cbcf17cd42969bed0a4e705 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/merge_requests.rb4
-rw-r--r--spec/features/groups/clusters/user_spec.rb8
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb8
-rw-r--r--spec/features/projects/clusters/user_spec.rb8
-rw-r--r--spec/finders/keys_finder_spec.rb153
-rw-r--r--spec/finders/merge_request_target_project_finder_spec.rb16
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb10
-rw-r--r--spec/frontend/boards/boards_store_spec.js1
-rw-r--r--spec/frontend/clusters/clusters_bundle_spec.js1
-rw-r--r--spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap80
-rw-r--r--spec/frontend/clusters/components/remove_cluster_confirmation_spec.js57
-rw-r--r--spec/frontend/commit/commit_pipeline_status_component_spec.js1
-rw-r--r--spec/frontend/create_cluster/eks_cluster/store/actions_spec.js11
-rw-r--r--spec/frontend/ide/components/preview/clientside_spec.js4
-rw-r--r--spec/frontend/ide/stores/modules/pipelines/actions_spec.js2
-rw-r--r--spec/frontend/issuables_list/components/issuables_list_app_spec.js1
-rw-r--r--spec/frontend/jest_self_check/mocks_spec.js43
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js1
-rw-r--r--spec/frontend/pages/admin/users/components/user_modal_manager_spec.js4
-rw-r--r--spec/frontend/project_find_file_spec.js45
-rw-r--r--spec/frontend/registry/list/components/app_spec.js1
-rw-r--r--spec/frontend/repository/components/table/row_spec.js1
-rw-r--r--spec/frontend/sentry/sentry_config_spec.js7
-rw-r--r--spec/frontend/sidebar/confidential_issue_sidebar_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap1
-rw-r--r--spec/models/key_spec.rb26
-rw-r--r--spec/models/personal_access_token_spec.rb12
-rw-r--r--spec/models/project_spec.rb4
-rw-r--r--spec/models/user_spec.rb8
-rw-r--r--spec/requests/projects/merge_requests/creations_spec.rb28
30 files changed, 432 insertions, 115 deletions
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 42248dc1165..2344ffffa65 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -188,6 +188,10 @@ FactoryBot.define do
end
end
+ trait :sequence_source_branch do
+ sequence(:source_branch) { |n| "feature#{n}" }
+ end
+
after(:build) do |merge_request|
target_project = merge_request.target_project
source_project = merge_request.source_project
diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb
index e06f2efe183..ceec50e4f58 100644
--- a/spec/features/groups/clusters/user_spec.rb
+++ b/spec/features/groups/clusters/user_spec.rb
@@ -115,11 +115,11 @@ describe 'User Cluster', :js do
end
end
- context 'when user destroy the cluster' do
+ context 'when user destroys the cluster' do
before do
- page.accept_confirm do
- click_link 'Remove integration'
- end
+ click_button 'Remove integration and resources'
+ fill_in 'confirm_cluster_name_input', with: cluster.name
+ click_button 'Remove integration'
end
it 'user sees creation form with the successful message' do
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 741f46cef45..7c8b2640e89 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -131,11 +131,11 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
end
end
- context 'when user destroy the cluster' do
+ context 'when user destroys the cluster' do
before do
- page.accept_confirm do
- click_link 'Remove integration'
- end
+ click_button 'Remove integration and resources'
+ fill_in 'confirm_cluster_name_input', with: cluster.name
+ click_button 'Remove integration'
end
it 'user sees creation form with the successful message' do
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index bdaeda83926..38efcf758e1 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -101,11 +101,11 @@ describe 'User Cluster', :js do
end
end
- context 'when user destroy the cluster' do
+ context 'when user destroys the cluster' do
before do
- page.accept_confirm do
- click_link 'Remove integration'
- end
+ click_button 'Remove integration and resources'
+ fill_in 'confirm_cluster_name_input', with: cluster.name
+ click_button 'Remove integration'
end
it 'user sees creation form with the successful message' do
diff --git a/spec/finders/keys_finder_spec.rb b/spec/finders/keys_finder_spec.rb
index 147e6ee3d84..f80abdcdb38 100644
--- a/spec/finders/keys_finder_spec.rb
+++ b/spec/finders/keys_finder_spec.rb
@@ -3,74 +3,145 @@
require 'spec_helper'
describe KeysFinder do
- subject(:keys_finder) { described_class.new(user, params) }
+ subject { described_class.new(user, params).execute }
let(:user) { create(:user) }
- let(:fingerprint_type) { 'md5' }
- let(:fingerprint) { 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1' }
-
- let(:params) do
- {
- type: fingerprint_type,
- fingerprint: fingerprint
- }
- end
+ let(:params) { {} }
- let!(:key) do
- create(:key, user: user,
+ let!(:key_1) do
+ create(:personal_key,
+ last_used_at: 7.days.ago,
+ user: user,
key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1016k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
fingerprint: 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1',
- fingerprint_sha256: 'nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
- )
+ fingerprint_sha256: 'nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg')
end
+ let!(:key_2) { create(:personal_key, last_used_at: nil, user: user) }
+ let!(:key_3) { create(:personal_key, last_used_at: 2.days.ago) }
+
context 'with a regular user' do
it 'raises GitLabAccessDeniedError' do
- expect do
- keys_finder.execute
- end.to raise_error(KeysFinder::GitLabAccessDeniedError)
+ expect { subject }.to raise_error(KeysFinder::GitLabAccessDeniedError)
end
end
context 'with an admin user' do
let(:user) {create(:admin)}
- context 'with invalid MD5 fingerprint' do
- let(:fingerprint) { '11:11:11:11' }
+ context 'key_type' do
+ let!(:deploy_key) { create(:deploy_key) }
- it 'raises InvalidFingerprint' do
- expect { keys_finder.execute }
- .to raise_error(KeysFinder::InvalidFingerprint)
- end
- end
+ context 'when `key_type` is `ssh`' do
+ before do
+ params[:key_type] = 'ssh'
+ end
- context 'with invalid SHA fingerprint' do
- let(:fingerprint_type) { 'sha256' }
- let(:fingerprint) { 'nUhzNyftwAAKs7HufskYTte2g' }
+ it 'returns only SSH keys' do
+ expect(subject).to contain_exactly(key_1, key_2, key_3)
+ end
+ end
- it 'raises InvalidFingerprint' do
- expect { keys_finder.execute }
- .to raise_error(KeysFinder::InvalidFingerprint)
+ context 'when `key_type` is not specified' do
+ it 'returns all types of keys' do
+ expect(subject).to contain_exactly(key_1, key_2, key_3, deploy_key)
+ end
end
end
- context 'with valid MD5 params' do
- it 'returns key if the fingerprint is found' do
- result = keys_finder.execute
+ context 'fingerprint' do
+ context 'with invalid fingerprint' do
+ context 'with invalid MD5 fingerprint' do
+ before do
+ params[:fingerprint] = '11:11:11:11'
+ end
+
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ end
+ end
+
+ context 'with invalid SHA fingerprint' do
+ before do
+ params[:fingerprint] = 'nUhzNyftwAAKs7HufskYTte2g'
+ end
+
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ end
+ end
+ end
- expect(result).to eq(key)
- expect(key.user).to eq(user)
+ context 'with valid fingerprints' do
+ context 'with valid MD5 params' do
+ context 'with an existent fingerprint' do
+ before do
+ params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
+ end
+
+ it 'returns the key' do
+ expect(subject).to eq(key_1)
+ expect(subject.user).to eq(user)
+ end
+ end
+
+ context 'with a non-existent fingerprint' do
+ before do
+ params[:fingerprint] = 'bb:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d2'
+ end
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+ end
+
+ context 'with valid SHA256 params' do
+ context 'with an existent fingerprint' do
+ before do
+ params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
+ end
+
+ it 'returns key' do
+ expect(subject).to eq(key_1)
+ expect(subject.user).to eq(user)
+ end
+ end
+
+ context 'with a non-existent fingerprint' do
+ before do
+ params[:fingerprint] = 'SHA256:xTjuFqftwADy8AH3wFY31tAKs7HufskYTte2aXi/mNp'
+ end
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+ end
end
end
- context 'with valid SHA256 params' do
- let(:fingerprint) { 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1' }
+ context 'user' do
+ context 'without user' do
+ it 'contains ssh_keys of all users in the system' do
+ expect(subject).to contain_exactly(key_1, key_2, key_3)
+ end
+ end
+
+ context 'with user' do
+ before do
+ params[:user] = user
+ end
- it 'returns key if the fingerprint is found' do
- result = keys_finder.execute
+ it 'contains ssh_keys of only the specified users' do
+ expect(subject).to contain_exactly(key_1, key_2)
+ end
+ end
+ end
- expect(result).to eq(key)
- expect(key.user).to eq(user)
+ context 'sort order' do
+ it 'sorts in last_used_at_desc order' do
+ expect(subject).to eq([key_3, key_1, key_2])
end
end
end
diff --git a/spec/finders/merge_request_target_project_finder_spec.rb b/spec/finders/merge_request_target_project_finder_spec.rb
index 1d78b7ba4e3..7fef16d1040 100644
--- a/spec/finders/merge_request_target_project_finder_spec.rb
+++ b/spec/finders/merge_request_target_project_finder_spec.rb
@@ -27,6 +27,22 @@ describe MergeRequestTargetProjectFinder do
expect(finder.execute).to contain_exactly(other_fork, forked_project)
end
+
+ it 'does not include routes by default' do
+ row = finder.execute.first
+
+ expect(row.association(:route).loaded?).to be_falsey
+ expect(row.association(:namespace).loaded?).to be_falsey
+ expect(row.namespace.association(:route).loaded?).to be_falsey
+ end
+
+ it 'includes routes when requested' do
+ row = finder.execute(include_routes: true).first
+
+ expect(row.association(:route).loaded?).to be_truthy
+ expect(row.association(:namespace).loaded?).to be_truthy
+ expect(row.namespace.association(:route).loaded?).to be_truthy
+ end
end
context 'public projects' do
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index a44daf585ba..ce8ef80bb99 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -26,6 +26,16 @@ describe PersonalAccessTokensFinder do
revoked_impersonation_token, expired_impersonation_token)
end
+ describe 'with sort order' do
+ before do
+ params[:sort] = 'id_asc'
+ end
+
+ it 'sorts records as per the specified sort order' do
+ expect(subject).to match_array(PersonalAccessToken.all.order(id: :asc))
+ end
+ end
+
describe 'without impersonation' do
before do
params[:impersonation] = false
diff --git a/spec/frontend/boards/boards_store_spec.js b/spec/frontend/boards/boards_store_spec.js
index 3588197ebdc..bf3d81d3117 100644
--- a/spec/frontend/boards/boards_store_spec.js
+++ b/spec/frontend/boards/boards_store_spec.js
@@ -41,7 +41,6 @@ describe('boardsStore', () => {
afterEach(() => {
axiosMock.restore();
- jest.clearAllMocks();
});
const setupDefaultResponses = () => {
diff --git a/spec/frontend/clusters/clusters_bundle_spec.js b/spec/frontend/clusters/clusters_bundle_spec.js
index 7b1d96c8da5..d7c648bcd20 100644
--- a/spec/frontend/clusters/clusters_bundle_spec.js
+++ b/spec/frontend/clusters/clusters_bundle_spec.js
@@ -46,7 +46,6 @@ describe('Clusters', () => {
afterEach(() => {
cluster.destroy();
mock.restore();
- jest.clearAllMocks();
});
describe('class constructor', () => {
diff --git a/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
new file mode 100644
index 00000000000..8f406c62824
--- /dev/null
+++ b/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
@@ -0,0 +1,80 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Remove cluster confirmation modal renders splitbutton with modal included 1`] = `
+<div>
+ <div
+ class="dropdown btn-group b-dropdown gl-dropdown"
+ >
+ <button
+ class="btn btn-danger"
+ type="button"
+ >
+
+ Remove integration and resources
+
+ <!---->
+ </button>
+ <button
+ aria-expanded="false"
+ aria-haspopup="true"
+ class="btn dropdown-toggle btn-danger dropdown-toggle-split"
+ type="button"
+ >
+ <span
+ class="sr-only"
+ >
+ Toggle Dropdown
+ </span>
+ </button>
+ <ul
+ class="dropdown-menu dropdown-menu-selectable dropdown-menu-large"
+ role="menu"
+ tabindex="-1"
+ >
+ <li>
+ <button
+ class="dropdown-item is-active"
+ role="menuitem"
+ type="button"
+ >
+ <strong>
+ Remove integration and resources
+ </strong>
+
+ <div>
+ Deletes all GitLab resources attached to this cluster during removal
+ </div>
+ </button>
+ </li>
+
+ <li>
+ <hr
+ aria-orientation="horizontal"
+ class="dropdown-divider"
+ role="separator"
+ />
+ </li>
+ <li>
+ <button
+ class="dropdown-item"
+ role="menuitem"
+ type="button"
+ >
+ <strong>
+ Remove integration
+ </strong>
+
+ <div>
+ Removes cluster from project but keeps associated resources
+ </div>
+ </button>
+ </li>
+
+ <!---->
+
+ </ul>
+ </div>
+
+ <!---->
+</div>
+`;
diff --git a/spec/frontend/clusters/components/remove_cluster_confirmation_spec.js b/spec/frontend/clusters/components/remove_cluster_confirmation_spec.js
new file mode 100644
index 00000000000..b5aead238ad
--- /dev/null
+++ b/spec/frontend/clusters/components/remove_cluster_confirmation_spec.js
@@ -0,0 +1,57 @@
+import { mount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import SplitButton from '~/vue_shared/components/split_button.vue';
+import RemoveClusterConfirmation from '~/clusters/components/remove_cluster_confirmation.vue';
+
+describe('Remove cluster confirmation modal', () => {
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ wrapper = mount(RemoveClusterConfirmation, {
+ propsData: {
+ clusterPath: 'clusterPath',
+ clusterName: 'clusterName',
+ ...props,
+ },
+ sync: false,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders splitbutton with modal included', () => {
+ createComponent();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ describe('split button dropdown', () => {
+ const findModal = () => wrapper.find(GlModal).vm;
+ const findSplitButton = () => wrapper.find(SplitButton).vm;
+
+ beforeEach(() => {
+ createComponent({ clusterName: 'my-test-cluster' });
+ jest.spyOn(findModal(), 'show').mockReturnValue();
+ });
+
+ it('opens modal with "cleanup" option', () => {
+ findSplitButton().$emit('remove-cluster-and-cleanup');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findModal().show).toHaveBeenCalled();
+ expect(wrapper.vm.confirmCleanup).toEqual(true);
+ });
+ });
+
+ it('opens modal without "cleanup" option', () => {
+ findSplitButton().$emit('remove-cluster');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findModal().show).toHaveBeenCalled();
+ expect(wrapper.vm.confirmCleanup).toEqual(false);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/commit/commit_pipeline_status_component_spec.js b/spec/frontend/commit/commit_pipeline_status_component_spec.js
index 36fc6ee52a8..a2a6d405eab 100644
--- a/spec/frontend/commit/commit_pipeline_status_component_spec.js
+++ b/spec/frontend/commit/commit_pipeline_status_component_spec.js
@@ -44,7 +44,6 @@ describe('Commit pipeline status component', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
- jest.clearAllMocks();
});
describe('Visibility management', () => {
diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
index fda1f71b1f9..1139f094705 100644
--- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
@@ -272,14 +272,11 @@ describe('EKS Cluster Store Actions', () => {
payload = { name: ['Create cluster failed'] };
});
- it('commits createClusterError mutation', () => {
+ it('commits createClusterError mutation and displays flash message', () =>
testAction(actions.createClusterError, payload, state, [
{ type: CREATE_CLUSTER_ERROR, payload },
- ]);
- });
-
- it('creates a flash that displays the create cluster error', () => {
- expect(createFlash).toHaveBeenCalledWith(payload.name[0]);
- });
+ ]).then(() => {
+ expect(createFlash).toHaveBeenCalledWith(payload.name[0]);
+ }));
});
});
diff --git a/spec/frontend/ide/components/preview/clientside_spec.js b/spec/frontend/ide/components/preview/clientside_spec.js
index 6a33f4998c5..5cb9e598fc4 100644
--- a/spec/frontend/ide/components/preview/clientside_spec.js
+++ b/spec/frontend/ide/components/preview/clientside_spec.js
@@ -68,10 +68,6 @@ describe('IDE clientside preview', () => {
jest.useRealTimers();
});
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
afterEach(() => {
wrapper.destroy();
});
diff --git a/spec/frontend/ide/stores/modules/pipelines/actions_spec.js b/spec/frontend/ide/stores/modules/pipelines/actions_spec.js
index a58c7b8f819..b08d1cd01da 100644
--- a/spec/frontend/ide/stores/modules/pipelines/actions_spec.js
+++ b/spec/frontend/ide/stores/modules/pipelines/actions_spec.js
@@ -111,8 +111,6 @@ describe('IDE pipelines actions', () => {
});
describe('fetchLatestPipeline', () => {
- beforeEach(() => {});
-
afterEach(() => {
stopPipelinePolling();
clearEtagPoll();
diff --git a/spec/frontend/issuables_list/components/issuables_list_app_spec.js b/spec/frontend/issuables_list/components/issuables_list_app_spec.js
index 666ccc07416..621e8b8aa54 100644
--- a/spec/frontend/issuables_list/components/issuables_list_app_spec.js
+++ b/spec/frontend/issuables_list/components/issuables_list_app_spec.js
@@ -72,7 +72,6 @@ describe('Issuables list component', () => {
afterEach(() => {
wrapper.destroy();
mockAxios.restore();
- jest.clearAllMocks();
window.location = oldLocation;
});
diff --git a/spec/frontend/jest_self_check/mocks_spec.js b/spec/frontend/jest_self_check/mocks_spec.js
new file mode 100644
index 00000000000..f1e9e12e633
--- /dev/null
+++ b/spec/frontend/jest_self_check/mocks_spec.js
@@ -0,0 +1,43 @@
+import * as textUtils from '~/lib/utils/text_utility';
+
+jest.mock('~/lib/utils/text_utility');
+
+describe('does restore mocks config work?', () => {
+ describe('shared spy', () => {
+ const spy = jest.fn();
+
+ beforeEach(() => {
+ spy();
+ });
+
+ it('is only called once', () => {
+ expect(spy).toHaveBeenCalledTimes(1);
+ });
+
+ it('is only called once B', () => {
+ expect(spy).toHaveBeenCalledTimes(1);
+ });
+
+ it('is only called once C', () => {
+ expect(spy).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('module mock', () => {
+ beforeEach(() => {
+ textUtils.humanize('');
+ });
+
+ it('is only called once', () => {
+ expect(textUtils.humanize).toHaveBeenCalledTimes(1);
+ });
+
+ it('is only called once B', () => {
+ expect(textUtils.humanize).toHaveBeenCalledTimes(1);
+ });
+
+ it('is only called once C', () => {
+ expect(textUtils.humanize).toHaveBeenCalledTimes(1);
+ });
+ });
+});
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index 10d92e9535c..7652f48474d 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -50,7 +50,6 @@ describe('issue_comment_form component', () => {
afterEach(() => {
axiosMock.restore();
wrapper.destroy();
- jest.clearAllMocks();
});
describe('user is logged in', () => {
diff --git a/spec/frontend/pages/admin/users/components/user_modal_manager_spec.js b/spec/frontend/pages/admin/users/components/user_modal_manager_spec.js
index 7653fffc502..c88a182660d 100644
--- a/spec/frontend/pages/admin/users/components/user_modal_manager_spec.js
+++ b/spec/frontend/pages/admin/users/components/user_modal_manager_spec.js
@@ -83,10 +83,6 @@ describe('Users admin page Modal Manager', () => {
jest.spyOn(document, 'removeEventListener');
});
- afterEach(() => {
- jest.clearAllMocks();
- });
-
afterAll(() => {
jest.restoreAllMocks();
});
diff --git a/spec/frontend/project_find_file_spec.js b/spec/frontend/project_find_file_spec.js
index b697ca01046..b4c6d202e14 100644
--- a/spec/frontend/project_find_file_spec.js
+++ b/spec/frontend/project_find_file_spec.js
@@ -42,21 +42,23 @@ describe('ProjectFindFile', () => {
}));
const files = [
- 'fileA.txt',
- 'fileB.txt',
- 'fi#leC.txt',
- 'folderA/fileD.txt',
- 'folder#B/fileE.txt',
- 'folde?rC/fil#F.txt',
+ { path: 'fileA.txt', escaped: 'fileA.txt' },
+ { path: 'fileB.txt', escaped: 'fileB.txt' },
+ { path: 'fi#leC.txt', escaped: 'fi%23leC.txt' },
+ { path: 'folderA/fileD.txt', escaped: 'folderA/fileD.txt' },
+ { path: 'folder#B/fileE.txt', escaped: 'folder%23B/fileE.txt' },
+ { path: 'folde?rC/fil#F.txt', escaped: 'folde%3FrC/fil%23F.txt' },
];
- beforeEach(() => {
+ beforeEach(done => {
// Create a mock adapter for stubbing axios API requests
mock = new MockAdapter(axios);
element = $(TEMPLATE);
- mock.onGet(FILE_FIND_URL).replyOnce(200, files);
+ mock.onGet(FILE_FIND_URL).replyOnce(200, files.map(x => x.path));
getProjectFindFileInstance(); // This triggers a load / axios call + subsequent render in the constructor
+
+ setImmediate(done);
});
afterEach(() => {
@@ -65,26 +67,19 @@ describe('ProjectFindFile', () => {
sanitize.mockClear();
});
- it('loads and renders elements from remote server', done => {
- setImmediate(() => {
- expect(findFiles()).toEqual(
- files.map(text => ({
- text,
- href: `${BLOB_URL_TEMPLATE}/${encodeURIComponent(text)}`,
- })),
- );
-
- done();
- });
+ it('loads and renders elements from remote server', () => {
+ expect(findFiles()).toEqual(
+ files.map(({ path, escaped }) => ({
+ text: path,
+ href: `${BLOB_URL_TEMPLATE}/${escaped}`,
+ })),
+ );
});
- it('sanitizes search text', done => {
+ it('sanitizes search text', () => {
const searchText = element.find('.file-finder-input').val();
- setImmediate(() => {
- expect(sanitize).toHaveBeenCalledTimes(1);
- expect(sanitize).toHaveBeenCalledWith(searchText);
- done();
- });
+ expect(sanitize).toHaveBeenCalledTimes(1);
+ expect(sanitize).toHaveBeenCalledWith(searchText);
});
});
diff --git a/spec/frontend/registry/list/components/app_spec.js b/spec/frontend/registry/list/components/app_spec.js
index f2733ac9fef..5072a285f83 100644
--- a/spec/frontend/registry/list/components/app_spec.js
+++ b/spec/frontend/registry/list/components/app_spec.js
@@ -52,7 +52,6 @@ describe('Registry List', () => {
});
afterEach(() => {
- jest.clearAllMocks();
Vue.config.silent = false;
wrapper.destroy();
});
diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js
index aa0b9385f1a..94fa8b1e363 100644
--- a/spec/frontend/repository/components/table/row_spec.js
+++ b/spec/frontend/repository/components/table/row_spec.js
@@ -35,7 +35,6 @@ function factory(propsData = {}) {
describe('Repository table row component', () => {
afterEach(() => {
vm.destroy();
- jest.clearAllMocks();
});
it('renders table row', () => {
diff --git a/spec/frontend/sentry/sentry_config_spec.js b/spec/frontend/sentry/sentry_config_spec.js
index 62b8bbd50a2..bcc7f29b98d 100644
--- a/spec/frontend/sentry/sentry_config_spec.js
+++ b/spec/frontend/sentry/sentry_config_spec.js
@@ -54,8 +54,7 @@ describe('SentryConfig', () => {
});
it('should not call setUser if there is no current user ID', () => {
- jest.clearAllMocks();
-
+ SentryConfig.setUser.mockClear();
options.currentUserId = undefined;
SentryConfig.init(options);
@@ -167,8 +166,6 @@ describe('SentryConfig', () => {
describe('if no err is provided', () => {
beforeEach(() => {
- jest.clearAllMocks();
-
SentryConfig.handleSentryErrors(event, req, config);
});
@@ -191,8 +188,6 @@ describe('SentryConfig', () => {
beforeEach(() => {
req.responseText = undefined;
- jest.clearAllMocks();
-
SentryConfig.handleSentryErrors(event, req, config, err);
});
diff --git a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
index 68dde14880a..432ec111e52 100644
--- a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
+++ b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
@@ -42,7 +42,6 @@ describe('Confidential Issue Sidebar Block', () => {
};
beforeEach(() => {
- jest.clearAllMocks();
jest.spyOn(window.location, 'reload').mockImplementation();
});
diff --git a/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
index 95296de5a5d..530428ef27c 100644
--- a/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
+++ b/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
@@ -5,6 +5,7 @@ exports[`SplitButton renders actionItems 1`] = `
menu-class="dropdown-menu-selectable "
split="true"
text="professor"
+ variant="secondary"
>
<gldropdownitem-stub
active="true"
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index 559dc95768a..2dd9583087f 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -50,6 +50,32 @@ describe Key, :mailer do
end
end
+ describe 'scopes' do
+ describe '.for_user' do
+ let(:user_1) { create(:user) }
+ let(:key_of_user_1) { create(:personal_key, user: user_1) }
+
+ before do
+ create_list(:personal_key, 2, user: create(:user))
+ end
+
+ it 'returns keys of the specified user only' do
+ expect(described_class.for_user(user_1)).to contain_exactly(key_of_user_1)
+ end
+ end
+
+ describe '.order_last_used_at_desc' do
+ it 'sorts by last_used_at descending, with null values at last' do
+ key_1 = create(:personal_key, last_used_at: 7.days.ago)
+ key_2 = create(:personal_key, last_used_at: nil)
+ key_3 = create(:personal_key, last_used_at: 2.days.ago)
+
+ expect(described_class.order_last_used_at_desc)
+ .to eq([key_3, key_1, key_2])
+ end
+ end
+ end
+
context "validation of uniqueness (based on fingerprint uniqueness)" do
let(:user) { create(:user) }
diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb
index aaf9ecb8089..b16d1f58be5 100644
--- a/spec/models/personal_access_token_spec.rb
+++ b/spec/models/personal_access_token_spec.rb
@@ -21,6 +21,18 @@ describe PersonalAccessToken do
end
end
+ describe 'scopes' do
+ describe '.for_user' do
+ it 'returns personal access tokens of specified user only' do
+ user_1 = create(:user)
+ token_of_user_1 = create(:personal_access_token, user: user_1)
+ create_list(:personal_access_token, 2)
+
+ expect(described_class.for_user(user_1)).to contain_exactly(token_of_user_1)
+ end
+ end
+ end
+
describe ".active?" do
let(:active_personal_access_token) { build(:personal_access_token) }
let(:revoked_personal_access_token) { build(:personal_access_token, :revoked) }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index e5c30e4ca46..99d7e4d156f 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1786,11 +1786,11 @@ describe Project do
end
end
- describe '.including_namespace_and_owner' do
+ describe '.eager_load_namespace_and_owner' do
it 'eager loads the namespace and namespace owner' do
create(:project)
- row = described_class.eager_load_namespace_and_owner.to_a.first
+ row = described_class.eager_load_namespace_and_owner.first
recorder = ActiveRecord::QueryRecorder.new { row.namespace.owner }
expect(recorder.count).to be_zero
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index db26b872045..749d80ebfc2 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -2894,11 +2894,11 @@ describe User, :do_not_mock_admin_mode do
end
end
- describe '#full_private_access?' do
+ describe '#can_read_all_resources?' do
it 'returns false for regular user' do
user = build(:user)
- expect(user.full_private_access?).to be_falsy
+ expect(user.can_read_all_resources?).to be_falsy
end
context 'for admin user' do
@@ -2908,7 +2908,7 @@ describe User, :do_not_mock_admin_mode do
context 'when admin mode is disabled' do
it 'returns false' do
- expect(user.full_private_access?).to be_falsy
+ expect(user.can_read_all_resources?).to be_falsy
end
end
@@ -2919,7 +2919,7 @@ describe User, :do_not_mock_admin_mode do
end
it 'returns true' do
- expect(user.full_private_access?).to be_truthy
+ expect(user.can_read_all_resources?).to be_truthy
end
end
end
diff --git a/spec/requests/projects/merge_requests/creations_spec.rb b/spec/requests/projects/merge_requests/creations_spec.rb
new file mode 100644
index 00000000000..d192e1bca7f
--- /dev/null
+++ b/spec/requests/projects/merge_requests/creations_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'merge requests creations' do
+ describe 'GET /:namespace/:project/merge_requests/new' do
+ include ProjectForksHelper
+
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.owner }
+
+ before do
+ login_as(user)
+ end
+
+ def get_new
+ get namespace_project_new_merge_request_path(namespace_id: project.namespace, project_id: project)
+ end
+
+ it 'avoids N+1 DB queries even with forked projects' do
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get_new }
+
+ 5.times { fork_project(project, user) }
+
+ expect { get_new }.not_to exceed_query_limit(control)
+ end
+ end
+end