Browse Source

Added API limits code + tests (merged from shopify-api-limits)

David Underwood 13 years ago
parent
commit
4ffdb62f60
4 changed files with 134 additions and 0 deletions
  1. 16 0
      lib/active_resource/connection_ext.rb
  2. 5 0
      lib/shopify_api.rb
  3. 76 0
      lib/shopify_api/limits.rb
  4. 37 0
      test/limits_test.rb

+ 16 - 0
lib/active_resource/connection_ext.rb

@@ -0,0 +1,16 @@
+require 'active_support/core_ext/module/aliasing'
+
+module ActiveResource
+  class Connection
+    
+    attr_reader :response
+    
+    def handle_response_with_response_capture(response)
+      @response = handle_response_without_response_capture(response)
+    end
+    
+    alias_method_chain :handle_response, :response_capture
+    # alias_method :handle_response_without_instance, :handle_response
+    # alias_method :handle_response, :handle_response_with_instance
+  end
+end

+ 5 - 0
lib/shopify_api.rb

@@ -2,8 +2,12 @@ require 'active_resource'
 require 'active_support/core_ext/class/attribute_accessors'
 require 'digest/md5'
 require 'base64'
+require 'active_resource/connection_ext'
+require 'shopify_api/limits'
 
 module ShopifyAPI
+  include Limits
+  
   METAFIELD_ENABLED_CLASSES = %w( Order Product CustomCollection SmartCollection Page Blog Article Variant)
   EVENT_ENABLED_CLASSES = %w( Order Product CustomCollection SmartCollection Page Blog Article )
   
@@ -547,4 +551,5 @@ module ShopifyAPI
   EVENT_ENABLED_CLASSES.each do |klass|
     "ShopifyAPI::#{klass}".constantize.send(:include, Events)
   end
+  
 end

+ 76 - 0
lib/shopify_api/limits.rb

@@ -0,0 +1,76 @@
+module ShopifyAPI
+  module Limits
+    def self.included(klass)
+      klass.send(:extend, ClassMethods)
+    end
+    
+    module ClassMethods
+
+      # Takes form num_requests_executed/max_requests
+      # Eg: 101/3000
+      CREDIT_LIMIT_HEADER_PARAM = {
+        :global => 'http_x_shopify_api_call_limit',
+        :shop => 'http_x_shopify_shop_api_call_limit'
+      }
+
+        ##
+      # How many more API calls can I make?
+      # @return {Integer}
+      #
+      def credit_left
+        shop = credit_limit(:shop) - credit_used(:shop)
+        global = credit_limit(:global) - credit_used(:global)      
+        shop < global ? shop : global
+      end
+      alias_method :available_calls, :credit_left
+      
+      ##
+      # Have I reached my API call limit?
+      # @return {Boolean}
+      #
+      def credit_maxed?
+        credit_left <= 0
+      end
+      alias_method :maxed?, :credit_maxed?
+      
+      ##
+      # How many total API calls can I make?
+      # NOTE: subtracting 1 from credit_limit because I think ShopifyAPI cuts off at 299/2999 or shop/global limits.
+      # @param {Symbol} scope [:shop|:global]
+      # @return {Integer}
+      #
+      def credit_limit(scope=:shop)
+        @api_credit_limit ||= {}
+        @api_credit_limit[scope] ||= api_credit_limit_param(scope).pop.to_i - 1     
+      end
+      alias_method :call_limit, :credit_limit
+
+      ##
+      # How many API calls have I made?
+      # @param {Symbol} scope [:shop|:global]
+      # @return {Integer}
+      #
+      def credit_used(scope=:shop)
+        api_credit_limit_param(scope).shift.to_i
+      end
+      alias_method :call_count, :credit_used
+      
+      ##
+      # @return {HTTPResonse}
+      #
+      def response
+        Shop.current unless ShopifyAPI::Base.connection.response
+        ShopifyAPI::Base.connection.response
+      end
+
+      private
+
+      ##
+      # @return {Array}
+      #
+      def api_credit_limit_param(scope)    
+        response[CREDIT_LIMIT_HEADER_PARAM[scope]].split('/')
+      end    
+    end
+  end
+end

+ 37 - 0
test/limits_test.rb

@@ -0,0 +1,37 @@
+require 'test_helper'
+require 'mocha'
+
+class LimitsTest < Test::Unit::TestCase
+  def setup
+    ShopifyAPI::Base.site = "test.myshopify.com"
+    @header_hash = {'http_x_shopify_api_call_limit' => '150/3000',
+                    'http_x_shopify_shop_api_call_limit' => '100/300'}
+    ShopifyAPI::Base.connection.expects(:response).at_least(0).returns(@header_hash)
+  end
+  
+  context "Limits" do
+    should "fetch limit total" do
+      assert_equal(299, ShopifyAPI.credit_limit(:shop))
+      assert_equal(2999, ShopifyAPI.credit_limit(:global))
+    end
+    
+    should "fetch used calls" do
+      assert_equal(100, ShopifyAPI.credit_used(:shop))
+      assert_equal(150, ShopifyAPI.credit_used(:global))
+    end
+    
+    should "calculate remaining calls" do
+      assert_equal(199, ShopifyAPI.credit_left)
+    end
+    
+    should "flag maxed out credits" do
+      assert !ShopifyAPI.maxed?
+      @header_hash = {'http_x_shopify_api_call_limit' => '2999/3000',
+                      'http_x_shopify_shop_api_call_limit' => '299/300'}
+      ShopifyAPI::Base.connection.expects(:response).at_least(1).returns(@header_hash)
+      assert ShopifyAPI.maxed?
+    end
+  end
+  
+  
+end