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