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-01-28 21:09:27 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-01-28 21:09:27 +0300
commite1b9b92a49eea88ea7c3b101aec0315e64e94678 (patch)
treefadb5aa290045f6b345ad51b4752515d5a126dd7 /spec
parentc6ee7ef0f577e0155740d022babdc1b2b0e28d87 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/merge_request/user_views_open_merge_request_spec.rb16
-rw-r--r--spec/finders/autocomplete/users_finder_spec.rb5
-rw-r--r--spec/fixtures/api/schemas/entities/member.json4
-rw-r--r--spec/fixtures/api/schemas/entities/member_user.json1
-rw-r--r--spec/frontend/members/components/table/members_table_cell_spec.js20
-rw-r--r--spec/frontend/members/components/table/members_table_spec.js7
-rw-r--r--spec/frontend/members/mock_data.js4
-rw-r--r--spec/frontend/members/utils_spec.js62
-rw-r--r--spec/models/terraform/state_spec.rb3
-rw-r--r--spec/serializers/member_entity_spec.rb36
-rw-r--r--spec/serializers/member_serializer_spec.rb4
-rw-r--r--spec/serializers/merge_request_user_entity_spec.rb18
12 files changed, 128 insertions, 52 deletions
diff --git a/spec/features/merge_request/user_views_open_merge_request_spec.rb b/spec/features/merge_request/user_views_open_merge_request_spec.rb
index e8998f9457a..fdf29d32836 100644
--- a/spec/features/merge_request/user_views_open_merge_request_spec.rb
+++ b/spec/features/merge_request/user_views_open_merge_request_spec.rb
@@ -107,5 +107,21 @@ RSpec.describe 'User views an open merge request' do
end
end
end
+
+ context 'when the assignee\'s availability set' do
+ before do
+ merge_request.author.create_status(availability: 'busy')
+ merge_request.assignees << merge_request.author
+
+ visit(merge_request_path(merge_request))
+ end
+
+ it 'exposes the availability in the data-availability attribute' do
+ assignees_data = find_all("input[name='merge_request[assignee_ids][]']", visible: false)
+
+ expect(assignees_data.size).to eq(1)
+ expect(assignees_data.first['data-availability']).to eq('busy')
+ end
+ end
end
end
diff --git a/spec/finders/autocomplete/users_finder_spec.rb b/spec/finders/autocomplete/users_finder_spec.rb
index 357b6dfcea2..28bd7e12916 100644
--- a/spec/finders/autocomplete/users_finder_spec.rb
+++ b/spec/finders/autocomplete/users_finder_spec.rb
@@ -118,5 +118,10 @@ RSpec.describe Autocomplete::UsersFinder do
it { is_expected.to match_array([user1, external_user, omniauth_user, current_user]) }
end
+
+ it 'preloads the status association' do
+ associations = subject.map { |user| user.association(:status) }
+ expect(associations).to all(be_loaded)
+ end
end
end
diff --git a/spec/fixtures/api/schemas/entities/member.json b/spec/fixtures/api/schemas/entities/member.json
index e8b40745803..03b1872632e 100644
--- a/spec/fixtures/api/schemas/entities/member.json
+++ b/spec/fixtures/api/schemas/entities/member.json
@@ -9,7 +9,8 @@
"source",
"valid_roles",
"can_update",
- "can_remove"
+ "can_remove",
+ "is_direct_member"
],
"properties": {
"id": { "type": "integer" },
@@ -18,6 +19,7 @@
"requested_at": { "type": ["date-time", "null"] },
"can_update": { "type": "boolean" },
"can_remove": { "type": "boolean" },
+ "is_direct_member": { "type": "boolean" },
"access_level": {
"type": "object",
"required": ["integer_value", "string_value"],
diff --git a/spec/fixtures/api/schemas/entities/member_user.json b/spec/fixtures/api/schemas/entities/member_user.json
index 983cdb7b9d9..ebd26bfaaaa 100644
--- a/spec/fixtures/api/schemas/entities/member_user.json
+++ b/spec/fixtures/api/schemas/entities/member_user.json
@@ -9,6 +9,7 @@
"web_url": { "type": "string" },
"blocked": { "type": "boolean" },
"two_factor_enabled": { "type": "boolean" },
+ "availability": { "type": ["string", "null"] },
"status": {
"type": "object",
"required": ["emoji"],
diff --git a/spec/frontend/members/components/table/members_table_cell_spec.js b/spec/frontend/members/components/table/members_table_cell_spec.js
index 4e176dac725..30e6013aab2 100644
--- a/spec/frontend/members/components/table/members_table_cell_spec.js
+++ b/spec/frontend/members/components/table/members_table_cell_spec.js
@@ -1,7 +1,14 @@
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { MEMBER_TYPES } from '~/members/constants';
-import { member as memberMock, group, invite, accessRequest } from '../../mock_data';
+import {
+ member as memberMock,
+ directMember,
+ inheritedMember,
+ group,
+ invite,
+ accessRequest,
+} from '../../mock_data';
import MembersTableCell from '~/members/components/table/members_table_cell.vue';
describe('MembersTableCell', () => {
@@ -75,19 +82,12 @@ describe('MembersTableCell', () => {
const createComponentWithDirectMember = (member = {}) => {
createComponent({
- member: {
- ...memberMock,
- source: {
- ...memberMock.source,
- id: 1,
- },
- ...member,
- },
+ member: { ...directMember, ...member },
});
};
const createComponentWithInheritedMember = (member = {}) => {
createComponent({
- member: { ...memberMock, ...member },
+ member: { ...inheritedMember, ...member },
});
};
diff --git a/spec/frontend/members/components/table/members_table_spec.js b/spec/frontend/members/components/table/members_table_spec.js
index 476d7118c46..729b65f37aa 100644
--- a/spec/frontend/members/components/table/members_table_spec.js
+++ b/spec/frontend/members/components/table/members_table_spec.js
@@ -15,7 +15,7 @@ import RoleDropdown from '~/members/components/table/role_dropdown.vue';
import ExpirationDatepicker from '~/members/components/table/expiration_datepicker.vue';
import MemberActionButtons from '~/members/components/table/member_action_buttons.vue';
import * as initUserPopovers from '~/user_popovers';
-import { member as memberMock, invite, accessRequest } from '../../mock_data';
+import { member as memberMock, directMember, invite, accessRequest } from '../../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -74,11 +74,6 @@ describe('MembersTable', () => {
});
describe('fields', () => {
- const directMember = {
- ...memberMock,
- source: { ...memberMock.source, id: 1 },
- };
-
const memberCanUpdate = {
...directMember,
canUpdate: true,
diff --git a/spec/frontend/members/mock_data.js b/spec/frontend/members/mock_data.js
index 5c00745a590..fa324ce1cf9 100644
--- a/spec/frontend/members/mock_data.js
+++ b/spec/frontend/members/mock_data.js
@@ -4,6 +4,7 @@ export const member = {
canRemove: false,
canOverride: false,
isOverridden: false,
+ isDirectMember: false,
accessLevel: { integerValue: 50, stringValue: 'Owner' },
source: {
id: 178,
@@ -71,3 +72,6 @@ export const accessRequest = {
export const members = [member];
export const membersJsonString = JSON.stringify(members);
+
+export const directMember = { ...member, isDirectMember: true };
+export const inheritedMember = { ...member, isDirectMember: false };
diff --git a/spec/frontend/members/utils_spec.js b/spec/frontend/members/utils_spec.js
index f123b2c6a91..5c9484fe128 100644
--- a/spec/frontend/members/utils_spec.js
+++ b/spec/frontend/members/utils_spec.js
@@ -13,10 +13,16 @@ import {
groupLinkRequestFormatter,
} from '~/members/utils';
import { DEFAULT_SORT } from '~/members/constants';
-import { member as memberMock, group, invite, membersJsonString, members } from './mock_data';
+import {
+ member as memberMock,
+ directMember,
+ inheritedMember,
+ group,
+ invite,
+ membersJsonString,
+ members,
+} from './mock_data';
-const DIRECT_MEMBER_ID = 178;
-const INHERITED_MEMBER_ID = 179;
const IS_CURRENT_USER_ID = 123;
const IS_NOT_CURRENT_USER_ID = 124;
const URL_HOST = 'https://localhost/';
@@ -59,11 +65,11 @@ describe('Members Utils', () => {
describe('isDirectMember', () => {
test.each`
- sourceId | expected
- ${DIRECT_MEMBER_ID} | ${true}
- ${INHERITED_MEMBER_ID} | ${false}
- `('returns $expected', ({ sourceId, expected }) => {
- expect(isDirectMember(memberMock, sourceId)).toBe(expected);
+ member | expected
+ ${directMember} | ${true}
+ ${inheritedMember} | ${false}
+ `('returns $expected', ({ member, expected }) => {
+ expect(isDirectMember(member)).toBe(expected);
});
});
@@ -78,18 +84,13 @@ describe('Members Utils', () => {
});
describe('canRemove', () => {
- const memberCanRemove = {
- ...memberMock,
- canRemove: true,
- };
-
test.each`
- member | sourceId | expected
- ${memberCanRemove} | ${DIRECT_MEMBER_ID} | ${true}
- ${memberCanRemove} | ${INHERITED_MEMBER_ID} | ${false}
- ${memberMock} | ${INHERITED_MEMBER_ID} | ${false}
- `('returns $expected', ({ member, sourceId, expected }) => {
- expect(canRemove(member, sourceId)).toBe(expected);
+ member | expected
+ ${{ ...directMember, canRemove: true }} | ${true}
+ ${{ ...inheritedMember, canRemove: true }} | ${false}
+ ${{ ...memberMock, canRemove: false }} | ${false}
+ `('returns $expected', ({ member, expected }) => {
+ expect(canRemove(member)).toBe(expected);
});
});
@@ -98,25 +99,20 @@ describe('Members Utils', () => {
member | expected
${invite} | ${true}
${{ ...invite, invite: { ...invite.invite, canResend: false } }} | ${false}
- `('returns $expected', ({ member, sourceId, expected }) => {
- expect(canResend(member, sourceId)).toBe(expected);
+ `('returns $expected', ({ member, expected }) => {
+ expect(canResend(member)).toBe(expected);
});
});
describe('canUpdate', () => {
- const memberCanUpdate = {
- ...memberMock,
- canUpdate: true,
- };
-
test.each`
- member | currentUserId | sourceId | expected
- ${memberCanUpdate} | ${IS_NOT_CURRENT_USER_ID} | ${DIRECT_MEMBER_ID} | ${true}
- ${memberCanUpdate} | ${IS_CURRENT_USER_ID} | ${DIRECT_MEMBER_ID} | ${false}
- ${memberCanUpdate} | ${IS_CURRENT_USER_ID} | ${INHERITED_MEMBER_ID} | ${false}
- ${memberMock} | ${IS_NOT_CURRENT_USER_ID} | ${DIRECT_MEMBER_ID} | ${false}
- `('returns $expected', ({ member, currentUserId, sourceId, expected }) => {
- expect(canUpdate(member, currentUserId, sourceId)).toBe(expected);
+ member | currentUserId | expected
+ ${{ ...directMember, canUpdate: true }} | ${IS_NOT_CURRENT_USER_ID} | ${true}
+ ${{ ...directMember, canUpdate: true }} | ${IS_CURRENT_USER_ID} | ${false}
+ ${{ ...inheritedMember, canUpdate: true }} | ${IS_CURRENT_USER_ID} | ${false}
+ ${{ ...directMember, canUpdate: false }} | ${IS_NOT_CURRENT_USER_ID} | ${false}
+ `('returns $expected', ({ member, currentUserId, expected }) => {
+ expect(canUpdate(member, currentUserId)).toBe(expected);
});
});
diff --git a/spec/models/terraform/state_spec.rb b/spec/models/terraform/state_spec.rb
index 4eb03554378..1319e2adb03 100644
--- a/spec/models/terraform/state_spec.rb
+++ b/spec/models/terraform/state_spec.rb
@@ -8,8 +8,11 @@ RSpec.describe Terraform::State do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:locked_by_user).class_name('User') }
+ it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:project_id) }
+ it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
+
describe 'scopes' do
describe '.ordered_by_name' do
let_it_be(:project) { create(:project) }
diff --git a/spec/serializers/member_entity_spec.rb b/spec/serializers/member_entity_spec.rb
index f34434188c1..883cb511abc 100644
--- a/spec/serializers/member_entity_spec.rb
+++ b/spec/serializers/member_entity_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe MemberEntity do
let_it_be(:current_user) { create(:user) }
- let(:entity) { described_class.new(member, { current_user: current_user, group: group }) }
+ let(:entity) { described_class.new(member, { current_user: current_user, group: group, source: source }) }
let(:entity_hash) { entity.as_json }
shared_examples 'member.json' do
@@ -40,8 +40,27 @@ RSpec.describe MemberEntity do
end
end
+ shared_examples 'is_direct_member' do
+ context 'when `source` is the same as `member.source`' do
+ let(:source) { direct_member_source }
+
+ it 'exposes `is_direct_member` as `true`' do
+ expect(entity_hash[:is_direct_member]).to be(true)
+ end
+ end
+
+ context 'when `source` is not the same as `member.source`' do
+ let(:source) { inherited_member_source }
+
+ it 'exposes `is_direct_member` as `false`' do
+ expect(entity_hash[:is_direct_member]).to be(false)
+ end
+ end
+ end
+
context 'group member' do
let(:group) { create(:group) }
+ let(:source) { group }
let(:member) { GroupMemberPresenter.new(create(:group_member, group: group), current_user: current_user) }
it_behaves_like 'member.json'
@@ -52,11 +71,19 @@ RSpec.describe MemberEntity do
it_behaves_like 'member.json'
it_behaves_like 'invite'
end
+
+ context 'is_direct_member' do
+ let(:direct_member_source) { group }
+ let(:inherited_member_source) { create(:group) }
+
+ it_behaves_like 'is_direct_member'
+ end
end
context 'project member' do
let(:project) { create(:project) }
let(:group) { project.group }
+ let(:source) { project }
let(:member) { ProjectMemberPresenter.new(create(:project_member, project: project), current_user: current_user) }
it_behaves_like 'member.json'
@@ -67,5 +94,12 @@ RSpec.describe MemberEntity do
it_behaves_like 'member.json'
it_behaves_like 'invite'
end
+
+ context 'is_direct_member' do
+ let(:direct_member_source) { project }
+ let(:inherited_member_source) { group }
+
+ it_behaves_like 'is_direct_member'
+ end
end
end
diff --git a/spec/serializers/member_serializer_spec.rb b/spec/serializers/member_serializer_spec.rb
index d3ec45fe9c4..af209c0191f 100644
--- a/spec/serializers/member_serializer_spec.rb
+++ b/spec/serializers/member_serializer_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe MemberSerializer do
let_it_be(:current_user) { create(:user) }
- subject { described_class.new.represent(members, { current_user: current_user, group: group }) }
+ subject { described_class.new.represent(members, { current_user: current_user, group: group, source: source }) }
shared_examples 'members.json' do
it 'matches json schema' do
@@ -17,6 +17,7 @@ RSpec.describe MemberSerializer do
context 'group member' do
let(:group) { create(:group) }
+ let(:source) { group }
let(:members) { present_members(create_list(:group_member, 1, group: group)) }
it_behaves_like 'members.json'
@@ -24,6 +25,7 @@ RSpec.describe MemberSerializer do
context 'project member' do
let(:project) { create(:project) }
+ let(:source) { project }
let(:group) { project.group }
let(:members) { present_members(create_list(:project_member, 1, project: project)) }
diff --git a/spec/serializers/merge_request_user_entity_spec.rb b/spec/serializers/merge_request_user_entity_spec.rb
index a2ad8e72845..dcd4ef6acfb 100644
--- a/spec/serializers/merge_request_user_entity_spec.rb
+++ b/spec/serializers/merge_request_user_entity_spec.rb
@@ -17,5 +17,23 @@ RSpec.describe MergeRequestUserEntity do
it 'exposes needed attributes' do
expect(subject).to include(:id, :name, :username, :state, :avatar_url, :web_url, :can_merge)
end
+
+ context 'when `status` is not preloaded' do
+ it 'does not expose the availability attribute' do
+ expect(subject).not_to include(:availability)
+ end
+ end
+
+ context 'when `status` is preloaded' do
+ before do
+ user.create_status!(availability: :busy)
+
+ user.status # make sure `status` is loaded
+ end
+
+ it 'exposes the availibility attribute' do
+ expect(subject[:availability]).to eq('busy')
+ end
+ end
end
end