mws-connect 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gitignore +19 -0
  2. data/.sublime-project +19 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +111 -0
  6. data/Rakefile +1 -0
  7. data/lib/mws.rb +34 -0
  8. data/lib/mws/apis.rb +6 -0
  9. data/lib/mws/apis/feeds.rb +20 -0
  10. data/lib/mws/apis/feeds/api.rb +103 -0
  11. data/lib/mws/apis/feeds/distance.rb +23 -0
  12. data/lib/mws/apis/feeds/feed.rb +114 -0
  13. data/lib/mws/apis/feeds/image_listing.rb +44 -0
  14. data/lib/mws/apis/feeds/inventory.rb +77 -0
  15. data/lib/mws/apis/feeds/measurement.rb +32 -0
  16. data/lib/mws/apis/feeds/money.rb +31 -0
  17. data/lib/mws/apis/feeds/price_listing.rb +48 -0
  18. data/lib/mws/apis/feeds/product.rb +173 -0
  19. data/lib/mws/apis/feeds/sale_price.rb +31 -0
  20. data/lib/mws/apis/feeds/shipping.rb +160 -0
  21. data/lib/mws/apis/feeds/submission_info.rb +45 -0
  22. data/lib/mws/apis/feeds/submission_result.rb +87 -0
  23. data/lib/mws/apis/feeds/transaction.rb +37 -0
  24. data/lib/mws/apis/feeds/weight.rb +19 -0
  25. data/lib/mws/apis/orders.rb +23 -0
  26. data/lib/mws/connection.rb +84 -0
  27. data/lib/mws/enum.rb +81 -0
  28. data/lib/mws/errors.rb +32 -0
  29. data/lib/mws/query.rb +45 -0
  30. data/lib/mws/serializer.rb +81 -0
  31. data/lib/mws/signer.rb +20 -0
  32. data/lib/mws/utils.rb +50 -0
  33. data/mws.gemspec +25 -0
  34. data/scripts/catalog-workflow +136 -0
  35. data/spec/mws/apis/feeds/api_spec.rb +229 -0
  36. data/spec/mws/apis/feeds/distance_spec.rb +43 -0
  37. data/spec/mws/apis/feeds/feed_spec.rb +92 -0
  38. data/spec/mws/apis/feeds/image_listing_spec.rb +109 -0
  39. data/spec/mws/apis/feeds/inventory_spec.rb +135 -0
  40. data/spec/mws/apis/feeds/measurement_spec.rb +84 -0
  41. data/spec/mws/apis/feeds/money_spec.rb +43 -0
  42. data/spec/mws/apis/feeds/price_listing_spec.rb +90 -0
  43. data/spec/mws/apis/feeds/product_spec.rb +264 -0
  44. data/spec/mws/apis/feeds/shipping_spec.rb +78 -0
  45. data/spec/mws/apis/feeds/submission_info_spec.rb +111 -0
  46. data/spec/mws/apis/feeds/submission_result_spec.rb +157 -0
  47. data/spec/mws/apis/feeds/transaction_spec.rb +64 -0
  48. data/spec/mws/apis/feeds/weight_spec.rb +43 -0
  49. data/spec/mws/apis/orders_spec.rb +9 -0
  50. data/spec/mws/connection_spec.rb +331 -0
  51. data/spec/mws/enum_spec.rb +166 -0
  52. data/spec/mws/query_spec.rb +104 -0
  53. data/spec/mws/serializer_spec.rb +187 -0
  54. data/spec/mws/signer_spec.rb +67 -0
  55. data/spec/mws/utils_spec.rb +147 -0
  56. data/spec/spec_helper.rb +10 -0
  57. metadata +220 -0
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+ require 'nokogiri'
3
+
4
+ module Mws::Apis::Feeds
5
+
6
+ describe SubmissionInfo do
7
+
8
+ let(:submitted_node) do
9
+ Nokogiri::XML::Builder.new do
10
+ FeedSubmissionInfo {
11
+ FeedSubmissionId 5868304010
12
+ FeedType '_POST_PRODUCT_DATA_'
13
+ SubmittedDate '2012-10-16T21:19:08+00:00'
14
+ FeedProcessingStatus '_SUBMITTED_'
15
+ }
16
+ end.doc.root
17
+ end
18
+
19
+ let(:in_progress_node) do
20
+ Nokogiri::XML::Builder.new do
21
+ FeedSubmissionInfo {
22
+ FeedSubmissionId 5868304010
23
+ FeedType '_POST_PRODUCT_DATA_'
24
+ SubmittedDate '2012-10-16T21:19:08+00:00'
25
+ FeedProcessingStatus '_IN_PROGRESS_'
26
+ StartedProcessingDate '2012-10-16T21:21:35+00:00'
27
+ }
28
+ end.doc.root
29
+ end
30
+
31
+ let(:done_node) do
32
+ Nokogiri::XML::Builder.new do
33
+ FeedSubmissionInfo {
34
+ FeedSubmissionId 5868304010
35
+ FeedType '_POST_PRODUCT_DATA_'
36
+ SubmittedDate '2012-10-16T21:19:08+00:00'
37
+ FeedProcessingStatus '_DONE_'
38
+ StartedProcessingDate '2012-10-16T21:21:35+00:00'
39
+ CompletedProcessingDate '2012-10-16T21:23:40+00:00'
40
+ }
41
+ end.doc.root
42
+ end
43
+
44
+ it 'should not allow instance creation via new' do
45
+ expect { SubmissionInfo.new }.to raise_error NoMethodError
46
+ end
47
+
48
+ context '.from_xml' do
49
+
50
+ it 'should be able to create an info object in a submitted state' do
51
+ info = SubmissionInfo.from_xml submitted_node
52
+ info.id.should == "5868304010"
53
+ info.status.should == SubmissionInfo::Status.SUBMITTED.sym
54
+ info.type.should == Feed::Type.PRODUCT.sym
55
+ info.submitted.should == Time.parse('2012-10-16T21:19:08+00:00')
56
+ info.started.should be_nil
57
+ info.completed.should be_nil
58
+ end
59
+
60
+ it 'should be able to create an info object in and in progress state' do
61
+ info = SubmissionInfo.from_xml in_progress_node
62
+ info.id.should == "5868304010"
63
+ info.status.should == SubmissionInfo::Status.IN_PROGRESS.sym
64
+ info.type.should == Feed::Type.PRODUCT.sym
65
+ info.submitted.should == Time.parse('2012-10-16T21:19:08+00:00')
66
+ info.started.should == Time.parse('2012-10-16T21:21:35+00:00')
67
+ info.completed.should be_nil
68
+ end
69
+
70
+ it 'should be able to create an info object in a done state' do
71
+ info = SubmissionInfo.from_xml done_node
72
+ info.id.should == "5868304010"
73
+ info.status.should == SubmissionInfo::Status.DONE.sym
74
+ info.type.should == Feed::Type.PRODUCT.sym
75
+ info.submitted.should == Time.parse('2012-10-16T21:19:08+00:00')
76
+ info.started.should == Time.parse('2012-10-16T21:21:35+00:00')
77
+ info.completed.should == Time.parse('2012-10-16T21:23:40+00:00')
78
+ end
79
+
80
+ end
81
+
82
+ context '#==' do
83
+
84
+ it 'should be reflexive' do
85
+ a = SubmissionInfo.from_xml submitted_node
86
+ (a == a).should be true
87
+ end
88
+
89
+ it 'should be symmetric' do
90
+ a = SubmissionInfo.from_xml submitted_node
91
+ b = SubmissionInfo.from_xml submitted_node
92
+ (a == b).should == (b == a)
93
+ end
94
+
95
+ it 'should be transitive' do
96
+ a = SubmissionInfo.from_xml submitted_node
97
+ b = SubmissionInfo.from_xml submitted_node
98
+ c = SubmissionInfo.from_xml submitted_node
99
+ (a == c).should == (a == b && b == c)
100
+ end
101
+
102
+ it 'should handle comparison to nil' do
103
+ a = SubmissionInfo.from_xml submitted_node
104
+ (a == nil).should be false
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+
111
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+ require 'nokogiri'
3
+
4
+ module Mws::Apis::Feeds
5
+
6
+ class SubmissionResult
7
+ attr_reader :responses
8
+ end
9
+
10
+ describe SubmissionResult do
11
+ let(:success_node) do
12
+ Nokogiri::XML::Builder.new do
13
+ Message {
14
+ MessageID 1
15
+ ProcessingReport {
16
+ DocumentTransactionID 5868304010
17
+ StatusCode 'Complete'
18
+ ProcessingSummary {
19
+ MessagesProcessed 1
20
+ MessagesSuccessful 1
21
+ MessagesWithError 0
22
+ MessagesWithWarning 0
23
+ }
24
+ }
25
+ }
26
+ end.doc.root
27
+ end
28
+ let(:error_node) do
29
+ Nokogiri::XML::Builder.new do
30
+ Message {
31
+ MessageID 1
32
+ ProcessingReport {
33
+ DocumentTransactionID 5868304010
34
+ StatusCode 'Complete'
35
+ ProcessingSummary {
36
+ MessagesProcessed 2
37
+ MessagesSuccessful 0
38
+ MessagesWithError 2
39
+ MessagesWithWarning 1
40
+ }
41
+ Result {
42
+ MessageID 1
43
+ ResultCode 'Error'
44
+ ResultMessageCode 8560
45
+ ResultDescription 'Result description 1'
46
+ AdditionalInfo {
47
+ SKU '3455449'
48
+ }
49
+ }
50
+ Result {
51
+ MessageID 2
52
+ ResultCode 'Error'
53
+ ResultMessageCode 5000
54
+ ResultDescription "Result description 2"
55
+ AdditionalInfo {
56
+ SKU '8744969'
57
+ }
58
+ }
59
+ Result {
60
+ MessageID 3
61
+ ResultCode 'Warning'
62
+ ResultMessageCode 5001
63
+ ResultDescription "Result description 3"
64
+ AdditionalInfo {
65
+ SKU '7844970'
66
+ }
67
+ }
68
+ }
69
+ }
70
+ end.doc.root
71
+ end
72
+
73
+ it 'should not allow instance creation via new' do
74
+ expect { SubmissionResult.new }.to raise_error NoMethodError
75
+ end
76
+
77
+ describe '.from_xml' do
78
+
79
+ it 'should be able to be constructed from valid success xml' do
80
+ result = SubmissionResult.from_xml success_node
81
+ result.transaction_id.should == '5868304010'
82
+ result.status.should == SubmissionResult::Status.COMPLETE.sym
83
+ result.messages_processed.should == 1
84
+ result.count_for(:success).should == 1
85
+ result.count_for(:error).should == 0
86
+ result.count_for(:warning).should == 0
87
+ result.responses.should be_empty
88
+ end
89
+
90
+ it 'should be able to be constructed from valid error xml' do
91
+ result = SubmissionResult.from_xml error_node
92
+ result.transaction_id.should == '5868304010'
93
+ result.status.should == SubmissionResult::Status.COMPLETE.sym
94
+ result.messages_processed.should == 2
95
+ result.count_for(:success).should == 0
96
+ result.count_for(:error).should == 2
97
+ result.count_for(:warning).should == 1
98
+ result.responses.size.should == 3
99
+
100
+ response = result.response_for 1
101
+ response.type.should == SubmissionResult::Response::Type.ERROR.sym
102
+ response.code.should == 8560
103
+ response.description == 'Result description 1'
104
+ response.additional_info.should == {
105
+ sku: '3455449'
106
+ }
107
+
108
+
109
+ response = result.response_for 2
110
+ response.type.should == SubmissionResult::Response::Type.ERROR.sym
111
+ response.code.should == 5000
112
+ response.description == 'Result description 2'
113
+ response.additional_info.should == {
114
+ sku: '8744969'
115
+ }
116
+
117
+ response = result.response_for 3
118
+ response.type.should == SubmissionResult::Response::Type.WARNING.sym
119
+ response.code.should == 5001
120
+ response.description == 'Result description 3'
121
+ response.additional_info.should == {
122
+ sku: '7844970'
123
+ }
124
+ end
125
+
126
+ end
127
+
128
+ context '#==' do
129
+
130
+ it 'should be reflexive' do
131
+ a = SubmissionResult.from_xml success_node
132
+ (a == a).should be true
133
+ end
134
+
135
+ it 'should be symmetric' do
136
+ a = SubmissionResult.from_xml success_node
137
+ b = SubmissionResult.from_xml success_node
138
+ (a == b).should == (b == a)
139
+ end
140
+
141
+ it 'should be transitive' do
142
+ a = SubmissionResult.from_xml success_node
143
+ b = SubmissionResult.from_xml success_node
144
+ c = SubmissionResult.from_xml success_node
145
+ (a == c).should == (a == b && b == c)
146
+ end
147
+
148
+ it 'should handle comparison to nil' do
149
+ a = SubmissionResult.from_xml success_node
150
+ (a == nil).should be false
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'nokogiri'
3
+
4
+ module Mws::Apis::Feeds
5
+
6
+ describe Transaction do
7
+
8
+ let(:submission_info) do
9
+ SubmissionInfo.from_xml(
10
+ Nokogiri::XML::Builder.new do
11
+ FeedSubmissionInfo {
12
+ FeedSubmissionId 5868304010
13
+ FeedType '_POST_PRODUCT_DATA_'
14
+ SubmittedDate '2012-10-16T21:19:08+00:00'
15
+ FeedProcessingStatus '_SUBMITTED_'
16
+ }
17
+ end.doc.root
18
+ )
19
+ end
20
+
21
+ describe '.new' do
22
+
23
+ it 'should be able to create a transaction with no items' do
24
+ transaction = Transaction.new submission_info
25
+ transaction.id.should == "5868304010"
26
+ transaction.status.should == SubmissionInfo::Status.SUBMITTED.sym
27
+ transaction.type.should == Feed::Type.PRODUCT.sym
28
+ transaction.submitted.should == Time.parse('2012-10-16T21:19:08+00:00')
29
+ transaction.items.should be_empty
30
+ end
31
+
32
+ it 'should be able to create a transaction with items' do
33
+ transaction = Transaction.new submission_info do
34
+ item 1, '12345678', :update
35
+ item 2, '87654321', :update, :main
36
+ item 3, '87654321', :delete, :other
37
+ end
38
+
39
+ transaction.items.length.should == 3
40
+
41
+ item = transaction.items[0]
42
+ item.id.should == 1
43
+ item.sku.should == '12345678'
44
+ item.operation.should == :update
45
+ item.qualifier.should be_nil
46
+
47
+ item = transaction.items[1]
48
+ item.id.should == 2
49
+ item.sku.should == '87654321'
50
+ item.operation.should == :update
51
+ item.qualifier.should == :main
52
+
53
+ item = transaction.items[2]
54
+ item.id.should == 3
55
+ item.sku.should == '87654321'
56
+ item.operation.should == :delete
57
+ item.qualifier.should == :other
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module Mws::Apis::Feeds
4
+
5
+ describe Weight do
6
+
7
+ context '.new' do
8
+
9
+ it 'should default to pounds' do
10
+ weight = Weight.new 40
11
+ weight.amount.should == 40
12
+ weight.unit.should == :pounds
13
+ end
14
+
15
+ it 'should accept a valid unit override' do
16
+ weight = Weight.new 0, :ounces
17
+ weight.amount.should == 0
18
+ weight.unit.should == :ounces
19
+ end
20
+
21
+ it 'should validate the unit override' do
22
+ expect {
23
+ Weight.new 50, :cent
24
+ }.to raise_error Mws::Errors::ValidationError, "Invalid unit of measure 'cent'"
25
+ end
26
+
27
+ end
28
+
29
+ context '#to_xml' do
30
+
31
+ it 'should properly serialize to XML' do
32
+ weight = Weight.new 25, :grams
33
+ expected = Nokogiri::XML::Builder.new do
34
+ Weight 25, unitOfMeasure: 'GR'
35
+ end.doc.root.to_xml
36
+ weight.to_xml.should == expected
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ module Mws::Apis
4
+
5
+ describe Orders do
6
+
7
+ end
8
+
9
+ end
@@ -0,0 +1,331 @@
1
+ require 'spec_helper'
2
+ require 'nokogiri'
3
+
4
+ module Mws
5
+
6
+ class Connection
7
+ attr_reader :scheme, :host, :merchant, :access, :secret
8
+ public :request, :response_for, :parse
9
+ end
10
+
11
+ describe Connection do
12
+
13
+ let(:defaults) {
14
+ {
15
+ merchant: 'GSWCJ4UBA31UTJ',
16
+ access: 'AYQAKIAJSCWMLYXAQ6K3',
17
+ secret: 'Ubzq/NskSrW4m5ncq53kddzBej7O7IE5Yx9drGrX'
18
+ }
19
+ }
20
+
21
+ let(:connection) {
22
+ Mws.connect(defaults)
23
+ }
24
+
25
+ context '.new' do
26
+
27
+ it 'should default scheme to https' do
28
+ connection.scheme.should == 'https'
29
+ end
30
+
31
+ it 'should accept a custom scheme' do
32
+ Connection.new(defaults.merge(scheme: 'http')).scheme.should == 'http'
33
+ end
34
+
35
+ it 'should default host to mws.amazonservices.com' do
36
+ connection.host.should == 'mws.amazonservices.com'
37
+ end
38
+
39
+ it 'should accept a custom host' do
40
+ Connection.new(defaults.merge(host: 'mws.amazonservices.uk')).host.should == 'mws.amazonservices.uk'
41
+ end
42
+
43
+ it 'should require a merchant identifier' do
44
+ expect {
45
+ Connection.new(
46
+ access: defaults[:access],
47
+ secret: defaults[:secret]
48
+ )
49
+ }.to raise_error Mws::Errors::ValidationError, 'A merchant identifier must be specified.'
50
+ end
51
+
52
+ it 'should accept a merchant identifier' do
53
+ connection.merchant.should == 'GSWCJ4UBA31UTJ'
54
+ end
55
+
56
+ it 'should require an access key' do
57
+ expect {
58
+ Connection.new(
59
+ merchant: defaults[:merchant],
60
+ secret: defaults[:secret]
61
+ )
62
+ }.to raise_error Mws::Errors::ValidationError, 'An access key must be specified.'
63
+ end
64
+
65
+ it 'should accept an access key' do
66
+ connection.access.should == 'AYQAKIAJSCWMLYXAQ6K3'
67
+ end
68
+
69
+ it 'should require a secret key' do
70
+ expect {
71
+ Connection.new(
72
+ merchant: defaults[:merchant],
73
+ access: defaults[:access]
74
+ )
75
+ }.to raise_error Mws::Errors::ValidationError, 'A secret key must be specified.'
76
+ end
77
+
78
+ it 'should accept a secret key' do
79
+ connection.secret.should == 'Ubzq/NskSrW4m5ncq53kddzBej7O7IE5Yx9drGrX'
80
+ end
81
+
82
+ end
83
+
84
+ context '#get' do
85
+
86
+ it 'should appropriately delegate to #request' do
87
+ connection.should_receive(:request).with(:get, '/foo', { market: 'ATVPDKIKX0DER' }, nil, { version: 1 })
88
+ connection.get('/foo', { market: 'ATVPDKIKX0DER' }, { version: 1 })
89
+ end
90
+
91
+ end
92
+
93
+ context '#post' do
94
+
95
+ it 'should appropriately delegate to #request' do
96
+ connection.should_receive(:request).with(:post, '/foo', { market: 'ATVPDKIKX0DER' }, 'test_body', { version: 1 })
97
+ connection.post('/foo', { market: 'ATVPDKIKX0DER' }, 'test_body', { version: 1 })
98
+ end
99
+
100
+ end
101
+
102
+ context '#request' do
103
+
104
+ it 'should construct a query, signer and make the request' do
105
+ Query.should_receive(:new).with(
106
+ action: nil,
107
+ version: nil,
108
+ merchant: 'GSWCJ4UBA31UTJ',
109
+ access: 'AYQAKIAJSCWMLYXAQ6K3',
110
+ list_pattern: nil
111
+ ).and_return('the_query')
112
+ signer = double('signer')
113
+ Signer.should_receive(:new).with(
114
+ method: :get,
115
+ host: 'mws.amazonservices.com',
116
+ path: '/foo',
117
+ secret: 'Ubzq/NskSrW4m5ncq53kddzBej7O7IE5Yx9drGrX'
118
+ ).and_return(signer)
119
+ signer.should_receive(:sign).with('the_query').and_return('the_signed_query')
120
+ connection.should_receive(:response_for).with(:get, '/foo', 'the_signed_query', nil).and_return('the_response')
121
+ connection.should_receive(:parse).with('the_response', {})
122
+ connection.request(:get, '/foo', {}, nil, {})
123
+ end
124
+
125
+ it 'should merge additional request parameters into the query' do
126
+ connection = Connection.new(
127
+ merchant: 'GSWCJ4UBA31UTJ',
128
+ access: 'AYQAKIAJSCWMLYXAQ6K3',
129
+ secret: 'Ubzq/NskSrW4m5ncq53kddzBej7O7IE5Yx9drGrX'
130
+ )
131
+ Query.should_receive(:new).with(
132
+ action: nil,
133
+ version: nil,
134
+ merchant: 'GSWCJ4UBA31UTJ',
135
+ access: 'AYQAKIAJSCWMLYXAQ6K3',
136
+ list_pattern: nil,
137
+ foo: 'bar',
138
+ baz: 'quk'
139
+ ).and_return('the_query')
140
+ signer = double('signer')
141
+ Signer.should_receive(:new).with(
142
+ method: :get,
143
+ host: 'mws.amazonservices.com',
144
+ path: '/foo',
145
+ secret: 'Ubzq/NskSrW4m5ncq53kddzBej7O7IE5Yx9drGrX'
146
+ ).and_return(signer)
147
+ signer.should_receive(:sign).with('the_query').and_return('the_signed_query')
148
+ connection.should_receive(:response_for).with(:get, '/foo', 'the_signed_query', nil).and_return('the_response')
149
+ connection.should_receive(:parse).with('the_response', {})
150
+ connection.request(:get, '/foo', { foo: 'bar', baz: 'quk' }, nil, {})
151
+ end
152
+
153
+ it 'should accept overrides to action, version and list_pattern' do
154
+ Query.should_receive(:new).with(
155
+ action: 'SubmitFeed',
156
+ version: '2009-01-01',
157
+ merchant: 'GSWCJ4UBA31UTJ',
158
+ access: 'AYQAKIAJSCWMLYXAQ6K3',
159
+ list_pattern: 'a_list_pattern'
160
+ ).and_return('the_query')
161
+ signer = double('signer')
162
+ Signer.should_receive(:new).with(
163
+ method: :get,
164
+ host: 'mws.amazonservices.com',
165
+ path: '/foo',
166
+ secret: 'Ubzq/NskSrW4m5ncq53kddzBej7O7IE5Yx9drGrX'
167
+ ).and_return(signer)
168
+ signer.should_receive(:sign).with('the_query').and_return('the_signed_query')
169
+ connection.should_receive(:response_for).with(:get, '/foo', 'the_signed_query', nil).and_return('the_response')
170
+ connection.should_receive(:parse).with('the_response', { action: 'SubmitFeed', version: '2009-01-01' })
171
+ connection.request(:get, '/foo', {}, nil, { action: 'SubmitFeed', version: '2009-01-01', list_pattern: 'a_list_pattern' })
172
+ end
173
+
174
+ end
175
+
176
+ context '#parse' do
177
+
178
+ it 'should parse error messages correctly' do
179
+ body = <<-XML
180
+ <?xml version="1.0"?>
181
+ <ErrorResponse xmlns="https://mws.amazonservices.com/Orders/2011-01-01">
182
+ <Error>
183
+ <Type>Sender</Type>
184
+ <Code>InvalidParameterValue</Code>
185
+ <Message>CreatedAfter or LastUpdatedAfter must be specified</Message>
186
+ </Error>
187
+ <RequestId>fb03503e-97e3-4ed1-88e9-d93f4d2111c1</RequestId>
188
+ </ErrorResponse>
189
+ XML
190
+ expect { connection.parse(body, {}) }.to raise_error do | error |
191
+ error.should be_a Errors::ServerError
192
+ error.type.should == 'Sender'
193
+ error.code.should == 'InvalidParameterValue'
194
+ error.message.should == 'CreatedAfter or LastUpdatedAfter must be specified'
195
+ error.details.should == 'None'
196
+ end
197
+ end
198
+
199
+ it 'should parse result based on custom action' do
200
+ body = <<-XML
201
+ <?xml version="1.0"?>
202
+ <ListOrdersResponse xmlns="https://mws.amazonservices.com/Orders/2011-01-01">
203
+ <ListOrdersResult>
204
+ <Orders/>
205
+ <CreatedBefore>2012-11-19T20:54:33Z</CreatedBefore>
206
+ </ListOrdersResult>
207
+ <ResponseMetadata>
208
+ <RequestId>931137cb-add7-4232-ac08-b701435c8447</RequestId>
209
+ </ResponseMetadata>
210
+ </ListOrdersResponse>
211
+ XML
212
+ result = connection.parse(body, action: 'ListOrders').name.should == 'ListOrdersResult'
213
+ end
214
+
215
+ it 'shoudl parse result base on custom xpath' do
216
+ body = <<-XML
217
+ <?xml version="1.0"?>
218
+ <ListOrdersResponse xmlns="https://mws.amazonservices.com/Orders/2011-01-01">
219
+ <ListOrdersResult>
220
+ <Orders/>
221
+ <CreatedBefore>2012-11-19T20:54:33Z</CreatedBefore>
222
+ </ListOrdersResult>
223
+ <ResponseMetadata>
224
+ <RequestId>931137cb-add7-4232-ac08-b701435c8447</RequestId>
225
+ </ResponseMetadata>
226
+ </ListOrdersResponse>
227
+ XML
228
+ result = connection.parse(body, xpath: '/ListOrdersResponse/ListOrdersResult').name.should == 'ListOrdersResult'
229
+ end
230
+
231
+ end
232
+
233
+ context '#response_for' do
234
+
235
+ it 'should properly handle a secure get request' do
236
+ response = double(:response)
237
+ response.should_receive(:body).exactly(3).times.and_return('response_body')
238
+ http = double(:http)
239
+ http.should_receive(:request) do | req |
240
+ req.should be_a Net::HTTP::Get
241
+ req.method.should == 'GET'
242
+ req.path.should == '/?foo=bar'
243
+ req['User-Agent'].should == 'MWS Connect/0.0.1 (Language=Ruby)'
244
+ req['Accept-Encoding'].should == 'text/xml'
245
+ response
246
+ end
247
+ Net::HTTP.should_receive(:start).with('mws.amazonservices.com', 443, use_ssl: true).and_yield(http)
248
+ connection.response_for(:get, '/', 'foo=bar', nil).should == 'response_body'
249
+ end
250
+
251
+ it 'should properly handle an insecure get request' do
252
+ connection = Connection.new(defaults.merge(scheme: 'http'))
253
+ response = double(:response)
254
+ response.should_receive(:body).exactly(3).times.and_return('response_body')
255
+ http = double(:http)
256
+ http.should_receive(:request) do | req |
257
+ req.should be_a Net::HTTP::Get
258
+ req.method.should == 'GET'
259
+ req.path.should == '/?foo=bar'
260
+ req['User-Agent'].should == 'MWS Connect/0.0.1 (Language=Ruby)'
261
+ req['Accept-Encoding'].should == 'text/xml'
262
+ response
263
+ end
264
+ Net::HTTP.should_receive(:start).with('mws.amazonservices.com', 80, use_ssl: false).and_yield(http)
265
+ connection.response_for(:get, '/', 'foo=bar', nil).should == 'response_body'
266
+ end
267
+
268
+ it 'should properly handle requests with transport level errors' do
269
+ response = double(:response)
270
+ response.should_receive(:body).and_return(nil)
271
+ response.should_receive(:code).and_return(500)
272
+ response.should_receive(:msg).and_return('Internal Server Error')
273
+ http = double(:http)
274
+ http.should_receive(:request) do | req |
275
+ req.should be_a Net::HTTP::Get
276
+ req.method.should == 'GET'
277
+ req.path.should == '/?foo=bar'
278
+ req['User-Agent'].should == 'MWS Connect/0.0.1 (Language=Ruby)'
279
+ req['Accept-Encoding'].should == 'text/xml'
280
+ response
281
+ end
282
+ Net::HTTP.should_receive(:start).with('mws.amazonservices.com', 443, use_ssl: true).and_yield(http)
283
+ expect { connection.response_for(:get, '/', 'foo=bar', nil) }.to raise_error do | error |
284
+ error.should be_a Errors::ServerError
285
+ error.type.should == 'Server'
286
+ error.code.should == 500
287
+ error.message.should == 'Internal Server Error'
288
+ error.detail.should == 'None'
289
+ end
290
+ end
291
+
292
+ it 'should properly handle a post without a body' do
293
+ response = double(:response)
294
+ response.should_receive(:body).exactly(3).times.and_return('response_body')
295
+ http = double(:http)
296
+ http.should_receive(:request) do | req |
297
+ req.should be_a Net::HTTP::Post
298
+ req.method.should == 'POST'
299
+ req.path.should == '/?foo=bar'
300
+ req['User-Agent'].should == 'MWS Connect/0.0.1 (Language=Ruby)'
301
+ req['Accept-Encoding'].should == 'text/xml'
302
+ response
303
+ end
304
+ Net::HTTP.should_receive(:start).with('mws.amazonservices.com', 443, use_ssl: true).and_yield(http)
305
+ connection.response_for(:post, '/', 'foo=bar', nil).should == 'response_body'
306
+ end
307
+
308
+ it 'should properly handle a post with a body' do
309
+ response = double(:response)
310
+ response.should_receive(:body).exactly(3).times.and_return('response_body')
311
+ http = double(:http)
312
+ http.should_receive(:request) do | req |
313
+ req.should be_a Net::HTTP::Post
314
+ req.method.should == 'POST'
315
+ req.path.should == '/?foo=bar'
316
+ req.content_type.should == 'text/xml'
317
+ req.body.should == 'request_body'
318
+ req['Content-MD5'] = Digest::MD5.base64digest('request_body').strip
319
+ req['User-Agent'].should == 'MWS Connect/0.0.1 (Language=Ruby)'
320
+ req['Accept-Encoding'].should == 'text/xml'
321
+ response
322
+ end
323
+ Net::HTTP.should_receive(:start).with('mws.amazonservices.com', 443, use_ssl: true).and_yield(http)
324
+ connection.response_for(:post, '/', 'foo=bar', 'request_body').should == 'response_body'
325
+ end
326
+
327
+ end
328
+
329
+ end
330
+
331
+ end