Commit 93f71003 authored by Doug Stull's avatar Doug Stull Committed by Brandon Labuschagne

Remove invite members in comment experiment

parent bc2029ca
...@@ -20,7 +20,6 @@ import { BV_SHOW_MODAL } from '~/lib/utils/constants'; ...@@ -20,7 +20,6 @@ import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import { getParameterValues } from '~/lib/utils/url_utility'; import { getParameterValues } from '~/lib/utils/url_utility';
import { sprintf } from '~/locale'; import { sprintf } from '~/locale';
import { import {
INVITE_MEMBERS_IN_COMMENT,
GROUP_FILTERS, GROUP_FILTERS,
USERS_FILTER_ALL, USERS_FILTER_ALL,
INVITE_MEMBERS_FOR_TASK, INVITE_MEMBERS_FOR_TASK,
...@@ -254,11 +253,6 @@ export default { ...@@ -254,11 +253,6 @@ export default {
this.submitInviteMembers(); this.submitInviteMembers();
} }
}, },
trackInvite() {
if (this.source === INVITE_MEMBERS_IN_COMMENT) {
this.trackEvent(INVITE_MEMBERS_IN_COMMENT, 'comment_invite_success');
}
},
trackinviteMembersForTask() { trackinviteMembersForTask() {
const label = 'selected_tasks_to_be_done'; const label = 'selected_tasks_to_be_done';
const property = this.selectedTasksToBeDone.join(','); const property = this.selectedTasksToBeDone.join(',');
...@@ -312,7 +306,6 @@ export default { ...@@ -312,7 +306,6 @@ export default {
promises.push(apiAddByUserId(this.id, this.addByUserIdPostData(usersToAddById))); promises.push(apiAddByUserId(this.id, this.addByUserIdPostData(usersToAddById)));
} }
this.trackInvite();
this.trackinviteMembersForTask(); this.trackinviteMembersForTask();
Promise.all(promises) Promise.all(promises)
......
<script> <script>
import { GlButton, GlLink, GlIcon } from '@gitlab/ui'; import { GlButton, GlLink, GlIcon } from '@gitlab/ui';
import ExperimentTracking from '~/experimentation/experiment_tracking';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { TRIGGER_ELEMENT_BUTTON, TRIGGER_ELEMENT_SIDE_NAV } from '../constants'; import { TRIGGER_ELEMENT_BUTTON, TRIGGER_ELEMENT_SIDE_NAV } from '../constants';
...@@ -32,11 +31,6 @@ export default { ...@@ -32,11 +31,6 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
trackExperiment: {
type: String,
required: false,
default: undefined,
},
triggerElement: { triggerElement: {
type: String, type: String,
required: false, required: false,
...@@ -72,9 +66,6 @@ export default { ...@@ -72,9 +66,6 @@ export default {
return baseAttributes; return baseAttributes;
}, },
}, },
mounted() {
this.trackExperimentOnShow();
},
methods: { methods: {
checkTrigger(targetTriggerElement) { checkTrigger(targetTriggerElement) {
return this.triggerElement === targetTriggerElement; return this.triggerElement === targetTriggerElement;
...@@ -82,12 +73,6 @@ export default { ...@@ -82,12 +73,6 @@ export default {
openModal() { openModal() {
eventHub.$emit('openModal', { inviteeType: 'members', source: this.triggerSource }); eventHub.$emit('openModal', { inviteeType: 'members', source: this.triggerSource });
}, },
trackExperimentOnShow() {
if (this.trackExperiment) {
const tracking = new ExperimentTracking(this.trackExperiment);
tracking.event('comment_invite_shown');
}
},
}, },
TRIGGER_ELEMENT_BUTTON, TRIGGER_ELEMENT_BUTTON,
TRIGGER_ELEMENT_SIDE_NAV, TRIGGER_ELEMENT_SIDE_NAV,
......
...@@ -2,7 +2,6 @@ import { __, s__ } from '~/locale'; ...@@ -2,7 +2,6 @@ import { __, s__ } from '~/locale';
export const SEARCH_DELAY = 200; export const SEARCH_DELAY = 200;
export const INVITE_MEMBERS_IN_COMMENT = 'invite_members_in_comment';
export const INVITE_MEMBERS_FOR_TASK = { export const INVITE_MEMBERS_FOR_TASK = {
minimum_access_level: 30, minimum_access_level: 30,
name: 'invite_members_for_task', name: 'invite_members_for_task',
......
<script> <script>
import { GlButton, GlLink, GlLoadingIcon, GlSprintf, GlIcon } from '@gitlab/ui'; import { GlButton, GlLink, GlLoadingIcon, GlSprintf, GlIcon } from '@gitlab/ui';
import { isExperimentVariant } from '~/experimentation/utils';
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
import { INVITE_MEMBERS_IN_COMMENT } from '~/invite_members/constants';
export default { export default {
inviteMembersInComment: INVITE_MEMBERS_IN_COMMENT,
components: { components: {
GlButton, GlButton,
GlLink, GlLink,
GlLoadingIcon, GlLoadingIcon,
GlSprintf, GlSprintf,
GlIcon, GlIcon,
InviteMembersTrigger,
}, },
props: { props: {
markdownDocsPath: { markdownDocsPath: {
...@@ -34,9 +29,6 @@ export default { ...@@ -34,9 +29,6 @@ export default {
hasQuickActionsDocsPath() { hasQuickActionsDocsPath() {
return this.quickActionsDocsPath !== ''; return this.quickActionsDocsPath !== '';
}, },
inviteCommentEnabled() {
return isExperimentVariant(INVITE_MEMBERS_IN_COMMENT, 'invite_member_link');
},
}, },
}; };
</script> </script>
...@@ -67,16 +59,6 @@ export default { ...@@ -67,16 +59,6 @@ export default {
</template> </template>
</div> </div>
<span v-if="canAttachFile" class="uploading-container"> <span v-if="canAttachFile" class="uploading-container">
<invite-members-trigger
v-if="inviteCommentEnabled"
classes="gl-mr-3 gl-vertical-align-text-bottom"
:display-text="s__('InviteMember|Invite Member')"
icon="assignee"
variant="link"
:track-experiment="$options.inviteMembersInComment"
:trigger-source="$options.inviteMembersInComment"
data-track-action="comment_invite_click"
/>
<span class="uploading-progress-container hide"> <span class="uploading-progress-container hide">
<gl-icon name="media" /> <gl-icon name="media" />
<span class="attaching-file-message"></span> <span class="attaching-file-message"></span>
......
...@@ -52,15 +52,6 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -52,15 +52,6 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml) push_frontend_feature_flag(:confidential_notes, @project, default_enabled: :yaml)
push_frontend_feature_flag(:issue_assignees_widget, @project, default_enabled: :yaml) push_frontend_feature_flag(:issue_assignees_widget, @project, default_enabled: :yaml)
push_frontend_feature_flag(:paginated_issue_discussions, @project, default_enabled: :yaml) push_frontend_feature_flag(:paginated_issue_discussions, @project, default_enabled: :yaml)
experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance|
experiment_instance.exclude! unless helpers.can_admin_project_member?(@project)
experiment_instance.use {}
experiment_instance.try(:invite_member_link) {}
experiment_instance.track(:view, property: @project.root_ancestor.id.to_s)
end
end end
around_action :allow_gitaly_ref_name_caching, only: [:discussions] around_action :allow_gitaly_ref_name_caching, only: [:discussions]
......
...@@ -47,15 +47,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -47,15 +47,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml) push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml)
push_frontend_feature_flag(:diff_settings_usage_data, default_enabled: :yaml) push_frontend_feature_flag(:diff_settings_usage_data, default_enabled: :yaml)
push_frontend_feature_flag(:diff_searching_usage_data, @project, default_enabled: :yaml) push_frontend_feature_flag(:diff_searching_usage_data, @project, default_enabled: :yaml)
experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance|
experiment_instance.exclude! unless helpers.can_admin_project_member?(@project)
experiment_instance.use {}
experiment_instance.try(:invite_member_link) {}
experiment_instance.track(:view, property: @project.root_ancestor.id.to_s)
end
end end
before_action do before_action do
......
---
name: invite_members_in_comment
introduced_by_url: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51400'
rollout_issue_url: 'https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/300'
milestone: '13.10'
type: experiment
group: group::expansion
default_enabled: false
...@@ -19317,9 +19317,6 @@ msgstr "" ...@@ -19317,9 +19317,6 @@ msgstr ""
msgid "InviteMember|Add members to this project and start collaborating with your team." msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr "" msgstr ""
msgid "InviteMember|Invite Member"
msgstr ""
msgid "InviteMember|Invite Members (optional)" msgid "InviteMember|Invite Members (optional)"
msgstr "" msgstr ""
......
...@@ -201,32 +201,6 @@ RSpec.describe Projects::IssuesController do ...@@ -201,32 +201,6 @@ RSpec.describe Projects::IssuesController do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['issue_email_participants']).to contain_exactly({ "email" => participants[0].email }, { "email" => participants[1].email }) expect(json_response['issue_email_participants']).to contain_exactly({ "email" => participants[0].email }, { "email" => participants[1].email })
end end
context 'with the invite_members_in_comment experiment', :experiment do
context 'when user can invite' do
before do
stub_experiments(invite_members_in_comment: :invite_member_link)
project.add_maintainer(user)
end
it 'assigns the candidate experience and tracks the event' do
expect(experiment(:invite_members_in_comment)).to track(:view, property: project.root_ancestor.id.to_s)
.for(:invite_member_link)
.with_context(namespace: project.root_ancestor)
.on_next_instance
get :show, params: { namespace_id: project.namespace, project_id: project, id: issue.iid }
end
end
context 'when user can not invite' do
it 'does not track the event' do
expect(experiment(:invite_members_in_comment)).not_to track(:view)
get :show, params: { namespace_id: project.namespace, project_id: project, id: issue.iid }
end
end
end
end end
describe 'GET #new' do describe 'GET #new' do
......
...@@ -42,32 +42,6 @@ RSpec.describe Projects::MergeRequestsController do ...@@ -42,32 +42,6 @@ RSpec.describe Projects::MergeRequestsController do
get :show, params: params.merge(extra_params) get :show, params: params.merge(extra_params)
end end
context 'with the invite_members_in_comment experiment', :experiment do
context 'when user can invite' do
before do
stub_experiments(invite_members_in_comment: :invite_member_link)
project.add_maintainer(user)
end
it 'assigns the candidate experience and tracks the event' do
expect(experiment(:invite_members_in_comment)).to track(:view, property: project.root_ancestor.id.to_s)
.for(:invite_member_link)
.with_context(namespace: project.root_ancestor)
.on_next_instance
go
end
end
context 'when user can not invite' do
it 'does not track the event' do
expect(experiment(:invite_members_in_comment)).not_to track(:view)
go
end
end
end
context 'with view param' do context 'with view param' do
before do before do
go(view: 'parallel') go(view: 'parallel')
......
# frozen_string_literal: true
require "spec_helper"
RSpec.describe "User invites from a comment", :js do
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:user) { project.owner }
before do
sign_in(user)
end
it "launches the invite modal from invite link on a comment" do
stub_experiments(invite_members_in_comment: :invite_member_link)
visit project_issue_path(project, issue)
page.within(".new-note") do
click_button 'Invite Member'
end
expect(page).to have_content("You're inviting members to the")
end
end
# frozen_string_literal: true
require "spec_helper"
RSpec.describe "User invites from a comment", :js do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
let_it_be(:user) { project.owner }
before do
sign_in(user)
end
it "launches the invite modal from invite link on a comment" do
stub_experiments(invite_members_in_comment: :invite_member_link)
visit project_merge_request_path(project, merge_request)
page.within(".new-note") do
click_button 'Invite Member'
end
expect(page).to have_content("You're inviting members to the")
end
end
...@@ -17,7 +17,6 @@ import InviteMembersModal from '~/invite_members/components/invite_members_modal ...@@ -17,7 +17,6 @@ import InviteMembersModal from '~/invite_members/components/invite_members_modal
import ModalConfetti from '~/invite_members/components/confetti.vue'; import ModalConfetti from '~/invite_members/components/confetti.vue';
import MembersTokenSelect from '~/invite_members/components/members_token_select.vue'; import MembersTokenSelect from '~/invite_members/components/members_token_select.vue';
import { import {
INVITE_MEMBERS_IN_COMMENT,
INVITE_MEMBERS_FOR_TASK, INVITE_MEMBERS_FOR_TASK,
CANCEL_BUTTON_TEXT, CANCEL_BUTTON_TEXT,
INVITE_BUTTON_TEXT, INVITE_BUTTON_TEXT,
...@@ -746,7 +745,6 @@ describe('InviteMembersModal', () => { ...@@ -746,7 +745,6 @@ describe('InviteMembersModal', () => {
wrapper.vm.$toast = { show: jest.fn() }; wrapper.vm.$toast = { show: jest.fn() };
jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData }); jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({ data: postData });
jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData }); jest.spyOn(Api, 'addGroupMembersByUserId').mockResolvedValue({ data: postData });
jest.spyOn(wrapper.vm, 'trackInvite');
}); });
describe('when triggered from regular mounting', () => { describe('when triggered from regular mounting', () => {
...@@ -864,31 +862,6 @@ describe('InviteMembersModal', () => { ...@@ -864,31 +862,6 @@ describe('InviteMembersModal', () => {
jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({}); jest.spyOn(Api, 'inviteGroupMembersByEmail').mockResolvedValue({});
}); });
it('tracks the invite', () => {
eventHub.$emit('openModal', { inviteeType: 'members', source: INVITE_MEMBERS_IN_COMMENT });
clickInviteButton();
expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_IN_COMMENT);
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith('comment_invite_success');
});
it('does not track invite for unknown source', () => {
eventHub.$emit('openModal', { inviteeType: 'members', source: 'unknown' });
clickInviteButton();
expect(ExperimentTracking).not.toHaveBeenCalledWith(INVITE_MEMBERS_IN_COMMENT);
});
it('does not track invite undefined source', () => {
eventHub.$emit('openModal', { inviteeType: 'members' });
clickInviteButton();
expect(ExperimentTracking).not.toHaveBeenCalledWith(INVITE_MEMBERS_IN_COMMENT);
});
it('tracks the view for learn_gitlab source', () => { it('tracks the view for learn_gitlab source', () => {
eventHub.$emit('openModal', { inviteeType: 'members', source: LEARN_GITLAB }); eventHub.$emit('openModal', { inviteeType: 'members', source: LEARN_GITLAB });
......
import { GlButton, GlLink, GlIcon } from '@gitlab/ui'; import { GlButton, GlLink, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import ExperimentTracking from '~/experimentation/experiment_tracking';
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue'; import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
import eventHub from '~/invite_members/event_hub'; import eventHub from '~/invite_members/event_hub';
import { TRIGGER_ELEMENT_BUTTON, TRIGGER_ELEMENT_SIDE_NAV } from '~/invite_members/constants'; import { TRIGGER_ELEMENT_BUTTON, TRIGGER_ELEMENT_SIDE_NAV } from '~/invite_members/constants';
...@@ -79,19 +78,6 @@ describe.each(triggerItems)('with triggerElement as %s', (triggerItem) => { ...@@ -79,19 +78,6 @@ describe.each(triggerItems)('with triggerElement as %s', (triggerItem) => {
}); });
describe('tracking', () => { describe('tracking', () => {
it('tracks on mounting', () => {
createComponent({ trackExperiment: '_track_experiment_' });
expect(ExperimentTracking).toHaveBeenCalledWith('_track_experiment_');
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith('comment_invite_shown');
});
it('does not track on mounting', () => {
createComponent();
expect(ExperimentTracking).not.toHaveBeenCalledWith('_track_experiment_');
});
it('does not add tracking attributes', () => { it('does not add tracking attributes', () => {
createComponent(); createComponent();
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { isExperimentVariant } from '~/experimentation/utils';
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
import { INVITE_MEMBERS_IN_COMMENT } from '~/invite_members/constants';
import Toolbar from '~/vue_shared/components/markdown/toolbar.vue'; import Toolbar from '~/vue_shared/components/markdown/toolbar.vue';
jest.mock('~/experimentation/utils', () => ({ isExperimentVariant: jest.fn() }));
describe('toolbar', () => { describe('toolbar', () => {
let wrapper; let wrapper;
const createMountedWrapper = (props = {}) => { const createMountedWrapper = (props = {}) => {
wrapper = mount(Toolbar, { wrapper = mount(Toolbar, {
propsData: { markdownDocsPath: '', ...props }, propsData: { markdownDocsPath: '', ...props },
stubs: { 'invite-members-trigger': true },
}); });
}; };
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
isExperimentVariant.mockReset();
}); });
describe('user can attach file', () => { describe('user can attach file', () => {
...@@ -40,36 +33,4 @@ describe('toolbar', () => { ...@@ -40,36 +33,4 @@ describe('toolbar', () => {
expect(wrapper.vm.$el.querySelector('.uploading-container')).toBeNull(); expect(wrapper.vm.$el.querySelector('.uploading-container')).toBeNull();
}); });
}); });
describe('user can invite member', () => {
const findInviteLink = () => wrapper.find(InviteMembersTrigger);
beforeEach(() => {
isExperimentVariant.mockReturnValue(true);
createMountedWrapper();
});
it('should render the invite members trigger', () => {
expect(findInviteLink().exists()).toBe(true);
});
it('should have correct props', () => {
expect(findInviteLink().props().displayText).toBe('Invite Member');
expect(findInviteLink().props().trackExperiment).toBe(INVITE_MEMBERS_IN_COMMENT);
expect(findInviteLink().props().triggerSource).toBe(INVITE_MEMBERS_IN_COMMENT);
});
});
describe('user can not invite member', () => {
const findInviteLink = () => wrapper.find(InviteMembersTrigger);
beforeEach(() => {
isExperimentVariant.mockReturnValue(false);
createMountedWrapper();
});
it('should render the invite members trigger', () => {
expect(findInviteLink().exists()).toBe(false);
});
});
}); });
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