From dc1d360d9c0a5d06cb845d8ecfae27651ed6f3d9 Mon Sep 17 00:00:00 2001 From: Gareth du Plooy Date: Wed, 17 Jul 2019 13:49:45 -0500 Subject: [PATCH] Fix internals to parse headers on initialization --- README.md | 2 +- lib/shopify_api/collection_pagination.rb | 31 +++++++++-------- test/pagination_test.rb | 42 ++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 60bf8e6fc..6df6cb311 100644 --- a/README.md +++ b/README.md @@ -384,7 +384,7 @@ end Page based pagination will be deprecated in the `2019-10` API version, in favor of the second method of pagination: [Relative cursor based pagination](https://help.shopify.com/en/api/guides/paginated-rest-results) -``` +```ruby products = ShopifyAPI::Product.find(:all, params: { limit: 50 }) process_products(products) while products.next_page? diff --git a/lib/shopify_api/collection_pagination.rb b/lib/shopify_api/collection_pagination.rb index b1c4e5389..06b727315 100644 --- a/lib/shopify_api/collection_pagination.rb +++ b/lib/shopify_api/collection_pagination.rb @@ -1,20 +1,28 @@ module ShopifyAPI module CollectionPagination + def initialize(args) + @previous_url_params = extract_url_params(pagination_link_headers.previous_link) + @next_url_params = extract_url_params(pagination_link_headers.next_link) + super(args) + end + def next_page? - next_url_params.present? + ensure_available + @next_url_params.present? end def previous_page? - previous_url_params.present? + ensure_available + @previous_url_params.present? end def fetch_next_page - fetch_page(next_url_params) + fetch_page(@next_url_params) end def fetch_previous_page - fetch_page(previous_url_params) + fetch_page(@previous_url_params) end private @@ -22,22 +30,13 @@ def fetch_previous_page AVAILABLE_IN_VERSION = ShopifyAPI::ApiVersion::Unstable.new def fetch_page(url_params) + ensure_available return [] unless url_params.present? resource_class.where(url_params) end - def previous_url_params - @previous_url_params ||= extract_url_params(pagination_link_headers.previous_link) - end - - def next_url_params - @next_url_params ||= extract_url_params(pagination_link_headers.next_link) - end - def extract_url_params(link_header) - raise NotImplementedError unless ShopifyAPI::Base.api_version >= AVAILABLE_IN_VERSION - return nil unless link_header.present? Rack::Utils.parse_nested_query(link_header.url.query) end @@ -47,5 +46,9 @@ def pagination_link_headers ShopifyAPI::Base.connection.response["Link"] ) end + + def ensure_available + raise NotImplementedError unless ShopifyAPI::Base.api_version >= AVAILABLE_IN_VERSION + end end end diff --git a/test/pagination_test.rb b/test/pagination_test.rb index f3becdbd5..ad654702f 100644 --- a/test/pagination_test.rb +++ b/test/pagination_test.rb @@ -124,10 +124,9 @@ def setup test "raises on invalid pagination links" do link_header = ";" fake 'orders', :method => :get, :status => 200, api_version: @version, :body => load_fixture('orders'), :link => link_header - orders = ShopifyAPI::Order.all assert_raises ShopifyAPI::InvalidPaginationLinksError do - orders.fetch_next_page + ShopifyAPI::Order.all end end @@ -142,4 +141,43 @@ def setup orders.fetch_next_page end end + + test "allows for multiple concurrent API collection objects" do + first_request_params = "page_info=#{@next_page_info}&limit=5" + fake( + 'orders', + method: :get, + status: 200, + api_version: @version, + url: "https://this-is-my-test-shop.myshopify.com/admin/api/unstable/orders.json?limit=5", + body: load_fixture('orders'), + link: "; rel=\"next\"" + ) + orders = ShopifyAPI::Order.where(limit: 5) + + second_request_params = "page_info=#{@next_page_info}&limit=5" + fake( + 'orders', + method: :get, + status: 200, + api_version: @version, + url: "https://this-is-my-test-shop.myshopify.com/admin/api/unstable/orders.json?limit=10", + body: load_fixture('orders'), + link: "; rel=\"next\"" + ) + + orders2 = ShopifyAPI::Order.where(limit: 10) + + fake( + 'orders', + method: :get, + status: 200, + api_version: @version, + url: "https://this-is-my-test-shop.myshopify.com/admin/api/unstable/orders.json?limit=5&page_info=#{@next_page_info}", + body: load_fixture('orders') + ) + next_page = orders.fetch_next_page + assert_equal 450789469, next_page.first.id + end + end