Skip to content
Snippets Groups Projects
Verified Commit 3848e12c authored by Doug Stull's avatar Doug Stull :two:
Browse files

Move tracking for duo pro trial into service layer

- remove business logic from controller layer
- de-deduplicate tracking event for trial success
parent a4b23d79
No related branches found
No related tags found
1 merge request!147698Move tracking for duo pro trial into service layer
......@@ -37,9 +37,6 @@ def create
if @result.success?
# lead and trial created
track_event('duo_pro_trial_registration_success')
flash[:success] = success_flash_message
redirect_to group_usage_quotas_path(@result.payload[:namespace], anchor: 'code-suggestions-usage-tab')
......@@ -58,8 +55,6 @@ def create
render :step_namespace_failed
else
# trial creation failed
track_event('duo_pro_trial_registration_failure')
params[:namespace_id] = @result.payload[:namespace_id]
render :trial_failed
......
......@@ -40,27 +40,35 @@ def lead_flow
result = lead_service_class.new.execute({ trial_user: trial_user_params })
if result.success?
if single_eligible_namespace_for_trial?
@namespace = namespaces_eligible_for_trial.first
apply_trial_flow
else
# trigger new creation for next step...
trial_selection_params = {
step: TRIAL
}.merge(lead_params.slice(:glm_content, :glm_source))
.merge(trial_params.slice(:namespace_id))
ServiceResponse.error(
message: 'Lead created, but singular eligible namespace not present',
reason: NO_SINGLE_NAMESPACE,
payload: { trial_selection_params: trial_selection_params }
)
end
after_lead_success_hook
else
ServiceResponse.error(message: result.message, reason: LEAD_FAILED)
after_lead_error_hook(result)
end
end
def after_lead_success_hook
if single_eligible_namespace_for_trial?
@namespace = namespaces_eligible_for_trial.first
apply_trial_flow
else
# trigger new creation for next step...
trial_selection_params = {
step: TRIAL
}.merge(lead_params.slice(:glm_content, :glm_source))
.merge(trial_params.slice(:namespace_id))
ServiceResponse.error(
message: 'Lead created, but singular eligible namespace not present',
reason: NO_SINGLE_NAMESPACE,
payload: { trial_selection_params: trial_selection_params }
)
end
end
def after_lead_error_hook(result)
ServiceResponse.error(message: result.message, reason: LEAD_FAILED)
end
def lead_service_class
raise NoMethodError, 'Subclasses must implement the lead_service_class method'
end
......@@ -97,16 +105,24 @@ def apply_trial_flow
).execute
if result.success?
Gitlab::Tracking.event(self.class.name, 'create_trial', namespace: namespace, user: user)
ServiceResponse.success(message: 'Trial applied', payload: { namespace: namespace })
after_trial_success_hook
else
ServiceResponse.error(
message: result.message, payload: { namespace_id: trial_params[:namespace_id] }, reason: TRIAL_FAILED
)
after_trial_error_hook(result)
end
end
def after_trial_success_hook
Gitlab::Tracking.event(self.class.name, 'create_trial', namespace: namespace, user: user)
ServiceResponse.success(message: 'Trial applied', payload: { namespace: namespace })
end
def after_trial_error_hook(result)
ServiceResponse.error(
message: result.message, payload: { namespace_id: trial_params[:namespace_id] }, reason: TRIAL_FAILED
)
end
def apply_trial_service_class
raise NoMethodError, 'Subclasses must implement the apply_trial_service_class method'
end
......
......@@ -5,10 +5,28 @@ module Trials
class CreateDuoProService < ::GitlabSubscriptions::Trials::BaseCreateService
private
def lead_flow
super.tap do |response|
track_lead_creation(response)
end
def after_lead_success_hook
track_event('duo_pro_lead_creation_success')
super
end
def after_lead_error_hook(_result)
track_event('duo_pro_lead_creation_failure')
super
end
def after_trial_success_hook
track_event('duo_pro_trial_registration_success')
super
end
def after_trial_error_hook(_result)
track_event('duo_pro_trial_registration_failure')
super
end
def lead_service_class
......@@ -33,14 +51,6 @@ def trial_user_params
)
end
def track_lead_creation(response)
if response.error? && response.reason == LEAD_FAILED
track_event('duo_pro_lead_creation_failure')
else
track_event('duo_pro_lead_creation_success')
end
end
def track_event(action)
Gitlab::InternalEvents.track_event(action, user: user, namespace: namespace)
end
......
......@@ -129,17 +129,6 @@
end
context 'when authenticated as a user with eligible namespaces' do
shared_examples 'with tracking trial registration' do |event|
it_behaves_like 'internal event tracking' do
let(:event) { event }
let(:namespace) { group }
subject(:track_event) do
post trials_duo_pro_path, params: base_params
end
end
end
before do
login_as(user)
end
......@@ -165,8 +154,6 @@
'turning on the toggle for each team member. The subscription may take a minute to sync'
)
end
it_behaves_like 'with tracking trial registration', 'duo_pro_trial_registration_success'
end
context 'with create service failures' do
......@@ -230,8 +217,6 @@
expect(response.body).to include(_('We have found the following errors:'))
end
it_behaves_like 'with tracking trial registration', 'duo_pro_trial_registration_failure'
end
context 'with random failure' do
......@@ -240,8 +225,6 @@
let(:payload) { { namespace_id: namespace.id } }
it { is_expected.to render_select_namespace }
it_behaves_like 'with tracking trial registration', 'duo_pro_trial_registration_failure'
end
end
......
......@@ -30,7 +30,72 @@
it_behaves_like 'when on trial step', :ultimate_plan
it_behaves_like 'with an unknown step'
it_behaves_like 'with no step'
it_behaves_like 'with tracking duo pro trial lead', :ultimate_plan
context 'for tracking the lead step' do
context 'when lead creation is successful regardless' do
let_it_be(:namespace) do
create(:group_with_plan, plan: :ultimate_plan, name: 'gitlab') { |record| record.add_owner(user) }
end
before do
expect_create_lead_success(trial_user_params)
expect_apply_trial_fail(user, namespace, extra_params: existing_group_attrs(namespace))
end
it_behaves_like 'internal event tracking' do
let(:event) { 'duo_pro_lead_creation_success' }
subject(:track_event) { execute }
end
end
context 'when lead creation fails' do
before do
expect_create_lead_fail(trial_user_params)
end
it_behaves_like 'internal event tracking' do
let(:event) { 'duo_pro_lead_creation_failure' }
subject(:track_event) { execute }
end
end
end
context 'for tracking the trial step' do
let(:step) { described_class::TRIAL }
let_it_be(:namespace) do
create(:group_with_plan, plan: :ultimate_plan, name: 'gitlab') { |record| record.add_owner(user) }
end
let(:namespace_id) { namespace.id.to_s }
let(:extra_params) { { trial_entity: '_entity_' } }
let(:trial_params) { { namespace_id: namespace_id }.merge(extra_params) }
context 'for success' do
before do
expect_apply_trial_success(user, namespace, extra_params: extra_params.merge(existing_group_attrs(namespace)))
end
it_behaves_like 'internal event tracking' do
let(:event) { 'duo_pro_trial_registration_success' }
subject(:track_event) { execute }
end
end
context 'for failure' do
before do
expect_apply_trial_fail(user, namespace, extra_params: extra_params.merge(existing_group_attrs(namespace)))
end
it_behaves_like 'internal event tracking' do
let(:event) { 'duo_pro_trial_registration_failure' }
subject(:track_event) { execute }
end
end
end
end
def lead_params(user, extra_lead_params)
......
......@@ -94,40 +94,6 @@
end
end
RSpec.shared_examples 'with tracking duo pro trial lead' do |plan_name|
let_it_be(:group) { create(:group_with_plan, plan: plan_name, name: 'gitlab') { |record| record.add_owner(user) } }
context 'when lead creation is successful regardless' do
before do
expect_create_lead_success(trial_user_params)
expect_apply_trial_fail(user, group, extra_params: existing_group_attrs(group))
end
it_behaves_like 'internal event tracking' do
let(:event) { 'duo_pro_lead_creation_success' }
let(:namespace) { group }
subject(:track_event) do
execute
end
end
end
context 'when lead creation fails' do
before do
expect_create_lead_fail(trial_user_params)
end
it_behaves_like 'internal event tracking' do
let(:event) { 'duo_pro_lead_creation_failure' }
subject(:track_event) do
execute
end
end
end
end
def expect_create_lead_success(trial_user_params)
expect_next_instance_of(lead_service_class) do |instance|
expect(instance).to receive(:execute).with(trial_user_params).and_return(ServiceResponse.success)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment