Skip to content

Commit

Permalink
Enable score_percentiles in the scores api (#85)
Browse files Browse the repository at this point in the history
Score percentiles in Score API
  • Loading branch information
haneeshv authored Oct 5, 2023
1 parent e08b32c commit 0942fec
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/sift/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ def user_agent
#
# :path::
# Overrides the URI path for this API call.
#
# :include_score_percentiles::
# include_score_percentiles(optional) : Whether to add new parameter in the query parameter.
#
# ==== Returns:
#
Expand Down Expand Up @@ -275,6 +278,9 @@ def track(event, properties = {}, opts = {})
#
# :version::
# Overrides the version of the Events API to call.
#
# :include_score_percentiles::
# include_score_percentiles(optional) : Whether to add new parameter in the query parameter.
#
# ==== Returns:
#
Expand All @@ -286,13 +292,17 @@ def score(user_id, opts = {})
api_key = opts[:api_key] || @api_key
timeout = opts[:timeout] || @timeout
version = opts[:version] || @version
include_score_percentiles = opts[:include_score_percentiles]

raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
raise("Bad api_key parameter") if api_key.empty?

query = {}
query["api_key"] = api_key
query["abuse_types"] = abuse_types.join(",") if abuse_types
if include_score_percentiles == "true"
query["fields"] = "SCORE_PERCENTILES"
end

options = {
:headers => {"User-Agent" => user_agent},
Expand Down Expand Up @@ -332,6 +342,9 @@ def score(user_id, opts = {})
#
# :timeout::
# Overrides the timeout (in seconds) for this call.
#
# :include_score_percentiles::
# include_score_percentiles(optional) : Whether to add new parameter in the query parameter.
#
# ==== Returns:
#
Expand All @@ -342,13 +355,17 @@ def get_user_score(user_id, opts = {})
abuse_types = opts[:abuse_types]
api_key = opts[:api_key] || @api_key
timeout = opts[:timeout] || @timeout
include_score_percentiles = opts[:include_score_percentiles]

raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?
raise("Bad api_key parameter") if api_key.empty?

query = {}
query["api_key"] = api_key
query["abuse_types"] = abuse_types.join(",") if abuse_types
if include_score_percentiles == "true"
query["fields"] = "SCORE_PERCENTILES"
end

options = {
:headers => {"User-Agent" => user_agent},
Expand Down
135 changes: 135 additions & 0 deletions spec/unit/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,60 @@ def action_response_json
}
end

def percentile_response_json
{
:user_id => 'billy_jones_301',
:latest_labels => {},
:workflow_statuses => [],
:scores => {
:account_abuse => {
:score => 0.32787917675535705,
:reasons => [{
:name => 'Latest item product title',
:value => 'The Slanket Blanket-Texas Tea'
}],
:percentiles => {
:last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
}
},
:acontent_abuse => {
:score => 0.28056292905897995,
:reasons => [{
:name => 'timeSinceFirstEvent',
:value => '13.15 minutes'
}],
:percentiles => {
:last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
}
},
:payment_abuse => {
:score => 0.28610507028376797,
:reasons => [{
:name => 'Latest item currency code',
:value => 'USD'
}, {
:name => 'Latest item item ID',
:value => 'B004834GQO'
}, {
:name => 'Latest item product title',
:value => 'The Slanket Blanket-Texas Tea'
}],
:percentiles => {
:last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
}
},
:promotion_abuse => {
:score => 0.05731508921450917,
:percentiles => {
:last_7_days => -1.0, :last_1_days => -1.0, :last_10_days => -1.0, :last_5_days => -1.0
}
}
},
:status => 0,
:error_message => 'OK'
}
end

def fully_qualified_api_endpoint
Sift::Client::API_ENDPOINT + Sift.rest_api_path
end
Expand Down Expand Up @@ -554,4 +608,85 @@ def fully_qualified_api_endpoint
expect(response.body["decisions"]["content_abuse"]["decision"]["id"]).to eq("decision7")
end

it "Successfully submits a v205 event with SCORE_PERCENTILES" do
response_json =
{ :status => 0, :error_message => "OK", :score_response => percentile_response_json}
stub_request(:post, "https://api.siftscience.com/v205/events?fields=SCORE_PERCENTILES&return_score=true").
with { | request|
parsed_body = JSON.parse(request.body)
expect(parsed_body).to include("$api_key" => "overridden")
}.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})

api_key = "foobar"
event = "$transaction"
properties = valid_transaction_properties

response = Sift::Client.new(:api_key => api_key, :version => "205")
.track(event, properties, :api_key => "overridden", :include_score_percentiles => "true", :return_score => "true")
expect(response.ok?).to eq(true)
expect(response.api_status).to eq(0)
expect(response.api_error_message).to eq("OK")
expect(response.body["score_response"]["scores"]["account_abuse"]["percentiles"]["last_7_days"]).to eq(-1.0)
end

it "Successfully submits a v205 event with SCORE_PERCENTILES" do
response_json =
{ :status => 0, :error_message => "OK", :score_response => percentile_response_json}
stub_request(:post, "https://api.siftscience.com/v205/events?fields=SCORE_PERCENTILES&return_score=true").
with { | request|
parsed_body = JSON.parse(request.body)
expect(parsed_body).to include("$api_key" => "overridden")
}.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})

api_key = "foobar"
event = "$transaction"
properties = valid_transaction_properties

response = Sift::Client.new(:api_key => api_key, :version => "205")
.track(event, properties, :api_key => "overridden", :include_score_percentiles => "true", :return_score => "true")
expect(response.ok?).to eq(true)
expect(response.api_status).to eq(0)
expect(response.api_error_message).to eq("OK")
expect(response.body["score_response"]["scores"]["account_abuse"]["percentiles"]["last_7_days"]).to eq(-1.0)
end

it "Successfully fetches a v205 score with SCORE_PERCENTILES" do

api_key = "foobar"
response_json = score_response_json

stub_request(:get, "https://api.siftscience.com/v205/score/247019/?api_key=foobar&fields=SCORE_PERCENTILES")
.to_return(:status => 200, :body => MultiJson.dump(response_json),
:headers => {"content-type"=>"application/json; charset=UTF-8",
"content-length"=> "74"})

response = Sift::Client.new(:api_key => api_key)
.score(score_response_json[:user_id], :version => 205, :include_score_percentiles => "true")
expect(response.ok?).to eq(true)
expect(response.api_status).to eq(0)
expect(response.api_error_message).to eq("OK")

expect(response.body["score"]).to eq(0.93)
end

it "Successfully executes client.get_user_score() with SCORE_PERCENTILES" do

api_key = "foobar"
response_json = user_score_response_json

stub_request(:get, "https://api.siftscience.com/v205/users/247019/score?api_key=foobar&fields=SCORE_PERCENTILES")
.to_return(:status => 200, :body => MultiJson.dump(response_json),
:headers => {"content-type"=>"application/json; charset=UTF-8",
"content-length"=> "74"})

response = Sift::Client.new(:api_key => api_key)
.get_user_score(user_score_response_json[:entity_id], :include_score_percentiles => "true")
expect(response.ok?).to eq(true)
expect(response.api_status).to eq(0)
expect(response.api_error_message).to eq("OK")

expect(response.body["entity_id"]).to eq("247019")
expect(response.body["scores"]["payment_abuse"]["score"]).to eq(0.78)
end

end

0 comments on commit 0942fec

Please sign in to comment.