Permalink
Browse files

Merge pull request #19 from tstachl/clean

Add groups and max requests limit.
  • Loading branch information...
2 parents 534f27a + b768eca commit a3110d7a5f4da42012a57051a1573a161fe4a2c4 Chris Warren committed Feb 26, 2013
View
@@ -6,21 +6,27 @@
module Desk
extend Configuration
+ @counter = 0
+ @minute = Time.now.min
- # Alias for Desk::Client.new
- #
- # @return [Desk::Client]
- def self.client(options={})
- Desk::Client.new(options)
- end
+ class << self
+ attr_accessor :counter, :minute
+
+ # Alias for Desk::Client.new
+ #
+ # @return [Desk::Client]
+ def client(options={})
+ Desk::Client.new(options)
+ end
- # Delegate to Desk::Client
- def self.method_missing(method, *args, &block)
- return super unless client.respond_to?(method)
- client.send(method, *args, &block)
- end
+ # Delegate to Desk::Client
+ def method_missing(method, *args, &block)
+ return super unless client.respond_to?(method)
+ client.send(method, *args, &block)
+ end
- def self.respond_to?(method)
- client.respond_to?(method) || super
+ def respond_to?(method)
+ client.respond_to?(method) || super
+ end
end
end
View
@@ -8,6 +8,7 @@ class Client < API
# order to avoid a superclass mismatch error, allowing those modules to be
# Client-namespaced.
require 'desk/client/user'
+ require 'desk/client/group'
require 'desk/client/interaction'
require 'desk/client/case'
require 'desk/client/customer'
@@ -18,6 +19,7 @@ class Client < API
alias :api_endpoint :endpoint
include Desk::Client::User
+ include Desk::Client::Group
include Desk::Client::Interaction
include Desk::Client::Case
include Desk::Client::Customer
View
@@ -0,0 +1,37 @@
+module Desk
+ class Client
+ # Defines methods related to groups
+ module Group
+ # Returns extended information of groups
+ #
+ # @option options [Boolean, String, Integer]
+ # @example Return extended information for 12345
+ # Desk.groups
+ # Desk.groups(:count => 5)
+ # Desk.groups(:count => 5, :page => 3)
+ # @format :json
+ # @authenticated true
+ # @see http://dev.desk.com/docs/api/groups
+ def groups(*args)
+ options = args.last.is_a?(Hash) ? args.pop : {}
+ response = get("groups",options)
+ response
+ end
+
+ # Returns extended information on a single group
+ #
+ # @param id [Integer] a group ID
+ # @option options [Hash]
+ # @example Return extended information for 12345
+ # Desk.group(12345)
+ # @format :json
+ # @authenticated true
+ # @see http://dev.desk.com/docs/api/groups/show
+ def group(id)
+ response = get("groups/#{id}")
+ response.group
+ end
+
+ end
+ end
+end
View
@@ -10,11 +10,13 @@ module Configuration
:consumer_key,
:consumer_secret,
:format,
+ :max_requests,
:oauth_token,
:oauth_token_secret,
:proxy,
:subdomain,
:support_email,
+ :use_max_requests,
:user_agent,
:version].freeze
@@ -39,6 +41,12 @@ module Configuration
#
# @note JSON is preferred over XML because it is more concise and faster to parse.
DEFAULT_FORMAT = :json
+
+ # By default, set the max requests to 60 per minute
+ DEFAULT_MAX_REQUESTS = 60
+
+ # By default, don't use the max request feature
+ DEFAULT_USE_MAX_REQUESTS = false
# By default, don't set a user oauth token
DEFAULT_OAUTH_TOKEN = nil
@@ -85,11 +93,13 @@ def reset
self.consumer_key = DEFAULT_CONSUMER_KEY
self.consumer_secret = DEFAULT_CONSUMER_SECRET
self.format = DEFAULT_FORMAT
+ self.max_requests = DEFAULT_MAX_REQUESTS
self.oauth_token = DEFAULT_OAUTH_TOKEN
self.oauth_token_secret = DEFAULT_OAUTH_TOKEN_SECRET
self.proxy = DEFAULT_PROXY
self.subdomain = DEFAULT_SUBDOMAIN
self.support_email = DEFAULT_SUPPORT_EMAIL
+ self.use_max_requests = DEFAULT_USE_MAX_REQUESTS
self.user_agent = DEFAULT_USER_AGENT
self.version = DEFAULT_VERSION
self
View
@@ -50,6 +50,9 @@ def retry_after
@http_headers.values_at('retry-after', 'Retry-After').detect {|value| value }.to_i
end
end
+
+ # Raised when Desk max_requests is reached and use_max_requests is set to true
+ class TooManyRequests < StandardError; end
# Raised when Desk returns the HTTP status code 500
class InternalServerError < Error; end
View
@@ -22,9 +22,24 @@ def delete(path, options={}, raw=false)
end
private
+
+ def before_request
+ if Desk.minute != Time.now.min
+ Desk.minute = Time.now.min
+ Desk.counter = 0
+ end
+
+ Desk.counter += 1
+ if Desk.use_max_requests
+ if Desk.counter > Desk.max_requests
+ raise Desk::TooManyRequests
+ end
+ end
+ end
# Perform an HTTP request
def request(method, path, options, raw=false)
+ before_request
response = connection(raw).send(method) do |request|
case method
when :get, :delete
View
@@ -36,9 +36,11 @@
:oauth_token_secret => 'OS',
:adapter => :typhoeus,
:format => :xml,
+ :max_requests => 50,
:proxy => 'http://erik:sekret@proxy.example.com:8080',
:subdomain => 'zencoder',
:support_email => 'help@zencoder.com',
+ :use_max_requests => true,
:user_agent => 'Custom User Agent',
:version => "amazing"
}
@@ -0,0 +1,54 @@
+require 'helper'
+
+describe Desk::Client do
+ Desk::Configuration::VALID_FORMATS.each do |format|
+ context ".new(:format => '#{format}')" do
+ before do
+ @client = Desk::Client.new(:subdomain => "example", :format => format, :consumer_key => 'CK', :consumer_secret => 'CS', :oauth_token => 'OT', :oauth_token_secret => 'OS')
+ end
+
+ describe ".groups" do
+ context "lookup" do
+ before do
+ stub_get("groups.#{format}").
+ to_return(:body => fixture("groups.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
+ end
+
+ it "should get the correct resource" do
+ @client.groups
+ a_get("groups.#{format}").
+ should have_been_made
+ end
+
+ it "should return up to 100 groups worth of extended information" do
+ groups = @client.groups
+ groups.results.should be_a Array
+ groups.results.last.group.id.should == 2
+ groups.results.last.group.name.should == "Administrators"
+ end
+ end
+ end
+
+ describe ".group" do
+ context "lookup" do
+ before do
+ stub_get("groups/1.#{format}").
+ to_return(:body => fixture("group.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
+ end
+
+ it "should get the correct resource" do
+ @client.group(1)
+ a_get("groups/1.#{format}").
+ should have_been_made
+ end
+
+ it "should return up to 100 cases worth of extended information" do
+ group = @client.group(1)
+ group.id.should == 1
+ group.name.should == "Sales"
+ end
+ end
+ end
+ end
+ end
+end
View
@@ -98,6 +98,32 @@
Desk.format.should == 'xml'
end
end
+
+ describe ".max_requests" do
+ it "should return the default max requests" do
+ Desk.max_requests.should == Desk::Configuration::DEFAULT_MAX_REQUESTS
+ end
+ end
+
+ describe ".max_requests=" do
+ it "should set the max_requests" do
+ Desk.max_requests = 50
+ Desk.max_requests.should == 50
+ end
+ end
+
+ describe ".use_max_requests" do
+ it "should return the default max requests flag" do
+ Desk.use_max_requests.should == Desk::Configuration::DEFAULT_USE_MAX_REQUESTS
+ end
+ end
+
+ describe ".use_max_requests=" do
+ it "should set the use_max_requests flag" do
+ Desk.max_requests = true
+ Desk.max_requests.should == true
+ end
+ end
describe ".user_agent" do
it "should return the default user agent" do
@@ -124,4 +150,70 @@
end
end
end
+
+ describe ".counter" do
+ before do
+ Desk.counter = 0
+ stub_get("cases.json").
+ to_return(:body => fixture("cases.json"), :headers => {:content_type => "application/json; charset=utf-8"})
+ end
+
+ it "should be 0 in the beginning" do
+ Desk.counter.should == 0
+ end
+
+ it "should count the requests" do
+ 5.times {
+ Desk.cases
+ }
+ Desk.counter.should == 5
+ end
+
+ context "max requests enabled" do
+ before do
+ Desk.use_max_requests = true
+ end
+
+ it "should only allow 60 requests" do
+ expect {
+ 70.times {
+ Desk.cases
+ }
+ }.to raise_error
+ end
+
+ it "should only allow defined requests" do
+ Desk.max_requests = 50
+ expect {
+ 55.times {
+ Desk.cases
+ }
+ }.to raise_error
+ end
+
+ def make_request
+ Desk.cases
+ rescue Desk::TooManyRequests
+ sleep(5)
+ make_request
+ end
+
+ xit "should allow more requests after minute has passed" do
+ 70.times {
+ make_request
+ }
+ Desk.counter.should == 10
+ end
+ end
+ end
+
+ describe ".minute" do
+ before do
+ Desk.minute = Time.now.min
+ end
+
+ it "should be the current minute" do
+ Desk.minute.should == Time.now.min
+ end
+ end
end
View
@@ -0,0 +1,8 @@
+{
+ "group": {
+ "id": 1,
+ "name": "Sales",
+ "created_at": "2013-01-21T09:47:23Z",
+ "updated_at": "2013-01-21T09:47:23Z"
+ }
+}
View
@@ -0,0 +1,23 @@
+{
+ "results": [
+ {
+ "group": {
+ "id": 1,
+ "name": "Sales",
+ "created_at": "2013-01-21T09:47:23Z",
+ "updated_at": "2013-01-21T09:47:23Z"
+ }
+ },
+ {
+ "group": {
+ "id": 2,
+ "name": "Administrators",
+ "created_at": "2013-01-21T09:47:23Z",
+ "updated_at": "2013-01-21T09:47:23Z"
+ }
+ }
+ ],
+ "page": 1,
+ "count": 20,
+ "total": 2
+}

0 comments on commit a3110d7

Please sign in to comment.