shopify_api 9.2.0 → 9.5

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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/ISSUE_TEMPLATE.md +36 -0
  4. data/.github/workflows/build.yml +44 -0
  5. data/.gitignore +0 -1
  6. data/.rubocop.yml +23 -3
  7. data/.rubocop_todo.yml +75 -0
  8. data/CHANGELOG.md +29 -0
  9. data/Gemfile +1 -0
  10. data/Gemfile.lock +153 -0
  11. data/Gemfile_ar51 +1 -1
  12. data/README.md +41 -31
  13. data/RELEASING +10 -6
  14. data/Rakefile +10 -6
  15. data/dev.yml +11 -0
  16. data/docs/graphql.md +1 -1
  17. data/docs/index.md +1 -1
  18. data/lib/active_resource/connection_ext.rb +1 -0
  19. data/lib/active_resource/detailed_log_subscriber.rb +10 -7
  20. data/lib/active_resource/json_errors.rb +8 -2
  21. data/lib/shopify_api/api_access.rb +57 -0
  22. data/lib/shopify_api/api_version.rb +6 -5
  23. data/lib/shopify_api/connection.rb +1 -0
  24. data/lib/shopify_api/countable.rb +3 -2
  25. data/lib/shopify_api/disable_prefix_check.rb +2 -2
  26. data/lib/shopify_api/events.rb +2 -1
  27. data/lib/shopify_api/graphql.rb +8 -6
  28. data/lib/shopify_api/hmac_params.rb +23 -0
  29. data/lib/shopify_api/limits.rb +3 -2
  30. data/lib/shopify_api/message_enricher.rb +11 -9
  31. data/lib/shopify_api/meta.rb +0 -1
  32. data/lib/shopify_api/metafields.rb +5 -4
  33. data/lib/shopify_api/pagination_link_headers.rb +4 -3
  34. data/lib/shopify_api/resources/access_scope.rb +1 -1
  35. data/lib/shopify_api/resources/access_token.rb +1 -0
  36. data/lib/shopify_api/resources/address.rb +1 -0
  37. data/lib/shopify_api/resources/announcement.rb +2 -1
  38. data/lib/shopify_api/resources/application_charge.rb +1 -0
  39. data/lib/shopify_api/resources/application_credit.rb +1 -0
  40. data/lib/shopify_api/resources/article.rb +3 -2
  41. data/lib/shopify_api/resources/asset.rb +6 -5
  42. data/lib/shopify_api/resources/assigned_fulfillment_order.rb +1 -1
  43. data/lib/shopify_api/resources/base.rb +11 -6
  44. data/lib/shopify_api/resources/billing_address.rb +1 -0
  45. data/lib/shopify_api/resources/blog.rb +2 -1
  46. data/lib/shopify_api/resources/carrier_service.rb +1 -0
  47. data/lib/shopify_api/resources/cart.rb +2 -1
  48. data/lib/shopify_api/resources/collect.rb +1 -0
  49. data/lib/shopify_api/resources/collection_listing.rb +1 -0
  50. data/lib/shopify_api/resources/comment.rb +20 -5
  51. data/lib/shopify_api/resources/country.rb +1 -0
  52. data/lib/shopify_api/resources/custom_collection.rb +4 -3
  53. data/lib/shopify_api/resources/customer.rb +2 -1
  54. data/lib/shopify_api/resources/customer_group.rb +1 -0
  55. data/lib/shopify_api/resources/customer_invite.rb +1 -0
  56. data/lib/shopify_api/resources/customer_saved_search.rb +2 -1
  57. data/lib/shopify_api/resources/discount_code.rb +1 -0
  58. data/lib/shopify_api/resources/discount_code_batch.rb +4 -2
  59. data/lib/shopify_api/resources/draft_order.rb +1 -0
  60. data/lib/shopify_api/resources/draft_order_invoice.rb +1 -0
  61. data/lib/shopify_api/resources/event.rb +1 -0
  62. data/lib/shopify_api/resources/fulfillment.rb +12 -3
  63. data/lib/shopify_api/resources/fulfillment_event.rb +1 -0
  64. data/lib/shopify_api/resources/fulfillment_order.rb +30 -16
  65. data/lib/shopify_api/resources/fulfillment_order_locations_for_move.rb +1 -0
  66. data/lib/shopify_api/resources/fulfillment_request.rb +1 -0
  67. data/lib/shopify_api/resources/fulfillment_service.rb +1 -0
  68. data/lib/shopify_api/resources/fulfillment_v2.rb +3 -2
  69. data/lib/shopify_api/resources/gift_card.rb +1 -0
  70. data/lib/shopify_api/resources/image.rb +2 -1
  71. data/lib/shopify_api/resources/inventory_level.rb +2 -3
  72. data/lib/shopify_api/resources/line_item.rb +4 -3
  73. data/lib/shopify_api/resources/location.rb +1 -1
  74. data/lib/shopify_api/resources/marketing_event.rb +1 -0
  75. data/lib/shopify_api/resources/metafield.rb +1 -0
  76. data/lib/shopify_api/resources/note_attribute.rb +1 -0
  77. data/lib/shopify_api/resources/option.rb +1 -0
  78. data/lib/shopify_api/resources/order.rb +2 -1
  79. data/lib/shopify_api/resources/order_risk.rb +1 -0
  80. data/lib/shopify_api/resources/page.rb +1 -0
  81. data/lib/shopify_api/resources/payment_details.rb +1 -0
  82. data/lib/shopify_api/resources/policy.rb +1 -0
  83. data/lib/shopify_api/resources/price_rule.rb +1 -1
  84. data/lib/shopify_api/resources/product.rb +14 -11
  85. data/lib/shopify_api/resources/product_listing.rb +1 -0
  86. data/lib/shopify_api/resources/province.rb +1 -0
  87. data/lib/shopify_api/resources/receipt.rb +1 -0
  88. data/lib/shopify_api/resources/recurring_application_charge.rb +4 -1
  89. data/lib/shopify_api/resources/redirect.rb +1 -0
  90. data/lib/shopify_api/resources/refund.rb +2 -1
  91. data/lib/shopify_api/resources/report.rb +1 -0
  92. data/lib/shopify_api/resources/resource_feedback.rb +1 -1
  93. data/lib/shopify_api/resources/rule.rb +1 -0
  94. data/lib/shopify_api/resources/script_tag.rb +1 -0
  95. data/lib/shopify_api/resources/shipping_address.rb +1 -0
  96. data/lib/shopify_api/resources/shipping_line.rb +1 -0
  97. data/lib/shopify_api/resources/shipping_zone.rb +1 -0
  98. data/lib/shopify_api/resources/shop.rb +2 -1
  99. data/lib/shopify_api/resources/smart_collection.rb +2 -2
  100. data/lib/shopify_api/resources/storefront_access_token.rb +1 -0
  101. data/lib/shopify_api/resources/tax_line.rb +1 -0
  102. data/lib/shopify_api/resources/tax_service.rb +1 -0
  103. data/lib/shopify_api/resources/theme.rb +1 -0
  104. data/lib/shopify_api/resources/transaction.rb +1 -0
  105. data/lib/shopify_api/resources/usage_charge.rb +1 -0
  106. data/lib/shopify_api/resources/user.rb +1 -0
  107. data/lib/shopify_api/resources/variant.rb +16 -18
  108. data/lib/shopify_api/resources/webhook.rb +1 -0
  109. data/lib/shopify_api/resources.rb +1 -0
  110. data/lib/shopify_api/session.rb +29 -19
  111. data/lib/shopify_api/version.rb +2 -1
  112. data/lib/shopify_api.rb +9 -1
  113. data/lib/verify_docs.rb +1 -0
  114. data/service.yml +2 -5
  115. data/shopify_api.gemspec +12 -5
  116. data/test/access_token_test.rb +6 -5
  117. data/test/active_resource/json_errors_test.rb +6 -6
  118. data/test/api_access_test.rb +153 -0
  119. data/test/api_version_test.rb +3 -3
  120. data/test/application_charge_test.rb +30 -27
  121. data/test/application_credit_test.rb +10 -9
  122. data/test/article_test.rb +34 -35
  123. data/test/asset_test.rb +14 -6
  124. data/test/assigned_fulfillment_order_test.rb +5 -4
  125. data/test/base_test.rb +55 -56
  126. data/test/blog_test.rb +4 -3
  127. data/test/carrier_service_test.rb +7 -6
  128. data/test/cart_test.rb +2 -1
  129. data/test/collect_test.rb +4 -3
  130. data/test/collection_listing_test.rb +21 -16
  131. data/test/collection_publication_test.rb +8 -8
  132. data/test/collection_test.rb +20 -19
  133. data/test/countable_test.rb +3 -2
  134. data/test/currency_test.rb +5 -5
  135. data/test/custom_collection_test.rb +4 -3
  136. data/test/customer_saved_search_test.rb +18 -8
  137. data/test/customer_test.rb +22 -14
  138. data/test/detailed_log_subscriber_test.rb +16 -12
  139. data/test/discount_code_batch_test.rb +11 -10
  140. data/test/discount_code_test.rb +21 -15
  141. data/test/draft_order_test.rb +68 -52
  142. data/test/fixtures/assigned_fulfillment_orders.json +2 -0
  143. data/test/fixtures/fulfillment_order.json +1 -0
  144. data/test/fixtures/fulfillment_orders.json +2 -0
  145. data/test/fulfillment_event_test.rb +31 -26
  146. data/test/fulfillment_order_test.rb +217 -149
  147. data/test/fulfillment_order_test_helper.rb +1 -0
  148. data/test/fulfillment_request_test.rb +10 -8
  149. data/test/fulfillment_service_test.rb +13 -12
  150. data/test/fulfillment_test.rb +81 -66
  151. data/test/fulfillment_v2_test.rb +16 -12
  152. data/test/gift_card_test.rb +6 -4
  153. data/test/graphql_test.rb +27 -27
  154. data/test/hmac_params_test.rb +25 -0
  155. data/test/image_test.rb +19 -17
  156. data/test/inventory_level_test.rb +24 -15
  157. data/test/lib/webmock_extensions/last_request.rb +1 -1
  158. data/test/limits_test.rb +2 -1
  159. data/test/location_test.rb +2 -1
  160. data/test/marketing_event_test.rb +20 -20
  161. data/test/message_enricher_test.rb +6 -6
  162. data/test/meta_test.rb +9 -11
  163. data/test/metafield_test.rb +30 -20
  164. data/test/order_risk_test.rb +17 -16
  165. data/test/order_test.rb +43 -28
  166. data/test/pagination_test.rb +89 -56
  167. data/test/policy_test.rb +6 -5
  168. data/test/price_rule_test.rb +20 -15
  169. data/test/product_listing_test.rb +20 -20
  170. data/test/product_publication_test.rb +8 -8
  171. data/test/product_test.rb +44 -32
  172. data/test/publication_test.rb +3 -3
  173. data/test/recurring_application_charge_test.rb +104 -42
  174. data/test/redirect_test.rb +4 -3
  175. data/test/refund_test.rb +22 -17
  176. data/test/report_test.rb +12 -10
  177. data/test/resource_feedback_test.rb +14 -13
  178. data/test/script_tag_test.rb +10 -9
  179. data/test/session_test.rb +159 -48
  180. data/test/shipping_zone_test.rb +4 -3
  181. data/test/shop_test.rb +47 -33
  182. data/test/smart_collection_test.rb +5 -4
  183. data/test/storefront_access_token_test.rb +13 -15
  184. data/test/tax_service_test.rb +7 -4
  185. data/test/tender_transaction_test.rb +3 -3
  186. data/test/test_helper.rb +13 -11
  187. data/test/transaction_test.rb +4 -3
  188. data/test/usage_charge_test.rb +12 -8
  189. data/test/user_test.rb +4 -3
  190. data/test/variant_test.rb +23 -54
  191. data/test/webhook_test.rb +10 -7
  192. metadata +34 -12
  193. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
  194. data/.travis.yml +0 -28
data/test/session_test.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
  require 'timecop'
3
4
 
4
5
  class SessionTest < Test::Unit::TestCase
6
+ SECONDS_IN_A_DAY = 24 * 60 * 60
5
7
 
6
8
  def setup
7
9
  super
@@ -10,33 +12,37 @@ class SessionTest < Test::Unit::TestCase
10
12
 
11
13
  test "not be valid without a url" do
12
14
  session = ShopifyAPI::Session.new(domain: nil, token: "any-token", api_version: any_api_version)
13
- assert_not session.valid?
15
+ assert_not(session.valid?)
14
16
  end
15
17
 
16
18
  test "not be valid without token" do
17
19
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
18
- assert_not session.valid?
20
+ assert_not(session.valid?)
19
21
  end
20
22
 
21
23
  test "not be valid without an API version" do
22
24
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: nil)
23
- assert_not session.valid?
25
+ assert_not(session.valid?)
24
26
 
25
- session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: ShopifyAPI::ApiVersion::NullVersion)
26
- assert_not session.valid?
27
+ session = ShopifyAPI::Session.new(
28
+ domain: "testshop.myshopify.com", token: "any-token", api_version: ShopifyAPI::ApiVersion::NullVersion
29
+ )
30
+ assert_not(session.valid?)
27
31
  end
28
32
 
29
33
  test "default to base API version" do
30
34
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token")
31
- assert session.valid?
32
- assert_equal session.api_version, ShopifyAPI::Base.api_version
35
+ assert(session.valid?)
36
+ assert_equal(session.api_version, ShopifyAPI::Base.api_version)
33
37
  end
34
38
 
35
39
  test "can override the base API version" do
36
40
  different_api_version = '2020-01'
37
- session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: different_api_version)
38
- assert session.valid?
39
- assert_equal session.api_version, ShopifyAPI::ApiVersion.find_version(different_api_version)
41
+ session = ShopifyAPI::Session.new(
42
+ domain: "testshop.myshopify.com", token: "any-token", api_version: different_api_version
43
+ )
44
+ assert(session.valid?)
45
+ assert_equal(session.api_version, ShopifyAPI::ApiVersion.find_version(different_api_version))
40
46
  end
41
47
 
42
48
  test "be valid with any token, any url and version" do
@@ -45,7 +51,40 @@ class SessionTest < Test::Unit::TestCase
45
51
  token: "any-token",
46
52
  api_version: any_api_version
47
53
  )
48
- assert session.valid?
54
+ assert(session.valid?)
55
+ end
56
+
57
+ test "be valid with nil access_scopes" do
58
+ session = ShopifyAPI::Session.new(
59
+ domain: "testshop.myshopify.com",
60
+ token: "any-token",
61
+ api_version: any_api_version,
62
+ access_scopes: nil
63
+ )
64
+
65
+ assert(session.valid?)
66
+ end
67
+
68
+ test "be valid with string of access_scopes" do
69
+ session = ShopifyAPI::Session.new(
70
+ domain: "testshop.myshopify.com",
71
+ token: "any-token",
72
+ api_version: any_api_version,
73
+ access_scopes: "read_products, write_orders"
74
+ )
75
+
76
+ assert(session.valid?)
77
+ end
78
+
79
+ test "be valid with a collection of access_scopes" do
80
+ session = ShopifyAPI::Session.new(
81
+ domain: "testshop.myshopify.com",
82
+ token: "any-token",
83
+ api_version: any_api_version,
84
+ access_scopes: %w(read_products write_orders)
85
+ )
86
+
87
+ assert(session.valid?)
49
88
  end
50
89
 
51
90
  test "not raise error without params" do
@@ -55,7 +94,7 @@ class SessionTest < Test::Unit::TestCase
55
94
  end
56
95
 
57
96
  test "ignore everything but the subdomain in the shop" do
58
- assert_equal(
97
+ assert_equal_uri(
59
98
  "https://testshop.myshopify.com",
60
99
  ShopifyAPI::Session.new(
61
100
  domain: "http://user:pass@testshop.notshopify.net/path",
@@ -66,7 +105,7 @@ class SessionTest < Test::Unit::TestCase
66
105
  end
67
106
 
68
107
  test "append the myshopify domain if not given" do
69
- assert_equal(
108
+ assert_equal_uri(
70
109
  "https://testshop.myshopify.com",
71
110
  ShopifyAPI::Session.new(domain: "testshop", token: "any-token", api_version: any_api_version).site
72
111
  )
@@ -78,17 +117,47 @@ class SessionTest < Test::Unit::TestCase
78
117
  end
79
118
  end
80
119
 
120
+ test "provides default nil access_scopes attribute" do
121
+ session = ShopifyAPI::Session.new(
122
+ domain: "testshop.myshopify.com",
123
+ token: "any-token",
124
+ api_version: any_api_version
125
+ )
126
+ assert_nil session.access_scopes
127
+ end
128
+
129
+ test "provides specified nil access_scopes attribute" do
130
+ session = ShopifyAPI::Session.new(
131
+ domain: "testshop.myshopify.com",
132
+ token: "any-token",
133
+ access_scopes: "read_products",
134
+ api_version: any_api_version
135
+ )
136
+ assert_equal "read_products", session.access_scopes.to_s
137
+ end
138
+
139
+ test "session instantiation raises error if bad access scopes are provided" do
140
+ assert_raises NoMethodError do
141
+ ShopifyAPI::Session.new(
142
+ domain: "testshop.myshopify.com",
143
+ token: "any-token",
144
+ access_scopes: { bad_input: "bad_input" },
145
+ api_version: any_api_version
146
+ )
147
+ end
148
+ end
149
+
81
150
  test "raise error if params passed but signature omitted" do
82
151
  assert_raises(ShopifyAPI::ValidationException) do
83
152
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
84
- session.request_token({'code' => 'any-code'})
153
+ session.request_token({ 'code' => 'any-code' })
85
154
  end
86
155
  end
87
156
 
88
157
  test "setup api_key and secret for all sessions" do
89
- ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
90
- assert_equal "My test key", ShopifyAPI::Session.api_key
91
- assert_equal "My test secret", ShopifyAPI::Session.secret
158
+ ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
159
+ assert_equal("My test key", ShopifyAPI::Session.api_key)
160
+ assert_equal("My test secret", ShopifyAPI::Session.secret)
92
161
  end
93
162
 
94
163
  test "#temp reset ShopifyAPI::Base values to original value" do
@@ -168,7 +237,7 @@ class SessionTest < Test::Unit::TestCase
168
237
  api_version: :unstable
169
238
  )
170
239
 
171
- assert_raises StandardError do
240
+ assert_raises(StandardError) do
172
241
  ShopifyAPI::Session.with_session(other_session) { raise StandardError, "" }
173
242
  end
174
243
 
@@ -214,7 +283,11 @@ class SessionTest < Test::Unit::TestCase
214
283
  )
215
284
  scope = ["write_products"]
216
285
  permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
217
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products&redirect_uri=http://my_redirect_uri.com", permission_url
286
+ assert_equal_uri(
287
+ "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
288
+ "scope=write_products&redirect_uri=http://my_redirect_uri.com",
289
+ permission_url
290
+ )
218
291
  end
219
292
 
220
293
  test "create_permission_url returns correct url with dual scope" do
@@ -224,9 +297,13 @@ class SessionTest < Test::Unit::TestCase
224
297
  token: 'any-token',
225
298
  api_version: any_api_version
226
299
  )
227
- scope = ["write_products","write_customers"]
300
+ scope = ["write_products", "write_customers"]
228
301
  permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
229
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products,write_customers&redirect_uri=http://my_redirect_uri.com", permission_url
302
+ assert_equal_uri(
303
+ "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
304
+ "scope=write_products,write_customers&redirect_uri=http://my_redirect_uri.com",
305
+ permission_url
306
+ )
230
307
  end
231
308
 
232
309
  test "create_permission_url returns correct url with no scope" do
@@ -238,7 +315,11 @@ class SessionTest < Test::Unit::TestCase
238
315
  )
239
316
  scope = []
240
317
  permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
241
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=&redirect_uri=http://my_redirect_uri.com", permission_url
318
+ assert_equal_uri(
319
+ "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
320
+ "scope=&redirect_uri=http://my_redirect_uri.com",
321
+ permission_url
322
+ )
242
323
  end
243
324
 
244
325
  test "create_permission_url returns correct url with state" do
@@ -250,11 +331,31 @@ class SessionTest < Test::Unit::TestCase
250
331
  )
251
332
  scope = []
252
333
  permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", state: "My nonce")
253
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=&redirect_uri=http://my_redirect_uri.com&state=My%20nonce", permission_url
334
+ assert_equal_uri(
335
+ "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
336
+ "scope=&redirect_uri=http://my_redirect_uri.com&state=My+nonce",
337
+ permission_url
338
+ )
339
+ end
340
+
341
+ test "create_permission_url returns correct url with grant_options[]" do
342
+ ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
343
+ session = ShopifyAPI::Session.new(
344
+ domain: 'http://localhost.myshopify.com',
345
+ token: 'any-token',
346
+ api_version: any_api_version
347
+ )
348
+ scope = []
349
+ permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", grant_options: "per-user")
350
+ assert_equal_uri(
351
+ "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
352
+ "scope=&redirect_uri=http://my_redirect_uri.com&grant_options[]=per-user",
353
+ permission_url
354
+ )
254
355
  end
255
356
 
256
357
  test "raise exception if code invalid in request token" do
257
- ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
358
+ ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
258
359
  session = ShopifyAPI::Session.new(
259
360
  domain: 'http://localhost.myshopify.com',
260
361
  token: nil,
@@ -270,7 +371,7 @@ class SessionTest < Test::Unit::TestCase
270
371
  assert_raises(ShopifyAPI::ValidationException) do
271
372
  session.request_token(code: "bad-code")
272
373
  end
273
- assert_equal false, session.valid?
374
+ assert_equal(false, session.valid?)
274
375
  end
275
376
 
276
377
  test "return site for session" do
@@ -279,87 +380,93 @@ class SessionTest < Test::Unit::TestCase
279
380
  token: "any-token",
280
381
  api_version: any_api_version
281
382
  )
282
- assert_equal "https://testshop.myshopify.com", session.site
383
+ assert_equal_uri("https://testshop.myshopify.com", session.site)
283
384
  end
284
385
 
285
386
  test "return_token_if_signature_is_valid" do
286
387
  api_version = any_api_version
287
- fake nil,
388
+ fake(
389
+ nil,
288
390
  url: "https://testshop.myshopify.com/admin/oauth/access_token",
289
391
  method: :post,
290
392
  body: '{"access_token":"any-token"}'
393
+ )
291
394
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
292
395
 
293
396
  params = { code: 'any-code', timestamp: Time.now }
294
397
  token = session.request_token(params.merge(hmac: generate_signature(params)))
295
398
 
296
- assert_equal "any-token", token
297
- assert_equal "any-token", session.token
399
+ assert_equal("any-token", token)
400
+ assert_equal("any-token", session.token)
298
401
  end
299
402
 
300
403
  test "extra parameters are stored in session" do
301
404
  api_version = ShopifyAPI::ApiVersion.new(handle: :unstable)
302
- fake nil,
405
+ fake(
406
+ nil,
303
407
  url: "https://testshop.myshopify.com/admin/oauth/access_token",
304
408
  method: :post,
305
409
  body: '{"access_token":"any-token","foo":"example"}'
410
+ )
306
411
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
307
412
 
308
413
  params = { code: 'any-code', timestamp: Time.now }
309
- assert session.request_token(params.merge(hmac: generate_signature(params)))
414
+ assert(session.request_token(params.merge(hmac: generate_signature(params))))
310
415
 
311
- assert_equal ({ "foo" => "example" }), session.extra
416
+ assert_equal({ "foo" => "example" }, session.extra)
312
417
  end
313
418
 
314
419
  test "expires_in is automatically converted in expires_at" do
315
420
  api_version = any_api_version
316
- fake nil,
421
+ fake(
422
+ nil,
317
423
  url: "https://testshop.myshopify.com/admin/oauth/access_token",
318
424
  method: :post,
319
425
  body: '{"access_token":"any-token","expires_in":86393}'
426
+ )
320
427
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
321
428
 
322
429
  Timecop.freeze do
323
430
  params = { code: 'any-code', timestamp: Time.now }
324
- assert session.request_token(params.merge(hmac: generate_signature(params)))
431
+ assert(session.request_token(params.merge(hmac: generate_signature(params))))
325
432
 
326
433
  expires_at = Time.now.utc + 86393
327
- assert_equal ({ "expires_at" => expires_at.to_i }), session.extra
328
- assert session.expires_at.is_a?(Time)
329
- assert_equal expires_at.to_i, session.expires_at.to_i
330
- assert_equal 86393, session.expires_in
331
- assert_equal false, session.expired?
434
+ assert_equal({ "expires_at" => expires_at.to_i }, session.extra)
435
+ assert(session.expires_at.is_a?(Time))
436
+ assert_equal(expires_at.to_i, session.expires_at.to_i)
437
+ assert_equal(86393, session.expires_in)
438
+ assert_equal(false, session.expired?)
332
439
 
333
440
  Timecop.travel(session.expires_at) do
334
- assert_equal true, session.expired?
441
+ assert_equal(true, session.expired?)
335
442
  end
336
443
  end
337
444
  end
338
445
 
339
446
  test "raise error if signature does not match expected" do
340
- params = {:code => "any-code", :timestamp => Time.now}
447
+ params = { code: "any-code", timestamp: Time.now }
341
448
  signature = generate_signature(params)
342
449
  params[:foo] = 'world'
343
450
  assert_raises(ShopifyAPI::ValidationException) do
344
451
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
345
- session.request_token(params.merge(:hmac => signature))
452
+ session.request_token(params.merge(hmac: signature))
346
453
  end
347
454
  end
348
455
 
349
456
  test "raise error if timestamp is too old" do
350
- params = {:code => "any-code", :timestamp => Time.now - 2.days}
457
+ params = { code: "any-code", timestamp: Time.now - 2 * SECONDS_IN_A_DAY }
351
458
  signature = generate_signature(params)
352
459
  params[:foo] = 'world'
353
460
  assert_raises(ShopifyAPI::ValidationException) do
354
461
  session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
355
- session.request_token(params.merge(:hmac => signature))
462
+ session.request_token(params.merge(hmac: signature))
356
463
  end
357
464
  end
358
465
 
359
466
  test "return true when the signature is valid and the keys of params are strings" do
360
467
  params = { 'code' => 'any-code', 'timestamp' => Time.now }
361
468
  params[:hmac] = generate_signature(params)
362
- assert_equal true, ShopifyAPI::Session.validate_signature(params)
469
+ assert_equal(true, ShopifyAPI::Session.validate_signature(params))
363
470
  end
364
471
 
365
472
  test "return true when validating signature of params with ampersand and equal sign characters" do
@@ -367,7 +474,7 @@ class SessionTest < Test::Unit::TestCase
367
474
  params = { 'a' => '1&b=2', 'c=3&d' => '4' }
368
475
  to_sign = 'a=1%26b=2&c%3D3%26d=4'
369
476
  params[:hmac] = generate_signature(to_sign)
370
- assert_equal true, ShopifyAPI::Session.validate_signature(params)
477
+ assert_equal(true, ShopifyAPI::Session.validate_signature(params))
371
478
  end
372
479
 
373
480
  test "return true when validating signature of params with percent sign characters" do
@@ -375,7 +482,7 @@ class SessionTest < Test::Unit::TestCase
375
482
  params = { 'a%3D1%26b' => '2%26c%3D3' }
376
483
  to_sign = 'a%253D1%2526b=2%2526c%253D3'
377
484
  params[:hmac] = generate_signature(to_sign)
378
- assert_equal true, ShopifyAPI::Session.validate_signature(params)
485
+ assert_equal(true, ShopifyAPI::Session.validate_signature(params))
379
486
  end
380
487
 
381
488
  test "url is aliased to domain to minimize the upgrade changes" do
@@ -511,6 +618,10 @@ class SessionTest < Test::Unit::TestCase
511
618
 
512
619
  private
513
620
 
621
+ def assert_equal_uri(expected, actual)
622
+ assert_equal(Addressable::URI.parse(expected), Addressable::URI.parse(actual))
623
+ end
624
+
514
625
  def make_sorted_params(params)
515
626
  params.with_indifferent_access.except(
516
627
  :signature, :hmac, :action, :controller
@@ -519,7 +630,7 @@ class SessionTest < Test::Unit::TestCase
519
630
 
520
631
  def generate_signature(params)
521
632
  params = make_sorted_params(params) if params.is_a?(Hash)
522
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, ShopifyAPI::Session.secret, params)
633
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA256'), ShopifyAPI::Session.secret, params)
523
634
  end
524
635
 
525
636
  def any_api_version
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class ShippingZoneTest < Test::Unit::TestCase
4
5
  test "get all should get all shipping zones" do
5
- fake 'shipping_zones', :method => :get, :status => 200, :body => load_fixture('shipping_zones')
6
+ fake('shipping_zones', method: :get, status: 200, body: load_fixture('shipping_zones'))
6
7
  checkout = ShopifyAPI::ShippingZone.all
7
- assert_equal 1, checkout.first.id
8
- assert_equal "Canada", checkout.first.name
8
+ assert_equal(1, checkout.first.id)
9
+ assert_equal("Canada", checkout.first.name)
9
10
  end
10
11
  end
data/test/shop_test.rb CHANGED
@@ -1,68 +1,82 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class ShopTest < Test::Unit::TestCase
4
5
  def setup
5
6
  super
6
- fake "shop"
7
+ fake("shop")
7
8
  @shop = ShopifyAPI::Shop.current
8
9
  end
9
10
 
10
11
  def test_current_should_return_current_shop
11
- assert @shop.is_a?(ShopifyAPI::Shop)
12
- assert_equal "Apple Computers", @shop.name
13
- assert_equal "apple.myshopify.com", @shop.myshopify_domain
14
- assert_equal 690933842, @shop.id
15
- assert_equal "2007-12-31T19:00:00-05:00", @shop.created_at
16
- assert_nil @shop.tax_shipping
12
+ assert(@shop.is_a?(ShopifyAPI::Shop))
13
+ assert_equal("Apple Computers", @shop.name)
14
+ assert_equal("apple.myshopify.com", @shop.myshopify_domain)
15
+ assert_equal(690933842, @shop.id)
16
+ assert_equal("2007-12-31T19:00:00-05:00", @shop.created_at)
17
+ assert_nil(@shop.tax_shipping)
17
18
  end
18
19
 
19
20
  def test_current_with_options_should_return_current_shop
20
- fake "shop.json?fields%5B%5D=name&fields%5B%5D=myshopify_domain", :extension => false, :method => :get, :status => 201, :body => load_fixture('shop')
21
-
22
- @shop = ShopifyAPI::Shop.current(params: { fields: [:name, :myshopify_domain]})
23
- assert @shop.is_a?(ShopifyAPI::Shop)
24
- assert_equal "Apple Computers", @shop.name
25
- assert_equal "apple.myshopify.com", @shop.myshopify_domain
21
+ fake(
22
+ "shop.json?fields%5B%5D=name&fields%5B%5D=myshopify_domain",
23
+ extension: false,
24
+ method: :get,
25
+ status: 201,
26
+ body: load_fixture('shop')
27
+ )
28
+
29
+ @shop = ShopifyAPI::Shop.current(params: { fields: [:name, :myshopify_domain] })
30
+ assert(@shop.is_a?(ShopifyAPI::Shop))
31
+ assert_equal("Apple Computers", @shop.name)
32
+ assert_equal("apple.myshopify.com", @shop.myshopify_domain)
26
33
  end
27
34
 
28
35
  def test_get_all_metafields_for_shop
29
- fake "metafields"
36
+ fake("metafields")
30
37
 
31
38
  metafields = @shop.metafields
32
39
 
33
- assert_equal 3, metafields.length
34
- assert metafields.all?{|m| m.is_a?(ShopifyAPI::Metafield)}
40
+ assert_equal(3, metafields.length)
41
+ assert(metafields.all? { |m| m.is_a?(ShopifyAPI::Metafield) })
35
42
  end
36
43
 
37
44
  def test_get_2_metafields_for_shop
38
- body = ActiveSupport::JSON.decode load_fixture 'metafields'
39
- body['metafields'].slice! 2, 1
45
+ body = ActiveSupport::JSON.decode(load_fixture('metafields'))
46
+ body['metafields'].slice!(2, 1)
40
47
 
41
- fake 'metafields.json?limit=2', body: body.to_json, extension: false
48
+ fake('metafields.json?limit=2', body: body.to_json, extension: false)
42
49
 
43
- metafields = @shop.metafields limit: 2
50
+ metafields = @shop.metafields(limit: 2)
44
51
 
45
- assert_equal 2, metafields.length
46
- assert metafields.all?{ |m| m.is_a? ShopifyAPI::Metafield }
52
+ assert_equal(2, metafields.length)
53
+ assert(metafields.all? { |m| m.is_a?(ShopifyAPI::Metafield) })
47
54
  end
48
55
 
49
56
  def test_add_metafield
50
- fake "metafields", :method => :post, :status => 201, :body =>load_fixture('metafield')
51
-
52
- field = @shop.add_metafield(ShopifyAPI::Metafield.new(:namespace => "contact", :key => "email", :value => "123@example.com", :value_type => "string"))
53
- assert_equal ActiveSupport::JSON.decode('{"metafield":{"namespace":"contact","key":"email","value":"123@example.com","value_type":"string"}}'), ActiveSupport::JSON.decode(WebMock.last_request.body)
54
- assert !field.new_record?
55
- assert_equal "contact", field.namespace
56
- assert_equal "email", field.key
57
- assert_equal "123@example.com", field.value
57
+ fake("metafields", method: :post, status: 201, body: load_fixture('metafield'))
58
+
59
+ field = @shop.add_metafield(
60
+ ShopifyAPI::Metafield.new(namespace: "contact", key: "email", value: "123@example.com", value_type: "string")
61
+ )
62
+ assert_equal(
63
+ ActiveSupport::JSON.decode(
64
+ '{"metafield":{"namespace":"contact","key":"email","value":"123@example.com","value_type":"string"}}'
65
+ ),
66
+ ActiveSupport::JSON.decode(WebMock.last_request.body)
67
+ )
68
+ assert(!field.new_record?)
69
+ assert_equal("contact", field.namespace)
70
+ assert_equal("email", field.key)
71
+ assert_equal("123@example.com", field.value)
58
72
  end
59
73
 
60
74
  def test_events
61
- fake "events"
75
+ fake("events")
62
76
 
63
77
  events = @shop.events
64
78
 
65
- assert_equal 3, events.length
66
- assert events.all?{|m| m.is_a?(ShopifyAPI::Event)}
79
+ assert_equal(3, events.length)
80
+ assert(events.all? { |m| m.is_a?(ShopifyAPI::Event) })
67
81
  end
68
82
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class SmartCollectionTest < Test::Unit::TestCase
4
5
  test "Smart Collection creation" do
5
- fake "smart_collections", :method => :post, :status => 201, :body => load_fixture('smart_collection')
6
- rules = { :column => "title", :relation => "starts_with", :condition => "mac" }
7
- smart_collection = ShopifyAPI::SmartCollection.create(:title => "Macbooks", :rules => rules)
8
- assert_equal 1063001432, smart_collection.id
6
+ fake("smart_collections", method: :post, status: 201, body: load_fixture('smart_collection'))
7
+ rules = { column: "title", relation: "starts_with", condition: "mac" }
8
+ smart_collection = ShopifyAPI::SmartCollection.create(title: "Macbooks", rules: rules)
9
+ assert_equal(1063001432, smart_collection.id)
9
10
  end
10
11
  end
@@ -1,32 +1,30 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class StorefrontAccessTokenTest < Test::Unit::TestCase
4
-
5
5
  def test_create_storefront_access_token
6
- fake "storefront_access_tokens", :method => :post, :body => load_fixture('storefront_access_token')
6
+ fake("storefront_access_tokens", method: :post, body: load_fixture('storefront_access_token'))
7
7
  storefront_access_token = ShopifyAPI::StorefrontAccessToken.create(title: 'Test')
8
- assert_equal 1, storefront_access_token.id
9
- assert_equal "Test", storefront_access_token.title
8
+ assert_equal(1, storefront_access_token.id)
9
+ assert_equal("Test", storefront_access_token.title)
10
10
  end
11
11
 
12
12
  def test_delete_storefront_access_token
13
- fake 'storefront_access_tokens/1', method: :get, status: 200, body: load_fixture('storefront_access_token')
14
- fake 'storefront_access_tokens/1', method: :delete, status: 200, body: 'destroyed'
15
-
13
+ fake('storefront_access_tokens/1', method: :get, status: 200, body: load_fixture('storefront_access_token'))
14
+ fake('storefront_access_tokens/1', method: :delete, status: 200, body: 'destroyed')
16
15
  storefront_access_tokens = ShopifyAPI::StorefrontAccessToken.find(1)
17
- assert storefront_access_tokens.destroy
16
+ assert(storefront_access_tokens.destroy)
18
17
  end
19
18
 
20
19
  def test_get_storefront_access_tokens
21
- fake "storefront_access_tokens", method: :get, status: 201, body: load_fixture('storefront_access_tokens')
20
+ fake("storefront_access_tokens", method: :get, status: 201, body: load_fixture('storefront_access_tokens'))
22
21
 
23
22
  tokens = ShopifyAPI::StorefrontAccessToken.all
24
23
 
25
- assert_equal 2, tokens.size
26
- assert_equal 1, tokens.first.id
27
- assert_equal 2, tokens.last.id
28
- assert_equal 'Test 1', tokens.first.title
29
- assert_equal 'Test 2', tokens.last.title
24
+ assert_equal(2, tokens.size)
25
+ assert_equal(1, tokens.first.id)
26
+ assert_equal(2, tokens.last.id)
27
+ assert_equal('Test 1', tokens.first.title)
28
+ assert_equal('Test 2', tokens.last.title)
30
29
  end
31
-
32
30
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
  class TaxServiceTest < Test::Unit::TestCase
3
4
  test "tax service creation" do
4
- fake "tax_services", :method => :post, :status => 202, :body => load_fixture('tax_service')
5
- tax_service = ShopifyAPI::TaxService.create(:name => "My Tax Service", :url => "https://mytaxservice.com")
6
- assert_equal '{"tax_service":{"name":"My Tax Service","url":"https://mytaxservice.com"}}', WebMock.last_request.body
7
-
5
+ fake("tax_services", method: :post, status: 202, body: load_fixture('tax_service'))
6
+ ShopifyAPI::TaxService.create(name: "My Tax Service", url: "https://mytaxservice.com")
7
+ assert_equal(
8
+ '{"tax_service":{"name":"My Tax Service","url":"https://mytaxservice.com"}}',
9
+ WebMock.last_request.body
10
+ )
8
11
  end
9
12
  end
@@ -5,14 +5,14 @@ require 'test_helper'
5
5
  class TenderTransactionTest < Test::Unit::TestCase
6
6
  def setup
7
7
  super
8
- fake "tender_transactions", method: :get, body: load_fixture('tender_transactions')
8
+ fake("tender_transactions", method: :get, body: load_fixture('tender_transactions'))
9
9
  end
10
10
 
11
11
  context "Tender Transaction" do
12
12
  should 'return a list of transactions' do
13
13
  tender_transactions = ShopifyAPI::TenderTransaction.all
14
- assert_equal 3, tender_transactions.length
15
- assert_equal [1, 2, 3], tender_transactions.map(&:id)
14
+ assert_equal(3, tender_transactions.length)
15
+ assert_equal([1, 2, 3], tender_transactions.map(&:id))
16
16
  end
17
17
  end
18
18
  end