shopify_api 9.2.0 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +36 -0
- data/.github/workflows/build.yml +41 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +23 -3
- data/.rubocop_todo.yml +75 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +151 -0
- data/Gemfile_ar51 +1 -1
- data/README.md +40 -30
- data/RELEASING +10 -6
- data/Rakefile +10 -6
- data/docs/graphql.md +1 -1
- data/docs/index.md +1 -1
- data/lib/active_resource/connection_ext.rb +1 -0
- data/lib/active_resource/detailed_log_subscriber.rb +6 -7
- data/lib/active_resource/json_errors.rb +8 -2
- data/lib/shopify_api.rb +8 -1
- data/lib/shopify_api/api_access.rb +57 -0
- data/lib/shopify_api/api_version.rb +6 -5
- data/lib/shopify_api/connection.rb +1 -0
- data/lib/shopify_api/countable.rb +3 -2
- data/lib/shopify_api/disable_prefix_check.rb +2 -2
- data/lib/shopify_api/events.rb +2 -1
- data/lib/shopify_api/graphql.rb +8 -6
- data/lib/shopify_api/limits.rb +3 -2
- data/lib/shopify_api/message_enricher.rb +11 -9
- data/lib/shopify_api/meta.rb +0 -1
- data/lib/shopify_api/metafields.rb +5 -4
- data/lib/shopify_api/pagination_link_headers.rb +4 -3
- data/lib/shopify_api/resources.rb +1 -0
- data/lib/shopify_api/resources/access_scope.rb +1 -1
- data/lib/shopify_api/resources/access_token.rb +1 -0
- data/lib/shopify_api/resources/address.rb +1 -0
- data/lib/shopify_api/resources/announcement.rb +2 -1
- data/lib/shopify_api/resources/application_charge.rb +1 -0
- data/lib/shopify_api/resources/application_credit.rb +1 -0
- data/lib/shopify_api/resources/article.rb +3 -2
- data/lib/shopify_api/resources/asset.rb +6 -5
- data/lib/shopify_api/resources/assigned_fulfillment_order.rb +1 -1
- data/lib/shopify_api/resources/base.rb +11 -6
- data/lib/shopify_api/resources/billing_address.rb +1 -0
- data/lib/shopify_api/resources/blog.rb +2 -1
- data/lib/shopify_api/resources/carrier_service.rb +1 -0
- data/lib/shopify_api/resources/cart.rb +2 -1
- data/lib/shopify_api/resources/collect.rb +1 -0
- data/lib/shopify_api/resources/collection_listing.rb +1 -0
- data/lib/shopify_api/resources/comment.rb +20 -5
- data/lib/shopify_api/resources/country.rb +1 -0
- data/lib/shopify_api/resources/custom_collection.rb +4 -3
- data/lib/shopify_api/resources/customer.rb +2 -1
- data/lib/shopify_api/resources/customer_group.rb +1 -0
- data/lib/shopify_api/resources/customer_invite.rb +1 -0
- data/lib/shopify_api/resources/customer_saved_search.rb +2 -1
- data/lib/shopify_api/resources/discount_code.rb +1 -0
- data/lib/shopify_api/resources/discount_code_batch.rb +4 -2
- data/lib/shopify_api/resources/draft_order.rb +1 -0
- data/lib/shopify_api/resources/draft_order_invoice.rb +1 -0
- data/lib/shopify_api/resources/event.rb +1 -0
- data/lib/shopify_api/resources/fulfillment.rb +12 -3
- data/lib/shopify_api/resources/fulfillment_event.rb +1 -0
- data/lib/shopify_api/resources/fulfillment_order.rb +30 -16
- data/lib/shopify_api/resources/fulfillment_order_locations_for_move.rb +1 -0
- data/lib/shopify_api/resources/fulfillment_request.rb +1 -0
- data/lib/shopify_api/resources/fulfillment_service.rb +1 -0
- data/lib/shopify_api/resources/fulfillment_v2.rb +3 -2
- data/lib/shopify_api/resources/gift_card.rb +1 -0
- data/lib/shopify_api/resources/image.rb +2 -1
- data/lib/shopify_api/resources/inventory_level.rb +2 -3
- data/lib/shopify_api/resources/line_item.rb +4 -3
- data/lib/shopify_api/resources/location.rb +1 -1
- data/lib/shopify_api/resources/marketing_event.rb +1 -0
- data/lib/shopify_api/resources/metafield.rb +1 -0
- data/lib/shopify_api/resources/note_attribute.rb +1 -0
- data/lib/shopify_api/resources/option.rb +1 -0
- data/lib/shopify_api/resources/order.rb +2 -1
- data/lib/shopify_api/resources/order_risk.rb +1 -0
- data/lib/shopify_api/resources/page.rb +1 -0
- data/lib/shopify_api/resources/payment_details.rb +1 -0
- data/lib/shopify_api/resources/policy.rb +1 -0
- data/lib/shopify_api/resources/price_rule.rb +1 -1
- data/lib/shopify_api/resources/product.rb +14 -11
- data/lib/shopify_api/resources/product_listing.rb +1 -0
- data/lib/shopify_api/resources/province.rb +1 -0
- data/lib/shopify_api/resources/receipt.rb +1 -0
- data/lib/shopify_api/resources/recurring_application_charge.rb +4 -1
- data/lib/shopify_api/resources/redirect.rb +1 -0
- data/lib/shopify_api/resources/refund.rb +2 -1
- data/lib/shopify_api/resources/report.rb +1 -0
- data/lib/shopify_api/resources/resource_feedback.rb +1 -1
- data/lib/shopify_api/resources/rule.rb +1 -0
- data/lib/shopify_api/resources/script_tag.rb +1 -0
- data/lib/shopify_api/resources/shipping_address.rb +1 -0
- data/lib/shopify_api/resources/shipping_line.rb +1 -0
- data/lib/shopify_api/resources/shipping_zone.rb +1 -0
- data/lib/shopify_api/resources/shop.rb +2 -1
- data/lib/shopify_api/resources/smart_collection.rb +2 -2
- data/lib/shopify_api/resources/storefront_access_token.rb +1 -0
- data/lib/shopify_api/resources/tax_line.rb +1 -0
- data/lib/shopify_api/resources/tax_service.rb +1 -0
- data/lib/shopify_api/resources/theme.rb +1 -0
- data/lib/shopify_api/resources/transaction.rb +1 -0
- data/lib/shopify_api/resources/usage_charge.rb +1 -0
- data/lib/shopify_api/resources/user.rb +1 -0
- data/lib/shopify_api/resources/variant.rb +16 -18
- data/lib/shopify_api/resources/webhook.rb +1 -0
- data/lib/shopify_api/session.rb +20 -12
- data/lib/shopify_api/version.rb +2 -1
- data/lib/verify_docs.rb +1 -0
- data/service.yml +1 -1
- data/shopify_api.gemspec +10 -4
- data/test/access_token_test.rb +6 -5
- data/test/active_resource/json_errors_test.rb +6 -6
- data/test/api_access_test.rb +153 -0
- data/test/api_version_test.rb +3 -3
- data/test/application_charge_test.rb +30 -27
- data/test/application_credit_test.rb +10 -9
- data/test/article_test.rb +34 -35
- data/test/asset_test.rb +14 -6
- data/test/assigned_fulfillment_order_test.rb +5 -4
- data/test/base_test.rb +55 -56
- data/test/blog_test.rb +4 -3
- data/test/carrier_service_test.rb +7 -6
- data/test/cart_test.rb +2 -1
- data/test/collect_test.rb +4 -3
- data/test/collection_listing_test.rb +21 -16
- data/test/collection_publication_test.rb +8 -8
- data/test/collection_test.rb +20 -19
- data/test/countable_test.rb +3 -2
- data/test/currency_test.rb +5 -5
- data/test/custom_collection_test.rb +4 -3
- data/test/customer_saved_search_test.rb +18 -8
- data/test/customer_test.rb +22 -14
- data/test/detailed_log_subscriber_test.rb +15 -11
- data/test/discount_code_batch_test.rb +11 -10
- data/test/discount_code_test.rb +21 -15
- data/test/draft_order_test.rb +68 -52
- data/test/fixtures/assigned_fulfillment_orders.json +2 -0
- data/test/fixtures/fulfillment_order.json +1 -0
- data/test/fixtures/fulfillment_orders.json +2 -0
- data/test/fulfillment_event_test.rb +31 -26
- data/test/fulfillment_order_test.rb +215 -147
- data/test/fulfillment_order_test_helper.rb +1 -0
- data/test/fulfillment_request_test.rb +10 -8
- data/test/fulfillment_service_test.rb +13 -12
- data/test/fulfillment_test.rb +81 -66
- data/test/fulfillment_v2_test.rb +16 -12
- data/test/gift_card_test.rb +6 -4
- data/test/graphql_test.rb +27 -27
- data/test/image_test.rb +19 -17
- data/test/inventory_level_test.rb +24 -15
- data/test/lib/webmock_extensions/last_request.rb +1 -1
- data/test/limits_test.rb +2 -1
- data/test/location_test.rb +2 -1
- data/test/marketing_event_test.rb +20 -20
- data/test/message_enricher_test.rb +6 -6
- data/test/meta_test.rb +7 -9
- data/test/metafield_test.rb +30 -20
- data/test/order_risk_test.rb +17 -16
- data/test/order_test.rb +43 -28
- data/test/pagination_test.rb +89 -56
- data/test/policy_test.rb +6 -5
- data/test/price_rule_test.rb +20 -15
- data/test/product_listing_test.rb +20 -20
- data/test/product_publication_test.rb +8 -8
- data/test/product_test.rb +44 -32
- data/test/publication_test.rb +3 -3
- data/test/recurring_application_charge_test.rb +104 -42
- data/test/redirect_test.rb +4 -3
- data/test/refund_test.rb +22 -17
- data/test/report_test.rb +12 -10
- data/test/resource_feedback_test.rb +14 -13
- data/test/script_tag_test.rb +10 -9
- data/test/session_test.rb +74 -46
- data/test/shipping_zone_test.rb +4 -3
- data/test/shop_test.rb +47 -33
- data/test/smart_collection_test.rb +5 -4
- data/test/storefront_access_token_test.rb +13 -15
- data/test/tax_service_test.rb +7 -4
- data/test/tender_transaction_test.rb +3 -3
- data/test/test_helper.rb +13 -11
- data/test/transaction_test.rb +4 -3
- data/test/usage_charge_test.rb +12 -8
- data/test/user_test.rb +4 -3
- data/test/variant_test.rb +23 -54
- data/test/webhook_test.rb +10 -7
- metadata +14 -9
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
- data/.travis.yml +0 -28
data/test/redirect_test.rb
CHANGED
|
@@ -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
|
|
6
|
-
redirect = ShopifyAPI::Redirect.create(:
|
|
7
|
-
assert_equal
|
|
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
|
|
6
|
+
fake("orders/450789469/refunds", method: :post, status: 201, body: load_fixture('refund'))
|
|
7
7
|
refund = ShopifyAPI::Refund.create(
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:
|
|
11
|
-
:
|
|
12
|
-
:
|
|
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
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
|
26
|
-
data = { :
|
|
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, :
|
|
29
|
-
assert_equal
|
|
30
|
-
assert_equal
|
|
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
|
|
6
|
+
fake('reports/987', method: :get, status: 200, body: load_fixture('report'))
|
|
6
7
|
|
|
7
8
|
report = ShopifyAPI::Report.find(987)
|
|
8
|
-
assert_equal
|
|
9
|
+
assert_equal(987, report.id)
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
test 'get all should get all reports' do
|
|
12
|
-
fake
|
|
13
|
+
fake('reports', method: :get, status: 200, body: load_fixture('reports'))
|
|
13
14
|
|
|
14
15
|
reports = ShopifyAPI::Report.all
|
|
15
|
-
assert_equal
|
|
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
|
|
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
|
|
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
|
|
27
|
+
assert_equal('custom_app_reports', report.category)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
test 'delete should delete report' do
|
|
29
|
-
fake
|
|
30
|
-
fake
|
|
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
|
|
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: [
|
|
4
|
-
fake
|
|
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
|
|
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
|
|
12
|
+
fake('resource_feedback', method: :post, body: body)
|
|
12
13
|
ShopifyAPI::ResourceFeedback.new.save
|
|
13
|
-
assert_request_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: [
|
|
18
|
-
fake
|
|
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
|
|
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
|
|
26
|
+
fake('products/42/resource_feedback', method: :post, body: body)
|
|
26
27
|
ShopifyAPI::ResourceFeedback.new(product_id: 42).save
|
|
27
|
-
assert_request_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
|
|
33
|
+
fake('resource_feedback', method: :post, body: body)
|
|
33
34
|
resource_feedback = ShopifyAPI::ResourceFeedback.new
|
|
34
35
|
resource_feedback.save
|
|
35
|
-
assert_request_body
|
|
36
|
+
assert_request_body(body)
|
|
36
37
|
|
|
37
38
|
ShopifyAPI::ResourceFeedback.any_instance.expects(:persisted?).returns(true)
|
|
38
|
-
assert_raises
|
|
39
|
+
assert_raises(ShopifyAPI::ResourceFeedback::ExistingFeedbackSaved) do
|
|
39
40
|
resource_feedback.save
|
|
40
41
|
end
|
|
41
42
|
end
|
data/test/script_tag_test.rb
CHANGED
|
@@ -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
|
|
6
|
+
fake('script_tags', method: :get, status: 200, body: load_fixture('script_tags'))
|
|
6
7
|
script_tags = ShopifyAPI::ScriptTag.all
|
|
7
|
-
assert_equal
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
27
|
+
fake('script_tags/421379493', method: :put, status: 200, body: load_fixture('script_tag'))
|
|
27
28
|
script_tag.save
|
|
28
|
-
assert_equal
|
|
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
|
|
@@ -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
|
|
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
|
|
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
|
|
25
|
+
assert_not(session.valid?)
|
|
24
26
|
|
|
25
|
-
session = ShopifyAPI::Session.new(
|
|
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?)
|
|
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
|
|
32
|
-
assert_equal
|
|
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(
|
|
38
|
-
|
|
39
|
-
|
|
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,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
45
51
|
token: "any-token",
|
|
46
52
|
api_version: any_api_version
|
|
47
53
|
)
|
|
48
|
-
assert
|
|
54
|
+
assert(session.valid?)
|
|
49
55
|
end
|
|
50
56
|
|
|
51
57
|
test "not raise error without params" do
|
|
@@ -81,14 +87,14 @@ class SessionTest < Test::Unit::TestCase
|
|
|
81
87
|
test "raise error if params passed but signature omitted" do
|
|
82
88
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
83
89
|
session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
|
|
84
|
-
session.request_token({'code' => 'any-code'})
|
|
90
|
+
session.request_token({ 'code' => 'any-code' })
|
|
85
91
|
end
|
|
86
92
|
end
|
|
87
93
|
|
|
88
94
|
test "setup api_key and secret for all sessions" do
|
|
89
|
-
ShopifyAPI::Session.setup(:
|
|
90
|
-
assert_equal
|
|
91
|
-
assert_equal
|
|
95
|
+
ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
|
|
96
|
+
assert_equal("My test key", ShopifyAPI::Session.api_key)
|
|
97
|
+
assert_equal("My test secret", ShopifyAPI::Session.secret)
|
|
92
98
|
end
|
|
93
99
|
|
|
94
100
|
test "#temp reset ShopifyAPI::Base values to original value" do
|
|
@@ -168,7 +174,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
168
174
|
api_version: :unstable
|
|
169
175
|
)
|
|
170
176
|
|
|
171
|
-
assert_raises
|
|
177
|
+
assert_raises(StandardError) do
|
|
172
178
|
ShopifyAPI::Session.with_session(other_session) { raise StandardError, "" }
|
|
173
179
|
end
|
|
174
180
|
|
|
@@ -214,7 +220,11 @@ class SessionTest < Test::Unit::TestCase
|
|
|
214
220
|
)
|
|
215
221
|
scope = ["write_products"]
|
|
216
222
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
|
|
217
|
-
assert_equal
|
|
223
|
+
assert_equal(
|
|
224
|
+
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
|
225
|
+
"scope=write_products&redirect_uri=http://my_redirect_uri.com",
|
|
226
|
+
permission_url
|
|
227
|
+
)
|
|
218
228
|
end
|
|
219
229
|
|
|
220
230
|
test "create_permission_url returns correct url with dual scope" do
|
|
@@ -224,9 +234,13 @@ class SessionTest < Test::Unit::TestCase
|
|
|
224
234
|
token: 'any-token',
|
|
225
235
|
api_version: any_api_version
|
|
226
236
|
)
|
|
227
|
-
scope = ["write_products","write_customers"]
|
|
237
|
+
scope = ["write_products", "write_customers"]
|
|
228
238
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
|
|
229
|
-
assert_equal
|
|
239
|
+
assert_equal(
|
|
240
|
+
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
|
241
|
+
"scope=write_products,write_customers&redirect_uri=http://my_redirect_uri.com",
|
|
242
|
+
permission_url
|
|
243
|
+
)
|
|
230
244
|
end
|
|
231
245
|
|
|
232
246
|
test "create_permission_url returns correct url with no scope" do
|
|
@@ -238,7 +252,11 @@ class SessionTest < Test::Unit::TestCase
|
|
|
238
252
|
)
|
|
239
253
|
scope = []
|
|
240
254
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
|
|
241
|
-
assert_equal
|
|
255
|
+
assert_equal(
|
|
256
|
+
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
|
257
|
+
"scope=&redirect_uri=http://my_redirect_uri.com",
|
|
258
|
+
permission_url
|
|
259
|
+
)
|
|
242
260
|
end
|
|
243
261
|
|
|
244
262
|
test "create_permission_url returns correct url with state" do
|
|
@@ -250,11 +268,15 @@ class SessionTest < Test::Unit::TestCase
|
|
|
250
268
|
)
|
|
251
269
|
scope = []
|
|
252
270
|
permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com", state: "My nonce")
|
|
253
|
-
assert_equal
|
|
271
|
+
assert_equal(
|
|
272
|
+
"https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&" \
|
|
273
|
+
"scope=&redirect_uri=http://my_redirect_uri.com&state=My%20nonce",
|
|
274
|
+
permission_url
|
|
275
|
+
)
|
|
254
276
|
end
|
|
255
277
|
|
|
256
278
|
test "raise exception if code invalid in request token" do
|
|
257
|
-
ShopifyAPI::Session.setup(:
|
|
279
|
+
ShopifyAPI::Session.setup(api_key: "My test key", secret: "My test secret")
|
|
258
280
|
session = ShopifyAPI::Session.new(
|
|
259
281
|
domain: 'http://localhost.myshopify.com',
|
|
260
282
|
token: nil,
|
|
@@ -270,7 +292,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
270
292
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
271
293
|
session.request_token(code: "bad-code")
|
|
272
294
|
end
|
|
273
|
-
assert_equal
|
|
295
|
+
assert_equal(false, session.valid?)
|
|
274
296
|
end
|
|
275
297
|
|
|
276
298
|
test "return site for session" do
|
|
@@ -279,87 +301,93 @@ class SessionTest < Test::Unit::TestCase
|
|
|
279
301
|
token: "any-token",
|
|
280
302
|
api_version: any_api_version
|
|
281
303
|
)
|
|
282
|
-
assert_equal
|
|
304
|
+
assert_equal("https://testshop.myshopify.com", session.site)
|
|
283
305
|
end
|
|
284
306
|
|
|
285
307
|
test "return_token_if_signature_is_valid" do
|
|
286
308
|
api_version = any_api_version
|
|
287
|
-
fake
|
|
309
|
+
fake(
|
|
310
|
+
nil,
|
|
288
311
|
url: "https://testshop.myshopify.com/admin/oauth/access_token",
|
|
289
312
|
method: :post,
|
|
290
313
|
body: '{"access_token":"any-token"}'
|
|
314
|
+
)
|
|
291
315
|
session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
|
|
292
316
|
|
|
293
317
|
params = { code: 'any-code', timestamp: Time.now }
|
|
294
318
|
token = session.request_token(params.merge(hmac: generate_signature(params)))
|
|
295
319
|
|
|
296
|
-
assert_equal
|
|
297
|
-
assert_equal
|
|
320
|
+
assert_equal("any-token", token)
|
|
321
|
+
assert_equal("any-token", session.token)
|
|
298
322
|
end
|
|
299
323
|
|
|
300
324
|
test "extra parameters are stored in session" do
|
|
301
325
|
api_version = ShopifyAPI::ApiVersion.new(handle: :unstable)
|
|
302
|
-
fake
|
|
326
|
+
fake(
|
|
327
|
+
nil,
|
|
303
328
|
url: "https://testshop.myshopify.com/admin/oauth/access_token",
|
|
304
329
|
method: :post,
|
|
305
330
|
body: '{"access_token":"any-token","foo":"example"}'
|
|
331
|
+
)
|
|
306
332
|
session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
|
|
307
333
|
|
|
308
334
|
params = { code: 'any-code', timestamp: Time.now }
|
|
309
|
-
assert
|
|
335
|
+
assert(session.request_token(params.merge(hmac: generate_signature(params))))
|
|
310
336
|
|
|
311
|
-
assert_equal
|
|
337
|
+
assert_equal({ "foo" => "example" }, session.extra)
|
|
312
338
|
end
|
|
313
339
|
|
|
314
340
|
test "expires_in is automatically converted in expires_at" do
|
|
315
341
|
api_version = any_api_version
|
|
316
|
-
fake
|
|
342
|
+
fake(
|
|
343
|
+
nil,
|
|
317
344
|
url: "https://testshop.myshopify.com/admin/oauth/access_token",
|
|
318
345
|
method: :post,
|
|
319
346
|
body: '{"access_token":"any-token","expires_in":86393}'
|
|
347
|
+
)
|
|
320
348
|
session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: api_version)
|
|
321
349
|
|
|
322
350
|
Timecop.freeze do
|
|
323
351
|
params = { code: 'any-code', timestamp: Time.now }
|
|
324
|
-
assert
|
|
352
|
+
assert(session.request_token(params.merge(hmac: generate_signature(params))))
|
|
325
353
|
|
|
326
354
|
expires_at = Time.now.utc + 86393
|
|
327
|
-
assert_equal
|
|
328
|
-
assert
|
|
329
|
-
assert_equal
|
|
330
|
-
assert_equal
|
|
331
|
-
assert_equal
|
|
355
|
+
assert_equal({ "expires_at" => expires_at.to_i }, session.extra)
|
|
356
|
+
assert(session.expires_at.is_a?(Time))
|
|
357
|
+
assert_equal(expires_at.to_i, session.expires_at.to_i)
|
|
358
|
+
assert_equal(86393, session.expires_in)
|
|
359
|
+
assert_equal(false, session.expired?)
|
|
332
360
|
|
|
333
361
|
Timecop.travel(session.expires_at) do
|
|
334
|
-
assert_equal
|
|
362
|
+
assert_equal(true, session.expired?)
|
|
335
363
|
end
|
|
336
364
|
end
|
|
337
365
|
end
|
|
338
366
|
|
|
339
367
|
test "raise error if signature does not match expected" do
|
|
340
|
-
params = {:
|
|
368
|
+
params = { code: "any-code", timestamp: Time.now }
|
|
341
369
|
signature = generate_signature(params)
|
|
342
370
|
params[:foo] = 'world'
|
|
343
371
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
344
372
|
session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
|
|
345
|
-
session.request_token(params.merge(:
|
|
373
|
+
session.request_token(params.merge(hmac: signature))
|
|
346
374
|
end
|
|
347
375
|
end
|
|
348
376
|
|
|
349
377
|
test "raise error if timestamp is too old" do
|
|
350
|
-
params = {:
|
|
378
|
+
params = { code: "any-code", timestamp: Time.now - 2 * SECONDS_IN_A_DAY }
|
|
351
379
|
signature = generate_signature(params)
|
|
352
380
|
params[:foo] = 'world'
|
|
353
381
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
354
382
|
session = ShopifyAPI::Session.new(domain: "testshop.myshopify.com", token: nil, api_version: any_api_version)
|
|
355
|
-
session.request_token(params.merge(:
|
|
383
|
+
session.request_token(params.merge(hmac: signature))
|
|
356
384
|
end
|
|
357
385
|
end
|
|
358
386
|
|
|
359
387
|
test "return true when the signature is valid and the keys of params are strings" do
|
|
360
388
|
params = { 'code' => 'any-code', 'timestamp' => Time.now }
|
|
361
389
|
params[:hmac] = generate_signature(params)
|
|
362
|
-
assert_equal
|
|
390
|
+
assert_equal(true, ShopifyAPI::Session.validate_signature(params))
|
|
363
391
|
end
|
|
364
392
|
|
|
365
393
|
test "return true when validating signature of params with ampersand and equal sign characters" do
|
|
@@ -367,7 +395,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
367
395
|
params = { 'a' => '1&b=2', 'c=3&d' => '4' }
|
|
368
396
|
to_sign = 'a=1%26b=2&c%3D3%26d=4'
|
|
369
397
|
params[:hmac] = generate_signature(to_sign)
|
|
370
|
-
assert_equal
|
|
398
|
+
assert_equal(true, ShopifyAPI::Session.validate_signature(params))
|
|
371
399
|
end
|
|
372
400
|
|
|
373
401
|
test "return true when validating signature of params with percent sign characters" do
|
|
@@ -375,7 +403,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
375
403
|
params = { 'a%3D1%26b' => '2%26c%3D3' }
|
|
376
404
|
to_sign = 'a%253D1%2526b=2%2526c%253D3'
|
|
377
405
|
params[:hmac] = generate_signature(to_sign)
|
|
378
|
-
assert_equal
|
|
406
|
+
assert_equal(true, ShopifyAPI::Session.validate_signature(params))
|
|
379
407
|
end
|
|
380
408
|
|
|
381
409
|
test "url is aliased to domain to minimize the upgrade changes" do
|
|
@@ -519,7 +547,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
519
547
|
|
|
520
548
|
def generate_signature(params)
|
|
521
549
|
params = make_sorted_params(params) if params.is_a?(Hash)
|
|
522
|
-
OpenSSL::HMAC.hexdigest(OpenSSL::Digest
|
|
550
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA256'), ShopifyAPI::Session.secret, params)
|
|
523
551
|
end
|
|
524
552
|
|
|
525
553
|
def any_api_version
|