sift 4.2.0 → 4.5.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.
@@ -0,0 +1,133 @@
1
+ require_relative "../spec_helper"
2
+ require "sift"
3
+
4
+ describe Sift::Client do
5
+
6
+ before :each do
7
+ Sift.api_key = nil
8
+ end
9
+
10
+ def post_psp_merchant_properties
11
+ {
12
+ "id": "api-key1-6",
13
+ "name": "Wonderful Payments Inc.",
14
+ "description": "Wonderful Payments payment provider.",
15
+ "address": {
16
+ "name": "Alany",
17
+ "address_1": "Big Payment blvd, 22",
18
+ "address_2": "apt, 8",
19
+ "city": "New Orleans",
20
+ "region": "NA",
21
+ "country": "US",
22
+ "zipcode": "76830",
23
+ "phone": "0394888320"
24
+ },
25
+ "category": "1002",
26
+ "service_level": "Platinum",
27
+ "status": "active",
28
+ "risk_profile": {
29
+ "level": "low",
30
+ "score": 10
31
+ }
32
+ }
33
+ end
34
+
35
+ def put_psp_merchant_properties
36
+ {
37
+ "id": "api-key1-7",
38
+ "name": "Wonderful Payments Inc.",
39
+ "description": "Wonderful Payments payment provider.",
40
+ "address": {
41
+ "name": "Alany",
42
+ "address_1": "Big Payment blvd, 22",
43
+ "address_2": "apt, 8",
44
+ "city": "New Orleans",
45
+ "region": "NA",
46
+ "country": "US",
47
+ "zipcode": "76830",
48
+ "phone": "0394888320"
49
+ },
50
+ "category": "1002",
51
+ "service_level": "Platinum",
52
+ "status": "active",
53
+ "risk_profile": {
54
+ "level": "low",
55
+ "score": 10
56
+ }
57
+ }
58
+ end
59
+
60
+ it "Successfully sumit create psp merchant" do
61
+ api_key = "foobar1"
62
+
63
+ response_json = { :status => 0, :error_message => "OK" }
64
+
65
+ stub_request(:post, "https://foobar1:@api.siftscience.com/v3/accounts/ACCT/psp_management/merchants")
66
+ .to_return(:status => 200, :body => MultiJson.dump(response_json))
67
+
68
+ response = Sift::Client.new(:api_key => api_key, :account_id => "ACCT").create_psp_merchant_profile(post_psp_merchant_properties)
69
+ expect(response.ok?).to eq(true)
70
+ expect(response.api_status).to eq(0)
71
+ expect(response.api_error_message).to eq("OK")
72
+ end
73
+
74
+ it "Successfully submit update psp merchant" do
75
+ api_key = "foobar1"
76
+ merchant_id = "api-key1-7"
77
+
78
+ response_json = { :status => 0, :error_message => "OK"}
79
+
80
+ stub_request(:put, "https://foobar1:@api.siftscience.com/v3/accounts/ACCT/psp_management/merchants/api-key1-7")
81
+ .to_return(:status => 200, :body => MultiJson.dump(response_json))
82
+
83
+ response = Sift::Client.new(:api_key => api_key, :account_id => "ACCT").update_psp_merchant_profile(merchant_id, put_psp_merchant_properties)
84
+ expect(response.ok?).to eq(true)
85
+ expect(response.api_status).to eq(0)
86
+ expect(response.api_error_message).to eq("OK")
87
+ end
88
+
89
+ it "Successfully get a psp merchant profile" do
90
+ api_key = "foobar1"
91
+ merchant_id = "api-key1-7"
92
+
93
+ response_json = { :status => 0, :error_message => "OK"}
94
+
95
+ stub_request(:get, "https://foobar1:@api.siftscience.com/v3/accounts/ACCT/psp_management/merchants/api-key1-7")
96
+ .to_return(:status => 200, :body => MultiJson.dump(response_json))
97
+
98
+ response = Sift::Client.new(:api_key => api_key, :account_id => "ACCT").get_a_psp_merchant_profile(merchant_id)
99
+ expect(response.ok?).to eq(true)
100
+ expect(response.api_status).to eq(0)
101
+ expect(response.api_error_message).to eq("OK")
102
+ end
103
+
104
+ it "Successfully get all psp merchant profile with batch size" do
105
+ api_key = "foobar1"
106
+
107
+ response_json = { :status => 0, :error_message => "OK"}
108
+
109
+ stub_request(:get, "https://foobar1:@api.siftscience.com/v3/accounts/ACCT/psp_management/merchants?batch_size=2")
110
+ .to_return(:status => 200, :body => MultiJson.dump(response_json))
111
+
112
+ response = Sift::Client.new(:api_key => api_key, :account_id => "ACCT").get_psp_merchant_profiles(2)
113
+ expect(response.ok?).to eq(true)
114
+ expect(response.api_status).to eq(0)
115
+ expect(response.api_error_message).to eq("OK")
116
+ end
117
+
118
+ it "Successfully get all psp merchant profile with batch size and batch token" do
119
+ api_key = "foobar1"
120
+ batch_size = 2
121
+ batch_token = "batch_token"
122
+ response_json = { :status => 0, :error_message => "OK"}
123
+
124
+ stub_request(:get, "https://foobar1:@api.siftscience.com/v3/accounts/ACCT/psp_management/merchants?batch_size=2&batch_token=batch_token")
125
+ .to_return(:status => 200, :body => MultiJson.dump(response_json))
126
+
127
+ response = Sift::Client.new(:api_key => api_key, :account_id => "ACCT").get_psp_merchant_profiles(batch_size, batch_token)
128
+ expect(response.ok?).to eq(true)
129
+ expect(response.api_status).to eq(0)
130
+ expect(response.api_error_message).to eq("OK")
131
+ end
132
+
133
+ end
@@ -110,6 +110,69 @@ describe Sift::Client do
110
110
  }
111
111
  end
112
112
 
113
+ def warnings
114
+ {
115
+ :count => 1,
116
+ :items => [{
117
+ :message => 'Invalid currency'
118
+ }]
119
+ }
120
+ end
121
+
122
+ def percentile_response_json
123
+ {
124
+ :user_id => 'billy_jones_301',
125
+ :latest_labels => {},
126
+ :workflow_statuses => [],
127
+ :scores => {
128
+ :account_abuse => {
129
+ :score => 0.32787917675535705,
130
+ :reasons => [{
131
+ :name => 'Latest item product title',
132
+ :value => 'The Slanket Blanket-Texas Tea'
133
+ }],
134
+ :percentiles => {
135
+ :last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
136
+ }
137
+ },
138
+ :acontent_abuse => {
139
+ :score => 0.28056292905897995,
140
+ :reasons => [{
141
+ :name => 'timeSinceFirstEvent',
142
+ :value => '13.15 minutes'
143
+ }],
144
+ :percentiles => {
145
+ :last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
146
+ }
147
+ },
148
+ :payment_abuse => {
149
+ :score => 0.28610507028376797,
150
+ :reasons => [{
151
+ :name => 'Latest item currency code',
152
+ :value => 'USD'
153
+ }, {
154
+ :name => 'Latest item item ID',
155
+ :value => 'B004834GQO'
156
+ }, {
157
+ :name => 'Latest item product title',
158
+ :value => 'The Slanket Blanket-Texas Tea'
159
+ }],
160
+ :percentiles => {
161
+ :last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
162
+ }
163
+ },
164
+ :promotion_abuse => {
165
+ :score => 0.05731508921450917,
166
+ :percentiles => {
167
+ :last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
168
+ }
169
+ }
170
+ },
171
+ :status => 0,
172
+ :error_message => 'OK'
173
+ }
174
+ end
175
+
113
176
  def fully_qualified_api_endpoint
114
177
  Sift::Client::API_ENDPOINT + Sift.rest_api_path
115
178
  end
@@ -554,4 +617,106 @@ describe Sift::Client do
554
617
  expect(response.body["decisions"]["content_abuse"]["decision"]["id"]).to eq("decision7")
555
618
  end
556
619
 
620
+ it "Successfully submits a v205 event with SCORE_PERCENTILES" do
621
+ response_json =
622
+ { :status => 0, :error_message => "OK", :score_response => percentile_response_json}
623
+ stub_request(:post, "https://api.siftscience.com/v205/events?fields=SCORE_PERCENTILES&return_score=true").
624
+ with { | request|
625
+ parsed_body = JSON.parse(request.body)
626
+ expect(parsed_body).to include("$api_key" => "overridden")
627
+ }.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})
628
+
629
+ api_key = "foobar"
630
+ event = "$transaction"
631
+ properties = valid_transaction_properties
632
+
633
+ response = Sift::Client.new(:api_key => api_key, :version => "205")
634
+ .track(event, properties, :api_key => "overridden", :include_score_percentiles => "true", :return_score => "true")
635
+ expect(response.ok?).to eq(true)
636
+ expect(response.api_status).to eq(0)
637
+ expect(response.api_error_message).to eq("OK")
638
+ expect(response.body["score_response"]["scores"]["account_abuse"]["percentiles"]["last_7_days"]).to eq(-1.0)
639
+ end
640
+
641
+ it "Successfully submits a v205 event with SCORE_PERCENTILES" do
642
+ response_json =
643
+ { :status => 0, :error_message => "OK", :score_response => percentile_response_json}
644
+ stub_request(:post, "https://api.siftscience.com/v205/events?fields=SCORE_PERCENTILES&return_score=true").
645
+ with { | request|
646
+ parsed_body = JSON.parse(request.body)
647
+ expect(parsed_body).to include("$api_key" => "overridden")
648
+ }.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})
649
+
650
+ api_key = "foobar"
651
+ event = "$transaction"
652
+ properties = valid_transaction_properties
653
+
654
+ response = Sift::Client.new(:api_key => api_key, :version => "205")
655
+ .track(event, properties, :api_key => "overridden", :include_score_percentiles => "true", :return_score => "true")
656
+ expect(response.ok?).to eq(true)
657
+ expect(response.api_status).to eq(0)
658
+ expect(response.api_error_message).to eq("OK")
659
+ expect(response.body["score_response"]["scores"]["account_abuse"]["percentiles"]["last_7_days"]).to eq(-1.0)
660
+ end
661
+
662
+ it "Successfully fetches a v205 score with SCORE_PERCENTILES" do
663
+
664
+ api_key = "foobar"
665
+ response_json = score_response_json
666
+
667
+ stub_request(:get, "https://api.siftscience.com/v205/score/247019/?api_key=foobar&fields=SCORE_PERCENTILES")
668
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
669
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
670
+ "content-length"=> "74"})
671
+
672
+ response = Sift::Client.new(:api_key => api_key)
673
+ .score(score_response_json[:user_id], :version => 205, :include_score_percentiles => "true")
674
+ expect(response.ok?).to eq(true)
675
+ expect(response.api_status).to eq(0)
676
+ expect(response.api_error_message).to eq("OK")
677
+
678
+ expect(response.body["score"]).to eq(0.93)
679
+ end
680
+
681
+ it "Successfully executes client.get_user_score() with SCORE_PERCENTILES" do
682
+
683
+ api_key = "foobar"
684
+ response_json = user_score_response_json
685
+
686
+ stub_request(:get, "https://api.siftscience.com/v205/users/247019/score?api_key=foobar&fields=SCORE_PERCENTILES")
687
+ .to_return(:status => 200, :body => MultiJson.dump(response_json),
688
+ :headers => {"content-type"=>"application/json; charset=UTF-8",
689
+ "content-length"=> "74"})
690
+
691
+ response = Sift::Client.new(:api_key => api_key)
692
+ .get_user_score(user_score_response_json[:entity_id], :include_score_percentiles => "true")
693
+ expect(response.ok?).to eq(true)
694
+ expect(response.api_status).to eq(0)
695
+ expect(response.api_error_message).to eq("OK")
696
+
697
+ expect(response.body["entity_id"]).to eq("247019")
698
+ expect(response.body["scores"]["payment_abuse"]["score"]).to eq(0.78)
699
+ end
700
+
701
+ it "Successfully submits a v205 event with WARNINGS" do
702
+ response_json =
703
+ { :status => 0, :error_message => "OK", :warnings => warnings}
704
+ stub_request(:post, "https://api.siftscience.com/v205/events?fields=WARNINGS").
705
+ with { | request|
706
+ parsed_body = JSON.parse(request.body)
707
+ expect(parsed_body).to include("$api_key" => "overridden")
708
+ }.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})
709
+
710
+ api_key = "foobar"
711
+ event = "$transaction"
712
+ properties = valid_transaction_properties
713
+
714
+ response = Sift::Client.new(:api_key => api_key, :version => "205")
715
+ .track(event, properties, :api_key => "overridden",:warnings => "true")
716
+ expect(response.ok?).to eq(true)
717
+ expect(response.api_status).to eq(0)
718
+ expect(response.api_error_message).to eq("OK")
719
+ expect(response.body["warnings"]["count"]).to eq(1)
720
+ expect(response.body["warnings"]["items"][0]["message"]).to eq("Invalid currency")
721
+ end
557
722
  end
@@ -0,0 +1,31 @@
1
+ require "sift"
2
+
3
+ class DecisionAPI
4
+
5
+ @@client = Sift::Client.new(:api_key => ENV["API_KEY"], :account_id => ENV["ACCOUNT_ID"])
6
+
7
+ def apply_user_decision()
8
+ properties = {
9
+ "decision_id": "integration_app_watch_account_abuse",
10
+ "description": "User linked to three other payment abusers and ordering high value items",
11
+ "source": "manual_review",
12
+ "analyst": "analyst@example.com",
13
+ "user_id": "userId"
14
+ }
15
+
16
+ return @@client.apply_decision(properties)
17
+ end
18
+
19
+ def apply_order_decision()
20
+ properties = {
21
+ "decision_id": "block_order_payment_abuse",
22
+ "description": "applied via the high priority queue, queued user because their risk score exceeded 85",
23
+ "source": "AUTOMATED_RULE",
24
+ "user_id": "userId",
25
+ "order_id": "orderId"
26
+ }
27
+
28
+ return @@client.apply_decision(properties)
29
+ end
30
+
31
+ end