sift 1.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+