diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-31 03:16:38 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-31 03:16:38 +0300 |
commit | 453bb35fc81741c1dd7178cde1f64df2c9ec7252 (patch) | |
tree | 44edb488772b5fc89967865e4e0e70c8feab832f /spec | |
parent | 892e58c41fd07cc59b9e06b2a856ee61790d5bc4 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
17 files changed, 366 insertions, 191 deletions
diff --git a/spec/fixtures/api/schemas/group_link/group_link.json b/spec/fixtures/api/schemas/group_link/group_link.json index 885ed6d18e0..4db38952ecc 100644 --- a/spec/fixtures/api/schemas/group_link/group_link.json +++ b/spec/fixtures/api/schemas/group_link/group_link.json @@ -44,6 +44,9 @@ "valid_roles": { "type": "object" }, + "is_shared_with_group_private": { + "type": "boolean" + }, "shared_with_group": { "type": "object", "required": [ @@ -89,4 +92,4 @@ "type": "boolean" } } -}
\ No newline at end of file +} diff --git a/spec/frontend/helpers/init_simple_app_helper_spec.js b/spec/frontend/helpers/init_simple_app_helper_spec.js index 7938e3851d0..de39a6f9d70 100644 --- a/spec/frontend/helpers/init_simple_app_helper_spec.js +++ b/spec/frontend/helpers/init_simple_app_helper_spec.js @@ -1,7 +1,9 @@ import { createWrapper } from '@vue/test-utils'; import Vue from 'vue'; +import VueApollo from 'vue-apollo'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import { initSimpleApp } from '~/helpers/init_simple_app_helper'; +import createDefaultClient from '~/lib/graphql'; const MockComponent = Vue.component('MockComponent', { props: { @@ -25,10 +27,10 @@ const findMock = () => wrapper.findComponent(MockComponent); const didCreateApp = () => wrapper !== undefined; -const initMock = (html, props = {}) => { +const initMock = (html, options = {}) => { setHTMLFixture(html); - const app = initSimpleApp('#mount-here', MockComponent, { props }); + const app = initSimpleApp('#mount-here', MockComponent, options); wrapper = app ? createWrapper(app) : undefined; }; @@ -58,4 +60,35 @@ describe('helpers/init_simple_app_helper/initSimpleApp', () => { count: 123, }); }); + + describe('options', () => { + describe('withApolloProvider', () => { + describe('if not true or not VueApollo', () => { + it('apolloProvider not created', () => { + initMock('<div id="mount-here"></div>', { withApolloProvider: false }); + + expect(wrapper.vm.$apollo).toBeUndefined(); + }); + }); + + describe('if true, creates default provider', () => { + it('creates a default apolloProvider', () => { + initMock('<div id="mount-here"></div>', { withApolloProvider: true }); + + expect(wrapper.vm.$apollo).not.toBeUndefined(); + }); + }); + + describe('if VueApollo, sets as default provider', () => { + it('uses the provided apolloClient', () => { + Vue.use(VueApollo); + const apolloProvider = new VueApollo({ defaultClient: createDefaultClient() }); + + initMock('<div id="mount-here"></div>', { withApolloProvider: apolloProvider }); + + expect(wrapper.vm.$apolloProvider).toBe(apolloProvider); + }); + }); + }); + }); }); diff --git a/spec/frontend/members/components/avatars/group_avatar_spec.js b/spec/frontend/members/components/avatars/group_avatar_spec.js index 8e4263f88fe..1463aa5ae59 100644 --- a/spec/frontend/members/components/avatars/group_avatar_spec.js +++ b/spec/frontend/members/components/avatars/group_avatar_spec.js @@ -1,8 +1,9 @@ -import { GlAvatarLink } from '@gitlab/ui'; +import { GlAvatarLabeled, GlAvatarLink } from '@gitlab/ui'; import { getByText as getByTextHelper } from '@testing-library/dom'; import { mount, createWrapper } from '@vue/test-utils'; import GroupAvatar from '~/members/components/avatars/group_avatar.vue'; -import { group as member } from '../../mock_data'; +import PrivateIcon from '~/members/components/icons/private_icon.vue'; +import { group as member, privateGroup as privateMember } from '../../mock_data'; describe('MemberList', () => { let wrapper; @@ -21,11 +22,9 @@ describe('MemberList', () => { const getByText = (text, options) => createWrapper(getByTextHelper(wrapper.element, text, options)); - beforeEach(() => { + it('renders link to group', () => { createComponent(); - }); - it('renders link to group', () => { const link = wrapper.findComponent(GlAvatarLink); expect(link.exists()).toBe(true); @@ -33,10 +32,26 @@ describe('MemberList', () => { }); it("renders group's full name", () => { + createComponent(); + expect(getByText(group.fullName).exists()).toBe(true); }); it("renders group's avatar", () => { + createComponent(); + expect(wrapper.find('img').attributes('src')).toBe(group.avatarUrl); }); + + describe('when group is private', () => { + beforeEach(() => { + createComponent({ member: privateMember }); + }); + + it('renders private avatar with icon', () => { + expect(wrapper.findComponent(GlAvatarLink).exists()).toBe(false); + expect(wrapper.findComponent(GlAvatarLabeled).props('label')).toBe('Private'); + expect(wrapper.findComponent(PrivateIcon).exists()).toBe(true); + }); + }); }); diff --git a/spec/frontend/members/components/icons/private_icon_spec.js b/spec/frontend/members/components/icons/private_icon_spec.js new file mode 100644 index 00000000000..ea2b65e3307 --- /dev/null +++ b/spec/frontend/members/components/icons/private_icon_spec.js @@ -0,0 +1,30 @@ +import { GlIcon } from '@gitlab/ui'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import PrivateIcon from '~/members/components/icons/private_icon.vue'; + +describe('PrivateIcon', () => { + let wrapper; + + const createComponent = () => { + wrapper = mountExtended(PrivateIcon, { + directives: { + GlTooltip: createMockDirective('gl-tooltip'), + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + it('renders private icon with tooltip', () => { + const icon = wrapper.findComponent(GlIcon); + const tooltipDirective = getBinding(icon.element, 'gl-tooltip'); + + expect(icon.props('name')).toBe('eye-slash'); + expect(tooltipDirective.value).toBe( + 'Private group information is only accessible to its members.', + ); + }); +}); diff --git a/spec/frontend/members/components/table/member_source_spec.js b/spec/frontend/members/components/table/member_source_spec.js index bbfbb19fd92..16b8d239944 100644 --- a/spec/frontend/members/components/table/member_source_spec.js +++ b/spec/frontend/members/components/table/member_source_spec.js @@ -1,6 +1,7 @@ import { mountExtended } from 'helpers/vue_test_utils_helper'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import MemberSource from '~/members/components/table/member_source.vue'; +import PrivateIcon from '~/members/components/icons/private_icon.vue'; describe('MemberSource', () => { let wrapper; @@ -30,6 +31,20 @@ describe('MemberSource', () => { const getTooltipDirective = (elementWrapper) => getBinding(elementWrapper.element, 'gl-tooltip'); + describe('when source is private', () => { + beforeEach(() => { + createComponent({ + isSharedWithGroupPrivate: true, + isDirectMember: false, + }); + }); + + it('displays private with icon', () => { + expect(wrapper.findByText('Private').exists()).toBe(true); + expect(wrapper.findComponent(PrivateIcon).exists()).toBe(true); + }); + }); + describe('direct member', () => { describe('when created by is available', () => { it('displays "Direct member by <user name>"', () => { diff --git a/spec/frontend/members/components/table/members_table_spec.js b/spec/frontend/members/components/table/members_table_spec.js index 4539478bf9a..791155fcd1b 100644 --- a/spec/frontend/members/components/table/members_table_spec.js +++ b/spec/frontend/members/components/table/members_table_spec.js @@ -27,6 +27,7 @@ import { directMember, invite, accessRequest, + privateGroup, pagination, } from '../../mock_data'; @@ -245,6 +246,24 @@ describe('MembersTable', () => { }); }); }); + + describe('Source field', () => { + beforeEach(() => { + createComponent({ + members: [privateGroup], + tableFields: ['source'], + }); + }); + + it('passes correct props to `MemberSource` component', () => { + expect(wrapper.findComponent(MemberSource).props()).toMatchObject({ + memberSource: {}, + isDirectMember: true, + isSharedWithGroupPrivate: true, + createdBy: null, + }); + }); + }); }); describe('when `members` is an empty array', () => { diff --git a/spec/frontend/members/mock_data.js b/spec/frontend/members/mock_data.js index 4598c74757e..4fb0b76fa49 100644 --- a/spec/frontend/members/mock_data.js +++ b/spec/frontend/members/mock_data.js @@ -70,6 +70,19 @@ export const group = { validRoles: { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 }, }; +export const privateGroup = { + accessLevel: { integerValue: 10, stringValue: 'Guest' }, + isSharedWithGroupPrivate: true, + sharedWithGroup: { + id: 24, + }, + id: 3, + isDirectMember: true, + createdAt: '2020-08-06T15:31:07.662Z', + expiresAt: null, + validRoles: { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 }, +}; + export const modalData = { isAccessRequest: true, isInvite: true, diff --git a/spec/helpers/colors_helper_spec.rb b/spec/helpers/colors_helper_spec.rb index ca5cafb7ebe..328796ef1ae 100644 --- a/spec/helpers/colors_helper_spec.rb +++ b/spec/helpers/colors_helper_spec.rb @@ -39,51 +39,4 @@ RSpec.describe ColorsHelper do end end end - - describe '#rgb_array_to_hex_color' do - context 'valid RGB array' do - where(:rgb_array, :hex_color) do - [0, 0, 0] | '#000000' - [0, 0, 255] | '#0000ff' - [0, 255, 0] | '#00ff00' - [255, 0, 0] | '#ff0000' - [12, 34, 56] | '#0c2238' - [222, 111, 88] | '#de6f58' - [255, 255, 255] | '#ffffff' - end - - with_them do - it 'returns correct hex color' do - expect(helper.rgb_array_to_hex_color(rgb_array)).to eq(hex_color) - end - end - end - - context 'invalid RGB array' do - where(:rgb_array) do - [ - '', - '#000000', - 0, - nil, - [], - [0], - [0, 0], - [0, 0, 0, 0], - [-1, 0, 0], - [0, -1, 0], - [0, 0, -1], - [256, 0, 0], - [0, 256, 0], - [0, 0, 256] - ] - end - - with_them do - it 'raise ArgumentError' do - expect { helper.rgb_array_to_hex_color(rgb_array) }.to raise_error(ArgumentError) - end - end - end - end end diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb index 1383bf34881..0c04417fca6 100644 --- a/spec/helpers/environment_helper_spec.rb +++ b/spec/helpers/environment_helper_spec.rb @@ -3,45 +3,6 @@ require 'spec_helper' RSpec.describe EnvironmentHelper, feature_category: :environment_management do - describe '#render_deployment_status' do - context 'when using a manual deployment' do - it 'renders a span tag' do - deploy = build(:deployment, deployable: nil, status: :success) - html = helper.render_deployment_status(deploy) - - expect(html).to have_css('span.ci-status.ci-success') - end - end - - context 'when using a deployment from a build' do - it 'renders a link tag' do - deploy = build(:deployment, status: :success) - html = helper.render_deployment_status(deploy) - - expect(html).to have_css('a.ci-status.ci-success') - end - end - - context 'when deploying from a bridge' do - it 'renders a span tag' do - deploy = build(:deployment, deployable: create(:ci_bridge), status: :success) - html = helper.render_deployment_status(deploy) - - expect(html).to have_css('span.ci-status.ci-success') - end - end - - context 'for a blocked deployment' do - subject { helper.render_deployment_status(deployment) } - - let(:deployment) { build(:deployment, :blocked) } - - it 'indicates the status' do - expect(subject).to have_text('blocked') - end - end - end - describe '#environments_detail_data_json' do subject { helper.environments_detail_data_json(user, project, environment) } diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb index 6624404bc49..997f9e6eac7 100644 --- a/spec/helpers/environments_helper_spec.rb +++ b/spec/helpers/environments_helper_spec.rb @@ -95,17 +95,4 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do expect(subject).to eq(true) end end - - describe '#environment_logs_data' do - it 'returns logs data' do - expected_data = { - "environment_name": environment.name, - "environments_path": api_v4_projects_environments_path(id: project.id), - "environment_id": environment.id, - "clusters_path": project_clusters_path(project, format: :json) - } - - expect(helper.environment_logs_data(project, environment)).to eq(expected_data) - end - end end diff --git a/spec/helpers/groups/group_members_helper_spec.rb b/spec/helpers/groups/group_members_helper_spec.rb index a9c6822e2c1..3a7c852b683 100644 --- a/spec/helpers/groups/group_members_helper_spec.rb +++ b/spec/helpers/groups/group_members_helper_spec.rb @@ -19,14 +19,9 @@ RSpec.describe Groups::GroupMembersHelper do let(:members_collection) { members } before do - allow(helper).to receive(:can?).with(current_user, :export_group_memberships, group).and_return(false) - allow(helper).to receive(:can?).with(current_user, :owner_access, group).and_return(true) allow(helper).to receive(:current_user).and_return(current_user) - allow(helper).to receive(:can?).with(current_user, :export_group_memberships, shared_group).and_return(true) allow(helper).to receive(:group_group_member_path).with(shared_group, ':id').and_return('/groups/foo-bar/-/group_members/:id') allow(helper).to receive(:group_group_link_path).with(shared_group, ':id').and_return('/groups/foo-bar/-/group_links/:id') - allow(helper).to receive(:can?).with(current_user, :admin_group_member, shared_group).and_return(true) - allow(helper).to receive(:can?).with(current_user, :admin_member_access_request, shared_group).and_return(true) end subject do @@ -54,8 +49,8 @@ RSpec.describe Groups::GroupMembersHelper do it 'returns expected json' do expected = { source_id: shared_group.id, - can_manage_members: true, - can_manage_access_requests: true, + can_manage_members: be_in([true, false]), + can_manage_access_requests: be_in([true, false]), group_name: shared_group.name, group_path: shared_group.full_path } @@ -102,9 +97,6 @@ RSpec.describe Groups::GroupMembersHelper do before do allow(helper).to receive(:group_group_member_path).with(sub_shared_group, ':id').and_return('/groups/foo-bar/-/group_members/:id') allow(helper).to receive(:group_group_link_path).with(sub_shared_group, ':id').and_return('/groups/foo-bar/-/group_links/:id') - allow(helper).to receive(:can?).with(current_user, :admin_group_member, sub_shared_group).and_return(true) - allow(helper).to receive(:can?).with(current_user, :admin_member_access_request, sub_shared_group).and_return(true) - allow(helper).to receive(:can?).with(current_user, :export_group_memberships, sub_shared_group).and_return(true) end subject do diff --git a/spec/helpers/members_helper_spec.rb b/spec/helpers/members_helper_spec.rb index 68a12d8dbf7..d2d758cdc7c 100644 --- a/spec/helpers/members_helper_spec.rb +++ b/spec/helpers/members_helper_spec.rb @@ -45,21 +45,6 @@ RSpec.describe MembersHelper do end end - describe '#remove_member_title' do - let(:requester) { create(:user) } - let(:project) { create(:project, :public) } - let(:project_member) { build(:project_member, project: project) } - let(:project_member_request) { project.request_access(requester) } - let(:group) { create(:group) } - let(:group_member) { build(:group_member, group: group) } - let(:group_member_request) { group.request_access(requester) } - - it { expect(remove_member_title(project_member)).to eq 'Remove user from project' } - it { expect(remove_member_title(project_member_request)).to eq 'Deny access request from project' } - it { expect(remove_member_title(group_member)).to eq 'Remove user from group and any subresources' } - it { expect(remove_member_title(group_member_request)).to eq 'Deny access request from group' } - end - describe '#leave_confirmation_message' do let(:project) { build_stubbed(:project) } let(:group) { build_stubbed(:group) } diff --git a/spec/helpers/users/callouts_helper_spec.rb b/spec/helpers/users/callouts_helper_spec.rb index 10f021330db..2a0ba1279b0 100644 --- a/spec/helpers/users/callouts_helper_spec.rb +++ b/spec/helpers/users/callouts_helper_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" -RSpec.describe Users::CalloutsHelper do +RSpec.describe Users::CalloutsHelper, feature_category: :navigation do let_it_be(:user, refind: true) { create(:user) } before do diff --git a/spec/policies/group_group_link_policy_spec.rb b/spec/policies/group_group_link_policy_spec.rb new file mode 100644 index 00000000000..34bc1bc3bec --- /dev/null +++ b/spec/policies/group_group_link_policy_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GroupGroupLinkPolicy, feature_category: :system_access do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group, :private) } + let_it_be(:group2) { create(:group, :private) } + + let(:group_group_link) do + create(:group_group_link, shared_group: group, shared_with_group: group2) + end + + subject(:policy) { described_class.new(user, group_group_link) } + + describe 'read_shared_with_group' do + context 'when the user is a shared_group member' do + before_all do + group.add_guest(user) + end + + it 'can read_shared_with_group' do + expect(policy).to be_allowed(:read_shared_with_group) + end + end + + context 'when the user is not a shared_group member' do + context 'when user is not a shared_with_group member' do + context 'when the shared_with_group is private' do + it 'cannot read_shared_with_group' do + expect(policy).to be_disallowed(:read_shared_with_group) + end + + context 'when the shared group is public' do + let_it_be(:group) { create(:group, :public) } + + it 'cannot read_shared_with_group' do + expect(policy).to be_disallowed(:read_shared_with_group) + end + end + end + + context 'when the shared_with_group is public' do + let_it_be(:group2) { create(:group, :public) } + + it 'can read_shared_with_group' do + expect(policy).to be_allowed(:read_shared_with_group) + end + end + end + + context 'when user is a shared_with_group member' do + before_all do + group2.add_developer(user) + end + + it 'can read_shared_with_group' do + expect(policy).to be_allowed(:read_shared_with_group) + end + end + end + end +end diff --git a/spec/policies/project_group_link_policy_spec.rb b/spec/policies/project_group_link_policy_spec.rb index 9461f33decb..1047d3acb1e 100644 --- a/spec/policies/project_group_link_policy_spec.rb +++ b/spec/policies/project_group_link_policy_spec.rb @@ -4,9 +4,8 @@ require 'spec_helper' RSpec.describe ProjectGroupLinkPolicy, feature_category: :system_access do let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group, :private) } let_it_be(:group2) { create(:group, :private) } - let_it_be(:project) { create(:project, :private, group: group) } + let_it_be(:project) { create(:project, :private) } let(:project_group_link) do create(:project_group_link, project: project, group: group2, group_access: Gitlab::Access::DEVELOPER) @@ -14,42 +13,92 @@ RSpec.describe ProjectGroupLinkPolicy, feature_category: :system_access do subject(:policy) { described_class.new(user, project_group_link) } - context 'when the user is a group owner' do - before do - project_group_link.group.add_owner(user) - end + describe 'admin_project_group_link' do + context 'when the user is a group owner' do + before_all do + group2.add_owner(user) + end - context 'when user is not project maintainer' do - it 'can admin group_project_link' do - expect(policy).to be_allowed(:admin_project_group_link) + context 'when user is not project maintainer' do + it 'can admin group_project_link' do + expect(policy).to be_allowed(:admin_project_group_link) + end + end + + context 'when user is a project maintainer' do + before do + project_group_link.project.add_maintainer(user) + end + + it 'can admin group_project_link' do + expect(policy).to be_allowed(:admin_project_group_link) + end end end - context 'when user is a project maintainer' do - before do - project_group_link.project.add_maintainer(user) + context 'when user is not a group owner' do + context 'when user is a project maintainer' do + it 'can admin group_project_link' do + project_group_link.project.add_maintainer(user) + + expect(policy).to be_allowed(:admin_project_group_link) + end end - it 'can admin group_project_link' do - expect(policy).to be_allowed(:admin_project_group_link) + context 'when user is not a project maintainer' do + it 'cannot admin group_project_link' do + project_group_link.project.add_developer(user) + + expect(policy).to be_disallowed(:admin_project_group_link) + end end end end - context 'when user is not a group owner' do - context 'when user is a project maintainer' do - it 'can admin group_project_link' do - project_group_link.project.add_maintainer(user) + describe 'read_shared_with_group' do + context 'when the user is a project member' do + before_all do + project.add_guest(user) + end - expect(policy).to be_allowed(:admin_project_group_link) + it 'can read_shared_with_group' do + expect(policy).to be_allowed(:read_shared_with_group) end end - context 'when user is not a project maintainer' do - it 'cannot admin group_project_link' do - project_group_link.project.add_developer(user) + context 'when the user is not a project member' do + context 'when user is not a group member' do + context 'when the group is private' do + it 'cannot read_shared_with_group' do + expect(policy).to be_disallowed(:read_shared_with_group) + end + + context 'when the project is public' do + let_it_be(:project) { create(:project, :public) } + + it 'cannot read_shared_with_group' do + expect(policy).to be_disallowed(:read_shared_with_group) + end + end + end + + context 'when the group is public' do + let_it_be(:group2) { create(:group, :public) } + + it 'can read_shared_with_group' do + expect(policy).to be_allowed(:read_shared_with_group) + end + end + end + + context 'when user is a group member' do + before_all do + group2.add_guest(user) + end - expect(policy).to be_disallowed(:admin_project_group_link) + it 'can read_shared_with_group' do + expect(policy).to be_allowed(:read_shared_with_group) + end end end end diff --git a/spec/serializers/group_link/group_group_link_entity_spec.rb b/spec/serializers/group_link/group_group_link_entity_spec.rb index 502cdc5c048..8f31c53e841 100644 --- a/spec/serializers/group_link/group_group_link_entity_spec.rb +++ b/spec/serializers/group_link/group_group_link_entity_spec.rb @@ -9,8 +9,8 @@ RSpec.describe GroupLink::GroupGroupLinkEntity do let(:entity) { described_class.new(group_group_link, { current_user: current_user, source: shared_group }) } - before do - allow(entity).to receive(:current_user).and_return(current_user) + subject(:as_json) do + entity.as_json end it 'matches json schema' do @@ -19,7 +19,7 @@ RSpec.describe GroupLink::GroupGroupLinkEntity do context 'source' do it 'exposes `source`' do - expect(entity.as_json[:source]).to include( + expect(as_json[:source]).to include( id: shared_group.id, full_name: shared_group.full_name, web_url: shared_group.web_url @@ -38,9 +38,9 @@ RSpec.describe GroupLink::GroupGroupLinkEntity do end end - context 'when current user has `:admin_group_member` permissions' do - before do - allow(entity).to receive(:can?).with(current_user, :admin_group_member, shared_group).and_return(true) + context 'when current user has owner permissions for the shared group' do + before_all do + shared_group.add_owner(current_user) end context 'when direct_member? is true' do @@ -49,10 +49,8 @@ RSpec.describe GroupLink::GroupGroupLinkEntity do end it 'exposes `can_update` and `can_remove` as `true`' do - json = entity.as_json - - expect(json[:can_update]).to be true - expect(json[:can_remove]).to be true + expect(as_json[:can_update]).to be true + expect(as_json[:can_remove]).to be true end end @@ -62,10 +60,51 @@ RSpec.describe GroupLink::GroupGroupLinkEntity do end it 'exposes `can_update` and `can_remove` as `true`' do - json = entity.as_json + expect(as_json[:can_update]).to be false + expect(as_json[:can_remove]).to be false + end + end + end + + context 'when current user is not a group member' do + context 'when shared with group is public' do + it 'does expose shared_with_group details' do + expect(as_json[:shared_with_group].keys).to include(:id, :avatar_url, :web_url, :name) + end + + it 'does expose source details' do + expect(as_json[:source].keys).to include(:id, :full_name) + end + + it 'sets is_shared_with_group_private to false' do + expect(as_json[:is_shared_with_group_private]).to be false + end + end + + context 'when shared with group is private' do + let_it_be(:shared_with_group) { create(:group, :private) } + + let_it_be(:group_group_link) do + create( + :group_group_link, + { + shared_group: shared_group, + shared_with_group: shared_with_group, + expires_at: '2020-05-12' + } + ) + end + + it 'does not expose shared_with_group details' do + expect(as_json[:shared_with_group].keys).to contain_exactly(:id) + end + + it 'does not expose source details' do + expect(as_json[:source]).to be_nil + end - expect(json[:can_update]).to be false - expect(json[:can_remove]).to be false + it 'sets is_shared_with_group_private to true' do + expect(as_json[:is_shared_with_group_private]).to be true end end end diff --git a/spec/serializers/group_link/project_group_link_entity_spec.rb b/spec/serializers/group_link/project_group_link_entity_spec.rb index 1a8fcb2cfd3..00bfc43f17e 100644 --- a/spec/serializers/group_link/project_group_link_entity_spec.rb +++ b/spec/serializers/group_link/project_group_link_entity_spec.rb @@ -8,51 +8,69 @@ RSpec.describe GroupLink::ProjectGroupLinkEntity do let(:entity) { described_class.new(project_group_link, { current_user: current_user, source: project_group_link.project }) } - before do - allow(entity).to receive(:current_user).and_return(current_user) + subject(:as_json) do + entity.as_json end it 'matches json schema' do expect(entity.to_json).to match_schema('group_link/project_group_link') end - context 'when current user has `admin_project_member` permissions' do - before do - allow(entity).to receive(:can?).with(current_user, :admin_project_group_link, project_group_link).and_return(false) - allow(entity).to receive(:can?).with(current_user, :admin_project_member, project_group_link.project).and_return(true) + context 'when current user is a project maintainer' do + before_all do + project_group_link.project.add_maintainer(current_user) end it 'exposes `can_update` and `can_remove` as `true`' do - json = entity.as_json - - expect(json[:can_update]).to be true - expect(json[:can_remove]).to be false + expect(as_json[:can_update]).to be true + expect(as_json[:can_remove]).to be true end end context 'when current user is a group owner' do - before do - allow(entity).to receive(:can?).with(current_user, :admin_project_group_link, project_group_link).and_return(true) - allow(entity).to receive(:can?).with(current_user, :admin_project_member, project_group_link.project).and_return(false) + before_all do + project_group_link.group.add_owner(current_user) end it 'exposes `can_remove` as true' do - json = entity.as_json - - expect(json[:can_remove]).to be true + expect(as_json[:can_remove]).to be true end end context 'when current user is not a group owner' do - before do - allow(entity).to receive(:can?).with(current_user, :admin_project_group_link, project_group_link).and_return(false) - allow(entity).to receive(:can?).with(current_user, :admin_project_member, project_group_link.project).and_return(false) + it 'exposes `can_remove` as false' do + expect(as_json[:can_remove]).to be false end - it 'exposes `can_remove` as false' do - json = entity.as_json + context 'when group is public' do + it 'does expose shared_with_group details' do + expect(as_json[:shared_with_group].keys).to include(:id, :avatar_url, :web_url, :name) + end + + it 'does expose source details' do + expect(as_json[:source].keys).to include(:id, :full_name) + end + + it 'sets is_shared_with_group_private to false' do + expect(as_json[:is_shared_with_group_private]).to be false + end + end + + context 'when group is private' do + let_it_be(:private_group) { create(:group, :private) } + let_it_be(:project_group_link) { create(:project_group_link, group: private_group) } + + it 'does not expose shared_with_group details' do + expect(as_json[:shared_with_group].keys).to contain_exactly(:id) + end + + it 'does not expose source details' do + expect(as_json[:source]).to be_nil + end - expect(json[:can_remove]).to be false + it 'sets is_shared_with_group_private to true' do + expect(as_json[:is_shared_with_group_private]).to be true + end end end end |