Skip to content

Commit

Permalink
Merge pull request #19 from tstachl/clean
Browse files Browse the repository at this point in the history
Add groups and max requests limit.
  • Loading branch information
Chris Warren committed Feb 26, 2013
2 parents 534f27a + b768eca commit a3110d7
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 13 deletions.
32 changes: 19 additions & 13 deletions lib/desk.rb
Expand Up @@ -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
2 changes: 2 additions & 0 deletions lib/desk/client.rb
Expand Up @@ -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'
Expand All @@ -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
Expand Down
37 changes: 37 additions & 0 deletions lib/desk/client/group.rb
@@ -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
10 changes: 10 additions & 0 deletions lib/desk/configuration.rb
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions lib/desk/error.rb
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions lib/desk/request.rb
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions spec/desk/api_spec.rb
Expand Up @@ -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"
}
Expand Down
54 changes: 54 additions & 0 deletions spec/desk/client/group_spec.rb
@@ -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
92 changes: 92 additions & 0 deletions spec/desk_spec.rb
Expand Up @@ -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
Expand All @@ -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
8 changes: 8 additions & 0 deletions spec/fixtures/group.json
@@ -0,0 +1,8 @@
{
"group": {
"id": 1,
"name": "Sales",
"created_at": "2013-01-21T09:47:23Z",
"updated_at": "2013-01-21T09:47:23Z"
}
}
23 changes: 23 additions & 0 deletions spec/fixtures/groups.json
@@ -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.