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>2021-02-24 18:11:10 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-24 18:11:10 +0300
commit958d8a85d32fece017eac7d99bf28860b01a49d8 (patch)
tree3c84c8447a8d9a6f7ccf7401eeb3cd268570c94f /spec
parent35c5f0c35c83f3c5f8d33fb61713495e29bdec4d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/finders/users_finder_spec.rb20
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_table_row_spec.js101
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_table_spec.js1
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/sorting_spec.rb58
-rw-r--r--spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb33
-rw-r--r--spec/models/list_spec.rb68
-rw-r--r--spec/requests/api/users_spec.rb12
-rw-r--r--spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb68
8 files changed, 264 insertions, 97 deletions
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index d9cc71106d5..b0f8b803141 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe UsersFinder do
it 'returns all users' do
users = described_class.new(user).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user)
end
it 'filters by username' do
@@ -48,12 +48,18 @@ RSpec.describe UsersFinder do
it 'filters by active users' do
users = described_class.new(user, active: true).execute
- expect(users).to contain_exactly(user, normal_user, omniauth_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, external_user, omniauth_user, admin_user)
end
- it 'returns no external users' do
+ it 'filters by external users' do
users = described_class.new(user, external: true).execute
+ expect(users).to contain_exactly(external_user)
+ end
+
+ it 'filters by non external users' do
+ users = described_class.new(user, non_external: true).execute
+
expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user)
end
@@ -71,7 +77,7 @@ RSpec.describe UsersFinder do
it 'filters by non internal users' do
users = described_class.new(user, non_internal: true).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, external_user, blocked_user, omniauth_user, admin_user)
end
it 'does not filter by custom attributes' do
@@ -80,18 +86,18 @@ RSpec.describe UsersFinder do
custom_attributes: { foo: 'bar' }
).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user)
end
it 'orders returned results' do
users = described_class.new(user, sort: 'id_asc').execute
- expect(users).to eq([normal_user, admin_user, blocked_user, omniauth_user, internal_user, user])
+ expect(users).to eq([normal_user, admin_user, blocked_user, external_user, omniauth_user, internal_user, user])
end
it 'does not filter by admins' do
users = described_class.new(user, admins: true).execute
- expect(users).to contain_exactly(user, normal_user, admin_user, blocked_user, omniauth_user, internal_user)
+ expect(users).to contain_exactly(user, normal_user, external_user, admin_user, blocked_user, omniauth_user, internal_user)
end
end
diff --git a/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js
index 074d6cf3786..7a83136e785 100644
--- a/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js
+++ b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js
@@ -1,10 +1,15 @@
-import { GlButton, GlLink, GlFormInput } from '@gitlab/ui';
+import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
import { STATUSES } from '~/import_entities/constants';
import ImportTableRow from '~/import_entities/import_groups/components/import_table_row.vue';
-import Select2Select from '~/vue_shared/components/select2_select.vue';
+import groupQuery from '~/import_entities/import_groups/graphql/queries/group.query.graphql';
import { availableNamespacesFixture } from '../graphql/fixtures';
+Vue.use(VueApollo);
+
const getFakeGroup = (status) => ({
web_url: 'https://fake.host/',
full_path: 'fake_group_1',
@@ -17,8 +22,12 @@ const getFakeGroup = (status) => ({
status,
});
+const EXISTING_GROUP_TARGET_NAMESPACE = 'existing-group';
+const EXISTING_GROUP_PATH = 'existing-path';
+
describe('import table row', () => {
let wrapper;
+ let apolloProvider;
let group;
const findByText = (cmp, text) => {
@@ -26,12 +35,27 @@ describe('import table row', () => {
};
const findImportButton = () => findByText(GlButton, 'Import');
const findNameInput = () => wrapper.find(GlFormInput);
- const findNamespaceDropdown = () => wrapper.find(Select2Select);
+ const findNamespaceDropdown = () => wrapper.find(GlDropdown);
const createComponent = (props) => {
+ apolloProvider = createMockApollo([
+ [
+ groupQuery,
+ ({ fullPath }) => {
+ const existingGroup =
+ fullPath === `${EXISTING_GROUP_TARGET_NAMESPACE}/${EXISTING_GROUP_PATH}`
+ ? { id: 1 }
+ : null;
+ return Promise.resolve({ data: { existingGroup } });
+ },
+ ],
+ ]);
+
wrapper = shallowMount(ImportTableRow, {
+ apolloProvider,
propsData: {
availableNamespaces: availableNamespacesFixture,
+ groupPathRegex: /.*/,
...props,
},
});
@@ -49,15 +73,24 @@ describe('import table row', () => {
});
it.each`
- selector | sourceEvent | payload | event
- ${findNamespaceDropdown} | ${'input'} | ${'demo'} | ${'update-target-namespace'}
- ${findNameInput} | ${'input'} | ${'demo'} | ${'update-new-name'}
- ${findImportButton} | ${'click'} | ${undefined} | ${'import-group'}
+ selector | sourceEvent | payload | event
+ ${findNameInput} | ${'input'} | ${'demo'} | ${'update-new-name'}
+ ${findImportButton} | ${'click'} | ${undefined} | ${'import-group'}
`('invokes $event', ({ selector, sourceEvent, payload, event }) => {
selector().vm.$emit(sourceEvent, payload);
expect(wrapper.emitted(event)).toBeDefined();
expect(wrapper.emitted(event)[0][0]).toBe(payload);
});
+
+ it('emits update-target-namespace when dropdown option is clicked', () => {
+ const dropdownItem = findNamespaceDropdown().findAllComponents(GlDropdownItem).at(2);
+ const dropdownItemText = dropdownItem.text();
+
+ dropdownItem.vm.$emit('click');
+
+ expect(wrapper.emitted('update-target-namespace')).toBeDefined();
+ expect(wrapper.emitted('update-target-namespace')[0][0]).toBe(dropdownItemText);
+ });
});
describe('when entity status is NONE', () => {
@@ -81,12 +114,12 @@ describe('import table row', () => {
availableNamespaces: [],
});
- const dropdownData = findNamespaceDropdown().props().options.data;
- const noParentOption = dropdownData.find((o) => o.text === 'No parent');
- const existingGroupOption = dropdownData.find((o) => o.text === 'Existing groups');
+ const items = findNamespaceDropdown()
+ .findAllComponents(GlDropdownItem)
+ .wrappers.map((w) => w.text());
- expect(noParentOption.id).toBe('');
- expect(existingGroupOption).toBeUndefined();
+ expect(items[0]).toBe('No parent');
+ expect(items).toHaveLength(1);
});
it('renders both no parent option and available namespaces list when available namespaces list is not empty', () => {
@@ -95,12 +128,12 @@ describe('import table row', () => {
availableNamespaces: availableNamespacesFixture,
});
- const dropdownData = findNamespaceDropdown().props().options.data;
- const noParentOption = dropdownData.find((o) => o.text === 'No parent');
- const existingGroupOption = dropdownData.find((o) => o.text === 'Existing groups');
+ const [firstItem, ...rest] = findNamespaceDropdown()
+ .findAllComponents(GlDropdownItem)
+ .wrappers.map((w) => w.text());
- expect(noParentOption.id).toBe('');
- expect(existingGroupOption.children).toHaveLength(availableNamespacesFixture.length);
+ expect(firstItem).toBe('No parent');
+ expect(rest).toHaveLength(availableNamespacesFixture.length);
});
describe('when entity status is SCHEDULING', () => {
@@ -137,4 +170,38 @@ describe('import table row', () => {
expect(findByText(GlLink, TARGET_LINK).exists()).toBe(true);
});
});
+
+ describe('validations', () => {
+ it('Reports invalid group name when name is not matching regex', () => {
+ createComponent({
+ group: {
+ ...getFakeGroup(STATUSES.NONE),
+ import_target: {
+ target_namespace: 'root',
+ new_name: 'very`bad`name',
+ },
+ },
+ groupPathRegex: /^[a-zA-Z]+$/,
+ });
+
+ expect(wrapper.text()).toContain('Please choose a group URL with no special characters.');
+ });
+
+ it('Reports invalid group name if group already exists', async () => {
+ createComponent({
+ group: {
+ ...getFakeGroup(STATUSES.NONE),
+ import_target: {
+ target_namespace: EXISTING_GROUP_TARGET_NAMESPACE,
+ new_name: EXISTING_GROUP_PATH,
+ },
+ },
+ });
+
+ jest.runOnlyPendingTimers();
+ await nextTick();
+
+ expect(wrapper.text()).toContain('Name already exists.');
+ });
+ });
});
diff --git a/spec/frontend/import_entities/import_groups/components/import_table_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_spec.js
index 59330e58e26..14445132f48 100644
--- a/spec/frontend/import_entities/import_groups/components/import_table_spec.js
+++ b/spec/frontend/import_entities/import_groups/components/import_table_spec.js
@@ -43,6 +43,7 @@ describe('import table', () => {
wrapper = shallowMount(ImportTable, {
propsData: {
sourceUrl: 'https://demo.host',
+ groupPathRegex: /.*/,
},
stubs: {
GlSprintf,
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/sorting_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/sorting_spec.rb
new file mode 100644
index 00000000000..8f5be709a11
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/sorting_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Analytics::CycleAnalytics::Sorting do
+ let(:stage) { build(:cycle_analytics_project_stage, start_event_identifier: :merge_request_created, end_event_identifier: :merge_request_merged) }
+
+ subject(:order_values) { described_class.apply(MergeRequest.joins(:metrics), stage, sort, direction).order_values }
+
+ context 'when invalid sorting params are given' do
+ let(:sort) { :unknown_sort }
+ let(:direction) { :unknown_direction }
+
+ it 'falls back to end_event DESC sorting' do
+ expect(order_values).to eq([stage.end_event.timestamp_projection.desc])
+ end
+ end
+
+ context 'sorting end_event' do
+ let(:sort) { :end_event }
+
+ context 'direction desc' do
+ let(:direction) { :desc }
+
+ specify do
+ expect(order_values).to eq([stage.end_event.timestamp_projection.desc])
+ end
+ end
+
+ context 'direction asc' do
+ let(:direction) { :asc }
+
+ specify do
+ expect(order_values).to eq([stage.end_event.timestamp_projection.asc])
+ end
+ end
+ end
+
+ context 'sorting duration' do
+ let(:sort) { :duration }
+
+ context 'direction desc' do
+ let(:direction) { :desc }
+
+ specify do
+ expect(order_values).to eq([Arel::Nodes::Subtraction.new(stage.end_event.timestamp_projection, stage.start_event.timestamp_projection).desc])
+ end
+ end
+
+ context 'direction asc' do
+ let(:direction) { :asc }
+
+ specify do
+ expect(order_values).to eq([Arel::Nodes::Subtraction.new(stage.end_event.timestamp_projection, stage.start_event.timestamp_projection).asc])
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
index 8e74935e127..07b1d99d333 100644
--- a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
@@ -27,12 +27,33 @@ RSpec.describe Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityF
let(:finding_1) { finding_creator.call(sast_report, location_fingerprint_1) }
let(:finding_2) { finding_creator.call(dast_report, location_fingerprint_2) }
let(:finding_3) { finding_creator.call(secret_detection_report, location_fingerprint_3) }
- let(:uuid_1_components) { ['sast', identifier.fingerprint, location_fingerprint_1, project.id].join('-') }
- let(:uuid_2_components) { ['dast', identifier.fingerprint, location_fingerprint_2, project.id].join('-') }
- let(:uuid_3_components) { ['secret_detection', identifier.fingerprint, location_fingerprint_3, project.id].join('-') }
- let(:expected_uuid_1) { Gitlab::UUID.v5(uuid_1_components) }
- let(:expected_uuid_2) { Gitlab::UUID.v5(uuid_2_components) }
- let(:expected_uuid_3) { Gitlab::UUID.v5(uuid_3_components) }
+ let(:expected_uuid_1) do
+ Security::VulnerabilityUUID.generate(
+ report_type: 'sast',
+ primary_identifier_fingerprint: identifier.fingerprint,
+ location_fingerprint: location_fingerprint_1,
+ project_id: project.id
+ )
+ end
+
+ let(:expected_uuid_2) do
+ Security::VulnerabilityUUID.generate(
+ report_type: 'dast',
+ primary_identifier_fingerprint: identifier.fingerprint,
+ location_fingerprint: location_fingerprint_2,
+ project_id: project.id
+ )
+ end
+
+ let(:expected_uuid_3) do
+ Security::VulnerabilityUUID.generate(
+ report_type: 'secret_detection',
+ primary_identifier_fingerprint: identifier.fingerprint,
+ location_fingerprint: location_fingerprint_3,
+ project_id: project.id
+ )
+ end
+
let(:finding_creator) do
-> (report_type, location_fingerprint) do
findings.create!(
diff --git a/spec/models/list_spec.rb b/spec/models/list_spec.rb
index 922d6b01b82..ad07ee1115b 100644
--- a/spec/models/list_spec.rb
+++ b/spec/models/list_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe List do
it_behaves_like 'having unique enum values'
it_behaves_like 'boards listable model', :list
+ it_behaves_like 'list_preferences_for user', :list, :list_id
describe 'relationships' do
it { is_expected.to belong_to(:board) }
@@ -29,71 +30,4 @@ RSpec.describe List do
expect(lists.where(board: board)).to match_array([backlog_list])
end
end
-
- describe '#update_preferences_for' do
- let(:user) { create(:user) }
- let(:list) { create(:list) }
-
- context 'when user is present' do
- context 'when there are no preferences for user' do
- it 'creates new user preferences' do
- expect { list.update_preferences_for(user, collapsed: true) }.to change { ListUserPreference.count }.by(1)
- expect(list.preferences_for(user).collapsed).to eq(true)
- end
- end
-
- context 'when there are preferences for user' do
- it 'updates user preferences' do
- list.update_preferences_for(user, collapsed: false)
-
- expect { list.update_preferences_for(user, collapsed: true) }.not_to change { ListUserPreference.count }
- expect(list.preferences_for(user).collapsed).to eq(true)
- end
- end
-
- context 'when user is nil' do
- it 'does not create user preferences' do
- expect { list.update_preferences_for(nil, collapsed: true) }.not_to change { ListUserPreference.count }
- end
- end
- end
- end
-
- describe '#preferences_for' do
- let(:user) { create(:user) }
- let(:list) { create(:list) }
-
- context 'when user is nil' do
- it 'returns not persisted preferences' do
- preferences = list.preferences_for(nil)
-
- expect(preferences.persisted?).to eq(false)
- expect(preferences.list_id).to eq(list.id)
- expect(preferences.user_id).to be_nil
- end
- end
-
- context 'when a user preference already exists' do
- before do
- list.update_preferences_for(user, collapsed: true)
- end
-
- it 'loads preference for user' do
- preferences = list.preferences_for(user)
-
- expect(preferences).to be_persisted
- expect(preferences.collapsed).to eq(true)
- end
- end
-
- context 'when preferences for user does not exist' do
- it 'returns not persisted preferences' do
- preferences = list.preferences_for(user)
-
- expect(preferences.persisted?).to eq(false)
- expect(preferences.user_id).to eq(user.id)
- expect(preferences.list_id).to eq(list.id)
- end
- end
- end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 44b7a38ed2b..4a7232d6316 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -320,6 +320,18 @@ RSpec.describe API::Users do
expect(json_response).to all(include('state' => /(blocked|ldap_blocked)/))
end
+ it "returns an array of external users" do
+ create(:user)
+ external_user = create(:user, external: true)
+
+ get api("/users?external=true", user)
+
+ expect(response).to match_response_schema('public_api/v4/user/basics')
+ expect(response).to include_pagination_headers
+ expect(json_response.size).to eq(1)
+ expect(json_response[0]['id']).to eq(external_user.id)
+ end
+
it "returns one user" do
get api("/users?username=#{omniauth_user.username}", user)
diff --git a/spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb b/spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb
new file mode 100644
index 00000000000..766aeac9476
--- /dev/null
+++ b/spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'list_preferences_for user' do |list_factory, list_id_attribute|
+ subject { create(list_factory) } # rubocop:disable Rails/SaveBang
+
+ let_it_be(:user) { create(:user) }
+
+ describe '#preferences_for' do
+ context 'when user is nil' do
+ it 'returns not persisted preferences' do
+ preferences = subject.preferences_for(nil)
+
+ expect(preferences).not_to be_persisted
+ expect(preferences[list_id_attribute]).to eq(subject.id)
+ expect(preferences.user_id).to be_nil
+ end
+ end
+
+ context 'when a user preference already exists' do
+ before do
+ subject.update_preferences_for(user, collapsed: true)
+ end
+
+ it 'loads preference for user' do
+ preferences = subject.preferences_for(user)
+
+ expect(preferences).to be_persisted
+ expect(preferences.collapsed).to eq(true)
+ end
+ end
+
+ context 'when preferences for user does not exist' do
+ it 'returns not persisted preferences' do
+ preferences = subject.preferences_for(user)
+
+ expect(preferences).not_to be_persisted
+ expect(preferences.user_id).to eq(user.id)
+ expect(preferences.public_send(list_id_attribute)).to eq(subject.id)
+ end
+ end
+ end
+
+ describe '#update_preferences_for' do
+ context 'when user is present' do
+ context 'when there are no preferences for user' do
+ it 'creates new user preferences' do
+ expect { subject.update_preferences_for(user, collapsed: true) }.to change { subject.preferences.count }.by(1)
+ expect(subject.preferences_for(user).collapsed).to eq(true)
+ end
+ end
+
+ context 'when there are preferences for user' do
+ it 'updates user preferences' do
+ subject.update_preferences_for(user, collapsed: false)
+
+ expect { subject.update_preferences_for(user, collapsed: true) }.not_to change { subject.preferences.count }
+ expect(subject.preferences_for(user).collapsed).to eq(true)
+ end
+ end
+
+ context 'when user is nil' do
+ it 'does not create user preferences' do
+ expect { subject.update_preferences_for(nil, collapsed: true) }.not_to change { subject.preferences.count }
+ end
+ end
+ end
+ end
+end