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,43 @@
1
+ require 'spec_helper'
2
+
3
+ module Mws::Apis::Feeds
4
+
5
+ describe Money do
6
+
7
+ context '.new' do
8
+
9
+ it 'should default to usd' do
10
+ money = Money.new 40
11
+ money.amount.should == 40
12
+ money.currency.should == :usd
13
+ end
14
+
15
+ it 'should accept a valid currency override' do
16
+ money = Money.new 0, :eur
17
+ money.amount.should == 0
18
+ money.currency.should == :eur
19
+ end
20
+
21
+ it 'should validate the currency override' do
22
+ expect {
23
+ Money.new 40, :acres
24
+ }.to raise_error Mws::Errors::ValidationError, "Invalid currency 'acres'"
25
+ end
26
+
27
+ end
28
+
29
+ context '#to_xml' do
30
+
31
+ it 'should properly serialize to XML' do
32
+ money = Money.new 25, :cad
33
+ expected = Nokogiri::XML::Builder.new do
34
+ Price '25.00', currency: 'CAD'
35
+ end.doc.root.to_xml
36
+ money.to_xml.should == expected
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ module Mws::Apis::Feeds
4
+
5
+ describe PriceListing do
6
+
7
+ context '.new' do
8
+
9
+ it 'should be able to construct a price with only sku and base price' do
10
+ price = PriceListing.new('987612345', 14.99)
11
+ price.sku.should == '987612345'
12
+ price.currency.should == :usd
13
+ price.base.should == Money.new(14.99, :usd)
14
+ price.min.should be nil
15
+ price.sale.should be nil
16
+ end
17
+
18
+ it 'should be able to construct a price with custom currency code' do
19
+ price = PriceListing.new('9876123456', 14.99, currency: :eur)
20
+ price.currency.should == :eur
21
+ price.base.should == Money.new(14.99, :eur)
22
+ end
23
+
24
+ it 'should be able to construct a price with custom minimum advertised price' do
25
+ price = PriceListing.new('987612345', 14.99, min: 11.99)
26
+ price.min.should == Money.new(11.99, :usd)
27
+ end
28
+
29
+ it 'should be able to construct a new price with custom sale price' do
30
+ from = 1.day.ago
31
+ to = 4.months.from_now
32
+ price = PriceListing.new('987612345', 14.99, sale: {
33
+ amount: 12.99,
34
+ from: from,
35
+ to: to
36
+ })
37
+ price.sale.should == SalePrice.new(Money.new(12.99, :usd), from, to)
38
+ end
39
+
40
+ it 'should validate that the base price is less than the minimum advertised price' do
41
+ expect {
42
+ PriceListing.new('987612345', 9.99, min: 10.00)
43
+ }.to raise_error Mws::Errors::ValidationError, "'Base Price' must be greater than 'Minimum Advertised Price'."
44
+ end
45
+
46
+ it 'should validate that the sale price is less than the minimum advertised price' do
47
+ expect {
48
+ PriceListing.new('987612345', 14.99, min: 10.00).on_sale(9.99, 1.day.ago, 4.months.from_now)
49
+ }.to raise_error Mws::Errors::ValidationError, "'Sale Price' must be greater than 'Minimum Advertised Price'."
50
+ end
51
+
52
+ end
53
+
54
+ context '#on_sale' do
55
+
56
+ it 'should provide a nicer syntax for specifying the sale price' do
57
+ from = 1.day.ago
58
+ to = 4.months.from_now
59
+ price = PriceListing.new('987612345', 14.99).on_sale(12.99, from, to)
60
+ price.sale.should == SalePrice.new(Money.new(12.99, :usd) , from, to)
61
+ end
62
+
63
+ end
64
+
65
+ context '#to_xml' do
66
+
67
+ it 'should properly serialize to XML' do
68
+ from = 1.day.ago
69
+ to = 4.months.from_now
70
+ price = PriceListing.new('987612345', 14.99, currency: :eur, min: 10.99).on_sale(12.99, from, to)
71
+ expected = Nokogiri::XML::Builder.new do
72
+ Price {
73
+ SKU '987612345'
74
+ StandardPrice '14.99', currency: 'EUR'
75
+ MAP '10.99', currency: 'EUR'
76
+ Sale {
77
+ StartDate from.iso8601
78
+ EndDate to.iso8601
79
+ SalePrice '12.99', currency: 'EUR'
80
+ }
81
+ }
82
+ end.doc.root.to_xml
83
+ price.to_xml.should == expected
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,264 @@
1
+ require 'spec_helper'
2
+ require 'nokogiri'
3
+
4
+ module Mws::Apis::Feeds
5
+
6
+ describe Product do
7
+
8
+ context '.new' do
9
+
10
+ it 'should require a sku' do
11
+ expect { Product.new }.to raise_error ArgumentError
12
+
13
+ sku = '12343533'
14
+ Product.new(sku).sku.should == sku
15
+ end
16
+
17
+ it 'should support product builder block initialization' do
18
+ capture = nil
19
+ product = Product.new('123431') do
20
+ capture = self
21
+ end
22
+ capture.should be_an_instance_of Product::ProductBuilder
23
+ end
24
+
25
+ it 'should support building with upc, tax code, brand, manufacture and name' do
26
+ product = Product.new('12324') do
27
+ upc '4321'
28
+ tax_code 'GEN_TAX_CODE'
29
+ brand 'Test Brand'
30
+ manufacturer 'Test manufacture'
31
+ name 'Test Product'
32
+ end
33
+
34
+ product.upc.should == '4321'
35
+ product.tax_code.should == 'GEN_TAX_CODE'
36
+ product.brand.should == 'Test Brand'
37
+ product.manufacturer.should == 'Test manufacture'
38
+ product.name.should == 'Test Product'
39
+ end
40
+
41
+ it 'should support building with msrp' do
42
+ product = Product.new('12324') do
43
+ msrp 10.99, :usd
44
+ end
45
+
46
+ product.msrp.amount.should == 10.99
47
+ product.msrp.currency.should == :usd
48
+ end
49
+
50
+ it 'should support building with item dimensions' do
51
+ product = Product.new('12324') do
52
+ item_dimensions {
53
+ length 2, :feet
54
+ width 3, :inches
55
+ height 1, :meters
56
+ weight 4, :pounds
57
+ }
58
+ end
59
+
60
+ product.item_dimensions.length.should == Distance.new(2, :feet)
61
+ product.item_dimensions.width.should == Distance.new(3, :inches)
62
+ product.item_dimensions.height.should == Distance.new(1, :meters)
63
+ product.item_dimensions.weight.should == Weight.new(4, :pounds)
64
+ end
65
+
66
+ it 'should support building with package dimensions' do
67
+ product = Product.new('12324') do
68
+ package_dimensions {
69
+ length 2, :feet
70
+ width 3, :inches
71
+ height 1, :meters
72
+ weight 4, :pounds
73
+ }
74
+ end
75
+
76
+ product.package_dimensions.length.should == Distance.new(2, :feet)
77
+ product.package_dimensions.width.should == Distance.new(3, :inches)
78
+ product.package_dimensions.height.should == Distance.new(1, :meters)
79
+ product.package_dimensions.weight.should == Weight.new(4, :pounds)
80
+ end
81
+
82
+ it 'should require valid package and shipping dimensions' do
83
+ capture = self
84
+ product = Product.new('12324') do
85
+ package_dimensions {
86
+ capture.expect { length 2, :foots }.to capture.raise_error Mws::Errors::ValidationError
87
+ capture.expect { width 2, :decades }.to capture.raise_error Mws::Errors::ValidationError
88
+ capture.expect { height 1, :miles }.to capture.raise_error Mws::Errors::ValidationError
89
+ capture.expect { weight 1, :stone }.to capture.raise_error Mws::Errors::ValidationError
90
+ }
91
+ end
92
+ end
93
+
94
+ it 'should support building with description and bullet points' do
95
+ product = Product.new('12343') do
96
+ description 'This is a test product description.'
97
+ bullet_point 'Bullet Point 1'
98
+ bullet_point 'Bullet Point 2'
99
+ bullet_point 'Bullet Point 3'
100
+ bullet_point 'Bullet Point 4'
101
+ end
102
+ product.description.should == 'This is a test product description.'
103
+ product.bullet_points.length.should == 4
104
+ product.bullet_points[0].should == 'Bullet Point 1'
105
+ product.bullet_points[1].should == 'Bullet Point 2'
106
+ product.bullet_points[2].should == 'Bullet Point 3'
107
+ product.bullet_points[3].should == 'Bullet Point 4'
108
+ end
109
+
110
+
111
+ it 'should support building with package and shipping weight' do
112
+ product = Product.new('12343') do
113
+ package_weight 3, :pounds
114
+ shipping_weight 4, :ounces
115
+ end
116
+
117
+ product.package_weight.should == Weight.new(3, :pounds)
118
+ product.shipping_weight.should == Weight.new(4, :ounces)
119
+ end
120
+
121
+ it 'should support building with product details' do
122
+ product = Product.new '12343' do
123
+ category :ce
124
+ details {
125
+ value 'some value'
126
+ nested {
127
+ foo 'bar'
128
+ nested {
129
+ baz 'bahhh'
130
+ }
131
+ }
132
+ }
133
+ end
134
+
135
+ product.details.should_not be nil
136
+ product.details[:value].should == 'some value'
137
+ product.details[:nested][:foo].should == 'bar'
138
+ product.details[:nested][:nested][:baz].should == 'bahhh'
139
+ end
140
+
141
+ it 'should require a category when product details are specified' do
142
+ expect {
143
+ Product.new '12343' do
144
+ details {
145
+ value 'some value'
146
+ nested {
147
+ foo 'bar'
148
+ nested {
149
+ baz 'bahhh'
150
+ }
151
+ }
152
+ }
153
+ end
154
+ }.to raise_error Mws::Errors::ValidationError, 'Product must have a category when details are specified.'
155
+ end
156
+
157
+ end
158
+
159
+ context '#to_xml' do
160
+
161
+ it 'should create xml for standard attributes' do
162
+
163
+ expected = Nokogiri::XML::Builder.new do
164
+ Product {
165
+ SKU '12343'
166
+ StandardProductID {
167
+ Type 'UPC'
168
+ Value '432154321'
169
+ }
170
+ ProductTaxCode 'GEN_TAX_CODE'
171
+ DescriptionData {
172
+ Title 'Test Product'
173
+ Brand 'Test Brand'
174
+ Description 'Some product'
175
+ BulletPoint 'Bullet Point 1'
176
+ BulletPoint 'Bullet Point 2'
177
+ BulletPoint 'Bullet Point 3'
178
+ BulletPoint 'Bullet Point 4'
179
+ ItemDimensions {
180
+ Length 2, unitOfMeasure: 'feet'
181
+ Width 3, unitOfMeasure: 'inches'
182
+ Height 1, unitOfMeasure: 'meters'
183
+ Weight 4, unitOfMeasure: 'LB'
184
+ }
185
+ PackageDimensions {
186
+ Length 2, unitOfMeasure: 'feet'
187
+ Width 3, unitOfMeasure: 'inches'
188
+ Height 1, unitOfMeasure: 'meters'
189
+ Weight 4, unitOfMeasure: 'LB'
190
+ }
191
+ PackageWeight 2, unitOfMeasure: 'LB'
192
+ ShippingWeight 3, unitOfMeasure: 'MG'
193
+ MSRP 19.99, currency: 'USD'
194
+ Manufacturer 'Test manufacture'
195
+ }
196
+ }
197
+ end.doc.root.to_xml
198
+
199
+ expected.should == Product.new('12343') do
200
+ upc '432154321'
201
+ tax_code 'GEN_TAX_CODE'
202
+ brand 'Test Brand'
203
+ name 'Test Product'
204
+ description 'Some product'
205
+ msrp 19.99, 'USD'
206
+ manufacturer 'Test manufacture'
207
+ bullet_point 'Bullet Point 1'
208
+ bullet_point 'Bullet Point 2'
209
+ bullet_point 'Bullet Point 3'
210
+ bullet_point 'Bullet Point 4'
211
+ item_dimensions {
212
+ length 2, :feet
213
+ width 3, :inches
214
+ height 1, :meters
215
+ weight 4, :pounds
216
+ }
217
+ package_dimensions {
218
+ length 2, :feet
219
+ width 3, :inches
220
+ height 1, :meters
221
+ weight 4, :pounds
222
+ }
223
+ package_weight 2, :pounds
224
+ shipping_weight 3, :miligrams
225
+ end.to_xml
226
+
227
+ end
228
+
229
+ it 'should create xml for product details' do
230
+ expected = Nokogiri::XML::Builder.new do
231
+ Product {
232
+ SKU '12343'
233
+ DescriptionData {}
234
+ ProductData {
235
+ CE {
236
+ ProductType {
237
+ CableOrAdapter {
238
+ CableLength 6, unitOfMeasure: 'feet'
239
+ CableWeight 6, unitOfMeasure: 'OZ'
240
+ CostSavings '6.99', currency: 'USD'
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ end.doc.root.to_xml
247
+
248
+ expected.should == Product.new('12343') do
249
+ category :ce
250
+ details {
251
+ cable_or_adapter {
252
+ cable_length as_distance 6, :feet
253
+ cable_weight as_weight 6, :ounces
254
+ cost_savings as_money 6.99, :usd
255
+ }
256
+ }
257
+ end.to_xml
258
+ end
259
+
260
+ end
261
+
262
+ end
263
+
264
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ module Mws::Apis::Feeds
4
+
5
+ describe Shipping do
6
+
7
+ context '.new' do
8
+
9
+ it 'should require non-nil sku' do
10
+ expect { Shipping.new(nil) }.to raise_error Mws::Errors::ValidationError,
11
+ 'SKU is required.'
12
+ end
13
+
14
+ it 'should require a non-empty sku' do
15
+ expect { Shipping.new('') }.to raise_error Mws::Errors::ValidationError,
16
+ 'SKU is required.'
17
+ end
18
+
19
+ it 'should require a sku that is not all whitespace' do
20
+ expect { Shipping.new(' ') }.to raise_error Mws::Errors::ValidationError,
21
+ 'SKU is required.'
22
+ end
23
+
24
+ it 'should accept a valid value for sku' do
25
+ Shipping.new('987612345').sku.should == '987612345'
26
+ end
27
+
28
+ it 'should accept a block to associate shipping option overrides' do
29
+ shipping = Shipping.new('987612345') do
30
+ replace 4.99, :usd, :continental_us, :standard, :street
31
+ end
32
+ shipping.sku.should == '987612345'
33
+ shipping.options.size.should == 1
34
+ override = shipping.options.first
35
+ override.amount.should == Money.new(4.99, :usd)
36
+ override.option.region.should == :continental_us
37
+ override.option.speed.should == :standard
38
+ override.option.variant.should == :street
39
+ end
40
+
41
+ end
42
+
43
+ context '#to_xml' do
44
+ shipping = Shipping.new('987612345') do
45
+ unrestricted :continental_us, :standard
46
+ restricted :continental_us, :expedited
47
+ adjust 19.99, :usd, :continental_us, :two_day, :street
48
+ replace 29.99, :usd, :continental_us, :one_day, :street
49
+ end
50
+ expected = Nokogiri::XML::Builder.new do
51
+ Override {
52
+ SKU '987612345'
53
+ ShippingOverride {
54
+ ShipOption 'Std Cont US Street Addr'
55
+ IsShippingRestricted 'false'
56
+ }
57
+ ShippingOverride {
58
+ ShipOption 'Exp Cont US Street Addr'
59
+ IsShippingRestricted 'true'
60
+ }
61
+ ShippingOverride {
62
+ ShipOption 'Second'
63
+ Type 'Additive'
64
+ ShipAmount '19.99', currency: 'USD'
65
+ }
66
+ ShippingOverride {
67
+ ShipOption 'Next'
68
+ Type 'Exclusive'
69
+ ShipAmount '29.99', currency: 'USD'
70
+ }
71
+ }
72
+ end.doc.root.to_xml
73
+ shipping.to_xml.should == expected
74
+ end
75
+
76
+ end
77
+
78
+ end