diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-28 21:09:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-28 21:09:27 +0300 |
commit | e1b9b92a49eea88ea7c3b101aec0315e64e94678 (patch) | |
tree | fadb5aa290045f6b345ad51b4752515d5a126dd7 /spec | |
parent | c6ee7ef0f577e0155740d022babdc1b2b0e28d87 (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.rb | 16 | ||||
-rw-r--r-- | spec/finders/autocomplete/users_finder_spec.rb | 5 | ||||
-rw-r--r-- | spec/fixtures/api/schemas/entities/member.json | 4 | ||||
-rw-r--r-- | spec/fixtures/api/schemas/entities/member_user.json | 1 | ||||
-rw-r--r-- | spec/frontend/members/components/table/members_table_cell_spec.js | 20 | ||||
-rw-r--r-- | spec/frontend/members/components/table/members_table_spec.js | 7 | ||||
-rw-r--r-- | spec/frontend/members/mock_data.js | 4 | ||||
-rw-r--r-- | spec/frontend/members/utils_spec.js | 62 | ||||
-rw-r--r-- | spec/models/terraform/state_spec.rb | 3 | ||||
-rw-r--r-- | spec/serializers/member_entity_spec.rb | 36 | ||||
-rw-r--r-- | spec/serializers/member_serializer_spec.rb | 4 | ||||
-rw-r--r-- | spec/serializers/merge_request_user_entity_spec.rb | 18 |
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 |