Commit ccaa45bb authored by Mikołaj Wawrzyniak's avatar Mikołaj Wawrzyniak

Merge branch '342168-make-invite-email-preview-part-of-product' into 'master'

Add preview text to invit emails with goto action

See merge request gitlab-org/gitlab!76573
parents d70fa1b7 a93571a4
...@@ -77,10 +77,6 @@ class InvitesController < ApplicationController ...@@ -77,10 +77,6 @@ class InvitesController < ApplicationController
def track_invite_join_click def track_invite_join_click
return unless member && initial_invite_email? return unless member && initial_invite_email?
if params[:experiment_name] == 'invite_email_preview_text'
experiment(:invite_email_preview_text, actor: member).track(:join_clicked)
end
Gitlab::Tracking.event(self.class.name, 'join_clicked', label: 'invite_email', property: member.id.to_s) Gitlab::Tracking.event(self.class.name, 'join_clicked', label: 'invite_email', property: member.id.to_s)
end end
...@@ -102,7 +98,6 @@ class InvitesController < ApplicationController ...@@ -102,7 +98,6 @@ class InvitesController < ApplicationController
session[:invite_email] = member.invite_email session[:invite_email] = member.invite_email
session[:originating_member_id] = member.id if initial_invite_email? session[:originating_member_id] = member.id if initial_invite_email?
session[:invite_email_experiment_name] = params[:experiment_name] if initial_invite_email? && params[:experiment_name]
end end
def initial_invite_email? def initial_invite_email?
......
...@@ -210,8 +210,6 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -210,8 +210,6 @@ class RegistrationsController < Devise::RegistrationsController
return unless member return unless member
experiment_name = session.delete(:invite_email_experiment_name)
experiment(:invite_email_preview_text, actor: member).track(:accepted) if experiment_name == 'invite_email_preview_text'
Gitlab::Tracking.event(self.class.name, 'accepted', label: 'invite_email', property: member.id.to_s) Gitlab::Tracking.event(self.class.name, 'accepted', label: 'invite_email', property: member.id.to_s)
end end
......
...@@ -20,14 +20,4 @@ module NotifyHelper ...@@ -20,14 +20,4 @@ module NotifyHelper
(source.description || default_description).truncate(200, separator: ' ') (source.description || default_description).truncate(200, separator: ' ')
end end
def invited_join_url(token, member)
additional_params = { invite_type: Emails::Members::INITIAL_INVITE }
if experiment(:invite_email_preview_text, actor: member).enabled?
additional_params[:experiment_name] = 'invite_email_preview_text'
end
invite_url(token, additional_params)
end
end end
...@@ -6,17 +6,15 @@ ...@@ -6,17 +6,15 @@
role: member.human_access.downcase } role: member.human_access.downcase }
- join_text = s_('InviteEmail|Join now') - join_text = s_('InviteEmail|Join now')
- inviter_name = member.created_by.name if member.created_by - inviter_name = member.created_by.name if member.created_by
- join_url = invite_url(@token, invite_type: Emails::Members::INITIAL_INVITE)
- experiment(:invite_email_preview_text, actor: member) do |experiment_instance| = content_for :preview_text do
- experiment_instance.use {}
- experiment_instance.candidate do
= content_for :preview_text do
%div{ style: "display:none;font-size:1px;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;" } %div{ style: "display:none;font-size:1px;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;" }
- if member.created_by - if member.created_by
= s_('InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}') % { inviter: inviter_name, project_or_group_name: placeholders[:project_or_group_name] } = s_('InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}') % { inviter: inviter_name, project_or_group_name: placeholders[:project_or_group_name] }
- else - else
= s_('InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}') % { project_or_group_name: placeholders[:project_or_group_name] } = s_('InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}') % { project_or_group_name: placeholders[:project_or_group_name] }
= gmail_goto_action(join_text, invited_join_url(@token, member)) = gmail_goto_action(join_text, join_url)
%tr %tr
%td.text-content{ colspan: 2 } %td.text-content{ colspan: 2 }
...@@ -32,7 +30,7 @@ ...@@ -32,7 +30,7 @@
- else - else
= html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders = html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders
%p.invite-actions %p.invite-actions
= link_to join_text, invited_join_url(@token, member), class: 'invite-btn-join' = link_to join_text, join_url, class: 'invite-btn-join'
%tr.border-top %tr.border-top
%td.text-content.mailer-align-left.half-width %td.text-content.mailer-align-left.half-width
%h4 %h4
......
---
name: invite_email_preview_text
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67236
rollout_issue_url: https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/421
milestone: '14.2'
type: experiment
group: group::expansion
default_enabled: false
...@@ -97,29 +97,6 @@ RSpec.describe InvitesController do ...@@ -97,29 +97,6 @@ RSpec.describe InvitesController do
) )
end end
context 'when it is part of the invite_email_preview_text experiment' do
let(:extra_params) { { invite_type: 'initial_email', experiment_name: 'invite_email_preview_text' } }
it 'tracks the initial join click from email' do
experiment = double(track: true)
allow(controller).to receive(:experiment).with(:invite_email_preview_text, actor: member).and_return(experiment)
request
expect(experiment).to have_received(:track).with(:join_clicked)
end
context 'when member does not exist' do
let(:raw_invite_token) { '_bogus_token_' }
it 'does not track the experiment' do
expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member)
request
end
end
end
context 'when member does not exist' do context 'when member does not exist' do
let(:raw_invite_token) { '_bogus_token_' } let(:raw_invite_token) { '_bogus_token_' }
...@@ -145,14 +122,6 @@ RSpec.describe InvitesController do ...@@ -145,14 +122,6 @@ RSpec.describe InvitesController do
label: 'invite_email' label: 'invite_email'
) )
end end
context 'when it is not part of our invite email experiment' do
it 'does not track via experiment' do
expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member)
request
end
end
end end
context 'when not logged in' do context 'when not logged in' do
......
...@@ -159,12 +159,11 @@ RSpec.describe RegistrationsController do ...@@ -159,12 +159,11 @@ RSpec.describe RegistrationsController do
let_it_be(:member) { create(:project_member, :invited, invite_email: user_params.dig(:user, :email)) } let_it_be(:member) { create(:project_member, :invited, invite_email: user_params.dig(:user, :email)) }
let(:originating_member_id) { member.id } let(:originating_member_id) { member.id }
let(:extra_session_params) { {} }
let(:session_params) do let(:session_params) do
{ {
invite_email: user_params.dig(:user, :email), invite_email: user_params.dig(:user, :email),
originating_member_id: originating_member_id originating_member_id: originating_member_id
}.merge extra_session_params }
end end
context 'when member exists from the session key value' do context 'when member exists from the session key value' do
...@@ -193,40 +192,6 @@ RSpec.describe RegistrationsController do ...@@ -193,40 +192,6 @@ RSpec.describe RegistrationsController do
) )
end end
end end
context 'with the invite_email_preview_text experiment', :experiment do
let(:extra_session_params) { { invite_email_experiment_name: 'invite_email_preview_text' } }
context 'when member and invite_email_experiment_name exists from the session key value' do
it 'tracks the invite acceptance' do
expect(experiment(:invite_email_preview_text)).to track(:accepted)
.with_context(actor: member)
.on_next_instance
subject
end
end
context 'when member does not exist from the session key value' do
let(:originating_member_id) { -1 }
it 'does not track invite acceptance' do
expect(experiment(:invite_email_preview_text)).not_to track(:accepted)
subject
end
end
context 'when invite_email_experiment_name does not exist from the session key value' do
let(:extra_session_params) { {} }
it 'does not track invite acceptance' do
expect(experiment(:invite_email_preview_text)).not_to track(:accepted)
subject
end
end
end
end end
context 'when invite email matches email used on registration' do context 'when invite email matches email used on registration' do
......
...@@ -226,20 +226,6 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do ...@@ -226,20 +226,6 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end end
end end
context 'with invite email acceptance for the invite_email_preview_text experiment', :experiment do
let(:extra_params) do
{ invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_preview_text' }
end
it 'tracks the accepted invite' do
expect(experiment(:invite_email_preview_text)).to track(:accepted)
.with_context(actor: group_invite)
.on_next_instance
fill_in_sign_up_form(new_user)
end
end
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
fill_in_sign_up_form(new_user) fill_in_sign_up_form(new_user)
fill_in_welcome_form fill_in_welcome_form
......
...@@ -55,31 +55,4 @@ RSpec.describe NotifyHelper do ...@@ -55,31 +55,4 @@ RSpec.describe NotifyHelper do
def reference_link(entity, url) def reference_link(entity, url)
"<a href=\"#{url}\">#{entity.to_reference}</a>" "<a href=\"#{url}\">#{entity.to_reference}</a>"
end end
describe '#invited_join_url' do
let_it_be(:member) { create(:project_member) }
let(:token) { '_token_' }
context 'when invite_email_preview_text is enabled', :experiment do
before do
stub_experiments(invite_email_preview_text: :control)
end
it 'has correct params' do
expect(helper.invited_join_url(token, member))
.to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_preview_text&invite_type=initial_email")
end
end
context 'when invite_email_preview_text is disabled' do
before do
stub_feature_flags(invite_email_preview_text: false)
end
it 'has correct params' do
expect(helper.invited_join_url(token, member)).to eq("http://test.host/-/invites/#{token}?invite_type=initial_email")
end
end
end
end end
...@@ -829,7 +829,7 @@ RSpec.describe Notify do ...@@ -829,7 +829,7 @@ RSpec.describe Notify do
end end
it_behaves_like 'an email sent from GitLab' it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should show Gmail Actions Join now link'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled' it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled' it_behaves_like 'appearance header and footer not enabled'
...@@ -867,27 +867,6 @@ RSpec.describe Notify do ...@@ -867,27 +867,6 @@ RSpec.describe Notify do
end end
end end
context 'with invite_email_preview_text enabled', :experiment do
before do
stub_experiments(invite_email_preview_text: :control)
end
it 'has the correct invite_url with params' do
is_expected.to have_link('Join now',
href: invite_url(project_member.invite_token,
invite_type: Emails::Members::INITIAL_INVITE,
experiment_name: 'invite_email_preview_text'))
end
it 'tracks the sent invite' do
expect(experiment(:invite_email_preview_text)).to track(:assignment)
.with_context(actor: project_member)
.on_next_instance
invite_email.deliver_now
end
end
context 'when invite email sent is tracked', :snowplow do context 'when invite email sent is tracked', :snowplow do
it 'tracks the sent invite' do it 'tracks the sent invite' do
invite_email.deliver_now invite_email.deliver_now
...@@ -1461,7 +1440,7 @@ RSpec.describe Notify do ...@@ -1461,7 +1440,7 @@ RSpec.describe Notify do
subject { described_class.member_invited_email('Group', group_member.id, group_member.invite_token) } subject { described_class.member_invited_email('Group', group_member.id, group_member.invite_token) }
it_behaves_like 'an email sent from GitLab' it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should show Gmail Actions Join now link'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled' it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled' it_behaves_like 'appearance header and footer not enabled'
......
...@@ -161,6 +161,12 @@ RSpec.shared_examples 'it should not have Gmail Actions links' do ...@@ -161,6 +161,12 @@ RSpec.shared_examples 'it should not have Gmail Actions links' do
end end
end end
RSpec.shared_examples 'it should show Gmail Actions Join now link' do
it_behaves_like 'it should have Gmail Actions links'
it { is_expected.to have_body_text('Join now') }
end
RSpec.shared_examples 'it should show Gmail Actions View Issue link' do RSpec.shared_examples 'it should show Gmail Actions View Issue link' do
it_behaves_like 'it should have Gmail Actions links' it_behaves_like 'it should have Gmail Actions links'
......
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