shopify_api 4.9.0 → 9.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +36 -0
  4. data/.github/probots.yml +2 -0
  5. data/.github/workflows/build.yml +41 -0
  6. data/.gitignore +5 -1
  7. data/.rubocop.yml +28 -0
  8. data/.rubocop_todo.yml +75 -0
  9. data/CHANGELOG.md +491 -0
  10. data/CONTRIBUTING.md +1 -1
  11. data/Gemfile +6 -2
  12. data/Gemfile.lock +151 -0
  13. data/Gemfile_ar41 +5 -0
  14. data/Gemfile_ar50 +5 -0
  15. data/Gemfile_ar51 +5 -0
  16. data/Gemfile_ar_master +0 -1
  17. data/README.md +492 -100
  18. data/RELEASING +10 -9
  19. data/Rakefile +21 -5
  20. data/SECURITY.md +59 -0
  21. data/docker-compose.yml +13 -0
  22. data/docs/_config.yml +1 -0
  23. data/docs/_includes/footer.html +28 -0
  24. data/docs/_includes/head.html +28 -0
  25. data/docs/_layouts/index.html +57 -0
  26. data/docs/graphql.md +241 -0
  27. data/docs/index.md +639 -0
  28. data/lib/active_resource/connection_ext.rb +1 -0
  29. data/lib/active_resource/detailed_log_subscriber.rb +43 -7
  30. data/lib/active_resource/json_errors.rb +8 -2
  31. data/lib/shopify_api.rb +16 -6
  32. data/lib/shopify_api/api_access.rb +57 -0
  33. data/lib/shopify_api/api_version.rb +206 -0
  34. data/lib/shopify_api/connection.rb +7 -4
  35. data/lib/shopify_api/countable.rb +3 -2
  36. data/lib/shopify_api/disable_prefix_check.rb +31 -0
  37. data/lib/shopify_api/events.rb +2 -1
  38. data/lib/shopify_api/graphql.rb +103 -0
  39. data/lib/shopify_api/graphql/http_client.rb +22 -0
  40. data/lib/shopify_api/graphql/railtie.rb +17 -0
  41. data/lib/shopify_api/graphql/task.rake +100 -0
  42. data/lib/shopify_api/limits.rb +9 -9
  43. data/lib/shopify_api/message_enricher.rb +25 -0
  44. data/lib/shopify_api/meta.rb +14 -0
  45. data/lib/shopify_api/metafields.rb +5 -4
  46. data/lib/shopify_api/paginated_collection.rb +69 -0
  47. data/lib/shopify_api/pagination_link_headers.rb +34 -0
  48. data/lib/shopify_api/resources.rb +3 -1
  49. data/lib/shopify_api/resources/abandoned_checkout.rb +7 -0
  50. data/lib/shopify_api/resources/access_scope.rb +10 -0
  51. data/lib/shopify_api/resources/access_token.rb +1 -0
  52. data/lib/shopify_api/resources/address.rb +1 -0
  53. data/lib/shopify_api/resources/announcement.rb +2 -1
  54. data/lib/shopify_api/resources/api_permission.rb +9 -0
  55. data/lib/shopify_api/resources/application_charge.rb +1 -0
  56. data/lib/shopify_api/resources/application_credit.rb +1 -0
  57. data/lib/shopify_api/resources/array_base.rb +13 -0
  58. data/lib/shopify_api/resources/article.rb +3 -2
  59. data/lib/shopify_api/resources/asset.rb +28 -23
  60. data/lib/shopify_api/resources/assigned_fulfillment_order.rb +16 -0
  61. data/lib/shopify_api/resources/base.rb +101 -24
  62. data/lib/shopify_api/resources/billing_address.rb +2 -1
  63. data/lib/shopify_api/resources/blog.rb +2 -1
  64. data/lib/shopify_api/resources/carrier_service.rb +1 -0
  65. data/lib/shopify_api/resources/cart.rb +2 -1
  66. data/lib/shopify_api/resources/checkout.rb +27 -1
  67. data/lib/shopify_api/resources/collect.rb +2 -0
  68. data/lib/shopify_api/resources/collection.rb +14 -0
  69. data/lib/shopify_api/resources/collection_listing.rb +11 -1
  70. data/lib/shopify_api/resources/collection_publication.rb +10 -0
  71. data/lib/shopify_api/resources/comment.rb +20 -5
  72. data/lib/shopify_api/resources/country.rb +1 -0
  73. data/lib/shopify_api/resources/currency.rb +6 -0
  74. data/lib/shopify_api/resources/custom_collection.rb +7 -6
  75. data/lib/shopify_api/resources/customer.rb +2 -1
  76. data/lib/shopify_api/resources/customer_group.rb +1 -0
  77. data/lib/shopify_api/resources/{customer_invite_message.rb → customer_invite.rb} +1 -0
  78. data/lib/shopify_api/resources/customer_saved_search.rb +4 -1
  79. data/lib/shopify_api/resources/discount_code.rb +1 -0
  80. data/lib/shopify_api/resources/discount_code_batch.rb +34 -0
  81. data/lib/shopify_api/resources/draft_order.rb +1 -0
  82. data/lib/shopify_api/resources/draft_order_invoice.rb +1 -0
  83. data/lib/shopify_api/resources/event.rb +2 -0
  84. data/lib/shopify_api/resources/fulfillment.rb +46 -3
  85. data/lib/shopify_api/resources/fulfillment_event.rb +2 -1
  86. data/lib/shopify_api/resources/fulfillment_order.rb +151 -0
  87. data/lib/shopify_api/resources/fulfillment_order_locations_for_move.rb +5 -0
  88. data/lib/shopify_api/resources/fulfillment_request.rb +1 -0
  89. data/lib/shopify_api/resources/fulfillment_service.rb +1 -0
  90. data/lib/shopify_api/resources/fulfillment_v2.rb +21 -0
  91. data/lib/shopify_api/resources/gift_card.rb +1 -0
  92. data/lib/shopify_api/resources/image.rb +4 -3
  93. data/lib/shopify_api/resources/inventory_item.rb +6 -0
  94. data/lib/shopify_api/resources/inventory_level.rb +54 -0
  95. data/lib/shopify_api/resources/line_item.rb +10 -1
  96. data/lib/shopify_api/resources/location.rb +4 -0
  97. data/lib/shopify_api/resources/marketing_event.rb +3 -0
  98. data/lib/shopify_api/resources/metafield.rb +2 -0
  99. data/lib/shopify_api/resources/note_attribute.rb +1 -0
  100. data/lib/shopify_api/resources/option.rb +1 -0
  101. data/lib/shopify_api/resources/order.rb +25 -5
  102. data/lib/shopify_api/resources/order_risk.rb +1 -0
  103. data/lib/shopify_api/resources/page.rb +1 -0
  104. data/lib/shopify_api/resources/payment.rb +7 -0
  105. data/lib/shopify_api/resources/payment_details.rb +1 -0
  106. data/lib/shopify_api/resources/ping.rb +3 -0
  107. data/lib/shopify_api/resources/policy.rb +1 -0
  108. data/lib/shopify_api/resources/price_rule.rb +1 -1
  109. data/lib/shopify_api/resources/product.rb +33 -7
  110. data/lib/shopify_api/resources/product_listing.rb +9 -1
  111. data/lib/shopify_api/resources/product_publication.rb +10 -0
  112. data/lib/shopify_api/resources/province.rb +1 -0
  113. data/lib/shopify_api/resources/publication.rb +5 -0
  114. data/lib/shopify_api/resources/receipt.rb +1 -0
  115. data/lib/shopify_api/resources/recurring_application_charge.rb +4 -1
  116. data/lib/shopify_api/resources/redirect.rb +1 -0
  117. data/lib/shopify_api/resources/refund.rb +6 -4
  118. data/lib/shopify_api/resources/report.rb +1 -0
  119. data/lib/shopify_api/resources/resource_feedback.rb +1 -1
  120. data/lib/shopify_api/resources/rule.rb +1 -0
  121. data/lib/shopify_api/resources/script_tag.rb +1 -0
  122. data/lib/shopify_api/resources/shipping_address.rb +1 -0
  123. data/lib/shopify_api/resources/shipping_line.rb +2 -1
  124. data/lib/shopify_api/resources/shipping_rate.rb +7 -0
  125. data/lib/shopify_api/resources/shipping_zone.rb +1 -0
  126. data/lib/shopify_api/resources/shop.rb +10 -7
  127. data/lib/shopify_api/resources/smart_collection.rb +3 -3
  128. data/lib/shopify_api/resources/storefront_access_token.rb +1 -0
  129. data/lib/shopify_api/resources/tax_line.rb +1 -0
  130. data/lib/shopify_api/resources/tax_service.rb +1 -0
  131. data/lib/shopify_api/resources/tender_transaction.rb +6 -0
  132. data/lib/shopify_api/resources/theme.rb +1 -0
  133. data/lib/shopify_api/resources/transaction.rb +1 -0
  134. data/lib/shopify_api/resources/usage_charge.rb +1 -0
  135. data/lib/shopify_api/resources/user.rb +1 -0
  136. data/lib/shopify_api/resources/variant.rb +35 -0
  137. data/lib/shopify_api/resources/webhook.rb +1 -0
  138. data/lib/shopify_api/session.rb +109 -45
  139. data/lib/shopify_api/version.rb +2 -1
  140. data/lib/verify_docs.rb +8 -0
  141. data/service.yml +8 -0
  142. data/shopify_api.gemspec +19 -8
  143. data/test/abandoned_checkouts_test.rb +29 -0
  144. data/test/access_scope_test.rb +23 -0
  145. data/test/access_token_test.rb +6 -5
  146. data/test/active_resource/json_errors_test.rb +6 -6
  147. data/test/api_access_test.rb +153 -0
  148. data/test/api_permission_test.rb +9 -0
  149. data/test/api_version_test.rb +157 -0
  150. data/test/application_charge_test.rb +30 -27
  151. data/test/application_credit_test.rb +10 -9
  152. data/test/article_test.rb +34 -35
  153. data/test/asset_test.rb +14 -6
  154. data/test/assigned_fulfillment_order_test.rb +78 -0
  155. data/test/base_test.rb +147 -59
  156. data/test/blog_test.rb +4 -3
  157. data/test/carrier_service_test.rb +7 -6
  158. data/test/cart_test.rb +2 -1
  159. data/test/checkouts_test.rb +72 -4
  160. data/test/collect_test.rb +4 -3
  161. data/test/collection_listing_test.rb +56 -13
  162. data/test/collection_publication_test.rb +40 -0
  163. data/test/collection_test.rb +50 -0
  164. data/test/countable_test.rb +3 -2
  165. data/test/currency_test.rb +21 -0
  166. data/test/custom_collection_test.rb +4 -3
  167. data/test/customer_saved_search_test.rb +18 -8
  168. data/test/customer_test.rb +22 -14
  169. data/test/detailed_log_subscriber_test.rb +113 -19
  170. data/test/discount_code_batch_test.rb +41 -0
  171. data/test/discount_code_test.rb +22 -16
  172. data/test/draft_order_test.rb +68 -52
  173. data/test/fixtures/abandoned_checkout.json +184 -0
  174. data/test/fixtures/abandoned_checkouts.json +186 -0
  175. data/test/fixtures/access_scopes.json +10 -0
  176. data/test/fixtures/api_versions.json +38 -0
  177. data/test/fixtures/apis.json +42 -0
  178. data/test/fixtures/assigned_fulfillment_orders.json +80 -0
  179. data/test/fixtures/checkout.json +160 -0
  180. data/test/fixtures/checkouts.json +25 -49
  181. data/test/fixtures/collection.json +17 -0
  182. data/test/fixtures/collection_listing_product_ids2.json +1 -0
  183. data/test/fixtures/collection_products.json +47 -0
  184. data/test/fixtures/collection_publication.json +11 -0
  185. data/test/fixtures/collection_publications.json +13 -0
  186. data/test/fixtures/currencies.json +25 -0
  187. data/test/fixtures/discount_code_batch.json +14 -0
  188. data/test/fixtures/discount_code_batch_discount_codes.json +21 -0
  189. data/test/fixtures/fulfillment_order.json +39 -0
  190. data/test/fixtures/fulfillment_order_locations_for_move.json +18 -0
  191. data/test/fixtures/fulfillment_orders.json +80 -0
  192. data/test/fixtures/fulfillments.json +53 -0
  193. data/test/fixtures/graphql/2019-10.json +1083 -0
  194. data/test/fixtures/graphql/dummy_schema.rb +16 -0
  195. data/test/fixtures/graphql/unstable.json +1083 -0
  196. data/test/fixtures/inventory_level.json +7 -0
  197. data/test/fixtures/inventory_levels.json +24 -0
  198. data/test/fixtures/order_with_properties.json +373 -0
  199. data/test/fixtures/payment.json +7 -0
  200. data/test/fixtures/payments.json +9 -0
  201. data/test/fixtures/ping/conversation.json +1 -0
  202. data/test/fixtures/ping/failed_delivery_confirmation.json +1 -0
  203. data/test/fixtures/ping/message.json +1 -0
  204. data/test/fixtures/ping/successful_delivery_confirmation.json +1 -0
  205. data/test/fixtures/product_listing_product_ids.json +1 -1
  206. data/test/fixtures/product_listing_product_ids2.json +1 -0
  207. data/test/fixtures/product_publication.json +11 -0
  208. data/test/fixtures/product_publications.json +13 -0
  209. data/test/fixtures/publications.json +9 -0
  210. data/test/fixtures/shipping_rates.json +12 -0
  211. data/test/fixtures/smart_collection_products.json +155 -0
  212. data/test/fixtures/tender_transactions.json +52 -0
  213. data/test/fulfillment_event_test.rb +31 -26
  214. data/test/fulfillment_order_test.rb +530 -0
  215. data/test/fulfillment_order_test_helper.rb +8 -0
  216. data/test/fulfillment_request_test.rb +10 -8
  217. data/test/fulfillment_service_test.rb +13 -12
  218. data/test/fulfillment_test.rb +198 -20
  219. data/test/fulfillment_v2_test.rb +66 -0
  220. data/test/gift_card_test.rb +6 -4
  221. data/test/graphql/http_client_test.rb +26 -0
  222. data/test/graphql_test.rb +190 -0
  223. data/test/image_test.rb +19 -17
  224. data/test/inventory_level_test.rb +68 -0
  225. data/test/lib/webmock_extensions/last_request.rb +16 -0
  226. data/test/limits_test.rb +4 -3
  227. data/test/location_test.rb +15 -0
  228. data/test/marketing_event_test.rb +21 -21
  229. data/test/message_enricher_test.rb +45 -0
  230. data/test/meta_test.rb +47 -0
  231. data/test/metafield_test.rb +30 -20
  232. data/test/order_risk_test.rb +17 -16
  233. data/test/order_test.rb +110 -17
  234. data/test/pagination_test.rb +290 -0
  235. data/test/payment_test.rb +19 -0
  236. data/test/policy_test.rb +6 -5
  237. data/test/price_rule_test.rb +20 -15
  238. data/test/product_listing_test.rb +72 -15
  239. data/test/product_publication_test.rb +40 -0
  240. data/test/product_test.rb +80 -19
  241. data/test/publication_test.rb +12 -0
  242. data/test/recurring_application_charge_test.rb +105 -50
  243. data/test/redirect_test.rb +4 -3
  244. data/test/refund_test.rb +22 -17
  245. data/test/report_test.rb +12 -10
  246. data/test/resource_feedback_test.rb +14 -13
  247. data/test/script_tag_test.rb +10 -9
  248. data/test/session_test.rb +497 -111
  249. data/test/shipping_rate_test.rb +17 -0
  250. data/test/shipping_zone_test.rb +4 -3
  251. data/test/shop_test.rb +47 -33
  252. data/test/smart_collection_test.rb +5 -4
  253. data/test/storefront_access_token_test.rb +13 -15
  254. data/test/tax_service_test.rb +7 -3
  255. data/test/tender_transaction_test.rb +18 -0
  256. data/test/test_helper.rb +98 -67
  257. data/test/transaction_test.rb +4 -3
  258. data/test/usage_charge_test.rb +12 -8
  259. data/test/user_test.rb +4 -3
  260. data/test/variant_test.rb +50 -20
  261. data/test/webhook_test.rb +10 -7
  262. metadata +196 -37
  263. data/.travis.yml +0 -36
  264. data/CHANGELOG +0 -292
  265. data/Gemfile_ar30 +0 -6
  266. data/Gemfile_ar31 +0 -6
  267. data/Gemfile_ar32 +0 -6
  268. data/Gemfile_ar40 +0 -6
  269. data/bin/shopify +0 -3
  270. data/lib/active_resource/base_ext.rb +0 -21
  271. data/lib/active_resource/disable_prefix_check.rb +0 -36
  272. data/lib/active_resource/to_query.rb +0 -10
  273. data/lib/shopify_api/json_format.rb +0 -18
  274. data/lib/shopify_api/resources/discount.rb +0 -11
  275. data/lib/shopify_api/resources/o_auth.rb +0 -9
  276. data/test/discount_test.rb +0 -52
  277. data/test/fixtures/discount.json +0 -17
  278. data/test/fixtures/discount_disabled.json +0 -17
  279. data/test/fixtures/discounts.json +0 -34
  280. data/test/fixtures/o_auth_revoke.json +0 -5
  281. data/test/o_auth_test.rb +0 -8
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class RedirectTest < Test::Unit::TestCase
4
5
  test "#create should create a redirect" do
5
- fake "redirects", :method => :post, :status => 201, :body => load_fixture('redirect')
6
- redirect = ShopifyAPI::Redirect.create(:path => "/ipod", :target => "/pages/itunes")
7
- assert_equal 979034150, redirect.id
6
+ fake("redirects", method: :post, status: 201, body: load_fixture('redirect'))
7
+ redirect = ShopifyAPI::Redirect.create(path: "/ipod", target: "/pages/itunes")
8
+ assert_equal(979034150, redirect.id)
8
9
  end
9
10
  end
data/test/refund_test.rb CHANGED
@@ -1,32 +1,37 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class RefundTest < Test::Unit::TestCase
4
-
5
5
  test '#create should create a refund' do
6
- fake "orders/450789469/refunds", :method => :post, :status => 201, :body => load_fixture('refund')
6
+ fake("orders/450789469/refunds", method: :post, status: 201, body: load_fixture('refund'))
7
7
  refund = ShopifyAPI::Refund.create(
8
- :order_id => 450789469,
9
- :restock => true,
10
- :note => "wrong size",
11
- :shipping => { :full_refund => true },
12
- :refund_line_items => [{ :line_item_id => 518995019, :quantity => 1 }]
8
+ order_id: 450789469,
9
+ restock: true,
10
+ note: "wrong size",
11
+ shipping: { full_refund: true },
12
+ refund_line_items: [{ line_item_id: 518995019, quantity: 1 }]
13
13
  )
14
- assert_equal 703073504, refund.refund_line_items.first.line_item_id
14
+ assert_equal(703073504, refund.refund_line_items.first.line_item_id)
15
15
  end
16
16
 
17
17
  test '#find should return a refund' do
18
- fake "orders/450789469/refunds/509562969.json?order_id=450789469", :extension => false, :method => :get, :body => load_fixture('refund')
19
- fake "orders/450789469/refunds/509562969", :method => :get, :body => load_fixture('refund')
20
- refund = ShopifyAPI::Refund.find(509562969, :params => {:order_id => 450789469})
21
- assert_equal 509562969, refund.id
18
+ fake(
19
+ "orders/450789469/refunds/509562969.json?order_id=450789469",
20
+ extension: false,
21
+ method: :get,
22
+ body: load_fixture('refund')
23
+ )
24
+ fake("orders/450789469/refunds/509562969", method: :get, body: load_fixture('refund'))
25
+ refund = ShopifyAPI::Refund.find(509562969, params: { order_id: 450789469 })
26
+ assert_equal(509562969, refund.id)
22
27
  end
23
28
 
24
29
  test '#calculate a refund' do
25
- fake "orders/450789469/refunds/calculate", :method => :post, :body => load_fixture('refund')
26
- data = { :shipping => { :amount => 0 } }
30
+ fake("orders/450789469/refunds/calculate", method: :post, body: load_fixture('refund'))
31
+ data = { shipping: { amount: 0 } }
27
32
 
28
- refund = ShopifyAPI::Refund.calculate(data, :params => {:order_id => 450789469})
29
- assert_equal 2, refund.refund_line_items.count
30
- assert_equal 703073504, refund.refund_line_items.first.line_item_id
33
+ refund = ShopifyAPI::Refund.calculate(data, params: { order_id: 450789469 })
34
+ assert_equal(2, refund.refund_line_items.count)
35
+ assert_equal(703073504, refund.refund_line_items.first.line_item_id)
31
36
  end
32
37
  end
data/test/report_test.rb CHANGED
@@ -1,35 +1,37 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class ReportTest < Test::Unit::TestCase
4
5
  test 'get should get a report' do
5
- fake 'reports/987', method: :get, status: 200, body: load_fixture('report')
6
+ fake('reports/987', method: :get, status: 200, body: load_fixture('report'))
6
7
 
7
8
  report = ShopifyAPI::Report.find(987)
8
- assert_equal 987, report.id
9
+ assert_equal(987, report.id)
9
10
  end
10
11
 
11
12
  test 'get all should get all reports' do
12
- fake 'reports', method: :get, status: 200, body: load_fixture('reports')
13
+ fake('reports', method: :get, status: 200, body: load_fixture('reports'))
13
14
 
14
15
  reports = ShopifyAPI::Report.all
15
- assert_equal 'custom_app_reports', reports.first.category
16
+ assert_equal('custom_app_reports', reports.first.category)
16
17
  end
17
18
 
18
19
  test 'create should create a report' do
19
- fake 'reports', method: :post, status: 201, body: load_fixture('report')
20
+ fake('reports', method: :post, status: 201, body: load_fixture('report'))
20
21
 
21
22
  report = ShopifyAPI::Report.create(
22
23
  name: 'Custom App Report',
23
- shopify_ql: 'SHOW quantity_count, total_sales BY product_type, vendor, product_title FROM products SINCE -1m UNTIL -0m ORDER BY total_sales DESC'
24
+ shopify_ql: 'SHOW quantity_count, total_sales BY product_type, vendor, product_title ' \
25
+ 'FROM products SINCE -1m UNTIL -0m ORDER BY total_sales DESC'
24
26
  )
25
- assert_equal 'custom_app_reports', report.category
27
+ assert_equal('custom_app_reports', report.category)
26
28
  end
27
29
 
28
30
  test 'delete should delete report' do
29
- fake 'reports/987', method: :get, status: 200, body: load_fixture('report')
30
- fake 'reports/987', method: :delete, status: 200, body: '[]'
31
+ fake('reports/987', method: :get, status: 200, body: load_fixture('report'))
32
+ fake('reports/987', method: :delete, status: 200, body: '[]')
31
33
 
32
34
  report = ShopifyAPI::Report.find(987)
33
- assert report.destroy
35
+ assert(report.destroy)
34
36
  end
35
37
  end
@@ -1,41 +1,42 @@
1
+ # frozen_string_literal: true
1
2
  class ResourceFeedbackTest < Test::Unit::TestCase
2
3
  def test_get_resource_feedback
3
- body = { resource_feedback: [ { resource_type: 'Shop' } ] }.to_json
4
- fake 'resource_feedback', method: :get, body: body
4
+ body = { resource_feedback: [{ resource_type: 'Shop' }] }.to_json
5
+ fake('resource_feedback', method: :get, body: body)
5
6
  resource_feedback = ShopifyAPI::ResourceFeedback.find(:all)
6
- assert_equal 'Shop', resource_feedback.first.resource_type
7
+ assert_equal('Shop', resource_feedback.first.resource_type)
7
8
  end
8
9
 
9
10
  def test_save_with_resource_feedback_endpoint
10
11
  body = { resource_feedback: {} }.to_json
11
- fake 'resource_feedback', method: :post, body: body
12
+ fake('resource_feedback', method: :post, body: body)
12
13
  ShopifyAPI::ResourceFeedback.new.save
13
- assert_request_body body
14
+ assert_request_body(body)
14
15
  end
15
16
 
16
17
  def test_get_resource_feedback_with_product_id
17
- body = { resource_feedback: [ { resource_type: 'Product' } ] }.to_json
18
- fake 'products/42/resource_feedback', method: :get, body: body
18
+ body = { resource_feedback: [{ resource_type: 'Product' }] }.to_json
19
+ fake('products/42/resource_feedback', method: :get, body: body)
19
20
  resource_feedback = ShopifyAPI::ResourceFeedback.find(:all, params: { product_id: 42 })
20
- assert_equal 'Product', resource_feedback.first.resource_type
21
+ assert_equal('Product', resource_feedback.first.resource_type)
21
22
  end
22
23
 
23
24
  def test_save_with_product_id_resource_feedback_endpoint
24
25
  body = { resource_feedback: {} }.to_json
25
- fake 'products/42/resource_feedback', method: :post, body: body
26
+ fake('products/42/resource_feedback', method: :post, body: body)
26
27
  ShopifyAPI::ResourceFeedback.new(product_id: 42).save
27
- assert_request_body body
28
+ assert_request_body(body)
28
29
  end
29
30
 
30
31
  def test_save_raises_exception_when_already_persisted
31
32
  body = { resource_feedback: {} }.to_json
32
- fake 'resource_feedback', method: :post, body: body
33
+ fake('resource_feedback', method: :post, body: body)
33
34
  resource_feedback = ShopifyAPI::ResourceFeedback.new
34
35
  resource_feedback.save
35
- assert_request_body body
36
+ assert_request_body(body)
36
37
 
37
38
  ShopifyAPI::ResourceFeedback.any_instance.expects(:persisted?).returns(true)
38
- assert_raises ShopifyAPI::ResourceFeedback::ExistingFeedbackSaved do
39
+ assert_raises(ShopifyAPI::ResourceFeedback::ExistingFeedbackSaved) do
39
40
  resource_feedback.save
40
41
  end
41
42
  end
@@ -1,30 +1,31 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class ScriptTagTest < Test::Unit::TestCase
4
5
  test "get all should get all script tags" do
5
- fake 'script_tags', :method => :get, :status => 200, :body => load_fixture('script_tags')
6
+ fake('script_tags', method: :get, status: 200, body: load_fixture('script_tags'))
6
7
  script_tags = ShopifyAPI::ScriptTag.all
7
- assert_equal "http://js-aplenty.com/bar.js", script_tags.first.src
8
+ assert_equal("http://js-aplenty.com/bar.js", script_tags.first.src)
8
9
  end
9
10
 
10
11
  test "get should get a script tag" do
11
- fake 'script_tags/421379493', :method => :get, :status => 200, :body => load_fixture('script_tag')
12
+ fake('script_tags/421379493', method: :get, status: 200, body: load_fixture('script_tag'))
12
13
  script_tag = ShopifyAPI::ScriptTag.find(421379493)
13
- assert_equal "http://js-aplenty.com/bar.js", script_tag.src
14
+ assert_equal("http://js-aplenty.com/bar.js", script_tag.src)
14
15
  end
15
16
 
16
17
  test "create should create a new script tag" do
17
- fake 'script_tags', :method => :post, :status => 201, :body => load_fixture('script_tag')
18
+ fake('script_tags', method: :post, status: 201, body: load_fixture('script_tag'))
18
19
  script_tag = ShopifyAPI::ScriptTag.create(event: "onload", src: "http://js-aplenty.com/bar.js")
19
- assert_equal "http://js-aplenty.com/bar.js", script_tag.src
20
+ assert_equal("http://js-aplenty.com/bar.js", script_tag.src)
20
21
  end
21
22
 
22
23
  test "editing script tag should update script tag" do
23
- fake 'script_tags/421379493', :method => :get, :status => 200, :body => load_fixture('script_tag')
24
+ fake('script_tags/421379493', method: :get, status: 200, body: load_fixture('script_tag'))
24
25
  script_tag = ShopifyAPI::ScriptTag.find(421379493)
25
26
  script_tag.src = "http://js-aplenty.com/bar.js"
26
- fake 'script_tags/421379493', :method => :put, :status => 200, :body => load_fixture('script_tag')
27
+ fake('script_tags/421379493', method: :put, status: 200, body: load_fixture('script_tag'))
27
28
  script_tag.save
28
- assert_equal "http://js-aplenty.com/bar.js", script_tag.src
29
+ assert_equal("http://js-aplenty.com/bar.js", script_tag.src)
29
30
  end
30
31
  end
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
@@ -9,242 +11,626 @@ class SessionTest < Test::Unit::TestCase
9
11
  end
10
12
 
11
13
  test "not be valid without a url" do
12
- session = ShopifyAPI::Session.new(nil, "any-token")
13
- assert_not session.valid?
14
+ session = ShopifyAPI::Session.new(domain: nil, token: "any-token", api_version: any_api_version)
15
+ assert_not(session.valid?)
14
16
  end
15
17
 
16
18
  test "not be valid without token" do
17
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
18
- assert_not session.valid?
19
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
20
+ assert_not(session.valid?)
19
21
  end
20
22
 
21
- test "be valid with any token and any url" do
22
- session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
23
- assert session.valid?
23
+ test "not be valid without an API version" do
24
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: nil)
25
+ assert_not(session.valid?)
26
+
27
+ session = ShopifyAPI::Session.new(
28
+ domain: "testshop.myshopify.com", token: "any-token", api_version: ShopifyAPI::ApiVersion::NullVersion
29
+ )
30
+ assert_not(session.valid?)
31
+ end
32
+
33
+ test "default to base API version" do
34
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token")
35
+ assert(session.valid?)
36
+ assert_equal(session.api_version, ShopifyAPI::Base.api_version)
37
+ end
38
+
39
+ test "can override the base API version" do
40
+ different_api_version = '2020-01'
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))
46
+ end
47
+
48
+ test "be valid with any token, any url and version" do
49
+ session = ShopifyAPI::Session.new(
50
+ domain: "testshop.myshopify.com",
51
+ token: "any-token",
52
+ api_version: any_api_version
53
+ )
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?)
24
88
  end
25
89
 
26
90
  test "not raise error without params" do
27
91
  assert_nothing_raised do
28
- session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
92
+ ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: any_api_version)
29
93
  end
30
94
  end
31
95
 
32
96
  test "ignore everything but the subdomain in the shop" do
33
- assert_equal "https://testshop.myshopify.com/admin", ShopifyAPI::Session.new("http://user:pass@testshop.notshopify.net/path", "any-token").site
97
+ assert_equal(
98
+ "https://testshop.myshopify.com",
99
+ ShopifyAPI::Session.new(
100
+ domain: "http://user:pass@testshop.notshopify.net/path",
101
+ token: "any-token",
102
+ api_version: any_api_version
103
+ ).site
104
+ )
34
105
  end
35
106
 
36
107
  test "append the myshopify domain if not given" do
37
- assert_equal "https://testshop.myshopify.com/admin", ShopifyAPI::Session.new("testshop", "any-token").site
108
+ assert_equal(
109
+ "https://testshop.myshopify.com",
110
+ ShopifyAPI::Session.new(domain: "testshop", token: "any-token", api_version: any_api_version).site
111
+ )
38
112
  end
39
113
 
40
114
  test "not raise error without params" do
41
115
  assert_nothing_raised do
42
- session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
116
+ ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: "any-token", api_version: any_api_version)
117
+ end
118
+ end
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
+ )
43
147
  end
44
148
  end
45
149
 
46
150
  test "raise error if params passed but signature omitted" do
47
151
  assert_raises(ShopifyAPI::ValidationException) do
48
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
49
- session.request_token({'code' => 'any-code'})
152
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
153
+ session.request_token({ 'code' => 'any-code' })
50
154
  end
51
155
  end
52
156
 
53
157
  test "setup api_key and secret for all sessions" do
54
- ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
55
- assert_equal "My test key", ShopifyAPI::Session.api_key
56
- 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)
57
161
  end
58
162
 
59
- test "use 'https' protocol by default for all sessions" do
60
- assert_equal 'https', ShopifyAPI::Session.protocol
163
+ test "#temp reset ShopifyAPI::Base values to original value" do
164
+ session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
165
+ ShopifyAPI::Base.user = 'foo'
166
+ ShopifyAPI::Base.password = 'bar'
167
+ ShopifyAPI::Base.activate_session(session1)
168
+
169
+ ShopifyAPI::Session.temp(domain: "testshop.myshopify.com", token: "any-token", api_version: :unstable) do
170
+ @assigned_site = ShopifyAPI::Base.site
171
+ @assigned_version = ShopifyAPI::Base.api_version
172
+ @assigned_user = ShopifyAPI::Base.user
173
+ @assigned_password = ShopifyAPI::Base.password
174
+ end
175
+
176
+ assert_equal('https://testshop.myshopify.com', @assigned_site.to_s)
177
+ assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
178
+
179
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: :unstable), @assigned_version)
180
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
181
+
182
+ assert_nil(@assigned_user)
183
+ assert_equal('foo', ShopifyAPI::Base.user)
184
+
185
+ assert_nil(@assigned_password)
186
+ assert_equal('bar', ShopifyAPI::Base.password)
61
187
  end
62
188
 
63
- test "#temp reset ShopifyAPI::Base.site to original value" do
189
+ test "#temp does not use basic auth values from Base.site" do
190
+ ShopifyAPI::Base.site = 'https://user:pass@fakeshop.myshopify.com'
191
+
192
+ ShopifyAPI::Session.temp(domain: "testshop.myshopify.com", token: "any-token", api_version: :unstable) do
193
+ @assigned_site = ShopifyAPI::Base.site
194
+ @assigned_user = ShopifyAPI::Base.user
195
+ @assigned_password = ShopifyAPI::Base.password
196
+ end
197
+
198
+ assert_equal('https://testshop.myshopify.com', @assigned_site.to_s)
199
+ assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
200
+
201
+ assert_nil(@assigned_user)
202
+ assert_equal('user', ShopifyAPI::Base.user)
203
+
204
+ assert_nil(@assigned_password)
205
+ assert_equal('pass', ShopifyAPI::Base.password)
206
+ end
64
207
 
65
- ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret")
66
- session1 = ShopifyAPI::Session.new('fakeshop.myshopify.com', 'token1')
208
+ test "#with_session activates the session for the duration of the block" do
209
+ session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
67
210
  ShopifyAPI::Base.activate_session(session1)
68
211
 
69
- ShopifyAPI::Session.temp("testshop.myshopify.com", "any-token") {
212
+ other_session = ShopifyAPI::Session.new(
213
+ domain: "testshop.myshopify.com",
214
+ token: "any-token",
215
+ api_version: :unstable
216
+ )
217
+
218
+ ShopifyAPI::Session.with_session(other_session) do
70
219
  @assigned_site = ShopifyAPI::Base.site
71
- }
72
- assert_equal 'https://testshop.myshopify.com/admin', @assigned_site.to_s
73
- assert_equal 'https://fakeshop.myshopify.com/admin', ShopifyAPI::Base.site.to_s
220
+ @assigned_version = ShopifyAPI::Base.api_version
221
+ end
222
+
223
+ assert_equal('https://testshop.myshopify.com', @assigned_site.to_s)
224
+ assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
225
+
226
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: :unstable), @assigned_version)
227
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
74
228
  end
75
229
 
76
- test "create_permission_url returns correct url with single scope no redirect uri" do
77
- ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
78
- session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
230
+ test "#with_session resets the activated session even if there an exception during the block" do
231
+ session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
232
+ ShopifyAPI::Base.activate_session(session1)
233
+
234
+ other_session = ShopifyAPI::Session.new(
235
+ domain: "testshop.myshopify.com",
236
+ token: "any-token",
237
+ api_version: :unstable
238
+ )
239
+
240
+ assert_raises(StandardError) do
241
+ ShopifyAPI::Session.with_session(other_session) { raise StandardError, "" }
242
+ end
243
+
244
+ assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
245
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
246
+ end
247
+
248
+ test "#with_version will adjust the actvated api version for the duration of the block" do
249
+ session1 = ShopifyAPI::Session.new(domain: 'fakeshop.myshopify.com', token: 'token1', api_version: '2019-01')
250
+ ShopifyAPI::Base.activate_session(session1)
251
+
252
+ ShopifyAPI::Session.with_version(:unstable) do
253
+ @assigned_site = ShopifyAPI::Base.site
254
+ @assigned_version = ShopifyAPI::Base.api_version
255
+ end
256
+
257
+ assert_equal('https://fakeshop.myshopify.com', @assigned_site.to_s)
258
+ assert_equal('https://fakeshop.myshopify.com', ShopifyAPI::Base.site.to_s)
259
+
260
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: :unstable), @assigned_version)
261
+ assert_equal(ShopifyAPI::ApiVersion.new(handle: '2019-01'), ShopifyAPI::Base.api_version)
262
+ end
263
+
264
+ test "create_permission_url requires redirect_uri" do
265
+ ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
266
+ session = ShopifyAPI::Session.new(
267
+ domain: 'http://localhost.myshopify.com',
268
+ token: 'any-token',
269
+ api_version: any_api_version
270
+ )
79
271
  scope = ["write_products"]
80
- permission_url = session.create_permission_url(scope)
81
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products", permission_url
272
+ assert_raises(ArgumentError) do
273
+ session.create_permission_url(scope)
274
+ end
82
275
  end
83
276
 
84
277
  test "create_permission_url returns correct url with single scope and redirect uri" do
85
- ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
86
- session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
278
+ ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
279
+ session = ShopifyAPI::Session.new(
280
+ domain: 'http://localhost.myshopify.com',
281
+ token: 'any-token',
282
+ api_version: any_api_version
283
+ )
87
284
  scope = ["write_products"]
88
285
  permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
89
- 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(
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
+ )
90
291
  end
91
292
 
92
- test "create_permission_url returns correct url with dual scope no redirect uri" do
93
- ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
94
- session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
95
- scope = ["write_products","write_customers"]
96
- permission_url = session.create_permission_url(scope)
97
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products,write_customers", permission_url
293
+ test "create_permission_url returns correct url with dual scope" do
294
+ ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
295
+ session = ShopifyAPI::Session.new(
296
+ domain: 'http://localhost.myshopify.com',
297
+ token: 'any-token',
298
+ api_version: any_api_version
299
+ )
300
+ scope = ["write_products", "write_customers"]
301
+ permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
302
+ assert_equal(
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
+ )
98
307
  end
99
308
 
100
- test "create_permission_url returns correct url with no scope no redirect uri" do
101
- ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
102
- session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
309
+ test "create_permission_url returns correct url with no scope" do
310
+ ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
311
+ session = ShopifyAPI::Session.new(
312
+ domain: 'http://localhost.myshopify.com',
313
+ token: 'any-token',
314
+ api_version: any_api_version
315
+ )
103
316
  scope = []
104
- permission_url = session.create_permission_url(scope)
105
- assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=", permission_url
317
+ permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
318
+ assert_equal(
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
+ )
106
323
  end
107
324
 
108
- test "raise exception if code invalid in request token" do
109
- ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
110
- session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
111
- fake nil, :url => 'https://localhost.myshopify.com/admin/oauth/access_token',:method => :post, :status => 404, :body => '{"error" : "invalid_request"}'
112
- assert_raises(ShopifyAPI::ValidationException) do
113
- session.request_token(params={:code => "bad-code"})
114
- end
115
- assert_equal false, session.valid?
325
+ test "create_permission_url returns correct url with state" do
326
+ ShopifyAPI::Session.setup(api_key: "My_test_key", secret: "My test secret")
327
+ session = ShopifyAPI::Session.new(
328
+ domain: 'http://localhost.myshopify.com',
329
+ token: 'any-token',
330
+ api_version: any_api_version
331
+ )
332
+ scope = []
333
+ permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", state: "My nonce")
334
+ assert_equal(
335
+ "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
336
+ "scope=&redirect_uri=http://my_redirect_uri.com&state=My%20nonce",
337
+ permission_url
338
+ )
116
339
  end
117
340
 
118
- test "#temp reset ShopifyAPI::Base.site to original value when using a non-standard port" do
119
- ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret")
120
- session1 = ShopifyAPI::Session.new('fakeshop.myshopify.com:3000', 'token1')
121
- ShopifyAPI::Base.activate_session(session1)
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(
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
+ )
122
355
  end
123
356
 
124
- test "myshopify_domain supports non-standard ports" do
125
- begin
126
- ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret", :myshopify_domain => 'localhost', port: '3000')
127
- session = ShopifyAPI::Session.new('fakeshop.localhost:3000', 'token1')
128
- ShopifyAPI::Base.activate_session(session)
129
- assert_equal 'https://fakeshop.localhost:3000/admin', ShopifyAPI::Base.site.to_s
130
-
131
- session = ShopifyAPI::Session.new('fakeshop', 'token1')
132
- ShopifyAPI::Base.activate_session(session)
133
- assert_equal 'https://fakeshop.localhost:3000/admin', ShopifyAPI::Base.site.to_s
134
- ensure
135
- ShopifyAPI::Session.myshopify_domain = "myshopify.com"
136
- ShopifyAPI::Session.port = nil
357
+ test "raise exception if code invalid in request token" do
358
+ ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
359
+ session = ShopifyAPI::Session.new(
360
+ domain: 'http://localhost.myshopify.com',
361
+ token: nil,
362
+ api_version: any_api_version
363
+ )
364
+ fake(
365
+ nil,
366
+ url: 'https://localhost.myshopify.com/admin/oauth/access_token',
367
+ method: :post,
368
+ status: 404,
369
+ body: '{"error" : "invalid_request"}'
370
+ )
371
+ assert_raises(ShopifyAPI::ValidationException) do
372
+ session.request_token(code: "bad-code")
137
373
  end
374
+ assert_equal(false, session.valid?)
138
375
  end
139
376
 
140
377
  test "return site for session" do
141
- session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
142
- assert_equal "https://testshop.myshopify.com/admin", session.site
378
+ session = ShopifyAPI::Session.new(
379
+ domain: "testshop.myshopify.com",
380
+ token: "any-token",
381
+ api_version: any_api_version
382
+ )
383
+ assert_equal("https://testshop.myshopify.com", session.site)
143
384
  end
144
385
 
145
386
  test "return_token_if_signature_is_valid" do
146
- fake nil,
147
- url: 'https://testshop.myshopify.com/admin/oauth/access_token',
387
+ api_version = any_api_version
388
+ fake(
389
+ nil,
390
+ url: "https://testshop.myshopify.com/admin/oauth/access_token",
148
391
  method: :post,
149
392
  body: '{"access_token":"any-token"}'
150
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
393
+ )
394
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
151
395
 
152
396
  params = { code: 'any-code', timestamp: Time.now }
153
397
  token = session.request_token(params.merge(hmac: generate_signature(params)))
154
398
 
155
- assert_equal "any-token", token
156
- assert_equal "any-token", session.token
399
+ assert_equal("any-token", token)
400
+ assert_equal("any-token", session.token)
157
401
  end
158
402
 
159
403
  test "extra parameters are stored in session" do
160
- fake nil,
161
- url: 'https://testshop.myshopify.com/admin/oauth/access_token',
404
+ api_version = ShopifyAPI::ApiVersion.new(handle: :unstable)
405
+ fake(
406
+ nil,
407
+ url: "https://testshop.myshopify.com/admin/oauth/access_token",
162
408
  method: :post,
163
409
  body: '{"access_token":"any-token","foo":"example"}'
164
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
410
+ )
411
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
165
412
 
166
413
  params = { code: 'any-code', timestamp: Time.now }
167
- assert session.request_token(params.merge(hmac: generate_signature(params)))
414
+ assert(session.request_token(params.merge(hmac: generate_signature(params))))
168
415
 
169
- assert_equal ({ "foo" => "example" }), session.extra
416
+ assert_equal({ "foo" => "example" }, session.extra)
170
417
  end
171
418
 
172
419
  test "expires_in is automatically converted in expires_at" do
173
- fake nil,
174
- url: 'https://testshop.myshopify.com/admin/oauth/access_token',
420
+ api_version = any_api_version
421
+ fake(
422
+ nil,
423
+ url: "https://testshop.myshopify.com/admin/oauth/access_token",
175
424
  method: :post,
176
425
  body: '{"access_token":"any-token","expires_in":86393}'
177
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
426
+ )
427
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
178
428
 
179
429
  Timecop.freeze do
180
430
  params = { code: 'any-code', timestamp: Time.now }
181
- assert session.request_token(params.merge(hmac: generate_signature(params)))
431
+ assert(session.request_token(params.merge(hmac: generate_signature(params))))
182
432
 
183
433
  expires_at = Time.now.utc + 86393
184
- assert_equal ({ "expires_at" => expires_at.to_i }), session.extra
185
- assert session.expires_at.is_a?(Time)
186
- assert_equal expires_at.to_i, session.expires_at.to_i
187
- assert_equal 86393, session.expires_in
188
- 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?)
189
439
 
190
440
  Timecop.travel(session.expires_at) do
191
- assert_equal true, session.expired?
441
+ assert_equal(true, session.expired?)
192
442
  end
193
443
  end
194
444
  end
195
445
 
196
446
  test "raise error if signature does not match expected" do
197
- params = {:code => "any-code", :timestamp => Time.now}
447
+ params = { code: "any-code", timestamp: Time.now }
198
448
  signature = generate_signature(params)
199
449
  params[:foo] = 'world'
200
450
  assert_raises(ShopifyAPI::ValidationException) do
201
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
202
- session.request_token(params.merge(:hmac => signature))
451
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
452
+ session.request_token(params.merge(hmac: signature))
203
453
  end
204
454
  end
205
455
 
206
456
  test "raise error if timestamp is too old" do
207
- params = {:code => "any-code", :timestamp => Time.now - 2.days}
457
+ params = { code: "any-code", timestamp: Time.now - 2 * SECONDS_IN_A_DAY }
208
458
  signature = generate_signature(params)
209
459
  params[:foo] = 'world'
210
460
  assert_raises(ShopifyAPI::ValidationException) do
211
- session = ShopifyAPI::Session.new("testshop.myshopify.com")
212
- session.request_token(params.merge(:hmac => signature))
461
+ session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
462
+ session.request_token(params.merge(hmac: signature))
213
463
  end
214
464
  end
215
465
 
216
466
  test "return true when the signature is valid and the keys of params are strings" do
217
- params = {"code" => "any-code", "timestamp" => Time.now}
218
- params["hmac"] = generate_signature(params)
219
- assert_equal true, ShopifyAPI::Session.validate_signature(params)
467
+ params = { 'code' => 'any-code', 'timestamp' => Time.now }
468
+ params[:hmac] = generate_signature(params)
469
+ assert_equal(true, ShopifyAPI::Session.validate_signature(params))
220
470
  end
221
471
 
222
472
  test "return true when validating signature of params with ampersand and equal sign characters" do
223
473
  ShopifyAPI::Session.secret = 'secret'
224
- params = {'a' => '1&b=2', 'c=3&d' => '4'}
225
- to_sign = "a=1%26b=2&c%3D3%26d=4"
226
- params['hmac'] = generate_signature(to_sign)
227
-
228
- assert_equal true, ShopifyAPI::Session.validate_signature(params)
474
+ params = { 'a' => '1&b=2', 'c=3&d' => '4' }
475
+ to_sign = 'a=1%26b=2&c%3D3%26d=4'
476
+ params[:hmac] = generate_signature(to_sign)
477
+ assert_equal(true, ShopifyAPI::Session.validate_signature(params))
229
478
  end
230
479
 
231
480
  test "return true when validating signature of params with percent sign characters" do
232
481
  ShopifyAPI::Session.secret = 'secret'
233
- params = {'a%3D1%26b' => '2%26c%3D3'}
234
- to_sign = "a%253D1%2526b=2%2526c%253D3"
235
- params['hmac'] = generate_signature(to_sign)
482
+ params = { 'a%3D1%26b' => '2%26c%3D3' }
483
+ to_sign = 'a%253D1%2526b=2%2526c%253D3'
484
+ params[:hmac] = generate_signature(to_sign)
485
+ assert_equal(true, ShopifyAPI::Session.validate_signature(params))
486
+ end
487
+
488
+ test "url is aliased to domain to minimize the upgrade changes" do
489
+ session = ShopifyAPI::Session.new(
490
+ domain: "http://testshop.myshopify.com",
491
+ token: "any-token",
492
+ api_version: any_api_version
493
+ )
494
+
495
+ assert_equal('testshop.myshopify.com', session.url)
496
+ end
497
+
498
+ test "#hash returns the same value for equal Sessions" do
499
+ session = ShopifyAPI::Session.new(
500
+ domain: "http://testshop.myshopify.com",
501
+ token: "any-token",
502
+ api_version: '2019-01',
503
+ extra: { foo: "bar" }
504
+ )
505
+ other_session = ShopifyAPI::Session.new(
506
+ domain: "http://testshop.myshopify.com",
507
+ token: "any-token",
508
+ api_version: '2019-01',
509
+ extra: { foo: "bar" }
510
+ )
511
+ assert_equal(session.hash, other_session.hash)
512
+ end
513
+
514
+ test "equality verifies domain" do
515
+ session = ShopifyAPI::Session.new(
516
+ domain: "http://testshop.myshopify.com",
517
+ token: "any-token",
518
+ api_version: '2019-01',
519
+ extra: { foo: "bar" }
520
+ )
521
+ other_session = ShopifyAPI::Session.new(
522
+ domain: "http://testshop.myshopify.com",
523
+ token: "any-token",
524
+ api_version: '2019-01',
525
+ extra: { foo: "bar" }
526
+ )
527
+ different_session = ShopifyAPI::Session.new(
528
+ domain: "http://another_testshop.myshopify.com",
529
+ token: "any-token",
530
+ api_version: '2019-01',
531
+ extra: { foo: "bar" }
532
+ )
533
+ assert_equal(session, other_session)
534
+ refute_equal(session, different_session)
535
+ end
536
+
537
+ test "equality verifies token" do
538
+ session = ShopifyAPI::Session.new(
539
+ domain: "http://testshop.myshopify.com",
540
+ token: "any-token",
541
+ api_version: '2019-01',
542
+ extra: { foo: "bar" }
543
+ )
544
+ different_session = ShopifyAPI::Session.new(
545
+ domain: "http://testshop.myshopify.com",
546
+ token: "very-different-token",
547
+ api_version: '2019-01',
548
+ extra: { foo: "bar" }
549
+ )
550
+ refute_equal(session, different_session)
551
+ end
236
552
 
237
- assert_equal true, ShopifyAPI::Session.validate_signature(params)
553
+ test "equality verifies api_version" do
554
+ session = ShopifyAPI::Session.new(
555
+ domain: "http://testshop.myshopify.com",
556
+ token: "any-token",
557
+ api_version: '2019-01',
558
+ extra: { foo: "bar" }
559
+ )
560
+ different_session = ShopifyAPI::Session.new(
561
+ domain: "http://testshop.myshopify.com",
562
+ token: "any-token",
563
+ api_version: :unstable,
564
+ extra: { foo: "bar" }
565
+ )
566
+ refute_equal(session, different_session)
567
+ end
568
+
569
+ test "equality verifies extra" do
570
+ session = ShopifyAPI::Session.new(
571
+ domain: "http://testshop.myshopify.com",
572
+ token: "any-token",
573
+ api_version: '2019-01',
574
+ extra: { foo: "bar" }
575
+ )
576
+ different_session = ShopifyAPI::Session.new(
577
+ domain: "http://testshop.myshopify.com",
578
+ token: "any-token",
579
+ api_version: '2019-01',
580
+ extra: { bar: "other-bar" }
581
+ )
582
+ refute_equal(session, different_session)
583
+ end
584
+
585
+ test "equality verifies other is a Session" do
586
+ session = ShopifyAPI::Session.new(
587
+ domain: "http://testshop.myshopify.com",
588
+ token: "any-token",
589
+ api_version: '2019-01',
590
+ extra: { foo: "bar" }
591
+ )
592
+ different_session = nil
593
+ refute_equal(session, different_session)
594
+ end
595
+
596
+ test "#eql? and #hash are implemented" do
597
+ session = ShopifyAPI::Session.new(
598
+ domain: "http://testshop.myshopify.com",
599
+ token: "any-token",
600
+ api_version: '2019-01',
601
+ extra: { foo: "bar" }
602
+ )
603
+ other_session = ShopifyAPI::Session.new(
604
+ domain: "http://testshop.myshopify.com",
605
+ token: "any-token",
606
+ api_version: '2019-01',
607
+ extra: { foo: "bar" }
608
+ )
609
+ different_session = ShopifyAPI::Session.new(
610
+ domain: "http://another_testshop.myshopify.com",
611
+ token: "any-token",
612
+ api_version: '2019-01',
613
+ extra: { foo: "bar" }
614
+ )
615
+
616
+ assert_equal([session, different_session], [session, other_session, different_session].uniq)
238
617
  end
239
618
 
240
619
  private
241
620
 
242
621
  def make_sorted_params(params)
243
- sorted_params = params.with_indifferent_access.except(:signature, :hmac, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join('&')
622
+ params.with_indifferent_access.except(
623
+ :signature, :hmac, :action, :controller
624
+ ).collect { |k, v| "#{k}=#{v}" }.sort.join('&')
244
625
  end
245
626
 
246
627
  def generate_signature(params)
247
628
  params = make_sorted_params(params) if params.is_a?(Hash)
248
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, ShopifyAPI::Session.secret, params)
629
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA256'), ShopifyAPI::Session.secret, params)
630
+ end
631
+
632
+ def any_api_version
633
+ version_name = ['2019-01', :unstable].sample(1).first
634
+ ShopifyAPI::ApiVersion.find_version(version_name)
249
635
  end
250
636
  end