amplitude-api 0.0.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +2 -1
- data/.rubocop.yml +32 -0
- data/.travis.yml +2 -3
- data/Changelog.md +34 -0
- data/Gemfile +9 -7
- data/Gemfile.lock +48 -43
- data/Rakefile +7 -5
- data/amplitude-api.gemspec +17 -16
- data/lib/amplitude-api.rb +3 -4
- data/lib/amplitude_api.rb +125 -24
- data/lib/amplitude_api/config.rb +51 -0
- data/lib/amplitude_api/event.rb +129 -80
- data/lib/amplitude_api/identification.rb +10 -3
- data/lib/amplitude_api/version.rb +3 -1
- data/readme.md +22 -5
- data/spec/lib/amplitude_api/event_spec.rb +234 -59
- data/spec/lib/amplitude_api/identification_spec.rb +21 -14
- data/spec/lib/amplitude_api_spec.rb +475 -161
- data/spec/spec_helper.rb +7 -4
- metadata +30 -29
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
2
4
|
|
|
3
5
|
describe AmplitudeAPI::Identification do
|
|
4
6
|
user = Struct.new(:id)
|
|
5
7
|
|
|
6
|
-
context
|
|
7
|
-
describe
|
|
8
|
+
context "with a user object" do
|
|
9
|
+
describe "#body" do
|
|
8
10
|
it "populates with the user's id" do
|
|
9
11
|
identification = described_class.new(user_id: user.new(123))
|
|
10
12
|
expect(identification.to_hash[:user_id]).to eq(123)
|
|
@@ -12,8 +14,8 @@ describe AmplitudeAPI::Identification do
|
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
context
|
|
16
|
-
describe
|
|
17
|
+
context "with a user id" do
|
|
18
|
+
describe "#body" do
|
|
17
19
|
it "populates with the user's id" do
|
|
18
20
|
identification = described_class.new(user_id: 123)
|
|
19
21
|
expect(identification.to_hash[:user_id]).to eq(123)
|
|
@@ -21,30 +23,35 @@ describe AmplitudeAPI::Identification do
|
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
context
|
|
25
|
-
describe
|
|
26
|
-
it
|
|
26
|
+
context "without a user" do
|
|
27
|
+
describe "#body" do
|
|
28
|
+
it "populates with the unknown user" do
|
|
27
29
|
identification = described_class.new(user_id: nil)
|
|
28
30
|
expect(identification.to_hash[:user_id]).to eq(AmplitudeAPI::USER_WITH_NO_ACCOUNT)
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
describe
|
|
34
|
-
it
|
|
35
|
+
describe "#body" do
|
|
36
|
+
it "includes the user id" do
|
|
35
37
|
identification = described_class.new(user_id: 123)
|
|
36
38
|
expect(identification.to_hash[:user_id]).to eq(123)
|
|
37
39
|
end
|
|
38
40
|
|
|
39
|
-
it
|
|
41
|
+
it "includes the device id" do
|
|
42
|
+
identification = described_class.new(user_id: 123, device_id: "abc")
|
|
43
|
+
expect(identification.to_hash[:device_id]).to eq("abc")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "includes arbitrary user properties" do
|
|
40
47
|
identification = described_class.new(
|
|
41
48
|
user_id: 123,
|
|
42
49
|
user_properties: {
|
|
43
|
-
first_name:
|
|
44
|
-
last_name:
|
|
50
|
+
first_name: "John",
|
|
51
|
+
last_name: "Doe"
|
|
45
52
|
}
|
|
46
53
|
)
|
|
47
|
-
expect(identification.to_hash[:user_properties]).to eq(first_name:
|
|
54
|
+
expect(identification.to_hash[:user_properties]).to eq(first_name: "John", last_name: "Doe")
|
|
48
55
|
end
|
|
49
56
|
end
|
|
50
57
|
end
|
|
@@ -1,83 +1,170 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
2
4
|
|
|
3
5
|
describe AmplitudeAPI do
|
|
4
6
|
let(:user) { Struct.new(:id).new(123) }
|
|
7
|
+
let(:device_id) { "abcdef" }
|
|
8
|
+
|
|
9
|
+
describe ".track" do
|
|
10
|
+
context "with a single event" do
|
|
11
|
+
context "with only user_id" do
|
|
12
|
+
it "sends the event to Amplitude" do
|
|
13
|
+
event = AmplitudeAPI::Event.new(
|
|
14
|
+
user_id: 123,
|
|
15
|
+
event_type: "clicked on sign up"
|
|
16
|
+
)
|
|
17
|
+
body = JSON.generate(
|
|
18
|
+
api_key: described_class.api_key,
|
|
19
|
+
events: [event.to_hash]
|
|
20
|
+
)
|
|
21
|
+
headers = { "Content-Type" => "application/json" }
|
|
22
|
+
|
|
23
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::TRACK_URI_STRING, body, headers)
|
|
24
|
+
|
|
25
|
+
described_class.track(event)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
5
28
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
context "with only device_id" do
|
|
30
|
+
it "sends the event to Amplitude" do
|
|
31
|
+
event = AmplitudeAPI::Event.new(
|
|
32
|
+
device_id: device_id,
|
|
33
|
+
event_type: "clicked on sign up"
|
|
34
|
+
)
|
|
35
|
+
body = JSON.generate(
|
|
36
|
+
api_key: described_class.api_key,
|
|
37
|
+
events: [event.to_hash]
|
|
38
|
+
)
|
|
39
|
+
headers = { "Content-Type" => "application/json" }
|
|
40
|
+
|
|
41
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::TRACK_URI_STRING, body, headers)
|
|
42
|
+
|
|
43
|
+
described_class.track(event)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
context "with both user_id and device_id" do
|
|
48
|
+
it "sends the event to Amplitude" do
|
|
49
|
+
event = AmplitudeAPI::Event.new(
|
|
50
|
+
user_id: 123,
|
|
51
|
+
device_id: device_id,
|
|
52
|
+
event_type: "clicked on sign up"
|
|
53
|
+
)
|
|
54
|
+
body = JSON.generate(
|
|
55
|
+
api_key: described_class.api_key,
|
|
56
|
+
events: [event.to_hash]
|
|
57
|
+
)
|
|
58
|
+
headers = { "Content-Type" => "application/json" }
|
|
59
|
+
|
|
60
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::TRACK_URI_STRING, body, headers)
|
|
61
|
+
|
|
62
|
+
described_class.track(event)
|
|
63
|
+
end
|
|
21
64
|
end
|
|
22
65
|
end
|
|
23
66
|
|
|
24
|
-
context
|
|
25
|
-
it
|
|
67
|
+
context "with multiple events" do
|
|
68
|
+
it "sends all events in a single request" do
|
|
26
69
|
event = AmplitudeAPI::Event.new(
|
|
27
70
|
user_id: 123,
|
|
28
|
-
event_type:
|
|
71
|
+
event_type: "clicked on sign up"
|
|
29
72
|
)
|
|
30
73
|
event2 = AmplitudeAPI::Event.new(
|
|
31
74
|
user_id: 456,
|
|
32
|
-
event_type:
|
|
75
|
+
event_type: "liked a widget"
|
|
33
76
|
)
|
|
34
|
-
body =
|
|
77
|
+
body = JSON.generate(
|
|
35
78
|
api_key: described_class.api_key,
|
|
36
|
-
|
|
37
|
-
|
|
79
|
+
events: [event.to_hash, event2.to_hash]
|
|
80
|
+
)
|
|
81
|
+
headers = { "Content-Type" => "application/json" }
|
|
38
82
|
|
|
39
|
-
expect(
|
|
83
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::TRACK_URI_STRING, body, headers)
|
|
40
84
|
|
|
41
85
|
described_class.track([event, event2])
|
|
42
86
|
end
|
|
43
87
|
end
|
|
44
88
|
end
|
|
45
89
|
|
|
46
|
-
describe
|
|
47
|
-
context
|
|
48
|
-
|
|
49
|
-
identification
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
90
|
+
describe ".identify" do
|
|
91
|
+
context "with a single identification" do
|
|
92
|
+
context "with only user_id" do
|
|
93
|
+
it "sends the identification to Amplitude" do
|
|
94
|
+
identification = AmplitudeAPI::Identification.new(
|
|
95
|
+
user_id: 123,
|
|
96
|
+
user_properties: {
|
|
97
|
+
first_name: "John",
|
|
98
|
+
last_name: "Doe"
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
body = {
|
|
102
|
+
api_key: described_class.api_key,
|
|
103
|
+
identification: JSON.generate([identification.to_hash])
|
|
54
104
|
}
|
|
55
|
-
)
|
|
56
|
-
body = {
|
|
57
|
-
api_key: described_class.api_key,
|
|
58
|
-
identification: JSON.generate([identification.to_hash])
|
|
59
|
-
}
|
|
60
105
|
|
|
61
|
-
|
|
106
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::IDENTIFY_URI_STRING, body)
|
|
107
|
+
|
|
108
|
+
described_class.identify(identification)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "with only device_id" do
|
|
113
|
+
it "sends the identification to Amplitude" do
|
|
114
|
+
identification = AmplitudeAPI::Identification.new(
|
|
115
|
+
device_id: device_id,
|
|
116
|
+
user_properties: {
|
|
117
|
+
first_name: "John",
|
|
118
|
+
last_name: "Doe"
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
body = {
|
|
122
|
+
api_key: described_class.api_key,
|
|
123
|
+
identification: JSON.generate([identification.to_hash])
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::IDENTIFY_URI_STRING, body)
|
|
62
127
|
|
|
63
|
-
|
|
128
|
+
described_class.identify(identification)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "with both user_id and device_id" do
|
|
133
|
+
it "sends the identification to Amplitude" do
|
|
134
|
+
identification = AmplitudeAPI::Identification.new(
|
|
135
|
+
user_id: 123,
|
|
136
|
+
device_id: device_id,
|
|
137
|
+
user_properties: {
|
|
138
|
+
first_name: "John",
|
|
139
|
+
last_name: "Doe"
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
body = {
|
|
143
|
+
api_key: described_class.api_key,
|
|
144
|
+
identification: JSON.generate([identification.to_hash])
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::IDENTIFY_URI_STRING, body)
|
|
148
|
+
|
|
149
|
+
described_class.identify(identification)
|
|
150
|
+
end
|
|
64
151
|
end
|
|
65
152
|
end
|
|
66
153
|
|
|
67
|
-
context
|
|
68
|
-
it
|
|
154
|
+
context "with multiple identifications" do
|
|
155
|
+
it "sends all identifications in a single request" do
|
|
69
156
|
identification = AmplitudeAPI::Identification.new(
|
|
70
157
|
user_id: 123,
|
|
71
158
|
user_properties: {
|
|
72
|
-
first_name:
|
|
73
|
-
last_name:
|
|
159
|
+
first_name: "Julian",
|
|
160
|
+
last_name: "Ponce"
|
|
74
161
|
}
|
|
75
162
|
)
|
|
76
163
|
identification2 = AmplitudeAPI::Identification.new(
|
|
77
|
-
|
|
164
|
+
device_id: 456,
|
|
78
165
|
user_properties: {
|
|
79
|
-
first_name:
|
|
80
|
-
last_name:
|
|
166
|
+
first_name: "John",
|
|
167
|
+
last_name: "Doe"
|
|
81
168
|
}
|
|
82
169
|
)
|
|
83
170
|
body = {
|
|
@@ -85,188 +172,415 @@ describe AmplitudeAPI do
|
|
|
85
172
|
identification: JSON.generate([identification.to_hash, identification2.to_hash])
|
|
86
173
|
}
|
|
87
174
|
|
|
88
|
-
expect(
|
|
175
|
+
expect(Faraday).to receive(:post).with(AmplitudeAPI::IDENTIFY_URI_STRING, body)
|
|
89
176
|
|
|
90
177
|
described_class.identify([identification, identification2])
|
|
91
178
|
end
|
|
92
179
|
end
|
|
93
180
|
end
|
|
94
181
|
|
|
95
|
-
describe
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
expect(event.to_hash).to eq(
|
|
99
|
-
event_type: '',
|
|
100
|
-
user_id: '',
|
|
101
|
-
event_properties: {},
|
|
102
|
-
user_properties: {},
|
|
103
|
-
ip: ''
|
|
104
|
-
)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it 'initializes event with parameter' do
|
|
108
|
-
event = AmplitudeAPI::Event.new(
|
|
182
|
+
describe ".initializer" do
|
|
183
|
+
let(:attributes) do
|
|
184
|
+
{
|
|
109
185
|
user_id: 123,
|
|
110
|
-
event_type:
|
|
186
|
+
event_type: "test_event",
|
|
111
187
|
event_properties: {
|
|
112
188
|
test_property: 1
|
|
113
189
|
},
|
|
114
|
-
ip: '8.8.8.8'
|
|
115
|
-
)
|
|
116
|
-
expect(event.to_hash).to eq(
|
|
117
|
-
event_type: 'test_event',
|
|
118
|
-
user_id: 123,
|
|
119
|
-
event_properties: { test_property: 1 },
|
|
120
190
|
user_properties: {},
|
|
121
|
-
ip:
|
|
122
|
-
|
|
191
|
+
ip: "8.8.8.8"
|
|
192
|
+
}
|
|
123
193
|
end
|
|
124
|
-
end
|
|
125
194
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
user_id: user,
|
|
130
|
-
event_type: 'test_event',
|
|
131
|
-
event_properties: { test_property: 1 }
|
|
132
|
-
)
|
|
133
|
-
expect(described_class).to receive(:track).with(event)
|
|
134
|
-
|
|
135
|
-
described_class.send_event('test_event', user, event_properties: { test_property: 1 })
|
|
195
|
+
it "requires event type" do
|
|
196
|
+
attributes.delete(:event_type)
|
|
197
|
+
expect { AmplitudeAPI::Event.new(attributes) }.to raise_error(ArgumentError)
|
|
136
198
|
end
|
|
137
199
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
expect(described_class).to receive(:track).with(event)
|
|
200
|
+
it "requires user id or device id" do
|
|
201
|
+
expect(AmplitudeAPI::Event.new(attributes).to_h).to eq(attributes)
|
|
202
|
+
attributes.merge!(device_id: "abc").delete(:user_id)
|
|
203
|
+
expect(AmplitudeAPI::Event.new(attributes).to_h).to eq(attributes)
|
|
204
|
+
attributes.delete(:device_id)
|
|
205
|
+
expect { AmplitudeAPI::Event.new(attributes) }.to raise_error(ArgumentError)
|
|
206
|
+
end
|
|
146
207
|
|
|
147
|
-
|
|
148
|
-
|
|
208
|
+
it "initializes event with parameter" do
|
|
209
|
+
expect(AmplitudeAPI::Event.new(attributes)).to eq(attributes)
|
|
149
210
|
end
|
|
211
|
+
end
|
|
150
212
|
|
|
151
|
-
|
|
152
|
-
|
|
213
|
+
describe ".send_event" do
|
|
214
|
+
context "with only user_id" do
|
|
215
|
+
it "sends an event to AmplitudeAPI" do
|
|
153
216
|
event = AmplitudeAPI::Event.new(
|
|
154
|
-
user_id:
|
|
155
|
-
event_type:
|
|
217
|
+
user_id: user,
|
|
218
|
+
event_type: "test_event",
|
|
156
219
|
event_properties: { test_property: 1 }
|
|
157
220
|
)
|
|
158
221
|
expect(described_class).to receive(:track).with(event)
|
|
159
222
|
|
|
160
|
-
described_class.send_event(
|
|
223
|
+
described_class.send_event("test_event", user, nil, event_properties: { test_property: 1 })
|
|
161
224
|
end
|
|
162
225
|
|
|
163
|
-
|
|
164
|
-
event
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
226
|
+
context "the user is nil" do
|
|
227
|
+
it "sends an event with the no account user" do
|
|
228
|
+
event = AmplitudeAPI::Event.new(
|
|
229
|
+
user_id: nil,
|
|
230
|
+
event_type: "test_event",
|
|
231
|
+
event_properties: { test_property: 1 }
|
|
232
|
+
)
|
|
233
|
+
expect(described_class).to receive(:track).with(event)
|
|
234
|
+
|
|
235
|
+
described_class.send_event("test_event", nil, nil, event_properties: { test_property: 1 })
|
|
236
|
+
end
|
|
237
|
+
end
|
|
171
238
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
239
|
+
context "the user is a user_id" do
|
|
240
|
+
it "sends an event to AmplitudeAPI" do
|
|
241
|
+
event = AmplitudeAPI::Event.new(
|
|
242
|
+
user_id: 123,
|
|
243
|
+
event_type: "test_event",
|
|
244
|
+
event_properties: { test_property: 1 }
|
|
245
|
+
)
|
|
246
|
+
expect(described_class).to receive(:track).with(event)
|
|
247
|
+
|
|
248
|
+
described_class.send_event("test_event", user.id, nil, event_properties: { test_property: 1 })
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it "sends arbitrary user_properties to AmplitudeAPI" do
|
|
252
|
+
event = AmplitudeAPI::Event.new(
|
|
253
|
+
user_id: 123,
|
|
254
|
+
event_type: "test_event",
|
|
255
|
+
event_properties: { test_property: 1 },
|
|
256
|
+
user_properties: { test_user_property: "abc" }
|
|
257
|
+
)
|
|
258
|
+
expect(described_class).to receive(:track).with(event)
|
|
259
|
+
|
|
260
|
+
described_class.send_event(
|
|
261
|
+
"test_event",
|
|
262
|
+
user.id,
|
|
263
|
+
nil,
|
|
264
|
+
event_properties: { test_property: 1 },
|
|
265
|
+
user_properties: { test_user_property: "abc" }
|
|
266
|
+
)
|
|
267
|
+
end
|
|
178
268
|
end
|
|
179
269
|
end
|
|
180
|
-
end
|
|
181
270
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
271
|
+
context "with device_id" do
|
|
272
|
+
context "the user is not nil" do
|
|
273
|
+
it "sends an event to AmplitudeAPI" do
|
|
274
|
+
event = AmplitudeAPI::Event.new(
|
|
275
|
+
user_id: user,
|
|
276
|
+
device_id: device_id,
|
|
277
|
+
event_type: "test_event",
|
|
278
|
+
event_properties: { test_property: 1 }
|
|
279
|
+
)
|
|
280
|
+
expect(described_class).to receive(:track).with(event)
|
|
281
|
+
|
|
282
|
+
described_class.send_event("test_event", user, device_id, event_properties: { test_property: 1 })
|
|
283
|
+
end
|
|
284
|
+
end
|
|
192
285
|
|
|
193
|
-
|
|
286
|
+
context "the user is nil" do
|
|
287
|
+
it "sends an event with the no account user" do
|
|
288
|
+
event = AmplitudeAPI::Event.new(
|
|
289
|
+
user_id: nil,
|
|
290
|
+
device_id: device_id,
|
|
291
|
+
event_type: "test_event",
|
|
292
|
+
event_properties: { test_property: 1 }
|
|
293
|
+
)
|
|
294
|
+
expect(described_class).to receive(:track).with(event)
|
|
295
|
+
|
|
296
|
+
described_class.send_event("test_event", nil, device_id, event_properties: { test_property: 1 })
|
|
297
|
+
end
|
|
298
|
+
end
|
|
194
299
|
end
|
|
300
|
+
end
|
|
195
301
|
|
|
196
|
-
|
|
197
|
-
|
|
302
|
+
describe ".send_identify" do
|
|
303
|
+
context "with no device_id" do
|
|
304
|
+
it "sends an identify to AmplitudeAPI" do
|
|
198
305
|
identification = AmplitudeAPI::Identification.new(
|
|
199
|
-
user_id:
|
|
306
|
+
user_id: user,
|
|
200
307
|
user_properties: {
|
|
201
|
-
first_name:
|
|
202
|
-
last_name:
|
|
308
|
+
first_name: "John",
|
|
309
|
+
last_name: "Doe"
|
|
203
310
|
}
|
|
204
311
|
)
|
|
205
312
|
expect(described_class).to receive(:identify).with(identification)
|
|
206
313
|
|
|
207
|
-
described_class.send_identify(nil, first_name:
|
|
314
|
+
described_class.send_identify(user, nil, first_name: "John", last_name: "Doe")
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
context "the user is nil" do
|
|
318
|
+
it "sends an identify with the no account user" do
|
|
319
|
+
identification = AmplitudeAPI::Identification.new(
|
|
320
|
+
user_id: nil,
|
|
321
|
+
user_properties: {
|
|
322
|
+
first_name: "John",
|
|
323
|
+
last_name: "Doe"
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
expect(described_class).to receive(:identify).with(identification)
|
|
327
|
+
|
|
328
|
+
described_class.send_identify(nil, nil, first_name: "John", last_name: "Doe")
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
context "the user is a user_id" do
|
|
333
|
+
it "sends an identify to AmplitudeAPI" do
|
|
334
|
+
identification = AmplitudeAPI::Identification.new(
|
|
335
|
+
user_id: 123,
|
|
336
|
+
user_properties: {
|
|
337
|
+
first_name: "John",
|
|
338
|
+
last_name: "Doe"
|
|
339
|
+
}
|
|
340
|
+
)
|
|
341
|
+
expect(described_class).to receive(:identify).with(identification)
|
|
342
|
+
|
|
343
|
+
described_class.send_identify(user.id, nil, first_name: "John", last_name: "Doe")
|
|
344
|
+
end
|
|
208
345
|
end
|
|
209
346
|
end
|
|
210
347
|
|
|
211
|
-
context
|
|
212
|
-
it
|
|
348
|
+
context "with a device_id" do
|
|
349
|
+
it "sends an identify to AmplitudeAPI" do
|
|
213
350
|
identification = AmplitudeAPI::Identification.new(
|
|
214
|
-
user_id:
|
|
351
|
+
user_id: user,
|
|
352
|
+
device_id: "abc",
|
|
215
353
|
user_properties: {
|
|
216
|
-
first_name:
|
|
217
|
-
last_name:
|
|
354
|
+
first_name: "John",
|
|
355
|
+
last_name: "Doe"
|
|
218
356
|
}
|
|
219
357
|
)
|
|
220
358
|
expect(described_class).to receive(:identify).with(identification)
|
|
221
359
|
|
|
222
|
-
described_class.send_identify(user
|
|
360
|
+
described_class.send_identify(user, "abc", first_name: "John", last_name: "Doe")
|
|
223
361
|
end
|
|
224
362
|
end
|
|
225
363
|
end
|
|
226
364
|
|
|
227
|
-
describe
|
|
228
|
-
|
|
365
|
+
describe ".segmentation" do
|
|
366
|
+
let(:end_time) { Time.now }
|
|
367
|
+
let(:start_time) { end_time - 60 * 60 * 24 } # -1 day
|
|
368
|
+
|
|
369
|
+
it "sends request to Amplitude" do
|
|
370
|
+
expect(Faraday).to receive(:get).with(AmplitudeAPI::SEGMENTATION_URI_STRING,
|
|
371
|
+
userpwd: "#{described_class.api_key}:#{described_class.secret_key}",
|
|
372
|
+
params: {
|
|
373
|
+
e: { event_type: "my event" }.to_json,
|
|
374
|
+
start: start_time.strftime("%Y%m%d"),
|
|
375
|
+
end: end_time.strftime("%Y%m%d"),
|
|
376
|
+
s: [{ prop: "foo", op: "is", values: %w[bar] }.to_json]
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
described_class.segmentation({ event_type: "my event" }, start_time, end_time,
|
|
380
|
+
s: [{ prop: "foo", op: "is", values: %w[bar] }])
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
describe ".delete" do
|
|
385
|
+
let(:connection) { instance_double("Faraday::Connection", post: nil, basic_auth: nil) }
|
|
386
|
+
|
|
387
|
+
before do
|
|
388
|
+
allow(Faraday).to receive(:new).and_yield(connection).and_return(connection)
|
|
389
|
+
allow(Faraday).to receive(:post)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it "sends the authentification" do
|
|
393
|
+
api_key = described_class.config.api_key
|
|
394
|
+
secret_key = described_class.config.secret_key
|
|
395
|
+
|
|
396
|
+
described_class.delete(user_ids: "123")
|
|
397
|
+
|
|
398
|
+
expect(connection).to have_received(:basic_auth).with(api_key, secret_key)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
it "sends the requester" do
|
|
402
|
+
requester = "privacy@gethopscotch.com"
|
|
403
|
+
body = {
|
|
404
|
+
amplitude_ids: ["123"],
|
|
405
|
+
requester: requester
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
described_class.delete(amplitude_ids: "123", requester: requester)
|
|
409
|
+
|
|
410
|
+
expect(connection).to have_received(:post).with(
|
|
411
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
412
|
+
JSON.generate(body),
|
|
413
|
+
"Content-Type" => "application/json"
|
|
414
|
+
)
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
it "sends the ignore_invalid_id flag" do
|
|
418
|
+
body = {
|
|
419
|
+
user_ids: ["123"],
|
|
420
|
+
ignore_invalid_id: "true"
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
described_class.delete(user_ids: "123", ignore_invalid_id: true)
|
|
424
|
+
|
|
425
|
+
expect(connection).to have_received(:post).with(
|
|
426
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
427
|
+
JSON.generate(body),
|
|
428
|
+
"Content-Type" => "application/json"
|
|
429
|
+
)
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
it "sends the delete_from_org flag" do
|
|
433
|
+
body = {
|
|
434
|
+
user_ids: ["123"],
|
|
435
|
+
delete_from_org: "true"
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
described_class.delete(user_ids: "123", delete_from_org: true)
|
|
439
|
+
|
|
440
|
+
expect(connection).to have_received(:post).with(
|
|
441
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
442
|
+
JSON.generate(body),
|
|
443
|
+
"Content-Type" => "application/json"
|
|
444
|
+
)
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
context "with a single user" do
|
|
448
|
+
it "sends the user_id to Amplitude" do
|
|
449
|
+
body = {
|
|
450
|
+
user_ids: ["123"]
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
described_class.delete(user_ids: "123")
|
|
454
|
+
|
|
455
|
+
expect(connection).to have_received(:post).with(
|
|
456
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
457
|
+
JSON.generate(body),
|
|
458
|
+
"Content-Type" => "application/json"
|
|
459
|
+
)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
it "sends the amplitude_id to Amplitude" do
|
|
463
|
+
body = {
|
|
464
|
+
amplitude_ids: ["123"]
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
described_class.delete(amplitude_ids: "123")
|
|
468
|
+
|
|
469
|
+
expect(connection).to have_received(:post).with(
|
|
470
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
471
|
+
JSON.generate(body),
|
|
472
|
+
"Content-Type" => "application/json"
|
|
473
|
+
)
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it "sends both user_id and amplitude_id to Amplitude" do
|
|
477
|
+
body = {
|
|
478
|
+
amplitude_ids: ["123"],
|
|
479
|
+
user_ids: ["456"]
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
described_class.delete(user_ids: "456", amplitude_ids: "123")
|
|
483
|
+
|
|
484
|
+
expect(connection).to have_received(:post).with(
|
|
485
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
486
|
+
JSON.generate(body),
|
|
487
|
+
"Content-Type" => "application/json"
|
|
488
|
+
)
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
context "with multiple user_ids" do
|
|
493
|
+
it "sends the user_ids to Amplitude" do
|
|
494
|
+
user_ids = [123, 456, 555]
|
|
495
|
+
body = {
|
|
496
|
+
user_ids: user_ids
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
described_class.delete(user_ids: user_ids)
|
|
500
|
+
|
|
501
|
+
expect(connection).to have_received(:post).with(
|
|
502
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
503
|
+
JSON.generate(body),
|
|
504
|
+
"Content-Type" => "application/json"
|
|
505
|
+
)
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
it "sends the amplitude_ids to Amplitude" do
|
|
509
|
+
amplitude_ids = [122, 456]
|
|
510
|
+
body = {
|
|
511
|
+
amplitude_ids: amplitude_ids
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
described_class.delete(amplitude_ids: amplitude_ids)
|
|
515
|
+
|
|
516
|
+
expect(connection).to have_received(:post).with(
|
|
517
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
518
|
+
JSON.generate(body),
|
|
519
|
+
"Content-Type" => "application/json"
|
|
520
|
+
)
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it "sends both user_ids and amplitude_ids to Amplitude" do
|
|
524
|
+
user_ids = [123, 456, 555]
|
|
525
|
+
amplitude_ids = [122, 456]
|
|
526
|
+
body = {
|
|
527
|
+
amplitude_ids: amplitude_ids,
|
|
528
|
+
user_ids: user_ids
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
described_class.delete(user_ids: user_ids, amplitude_ids: amplitude_ids)
|
|
532
|
+
|
|
533
|
+
expect(connection).to have_received(:post).with(
|
|
534
|
+
AmplitudeAPI::DELETION_URI_STRING,
|
|
535
|
+
JSON.generate(body),
|
|
536
|
+
"Content-Type" => "application/json"
|
|
537
|
+
)
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
describe "#body" do
|
|
543
|
+
it "adds an api key" do
|
|
229
544
|
event = AmplitudeAPI::Event.new(
|
|
230
545
|
user_id: user,
|
|
231
|
-
event_type:
|
|
546
|
+
event_type: "test_event",
|
|
232
547
|
event_properties: {
|
|
233
548
|
test_property: 1
|
|
234
549
|
}
|
|
235
550
|
)
|
|
236
|
-
|
|
237
|
-
|
|
551
|
+
json_body = described_class.track_body(event)
|
|
552
|
+
body = JSON.parse(json_body)
|
|
553
|
+
expect(body["api_key"]).to eq("stub api key")
|
|
238
554
|
end
|
|
239
555
|
|
|
240
|
-
it
|
|
556
|
+
it "creates an event" do
|
|
241
557
|
event = AmplitudeAPI::Event.new(
|
|
242
558
|
user_id: 23,
|
|
243
|
-
event_type:
|
|
559
|
+
event_type: "test_event",
|
|
244
560
|
event_properties: {
|
|
245
|
-
foo:
|
|
561
|
+
foo: "bar"
|
|
246
562
|
},
|
|
247
563
|
user_properties: {
|
|
248
|
-
abc:
|
|
564
|
+
abc: "123"
|
|
249
565
|
},
|
|
250
|
-
ip:
|
|
566
|
+
ip: "8.8.8.8"
|
|
251
567
|
)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
expected =
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
)
|
|
269
|
-
expect(body[:event]).to eq(expected)
|
|
568
|
+
json_body = described_class.track_body(event)
|
|
569
|
+
body = JSON.parse(json_body, symbolize_names: true)
|
|
570
|
+
expected = [
|
|
571
|
+
{
|
|
572
|
+
event_type: "test_event",
|
|
573
|
+
user_id: 23,
|
|
574
|
+
event_properties: {
|
|
575
|
+
foo: "bar"
|
|
576
|
+
},
|
|
577
|
+
user_properties: {
|
|
578
|
+
abc: "123"
|
|
579
|
+
},
|
|
580
|
+
ip: "8.8.8.8"
|
|
581
|
+
}
|
|
582
|
+
]
|
|
583
|
+
expect(body[:events]).to eq(expected)
|
|
270
584
|
end
|
|
271
585
|
end
|
|
272
586
|
end
|