1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::RecordTargetPlatformsService, '#execute' do
let_it_be(:project) { create(:project) }
let(:detector_service) { Projects::AppleTargetPlatformDetectorService }
subject(:execute) { described_class.new(project, detector_service).execute }
context 'when detector returns target platform values' do
let(:detector_result) { [:ios, :osx] }
let(:service_result) { detector_result.map(&:to_s) }
before do
double = instance_double(detector_service, execute: detector_result)
allow(detector_service).to receive(:new) { double }
end
shared_examples 'saves and returns detected target platforms' do
it 'creates a new setting record for the project', :aggregate_failures do
expect { execute }.to change { ProjectSetting.count }.from(0).to(1)
expect(ProjectSetting.last.target_platforms).to match_array(service_result)
end
it 'returns the array of stored target platforms' do
expect(execute).to match_array service_result
end
end
it_behaves_like 'saves and returns detected target platforms'
context 'when detector returns a non-array value' do
let(:detector_service) { Projects::AndroidTargetPlatformDetectorService }
let(:detector_result) { :android }
let(:service_result) { [detector_result.to_s] }
it_behaves_like 'saves and returns detected target platforms'
end
context 'when a project has an existing setting record' do
before do
create(:project_setting, project: project, target_platforms: saved_target_platforms)
end
def project_setting
ProjectSetting.find_by_project_id(project.id)
end
context 'when target platforms changed' do
let(:saved_target_platforms) { %w(tvos) }
it 'updates' do
expect { execute }.to change { project_setting.target_platforms }.from(%w(tvos)).to(%w(ios osx))
end
it { is_expected.to match_array %w(ios osx) }
end
context 'when target platforms are the same' do
let(:saved_target_platforms) { %w(osx ios) }
it 'does not update' do
expect { execute }.not_to change { project_setting.updated_at }
end
end
end
describe 'Build iOS guide email experiment' do
shared_examples 'tracks experiment assignment event' do
it 'tracks the assignment event', :experiment do
expect(experiment(:build_ios_app_guide_email))
.to track(:assignment)
.with_context(project: project)
.on_next_instance
execute
end
end
context 'experiment candidate' do
before do
stub_experiments(build_ios_app_guide_email: :candidate)
end
it 'executes a Projects::InProductMarketingCampaignEmailsService' do
service_double = instance_double(Projects::InProductMarketingCampaignEmailsService, execute: true)
expect(Projects::InProductMarketingCampaignEmailsService)
.to receive(:new).with(project, Users::InProductMarketingEmail::BUILD_IOS_APP_GUIDE)
.and_return service_double
expect(service_double).to receive(:execute)
execute
end
it_behaves_like 'tracks experiment assignment event'
end
shared_examples 'does not send email' do
it 'does not execute a Projects::InProductMarketingCampaignEmailsService' do
expect(Projects::InProductMarketingCampaignEmailsService).not_to receive(:new)
execute
end
end
context 'experiment control' do
before do
stub_experiments(build_ios_app_guide_email: :control)
end
it_behaves_like 'does not send email'
it_behaves_like 'tracks experiment assignment event'
end
context 'when project is not an iOS project' do
let(:detector_service) { Projects::AppleTargetPlatformDetectorService }
let(:detector_result) { :android }
before do
stub_experiments(build_ios_app_guide_email: :candidate)
end
it_behaves_like 'does not send email'
it 'does not track experiment assignment event', :experiment do
expect(experiment(:build_ios_app_guide_email))
.not_to track(:assignment)
execute
end
end
end
end
context 'when detector does not return any target platform values' do
before do
double = instance_double(Projects::AppleTargetPlatformDetectorService, execute: [])
allow(Projects::AppleTargetPlatformDetectorService).to receive(:new).with(project) { double }
end
it 'does nothing' do
expect { execute }.not_to change { ProjectSetting.count }
end
it { is_expected.to be_nil }
end
end
|