attune 0.0.1 → 0.0.2
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.
- checksums.yaml +5 -13
- data/README.md +29 -6
- data/attune.gemspec +2 -1
- data/lib/attune.rb +13 -0
- data/lib/attune/call_dropping.rb +52 -0
- data/lib/attune/client.rb +41 -14
- data/lib/attune/configurable.rb +14 -0
- data/lib/attune/default.rb +5 -0
- data/lib/attune/version.rb +1 -1
- data/spec/attune/call_dropping_spec.rb +84 -0
- data/spec/attune/client_spec.rb +57 -0
- data/spec/attune_spec.rb +14 -0
- data/spec/spec_helper.rb +6 -0
- metadata +33 -16
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YmRkYWIzMTRhOGNlOTVlYzBhZDFjY2FkMGFkNDY2MGVlNWIzMGY2ZA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a768188791c5cf1b4dbb0d9bb7639c79be622f49
|
4
|
+
data.tar.gz: 0b55667d588255b97df0fc7fbc7d7571f2a3a420
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZTQ3N2Q3ZGU3MzE0OWUzZWNiNmM2ZjUyMTQxMjU4NGJhMTA2MGUzYTI4ODk2
|
11
|
-
ODhhYmQ1MWQ0ZjM0MDA3ZDU4OWEyNDJjMDExYjY4ODk2MWE1MDk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NWI4YmYxMDMxNWZkMWQxYTZjZTIyODQ1MjdiYjkxMWIwZjYzM2E1MDM3MDk1
|
14
|
-
M2Y5ZTU5YWQ4ODcwNTk4ZDQ0NWE0ZjA1NzMzOTI1MTQyMGQ0NzQ5MDE3MzFi
|
15
|
-
YjJmYzVlNTQxNmQ5ZjUyMWQyNzZkZjU5NDMxNjQxZTIzMjA5YTc=
|
6
|
+
metadata.gz: a90ccfd4d4aa1893c315e161545a3bd04cdddcdaabdc98f7e4daf809a7a8acbefd3e15d03344fd933ae83e290b7ff3f4bdd2c15b0180565d4b00597c4c7d9e74
|
7
|
+
data.tar.gz: 1686b9cfa601e45f89590446c8c69a65f9c6f80b775f4031056fc6f9438c790514f836d7f00622ce31b0562d92e62c643aa19da5a53491c92d08cb2289be1ec8
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Attune
|
2
2
|
|
3
|
-
A client for the [Attune ranking API](http://attune.co/).
|
3
|
+
A client for the [Attune ranking API](http://attune.co/). Built using the excellent [faraday](https://github.com/lostisland/faraday) library.
|
4
|
+
|
5
|
+
* [Github](https://github.com/DigitalStripe/attune-ruby)
|
6
|
+
* [RubyGems](https://rubygems.org/gems/attune)
|
7
|
+
* [Documentation](http://rdoc.info/github/DigitalStripe/attune-ruby)
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -55,22 +59,24 @@ The client can then perform rankings
|
|
55
59
|
``` ruby
|
56
60
|
class ProductsController
|
57
61
|
def index
|
58
|
-
@products = Product.all
|
62
|
+
@products = sorted(Product.all)
|
63
|
+
end
|
59
64
|
|
65
|
+
private
|
66
|
+
def sorted products
|
60
67
|
ranking = attune_client.get_ranking(
|
61
68
|
id: session[:attune_id],
|
62
69
|
view: request.fullpath,
|
63
70
|
collection: 'products',
|
64
|
-
entities:
|
71
|
+
entities: products.map(&:id)
|
65
72
|
)
|
66
|
-
|
73
|
+
products.sort_by do |product|
|
67
74
|
ranking.index(product.id.to_s)
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
71
78
|
```
|
72
79
|
|
73
|
-
|
74
80
|
### Configuration
|
75
81
|
|
76
82
|
Attune can be configured globally
|
@@ -88,9 +94,26 @@ Settings can also be overridden on a client object
|
|
88
94
|
client = Attune::Client.new(timeout: 2)
|
89
95
|
```
|
90
96
|
|
97
|
+
See the documentation for
|
98
|
+
[Attune::Configurable](http://rdoc.info/github/DigitalStripe/attune-ruby/master/Attune/Configurable)
|
99
|
+
and the
|
100
|
+
[default configuration](http://rdoc.info/github/DigitalStripe/attune-ruby/master/Attune/Default)
|
101
|
+
for more details.
|
102
|
+
|
103
|
+
### Testing
|
104
|
+
|
105
|
+
For testing and development, the ranking API can be simulated using.
|
106
|
+
|
107
|
+
``` ruby
|
108
|
+
Attune.test_mode!
|
109
|
+
```
|
110
|
+
|
111
|
+
In this mode no API calls will be made, and rankings will be returned in their original order.
|
112
|
+
Calling `.test_mode!` is equivalent to setting `disabled` to true and `exception_handler` to `:mock`.
|
113
|
+
|
91
114
|
## Contributing
|
92
115
|
|
93
|
-
1. Fork it ( http://github.com/
|
116
|
+
1. Fork it ( http://github.com/DigitalStripe/attune/fork )
|
94
117
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
95
118
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
96
119
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/attune.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["john@freerunningtechnologies.com"]
|
11
11
|
spec.summary = %q{Client for the Attune product ranking API.}
|
12
12
|
spec.description = %q{Client for the Attune product ranking API.}
|
13
|
-
spec.homepage = "https://github.com/
|
13
|
+
spec.homepage = "https://github.com/DigitalStripe/attune-ruby"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -25,4 +25,5 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "rspec"
|
26
26
|
spec.add_development_dependency "yard"
|
27
27
|
spec.add_development_dependency "redcarpet"
|
28
|
+
spec.add_development_dependency "simplecov"
|
28
29
|
end
|
data/lib/attune.rb
CHANGED
@@ -9,4 +9,17 @@ module Attune
|
|
9
9
|
def self.client
|
10
10
|
Client.new
|
11
11
|
end
|
12
|
+
|
13
|
+
# Simulate all API calls
|
14
|
+
# This is equivalent to setting disabled to true and exception_handler to
|
15
|
+
# :mock
|
16
|
+
def self.test_mode!
|
17
|
+
configure do |c|
|
18
|
+
c.exception_handler = :mock
|
19
|
+
c.disabled = true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
def self.configure(&block)
|
23
|
+
Default.configure(&block)
|
24
|
+
end
|
12
25
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Attune
|
2
|
+
class CallDropping < Faraday::Middleware
|
3
|
+
def initialize app, storage=default_storage
|
4
|
+
@app = app
|
5
|
+
@storage = storage
|
6
|
+
end
|
7
|
+
|
8
|
+
def call env
|
9
|
+
raise_timeout if should_skip?
|
10
|
+
begin
|
11
|
+
result = @app.call(env)
|
12
|
+
increment_skips(-SKIP_STEP)
|
13
|
+
result
|
14
|
+
rescue Faraday::Error::TimeoutError => e
|
15
|
+
increment_skips(SKIP_STEP)
|
16
|
+
raise e
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
# requests to skip before retry
|
22
|
+
SKIP_STEP = 0.25
|
23
|
+
|
24
|
+
# The most requests to skip before retrying
|
25
|
+
SKIP_MAX = 10.0
|
26
|
+
|
27
|
+
def raise_timeout
|
28
|
+
raise Faraday::Error::TimeoutError, "dropped request"
|
29
|
+
end
|
30
|
+
|
31
|
+
def should_skip?
|
32
|
+
rand > (1.0 / (1.0 + skip_rate))
|
33
|
+
end
|
34
|
+
|
35
|
+
def increment_skips amount
|
36
|
+
self.skip_rate = skip_rate + amount
|
37
|
+
|
38
|
+
if skip_rate <= 0.0
|
39
|
+
self.skip_rate = 0.0
|
40
|
+
elsif skip_rate >= SKIP_MAX
|
41
|
+
self.skip_rate = SKIP_MAX
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def skip_rate; @storage[:skip_rate] || 0.0; end
|
46
|
+
def skip_rate= v; @storage[:skip_rate]= v; end
|
47
|
+
|
48
|
+
def default_storage
|
49
|
+
Thread.current
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/attune/client.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
3
|
module Attune
|
4
|
+
class DisabledException < Faraday::Error::ClientError
|
5
|
+
def initialize(message="Attune library disabled though config")
|
6
|
+
super(message)
|
7
|
+
end
|
8
|
+
end
|
4
9
|
|
5
|
-
# Client for the attune
|
6
10
|
class Client
|
7
11
|
include Attune::Configurable
|
8
12
|
|
@@ -38,14 +42,19 @@ module Attune
|
|
38
42
|
# @option options [String] :user_agent The user agent for the application used by the anonymous users
|
39
43
|
# @return id [String]
|
40
44
|
# @raise [ArgumentError] if user_agent is not provided
|
45
|
+
# @raise [Faraday::Error] if the request fails or exceeds the timeout
|
41
46
|
def create_anonymous(options)
|
42
47
|
raise ArgumentError, "user_agent required" unless options[:user_agent]
|
43
48
|
if id = options[:id]
|
44
|
-
|
49
|
+
put("anonymous/#{id}", {user_agent: options[:user_agent]})
|
45
50
|
id
|
46
51
|
else
|
47
|
-
response = post("anonymous", {user_agent: options[:user_agent]})
|
48
|
-
|
52
|
+
if response = post("anonymous", {user_agent: options[:user_agent]})
|
53
|
+
response[:location][/\Aurn:id:([a-z0-9\-]+)\Z/, 1]
|
54
|
+
else
|
55
|
+
# Return a new UUID if there was an exception and we're in mock mode
|
56
|
+
SecureRandom.uuid
|
57
|
+
end
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
@@ -67,10 +76,15 @@ module Attune
|
|
67
76
|
# @option options [String] :customer id of customer (optional)
|
68
77
|
# @return ranking [Array<String>] The entities in their ranked order
|
69
78
|
# @raise [ArgumentError] if required parameters are missing
|
79
|
+
# @raise [Faraday::Error] if the request fails or exceeds the timeout
|
70
80
|
def get_rankings(options)
|
71
81
|
qs = encoded_ranking_params(options)
|
72
|
-
response = get("rankings/#{qs}", customer: options.fetch(:customer, 'none'))
|
73
|
-
|
82
|
+
if response = get("rankings/#{qs}", customer: options.fetch(:customer, 'none'))
|
83
|
+
JSON.parse(response.body)['ranking']
|
84
|
+
else
|
85
|
+
# In mock mode: return the entities in the order passed in
|
86
|
+
options[:entities]
|
87
|
+
end
|
74
88
|
end
|
75
89
|
|
76
90
|
# Get multiple rankings in one call
|
@@ -92,14 +106,21 @@ module Attune
|
|
92
106
|
# ])
|
93
107
|
# @param [Array<Hash>] multi_options An array of options (see #get_rankings)
|
94
108
|
# @return [Array<Array<String>>] rankings
|
109
|
+
# @raise [Faraday::Error] if the request fails or exceeds the timeout
|
95
110
|
def multi_get_rankings(multi_options)
|
96
111
|
requests = multi_options.map do |options|
|
97
112
|
encoded_ranking_params(options)
|
98
113
|
end
|
99
|
-
response = get("rankings", ids: requests)
|
100
|
-
|
101
|
-
|
102
|
-
|
114
|
+
if response = get("rankings", ids: requests)
|
115
|
+
results = JSON.parse(response.body)['results']
|
116
|
+
results.values.map do |result|
|
117
|
+
result['ranking']
|
118
|
+
end
|
119
|
+
else
|
120
|
+
# In mock mode: return the entities in the order passed in
|
121
|
+
multi_options.map do |options|
|
122
|
+
options[:entities]
|
123
|
+
end
|
103
124
|
end
|
104
125
|
end
|
105
126
|
|
@@ -112,6 +133,7 @@ module Attune
|
|
112
133
|
# '25892e17-80f6-415f-9c65-7395632f022',
|
113
134
|
# 'cd171f7c-560d-4a62-8d65-16b87419a58'
|
114
135
|
# )
|
136
|
+
# @raise [Faraday::Error] if the request fails or exceeds the timeout
|
115
137
|
def bind(id, customer_id)
|
116
138
|
put("bindings/anonymous=#{id}&customer=#{customer_id}")
|
117
139
|
true
|
@@ -131,27 +153,32 @@ module Attune
|
|
131
153
|
|
132
154
|
def get(path, params={})
|
133
155
|
adapter.get(path, params)
|
134
|
-
rescue Faraday::ClientError => e
|
156
|
+
rescue Faraday::Error::ClientError => e
|
135
157
|
handle_exception(e)
|
136
158
|
end
|
137
159
|
|
138
160
|
def put(path, params={})
|
139
161
|
adapter.put(path, ::JSON.dump(params))
|
140
|
-
rescue Faraday::ClientError => e
|
162
|
+
rescue Faraday::Error::ClientError => e
|
141
163
|
handle_exception(e)
|
142
164
|
end
|
143
165
|
|
144
166
|
def post(path, params={})
|
145
167
|
adapter.post(path, ::JSON.dump(params))
|
146
|
-
rescue Faraday::ClientError => e
|
168
|
+
rescue Faraday::Error::ClientError => e
|
147
169
|
handle_exception(e)
|
148
170
|
end
|
149
171
|
|
150
172
|
def handle_exception e
|
151
|
-
|
173
|
+
if exception_handler == :mock
|
174
|
+
nil
|
175
|
+
else
|
176
|
+
raise e
|
177
|
+
end
|
152
178
|
end
|
153
179
|
|
154
180
|
def adapter
|
181
|
+
raise DisabledException if disabled?
|
155
182
|
Faraday.new(url: endpoint, builder: middleware, request: {timeout: timeout})
|
156
183
|
end
|
157
184
|
end
|
data/lib/attune/configurable.rb
CHANGED
@@ -4,6 +4,7 @@ module Attune
|
|
4
4
|
:endpoint,
|
5
5
|
:middleware,
|
6
6
|
:disabled,
|
7
|
+
:exception_handler,
|
7
8
|
:timeout
|
8
9
|
]
|
9
10
|
|
@@ -15,10 +16,23 @@ module Attune
|
|
15
16
|
|
16
17
|
# FIXME
|
17
18
|
attr_accessor :disabled
|
19
|
+
alias_method :disabled?, :disabled
|
18
20
|
|
19
21
|
# Time (in seconds) to wait for requests to finish
|
20
22
|
attr_accessor :timeout
|
21
23
|
|
24
|
+
# How to deal with HTTP exceptions
|
25
|
+
# @param [:mock, :raise] handler Method used for handling exceptions.
|
26
|
+
# @raise [ArgumentError] if handler is not :mock or :raise
|
27
|
+
attr_reader :exception_handler
|
28
|
+
def exception_handler= handler
|
29
|
+
if [:mock, :raise].include?(handler)
|
30
|
+
@exception_handler = handler
|
31
|
+
else
|
32
|
+
raise ArgumentError, "exception_handler must be :mock or :raise"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
22
36
|
# @example configure
|
23
37
|
# Attune.configure do |c|
|
24
38
|
# c.endpoint = "http://example.com:8080/"
|
data/lib/attune/default.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'attune/param_flattener'
|
2
|
+
require "attune/call_dropping"
|
2
3
|
require "attune/json_logger"
|
3
4
|
|
4
5
|
module Attune
|
@@ -12,6 +13,9 @@ module Attune
|
|
12
13
|
# Needed for encoding of BATCH GET requests
|
13
14
|
builder.use Attune::ParamFlattener
|
14
15
|
|
16
|
+
# Log all requests
|
17
|
+
builder.use Attune::CallDropping
|
18
|
+
|
15
19
|
# Allow one retry per request
|
16
20
|
builder.request :retry, 1
|
17
21
|
|
@@ -27,6 +31,7 @@ module Attune
|
|
27
31
|
c.endpoint = ENDPOINT
|
28
32
|
c.middleware = MIDDLEWARE
|
29
33
|
c.disabled = false
|
34
|
+
c.exception_handler = :raise
|
30
35
|
c.timeout = 1
|
31
36
|
end
|
32
37
|
end
|
data/lib/attune/version.rb
CHANGED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Attune::CallDropping do
|
4
|
+
let(:stubs){ Faraday::Adapter::Test::Stubs.new }
|
5
|
+
let(:connection) do
|
6
|
+
Faraday.new(url: 'http://example.com/') do |builder|
|
7
|
+
builder.use described_class, storage
|
8
|
+
builder.adapter :test, stubs
|
9
|
+
end
|
10
|
+
end
|
11
|
+
let(:response){ connection.get("/") }
|
12
|
+
let(:timeout){ Faraday::Error::TimeoutError.new("simulated timeout") }
|
13
|
+
|
14
|
+
context "using default storage" do
|
15
|
+
let(:connection) do
|
16
|
+
Faraday.new(url: 'http://example.com/') do |builder|
|
17
|
+
builder.use described_class
|
18
|
+
builder.adapter :test, stubs
|
19
|
+
end
|
20
|
+
end
|
21
|
+
it "can be initialized" do
|
22
|
+
stubs.get("/"){ [200, {}, "foobar"] }
|
23
|
+
expect(response.body).to eq "foobar"
|
24
|
+
stubs.verify_stubbed_calls
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "without previous timeouts" do
|
29
|
+
let(:storage){ {} }
|
30
|
+
context "no timeout" do
|
31
|
+
it "runs request" do
|
32
|
+
stubs.get("/"){ [200, {}, "foobar"] }
|
33
|
+
expect(response.body).to eq "foobar"
|
34
|
+
expect(storage).to eq(skip_rate: 0.0)
|
35
|
+
stubs.verify_stubbed_calls
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with a timeout" do
|
40
|
+
it "raises the timeout" do
|
41
|
+
stubs.get("/"){ raise timeout }
|
42
|
+
expect {
|
43
|
+
response
|
44
|
+
}.to raise_exception(Faraday::Error::TimeoutError)
|
45
|
+
expect(storage).to eq(skip_rate: 0.25)
|
46
|
+
stubs.verify_stubbed_calls
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with an existing skip rate" do
|
52
|
+
let(:storage){ {skip_rate: 1.0} }
|
53
|
+
before{ described_class.any_instance.stub(rand: random) }
|
54
|
+
context "request skipped" do
|
55
|
+
let(:random){ 1 }
|
56
|
+
it "raises timeout" do
|
57
|
+
expect {
|
58
|
+
response
|
59
|
+
}.to raise_exception(Faraday::Error::TimeoutError)
|
60
|
+
expect(storage).to eq(skip_rate: 1.00)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "request attempted" do
|
65
|
+
context "at max drop rate" do
|
66
|
+
let(:storage){ {skip_rate: 10.0} }
|
67
|
+
it "leaves drop rate unchanged" do
|
68
|
+
stubs.get("/"){ raise timeout }
|
69
|
+
expect { response }.to raise_exception(Faraday::Error::TimeoutError)
|
70
|
+
expect(storage).to eq(skip_rate: 10.0)
|
71
|
+
stubs.verify_stubbed_calls
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:random){ 0 }
|
76
|
+
it "succeeds an reduces skip rate" do
|
77
|
+
stubs.get("/"){ [200, {}, "foobar"] }
|
78
|
+
expect(response.body).to eq "foobar"
|
79
|
+
expect(storage).to eq(skip_rate: 0.75)
|
80
|
+
stubs.verify_stubbed_calls
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/spec/attune/client_spec.rb
CHANGED
@@ -24,6 +24,63 @@ describe Attune::Client do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
describe "API errors" do
|
28
|
+
it "will raise timeout" do
|
29
|
+
stubs.post("anonymous", %[{"user_agent":"Mozilla/5.0"}]){ raise Faraday::Error::TimeoutError.new("test") }
|
30
|
+
expect {
|
31
|
+
client.create_anonymous(user_agent: 'Mozilla/5.0')
|
32
|
+
}.to raise_exception(Faraday::Error::TimeoutError)
|
33
|
+
stubs.verify_stubbed_calls
|
34
|
+
end
|
35
|
+
it "will raise ConnectionFailed" do
|
36
|
+
stubs.post("anonymous", %[{"user_agent":"Mozilla/5.0"}]){ raise Faraday::Error::ConnectionFailed.new("test") }
|
37
|
+
expect {
|
38
|
+
client.create_anonymous(user_agent: 'Mozilla/5.0')
|
39
|
+
}.to raise_exception(Faraday::Error::ConnectionFailed)
|
40
|
+
stubs.verify_stubbed_calls
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "disabled" do
|
45
|
+
context "with raise" do
|
46
|
+
let(:options){ {disabled: true, exception_handler: :raise} }
|
47
|
+
it "will raise DisalbedException" do
|
48
|
+
expect {
|
49
|
+
client.create_anonymous(user_agent: 'Mozilla/5.0')
|
50
|
+
}.to raise_exception(Attune::DisabledException)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
context "with mock" do
|
54
|
+
let(:options){ {disabled: true, exception_handler: :mock} }
|
55
|
+
it "mocks create_anonymous with an id" do
|
56
|
+
result = client.create_anonymous(id: '12345', user_agent: 'Mozilla/5.0')
|
57
|
+
expect(result).to eq('12345')
|
58
|
+
end
|
59
|
+
it "mocks create_anonymous with no id" do
|
60
|
+
result = client.create_anonymous(user_agent: 'Mozilla/5.0')
|
61
|
+
expect(result).to match(/^[a-z0-9\-]+$/)
|
62
|
+
end
|
63
|
+
it "mocks get_rankings" do
|
64
|
+
result = client.get_rankings(
|
65
|
+
id: 'abcd123',
|
66
|
+
view: 'b/mens-pants',
|
67
|
+
collection: 'products',
|
68
|
+
entities: %w[1001, 1002, 1003, 1004]
|
69
|
+
)
|
70
|
+
expect(result).to eq %w[1001, 1002, 1003, 1004]
|
71
|
+
end
|
72
|
+
it "mocks multi_get_rankings" do
|
73
|
+
result = client.multi_get_rankings([
|
74
|
+
id: 'abcd123',
|
75
|
+
view: 'b/mens-pants',
|
76
|
+
collection: 'products',
|
77
|
+
entities: %w[1001, 1002, 1003, 1004]
|
78
|
+
])
|
79
|
+
expect(result).to eq [%w[1001, 1002, 1003, 1004]]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
27
84
|
it "can create_anonymous generating an id" do
|
28
85
|
stubs.post("anonymous", %[{"user_agent":"Mozilla/5.0"}]){ [200, {location: 'urn:id:abcd123'}, nil] }
|
29
86
|
id = client.create_anonymous(user_agent: 'Mozilla/5.0')
|
data/spec/attune_spec.rb
CHANGED
@@ -9,4 +9,18 @@ describe Attune do
|
|
9
9
|
specify { expect(subject.endpoint).to eq 'http://localhost/' }
|
10
10
|
specify { expect(subject.disabled).to eq false }
|
11
11
|
end
|
12
|
+
describe 'configure' do
|
13
|
+
it "yields with Attune::Default" do
|
14
|
+
Attune.configure do |c|
|
15
|
+
expect(c).to be Attune::Default
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
describe 'test_mode' do
|
20
|
+
it "sets correct test options" do
|
21
|
+
expect(Attune::Default).to receive(:exception_handler=).with(:mock)
|
22
|
+
expect(Attune::Default).to receive(:disabled=).with(true)
|
23
|
+
Attune.test_mode!
|
24
|
+
end
|
25
|
+
end
|
12
26
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attune
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hawthorn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -42,56 +42,70 @@ dependencies:
|
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: redcarpet
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
description: Client for the Attune product ranking API.
|
@@ -111,18 +125,20 @@ files:
|
|
111
125
|
- Rakefile
|
112
126
|
- attune.gemspec
|
113
127
|
- lib/attune.rb
|
128
|
+
- lib/attune/call_dropping.rb
|
114
129
|
- lib/attune/client.rb
|
115
130
|
- lib/attune/configurable.rb
|
116
131
|
- lib/attune/default.rb
|
117
132
|
- lib/attune/json_logger.rb
|
118
133
|
- lib/attune/param_flattener.rb
|
119
134
|
- lib/attune/version.rb
|
135
|
+
- spec/attune/call_dropping_spec.rb
|
120
136
|
- spec/attune/client_spec.rb
|
121
137
|
- spec/attune/json_logger_spec.rb
|
122
138
|
- spec/attune_spec.rb
|
123
139
|
- spec/remote_spec.rb
|
124
140
|
- spec/spec_helper.rb
|
125
|
-
homepage: https://github.com/
|
141
|
+
homepage: https://github.com/DigitalStripe/attune-ruby
|
126
142
|
licenses:
|
127
143
|
- MIT
|
128
144
|
metadata: {}
|
@@ -132,21 +148,22 @@ require_paths:
|
|
132
148
|
- lib
|
133
149
|
required_ruby_version: !ruby/object:Gem::Requirement
|
134
150
|
requirements:
|
135
|
-
- -
|
151
|
+
- - '>='
|
136
152
|
- !ruby/object:Gem::Version
|
137
153
|
version: '0'
|
138
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
155
|
requirements:
|
140
|
-
- -
|
156
|
+
- - '>='
|
141
157
|
- !ruby/object:Gem::Version
|
142
158
|
version: '0'
|
143
159
|
requirements: []
|
144
160
|
rubyforge_project:
|
145
|
-
rubygems_version: 2.1.
|
161
|
+
rubygems_version: 2.1.11
|
146
162
|
signing_key:
|
147
163
|
specification_version: 4
|
148
164
|
summary: Client for the Attune product ranking API.
|
149
165
|
test_files:
|
166
|
+
- spec/attune/call_dropping_spec.rb
|
150
167
|
- spec/attune/client_spec.rb
|
151
168
|
- spec/attune/json_logger_spec.rb
|
152
169
|
- spec/attune_spec.rb
|