Commit 0c30a68b authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '327120-add-invite-source-tracking-2' into 'master'

Add invite sources to invite modal submission

See merge request gitlab-org/gitlab!62609
parents ac530fa4 3256a371
...@@ -68,6 +68,7 @@ export default { ...@@ -68,6 +68,7 @@ export default {
newUsersToInvite: [], newUsersToInvite: [],
selectedDate: undefined, selectedDate: undefined,
groupToBeSharedWith: {}, groupToBeSharedWith: {},
source: 'unknown',
}; };
}, },
computed: { computed: {
...@@ -195,6 +196,7 @@ export default { ...@@ -195,6 +196,7 @@ export default {
...this.basePostData, ...this.basePostData,
email: usersToInviteByEmail, email: usersToInviteByEmail,
access_level: this.selectedAccessLevel, access_level: this.selectedAccessLevel,
invite_source: this.source,
}; };
}, },
addByUserIdPostData(usersToAddById) { addByUserIdPostData(usersToAddById) {
...@@ -202,6 +204,7 @@ export default { ...@@ -202,6 +204,7 @@ export default {
...this.basePostData, ...this.basePostData,
user_id: usersToAddById, user_id: usersToAddById,
access_level: this.selectedAccessLevel, access_level: this.selectedAccessLevel,
invite_source: this.source,
}; };
}, },
shareWithGroupPostData(groupToBeSharedWith) { shareWithGroupPostData(groupToBeSharedWith) {
......
...@@ -3,20 +3,19 @@ ...@@ -3,20 +3,19 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Groups > Members > Manage members' do RSpec.describe 'Groups > Members > Manage members' do
include Select2Helper
include Spec::Support::Helpers::Features::MembersHelpers include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper include Spec::Support::Helpers::Features::InviteMembersModalHelper
let(:user1) { create(:user, name: 'John Doe') } let_it_be(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') } let_it_be(:user2) { create(:user, name: 'Mary Jane') }
let(:group) { create(:group) } let_it_be(:group) { create(:group) }
before do before do
sign_in(user1) sign_in(user1)
end end
shared_examples 'includes the correct Invite link' do |should_include, should_not_include| shared_examples 'includes the correct Invite link' do |should_include, should_not_include|
it 'includes either the form or the modal trigger' do it 'includes either the form or the modal trigger', :aggregate_failures do
group.add_owner(user1) group.add_owner(user1)
visit group_group_members_path(group) visit group_group_members_path(group)
...@@ -27,12 +26,12 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -27,12 +26,12 @@ RSpec.describe 'Groups > Members > Manage members' do
end end
shared_examples 'does not include either invite modal or either invite form' do shared_examples 'does not include either invite modal or either invite form' do
it 'does not include either of the invite members or invite group modal buttons' do it 'does not include either of the invite members or invite group modal buttons', :aggregate_failures do
expect(page).not_to have_selector '.js-invite-members-modal' expect(page).not_to have_selector '.js-invite-members-modal'
expect(page).not_to have_selector '.js-invite-group-modal' expect(page).not_to have_selector '.js-invite-group-modal'
end end
it 'does not include either of the invite users or invite group forms' do it 'does not include either of the invite users or invite group forms', :aggregate_failures do
expect(page).not_to have_selector '.invite-users-form' expect(page).not_to have_selector '.invite-users-form'
expect(page).not_to have_selector '.invite-group-form' expect(page).not_to have_selector '.invite-group-form'
end end
...@@ -66,7 +65,7 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -66,7 +65,7 @@ RSpec.describe 'Groups > Members > Manage members' do
end end
end end
it 'add user to group', :js do it 'add user to group', :js, :snowplow, :aggregate_failures do
group.add_owner(user1) group.add_owner(user1)
visit group_group_members_path(group) visit group_group_members_path(group)
...@@ -77,6 +76,13 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -77,6 +76,13 @@ RSpec.describe 'Groups > Members > Manage members' do
expect(page).to have_content(user2.name) expect(page).to have_content(user2.name)
expect(page).to have_button('Reporter') expect(page).to have_button('Reporter')
end end
expect_snowplow_event(
category: 'Members::CreateService',
action: 'create_member',
label: 'unknown',
property: 'existing_user'
)
end end
it 'do not disclose email addresses', :js do it 'do not disclose email addresses', :js do
...@@ -143,11 +149,13 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -143,11 +149,13 @@ RSpec.describe 'Groups > Members > Manage members' do
wait_for_requests wait_for_requests
aggregate_failures do
expect(page).not_to have_content(user2.name) expect(page).not_to have_content(user2.name)
expect(group.users).not_to include(user2) expect(group.users).not_to include(user2)
end end
end
it 'add yourself to group when already an owner', :js do it 'add yourself to group when already an owner', :js, :aggregate_failures do
group.add_owner(user1) group.add_owner(user1)
visit group_group_members_path(group) visit group_group_members_path(group)
...@@ -160,7 +168,7 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -160,7 +168,7 @@ RSpec.describe 'Groups > Members > Manage members' do
end end
end end
it 'invite user to group', :js do it 'invite user to group', :js, :snowplow do
group.add_owner(user1) group.add_owner(user1)
visit group_group_members_path(group) visit group_group_members_path(group)
...@@ -170,14 +178,23 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -170,14 +178,23 @@ RSpec.describe 'Groups > Members > Manage members' do
expect(page).to have_link 'Invited' expect(page).to have_link 'Invited'
click_link 'Invited' click_link 'Invited'
aggregate_failures do
page.within(members_table) do page.within(members_table) do
expect(page).to have_content('test@example.com') expect(page).to have_content('test@example.com')
expect(page).to have_content('Invited') expect(page).to have_content('Invited')
expect(page).to have_button('Reporter') expect(page).to have_button('Reporter')
end end
expect_snowplow_event(
category: 'Members::InviteService',
action: 'create_member',
label: 'unknown',
property: 'net_new_user'
)
end
end end
context 'as a guest', :js do context 'when user is a guest' do
before do before do
group.add_guest(user1) group.add_guest(user1)
group.add_developer(user2) group.add_developer(user2)
...@@ -187,7 +204,7 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -187,7 +204,7 @@ RSpec.describe 'Groups > Members > Manage members' do
it_behaves_like 'does not include either invite modal or either invite form' it_behaves_like 'does not include either invite modal or either invite form'
it 'does not include a button on the members page list to manage or remove the existing member', :js do it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
page.within(second_row) do page.within(second_row) do
# Can not modify user2 role # Can not modify user2 role
expect(page).not_to have_button 'Developer' expect(page).not_to have_button 'Developer'
...@@ -198,7 +215,7 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -198,7 +215,7 @@ RSpec.describe 'Groups > Members > Manage members' do
end end
end end
context 'As a guest when the :invite_members_group_modal feature flag is disabled', :js do context 'when user is a guest and the :invite_members_group_modal feature flag is disabled' do
before do before do
stub_feature_flags(invite_members_group_modal: false) stub_feature_flags(invite_members_group_modal: false)
group.add_guest(user1) group.add_guest(user1)
...@@ -209,7 +226,7 @@ RSpec.describe 'Groups > Members > Manage members' do ...@@ -209,7 +226,7 @@ RSpec.describe 'Groups > Members > Manage members' do
it_behaves_like 'does not include either invite modal or either invite form' it_behaves_like 'does not include either invite modal or either invite form'
it 'does not include a button on the members page list to manage or remove the existing member', :js do it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
page.within(second_row) do page.within(second_row) do
# Can not modify user2 role # Can not modify user2 role
expect(page).not_to have_button 'Developer' expect(page).not_to have_button 'Developer'
......
...@@ -6,17 +6,17 @@ RSpec.describe 'Project members list', :js do ...@@ -6,17 +6,17 @@ RSpec.describe 'Project members list', :js do
include Spec::Support::Helpers::Features::MembersHelpers include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper include Spec::Support::Helpers::Features::InviteMembersModalHelper
let(:user1) { create(:user, name: 'John Doe') } let_it_be(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') } let_it_be(:user2) { create(:user, name: 'Mary Jane') }
let(:group) { create(:group) } let_it_be(:group) { create(:group) }
let(:project) { create(:project, :internal, namespace: group) } let_it_be(:project) { create(:project, :internal, namespace: group) }
before do before do
sign_in(user1) sign_in(user1)
group.add_owner(user1) group.add_owner(user1)
end end
it 'show members from project and group' do it 'show members from project and group', :aggregate_failures do
project.add_developer(user2) project.add_developer(user2)
visit_members_page visit_members_page
...@@ -25,7 +25,7 @@ RSpec.describe 'Project members list', :js do ...@@ -25,7 +25,7 @@ RSpec.describe 'Project members list', :js do
expect(second_row).to have_content(user2.name) expect(second_row).to have_content(user2.name)
end end
it 'show user once if member of both group and project' do it 'show user once if member of both group and project', :aggregate_failures do
project.add_developer(user1) project.add_developer(user1)
visit_members_page visit_members_page
...@@ -47,7 +47,7 @@ RSpec.describe 'Project members list', :js do ...@@ -47,7 +47,7 @@ RSpec.describe 'Project members list', :js do
end end
end end
it 'add user to project' do it 'add user to project', :snowplow, :aggregate_failures do
visit_members_page visit_members_page
invite_member(user2.name, role: 'Reporter') invite_member(user2.name, role: 'Reporter')
...@@ -55,9 +55,16 @@ RSpec.describe 'Project members list', :js do ...@@ -55,9 +55,16 @@ RSpec.describe 'Project members list', :js do
page.within find_member_row(user2) do page.within find_member_row(user2) do
expect(page).to have_button('Reporter') expect(page).to have_button('Reporter')
end end
expect_snowplow_event(
category: 'Members::CreateService',
action: 'create_member',
label: 'unknown',
property: 'existing_user'
)
end end
it 'uses ProjectMember access_level_roles for the invite members modal access option' do it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do
visit_members_page visit_members_page
click_on 'Invite members' click_on 'Invite members'
...@@ -95,7 +102,7 @@ RSpec.describe 'Project members list', :js do ...@@ -95,7 +102,7 @@ RSpec.describe 'Project members list', :js do
expect(members_table).not_to have_content(other_user.name) expect(members_table).not_to have_content(other_user.name)
end end
it 'invite user to project' do it 'invite user to project', :snowplow, :aggregate_failures do
visit_members_page visit_members_page
invite_member('test@example.com', role: 'Reporter') invite_member('test@example.com', role: 'Reporter')
...@@ -105,6 +112,13 @@ RSpec.describe 'Project members list', :js do ...@@ -105,6 +112,13 @@ RSpec.describe 'Project members list', :js do
page.within find_invited_member_row('test@example.com') do page.within find_invited_member_row('test@example.com') do
expect(page).to have_button('Reporter') expect(page).to have_button('Reporter')
end end
expect_snowplow_event(
category: 'Members::InviteService',
action: 'create_member',
label: 'unknown',
property: 'net_new_user'
)
end end
context 'as a signed out visitor viewing a public project' do context 'as a signed out visitor viewing a public project' do
...@@ -128,7 +142,7 @@ RSpec.describe 'Project members list', :js do ...@@ -128,7 +142,7 @@ RSpec.describe 'Project members list', :js do
project.add_maintainer(project_bot) project.add_maintainer(project_bot)
end end
it 'does not show form used to change roles and "Expiration date" or the remove user button' do it 'does not show form used to change roles and "Expiration date" or the remove user button', :aggregate_failures do
visit_members_page visit_members_page
page.within find_member_row(project_bot) do page.within find_member_row(project_bot) do
......
...@@ -15,6 +15,7 @@ const isProject = false; ...@@ -15,6 +15,7 @@ const isProject = false;
const inviteeType = 'members'; const inviteeType = 'members';
const accessLevels = { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 }; const accessLevels = { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 };
const defaultAccessLevel = 10; const defaultAccessLevel = 10;
const inviteSource = 'unknown';
const helpLink = 'https://example.com'; const helpLink = 'https://example.com';
const user1 = { id: 1, name: 'Name One', username: 'one_1', avatar_url: '' }; const user1 = { id: 1, name: 'Name One', username: 'one_1', avatar_url: '' };
...@@ -173,6 +174,7 @@ describe('InviteMembersModal', () => { ...@@ -173,6 +174,7 @@ describe('InviteMembersModal', () => {
user_id: '1', user_id: '1',
access_level: defaultAccessLevel, access_level: defaultAccessLevel,
expires_at: undefined, expires_at: undefined,
invite_source: inviteSource,
format: 'json', format: 'json',
}; };
...@@ -245,6 +247,7 @@ describe('InviteMembersModal', () => { ...@@ -245,6 +247,7 @@ describe('InviteMembersModal', () => {
access_level: defaultAccessLevel, access_level: defaultAccessLevel,
expires_at: undefined, expires_at: undefined,
email: 'email@example.com', email: 'email@example.com',
invite_source: inviteSource,
format: 'json', format: 'json',
}; };
...@@ -293,6 +296,7 @@ describe('InviteMembersModal', () => { ...@@ -293,6 +296,7 @@ describe('InviteMembersModal', () => {
const postData = { const postData = {
access_level: defaultAccessLevel, access_level: defaultAccessLevel,
expires_at: undefined, expires_at: undefined,
invite_source: inviteSource,
format: 'json', format: 'json',
}; };
...@@ -308,7 +312,10 @@ describe('InviteMembersModal', () => { ...@@ -308,7 +312,10 @@ describe('InviteMembersModal', () => {
jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData }); jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData });
jest.spyOn(wrapper.vm, 'showToastMessageSuccess'); jest.spyOn(wrapper.vm, 'showToastMessageSuccess');
jest.spyOn(wrapper.vm, 'trackInvite'); jest.spyOn(wrapper.vm, 'trackInvite');
});
describe('when triggered from regular mounting', () => {
beforeEach(() => {
clickInviteButton(); clickInviteButton();
}); });
...@@ -325,6 +332,22 @@ describe('InviteMembersModal', () => { ...@@ -325,6 +332,22 @@ describe('InviteMembersModal', () => {
}); });
}); });
it('calls Apis with the invite source passed through to openModal', () => {
wrapper.vm.openModal({ inviteeType: 'members', source: '_invite_source_' });
clickInviteButton();
expect(Api.inviteGroupMembersByEmail).toHaveBeenCalledWith(id, {
...emailPostData,
invite_source: '_invite_source_',
});
expect(Api.addGroupMembersByUserId).toHaveBeenCalledWith(id, {
...idPostData,
invite_source: '_invite_source_',
});
});
});
describe('when any invite failed for any reason', () => { describe('when any invite failed for any reason', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ newUsersToInvite: [user1, user3] }); wrapper = createComponent({ newUsersToInvite: [user1, user3] });
...@@ -403,18 +426,11 @@ describe('InviteMembersModal', () => { ...@@ -403,18 +426,11 @@ describe('InviteMembersModal', () => {
}); });
describe('tracking', () => { describe('tracking', () => {
const postData = {
user_id: '1',
access_level: defaultAccessLevel,
expires_at: undefined,
format: 'json',
};
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ newUsersToInvite: [user3] }); wrapper = createComponent({ newUsersToInvite: [user3] });
wrapper.vm.$toast = { show: jest.fn() }; wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData }); jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({});
}); });
it('tracks the invite', () => { it('tracks the invite', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment