Skip to content

Commit

Permalink
Merge pull request #31 from conekta/master
Browse files Browse the repository at this point in the history
Integrate return_action logic to sift client
  • Loading branch information
yschatzb committed Aug 18, 2015
2 parents 7669ff5 + 2523827 commit 77e994f
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 24 deletions.
25 changes: 19 additions & 6 deletions lib/sift/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,34 @@ def user_agent
# Overrides the default API path with a different URL.
#
# return_score (optional)
# Whether the API response should include a score for this user (the score will
# Whether the API response should include a score for this user. The score will
# be calculated using the submitted event. This feature must be
# enabled for your account in order to use it. Please contact
# [email protected] if you are interested in using this feature.
#
# return_action (optional)
# Whether the API response should include an action triggered for this transaction.
#
# == Returns:
# In the case of an HTTP error (timeout, broken connection, etc.), this
# method returns nil; otherwise, a Response object is returned and captures
# the status message and status code. In general, you can ignore the returned
# result, though.
#
def track(event, properties = {}, timeout = nil, path = nil, return_score = false, api_key = @api_key)
def track(event, properties = {}, timeout = nil, path = nil, return_score = false, api_key = @api_key, return_action = false)
warn "[WARNING] api_key cannot be empty, fallback to default api_key." if api_key.to_s.empty?
api_key ||= @api_key
raise("event must be a non-empty string") if (!event.is_a? String) || event.empty?
raise("properties cannot be empty") if properties.empty?
raise("Bad api_key parameter") if api_key.empty?
path ||= @path
timeout ||= @timeout
if return_score
path = path + "?return_score=true"
end

uri = URI.parse(API_ENDPOINT)
uri.query = URI.encode_www_form(URI.decode_www_form(uri.query.to_s) << ["return_score", "true"]) if return_score
uri.query = URI.encode_www_form(URI.decode_www_form(uri.query.to_s) << ["return_action", "true"]) if return_action
path = path + "?" + uri.query if !uri.query.to_s.empty?

options = {
:body => MultiJson.dump(delete_nils(properties).merge({"$type" => event,
"$api_key" => api_key})),
Expand Down Expand Up @@ -207,7 +215,9 @@ def label(user_id, properties = {}, timeout = nil, api_key = @api_key)
raise("user_id must be a non-empty string") if (!user_id.is_a? String) || user_id.to_s.empty?

path = Sift.current_users_label_api_path(user_id)
track("$label", delete_nils(properties), timeout, path, false, api_key)

# No return_action logic supported when using labels.
track("$label", delete_nils(properties), timeout, path, false, api_key, false)
end

# Unlabels a user. This call is blocking.
Expand Down Expand Up @@ -237,6 +247,9 @@ def unlabel(user_id, timeout = nil)
end

private
# def add_query_parameter(query_parameter)
# uri = URI.parse(API_ENDPOINT)
# end
def delete_nils(properties)
properties.delete_if do |k, v|
case v
Expand Down
2 changes: 1 addition & 1 deletion lib/sift/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Sift
VERSION = "1.1.7.2"
VERSION = "1.1.7.3"
API_VERSION = "203"
end
90 changes: 73 additions & 17 deletions spec/unit/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,41 @@ def score_response_json
}
end

def action_response_json
{
:user_id => "247019",
:score => 0.93,
:actions => [{
:action_id => "1234567890abcdefghijklmn",
:time => 1437421587052,
:triggers => [{
:triggerType => "FORMULA",
:source => "synchronous_action",
:trigger_id => "12345678900987654321abcd"
}],
:entity => {
:type => "USER",
:id => "23056"
}
},
{
:action_id => "12345678901234567890abcd",
:time => 1437421587410,
:triggers => [{
:triggerType => "FORMULA",
:source => "synchronous_action",
:trigger_id => "abcd12345678901234567890"
}],
:entity => {
:type => "ORDER",
:id => "order_at_ 1437421587009"
}
}],
:status => 0,
:error_message => "OK"
}
end

def fully_qualified_api_endpoint
Sift::Client::API_ENDPOINT + Sift.current_rest_api_path
end
Expand All @@ -58,41 +93,41 @@ def fully_qualified_api_endpoint
end

it "Cannot instantiate client with nil, empty, non-string, or blank api key" do
expect(lambda { Sift::Client.new(nil) }).to raise_error
expect(lambda { Sift::Client.new("") }).to raise_error
expect(lambda { Sift::Client.new(123456) }).to raise_error
expect(lambda { Sift::Client.new() }).to raise_error
expect(lambda { Sift::Client.new(nil) }).to raise_error(StandardError)
expect(lambda { Sift::Client.new("") }).to raise_error(StandardError)
expect(lambda { Sift::Client.new(123456) }).to raise_error(StandardError)
expect(lambda { Sift::Client.new() }).to raise_error(StandardError)
end

it "Cannot instantiate client with nil, empty, non-string, or blank path" do
api_key = "test_local_api_key"
expect(lambda { Sift::Client.new(api_key, nil) }).to raise_error
expect(lambda { Sift::Client.new(api_key, "") }).to raise_error
expect(lambda { Sift::Client.new(api_key, 123456) }).to raise_error
expect(lambda { Sift::Client.new(api_key, nil) }).to raise_error(StandardError)
expect(lambda { Sift::Client.new(api_key, "") }).to raise_error(StandardError)
expect(lambda { Sift::Client.new(api_key, 123456) }).to raise_error(StandardError)
end

it "Can instantiate client with non-default timeout" do
expect(lambda { Sift::Client.new("test_local_api_key", Sift.current_rest_api_path, 4) }).not_to raise_error
end

it "Track call must specify an event name" do
expect(lambda { Sift::Client.new("foo").track(nil) }).to raise_error
expect(lambda { Sift::Client.new("foo").track("") }).to raise_error
expect(lambda { Sift::Client.new("foo").track(nil) }).to raise_error(StandardError)
expect(lambda { Sift::Client.new("foo").track("") }).to raise_error(StandardError)
end

it "Must specify an event name" do
expect(lambda { Sift::Client.new("foo").track(nil) }).to raise_error
expect(lambda { Sift::Client.new("foo").track("") }).to raise_error
expect(lambda { Sift::Client.new("foo").track(nil) }).to raise_error(StandardError)
expect(lambda { Sift::Client.new("foo").track("") }).to raise_error(StandardError)
end

it "Must specify properties" do
event = "custom_event_name"
expect(lambda { Sift::Client.new("foo").track(event) }).to raise_error
expect(lambda { Sift::Client.new("foo").track(event) }).to raise_error(StandardError)
end

it "Score call must specify a user_id" do
expect(lambda { Sift::Client.new("foo").score(nil) }).to raise_error
expect(lambda { Sift::Client.new("foo").score("") }).to raise_error
expect(lambda { Sift::Client.new("foo").score(nil) }).to raise_error(StandardError)
expect(lambda { Sift::Client.new("foo").score("") }).to raise_error(StandardError)
end

it "Doesn't raise an exception on Net/HTTP errors" do
Expand Down Expand Up @@ -141,7 +176,7 @@ def fully_qualified_api_endpoint
expect(response.api_error_message).to eq("OK")
end

it "Successfully submits event with overriden key" do
it "Successfully submits event with overridden key" do
response_json = { :status => 0, :error_message => "OK"}
stub_request(:post, "https://api.siftscience.com/v203/events").
with { | request|
Expand All @@ -154,7 +189,7 @@ def fully_qualified_api_endpoint
event = "$transaction"
properties = valid_transaction_properties

response = Sift::Client.new(api_key).track(event, properties, nil, nil, false, "overridden")
response = Sift::Client.new(api_key).track(event, properties, nil, nil, false, "overridden", false)
expect(response.ok?).to eq(true)
expect(response.api_status).to eq(0)
expect(response.api_error_message).to eq("OK")
Expand Down Expand Up @@ -233,13 +268,34 @@ def fully_qualified_api_endpoint

event = "$transaction"
properties = valid_transaction_properties
response = Sift::Client.new(api_key).track(event, properties, nil, nil, true)
response = Sift::Client.new(api_key).track(event, properties, nil, nil, true, nil, nil)
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"]["score"]).to eq(0.93)
end

it "Successfuly make a sync action request" do

api_key = "foobar"
response_json = {
:status => 0,
:error_message => "OK",
:score_response => action_response_json
}

stub_request(:post, "https://api.siftscience.com/v203/events?return_action=true").
to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {"content-type"=>"application/json; charset=UTF-8","content-length"=> "74"})

event = "$transaction"
properties = valid_transaction_properties
response = Sift::Client.new(api_key).track(event, properties, nil, nil, nil, nil, 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"]["actions"].first["entity"]["type"]).to eq("USER")
end



end

0 comments on commit 77e994f

Please sign in to comment.