Browse Source

Allow for coercion of the api_version from a string.

Alex Aitken 6 years ago
parent
commit
1887de8c94

+ 2 - 0
lib/shopify_api.rb

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

+ 25 - 5
lib/shopify_api/api_version.rb

@@ -1,11 +1,14 @@
+# frozen_string_literal: true
 module ShopifyAPI
   class ApiVersion
+    class UnknownVersion < StandardError; end
+
     class NoVersion < ApiVersion
       API_PREFIX = '/admin/'
       GRAPHQL_PATH = '/admin/api/graphql.json'
 
       def initialize
-        @version_name = "no version"
+        @version_name = "no_version"
       end
 
       def construct_api_path(path)
@@ -33,17 +36,34 @@ module ShopifyAPI
       end
     end
 
-    def self.no_version
-      NoVersion.new
+    def self.coerce_to_version(version_or_name)
+      return version_or_name if version_or_name.is_a?(ApiVersion)
+
+      @versions ||= {}
+      @versions.fetch(version_or_name.to_s) do
+        raise UnknownVersion, "#{version_or_name} is not in the defined version set: #{@versions.keys.join(', ')}"
+      end
+    end
+
+    def self.define_version(version)
+      @versions ||= {}
+
+      @versions[version.name] = version
+    end
+
+    def self.clear_defined_versions
+      @versions = {}
     end
 
-    def self.unstable
-      Unstable.new
+    def self.define_known_versions
+      define_version(NoVersion.new)
+      define_version(Unstable.new)
     end
 
     def to_s
       @version_name
     end
+    alias_method :name, :to_s
 
     def inspect
       @version_name

+ 9 - 4
lib/shopify_api/session.rb

@@ -10,7 +10,8 @@ module ShopifyAPI
     cattr_accessor :api_key, :secret, :myshopify_domain
     self.myshopify_domain = 'myshopify.com'
 
-    attr_accessor :url, :token, :api_version, :name, :extra
+    attr_accessor :url, :token, :name, :extra
+    attr_reader :api_version
 
     class << self
 
@@ -18,7 +19,7 @@ module ShopifyAPI
         params.each { |k,value| public_send("#{k}=", value) }
       end
 
-      def temp(domain, token, api_version = ApiVersion.no_version, &block)
+      def temp(domain, token, api_version = :no_version, &_block)
         session = new(domain, token, api_version)
         original_site = ShopifyAPI::Base.site.to_s
         original_token = ShopifyAPI::Base.headers['X-Shopify-Access-Token']
@@ -66,9 +67,9 @@ module ShopifyAPI
       end
     end
 
-    def initialize(url, token = nil, api_verison = ApiVersion.no_version, extra = {})
+    def initialize(url, token = nil, api_version = :no_version, extra = {})
       self.url = self.class.prepare_url(url)
-      self.api_version = api_verison
+      self.api_version = api_version
       self.token = token
       self.extra = extra
     end
@@ -108,6 +109,10 @@ module ShopifyAPI
       "https://#{url}"
     end
 
+    def api_version=(version)
+      @api_version = ApiVersion.coerce_to_version(version)
+    end
+
     def valid?
       url.present? && token.present?
     end

+ 55 - 4
test/api_version_test.rb

@@ -2,31 +2,82 @@
 require 'test_helper'
 
 class ApiVersionTest < Test::Unit::TestCase
+  def teardown
+    super
+    ShopifyAPI::ApiVersion.clear_defined_versions
+    ShopifyAPI::ApiVersion.define_known_versions
+  end
+
   test "no version creates url that start with /admin/" do
     assert_equal(
       "/admin/resource_path/id.json",
-      ShopifyAPI::ApiVersion.no_version.construct_api_path("resource_path/id.json")
+      ShopifyAPI::ApiVersion::NoVersion.new.construct_api_path("resource_path/id.json")
     )
   end
 
   test "no version creates graphql url that start with /admin/api" do
     assert_equal(
       "/admin/api/graphql.json",
-      ShopifyAPI::ApiVersion.no_version.construct_graphql_path
+      ShopifyAPI::ApiVersion::NoVersion.new.construct_graphql_path
     )
   end
 
   test "unstable version creates url that start with /admin/api/unstable/" do
     assert_equal(
       "/admin/api/unstable/resource_path/id.json",
-      ShopifyAPI::ApiVersion.unstable.construct_api_path("resource_path/id.json")
+      ShopifyAPI::ApiVersion::Unstable.new.construct_api_path("resource_path/id.json")
     )
   end
 
   test "unstable version creates graphql url that start with /admin/api/unstable/" do
     assert_equal(
       "/admin/api/unstable/graphql.json",
-      ShopifyAPI::ApiVersion.unstable.construct_graphql_path
+      ShopifyAPI::ApiVersion::Unstable.new.construct_graphql_path
     )
   end
+
+  test "coerce_to_version returns any version object given" do
+    version = ShopifyAPI::ApiVersion::Unstable.new
+    assert_same(version, ShopifyAPI::ApiVersion.coerce_to_version(version))
+  end
+
+  test "coerce_to_version converts a known version into a version object" do
+    versions = [
+      ShopifyAPI::ApiVersion::Unstable.new,
+      ShopifyAPI::ApiVersion::NoVersion.new,
+    ]
+
+    assert_equal(versions, [
+      ShopifyAPI::ApiVersion.coerce_to_version('unstable'),
+      ShopifyAPI::ApiVersion.coerce_to_version(:no_version),
+    ])
+  end
+
+  test "coerce_to_version raises when coercing a string that doesn't match a known version" do
+    assert_raises ShopifyAPI::ApiVersion::UnknownVersion do
+      ShopifyAPI::ApiVersion.coerce_to_version('made up version')
+    end
+  end
+
+  test "additional defined versions will also be coerced" do
+    versions = [
+      TestApiVersion.new('my_name'),
+      TestApiVersion.new('other_name'),
+    ]
+
+    versions.each do |version|
+      ShopifyAPI::ApiVersion.define_version(version)
+    end
+
+    assert_equal(versions, [
+      ShopifyAPI::ApiVersion.coerce_to_version('my_name'),
+      ShopifyAPI::ApiVersion.coerce_to_version('other_name'),
+    ])
+  end
+
+  class TestApiVersion < ShopifyAPI::ApiVersion
+    def initialize(name)
+      @version_name = name
+    end
+  end
 end

+ 2 - 2
test/base_test.rb

@@ -131,8 +131,8 @@ class BaseTest < Test::Unit::TestCase
   end
 
   test "using a different version changes the url" do
-    no_version = ShopifyAPI::Session.new('shop1.myshopify.com', 'token1', ShopifyAPI::ApiVersion.no_version)
-    unstable_version = ShopifyAPI::Session.new('shop2.myshopify.com', 'token2', ShopifyAPI::ApiVersion.unstable)
+    no_version = ShopifyAPI::Session.new('shop1.myshopify.com', 'token1', :no_version)
+    unstable_version = ShopifyAPI::Session.new('shop2.myshopify.com', 'token2', :unstable)
 
     fake(
       "shop",

+ 1 - 1
test/detailed_log_subscriber_test.rb

@@ -15,7 +15,7 @@ class LogSubscriberTest < Test::Unit::TestCase
       "#{@ua_header}, \"X-Shopify-Access-Token\"=>\"access_token\"}"
 
     ShopifyAPI::Base.clear_session
-    session = ShopifyAPI::Session.new("https://this-is-my-test-shop.myshopify.com", "access_token", ShopifyAPI::ApiVersion.no_version)
+    session = ShopifyAPI::Session.new("https://this-is-my-test-shop.myshopify.com", "access_token", :no_version)
 
     ShopifyAPI::Base.activate_session(session)
 

+ 2 - 2
test/test_helper.rb

@@ -42,7 +42,7 @@ class Test::Unit::TestCase < Minitest::Unit::TestCase
     end
 
     ShopifyAPI::Base.clear_session
-    session = ShopifyAPI::Session.new("https://this-is-my-test-shop.myshopify.com", "token_test_helper", ShopifyAPI::ApiVersion.no_version)
+    session = ShopifyAPI::Session.new("https://this-is-my-test-shop.myshopify.com", "token_test_helper", :no_version)
 
     ShopifyAPI::Base.activate_session(session)
   end
@@ -85,7 +85,7 @@ class Test::Unit::TestCase < Minitest::Unit::TestCase
     body   = options.has_key?(:body) ? options.delete(:body) : load_fixture(endpoint)
     format = options.delete(:format) || :json
     method = options.delete(:method) || :get
-    api_version = options.delete(:api_version) || ShopifyAPI::ApiVersion.no_version
+    api_version = options.delete(:api_version) || ShopifyAPI::ApiVersion.coerce_to_version(:no_version)
     extension = ".#{options.delete(:extension)||'json'}" unless options[:extension]==false
 
     url = if options.has_key?(:url)