Selaa lähdekoodia

add coercion modes for apiversion validation

fix errors
Jon G 5 vuotta sitten
vanhempi
commit
c76e916350

+ 0 - 2
lib/shopify_api.rb

@@ -28,5 +28,3 @@ if ShopifyAPI::Base.respond_to?(:connection_class)
 else
   require 'active_resource/connection_ext'
 end
-
-ShopifyAPI::ApiVersion.define_known_versions

+ 36 - 14
lib/shopify_api/api_version.rb

@@ -13,41 +13,63 @@ module ShopifyAPI
     UNSTABLE_HANDLE = 'unstable'
     UNSTABLE_AS_DATE = Time.utc(3000, 1, 1)
     API_PREFIX = '/admin/api/'
+    COERSION_MODES = [:predefined_only, :define_on_unknown].freeze
 
     class << self
       attr_reader :versions
 
+      def coercion_mode
+        @coercion_mode ||= :define_on_unknown
+      end
+
+      def coercion_mode=(mode)
+        raise ArgumentError, "Mode must be one of #{COERSION_MODES}" unless COERSION_MODES.include?(mode)
+        sanitize_known_versions if mode == :predefined_only
+        @coercion_mode = mode
+      end
+
       def coerce_to_version(version_or_handle)
         return version_or_handle if version_or_handle.is_a?(ApiVersion)
-        if @versions.nil?
-          warn "[API VERSION WARNING] Known API Version set is empty. Initializing unvalidated version from handle."
-          return ApiVersion.new(handle: version_or_handle)
-        end
-
-        @versions[version_or_handle.to_s].tap do |api_version|
-          unless api_version
-            raise ApiVersion::UnknownVersion, "UnknownVersion API version specified, `#{version_or_handle}`. \n Versions available: #{@versions.keys}"
+        handle = version_or_handle.to_s
+
+        @versions ||= {}
+        @versions.fetch(handle) do
+          if @coercion_mode == :predefined_only
+            error_msg = if @versions.empty?
+              "No versions defined. You must call `ApiVersion.define_known_versions` first."
+            else
+              "`#{handle}` is not in the defined version set. Available versions: #{@versions.keys}"
+            end
+            raise UnknownVersion, "ApiVersion.coercion_mode is set to `:predefined_only`. #{error_msg}"
+          else
+            @versions[handle] = ApiVersion.new(handle: version_or_handle)
           end
         end
       end
 
       def define_known_versions
         @versions = Meta.admin_versions.map { |version| [version.handle, version] }.to_h
-      rescue ActiveResource::ConnectionError => e
-        warn "[API VERSION WARNING] Could not fetch Admin API versions."
-        warn "[API VERSION WARNING] #{e.message}"
-        @versions = nil
       end
 
       def clear_defined_versions
-        @versions = nil
+        @versions = {}
       end
 
       def latest_stable_version
         warn(
           '[DEPRECATED] ShopifyAPI::ApiVersion.latest_stable_version is deprecated and will be removed in a future version.'
         )
-        @versions.values.find(&:latest_supported?)
+        versions.values.find(&:latest_supported?)
+      end
+
+      private
+
+      def sanitize_known_versions
+        return if @versions.nil?
+        @versions = @versions.keys.map do |handle|
+          next unless @versions[handle].persisted?
+          [handle, @versions[handle]]
+        end.compact.to_h
       end
     end
 

+ 35 - 17
test/api_version_test.rb

@@ -19,17 +19,33 @@ class ApiVersionTest < Test::Unit::TestCase
     ])
   end
 
-  test "coerce_to_version raises when coercing a string that doesn't match a known version" do
-    refute ShopifyAPI::ApiVersion.versions.nil?
-    assert_raises ShopifyAPI::ApiVersion::UnknownVersion do
+  test "coerce_to_version removes unpersisted versions from version set if mode is set to :predefined_only" do
+    ShopifyAPI::ApiVersion.coercion_mode = :define_on_unknown
+    assert ShopifyAPI::ApiVersion.versions.values.all?(&:persisted?)
+    assert_equal 5, ShopifyAPI::ApiVersion.versions.size
+
+    ShopifyAPI::ApiVersion.coerce_to_version('2019-30')
+    refute ShopifyAPI::ApiVersion.versions.values.all?(&:persisted?)
+    assert_equal 6, ShopifyAPI::ApiVersion.versions.size
+    ShopifyAPI::ApiVersion.coercion_mode = :predefined_only
+
+    assert ShopifyAPI::ApiVersion.versions.values.all?(&:persisted?)
+    assert_equal 5, ShopifyAPI::ApiVersion.versions.size
+  end
+
+  test "coerce_to_version does not raise when coercing a string if no versions are defined when coercion_mode is :define_on_unknown" do
+    ShopifyAPI::ApiVersion.clear_defined_versions
+    ShopifyAPI::ApiVersion.coercion_mode = :define_on_unknown
+    assert_equal :define_on_unknown, ShopifyAPI::ApiVersion.coercion_mode
+    assert_nothing_raised do
       ShopifyAPI::ApiVersion.coerce_to_version('made up version')
     end
   end
 
-  test "coerce_to_version does not raise when coercing a string if no versions are defined" do
-    ShopifyAPI::ApiVersion.clear_defined_versions
-    assert_nil ShopifyAPI::ApiVersion.versions
-    assert_nothing_raised  do
+  test "coerce_to_version does raise when coercing a string if no versions are defined when coercion_mode is :predefined_only" do
+    refute ShopifyAPI::ApiVersion.versions['made up version']
+    ShopifyAPI::ApiVersion.coercion_mode = :predefined_only
+    assert_raises ShopifyAPI::ApiVersion::UnknownVersion do
       ShopifyAPI::ApiVersion.coerce_to_version('made up version')
     end
   end
@@ -77,20 +93,22 @@ class ApiVersionTest < Test::Unit::TestCase
         "2019-01" => ShopifyAPI::ApiVersion.new(handle: '2019-01', supported: true, latest_supported: false),
         "2019-04" => ShopifyAPI::ApiVersion.new(handle: '2019-04', supported: true, latest_supported: false),
         "2019-07" => ShopifyAPI::ApiVersion.new(handle: '2019-07', supported: true, latest_supported: true),
-        "2019-10" => ShopifyAPI::ApiVersion.new(handle: '2019-10', supported: true, latest_supported: false),
-        "unstable" => ShopifyAPI::ApiVersion.new(handle: 'unstable', supported: true, latest_supported: false),
+        "2019-10" => ShopifyAPI::ApiVersion.new(handle: '2019-10', supported: false, latest_supported: false),
+        "unstable" => ShopifyAPI::ApiVersion.new(handle: 'unstable', supported: false, latest_supported: false),
       }
     )
+    silence_warnings do
 
-    refute_equal(
-      ShopifyAPI::ApiVersion.new(handle: '2019-01'),
-      ShopifyAPI::ApiVersion.latest_stable_version
-    )
+      refute_equal(
+        ShopifyAPI::ApiVersion.new(handle: '2019-01'),
+        ShopifyAPI::ApiVersion.latest_stable_version
+      )
 
-    assert_equal(
-      ShopifyAPI::ApiVersion.new(handle: '2019-07'),
-      ShopifyAPI::ApiVersion.latest_stable_version
-    )
+      assert_equal(
+        ShopifyAPI::ApiVersion.new(handle: '2019-07'),
+        ShopifyAPI::ApiVersion.latest_stable_version
+      )
+    end
   end
 
   test "NullVersion raises ApiVersionNotSetError" do

+ 12 - 5
test/detailed_log_subscriber_test.rb

@@ -14,13 +14,14 @@ class LogSubscriberTest < Test::Unit::TestCase
     @request_headers = "Headers: {\"Accept\"=>\"application/json\", " \
       "#{@ua_header}, \"X-Shopify-Access-Token\"=>\"access_token\"}"
 
-    fake("api_versions",
+    ShopifyAPI::Base.clear_session
+    fake("apis",
+      url: "https://app.shopify.com/services/apis.json",
       method: :get,
       status: 200,
-      api_version: ShopifyAPI::ApiVersion.new(handle: :unstable),
-      body: load_fixture('api_versions'))
-
-    ShopifyAPI::Base.clear_session
+      api_version: :stub,
+      body: load_fixture('apis'))
+    ShopifyAPI::ApiVersion.define_known_versions
     session = ShopifyAPI::Session.new(
       domain: "https://this-is-my-test-shop.myshopify.com",
       token: "access_token",
@@ -33,6 +34,12 @@ class LogSubscriberTest < Test::Unit::TestCase
     ActiveResource::DetailedLogSubscriber.attach_to :active_resource_detailed
   end
 
+  def teardown
+    super
+    ShopifyAPI::ApiVersion.clear_defined_versions
+    ShopifyAPI::ApiVersion.coercion_mode = :predefined_only
+  end
+
   def set_logger(logger)
     ActiveResource::Base.logger = logger
   end

+ 3 - 3
test/pagination_test.rb

@@ -4,7 +4,7 @@ class PaginationTest < Test::Unit::TestCase
   def setup
     super
 
-    @version = ShopifyAPI::ApiVersion::Release.new('2019-10')
+    @version = ShopifyAPI::ApiVersion.coerce_to_version('2019-10')
     ShopifyAPI::Base.api_version = @version.to_s
     @next_page_info = "eyJkaXJlY3Rpb24iOiJuZXh0IiwibGFzdF9pZCI6NDQwMDg5NDIzLCJsYXN0X3ZhbHVlIjoiNDQwMDg5NDIzIn0%3D"
     @previous_page_info = "eyJsYXN0X2lkIjoxMDg4MjgzMDksImxhc3RfdmFsdWUiOiIxMDg4MjgzMDkiLCJkaXJlY3Rpb24iOiJuZXh0In0%3D"
@@ -131,7 +131,7 @@ class PaginationTest < Test::Unit::TestCase
   end
 
   test "raises on an older API version" do
-    version = ShopifyAPI::ApiVersion::Release.new('2019-04')
+    version = ShopifyAPI::ApiVersion.coerce_to_version('2019-04')
     ShopifyAPI::Base.api_version = version.to_s
 
     fake 'orders', :method => :get, :status => 200, api_version: version, :body => load_fixture('orders')
@@ -166,7 +166,7 @@ class PaginationTest < Test::Unit::TestCase
   end
 
   test "does not raise on the unstable version" do
-    version = ShopifyAPI::ApiVersion::Unstable.new
+    version = ShopifyAPI::ApiVersion.coerce_to_version('unstable')
     ShopifyAPI::Base.api_version = version.to_s
     @next_link_header = "<https://this-is-my-test-shop.myshopify.com/admin/api/unstable/orders.json?page_info=#{@next_page_info}>; rel=\"next\""
 

+ 9 - 1
test/test_helper.rb

@@ -38,6 +38,14 @@ module Test
         end
 
         ShopifyAPI::Base.clear_session
+
+        fake("apis",
+              url: "https://app.shopify.com/services/apis.json",
+              method: :get,
+              status: 200,
+              api_version: :stub,
+              body: load_fixture('apis'))
+
         ShopifyAPI::ApiVersion.define_known_versions
         session = ShopifyAPI::Session.new(
           domain: "https://this-is-my-test-shop.myshopify.com",
@@ -55,7 +63,7 @@ module Test
         ShopifyAPI::Base.user = nil
 
         ShopifyAPI::ApiVersion.clear_defined_versions
-        ShopifyAPI::ApiVersion.define_known_versions
+        ShopifyAPI::ApiVersion.coercion_mode = :predefined_only
       end
 
       # Custom Assertions