mws-connect 0.0.1

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.
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