veeqo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +629 -0
  6. data/.sample.pryrc +4 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +574 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +10 -0
  13. data/bin/rspec +17 -0
  14. data/bin/setup +8 -0
  15. data/lib/veeqo.rb +16 -0
  16. data/lib/veeqo/actions/base.rb +13 -0
  17. data/lib/veeqo/actions/delete.rb +11 -0
  18. data/lib/veeqo/actions/find.rb +11 -0
  19. data/lib/veeqo/actions/list.rb +11 -0
  20. data/lib/veeqo/allocation.rb +32 -0
  21. data/lib/veeqo/base.rb +26 -0
  22. data/lib/veeqo/company.rb +17 -0
  23. data/lib/veeqo/configuration.rb +17 -0
  24. data/lib/veeqo/customer.rb +24 -0
  25. data/lib/veeqo/delivery_method.rb +19 -0
  26. data/lib/veeqo/errors.rb +30 -0
  27. data/lib/veeqo/errors/forbidden.rb +9 -0
  28. data/lib/veeqo/errors/request_error.rb +15 -0
  29. data/lib/veeqo/errors/server_error.rb +9 -0
  30. data/lib/veeqo/errors/unauthorized.rb +9 -0
  31. data/lib/veeqo/order.rb +25 -0
  32. data/lib/veeqo/product.rb +25 -0
  33. data/lib/veeqo/purchase_order.rb +11 -0
  34. data/lib/veeqo/request.rb +89 -0
  35. data/lib/veeqo/response.rb +27 -0
  36. data/lib/veeqo/shipment.rb +30 -0
  37. data/lib/veeqo/store.rb +19 -0
  38. data/lib/veeqo/supplier.rb +19 -0
  39. data/lib/veeqo/version.rb +3 -0
  40. data/lib/veeqo/warehouse.rb +19 -0
  41. data/spec/fixtures/allocation_created.json +554 -0
  42. data/spec/fixtures/company.json +3 -0
  43. data/spec/fixtures/customer.json +4 -0
  44. data/spec/fixtures/customer_created.json +15 -0
  45. data/spec/fixtures/customers.json +38 -0
  46. data/spec/fixtures/delivery_method.json +3 -0
  47. data/spec/fixtures/delivery_method_created.json +4 -0
  48. data/spec/fixtures/delivery_methods.json +5 -0
  49. data/spec/fixtures/empty.json +0 -0
  50. data/spec/fixtures/order.json +3 -0
  51. data/spec/fixtures/order_created.json +554 -0
  52. data/spec/fixtures/orders.json +5 -0
  53. data/spec/fixtures/ping.json +3 -0
  54. data/spec/fixtures/product.json +4 -0
  55. data/spec/fixtures/product_created.json +137 -0
  56. data/spec/fixtures/products.json +5 -0
  57. data/spec/fixtures/purchase_orders.json +177 -0
  58. data/spec/fixtures/shipment_created.json +19 -0
  59. data/spec/fixtures/store.json +3 -0
  60. data/spec/fixtures/store_created.json +4 -0
  61. data/spec/fixtures/stores.json +5 -0
  62. data/spec/fixtures/supplier.json +3 -0
  63. data/spec/fixtures/supplier_created.json +4 -0
  64. data/spec/fixtures/suppliers.json +5 -0
  65. data/spec/fixtures/warehouse.json +3 -0
  66. data/spec/fixtures/warehouse_created.json +4 -0
  67. data/spec/fixtures/warehouses.json +5 -0
  68. data/spec/spec_helper.rb +15 -0
  69. data/spec/support/fake_veeqo_api.rb +408 -0
  70. data/spec/veeqo/actions/list_spec.rb +38 -0
  71. data/spec/veeqo/allocation_spec.rb +49 -0
  72. data/spec/veeqo/base_spec.rb +23 -0
  73. data/spec/veeqo/company_spec.rb +23 -0
  74. data/spec/veeqo/configuration_spec.rb +24 -0
  75. data/spec/veeqo/customer_spec.rb +77 -0
  76. data/spec/veeqo/delivery_method_spec.rb +65 -0
  77. data/spec/veeqo/order_spec.rb +93 -0
  78. data/spec/veeqo/product_spec.rb +82 -0
  79. data/spec/veeqo/purchase_order_spec.rb +14 -0
  80. data/spec/veeqo/request_spec.rb +40 -0
  81. data/spec/veeqo/shipment_spec.rb +38 -0
  82. data/spec/veeqo/store_spec.rb +61 -0
  83. data/spec/veeqo/supplier_spec.rb +61 -0
  84. data/spec/veeqo/warehouse_spec.rb +61 -0
  85. data/veeqo.gemspec +26 -0
  86. metadata +198 -0
@@ -0,0 +1,5 @@
1
+ [
2
+ {
3
+ "id": 123
4
+ }
5
+ ]
@@ -0,0 +1,3 @@
1
+ {
2
+ "data": "Pong!"
3
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": 123,
3
+ "title": "T-Shirt"
4
+ }
@@ -0,0 +1,137 @@
1
+ {
2
+ "active_channels": [],
3
+ "brand": null,
4
+ "channel_products": [],
5
+ "created_at": "2016-04-06T12:54:15Z",
6
+ "created_by_id": 1923,
7
+ "deleted_at": null,
8
+ "deleted_by_id": null,
9
+ "description": "",
10
+ "estimated_delivery": null,
11
+ "hs_tariff_number": null,
12
+ "id": 574316,
13
+ "image": null,
14
+ "inventory": {
15
+ "infinite": false
16
+ },
17
+ "main_image": null,
18
+ "main_image_src": null,
19
+ "notes": "",
20
+ "on_hand_value": 0,
21
+ "origin_country": null,
22
+ "product_tax_rate_id": null,
23
+ "sellables": [
24
+ {
25
+ "active_channels": [],
26
+ "allocated_stock_level_at_all_warehouses": 0,
27
+ "available_stock_level_at_all_warehouses": 0,
28
+ "channel_sellables": [],
29
+ "cost_price": 10,
30
+ "created_at": "2016-04-06T12:54:16Z",
31
+ "created_by_id": 1923,
32
+ "full_title": "T-Shirt Large",
33
+ "id": 1226620,
34
+ "images": [],
35
+ "inventory": {
36
+ "allocated_stock_level_at_all_warehouses": 0,
37
+ "available_stock_level_at_all_warehouses": 0,
38
+ "incoming_stock_level_at_all_warehouses": 0,
39
+ "infinite": false,
40
+ "physical_stock_level_at_all_warehouses": 0
41
+ },
42
+ "margin": 33.33,
43
+ "measurement_attributes": {
44
+ "depth": 0,
45
+ "dimensions_unit": "cm",
46
+ "height": 0,
47
+ "id": 622137,
48
+ "width": 0
49
+ },
50
+ "min_reorder_level": 0,
51
+ "model_number": "",
52
+ "on_hand_value": 0,
53
+ "price": 15,
54
+ "profit": 5,
55
+ "quantity_to_reorder": 0,
56
+ "sellable_title": "Large",
57
+ "sku_code": "t-shirt-large",
58
+ "stock_entries": [],
59
+ "stock_level_at_all_warehouses": 0,
60
+ "tax_rate": 0,
61
+ "title": "Large",
62
+ "total_quantity_sold": 0,
63
+ "type": "ProductVariant",
64
+ "upc_code": "",
65
+ "updated_at": "2016-04-06T12:54:16Z",
66
+ "variant_option_specifics": [],
67
+ "variant_property_specifics": [],
68
+ "weight": 0
69
+ },
70
+ {
71
+ "active_channels": [],
72
+ "allocated_stock_level_at_all_warehouses": 0,
73
+ "available_stock_level_at_all_warehouses": 0,
74
+ "channel_sellables": [],
75
+ "cost_price": 10,
76
+ "created_at": "2016-04-06T12:54:16Z",
77
+ "created_by_id": 1923,
78
+ "full_title": "T-Shirt Small",
79
+ "id": 1226621,
80
+ "images": [],
81
+ "inventory": {
82
+ "allocated_stock_level_at_all_warehouses": 0,
83
+ "available_stock_level_at_all_warehouses": 0,
84
+ "incoming_stock_level_at_all_warehouses": 0,
85
+ "infinite": false,
86
+ "physical_stock_level_at_all_warehouses": 0
87
+ },
88
+ "margin": 33.33,
89
+ "measurement_attributes": {
90
+ "depth": 0,
91
+ "dimensions_unit": "cm",
92
+ "height": 0,
93
+ "id": 622138,
94
+ "width": 0
95
+ },
96
+ "min_reorder_level": 0,
97
+ "model_number": "",
98
+ "on_hand_value": 0,
99
+ "price": 15,
100
+ "profit": 5,
101
+ "quantity_to_reorder": 0,
102
+ "sellable_title": "Small",
103
+ "sku_code": "t-shirt-small",
104
+ "stock_entries": [],
105
+ "stock_level_at_all_warehouses": 0,
106
+ "tax_rate": 0,
107
+ "title": "Small",
108
+ "total_quantity_sold": 0,
109
+ "type": "ProductVariant",
110
+ "upc_code": "",
111
+ "updated_at": "2016-04-06T12:54:16Z",
112
+ "variant_option_specifics": [],
113
+ "variant_property_specifics": [],
114
+ "weight": 0
115
+ }
116
+ ],
117
+ "stock_level_sync_status": {
118
+ "all_subordinate_entities_synced": null,
119
+ "last_change_at": null,
120
+ "last_sync_at": null
121
+ },
122
+ "tags": "",
123
+ "tax_rate": 0,
124
+ "title": "T-Shirt",
125
+ "total_allocated_stock_level": 0,
126
+ "total_available_stock_level": 0,
127
+ "total_quantity_sold": 0,
128
+ "total_stock_level": 0,
129
+ "updated_at": "2016-04-06T12:54:15Z",
130
+ "updated_by_id": null,
131
+ "web_meta_description": "",
132
+ "web_meta_keywords": "",
133
+ "web_meta_title": "",
134
+ "web_page_title": "",
135
+ "web_page_url": "",
136
+ "weight": 0
137
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ {
3
+ "id": 123
4
+ }
5
+ ]
@@ -0,0 +1,177 @@
1
+ [
2
+ {
3
+ "actual_delivery_days": null,
4
+ "actual_return_days": null,
5
+ "arrival_at_calc": null,
6
+ "completed_at": null,
7
+ "created_at": "2016-05-28T21:34:51Z",
8
+ "created_by_id": 1923,
9
+ "destination_warehouse_id": 1784,
10
+ "estimated_delivery_days": 1,
11
+ "estimated_return_days": null,
12
+ "id": 491,
13
+ "line_items": [
14
+ {
15
+ "cost": 10,
16
+ "id": 1575,
17
+ "product_variant": {
18
+ "active_channels": [],
19
+ "allocated_stock_level_at_all_warehouses": 1,
20
+ "available_stock_level_at_all_warehouses": 4,
21
+ "channel_sellables": [],
22
+ "cost_price": 0,
23
+ "created_at": "2016-03-21T11:42:56Z",
24
+ "created_by_id": 1923,
25
+ "full_title": "APPLE MAGIC MOUSE [TEST]",
26
+ "id": 1226617,
27
+ "images": [],
28
+ "inventory": {
29
+ "allocated_stock_level_at_all_warehouses": 1,
30
+ "available_stock_level_at_all_warehouses": 4,
31
+ "incoming_stock_level_at_all_warehouses": 0,
32
+ "infinite": false,
33
+ "physical_stock_level_at_all_warehouses": 5
34
+ },
35
+ "margin": 100,
36
+ "measurement_attributes": {
37
+ "depth": 0,
38
+ "dimensions_unit": "cm",
39
+ "height": 0,
40
+ "id": 622146,
41
+ "width": 0
42
+ },
43
+ "min_reorder_level": 5,
44
+ "model_number": "",
45
+ "on_hand_value": 0,
46
+ "price": 25.99,
47
+ "product": {
48
+ "description": "",
49
+ "estimated_delivery": null,
50
+ "hs_tariff_number": null,
51
+ "id": 574314,
52
+ "main_image": {
53
+ "binary_data": null,
54
+ "content_type": null,
55
+ "created_at": "2016-03-21T11:42:57Z",
56
+ "created_by_id": null,
57
+ "deleted_at": null,
58
+ "deleted_by_id": null,
59
+ "display_position": null,
60
+ "id": 795409,
61
+ "picture_content_type": null,
62
+ "picture_file_name": null,
63
+ "picture_file_size": null,
64
+ "picture_order": 9999,
65
+ "picture_updated_at": null,
66
+ "product_id": 574314,
67
+ "src": "https://veeqo-production-storage.s3.amazonaws.com/images/1943652/212ke3aqQ1L_original.jpg",
68
+ "updated_at": "2016-03-21T11:42:57Z",
69
+ "updated_by_id": null
70
+ },
71
+ "main_image_src": "https://veeqo-production-storage.s3.amazonaws.com/images/1943652/212ke3aqQ1L_original.jpg",
72
+ "origin_country": null,
73
+ "tax_rate": 0,
74
+ "title": "APPLE MAGIC MOUSE [TEST]",
75
+ "weight": 0
76
+ },
77
+ "product_title": "APPLE MAGIC MOUSE [TEST]",
78
+ "profit": 25.99,
79
+ "quantity_to_reorder": 0,
80
+ "sellable_title": "",
81
+ "sku_code": "MB829Z/A",
82
+ "stock_entries": [
83
+ {
84
+ "allocated_stock_level": 1,
85
+ "available_stock_level": 4,
86
+ "id": 1209224,
87
+ "incoming_stock_level": 0,
88
+ "infinite": false,
89
+ "location": null,
90
+ "physical_stock_level": 5,
91
+ "sellable_id": 1226617,
92
+ "sellable_on_hand_value": 0,
93
+ "stock_running_low": true,
94
+ "updated_at": "2016-03-21T11:42:58Z",
95
+ "warehouse": {
96
+ "address_line_1": "",
97
+ "address_line_2": "",
98
+ "city": "",
99
+ "click_and_collect_days": null,
100
+ "click_and_collect_enabled": false,
101
+ "country": null,
102
+ "created_at": "2016-03-21T11:42:55Z",
103
+ "created_by_id": 1923,
104
+ "default_min_reorder": 0,
105
+ "deleted_at": null,
106
+ "deleted_by_id": null,
107
+ "id": 1784,
108
+ "inventory_type_code": "wavg",
109
+ "name": "My Warehouse",
110
+ "phone": null,
111
+ "post_code": "",
112
+ "region": "",
113
+ "requested_carrier_account": null,
114
+ "updated_at": "2016-03-21T11:42:55Z",
115
+ "updated_by_id": null,
116
+ "user_id": null
117
+ },
118
+ "warehouse_id": 1784
119
+ }
120
+ ],
121
+ "stock_level_at_all_warehouses": 5,
122
+ "tax_rate": 0,
123
+ "title": "Default",
124
+ "total_quantity_sold": 1,
125
+ "type": "ProductVariant",
126
+ "upc_code": "",
127
+ "updated_at": "2016-04-26T17:30:12Z",
128
+ "variant_option_specifics": [],
129
+ "variant_property_specifics": [],
130
+ "weight": 0
131
+ },
132
+ "quantity": 1,
133
+ "received": null,
134
+ "received_at": null
135
+ }
136
+ ],
137
+ "number": "PO-0000001",
138
+ "received_at": null,
139
+ "returned_at": null,
140
+ "send_to_supplier": false,
141
+ "started_at": null,
142
+ "started_or_returned_at_calc": null,
143
+ "state": "pending",
144
+ "supplier": {
145
+ "accounting_contact_email": "",
146
+ "accounting_contact_name": "",
147
+ "accounting_phone_number": null,
148
+ "address_line_1": "",
149
+ "address_line_2": "",
150
+ "bank_account_number": null,
151
+ "bank_name": null,
152
+ "bank_sort_code": null,
153
+ "city": "",
154
+ "country": "",
155
+ "created_at": "2016-03-21T11:42:55Z",
156
+ "created_by_id": 1923,
157
+ "credit_limit": 0,
158
+ "currency_code": "gbp",
159
+ "deleted_at": null,
160
+ "deleted_by_id": null,
161
+ "id": 1748,
162
+ "name": "Default supplier",
163
+ "post_code": "",
164
+ "region": "",
165
+ "sales_contact_email": "",
166
+ "sales_contact_name": "",
167
+ "sales_phone_number": null,
168
+ "updated_at": "2016-03-21T11:42:55Z",
169
+ "updated_by_id": null
170
+ },
171
+ "supplier_id": 1748,
172
+ "total_calc": 10,
173
+ "updated_at": "2016-05-28T21:34:51Z",
174
+ "updated_by_id": null,
175
+ "user_id": 1923
176
+ }
177
+ ]
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": 3,
3
+ "created_at": "2016-11-14T15:05:35.709Z",
4
+ "allocation_id": 1,
5
+ "carrier_id": 3,
6
+ "shipped_by_id": 1402,
7
+ "weight": 20,
8
+ "notify_customer": false,
9
+ "update_remote_order": false,
10
+ "tracking_number": {
11
+ "id": 12618396,
12
+ "tracking_number": " 12345679ABC"
13
+ },
14
+ "order_id": 1,
15
+ "carrier": {
16
+ "id": 3,
17
+ "name": "Other"
18
+ }
19
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "Phone"
3
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": 123,
3
+ "name": "Phone"
4
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ {
3
+ "id": 123
4
+ }
5
+ ]
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "ACME"
3
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": 123,
3
+ "name": "ACME"
4
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ {
3
+ "id": 123
4
+ }
5
+ ]
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "My Warehouse"
3
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": 123,
3
+ "name": "My Warehouse"
4
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ {
3
+ "id": 123
4
+ }
5
+ ]
@@ -0,0 +1,15 @@
1
+ require "webmock/rspec"
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
+ require "veeqo"
4
+
5
+ Dir["./spec/support/**/*.rb"].sort.each { |file| require file }
6
+
7
+ RSpec.configure do |config|
8
+ config.before :suite do
9
+ Veeqo.configure do |veeqo_config|
10
+ veeqo_config.api_key = "SECRET_API_KEY"
11
+ end
12
+
13
+ config.include FakeVeeqoApi
14
+ end
15
+ end
@@ -0,0 +1,408 @@
1
+ require "uri"
2
+
3
+ module FakeVeeqoApi
4
+ def stub_veeqo_order_list_api(filters = nil)
5
+ stub_api_response(
6
+ :get,
7
+ "orders",
8
+ data: filters,
9
+ filename: "orders",
10
+ status: 200,
11
+ )
12
+ end
13
+
14
+ def stub_veeqo_order_find_api(order_id)
15
+ stub_api_response(
16
+ :get,
17
+ ["orders", order_id].join("/"),
18
+ filename: "order",
19
+ status: 200,
20
+ )
21
+ end
22
+
23
+ def stub_veeqo_order_create_api(order_attributes)
24
+ stub_api_response(
25
+ :post,
26
+ "orders",
27
+ status: 201,
28
+ filename: "order_created",
29
+ data: { "order": order_attributes },
30
+ )
31
+ end
32
+
33
+ def stub_veeqo_order_update_api(order_id, attributes)
34
+ stub_api_response(
35
+ :put,
36
+ ["orders", order_id].join("/"),
37
+ data: attributes,
38
+ filename: "empty",
39
+ status: 204,
40
+ )
41
+ end
42
+
43
+ def stub_veeqo_order_delete_api(order_id)
44
+ stub_api_response(
45
+ :delete,
46
+ ["orders", order_id].join("/"),
47
+ filename: "empty",
48
+ status: 204,
49
+ )
50
+ end
51
+
52
+ def stub_veeqo_product_list_api(filters = {})
53
+ stub_api_response(
54
+ :get,
55
+ "products",
56
+ data: filters,
57
+ filename: "products",
58
+ status: 200,
59
+ )
60
+ end
61
+
62
+ def stub_veeqo_product_find_api(product_id)
63
+ stub_api_response(
64
+ :get, ["products", product_id].join("/"), filename: "product", status: 200
65
+ )
66
+ end
67
+
68
+ def stub_veeqo_product_create_api(attributes)
69
+ attributes[:product_variants_attributes] = attributes.delete(:variants)
70
+ attributes[:images_attributes] = attributes.delete(:images)
71
+
72
+ stub_api_response(
73
+ :post,
74
+ "products",
75
+ data: { product: attributes },
76
+ filename: "product_created",
77
+ status: 201,
78
+ )
79
+ end
80
+
81
+ def stub_veeqo_product_update_api(product_id, new_attributes)
82
+ stub_api_response(
83
+ :put,
84
+ ["products", product_id].join("/"),
85
+ data: { product: new_attributes },
86
+ filename: "empty",
87
+ status: 204,
88
+ )
89
+ end
90
+
91
+ def stub_veeqo_product_delete_api(id)
92
+ stub_api_response(
93
+ :delete, ["products", id].join("/"), filename: "empty", status: 204
94
+ )
95
+ end
96
+
97
+ def stub_veeqo_purchase_order_list_api(filters = {})
98
+ stub_api_response(
99
+ :get,
100
+ "purchase_orders",
101
+ data: filters,
102
+ status: 200,
103
+ filename: "purchase_orders",
104
+ )
105
+ end
106
+
107
+ def stub_veeqo_supplier_list_api(filters = {})
108
+ stub_api_response(
109
+ :get,
110
+ "suppliers",
111
+ data: filters,
112
+ status: 200,
113
+ filename: "suppliers",
114
+ )
115
+ end
116
+
117
+ def stub_veeqo_supplier_create_api(attributes)
118
+ stub_api_response(
119
+ :post,
120
+ "suppliers",
121
+ data: attributes,
122
+ status: 201,
123
+ filename: "supplier_created",
124
+ )
125
+ end
126
+
127
+ def stub_veeqo_supplier_find_api(id)
128
+ stub_api_response(
129
+ :get, ["suppliers", id].join("/"), status: 200, filename: "supplier"
130
+ )
131
+ end
132
+
133
+ def stub_veeqo_supplier_update_api(id, attributes)
134
+ stub_api_response(
135
+ :put,
136
+ ["suppliers", id].join("/"),
137
+ data: attributes,
138
+ filename: "empty",
139
+ status: 204,
140
+ )
141
+ end
142
+
143
+ def stub_veeqo_supplier_delete_api(id)
144
+ stub_api_response(
145
+ :delete, ["suppliers", id].join("/"), status: 204, filename: "empty"
146
+ )
147
+ end
148
+
149
+ def stub_veeqo_company_find_api
150
+ stub_api_response(
151
+ :get, "current_company", status: 200, filename: "company"
152
+ )
153
+ end
154
+
155
+ def stub_veeqo_company_update_api(attributes)
156
+ stub_api_response(
157
+ :put, "current_company", data: attributes, filename: "empty", status: 204
158
+ )
159
+ end
160
+
161
+ def stub_veeqo_warehouse_list_api(filters = {})
162
+ stub_api_response(
163
+ :get, "warehouses", data: filters, status: 200, filename: "warehouses"
164
+ )
165
+ end
166
+
167
+ def stub_veeqo_warehouse_create_api(attributes)
168
+ stub_api_response(
169
+ :post,
170
+ "warehouses",
171
+ data: attributes,
172
+ status: 201,
173
+ filename: "warehouse_created",
174
+ )
175
+ end
176
+
177
+ def stub_veeqo_warehouse_find_api(id)
178
+ stub_api_response(
179
+ :get, ["warehouses", id].join("/"), filename: "warehouse", status: 200
180
+ )
181
+ end
182
+
183
+ def stub_veeqo_warehouse_update_api(id, attributes)
184
+ stub_api_response(
185
+ :put,
186
+ ["warehouses", id].join("/"),
187
+ data: attributes,
188
+ filename: "empty",
189
+ status: 204,
190
+ )
191
+ end
192
+
193
+ def stub_veeqo_warehouse_delete_api(id)
194
+ stub_api_response(
195
+ :delete, ["warehouses", id].join("/"), filename: "empty", status: 204
196
+ )
197
+ end
198
+
199
+ def stub_veeqo_customer_list_api(filters = {})
200
+ stub_api_response(
201
+ :get, "customers", data: filters, filename: "customers", status: 200
202
+ )
203
+ end
204
+
205
+ def stub_veeqo_customer_find_api(id)
206
+ stub_api_response(
207
+ :get, ["customers", id].join("/"), filename: "customer", status: 200
208
+ )
209
+ end
210
+
211
+ def stub_veeqo_customer_create_api(attributes)
212
+ stub_api_response(
213
+ :post,
214
+ "customers",
215
+ data: { customer: attributes },
216
+ filename: "customer_created",
217
+ status: 201,
218
+ )
219
+ end
220
+
221
+ def stub_veeqo_customer_update_api(id, attributes)
222
+ stub_api_response(
223
+ :put,
224
+ ["customers", id].join("/"),
225
+ data: { customer: attributes },
226
+ filename: "empty",
227
+ status: 204,
228
+ )
229
+ end
230
+
231
+ def stub_veeqo_customer_delete_api(id)
232
+ stub_api_response(
233
+ :delete, ["customers", id].join("/"), filename: "empty", status: 204
234
+ )
235
+ end
236
+
237
+ def stub_veeqo_store_list_api(filters = {})
238
+ stub_api_response(
239
+ :get, "channels", data: filters, filename: "stores", status: 200
240
+ )
241
+ end
242
+
243
+ def stub_veeqo_store_create_api(attributes)
244
+ stub_api_response(
245
+ :post,
246
+ "channels",
247
+ data: attributes,
248
+ filename: "store_created",
249
+ status: 201,
250
+ )
251
+ end
252
+
253
+ def stub_veeqo_store_find_api(id)
254
+ stub_api_response(
255
+ :get, ["channels", id].join("/"), filename: "store", status: 200
256
+ )
257
+ end
258
+
259
+ def stub_veeqo_store_update_api(id, attributes)
260
+ stub_api_response(
261
+ :put,
262
+ ["channels", id].join("/"),
263
+ data: attributes,
264
+ filename: "empty",
265
+ status: 204,
266
+ )
267
+ end
268
+
269
+ def stub_veeqo_store_delete_api(id)
270
+ stub_api_response(
271
+ :delete, ["channels", id].join("/"), filename: "empty", status: 204
272
+ )
273
+ end
274
+
275
+ def stub_veeqo_delivery_method_list_api(filters = {})
276
+ stub_api_response(
277
+ :get,
278
+ "delivery_methods",
279
+ data: filters,
280
+ filename: "delivery_methods",
281
+ status: 200,
282
+ )
283
+ end
284
+
285
+ def stub_veeqo_delivery_method_create_api(attributes)
286
+ stub_api_response(
287
+ :post,
288
+ "delivery_methods",
289
+ data: attributes,
290
+ filename: "delivery_method_created",
291
+ status: 201,
292
+ )
293
+ end
294
+
295
+ def stub_veeqo_delivery_method_find_api(id)
296
+ stub_api_response(
297
+ :get,
298
+ ["delivery_methods", id].join("/"),
299
+ filename: "delivery_method",
300
+ status: 200,
301
+ )
302
+ end
303
+
304
+ def stub_veeqo_delivery_method_update_api(id, attributes)
305
+ stub_api_response(
306
+ :put,
307
+ ["delivery_methods", id].join("/"),
308
+ data: attributes,
309
+ filename: "empty",
310
+ status: 204,
311
+ )
312
+ end
313
+
314
+ def stub_veeqo_delivery_method_delete_api(id)
315
+ stub_api_response(
316
+ :delete,
317
+ ["delivery_methods", id].join("/"),
318
+ filename: "empty",
319
+ status: 204,
320
+ )
321
+ end
322
+
323
+ def stub_veeqo_shipment_create_api(attributes)
324
+ attributes[:shipment][:tracking_number_attributes] = {
325
+ tracking_number: attributes[:shipment].delete(:tracking_number),
326
+ }
327
+
328
+ stub_api_response(
329
+ :post,
330
+ "shipments",
331
+ data: attributes,
332
+ filename: "shipment_created",
333
+ status: 201,
334
+ )
335
+ end
336
+
337
+ def stub_veeqo_shipment_delete_api(id)
338
+ stub_api_response(
339
+ :delete, ["shipments", id].join("/"), filename: "empty", status: 204
340
+ )
341
+ end
342
+
343
+ def stub_veeqo_allocation_create_api(order_id:, warehouse_id:, line_items:)
344
+ stub_api_response(
345
+ :post,
346
+ ["orders", order_id, "allocations"].join("/"),
347
+ data: { warehouse_id: warehouse_id, line_items_attributes: line_items },
348
+ filename: "allocation_created",
349
+ status: 201,
350
+ )
351
+ end
352
+
353
+ def stub_veeqo_allocation_update_api(id, order_id:, line_items:, **attrs)
354
+ stub_api_response(
355
+ :put,
356
+ ["orders", order_id, "allocations", id].compact.join("/"),
357
+ data: attrs.merge(line_items_attributes: line_items),
358
+ filename: "empty",
359
+ status: 204,
360
+ )
361
+ end
362
+
363
+ def stub_veeqo_allocation_delete_api(order_id, allocation_id)
364
+ stub_api_response(
365
+ :delete,
366
+ ["orders", order_id, "allocations", allocation_id].join("/"),
367
+ filename: "empty",
368
+ status: 204,
369
+ )
370
+ end
371
+
372
+ private
373
+
374
+ def stub_api_response(method, end_point, filename:, status:, data: nil)
375
+ stub_request(method, api_end_point(end_point)).
376
+ with(api_request_headers(data: data)).
377
+ to_return(response_with(filename: filename, status: status))
378
+ end
379
+
380
+ def api_end_point(end_point)
381
+ URI::HTTPS.build(host: Veeqo.configuration.api_host, path: "/#{end_point}")
382
+ end
383
+
384
+ def api_request_headers(data:)
385
+ Hash.new.tap do |request_headers|
386
+ request_headers[:headers] = api_key_header
387
+
388
+ unless data.nil?
389
+ request_headers[:body] = data.to_json
390
+ end
391
+ end
392
+ end
393
+
394
+ def api_key_header
395
+ { "x-api-key" => Veeqo.configuration.api_key }
396
+ end
397
+
398
+ def response_with(filename:, status:)
399
+ { body: veeqo_fixture(filename), status: status }
400
+ end
401
+
402
+ def veeqo_fixture(filename)
403
+ file_name = [filename, "json"].join(".")
404
+ file_path = ["../../", "fixtures", file_name].join("/")
405
+
406
+ File.read(File.expand_path(file_path, __FILE__))
407
+ end
408
+ end