veeqo 0.1.0

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