ecwid_api 0.0.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +8 -0
  3. data/README.md +123 -31
  4. data/ecwid_api.gemspec +10 -8
  5. data/lib/ecwid_api.rb +18 -29
  6. data/lib/ecwid_api/api.rb +12 -0
  7. data/lib/ecwid_api/api/base.rb +18 -0
  8. data/lib/ecwid_api/api/categories.rb +56 -0
  9. data/lib/ecwid_api/api/customers.rb +53 -0
  10. data/lib/ecwid_api/api/orders.rb +36 -0
  11. data/lib/ecwid_api/api/product_combinations.rb +48 -0
  12. data/lib/ecwid_api/api/product_types.rb +56 -0
  13. data/lib/ecwid_api/api/products.rb +148 -0
  14. data/lib/ecwid_api/category.rb +53 -4
  15. data/lib/ecwid_api/client.rb +65 -58
  16. data/lib/ecwid_api/customer.rb +10 -0
  17. data/lib/ecwid_api/entity.rb +151 -29
  18. data/lib/ecwid_api/error.rb +10 -0
  19. data/lib/ecwid_api/o_auth.rb +106 -0
  20. data/lib/ecwid_api/order.rb +118 -0
  21. data/lib/ecwid_api/order_item.rb +17 -0
  22. data/lib/ecwid_api/paged_ecwid_response.rb +57 -0
  23. data/lib/ecwid_api/paged_enumerator.rb +66 -0
  24. data/lib/ecwid_api/person.rb +7 -0
  25. data/lib/ecwid_api/product.rb +65 -0
  26. data/lib/ecwid_api/product_combination.rb +30 -0
  27. data/lib/ecwid_api/product_type.rb +18 -0
  28. data/lib/ecwid_api/product_type_attribute.rb +27 -0
  29. data/lib/ecwid_api/unpaged_ecwid_response.rb +38 -0
  30. data/lib/ecwid_api/version.rb +1 -1
  31. data/lib/ext/string.rb +9 -1
  32. data/spec/api/categories_spec.rb +31 -0
  33. data/spec/api/customers_spec.rb +20 -0
  34. data/spec/api/orders_spec.rb +30 -0
  35. data/spec/api/product_types_spec.rb +20 -0
  36. data/spec/api/products_spec.rb +20 -0
  37. data/spec/category_spec.rb +1 -6
  38. data/spec/client_spec.rb +4 -32
  39. data/spec/entity_spec.rb +120 -8
  40. data/spec/fixtures/categories.json +28 -22
  41. data/spec/fixtures/classes.json +44 -0
  42. data/spec/fixtures/customers.json +48 -0
  43. data/spec/fixtures/order.json +162 -0
  44. data/spec/fixtures/orders.json +303 -0
  45. data/spec/fixtures/products.json +141 -0
  46. data/spec/helpers/client.rb +34 -0
  47. data/spec/oauth_spec.rb +40 -0
  48. data/spec/order_item_spec.rb +12 -0
  49. data/spec/order_spec.rb +71 -0
  50. data/spec/paged_enumerator_spec.rb +38 -0
  51. data/spec/spec_helper.rb +3 -3
  52. metadata +93 -37
  53. data/lib/ecwid_api/category_api.rb +0 -62
  54. data/spec/category_api_spec.rb +0 -36
  55. data/spec/ecwid_api_spec.rb +0 -15
  56. data/spec/helpers/faraday.rb +0 -30
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe EcwidApi::Api::Products, faraday: true do
4
+ subject { client.products }
5
+
6
+ describe "#all" do
7
+ it "passes any other paramters through" do
8
+ expect(client).to receive(:get).with("products", hash_including(from_date: '1982-05-17'))
9
+ subject.all(from_date: '1982-05-17')
10
+ end
11
+
12
+ it "gets the proper response count (see fixture)" do
13
+ subject.all.count.should == 5
14
+ end
15
+
16
+ it "gets the proper product (see fixture)" do
17
+ subject.all.first.sku.should == "NC53090"
18
+ end
19
+ end
20
+ end
@@ -1,16 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe EcwidApi::Category, faraday: true do
4
- let(:client) { EcwidApi::Client.new { |config| config.store_id = '12345' } }
5
4
  subject { EcwidApi::Category.new({"id" => 123, "parentId" => 456}, client: client) }
6
5
 
7
- before(:each) do
8
- faraday_client(client)
9
- end
10
-
11
6
  describe "#sub_categories" do
12
7
  it "sends the request to the CategoryApi" do
13
- expect(client.categories).to receive(:all).with(123)
8
+ expect(client.categories).to receive(:all).with(parent: 123)
14
9
  subject.sub_categories
15
10
  end
16
11
 
@@ -1,41 +1,13 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe EcwidApi::Client do
4
- subject do
5
- EcwidApi::Client.new do |config|
6
- config.store_id = store_id
7
- end
8
- end
9
- let(:store_id) { 12345 }
10
-
11
- context "without a store_id" do
12
- it "raises an error" do
13
- expect { EcwidApi::Client.new }.to raise_error(EcwidApi::Error, /store_id/)
14
- end
15
- end
16
-
17
- describe "#url" do
18
- its(:url) { "http://app.ecwid.com/api/v1" }
19
-
20
- it "can be overridden" do
21
- client = EcwidApi::Client.new do |config|
22
- config.store_id = store_id
23
- config.url = "http://ladida.com"
24
- end
25
-
26
- client.url.should == "http://ladida.com"
27
- end
28
- end
4
+ subject { client }
29
5
 
30
6
  describe "#store_url" do
31
- its(:store_url) { "http://app.ecwid.com/api/v1/12345" }
7
+ it { is_expected.to have_attributes(store_url: "https://app.ecwid.com/api/v3/12345") }
32
8
  end
33
9
 
34
10
  describe "#get", faraday: true do
35
- before(:each) do
36
- faraday_client(subject)
37
- end
38
-
39
11
  it "delegates to the Faraday connection" do
40
12
  expect(subject.send(:connection)).to receive(:get).with("categories", parent: 1)
41
13
 
@@ -43,7 +15,7 @@ describe EcwidApi::Client do
43
15
  end
44
16
 
45
17
  it "returns a Faraday::Response" do
46
- subject.get("categories", parent: 1).is_a?(Faraday::Response).should be_true
18
+ expect(subject.get("categories", parent: 1)).to be_a(Faraday::Response)
47
19
  end
48
20
  end
49
- end
21
+ end
@@ -1,23 +1,135 @@
1
1
  require 'spec_helper'
2
2
 
3
+ class EntitySubject < EcwidApi::Entity
4
+ self.url_root = "stuff"
5
+
6
+ ecwid_reader :id, :parentId, :type, :modify, :override
7
+ ecwid_writer :writeOnly
8
+ ecwid_accessor :theStatus
9
+
10
+ def override
11
+ super.upcase
12
+ end
13
+ end
14
+
15
+ class EntityUrlSubject < EcwidApi::Entity
16
+ ecwid_reader :id, :parentId
17
+
18
+ self.url_root = -> { "parent/#{parent_id}/and" }
19
+ end
20
+
3
21
  describe EcwidApi::Entity do
4
- let(:data) { {"id" => 123, "parentId" => 456} }
22
+ let(:data) do
23
+ {
24
+ "id" => 123,
25
+ "parentId" => 456,
26
+ "type" => "AWESOME",
27
+ "theStatus" => "YOUNG",
28
+ "hidden" => "tee hee",
29
+ "writeOnly" => "write me!",
30
+ "override" => "upcase me"
31
+ }
32
+ end
33
+
34
+ subject { EntitySubject.new(data) }
35
+
36
+ describe "::url_root" do
37
+ it { is_expected.to have_attributes(url: "stuff/123") }
5
38
 
6
- subject { EcwidApi::Entity.new(data) }
39
+ context "with a proc" do
40
+ subject { EntityUrlSubject.new(data) }
41
+ it { is_expected.to have_attributes(url: "parent/456/and/123") }
42
+ end
43
+ end
7
44
 
8
45
  describe "#[]" do
9
46
  it "gets data with a symbol key" do
10
- subject[:id].should == 123
47
+ expect(subject[:id]).to eq 123
11
48
  end
12
49
 
13
50
  it "gets data with a string key" do
14
- subject["parentId"].should == 456
51
+ expect(subject["parentId"]).to eq 456
52
+ end
53
+
54
+ it "get nil for unknown data" do
55
+ expect(subject["whatever"]).to be_nil
56
+ end
57
+
58
+ it "gets attributes not revealed by ecwid_reader or ecwid_accessor" do
59
+ expect(subject["hidden"]).to eq "tee hee"
15
60
  end
16
61
  end
17
62
 
18
- describe "#method_missing" do
19
- it "gets data with snake_cased messages" do
20
- subject.parent_id.should == 456
63
+ describe "#==" do
64
+ context "with and without a client" do
65
+ let(:other) { EntitySubject.new(data, client: client) }
66
+
67
+ it "returns true" do
68
+ expect(subject).to eq(other)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "overrides" do
74
+ it { is_expected.to have_attributes(override: "UPCASE ME") }
75
+ end
76
+
77
+ describe "accessors" do
78
+ describe "::ecwid_reader" do
79
+ it "makes data accessible with a snake cased method" do
80
+ expect(subject.parent_id).to eq 456
81
+ end
82
+
83
+ it "doesn't have a writer" do
84
+ expect { subject.parent_id = 4 }.to raise_error(NoMethodError)
85
+ end
86
+ end
87
+
88
+ describe "::ecwid_writer" do
89
+ it "creates a writer method" do
90
+ subject.write_only = "yee haw!"
91
+ expect(subject["writeOnly"]).to eq "yee haw!"
92
+ end
93
+
94
+ it "doesn't have a reader" do
95
+ expect { subject.write_only }.to raise_error(NoMethodError)
96
+ end
97
+ end
98
+
99
+ describe "::ecwid_accessor" do
100
+ it "creates a reader and a writer" do
101
+ subject.the_status = "MATURE"
102
+ expect(subject.the_status).to eq "MATURE"
103
+ end
104
+ end
105
+
106
+ describe "without an accessor" do
107
+ it "is accessible with []" do
108
+ expect(subject[:hidden]).to eq "tee hee"
109
+ end
110
+
111
+ it "doesn't have an access method" do
112
+ expect { subject.hidden }.to raise_error(NoMethodError)
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "marshaling" do
118
+ context "with a client" do
119
+ subject { EntitySubject.new(data, client: client) }
120
+
121
+ describe "dump" do
122
+ it "does not raise" do
123
+ expect { Marshal.dump(subject) }.not_to raise_error
124
+ end
125
+ end
126
+
127
+ describe "load" do
128
+ it "converts a dumped object" do
129
+ source = Marshal.dump(subject)
130
+ expect(Marshal.load(source)).to eq(subject)
131
+ end
132
+ end
21
133
  end
22
134
  end
23
- end
135
+ end
@@ -1,22 +1,28 @@
1
- [
2
- {
3
- "id": 9389012,
4
- "name": "Bariatric Products",
5
- "url": "http://www.example.com#!/~/category/id=9389012",
6
- "productCount": 98
7
- },
8
- {
9
- "id": 9389013,
10
- "parentId": 9389012,
11
- "name": "Aids for Daily Living",
12
- "url": "http://www.example.com#!/~/category/id=9389013",
13
- "productCount": 72
14
- },
15
- {
16
- "id": 9389106,
17
- "parentId": 9389012,
18
- "name": "Mobility",
19
- "url": "http://www.example.com#!/~/category/id=9389106",
20
- "productCount": 12
21
- }
22
- ]
1
+ {
2
+ "total": 3,
3
+ "count": 3,
4
+ "limit": 100,
5
+ "offset": 0,
6
+ "items": [
7
+ {
8
+ "id": 9389012,
9
+ "name": "Bariatric Products",
10
+ "url": "http://www.example.com#!/~/category/id=9389012",
11
+ "productCount": 98
12
+ },
13
+ {
14
+ "id": 9389013,
15
+ "parentId": 9389012,
16
+ "name": "Aids for Daily Living",
17
+ "url": "http://www.example.com#!/~/category/id=9389013",
18
+ "productCount": 72
19
+ },
20
+ {
21
+ "id": 9389106,
22
+ "parentId": 9389012,
23
+ "name": "Mobility",
24
+ "url": "http://www.example.com#!/~/category/id=9389106",
25
+ "productCount": 12
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,44 @@
1
+ [
2
+ {
3
+ "id": 1,
4
+ "name": "Foo",
5
+ "googleTaxonomy": "This > That > Other > Foos",
6
+ "attributes": [{
7
+ "id": 111,
8
+ "name": "UPC",
9
+ "type": "UPC",
10
+ "show": "DESCR"
11
+ },
12
+ {
13
+ "id": 222,
14
+ "name": "Brand",
15
+ "type": "BRAND",
16
+ "show": "DESCR"
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "id": 2,
22
+ "name": "Bar",
23
+ "googleTaxonomy": "This > That > Other > Bars",
24
+ "attributes": [{
25
+ "id": 333,
26
+ "name": "UPC",
27
+ "type": "UPC",
28
+ "show": "DESCR"
29
+ },
30
+ {
31
+ "id": 444,
32
+ "name": "Brand",
33
+ "type": "BRAND",
34
+ "show": "DESCR"
35
+ },
36
+ {
37
+ "id": 555,
38
+ "name": "Blah",
39
+ "type": "BRAND",
40
+ "show": "NOTSHOW"
41
+ }
42
+ ]
43
+ }
44
+ ]
@@ -0,0 +1,48 @@
1
+ {
2
+ "total": 5,
3
+ "count": 5,
4
+ "offset": 0,
5
+ "limit": 100,
6
+ "items": [
7
+ {
8
+ "id": 1,
9
+ "name": "Abe Doe",
10
+ "email": "abe@example.com",
11
+ "totalOrderCount": 1,
12
+ "customerGroupId": 0,
13
+ "customerGroupName": "General"
14
+ },
15
+ {
16
+ "id": 2,
17
+ "name": "Bob Doe",
18
+ "email": "bob@example.com",
19
+ "totalOrderCount": 2,
20
+ "customerGroupId": 0,
21
+ "customerGroupName": "General"
22
+ },
23
+ {
24
+ "id": 3,
25
+ "name": "Chris Doe",
26
+ "email": "chris@example.com",
27
+ "totalOrderCount": 3,
28
+ "customerGroupId": 0,
29
+ "customerGroupName": "General"
30
+ },
31
+ {
32
+ "id": 4,
33
+ "name": "Debby Doe",
34
+ "email": "debby@example.com",
35
+ "totalOrderCount": 0,
36
+ "customerGroupId": 0,
37
+ "customerGroupName": "General"
38
+ },
39
+ {
40
+ "id": 5,
41
+ "name": "Ellen Doe",
42
+ "email": "ellen@example.com",
43
+ "totalOrderCount": 0,
44
+ "customerGroupId": 0,
45
+ "customerGroupName": "General"
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,162 @@
1
+ {
2
+ "vendorOrderNumber": "35",
3
+ "subtotal": 168.7,
4
+ "total": 181.35,
5
+ "email": "mbiehl@ncmedical.com",
6
+ "extTransactionId": "0",
7
+ "paymentModule": "Authorize.Net",
8
+ "paymentMethod": "Credit card",
9
+ "tax": 12.65,
10
+ "ticket": -495922403,
11
+ "ipAddress": "71.94.44.50",
12
+ "couponDiscount": 0,
13
+ "paymentStatus": "PAID",
14
+ "paymentMessage": "(TESTMODE) This transaction has been approved.",
15
+ "fulfillmentStatus": "AWAITING_PROCESSING",
16
+ "orderNumber": 35,
17
+ "refererUrl": "http://ecwid-tools.rubyex.ncmedical.com/",
18
+ "volumeDiscount": 0,
19
+ "customerId": 16497404,
20
+ "membershipBasedDiscount": 0,
21
+ "totalAndMembershipBasedDiscount": 0,
22
+ "discount": 0,
23
+ "usdTotal": 181.35,
24
+ "globalReferer": "http://ecwid-tools.rubyex.ncmedical.com/",
25
+ "createDate": "2014-11-05 12:53:30 -0800",
26
+ "updateDate": "2014-11-05 12:55:41 -0800",
27
+ "items": [
28
+ {
29
+ "id": 43440342,
30
+ "productId": 41269881,
31
+ "categoryId": 11025041,
32
+ "price": 22.95,
33
+ "productPrice": 22.95,
34
+ "sku": "NC50102",
35
+ "quantity": 2,
36
+ "shortDescription": "Economical burst-resistant balls provide versatile workouts for rehabilitation and exercise. Norco™ Exercise Balls are ...",
37
+ "tax": 3.44,
38
+ "shipping": 0,
39
+ "quantityInStock": 0,
40
+ "name": "Norco™ Exercise Balls",
41
+ "isShippingRequired": true,
42
+ "weight": 3.8335,
43
+ "trackQuantity": false,
44
+ "fixedShippingRateOnly": false,
45
+ "imageId": 250167929,
46
+ "fixedShippingRate": 0,
47
+ "digital": false,
48
+ "productAvailable": true,
49
+ "couponApplied": false,
50
+ "selectedOptions": [
51
+ {
52
+ "name": "Diameter",
53
+ "value": "65cm (25-1/2\") [Teal]",
54
+ "type": "CHOICE"
55
+ }
56
+ ],
57
+ "taxes": [
58
+ {
59
+ "name": "California Sales Tax",
60
+ "value": 7.5,
61
+ "total": 3.44
62
+ }
63
+ ]
64
+ },
65
+ {
66
+ "id": 43440343,
67
+ "productId": 41316480,
68
+ "categoryId": 11025041,
69
+ "price": 10.95,
70
+ "productPrice": 10.95,
71
+ "sku": "NC52080",
72
+ "quantity": 3,
73
+ "shortDescription": "Economical shoulder pulley that's great for home programs. The Norco™ Economy Shoulder Pulley is used to increase shou...",
74
+ "tax": 2.46,
75
+ "shipping": 0,
76
+ "quantityInStock": 0,
77
+ "name": "Norco™ Economy Shoulder Pulley",
78
+ "isShippingRequired": true,
79
+ "weight": 0.338,
80
+ "trackQuantity": false,
81
+ "fixedShippingRateOnly": false,
82
+ "imageId": 250188675,
83
+ "fixedShippingRate": 0,
84
+ "digital": false,
85
+ "productAvailable": true,
86
+ "couponApplied": false,
87
+ "taxes": [
88
+ {
89
+ "name": "California Sales Tax",
90
+ "value": 7.5,
91
+ "total": 2.46
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ "id": 43440344,
97
+ "productId": 41316623,
98
+ "categoryId": 11043406,
99
+ "price": 89.95,
100
+ "productPrice": 89.95,
101
+ "sku": "NC68700",
102
+ "quantity": 1,
103
+ "shortDescription": "Double swivel board promotes dynamic balance, core strength and proprioceptive awareness.  The Infinity™ 8-Board® har...",
104
+ "tax": 6.75,
105
+ "shipping": 0,
106
+ "quantityInStock": 0,
107
+ "name": "Infinity™ 8-Board®",
108
+ "isShippingRequired": true,
109
+ "weight": 3.5,
110
+ "trackQuantity": false,
111
+ "fixedShippingRateOnly": false,
112
+ "imageId": 250167423,
113
+ "fixedShippingRate": 0,
114
+ "digital": false,
115
+ "productAvailable": true,
116
+ "couponApplied": false,
117
+ "taxes": [
118
+ {
119
+ "name": "California Sales Tax",
120
+ "value": 7.5,
121
+ "total": 6.75
122
+ }
123
+ ]
124
+ }
125
+ ],
126
+ "billingPerson": {
127
+ "name": "Mark Consumer",
128
+ "companyName": "",
129
+ "street": "15305 Sycamore Drive",
130
+ "city": "Gilroy",
131
+ "countryCode": "US",
132
+ "countryName": "United States",
133
+ "postalCode": "95037",
134
+ "stateOrProvinceCode": "CA",
135
+ "stateOrProvinceName": "California",
136
+ "phone": "831-566-2310"
137
+ },
138
+ "shippingPerson": {
139
+ "name": "Mark Consumer",
140
+ "companyName": "",
141
+ "street": "15305 Sycamore Drive",
142
+ "city": "Gilroy",
143
+ "countryCode": "US",
144
+ "countryName": "United States",
145
+ "postalCode": "95037",
146
+ "stateOrProvinceCode": "CA",
147
+ "stateOrProvinceName": "California",
148
+ "phone": "831-566-2310"
149
+ },
150
+ "shippingOption": {
151
+ "shippingMethodName": "UPS Ground",
152
+ "shippingRate": 0,
153
+ "estimatedTransitTime": "1-3"
154
+ },
155
+ "additionalInfo": {
156
+ "Authorize.Net reason code": "1"
157
+ },
158
+ "paymentParams": {},
159
+ "creditCardStatus": {
160
+ "avsMessage": "AVS not applicable for this transaction"
161
+ }
162
+ }