sift 1.1.0 → 4.0.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.
@@ -1,7 +1,12 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
1
+ require_relative "../spec_helper"
2
+ require "sift"
2
3
 
3
4
  describe Sift::Client do
4
5
 
6
+ before :each do
7
+ Sift.api_key = nil
8
+ end
9
+
5
10
  def valid_transaction_properties
6
11
  {
7
12
  :$buyer_user_id => "123456",
@@ -18,103 +23,534 @@ describe Sift::Client do
18
23
  :$billing_region => "CA",
19
24
  :$billing_country => "US",
20
25
  :$billing_zip => "94131",
21
- :$buyer_email => "mike@example.com"
26
+ :$user_email => "mike@example.com"
27
+ }
28
+ end
29
+
30
+ def score_response_json
31
+ {
32
+ :user_id => "247019",
33
+ :score => 0.93,
34
+ :reasons => [{
35
+ :name => "UsersPerDevice",
36
+ :value => 4,
37
+ :details => {
38
+ :users => "a, b, c, d"
39
+ }
40
+ }],
41
+ :status => 0,
42
+ :error_message => "OK"
43
+ }
44
+ end
45
+
46
+ def user_score_response_json
47
+ {
48
+ :entity_type => "user",
49
+ :entity_id => "247019",
50
+ :scores => {
51
+ :payment_abuse => {
52
+ :score => 0.78
53
+ },
54
+ :content_abuse => {
55
+ :score => 0.11
56
+ }
57
+ },
58
+ :latest_decisions => {
59
+ :payment_abuse => {
60
+ :id => "user_looks_bad_payment_abuse",
61
+ :category => "block",
62
+ :source => "AUTOMATED_RULE",
63
+ :time => 1352201880,
64
+ :description => "Bad Fraudster"
65
+ }
66
+ },
67
+ :latest_labels => {
68
+ :payment_abuse => {
69
+ :is_bad => true,
70
+ :time => 1352201880
71
+ }
72
+ },
73
+ :status => 0,
74
+ :error_message => "OK"
75
+ }
76
+ end
77
+
78
+ def action_response_json
79
+ {
80
+ :user_id => "247019",
81
+ :score => 0.93,
82
+ :actions => [{
83
+ :action_id => "1234567890abcdefghijklmn",
84
+ :time => 1437421587052,
85
+ :triggers => [{
86
+ :triggerType => "FORMULA",
87
+ :source => "synchronous_action",
88
+ :trigger_id => "12345678900987654321abcd"
89
+ }],
90
+ :entity => {
91
+ :type => "USER",
92
+ :id => "23056"
93
+ }
94
+ },
95
+ {
96
+ :action_id => "12345678901234567890abcd",
97
+ :time => 1437421587410,
98
+ :triggers => [{
99
+ :triggerType => "FORMULA",
100
+ :source => "synchronous_action",
101
+ :trigger_id => "abcd12345678901234567890"
102
+ }],
103
+ :entity => {
104
+ :type => "ORDER",
105
+ :id => "order_at_ 1437421587009"
106
+ }
107
+ }],
108
+ :status => 0,
109
+ :error_message => "OK"
22
110
  }
23
111
  end
24
112
 
25
113
  def fully_qualified_api_endpoint
26
- Sift::Client::API_ENDPOINT + Sift.current_rest_api_path
114
+ Sift::Client::API_ENDPOINT + Sift.rest_api_path
115
+ end
116
+
117
+
118
+ it "Can instantiate client with blank api key if Sift.api_key set" do
119
+ Sift.api_key = "test_global_api_key"
120
+ expect(Sift::Client.new().api_key).to eq(Sift.api_key)
121
+ end
122
+
123
+
124
+ it "Parameter passed api key takes precedence over Sift.api_key" do
125
+ Sift.api_key = "test_global_api_key"
126
+ api_key = "test_local_api_key"
127
+ expect(Sift::Client.new(:api_key => api_key).api_key).to eq(api_key)
27
128
  end
28
129
 
29
- it "Cannot instantiate client with nil or blank api key" do
30
- lambda { Sift::Client.new(nil) }.should raise_error
31
- lambda { Sift::Client.new("") }.should raise_error
130
+
131
+ it "Cannot instantiate client with nil, empty, non-string, or blank api key" do
132
+ expect(lambda { Sift::Client.new(:api_key => nil) }).to raise_error(StandardError)
133
+ expect(lambda { Sift::Client.new(:api_key => "") }).to raise_error(StandardError)
134
+ expect(lambda { Sift::Client.new(:api_key => 123456) }).to raise_error(StandardError)
135
+ expect(lambda { Sift::Client.new() }).to raise_error(StandardError)
32
136
  end
33
137
 
138
+
139
+ it "Cannot instantiate client with empty, non-string, or blank path" do
140
+ expect(lambda { Sift::Client.new(:path => "") }).to raise_error(StandardError)
141
+ expect(lambda { Sift::Client.new(:path => 123456) }).to raise_error(StandardError)
142
+ end
143
+
144
+
145
+ it "Can instantiate client with non-default timeout" do
146
+ expect(lambda { Sift::Client.new(:api_key => "foo", :timeout => 4) })
147
+ .not_to raise_error
148
+ end
149
+
150
+
34
151
  it "Track call must specify an event name" do
35
- lambda { Sift::Client.new("foo").track(nil) }.should raise_error
36
- lambda { Sift::Client.new("foo").track("") }.should raise_error
152
+ expect(lambda { Sift::Client.new().track(nil) }).to raise_error(StandardError)
153
+ expect(lambda { Sift::Client.new().track("") }).to raise_error(StandardError)
37
154
  end
38
155
 
156
+
39
157
  it "Must specify an event name" do
40
- lambda { Sift::Client.new("foo").track(nil) }.should raise_error
41
- lambda { Sift::Client.new("foo").track("") }.should raise_error
158
+ expect(lambda { Sift::Client.new().track(nil) }).to raise_error(StandardError)
159
+ expect(lambda { Sift::Client.new().track("") }).to raise_error(StandardError)
42
160
  end
43
161
 
162
+
44
163
  it "Must specify properties" do
45
164
  event = "custom_event_name"
46
- lambda { Sift::Client.new("foo").track(event) }.should raise_error
165
+ expect(lambda { Sift::Client.new().track(event) }).to raise_error(StandardError)
47
166
  end
48
167
 
168
+
49
169
  it "Score call must specify a user_id" do
50
- lambda { Sift::Client.new("foo").score(nil) }.should raise_error
51
- lambda { Sift::Client.new("foo").score("") }.should raise_error
170
+ expect(lambda { Sift::Client.new().score(nil) }).to raise_error(StandardError)
171
+ expect(lambda { Sift::Client.new().score("") }).to raise_error(StandardError)
52
172
  end
53
173
 
54
174
 
55
- it "Doesn't raise an exception on Net/HTTP errors" do
175
+ it "Handles parse exceptions for 500 status" do
176
+ api_key = "foobar"
177
+ event = "$transaction"
178
+ properties = valid_transaction_properties
179
+ res = nil
180
+
181
+ stub_request(:any, /.*/).to_return(:body => "{123", :status => 500)
182
+
183
+ expect { res = Sift::Client.new(:api_key => api_key).track(event, properties) }.not_to raise_error
184
+ expect(res.http_status_code).to eq(500)
185
+ end
56
186
 
57
- FakeWeb.register_uri(:post, fully_qualified_api_endpoint,
58
- :body => nil, :exception => Net::HTTPError)
59
187
 
188
+ it "Handles parse exceptions for 200 status" do
60
189
  api_key = "foobar"
61
190
  event = "$transaction"
62
191
  properties = valid_transaction_properties
192
+ res = nil
193
+
194
+ stub_request(:any, /.*/).to_return(:body => "{123", :status => 200)
63
195
 
64
- # This method should just return false -- the track call failed because
65
- # of an HTTP error
66
- Sift::Client.new(api_key).track(event, properties).should eq(nil)
196
+ expect { res = Sift::Client.new(:api_key => api_key).track(event, properties) }.to raise_error(TypeError)
67
197
  end
68
198
 
69
- it "Successfuly handles an event and returns OK" do
70
199
 
200
+ it "Preserves response on HTTP errors but does not raise an exception" do
201
+ api_key = "foobar"
202
+ event = "$transaction"
203
+ properties = valid_transaction_properties
204
+ res = nil
205
+
206
+ stub_request(:any, /.*/).to_return(:status => 401)
207
+
208
+ expect { res = Sift::Client.new(:api_key => api_key).track(event, properties) }.not_to raise_error
209
+ expect(res.http_status_code).to eq(401)
210
+ end
211
+
212
+
213
+ it "Propagates exception when a StandardError occurs within the request" do
214
+ api_key = "foobar"
215
+ event = "$transaction"
216
+ properties = valid_transaction_properties
217
+
218
+ stub_request(:any, /.*/).to_raise(StandardError)
219
+
220
+ expect { Sift::Client.new(:api_key => api_key).track(event, properties) }.to raise_error(StandardError)
221
+ end
222
+
223
+
224
+ it "Successfuly handles an event and returns OK" do
71
225
  response_json = { :status => 0, :error_message => "OK" }
72
226
 
73
- FakeWeb.register_uri(:post, fully_qualified_api_endpoint,
74
- :body => MultiJson.dump(response_json),
75
- :status => [Net::HTTPOK, "OK"],
76
- :content_type => "text/json")
227
+ stub_request(:post, "https://api.siftscience.com/v205/events").
228
+ with { |request|
229
+ parsed_body = JSON.parse(request.body)
230
+ expect(parsed_body).to include("$buyer_user_id" => "123456")
231
+ }.to_return(:status => 200, :body => MultiJson.dump(response_json),
232
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
233
+ "content-length"=> "74"})
77
234
 
78
235
  api_key = "foobar"
79
236
  event = "$transaction"
80
237
  properties = valid_transaction_properties
81
238
 
82
- response = Sift::Client.new(api_key).track(event, properties)
83
- response.ok?.should eq(true)
84
- response.api_status.should eq(0)
85
- response.api_error_message.should eq("OK")
239
+ response = Sift::Client.new(:api_key => api_key).track(event, properties)
240
+ expect(response.ok?).to eq(true)
241
+ expect(response.api_status).to eq(0)
242
+ expect(response.api_error_message).to eq("OK")
86
243
  end
87
244
 
245
+
246
+ it "Successfully submits event with overridden key" do
247
+ response_json = { :status => 0, :error_message => "OK"}
248
+ stub_request(:post, "https://api.siftscience.com/v205/events").
249
+ with { | request|
250
+ parsed_body = JSON.parse(request.body)
251
+ expect(parsed_body).to include("$buyer_user_id" => "123456")
252
+ expect(parsed_body).to include("$api_key" => "overridden")
253
+ }.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})
254
+
255
+ api_key = "foobar"
256
+ event = "$transaction"
257
+ properties = valid_transaction_properties
258
+
259
+ response = Sift::Client.new(:api_key => api_key)
260
+ .track(event, properties, :api_key => "overridden")
261
+ expect(response.ok?).to eq(true)
262
+ expect(response.api_status).to eq(0)
263
+ expect(response.api_error_message).to eq("OK")
264
+ end
265
+
266
+
267
+ it "Successfully scrubs nils" do
268
+ response_json = { :status => 0, :error_message => "OK" }
269
+
270
+ stub_request(:post, "https://api.siftscience.com/v205/events")
271
+ .with { |request|
272
+ parsed_body = JSON.parse(request.body)
273
+ expect(parsed_body).not_to include("fake_property")
274
+ expect(parsed_body).to include("sub_object" => {"one" => "two"})
275
+ }.to_return(:status => 200, :body => MultiJson.dump(response_json),
276
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
277
+ "content-length"=> "74"})
278
+
279
+ api_key = "foobar"
280
+ event = "$transaction"
281
+ properties = valid_transaction_properties.merge(
282
+ "fake_property" => nil,
283
+ "sub_object" => {
284
+ "one" => "two",
285
+ "three" => nil
286
+ }
287
+ )
288
+ response = Sift::Client.new(:api_key => api_key).track(event, properties)
289
+ expect(response.ok?).to eq(true)
290
+ expect(response.api_status).to eq(0)
291
+ expect(response.api_error_message).to eq("OK")
292
+ end
293
+
294
+
88
295
  it "Successfully fetches a score" do
296
+ api_key = "foobar"
297
+ response_json = score_response_json
298
+
299
+ stub_request(:get, "https://api.siftscience.com/v205/score/247019/?api_key=foobar")
300
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
301
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
302
+ "content-length"=> "74"})
303
+
304
+ response = Sift::Client.new(:api_key => api_key).score(score_response_json[:user_id])
305
+ expect(response.ok?).to eq(true)
306
+ expect(response.api_status).to eq(0)
307
+ expect(response.api_error_message).to eq("OK")
308
+
309
+ expect(response.body["score"]).to eq(0.93)
310
+ end
311
+
89
312
 
313
+ it "Successfully fetches a score with an overridden key" do
90
314
  api_key = "foobar"
91
- user_id = "247019"
315
+ response_json = score_response_json
92
316
 
317
+ stub_request(:get, "https://api.siftscience.com/v205/score/247019/?api_key=overridden")
318
+ .to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})
319
+
320
+ response = Sift::Client.new(:api_key => api_key)
321
+ .score(score_response_json[:user_id], :api_key => "overridden")
322
+ expect(response.ok?).to eq(true)
323
+ expect(response.api_status).to eq(0)
324
+ expect(response.api_error_message).to eq("OK")
325
+
326
+ expect(response.body["score"]).to eq(0.93)
327
+ end
328
+
329
+
330
+ it "Successfully executes client.get_user_score()" do
331
+ api_key = "foobar"
332
+ response_json = user_score_response_json
333
+
334
+ stub_request(:get, "https://api.siftscience.com/v205/users/247019/score?api_key=foobar")
335
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
336
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
337
+ "content-length"=> "74"})
338
+
339
+ response = Sift::Client.new(:api_key => api_key).get_user_score(user_score_response_json[:entity_id])
340
+ expect(response.ok?).to eq(true)
341
+ expect(response.api_status).to eq(0)
342
+ expect(response.api_error_message).to eq("OK")
343
+
344
+ expect(response.body["entity_id"]).to eq("247019")
345
+ expect(response.body["scores"]["payment_abuse"]["score"]).to eq(0.78)
346
+ end
347
+
348
+
349
+ it "Successfully executes client.get_user_score() with abuse types specified" do
350
+ api_key = "foobar"
351
+ response_json = user_score_response_json
352
+
353
+ stub_request(:get, "https://api.siftscience.com/v205/users/247019/score" +
354
+ "?api_key=foobar&abuse_types=content_abuse,payment_abuse")
355
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
356
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
357
+ "content-length"=> "74"})
358
+
359
+ response = Sift::Client.new(:api_key => api_key).get_user_score(user_score_response_json[:entity_id],
360
+ :abuse_types => ["content_abuse",
361
+ "payment_abuse"])
362
+ expect(response.ok?).to eq(true)
363
+ expect(response.api_status).to eq(0)
364
+ expect(response.api_error_message).to eq("OK")
365
+
366
+ expect(response.body["entity_id"]).to eq("247019")
367
+ expect(response.body["scores"]["payment_abuse"]["score"]).to eq(0.78)
368
+ end
369
+
370
+
371
+ it "Successfully executes client.rescore_user()" do
372
+ api_key = "foobar"
373
+ response_json = user_score_response_json
374
+
375
+ stub_request(:post, "https://api.siftscience.com/v205/users/247019/score?api_key=foobar")
376
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
377
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
378
+ "content-length"=> "74"})
379
+
380
+ response = Sift::Client.new(:api_key => api_key).rescore_user(user_score_response_json[:entity_id])
381
+ expect(response.ok?).to eq(true)
382
+ expect(response.api_status).to eq(0)
383
+ expect(response.api_error_message).to eq("OK")
384
+
385
+ expect(response.body["entity_id"]).to eq("247019")
386
+ expect(response.body["scores"]["payment_abuse"]["score"]).to eq(0.78)
387
+ end
388
+
389
+
390
+ it "Successfully executes client.rescore_user() with abuse types specified" do
391
+ api_key = "foobar"
392
+ response_json = user_score_response_json
393
+
394
+ stub_request(:post, "https://api.siftscience.com/v205/users/247019/score" +
395
+ "?api_key=foobar&abuse_types=content_abuse,payment_abuse")
396
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
397
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
398
+ "content-length"=> "74"})
399
+
400
+ response = Sift::Client.new(:api_key => api_key).rescore_user(user_score_response_json[:entity_id],
401
+ :abuse_types => ["content_abuse",
402
+ "payment_abuse"])
403
+ expect(response.ok?).to eq(true)
404
+ expect(response.api_status).to eq(0)
405
+ expect(response.api_error_message).to eq("OK")
406
+
407
+ expect(response.body["entity_id"]).to eq("247019")
408
+ expect(response.body["scores"]["payment_abuse"]["score"]).to eq(0.78)
409
+ end
410
+
411
+
412
+ it "Successfully make a sync score request" do
413
+ api_key = "foobar"
93
414
  response_json = {
94
- :user_id => user_id,
95
- :score => 0.93,
96
- :reasons => [{
97
- :name => "UsersPerDevice",
98
- :value => 4,
99
- :details => {
100
- :users => "a, b, c, d"
101
- }
102
- }],
103
415
  :status => 0,
104
- :error_message => "OK"
416
+ :error_message => "OK",
417
+ :score_response => score_response_json
105
418
  }
106
419
 
107
- FakeWeb.register_uri(:get, Sift::Client::API_ENDPOINT + '/v203/score/'+user_id,
108
- :body => MultiJson.dump(response_json),
109
- :status => [Net::HTTPOK, "OK"],
110
- :content_type => "text/json")
420
+ stub_request(:post, "https://api.siftscience.com/v205/events?return_score=true")
421
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
422
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
423
+ "content-length"=> "74"})
424
+
425
+ event = "$transaction"
426
+ properties = valid_transaction_properties
427
+ response = Sift::Client.new(:api_key => api_key)
428
+ .track(event, properties, :return_score => true)
429
+ expect(response.ok?).to eq(true)
430
+ expect(response.api_status).to eq(0)
431
+ expect(response.api_error_message).to eq("OK")
432
+ expect(response.body["score_response"]["score"]).to eq(0.93)
433
+ end
434
+
435
+
436
+ it "Successfully make a sync action request" do
437
+ api_key = "foobar"
438
+ response_json = {
439
+ :status => 0,
440
+ :error_message => "OK",
441
+ :score_response => action_response_json
442
+ }
443
+
444
+ stub_request(:post, "https://api.siftscience.com/v205/events?return_action=true")
445
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
446
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
447
+ "content-length"=> "74"})
448
+
449
+ event = "$transaction"
450
+ properties = valid_transaction_properties
451
+ response = Sift::Client.new(:api_key => api_key)
452
+ .track(event, properties, :return_action => true)
453
+ expect(response.ok?).to eq(true)
454
+ expect(response.api_status).to eq(0)
455
+ expect(response.api_error_message).to eq("OK")
456
+ expect(response.body["score_response"]["actions"].first["entity"]["type"]).to eq("USER")
457
+ end
458
+
459
+
460
+ it "Successfully make a sync workflow request" do
461
+ api_key = "foobar"
462
+ response_json = {
463
+ :status => 0,
464
+ :error_message => "OK",
465
+ :score_response => {
466
+ :status => -1,
467
+ :error_message => "Internal server error."
468
+ }
469
+ }
470
+
471
+ stub_request(:post,
472
+ "https://api.siftscience.com/v205/events?return_workflow_status=true&abuse_types=legacy,payment_abuse")
473
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
474
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
475
+ "content-length"=> "74"})
476
+
477
+ event = "$transaction"
478
+ properties = valid_transaction_properties
479
+ response = Sift::Client.new(:api_key => api_key)
480
+ .track(event, properties,
481
+ :return_workflow_status => true, :abuse_types => ['legacy', 'payment_abuse'])
482
+ expect(response.ok?).to eq(true)
483
+ expect(response.api_status).to eq(0)
484
+ expect(response.api_error_message).to eq("OK")
485
+ end
486
+
487
+
488
+ it "Successfully make a workflow status request" do
489
+ response_text = '{"id":"skdjfnkse","config":{"id":"5rrbr4iaaa","version":"1468367620871"},"config_display_name":"workflow config","abuse_types":["payment_abuse"],"state":"running","entity":{"id":"example_user","type":"user"},"history":[{"app":"user","name":"Entity","state":"finished","config":{}}]}'
490
+
491
+ stub_request(:get, "https://foobar:@api3.siftscience.com/v3/accounts/ACCT/workflows/runs/skdjfnkse")
492
+ .to_return(:status => 200, :body => response_text, :headers => {})
493
+
494
+ client = Sift::Client.new(:api_key => "foobar", :account_id => "ACCT")
495
+ response = client.get_workflow_status("skdjfnkse")
496
+
497
+ expect(response.ok?).to eq(true)
498
+ expect(response.body["id"]).to eq("skdjfnkse")
499
+ expect(response.body["state"]).to eq("running")
500
+ end
501
+
502
+
503
+ it "Successfully make a user decisions request" do
504
+ response_text = '{"decisions":{"content_abuse":{"decision":{"id":"user_decision"},"time":1468707128659,"webhook_succeeded":false}}}'
505
+
506
+ stub_request(:get, "https://foobar:@api3.siftscience.com/v3/accounts/ACCT/users/example_user/decisions")
507
+ .to_return(:status => 200, :body => response_text, :headers => {})
508
+
509
+ client = Sift::Client.new(:api_key => "foobar", :account_id => "ACCT")
510
+ response = client.get_user_decisions("example_user")
511
+
512
+ expect(response.ok?).to eq(true)
513
+ expect(response.body["decisions"]["content_abuse"]["decision"]["id"]).to eq("user_decision")
514
+ end
515
+
516
+
517
+ it "Successfully make an order decisions request" do
518
+ response_text = '{"decisions":{"payment_abuse":{"decision":{"id":"decision7"},"time":1468599638005,"webhook_succeeded":false},"promotion_abuse":{"decision":{"id":"good_order"},"time":1468517407135,"webhook_succeeded":true}}}'
519
+
520
+ stub_request(:get, "https://foobar:@api3.siftscience.com/v3/accounts/ACCT/orders/example_order/decisions")
521
+ .to_return(:status => 200, :body => response_text, :headers => {})
522
+
523
+ client = Sift::Client.new(:api_key => "foobar", :account_id => "ACCT")
524
+ response = client.get_order_decisions("example_order", :timeout => 3)
525
+
526
+ expect(response.ok?).to eq(true)
527
+ expect(response.body["decisions"]["payment_abuse"]["decision"]["id"]).to eq("decision7")
528
+ end
529
+
530
+ it "Successfully make a session decisions request" do
531
+ response_text = '{"decisions":{"account_takeover":{"decision":{"id":"session_decision"},"time":1468707128659,"webhook_succeeded":false}}}'
532
+
533
+ stub_request(:get, "https://foobar:@api3.siftscience.com/v3/accounts/ACCT/users/example_user/sessions/example_session/decisions")
534
+ .to_return(:status => 200, :body => response_text, :headers => {})
535
+
536
+ client = Sift::Client.new(:api_key => "foobar", :account_id => "ACCT")
537
+ response = client.get_session_decisions("example_user", "example_session")
538
+
539
+ expect(response.ok?).to eq(true)
540
+ expect(response.body["decisions"]["account_takeover"]["decision"]["id"]).to eq("session_decision")
541
+ end
542
+
543
+ it "Successfully make an content decisions request" do
544
+ response_text = '{"decisions":{"content_abuse":{"decision":{"id":"decision7"},"time":1468599638005,"webhook_succeeded":false}}}'
545
+
546
+ stub_request(:get, "https://foobar:@api3.siftscience.com/v3/accounts/ACCT/users/USER/content/example_content/decisions")
547
+ .to_return(:status => 200, :body => response_text, :headers => {})
111
548
 
112
- response = Sift::Client.new(api_key).score(user_id)
113
- response.ok?.should eq(true)
114
- response.api_status.should eq(0)
115
- response.api_error_message.should eq("OK")
549
+ client = Sift::Client.new(:api_key => "foobar", :account_id => "ACCT")
550
+ response = client.get_content_decisions("USER", "example_content", :timeout => 3)
116
551
 
117
- response.json["score"].should eq(0.93)
552
+ expect(response.ok?).to eq(true)
553
+ expect(response.body["decisions"]["content_abuse"]["decision"]["id"]).to eq("decision7")
118
554
  end
119
555
 
120
556
  end
@@ -0,0 +1,37 @@
1
+ require_relative "../spec_helper"
2
+
3
+ require "sift/router"
4
+
5
+ module Sift
6
+ describe Router do
7
+ let(:path) { "https://example.com" }
8
+ let(:body) { { question: "Do you wanna go ball?" } }
9
+
10
+ describe ".get" do
11
+ it "with a successful request will return a response object" do
12
+ stub_request(:get, path)
13
+ .with(body: MultiJson.dump(body))
14
+ .to_return(body: MultiJson.dump({ cool: true }))
15
+
16
+ response = Router.get(path, { body: body })
17
+
18
+ expect(response.ok?).to be(true)
19
+ expect(response.body["cool"]).to be(true)
20
+ end
21
+
22
+ it "with an unsuccessful request will return a response object" do
23
+ stub_request(:get, path)
24
+ .with(body: MultiJson.dump(body))
25
+ .to_return(body: MultiJson.dump({ cool: false}), status: 403)
26
+
27
+ response = Router.get(path, { body: body })
28
+
29
+ expect(response.ok?).to be(false)
30
+ expect(response.body["cool"]).to be(false)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+
37
+