talon_one 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +3 -0
- data/README.md +71 -0
- data/Rakefile +10 -0
- data/lib/integration/client.rb +87 -0
- data/lib/integration/customer_profile.rb +21 -0
- data/lib/integration/effect.rb +20 -0
- data/lib/integration/event.rb +45 -0
- data/lib/integration/referral_code.rb +49 -0
- data/lib/integration/rule_engine_result.rb +23 -0
- data/lib/integration/search_profiles_result.rb +17 -0
- data/lib/management/client.rb +69 -0
- data/lib/talon_one.rb +7 -0
- data/talon_one.gemspec +16 -0
- data/test/test_helper.rb +20 -0
- data/test/test_integration_api_live.rb +52 -0
- data/test/test_integration_params.rb +23 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9b748e096eec0b2f1b84371700e28198ccc8e94a
|
4
|
+
data.tar.gz: aa2cf8fb236f2d95a6fa7fc532f5e586866e118c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7b7b29b00c77ed44c3709657be152324e03afbf620257a861585fab2b5ad0b025d7aae0146465f3401b8e33233e064380317f3090d5d81059c12bae832e4a6da
|
7
|
+
data.tar.gz: 907506fc01ee8489861ea820ff62c9449c9abae8122172f1cf5fbc1e8805f41f1061d5efd6d13fbf2cdc9b76d3f0173ba8e5ed05b83cf4e9aad54bf673d058da
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# 0.0.4 / 2016-08-25
|
2
|
+
|
3
|
+
* [FEATURE] Use BigDecimal for all decimal numbers coming in/out of the
|
4
|
+
Integration API.
|
5
|
+
|
6
|
+
# 0.0.3 / 2016-08-25
|
7
|
+
|
8
|
+
* [CHORE] Renamed "Shop" to "Application"
|
9
|
+
|
10
|
+
# 0.0.2 / 2016-08-04
|
11
|
+
|
12
|
+
* [BUG] Constructor param for integration client is `:shop_key` not `:secret`.
|
13
|
+
* [BUG] Strip trailing slashes from Talon.One endpoints.
|
14
|
+
|
15
|
+
# 0.0.1 / 2016-08-04
|
16
|
+
|
17
|
+
* [FEATURE] First sort-of useful release.
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Talon.One Ruby SDK [![Build Status](https://travis-ci.org/talon-one/talon_one.rb.svg?branch=master)](https://travis-ci.org/talon-one/talon_one.rb)
|
2
|
+
|
3
|
+
Talon.One enables marketers to create coupon, discount, loyalty, and referral
|
4
|
+
marketing campaigns of virtually unlimited power and flexibility. This library
|
5
|
+
provides 2 Ruby API clients:
|
6
|
+
|
7
|
+
- `TalonOne::Integration::Client` is used to feed customer activities (e.g.
|
8
|
+
purchasing items or referring friends) into the Talon.One platform so that
|
9
|
+
your marketing campaigns can react to these events. Authentication for the
|
10
|
+
Integration API is done with an Application ID and secret key.
|
11
|
+
|
12
|
+
- `TalonOne::Management::Client` is used to create and manipulate campaigns,
|
13
|
+
coupons, and user accounts on the Talon.One platform. Unlike the integration
|
14
|
+
client, the management client must authenticate with credentials for a
|
15
|
+
registered Talon.One user in your organization.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
There is no gem release yet, for now we recommend pulling directly from GitHub
|
20
|
+
in your Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'talon_one', :git => 'https://github.com/talon-one/talon-one.rb'
|
24
|
+
```
|
25
|
+
|
26
|
+
## Getting started with the Integration API
|
27
|
+
|
28
|
+
First, you will need to find your API endpoint, Application ID and Application Key in the Camapaign Manager by going to the "Settings" tab.
|
29
|
+
|
30
|
+
With these 3 things we can set up the integration API client:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
client = TalonOne::Integration::Client.new :endpoint => 'https://mycompany.talon.one',
|
34
|
+
:application_id => 213,
|
35
|
+
:application_key => '5ea4583bfb81d2e9'
|
36
|
+
```
|
37
|
+
|
38
|
+
Defaults for these configuration parameters can also be set via the environment
|
39
|
+
variables `TALONONE_ENDPOINT`, `TALONONE_APP_ID`, and `TALONONE_APP_KEY`.
|
40
|
+
|
41
|
+
Once the `client` has been created, you can start sending customer profiles,
|
42
|
+
sessions, and events to Talon.One:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# When the customer registers or updates their account
|
46
|
+
client.update_customer_profile "my_unique_profile_id",
|
47
|
+
"name" => "Val Kust",
|
48
|
+
"billingAddress1" => "21 Jump St."
|
49
|
+
|
50
|
+
# When the customer adds an item to their cart
|
51
|
+
client.update_customer_session "my_unique_session_id",
|
52
|
+
"profileId" => "my_unique_profile_id",
|
53
|
+
"cartItems" => [{
|
54
|
+
"name" => "Shiny Red Shoes",
|
55
|
+
"sku" => "srs_1234",
|
56
|
+
"price" => 49.99,
|
57
|
+
"quantity" => 1,
|
58
|
+
"currency" => "USD"
|
59
|
+
}],
|
60
|
+
"attributes" => {
|
61
|
+
"ShippingCost" => 3.75
|
62
|
+
},
|
63
|
+
"total" => 53.74 # total is _not_ required to match up to item cost + shipping"
|
64
|
+
|
65
|
+
# When the customer does something else interesting
|
66
|
+
client.track_event "my_unique_session_id", "viewed_promo_page", "url" => "http://example.com/summer-shoes-2016"
|
67
|
+
```
|
68
|
+
|
69
|
+
To view the full list of data that each of these API calls accepts, please consult our [API documentation][].
|
70
|
+
|
71
|
+
[API documentation]: http://developers.talon.one/integration-api/reference/
|
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'oj'
|
3
|
+
|
4
|
+
require_relative './search_profiles_result'
|
5
|
+
require_relative './rule_engine_result'
|
6
|
+
require_relative './referral_code'
|
7
|
+
|
8
|
+
module TalonOne
|
9
|
+
module Integration
|
10
|
+
# Basic REST client for the TalonOne integration API
|
11
|
+
class Client
|
12
|
+
def initialize(config = {})
|
13
|
+
@endpoint = URI(
|
14
|
+
config[:endpoint] || ENV["TALONONE_ENDPOINT"] || "https://example.talon.one"
|
15
|
+
)
|
16
|
+
@endpoint.path = @endpoint.path.sub(/\/+$/, '')
|
17
|
+
@http = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
18
|
+
@http.use_ssl = @endpoint.scheme == "https"
|
19
|
+
|
20
|
+
@application_id = config[:application_id] || ENV["TALONONE_APP_ID"]
|
21
|
+
@application_key = [config[:application_key] || ENV["TALONONE_APP_KEY"]].pack('H*')
|
22
|
+
end
|
23
|
+
|
24
|
+
def request(method, path, payload = nil, result = TalonOne::Integration::RuleEngineResult)
|
25
|
+
req = Net::HTTP.const_get(method).new(@endpoint.path + path)
|
26
|
+
req.body = Oj.dump payload, oj_options(:compat)
|
27
|
+
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), @application_key, req.body)
|
28
|
+
|
29
|
+
req['Content-Type'] = 'application/json'
|
30
|
+
req['Content-Signature'] = "signer=#{@application_id}; signature=#{signature}"
|
31
|
+
|
32
|
+
res = @http.request(req)
|
33
|
+
|
34
|
+
if res.code[0] == '2'
|
35
|
+
result.new(Oj.load(res.body, oj_options(:strict)))
|
36
|
+
else
|
37
|
+
raise "#{method.upcase} #{path} -> #{res.code} #{res.body}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def track_event(session_id, event_type, value)
|
42
|
+
request "Post", "/v1/events", { sessionId: session_id, type: event_type, attributes: value }
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_customer_session(session_id, data)
|
46
|
+
request "Put", "/v1/customer_sessions/#{session_id}", data
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_customer_profile(profile_id, data)
|
50
|
+
request "Put", "/v1/customer_profiles/#{profile_id}", data
|
51
|
+
end
|
52
|
+
|
53
|
+
def close_customer_session(session_id)
|
54
|
+
update_customer_session session_id, { state: "closed" }
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_referral_code(campaign_id, advocate_profile_id, friend_id: "", start: nil, expire: nil)
|
58
|
+
newReferral = {
|
59
|
+
campaignId: campaign_id,
|
60
|
+
advocateProfileIntegrationId: advocate_profile_id,
|
61
|
+
friendProfileIntegrationId: friend_id,
|
62
|
+
}
|
63
|
+
if start
|
64
|
+
newReferral[:startDate] = start
|
65
|
+
end
|
66
|
+
if expire
|
67
|
+
newReferral[:expiryDate] = expire
|
68
|
+
end
|
69
|
+
request "Post", "/v1/referrals", newReferral, TalonOne::Integration::ReferralCode
|
70
|
+
end
|
71
|
+
|
72
|
+
def search_profiles_by_attributes(profileAttr)
|
73
|
+
request "Post", "/v1/customer_profiles_search", { attributes: profileAttr }, TalonOne::Integration::SearchProfilesResult
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def oj_options(mode)
|
79
|
+
{ :mode => mode,
|
80
|
+
:class_cache => false,
|
81
|
+
:escape_mode => :json,
|
82
|
+
:bigdecimal_as_decimal => true,
|
83
|
+
:bigdecimal_load => :bigdecimal }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module TalonOne
|
2
|
+
module Integration
|
3
|
+
class CustomerProfile
|
4
|
+
def initialize(raw_data)
|
5
|
+
@raw = raw_data
|
6
|
+
end
|
7
|
+
|
8
|
+
def id
|
9
|
+
@raw["id"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def created
|
13
|
+
@raw["created"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def integration_id
|
17
|
+
@raw["integrationId"]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TalonOne
|
2
|
+
module Integration
|
3
|
+
class Effect
|
4
|
+
def initialize(raw_array)
|
5
|
+
@campaign_id = raw_array[0]
|
6
|
+
@ruleset_id = raw_array[1]
|
7
|
+
@ruleset_index = raw_array[2]
|
8
|
+
@raw = raw_array[3]
|
9
|
+
end
|
10
|
+
|
11
|
+
def function
|
12
|
+
@raw[0]
|
13
|
+
end
|
14
|
+
|
15
|
+
def args
|
16
|
+
@raw[1..-1]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative './effect'
|
2
|
+
|
3
|
+
module TalonOne
|
4
|
+
module Integration
|
5
|
+
class Event
|
6
|
+
def initialize(raw_data)
|
7
|
+
@raw = raw_data
|
8
|
+
end
|
9
|
+
|
10
|
+
def type
|
11
|
+
@raw["type"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def session_id
|
15
|
+
@raw["sessionId"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def attributes
|
19
|
+
@raw["attributes"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def effects
|
23
|
+
@effects ||= @raw["effects"].map do |raw_array|
|
24
|
+
TalonOne::Integration::Effect.new raw_array
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def accepted_coupon?
|
29
|
+
effects.any? {|e| e.function == "acceptCoupon"}
|
30
|
+
end
|
31
|
+
|
32
|
+
def rejected_coupon?
|
33
|
+
!accepted_coupon? && effects.any? {|e| e.function == "rejectCoupon"}
|
34
|
+
end
|
35
|
+
|
36
|
+
def accepted_referral?
|
37
|
+
effects.any? {|e| e.function == "acceptReferral"}
|
38
|
+
end
|
39
|
+
|
40
|
+
def rejected_referral?
|
41
|
+
!accepted_referral? && effects.any? {|e| e.function == "rejectReferral"}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module TalonOne
|
2
|
+
module Integration
|
3
|
+
class ReferralCode
|
4
|
+
def initialize(raw_data)
|
5
|
+
@raw = raw_data
|
6
|
+
end
|
7
|
+
|
8
|
+
def id
|
9
|
+
@raw["id"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def campaign_id
|
13
|
+
@raw["campaignId"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def created
|
17
|
+
@raw["created"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def advocate_id
|
21
|
+
@raw["advocateProfileIntegrationId"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def code
|
25
|
+
@raw["code"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def friend_id
|
29
|
+
@raw["friendProfileIntegrationId"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_date
|
33
|
+
@raw["startDate"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def expiry_date
|
37
|
+
@raw["expiryDate"]
|
38
|
+
end
|
39
|
+
|
40
|
+
def usage_count
|
41
|
+
@raw["usageCount"]
|
42
|
+
end
|
43
|
+
|
44
|
+
def usage_limit
|
45
|
+
@raw["usageLimit"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative './event'
|
2
|
+
|
3
|
+
module TalonOne
|
4
|
+
module Integration
|
5
|
+
class RuleEngineResult
|
6
|
+
def initialize(raw_data)
|
7
|
+
@raw = raw_data
|
8
|
+
end
|
9
|
+
|
10
|
+
def session
|
11
|
+
@raw["session"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def profile
|
15
|
+
@raw["profile"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def event
|
19
|
+
@event ||= TalonOne::Integration::Event.new(@raw["event"])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative './customer_profile'
|
2
|
+
|
3
|
+
module TalonOne
|
4
|
+
module Integration
|
5
|
+
class SearchProfilesResult
|
6
|
+
def initialize(raw_data)
|
7
|
+
@raw = raw_data
|
8
|
+
end
|
9
|
+
|
10
|
+
def profiles
|
11
|
+
@profiles ||= @raw["data"].map do |raw_array|
|
12
|
+
TalonOne::Integration::CustomerProfile.new raw_array
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module TalonOne
|
2
|
+
module Management
|
3
|
+
# Basic REST client for the TalonOne management API
|
4
|
+
class Client
|
5
|
+
def initialize(config = {})
|
6
|
+
@endpoint = URI(
|
7
|
+
config[:endpoint] || ENV["TALONONE_ENDPOINT"] || "https://app.talon.one"
|
8
|
+
)
|
9
|
+
@endpoint.path = @endpoint.path.sub(/\/+$/, '')
|
10
|
+
@http = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
11
|
+
@http.use_ssl = true
|
12
|
+
@token = ENV["TALONONE_SESSION_TOKEN"]
|
13
|
+
if !@token
|
14
|
+
email = config[:email] || ENV["TALONONE_EMAIL"]
|
15
|
+
password = config[:password] || ENV["TALONONE_PASSWORD"]
|
16
|
+
if email && password
|
17
|
+
login(email, password)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def login(email, password)
|
23
|
+
res = request "Post", "/v1/sessions", {"email" => email, "password" => password}
|
24
|
+
@token = res["token"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def request(method, path, payload = nil)
|
28
|
+
req = Net::HTTP.const_get(method).new(@endpoint.path + path)
|
29
|
+
if @token
|
30
|
+
req["Authorization"] = "Bearer #{@token}"
|
31
|
+
end
|
32
|
+
if payload
|
33
|
+
req.body = payload.to_json
|
34
|
+
req['Content-Type'] = 'application/json'
|
35
|
+
end
|
36
|
+
res = @http.request(req)
|
37
|
+
if res.code[0] == '2'
|
38
|
+
res.body && JSON.parse(res.body)
|
39
|
+
else
|
40
|
+
raise "#{method.upcase} #{path} -> #{res.code} #{res.body}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get(path)
|
45
|
+
request "Get", path
|
46
|
+
end
|
47
|
+
|
48
|
+
def put(path, payload)
|
49
|
+
request "Put", path, payload
|
50
|
+
end
|
51
|
+
|
52
|
+
def post(path, payload)
|
53
|
+
request "Post", path, payload
|
54
|
+
end
|
55
|
+
|
56
|
+
def delete(path)
|
57
|
+
request "Delete", path
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_application(params)
|
61
|
+
post "/v1/applications", params
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete_application(application)
|
65
|
+
delete "/v1/applications/#{application["id"]}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/talon_one.rb
ADDED
data/talon_one.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'talon_one'
|
3
|
+
s.version = '0.0.5'
|
4
|
+
s.date = '2017-03-06'
|
5
|
+
s.summary = 'Client for the Talon.One API'
|
6
|
+
s.description = 'A simple client for using the Talon.One API'
|
7
|
+
s.authors = ['Stephen Sugden']
|
8
|
+
s.email = 'stephen@talon.one'
|
9
|
+
s.files = `git ls-files`.split("\n")
|
10
|
+
s.require_paths = ['lib']
|
11
|
+
s.homepage = 'https://github.com/talon-one/talon-one.rb'
|
12
|
+
s.license = 'MIT'
|
13
|
+
s.add_runtime_dependency 'oj', '~> 2.17'
|
14
|
+
s.add_development_dependency 'rake', '~> 12.0.0'
|
15
|
+
s.add_development_dependency 'minitest', '~> 5.10.1'
|
16
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'talon_one'
|
3
|
+
|
4
|
+
class LiveApiTest < Minitest::Test
|
5
|
+
def integration_config
|
6
|
+
{}
|
7
|
+
end
|
8
|
+
|
9
|
+
def integration_client
|
10
|
+
@integration_client ||= TalonOne::Integration::Client.new integration_config
|
11
|
+
end
|
12
|
+
|
13
|
+
def management_config
|
14
|
+
{}
|
15
|
+
end
|
16
|
+
|
17
|
+
def management_client
|
18
|
+
@management_client ||= TalonOne::Management::Client.new management_config
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class TestIntegrationApiLive < LiveApiTest
|
2
|
+
def setup
|
3
|
+
@app = management_client.create_application(
|
4
|
+
name: "Ruby SDK Test App",
|
5
|
+
key: "fefecafedeadbeef",
|
6
|
+
currency: "USD",
|
7
|
+
timezone: "UTC"
|
8
|
+
)
|
9
|
+
@campaign = management_client.post "/v1/applications/#{@app["id"]}/campaigns", { name: "Test Campaign", state: 'disabled', tags: [], limits: [] }
|
10
|
+
@ruleset = management_client.post "/v1/applications/#{@app["id"]}/campaigns/#{@campaign["id"]}/rulesets", rules: [{
|
11
|
+
title: "Free money for all!",
|
12
|
+
condition: ["and", true],
|
13
|
+
effects: [
|
14
|
+
["setDiscount", "Free money", 45.55]
|
15
|
+
]
|
16
|
+
}]
|
17
|
+
@campaign["activeRulesetId"] = @ruleset["id"]
|
18
|
+
@campaign["state"] = "enabled"
|
19
|
+
management_client.put "/v1/applications/#{@app["id"]}/campaigns/#{@campaign["id"]}", @campaign
|
20
|
+
end
|
21
|
+
|
22
|
+
def teardown
|
23
|
+
management_client.delete_application @app
|
24
|
+
end
|
25
|
+
|
26
|
+
def integration_config
|
27
|
+
{ application_id: @app["id"], application_key: @app["key"] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_track_event
|
31
|
+
res = integration_client.track_event "a-session", "Viewed Page", { URL: "http://example.com" }
|
32
|
+
assert res.profile
|
33
|
+
assert res.session
|
34
|
+
assert_instance_of TalonOne::Integration::Event, res.event
|
35
|
+
assert !res.event.rejected_coupon?, "No coupon -> no rejectCoupon effect"
|
36
|
+
assert !res.event.accepted_coupon?, "No coupon -> no acceptCoupon effect"
|
37
|
+
assert_equal 1, res.event.effects.length
|
38
|
+
assert_equal "setDiscount", res.event.effects[0].function
|
39
|
+
assert_equal "Viewed Page", res.event.type
|
40
|
+
assert_equal "a-session", res.event.session_id, "a-session"
|
41
|
+
assert_equal({ "URL" => "http://example.com" }, res.event.attributes)
|
42
|
+
assert_instance_of BigDecimal, res.session["discounts"]["Free money"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_update_customer_session
|
46
|
+
res = integration_client.update_customer_session "new-session", {
|
47
|
+
coupon: "invalid coupon code",
|
48
|
+
total: BigDecimal.new("45.55"),
|
49
|
+
}
|
50
|
+
assert res.event.rejected_coupon?, "invalid coupon code was rejected"
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class TestIntegrationParams < Minitest::Test
|
2
|
+
def setup
|
3
|
+
@old_env_vars = ENV.keys.grep(/^TALONONE/).reduce({}) {|h, k| h.update(k => ENV.delete(k))}
|
4
|
+
end
|
5
|
+
|
6
|
+
def teardown
|
7
|
+
ENV.update(@old_env_vars)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_initialize_parameter_normalization
|
11
|
+
client = TalonOne::Integration::Client.new(
|
12
|
+
endpoint: "https://this.will.have.no.trailing.slashes////",
|
13
|
+
application_id: "1234",
|
14
|
+
application_key: "blah"
|
15
|
+
)
|
16
|
+
|
17
|
+
normalized_endpoint = client.instance_eval do
|
18
|
+
@endpoint.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
assert_equal normalized_endpoint, "https://this.will.have.no.trailing.slashes"
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: talon_one
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Sugden
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oj
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.17'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 12.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 12.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.10.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.10.1
|
55
|
+
description: A simple client for using the Talon.One API
|
56
|
+
email: stephen@talon.one
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ".gitignore"
|
62
|
+
- ".travis.yml"
|
63
|
+
- CHANGELOG.md
|
64
|
+
- Gemfile
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- lib/integration/client.rb
|
68
|
+
- lib/integration/customer_profile.rb
|
69
|
+
- lib/integration/effect.rb
|
70
|
+
- lib/integration/event.rb
|
71
|
+
- lib/integration/referral_code.rb
|
72
|
+
- lib/integration/rule_engine_result.rb
|
73
|
+
- lib/integration/search_profiles_result.rb
|
74
|
+
- lib/management/client.rb
|
75
|
+
- lib/talon_one.rb
|
76
|
+
- talon_one.gemspec
|
77
|
+
- test/test_helper.rb
|
78
|
+
- test/test_integration_api_live.rb
|
79
|
+
- test/test_integration_params.rb
|
80
|
+
homepage: https://github.com/talon-one/talon-one.rb
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.5.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Client for the Talon.One API
|
104
|
+
test_files: []
|