dschn-tweetsy 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 4
2
+ :patch: 5
3
3
  :major: 0
4
4
  :minor: 1
@@ -6,6 +6,7 @@ module Tweetsy
6
6
  class Unauthorized < CantConnect; end
7
7
  class BadRequest < CantConnect; end
8
8
  class NotFound < CantConnect; end
9
+ class Forbidden < CantConnect; end
9
10
  end
10
11
 
11
12
  require File.dirname(__FILE__) + '/tweetsy/user'
@@ -1,9 +1,11 @@
1
1
  module Tweetsy
2
2
  class Client
3
3
  API_HOST = "http://twitter.com"
4
-
4
+ attr_reader :rate_limits
5
+
5
6
  def initialize(login, password, options = {})
6
7
  @config = options.merge(:auth => [login, password].join(':'))
8
+ @rate_limits = {}
7
9
  end
8
10
 
9
11
  def authenticate_as(login, password)
@@ -105,12 +107,47 @@ module Tweetsy
105
107
  path
106
108
  end
107
109
  end
110
+
111
+ def parse(response)
112
+ Hpricot.XML(response.body_str)
113
+ end
114
+
115
+ def parse_error(response)
116
+ (parse(response)/:hash/:error).inner_text
117
+ end
118
+
119
+ def parse_rate_limit(response)
120
+ response.header_str.scan(/^X-RateLimit-([a-zA-Z]+): (\d+)/) do |match|
121
+ @rate_limits[match.first.downcase.to_sym] = match.last.to_i
122
+ end
123
+ end
124
+
125
+ def raise_errors(response)
126
+ case response.response_code
127
+ when 400
128
+ error_msg = parse_error(response)
129
+ raise BadRequest.new(error_msg)
130
+ when 401
131
+ error_msg = parse_error(response)
132
+ raise Unauthorized.new(error_msg)
133
+ when 403
134
+ error_msg = parse_error(response)
135
+ raise Forbidden.new(error_msg)
136
+ when 404
137
+ error_msg = parse_error(response)
138
+ raise NotFound.new(error_msg)
139
+ when 503
140
+ raise CantConnect, "Service unavailable"
141
+ else
142
+ raise CantConnect, "#{response.response_code}"
143
+ end
144
+ end
108
145
 
109
146
  def request(method, endpoint, options = {})
110
147
  raise ArgumentError, "#{method} is not a valid request method" unless [:get, :post].include?(method)
111
148
 
112
149
  begin
113
- result = case method
150
+ response = case method
114
151
  when :get
115
152
  Curl::Easy.perform("#{API_HOST}/#{endpoint}") do |curl|
116
153
  default_curl_options(curl)
@@ -128,19 +165,12 @@ module Tweetsy
128
165
  rescue => e
129
166
  raise CantConnect, "#{e.message}"
130
167
  end
131
-
132
- if [200, 304].include?(result.response_code)
133
- Hpricot(result.body_str)
134
- elsif result.response_code == 401
135
- raise Unauthorized
136
- elsif result.response_code == 403
137
- raise BadRequest
138
- elsif result.response_code == 404
139
- raise NotFound
140
- elsif result.response_code == 503
141
- raise CantConnect, "Service unavailable"
168
+
169
+ if [200, 304].include?(response.response_code)
170
+ parse_rate_limit(response)
171
+ parse(response)
142
172
  else
143
- raise CantConnect, "#{result.response_code}"
173
+ raise_errors(response)
144
174
  end
145
175
  end
146
176
 
@@ -4,6 +4,12 @@ describe "Tweetsy::Client" do
4
4
  before do
5
5
  @base = Tweetsy::Client.new('foo', 'bar')
6
6
  end
7
+
8
+ describe "on initialization" do
9
+ it "should have empty rate_limit hash" do
10
+ @base.rate_limits.should == {}
11
+ end
12
+ end
7
13
 
8
14
  describe "authenticated?" do
9
15
  it "should return true on successful authentication (200)" do
@@ -54,6 +60,16 @@ describe "Tweetsy::Client" do
54
60
  end
55
61
  end
56
62
 
63
+ def create_error_response(message)
64
+ "
65
+ <?xml version=\"1.0\" encoding=\"UTF-8\"?>
66
+ <hash>
67
+ <request>/users/show/genevate.xml</request>
68
+ <error>#{message}</error>
69
+ </hash>
70
+ "
71
+ end
72
+
57
73
  describe "request" do
58
74
  it "should raise ArgumentError on bad arguments" do
59
75
  lambda {
@@ -62,7 +78,7 @@ describe "Tweetsy::Client" do
62
78
  end
63
79
 
64
80
  it "should raise Unauthorized on 401" do
65
- response = mock(:response, :response_code => 401)
81
+ response = mock(:response, :response_code => 401, :header_str => "", :body_str => create_error_response("test"))
66
82
  Curl::Easy.stub!(:perform).and_return(response)
67
83
 
68
84
  lambda {
@@ -73,10 +89,36 @@ describe "Tweetsy::Client" do
73
89
  @base.request(:get, 'blah')
74
90
  }.should raise_error(Tweetsy::CantConnect)
75
91
  end
92
+
93
+ it "should raise BadRequest on 400" do
94
+ response = mock(:response, :response_code => 400, :header_str => "", :body_str => create_error_response("test"))
95
+ Curl::Easy.stub!(:perform).and_return(response)
96
+
97
+ lambda {
98
+ @base.request(:get, 'blah')
99
+ }.should raise_error(Tweetsy::BadRequest)
100
+
101
+ lambda {
102
+ @base.request(:get, 'blah')
103
+ }.should raise_error(Tweetsy::CantConnect)
104
+ end
105
+
106
+ it "should raise Forbidden on 403" do
107
+ response = mock(:response, :response_code => 403, :header_str => "", :body_str => create_error_response("test"))
108
+ Curl::Easy.stub!(:perform).and_return(response)
109
+
110
+ lambda {
111
+ @base.request(:get, 'blah')
112
+ }.should raise_error(Tweetsy::Forbidden)
113
+
114
+ lambda {
115
+ @base.request(:get, 'blah')
116
+ }.should raise_error(Tweetsy::CantConnect)
117
+ end
76
118
 
77
119
  it "should raise CantConnect on anything that isn't 200 or 304 response" do
78
120
  [401, 503, 504, 505, nil].each do |code|
79
- response = mock(:response, :response_code => code)
121
+ response = mock(:response, :response_code => code, :header_str => "", :body_str => create_error_response("test"))
80
122
  Curl::Easy.stub!(:perform).and_return(response)
81
123
 
82
124
  lambda {
@@ -84,5 +126,18 @@ describe "Tweetsy::Client" do
84
126
  }.should raise_error(Tweetsy::CantConnect)
85
127
  end
86
128
  end
129
+
130
+ it "should return rate limit status" do
131
+ response = mock(:response,
132
+ :body_str => "Hello World",
133
+ :response_code => 200,
134
+ :header_str => "X-RateLimit-Limit: 100\r\nX-RateLimit-Remaining: 98\r\nX-RateLimit-Reset: 12345678")
135
+ Curl::Easy.stub!(:perform).and_return(response)
136
+
137
+ @base.request(:get, 'blah')
138
+ @base.rate_limits[:limit].should == 100
139
+ @base.rate_limits[:remaining].should == 98
140
+ @base.rate_limits[:reset].should == 12345678
141
+ end
87
142
  end
88
143
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dschn-tweetsy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dustin Schneider
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-09 00:00:00 -07:00
12
+ date: 2009-04-28 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15