sucker 1.0.0 → 1.1.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.
- data/CHANGELOG.md +9 -18
- data/README.md +9 -5
- data/lib/sucker.rb +0 -3
- data/lib/sucker/request.rb +96 -18
- data/lib/sucker/response.rb +20 -14
- data/lib/sucker/version.rb +1 -1
- data/spec/integration/multiple_locales_spec.rb +28 -3
- data/spec/support/vcr.rb +3 -2
- data/spec/unit/sucker/request_spec.rb +109 -29
- data/spec/unit/sucker/response_spec.rb +26 -23
- metadata +23 -137
- data/lib/sucker.rbc +0 -341
- data/lib/sucker/request.rbc +0 -2481
- data/lib/sucker/response.rbc +0 -1554
- data/lib/sucker/version.rbc +0 -130
- data/spec/fixtures/cassette_library/integration/alternate_versions.yml +0 -27
- data/spec/fixtures/cassette_library/integration/errors.yml +0 -27
- data/spec/fixtures/cassette_library/integration/france.yml +0 -27
- data/spec/fixtures/cassette_library/integration/images.yml +0 -27
- data/spec/fixtures/cassette_library/integration/item_lookup/multiple.yml +0 -27
- data/spec/fixtures/cassette_library/integration/item_lookup/single.yml +0 -27
- data/spec/fixtures/cassette_library/integration/item_search.yml +0 -27
- data/spec/fixtures/cassette_library/integration/japan.yml +0 -27
- data/spec/fixtures/cassette_library/integration/keyword_search.yml +0 -27
- data/spec/fixtures/cassette_library/integration/kindle.yml +0 -27
- data/spec/fixtures/cassette_library/integration/kindle_2.yml +0 -27
- data/spec/fixtures/cassette_library/integration/multiple_locales.yml +0 -157
- data/spec/fixtures/cassette_library/integration/power_search.yml +0 -27
- data/spec/fixtures/cassette_library/integration/related_items/child.yml +0 -27
- data/spec/fixtures/cassette_library/integration/related_items/parent.yml +0 -27
- data/spec/fixtures/cassette_library/integration/seller_listings_search.yml +0 -27
- data/spec/fixtures/cassette_library/integration/twenty_items.yml +0 -27
- data/spec/fixtures/cassette_library/unit/sucker/request.yml +0 -29
- data/spec/fixtures/cassette_library/unit/sucker/response.yml +0 -27
- data/spec/integration/alternate_versions_spec.rbc +0 -843
- data/spec/integration/errors_spec.rbc +0 -964
- data/spec/integration/france_spec.rbc +0 -1012
- data/spec/integration/images_spec.rbc +0 -1047
- data/spec/integration/item_lookup_spec.rbc +0 -1723
- data/spec/integration/item_search_spec.rbc +0 -926
- data/spec/integration/japan_spec.rbc +0 -849
- data/spec/integration/keyword_search_spec.rbc +0 -838
- data/spec/integration/kindle_spec.rbc +0 -1425
- data/spec/integration/multiple_locales_spec.rbc +0 -1090
- data/spec/integration/power_search_spec.rbc +0 -838
- data/spec/integration/related_items_spec.rbc +0 -1228
- data/spec/integration/seller_listing_search_spec.rbc +0 -852
- data/spec/integration/twenty_items_spec.rbc +0 -1166
- data/spec/spec_helper.rbc +0 -231
- data/spec/support/amazon.yml +0 -3
- data/spec/support/amazon_credentials.rbc +0 -154
- data/spec/support/asins.rbc +0 -335
- data/spec/support/vcr.rbc +0 -360
- data/spec/unit/sucker/request_spec.rbc +0 -4031
- data/spec/unit/sucker/response_spec.rbc +0 -3787
- data/spec/unit/sucker_spec.rbc +0 -299
data/CHANGELOG.md
CHANGED
@@ -1,34 +1,25 @@
|
|
1
|
-
Version 1.
|
1
|
+
Version 1.1.0
|
2
2
|
=============
|
3
3
|
|
4
|
-
|
4
|
+
* Removed Request#get!. Bloat.
|
5
|
+
* Added Request#get_all to fetch responses from all venues
|
6
|
+
simultaneously.
|
7
|
+
* Added Request#associate_tags= to set associate tags for all locales.
|
8
|
+
* Added Request#keys= to set distinct keys for locales.
|
9
|
+
* Request#get validates presence of key and locale.
|
5
10
|
|
6
|
-
|
7
|
-
|
11
|
+
Version 1.0.0
|
12
|
+
=============
|
8
13
|
|
9
14
|
* Added #each and #map to Response. #find no longer yields.
|
10
15
|
|
11
16
|
Version 1.0.0.beta4
|
12
17
|
===================
|
13
18
|
|
14
|
-
Release date: 2010-10-28
|
15
|
-
|
16
|
-
Added
|
17
|
-
-----
|
18
|
-
|
19
19
|
* Sucker::Request#get! raises an error if response is not valid.
|
20
20
|
|
21
21
|
Version 1.0.0.beta3
|
22
22
|
===================
|
23
23
|
|
24
|
-
Release date: 2010-10-25
|
25
|
-
|
26
|
-
Added
|
27
|
-
-----
|
28
|
-
|
29
24
|
* Sucker::Response#find yields to a block if given one.
|
30
|
-
|
31
|
-
Deprecated
|
32
|
-
----------
|
33
|
-
|
34
25
|
* Renamed #node to #find
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Sucker
|
2
2
|
======
|
3
3
|
|
4
|
-
Sucker is a Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html). It runs on [curb](http://github.com/taf2/curb) and [the Nokogiri implementation of the XML Mini module](http://github.com/rails/rails/blob/master/activesupport/lib/active_support/xml_mini/nokogiri.rb) in Active Support. It's fast and supports __the entire API__.
|
4
|
+
Sucker is a minimal Ruby wrapper to the [Amazon Product Advertising API](https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html). It runs on [curb](http://github.com/taf2/curb) and [the Nokogiri implementation of the XML Mini module](http://github.com/rails/rails/blob/master/activesupport/lib/active_support/xml_mini/nokogiri.rb) in Active Support. It's fast and supports __the entire API__.
|
5
5
|
|
6
|
-

|
7
7
|
|
8
8
|
Examples
|
9
9
|
--------
|
@@ -43,10 +43,14 @@ Iterate over items in your item lookup.
|
|
43
43
|
|
44
44
|
response.each("Item") { |item| ... }
|
45
45
|
|
46
|
-
|
46
|
+
Map errors to a block.
|
47
47
|
|
48
48
|
errors = response.map("Error") { |error| ... }
|
49
49
|
|
50
|
+
Or simply get a hash of matching items.
|
51
|
+
|
52
|
+
items = response.find("Item")
|
53
|
+
|
50
54
|
Repeat ad infinitum.
|
51
55
|
|
52
56
|
Check my [integration specs](http://github.com/papercavalier/sucker/tree/master/spec/integration/) for more examples. See [twenty items](http://github.com/papercavalier/sucker/tree/master/spec/integration/twenty_items_spec.rb) and [multiple locales](http://github.com/papercavalier/sucker/tree/master/spec/integration/multiple_locales_spec.rb) for relatively advanced usage.
|
@@ -58,12 +62,12 @@ Stubbing
|
|
58
62
|
|
59
63
|
Use [VCR](http://github.com/myronmarston/vcr) to stub your requests.
|
60
64
|
|
61
|
-
Caveat: Match URIs on host only and create a new cassette for each query. [This is how
|
65
|
+
Caveat: Match URIs on host only and create a new cassette for each query. [This is how my VCR helper looks like.](http://github.com/papercavalier/sucker/blob/master/spec/support/vcr.rb).
|
62
66
|
|
63
67
|
Compatibility
|
64
68
|
-------------
|
65
69
|
|
66
|
-
Specs pass against Ruby 1.8.7
|
70
|
+
Specs pass against Ruby 1.8.7 and Ruby 1.9.2.
|
67
71
|
|
68
72
|
Sucker works seamlessly with or without Rails.
|
69
73
|
|
data/lib/sucker.rb
CHANGED
data/lib/sucker/request.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require "curb"
|
2
|
+
require "ostruct"
|
3
|
+
require "uri"
|
4
|
+
|
1
5
|
module Sucker #:nodoc:
|
2
6
|
|
3
7
|
# A wrapper around the API request
|
@@ -49,56 +53,125 @@ module Sucker #:nodoc:
|
|
49
53
|
self.parameters.merge!(hash)
|
50
54
|
end
|
51
55
|
|
52
|
-
#
|
56
|
+
# Returns the associate tag for the current locale
|
57
|
+
def associate_tag
|
58
|
+
@associate_tags[locale.to_sym] rescue nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sets the associate tag for the current locale
|
53
62
|
#
|
54
63
|
# worker = Sucker.new
|
55
64
|
# worker.associate_tag = 'foo-bar'
|
56
65
|
#
|
57
66
|
def associate_tag=(token)
|
58
|
-
|
67
|
+
@associate_tags = HOSTS.keys.inject({}) do |tags, loc|
|
68
|
+
tags[loc] = token
|
69
|
+
tags
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets associate tags for all locales
|
74
|
+
#
|
75
|
+
# tags = {
|
76
|
+
# :us => 'foo-bar-10',
|
77
|
+
# :uk => 'foo-bar-20',
|
78
|
+
# :de => 'foo-bar-30',
|
79
|
+
# ... }
|
80
|
+
#
|
81
|
+
# worker = Sucker.new
|
82
|
+
# worker.associate_tags = tags
|
83
|
+
#
|
84
|
+
def associate_tags=(tokens)
|
85
|
+
@associate_tags = tokens
|
59
86
|
end
|
60
87
|
|
61
|
-
#
|
88
|
+
# Returns options for curl and yields them if given a block
|
62
89
|
#
|
63
90
|
# worker = Sucker.new
|
64
91
|
# worker.curl { |c| c.interface = "eth1" }
|
65
92
|
#
|
66
|
-
def
|
67
|
-
@
|
68
|
-
yield @
|
69
|
-
|
93
|
+
def curl_opts
|
94
|
+
@curl_opts ||= CurlOptions.new
|
95
|
+
yield @curl_opts if block_given?
|
96
|
+
|
97
|
+
@curl_opts.marshal_dump
|
70
98
|
end
|
71
99
|
|
72
|
-
# Performs
|
100
|
+
# Performs a request and returns a response
|
73
101
|
#
|
74
102
|
# worker = Sucker.new
|
75
103
|
# response = worker.get
|
76
104
|
#
|
77
105
|
def get
|
78
|
-
|
79
|
-
|
106
|
+
raise ArgumentError.new "Locale missing" unless locale
|
107
|
+
raise ArgumentError.new "AWS access key missing" unless key
|
108
|
+
|
109
|
+
curl = Curl::Easy.perform(uri.to_s) do |easy|
|
110
|
+
curl_opts.each { |k, v| easy.send(k, v) }
|
111
|
+
end
|
80
112
|
|
81
113
|
Response.new(curl)
|
82
114
|
end
|
83
115
|
|
84
|
-
#
|
85
|
-
|
86
|
-
|
116
|
+
# Performs a request for all locales, returns an array of responses, and
|
117
|
+
# yields them if given a block
|
118
|
+
#
|
119
|
+
# worker = Sucker.new
|
120
|
+
#
|
121
|
+
# # This blocks until all requests are complete
|
122
|
+
# responses = worker.get_all
|
123
|
+
#
|
124
|
+
# # This does not block
|
125
|
+
# worker.get_all do |response|
|
126
|
+
# process_response
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
def get_all
|
130
|
+
uris = HOSTS.keys.map do |locale|
|
131
|
+
self.locale = locale
|
132
|
+
uri.to_s
|
133
|
+
end
|
134
|
+
responses = []
|
87
135
|
|
88
|
-
|
89
|
-
|
136
|
+
Curl::Multi.get(uris, curl_opts) do |curl|
|
137
|
+
response = Response.new(curl)
|
138
|
+
yield response if block_given?
|
139
|
+
responses << response
|
90
140
|
end
|
91
141
|
|
92
|
-
|
142
|
+
responses
|
93
143
|
end
|
94
144
|
|
95
|
-
#
|
145
|
+
# Returns the AWS access key for the current locale
|
146
|
+
def key
|
147
|
+
@keys[locale.to_sym]
|
148
|
+
end
|
149
|
+
|
150
|
+
# Sets a global AWS access key ID
|
96
151
|
#
|
97
152
|
# worker = Sucker.new
|
98
153
|
# worker.key = 'foo'
|
99
154
|
#
|
100
155
|
def key=(token)
|
101
|
-
|
156
|
+
@keys = HOSTS.keys.inject({}) do |keys, locale|
|
157
|
+
keys[locale] = token
|
158
|
+
keys
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Sets distinct AWS access keys for the locales
|
163
|
+
#
|
164
|
+
# keys = {
|
165
|
+
# :us => 'foo',
|
166
|
+
# :uk => 'bar',
|
167
|
+
# :de => 'baz',
|
168
|
+
# ... }
|
169
|
+
#
|
170
|
+
# worker = Sucker.new
|
171
|
+
# worker.keys = keys
|
172
|
+
#
|
173
|
+
def keys=(tokens)
|
174
|
+
@keys = tokens
|
102
175
|
end
|
103
176
|
|
104
177
|
# Sets the Amazon API version
|
@@ -116,6 +189,8 @@ module Sucker #:nodoc:
|
|
116
189
|
def build_query
|
117
190
|
parameters.
|
118
191
|
merge(timestamp).
|
192
|
+
merge({ "AWSAccessKeyId" => key }).
|
193
|
+
merge({ "AssociateTag" => associate_tag }).
|
119
194
|
sort.
|
120
195
|
collect do |k, v|
|
121
196
|
"#{k}=" + escape(v.is_a?(Array) ? v.join(",") : v.to_s)
|
@@ -156,4 +231,7 @@ module Sucker #:nodoc:
|
|
156
231
|
{ "Timestamp" => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ') }
|
157
232
|
end
|
158
233
|
end
|
234
|
+
|
235
|
+
# Curl options
|
236
|
+
class CurlOptions < OpenStruct; end
|
159
237
|
end
|
data/lib/sucker/response.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "active_support/xml_mini/nokogiri"
|
2
|
+
|
1
3
|
module Sucker #:nodoc:
|
2
4
|
|
3
5
|
# A Nokogiri-driven wrapper around the cURL response
|
@@ -12,19 +14,23 @@ module Sucker #:nodoc:
|
|
12
14
|
# Transaction time in seconds for request
|
13
15
|
attr_accessor :time
|
14
16
|
|
17
|
+
# The request URI
|
18
|
+
attr_accessor :uri
|
19
|
+
|
15
20
|
def initialize(curl)
|
16
21
|
self.body = curl.body_str
|
17
22
|
self.code = curl.response_code
|
18
23
|
self.time = curl.total_time
|
24
|
+
self.uri = curl.url
|
19
25
|
end
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
# A shorthand that yields each match to a block
|
28
|
+
#
|
29
|
+
# worker.get.each("Item") { |item| process(item) }
|
30
|
+
#
|
31
|
+
def each(path)
|
32
|
+
find(path).each { |e| yield e }
|
33
|
+
end
|
28
34
|
|
29
35
|
# Queries an xpath and returns an array of matching nodes
|
30
36
|
#
|
@@ -32,15 +38,15 @@ module Sucker #:nodoc:
|
|
32
38
|
# response.find("Item").each { |item| ... }
|
33
39
|
#
|
34
40
|
def find(path)
|
35
|
-
xml.xpath("//xmlns:#{path}").map { |
|
41
|
+
xml.xpath("//xmlns:#{path}").map { |e| strip_content(e.to_hash[path]) }
|
36
42
|
end
|
37
43
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
# A shorthand that yields matches to a block and collects returned values
|
45
|
+
#
|
46
|
+
# descriptions = worker.get.map("Item") { |item| build_description(item) }
|
47
|
+
#
|
48
|
+
def map(path)
|
49
|
+
find(path).map { |e| yield e }
|
44
50
|
end
|
45
51
|
|
46
52
|
def node(path) # :nodoc:
|
data/lib/sucker/version.rb
CHANGED
@@ -5,11 +5,36 @@ module Sucker
|
|
5
5
|
|
6
6
|
describe "Item lookup" do
|
7
7
|
|
8
|
-
|
8
|
+
use_vcr_cassette "integration/multiple_locales", :record => :new_episodes
|
9
9
|
|
10
|
-
|
10
|
+
context "when using Curl::Multi to search all locales simultaneously" do
|
11
11
|
|
12
|
-
it "returns matches
|
12
|
+
it "returns matches for all locales" do
|
13
|
+
worker = Sucker.new(
|
14
|
+
:key => amazon["key"],
|
15
|
+
:secret => amazon["secret"])
|
16
|
+
worker << {
|
17
|
+
"Operation" => "ItemLookup",
|
18
|
+
"IdType" => "ASIN",
|
19
|
+
"ResponseGroup" => "ItemAttributes",
|
20
|
+
"ItemId" => "0816614024" }
|
21
|
+
|
22
|
+
bindings = worker.get_all.map do |response|
|
23
|
+
item = response.find("Item").first
|
24
|
+
item["ItemAttributes"]["Binding"]
|
25
|
+
end
|
26
|
+
|
27
|
+
bindings.uniq.should =~ %w{ Paperback Taschenbuch Broché ペーパーバック }
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when using threads to search all locales simultaneously" do
|
34
|
+
|
35
|
+
# Leaving this spec here for reference purposes. Use approach in above spec.
|
36
|
+
|
37
|
+
it "returns matches for all locales" do
|
13
38
|
locales = %w{us uk de ca fr jp}
|
14
39
|
|
15
40
|
params = {
|
data/spec/support/vcr.rb
CHANGED
@@ -2,10 +2,11 @@ require 'vcr'
|
|
2
2
|
|
3
3
|
VCR.config do |c|
|
4
4
|
c.cassette_library_dir = File.dirname(__FILE__) + '/../fixtures/cassette_library'
|
5
|
-
c.http_stubbing_library = :webmock
|
6
5
|
c.default_cassette_options = {
|
7
|
-
:record => :
|
6
|
+
:record => :none,
|
8
7
|
:match_requests_on => [:host] }
|
8
|
+
|
9
|
+
c.stub_with :webmock
|
9
10
|
end
|
10
11
|
|
11
12
|
RSpec.configure do |config|
|
@@ -42,60 +42,134 @@ module Sucker
|
|
42
42
|
|
43
43
|
end
|
44
44
|
|
45
|
-
describe "#associate_tag
|
45
|
+
describe "#associate_tag" do
|
46
46
|
|
47
|
-
it "
|
48
|
-
worker.
|
49
|
-
|
47
|
+
it "returns the associate tag for the current locale" do
|
48
|
+
worker.instance_variable_set(:@associate_tags, { :us => 'foo-bar'})
|
49
|
+
|
50
|
+
worker.associate_tag.should eql 'foo-bar'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns nil if an associate tag is not set for the current locale" do
|
54
|
+
worker.associate_tag.should eql nil
|
50
55
|
end
|
51
56
|
|
52
57
|
end
|
53
58
|
|
54
|
-
describe "#
|
59
|
+
describe "#associate_tags=" do
|
55
60
|
|
56
|
-
it "
|
57
|
-
|
61
|
+
it "sets associate tags for the locales" do
|
62
|
+
tags = {
|
63
|
+
:us => 'foo',
|
64
|
+
:uk => 'bar',
|
65
|
+
:de => 'baz',
|
66
|
+
:ca => 'foo',
|
67
|
+
:fr => 'bar',
|
68
|
+
:jp => 'baz' }
|
69
|
+
worker.associate_tags = tags
|
70
|
+
|
71
|
+
worker.instance_variable_get(:@associate_tags).should eql tags
|
58
72
|
end
|
59
73
|
|
60
|
-
|
74
|
+
end
|
61
75
|
|
62
|
-
|
63
|
-
worker.curl.interface.should be_nil
|
76
|
+
describe "#curl_opts" do
|
64
77
|
|
65
|
-
|
78
|
+
it "returns options for curl" do
|
79
|
+
worker.curl_opts.should be_an_instance_of Hash
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when given a block" do
|
66
83
|
|
67
|
-
|
84
|
+
it "yields options for curl" do
|
85
|
+
worker.curl_opts { |c| c.interface = "eth1" }
|
86
|
+
|
87
|
+
worker.curl_opts[:interface].should eql "eth1"
|
68
88
|
end
|
69
89
|
|
70
90
|
end
|
71
91
|
|
72
92
|
end
|
73
93
|
|
74
|
-
describe "#get
|
94
|
+
describe "#get" do
|
95
|
+
|
96
|
+
it "returns a response" do
|
97
|
+
worker.get.class.ancestors.should include Response
|
98
|
+
end
|
75
99
|
|
76
|
-
it "raises if
|
77
|
-
worker
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
lambda { worker.get! }.should raise_error ResponseError
|
100
|
+
it "raises an argument error if no key is provided" do
|
101
|
+
worker.key = nil
|
102
|
+
expect do
|
103
|
+
worker.get
|
104
|
+
end.to raise_error(/AWS access key missing/)
|
82
105
|
end
|
83
106
|
|
107
|
+
it "raises an argument error if no locale is provided" do
|
108
|
+
worker.locale = nil
|
109
|
+
expect do
|
110
|
+
worker.get
|
111
|
+
end.to raise_error(/Locale missing/)
|
112
|
+
end
|
84
113
|
end
|
85
114
|
|
86
|
-
describe "#
|
115
|
+
describe "#get_all" do
|
87
116
|
|
88
|
-
it "returns
|
89
|
-
worker.
|
117
|
+
it "returns an array of responses" do
|
118
|
+
responses = worker.get_all
|
119
|
+
|
120
|
+
responses.should be_an_instance_of Array
|
121
|
+
responses.each { |resp| resp.should be_an_instance_of Response }
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when given a block" do
|
125
|
+
|
126
|
+
it "yields responses" do
|
127
|
+
count = 0
|
128
|
+
worker.get_all do |resp|
|
129
|
+
resp.should be_an_instance_of Response
|
130
|
+
count += 1
|
131
|
+
end
|
132
|
+
|
133
|
+
count.should eql Request::HOSTS.size
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#key" do
|
139
|
+
|
140
|
+
it "returns the Amazon AWS access key for the current locale" do
|
141
|
+
worker.instance_variable_set(:@keys, { :us => 'foo' })
|
142
|
+
|
143
|
+
worker.key.should eql 'foo'
|
90
144
|
end
|
91
145
|
|
92
146
|
end
|
93
147
|
|
94
148
|
describe "#key=" do
|
95
149
|
|
96
|
-
it "sets
|
150
|
+
it "sets a global Amazon AWS access key" do
|
97
151
|
worker.key = "foo"
|
98
|
-
worker.
|
152
|
+
keys = worker.instance_variable_get(:@keys)
|
153
|
+
|
154
|
+
keys.size.should eql Request::HOSTS.size
|
155
|
+
keys.values.uniq.should eql ["foo"]
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "#keys=" do
|
161
|
+
|
162
|
+
it "sets distinct Amazon AWS access keys for the locales" do
|
163
|
+
keys = {
|
164
|
+
:us => 'foo',
|
165
|
+
:uk => 'bar',
|
166
|
+
:de => 'baz',
|
167
|
+
:ca => 'foo',
|
168
|
+
:fr => 'bar',
|
169
|
+
:jp => 'baz' }
|
170
|
+
worker.keys = keys
|
171
|
+
|
172
|
+
worker.instance_variable_get(:@keys).should eql keys
|
99
173
|
end
|
100
174
|
|
101
175
|
end
|
@@ -104,32 +178,38 @@ module Sucker
|
|
104
178
|
|
105
179
|
describe "#build_query" do
|
106
180
|
|
181
|
+
let(:query) { worker.send(:build_query) }
|
182
|
+
|
107
183
|
it "canonicalizes parameters" do
|
108
|
-
query = worker.send(:build_query)
|
109
184
|
query.should match /Service=([^&]+)&Timestamp=([^&]+)&Version=([^&]+)/
|
110
185
|
end
|
111
186
|
|
187
|
+
it "includes the key for the current locale" do
|
188
|
+
worker.instance_variable_set(:@keys, { :us => 'foo' })
|
189
|
+
query.should include 'AWSAccessKeyId=foo'
|
190
|
+
end
|
191
|
+
|
192
|
+
it "includes a timestamp" do
|
193
|
+
query.should include 'Timestamp='
|
194
|
+
end
|
195
|
+
|
112
196
|
it "sorts parameters" do
|
113
197
|
worker.parameters["AAA"] = "foo"
|
114
|
-
query = worker.send(:build_query)
|
115
198
|
query.should match /^AAA=foo/
|
116
199
|
end
|
117
200
|
|
118
201
|
it "converts a parameter whose value is an array to a string" do
|
119
202
|
worker.parameters["Foo"] = ["bar", "baz"]
|
120
|
-
query = worker.send(:build_query)
|
121
203
|
query.should match /Foo=bar%2Cbaz/
|
122
204
|
end
|
123
205
|
|
124
206
|
it "handles integer parameter values" do
|
125
207
|
worker.parameters["Foo"] = 1
|
126
|
-
query = worker.send(:build_query)
|
127
208
|
query.should match /Foo=1/
|
128
209
|
end
|
129
210
|
|
130
211
|
it "handles floating-point parameter values" do
|
131
212
|
worker.parameters["Foo"] = 1.0
|
132
|
-
query = worker.send(:build_query)
|
133
213
|
query.should match /Foo=1/
|
134
214
|
end
|
135
215
|
|