mbbx6spp-twitter4r 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,7 @@ class Twitter::Client
3
3
  :get => '/statuses/show.json',
4
4
  :post => '/statuses/update.json',
5
5
  :delete => '/statuses/destroy.json',
6
+ :reply => '/statuses/update.json',
6
7
  }
7
8
 
8
9
  # Provides access to individual statuses via Twitter's Status APIs
@@ -11,6 +12,7 @@ class Twitter::Client
11
12
  # * <tt>:get</tt> to retrieve status content. Assumes <tt>value</tt> given responds to :to_i message in meaningful way to yield intended status id.
12
13
  # * <tt>:post</tt> to publish a new status
13
14
  # * <tt>:delete</tt> to remove an existing status. Assumes <tt>value</tt> given responds to :to_i message in meaningful way to yield intended status id.
15
+ # * <tt>:reply</tt> to reply to an existing status. Assumes <tt>value</tt> given is <tt>Hash</tt> which contains <tt>:in_reply_to_status_id</tt> and <tt>:status</tt>
14
16
  #
15
17
  # <tt>value</tt> should be set to:
16
18
  # * the status identifier for <tt>:get</tt> case
@@ -31,8 +33,8 @@ class Twitter::Client
31
33
  return self.timeline_for(action, value || {}) if :replies == action
32
34
  raise ArgumentError, "Invalid status action: #{action}" unless @@STATUS_URIS.keys.member?(action)
33
35
  return nil unless value
34
- uri = @@STATUS_URIS[action]
35
- response = nil
36
+ uri = @@STATUS_URIS[action]
37
+ response = nil
36
38
  case action
37
39
  when :get
38
40
  response = http_connect {|conn| create_http_get_request(uri, :id => value.to_i) }
@@ -40,6 +42,9 @@ class Twitter::Client
40
42
  response = http_connect({:status => value, :source => @@config.source}.to_http_str) {|conn| create_http_post_request(uri) }
41
43
  when :delete
42
44
  response = http_connect {|conn| create_http_delete_request(uri, :id => value.to_i) }
45
+ when :reply
46
+ return nil if (!value.is_a?(Hash) || !value[:status] || !value[:in_reply_to_status_id])
47
+ response = http_connect(value.merge(:source => @@config.source).to_http_str) {|conn| create_http_post_request(uri) }
43
48
  end
44
49
  bless_model(Twitter::Status.unmarshal(response.body))
45
50
  end
@@ -22,6 +22,9 @@ module Twitter
22
22
  :protocol,
23
23
  :host,
24
24
  :port,
25
+ :search_protocol,
26
+ :search_host,
27
+ :search_port,
25
28
  :proxy_host,
26
29
  :proxy_port,
27
30
  :proxy_user,
@@ -49,6 +52,9 @@ module Twitter
49
52
  @@defaults = { :host => 'twitter.com',
50
53
  :port => 443,
51
54
  :protocol => :ssl,
55
+ :search_host => 'search.twitter.com',
56
+ :search_port => 80,
57
+ :search_protocol => :http,
52
58
  :proxy_host => nil,
53
59
  :proxy_port => nil,
54
60
  :user_agent => "default",
@@ -1,5 +1,7 @@
1
1
  # Contains hooks for the twitter console
2
2
 
3
+ require('optparse')
4
+
3
5
  module Twitter
4
6
  class Client
5
7
  class << self
@@ -26,3 +28,4 @@ module Twitter
26
28
  end # class << self
27
29
  end
28
30
  end
31
+
data/lib/twitter/core.rb CHANGED
@@ -99,10 +99,10 @@ module Twitter
99
99
  # 404
100
100
  # Resource Not Found
101
101
  # /i_am_crap.json
102
- class RESTError < Exception
102
+ class RESTError < RuntimeError
103
103
  include ClassUtilMixin
104
- @@ATTRIBUTES = [:code, :message, :uri]
105
- attr_accessor :code, :message, :uri
104
+ @@ATTRIBUTES = [:code, :message, :uri, :error]
105
+ attr_accessor :code, :message, :uri, :error
106
106
 
107
107
  # Returns string in following format:
108
108
  # "HTTP #{@code}: #{@message} at #{@uri}"
@@ -42,9 +42,10 @@ module Kernel
42
42
  def gem_present?(gem_name, version = nil)
43
43
  present = false
44
44
  begin
45
- present = gem(gem_name, version)
45
+ present = !!(version ? gem(gem_name, version) : gem(gem_name))
46
46
  rescue Gem::LoadError => le
47
- warn("Gem load error: Couldn't load #{gem_name} with version requirement #{version}: #{le.to_s}")
47
+ present = false
48
+ warn("Gem load error: Couldn't load #{gem_name} #{version ? "with version requirement #{version}: #{le.to_s}": ""}")
48
49
  end
49
50
  present
50
51
  end
data/lib/twitter/model.rb CHANGED
@@ -158,7 +158,13 @@ module Twitter
158
158
  # Represents a <tt>Twitter</tt> user
159
159
  class User
160
160
  include ModelMixin
161
- @@ATTRIBUTES = [:id, :name, :description, :location, :screen_name, :url, :profile_image_url, :protected]
161
+ @@ATTRIBUTES = [:id, :name, :description, :location, :screen_name, :url,
162
+ :protected, :profile_image_url, :profile_background_color,
163
+ :profile_text_color, :profile_link_color, :profile_sidebar_fill_color,
164
+ :profile_sidebar_border_color, :profile_background_image_url,
165
+ :profile_background_tile, :utc_offset, :time_zone,
166
+ :following, :notifications, :favourites_count, :followers_count,
167
+ :friends_count, :statuses_count, :created_at, ]
162
168
  attr_accessor *@@ATTRIBUTES
163
169
 
164
170
  class << self
@@ -219,7 +225,9 @@ module Twitter
219
225
  # Represents a status posted to <tt>Twitter</tt> by a <tt>Twitter</tt> user.
220
226
  class Status
221
227
  include ModelMixin
222
- @@ATTRIBUTES = [:id, :text, :created_at, :user, :in_reply_to_status_id]
228
+ @@ATTRIBUTES = [:id, :text, :source, :truncated, :created_at, :user,
229
+ :favorited, :in_reply_to_status_id, :in_reply_to_user_id,
230
+ :in_reply_to_screen_name]
223
231
  attr_accessor *@@ATTRIBUTES
224
232
 
225
233
  class << self
@@ -264,6 +272,10 @@ module Twitter
264
272
  def reply?
265
273
  !!@in_reply_to_status_id
266
274
  end
275
+
276
+ def reply(status)
277
+ client.status(:reply, :status => status, :in_reply_to_status_id => @id)
278
+ end
267
279
 
268
280
  protected
269
281
  # Constructor callback
@@ -3,8 +3,8 @@
3
3
 
4
4
  module Twitter::Version #:nodoc:
5
5
  MAJOR = 0
6
- MINOR = 3
7
- REVISION = 1
6
+ MINOR = 4
7
+ REVISION = 0
8
8
  class << self
9
9
  # Returns X.Y.Z formatted version string
10
10
  def to_version
@@ -0,0 +1,28 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#account_info" do
4
+ before(:each) do
5
+ @uri = Twitter::Client.class_eval("@@ACCOUNT_URIS[:rate_limit_status]")
6
+ @request = mas_net_http_get(:basic_auth => nil)
7
+ @twitter = client_context
8
+ @default_header = @twitter.send(:http_header)
9
+ @response = mas_net_http_response(:success)
10
+ @connection = mas_net_http(@response)
11
+ @response.stub!(:body).and_return("{}")
12
+ Net::HTTP.stub!(:new).and_return(@connection)
13
+ @rate_limit_status = mock(Twitter::RateLimitStatus)
14
+ @twitter.stub!(:bless_models).and_return({})
15
+ end
16
+
17
+ it "should create expected HTTP GET request" do
18
+ @twitter.should_receive(:create_http_get_request).with(@uri).and_return(@request)
19
+ @twitter.account_info
20
+ end
21
+
22
+ it "should raise Twitter::RESTError when 500 HTTP response received when giving page options" do
23
+ @connection = mas_net_http(mas_net_http_response(:server_error))
24
+ lambda {
25
+ @twitter.account_info
26
+ }.should raise_error(Twitter::RESTError)
27
+ end
28
+ end
@@ -0,0 +1,67 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#graph(:friends...)" do
4
+ before(:each) do
5
+ @twitter = client_context
6
+ @id = 1234567
7
+ @screen_name = 'dummylogin'
8
+ @friend = Twitter::User.new(:id => @id, :screen_name => @screen_name)
9
+ @uris = Twitter::Client.class_eval("@@GRAPH_URIS")
10
+ @request = mas_net_http_get(:basic_auth => nil)
11
+ @response = mas_net_http_response(:success)
12
+ @response.stub!(:body).and_return("[1, 2, 3, 4, 5, 6]")
13
+ @connection = mas_net_http(@response)
14
+ Net::HTTP.stub!(:new).and_return(@connection)
15
+ Twitter::User.stub!(:unmarshal).and_return(@friend)
16
+ end
17
+
18
+ def create_uri(action)
19
+ "#{@uris[action]}.json"
20
+ end
21
+
22
+ it "should create expected HTTP GET request for :friends case using integer user ID" do
23
+ # the integer user ID scenario...
24
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:friends), :id => @id).and_return(@request)
25
+ @twitter.graph(:friends, @id)
26
+ end
27
+
28
+ it "should create expected HTTP GET request for :friends case using screen name" do
29
+ # the screen name scenario...
30
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:friends), :id => @screen_name).and_return(@request)
31
+ @twitter.graph(:friends, @screen_name)
32
+ end
33
+
34
+ it "should create expected HTTP GET request for :friends case using Twitter::User object" do
35
+ # the Twitter::User object scenario...
36
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:friends), :id => @friend.to_i).and_return(@request)
37
+ @twitter.graph(:friends, @friend)
38
+ end
39
+
40
+ it "should create expected HTTP GET request for :followers case using integer user ID" do
41
+ # the integer user ID scenario...
42
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:followers), :id => @id).and_return(@request)
43
+ @twitter.graph(:followers, @id)
44
+ end
45
+
46
+ it "should create expected HTTP GET request for :followers case using screen name" do
47
+ # the screen name scenario...
48
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:followers), :id => @screen_name).and_return(@request)
49
+ @twitter.graph(:followers, @screen_name)
50
+ end
51
+
52
+ it "should create expected HTTP GET request for :followers case using Twitter::User object" do
53
+ # the Twitter::User object scenario...
54
+ @twitter.should_receive(:create_http_get_request).with(create_uri(:followers), :id => @friend.to_i).and_return(@request)
55
+ @twitter.graph(:followers, @friend)
56
+ end
57
+
58
+ it "should raise ArgumentError if action given is not valid" do
59
+ lambda {
60
+ @twitter.graph(:crap, @friend)
61
+ }.should raise_error(ArgumentError)
62
+ end
63
+
64
+ after(:each) do
65
+ nilize(@twitter, @id, @uris, @request, @response, @connection)
66
+ end
67
+ end
@@ -0,0 +1,91 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#profile" do
4
+ before(:each) do
5
+ @twitter = client_context
6
+ @user_attrs = {
7
+ :id => "JaneEyre",
8
+ :login => "Jane Eyre",
9
+ :url => "http://janeeyrerocks.co.uk",
10
+ :location => "Thornfield Manor",
11
+ }
12
+ # name, email, url, location, description
13
+ @info_attrs = {
14
+ :name => "Jane Eyre",
15
+ :email => "jane.eyre@gmail.co.uk",
16
+ :url => "http://janeeyrerocks.co.uk",
17
+ :location => "Thornfield Manor",
18
+ :description => "Governess who falls for slave-trade aristocrat with French lovechild he doesn't acknowledge & wife locked in damp attic with keeper.",
19
+ }
20
+ # background_color, text_color, link_color, sidebar_fill_color, sidebar_border_color
21
+ @colors_attrs = {
22
+ :background_color => "#ffffff",
23
+ :text_color => "#101010",
24
+ :link_color => "#990000",
25
+ }
26
+ # value
27
+ @device_attrs = {
28
+ :value => "sms",
29
+ }
30
+ @user = Twitter::User.new
31
+ @uris = Twitter::Client.class_eval("@@PROFILE_URIS")
32
+ @request = mas_net_http_get(:basic_auth => nil)
33
+ @json = JSON.unparse(@user_attrs)
34
+ @response = mas_net_http_response(:success, @json)
35
+ @connection = mas_net_http(@response)
36
+
37
+ Net::HTTP.stub!(:new).and_return(@connection)
38
+ Twitter::User.stub!(:unmarshal).and_return(@user)
39
+ end
40
+
41
+ it "should invoke #http_connect with expected arguments for :info case" do
42
+ @twitter.should_receive(:http_connect).with(@info_attrs.to_http_str).and_return(@response)
43
+ @twitter.profile(:info, @info_attrs)
44
+ end
45
+
46
+ it "should invoke #http_connect with expected arguments for :colors case" do
47
+ @twitter.should_receive(:http_connect).with(@colors_attrs.to_http_str).and_return(@response)
48
+ @twitter.profile(:colors, @colors_attrs)
49
+ end
50
+
51
+ it "should invoke #http_connect with expected arguments for :device case" do
52
+ @twitter.should_receive(:http_connect).with(@device_attrs.to_http_str).and_return(@response)
53
+ @twitter.profile(:info, @device_attrs)
54
+ end
55
+
56
+ it "should create expected HTTP POST request for :info case" do
57
+ @twitter.should_receive(:create_http_post_request).with(@uris[:info]).and_return(@request)
58
+ @twitter.profile(:info, @info_attrs)
59
+ end
60
+
61
+ it "should create expected HTTP POST request for :colors case" do
62
+ @twitter.should_receive(:create_http_post_request).with(@uris[:colors]).and_return(@request)
63
+ @twitter.profile(:colors, @colors_attrs)
64
+ end
65
+
66
+ it "should create expected HTTP POST request for :device case" do
67
+ @twitter.should_receive(:create_http_post_request).with(@uris[:device]).and_return(@request)
68
+ @twitter.profile(:device, @device_attrs)
69
+ end
70
+
71
+ it "should bless returned Twitter::User object for :info case" do
72
+ @twitter.should_receive(:bless_model).with(@user)
73
+ @twitter.profile(:info, @info_attrs)
74
+ end
75
+
76
+ it "should bless returned Twitter::User object for :colors case" do
77
+ @twitter.should_receive(:bless_model).with(@user)
78
+ @twitter.profile(:colors, @colors_attrs)
79
+ end
80
+
81
+ it "should bless returned Twitter::User object for :device case" do
82
+ @twitter.should_receive(:bless_model).with(@user)
83
+ @twitter.profile(:device, @device_attrs)
84
+ end
85
+
86
+ it "should raise an ArgumentError when giving an invalid profile action"
87
+
88
+ after(:each) do
89
+ nilize(@twitter, @uris, @request, @response, @connection, @sender, @recipient, @user, @attributes)
90
+ end
91
+ end
@@ -0,0 +1,68 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ describe Twitter::Client, "#search" do
4
+ before(:each) do
5
+ @twitter = client_context
6
+ @uris = Twitter::Client.class_eval("@@SEARCH_URIS")
7
+ @request = mas_net_http_get(:basic_auth => nil)
8
+ @response = mas_net_http_response(:success, "{\"results\": [], \"refresh_url\":\"?since_id=1768746401&q=blabla\"}")
9
+ @connection = mas_net_http(@response)
10
+ Net::HTTP.stub!(:new).and_return(@connection)
11
+ @statuses = []
12
+ Twitter::Status.stub!(:unmarshal).and_return(@statuses)
13
+ @page = 2
14
+ @keywords = "twitter4r"
15
+ @to = "SusanPotter"
16
+ @from = "twitter4r"
17
+ end
18
+
19
+ it "should create expected HTTP GET request using :to" do
20
+ @twitter.should_receive(:create_http_get_request).with(@uris[:basic], {:to => @to}).and_return(@request)
21
+ @twitter.search(:to => @to)
22
+ end
23
+
24
+ it "should bless the Array returned from Twitter for :to case" do
25
+ @twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses)
26
+ @twitter.search(:to => @to)
27
+ end
28
+
29
+ it "should create expected HTTP GET request using :from" do
30
+ @twitter.should_receive(:create_http_get_request).with(@uris[:basic], {:from => @from}).and_return(@request)
31
+ @twitter.search(:from => @from)
32
+ end
33
+
34
+ it "should bless the Array returned from Twitter for :to case" do
35
+ @twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses)
36
+ @twitter.search(:from => @from)
37
+ end
38
+
39
+ it "should create expected HTTP GET request using :keywords" do
40
+ @twitter.should_receive(:create_http_get_request).with(@uris[:basic], {:keywords => @keywords}).and_return(@request)
41
+ @twitter.search(:keywords => @keywords)
42
+ end
43
+
44
+ it "should bless the Array returned from Twitter for :keywords case" do
45
+ @twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses)
46
+ @twitter.search(:keywords => @keywords)
47
+ end
48
+
49
+ it "should accept paging option" do
50
+ lambda {
51
+ @twitter.search(:keywords => @keywords, :page => @page)
52
+ }.should_not raise_error(Exception)
53
+ end
54
+
55
+ it "should generate expected GET HTTP request for paging case" do
56
+ @twitter.should_receive(:create_http_get_request).with(@uris[:basic], {:page => @page}).and_return(@request)
57
+ @twitter.search(:page => @page)
58
+ end
59
+
60
+ it "should bless models for paging case" do
61
+ @twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses)
62
+ @twitter.search(:page => @page)
63
+ end
64
+
65
+ after(:each) do
66
+ nilize(@twitter, @uris, @request, @response, @connection, @statuses)
67
+ end
68
+ end
@@ -11,6 +11,7 @@ describe Twitter::Client, "#status" do
11
11
  @connection = mas_net_http(@response)
12
12
  @float = 43.3434
13
13
  @status = Twitter::Status.new(:id => 2349343)
14
+ @reply_to_status_id = 3495293
14
15
  @source = Twitter::Client.class_eval("@@defaults[:source]")
15
16
  end
16
17
 
@@ -55,6 +56,32 @@ describe Twitter::Client, "#status" do
55
56
  @twitter.status(:post, @message)
56
57
  end
57
58
 
59
+ it "should return nil if no :status key-value given in the value argument for :reply case" do
60
+ status = @twitter.status(:reply, {})
61
+ status.should be_nil
62
+ end
63
+
64
+ it "should return nil if nil is passed as value argument for :reply case" do
65
+ status = @twitter.status(:reply, nil)
66
+ status.should be_nil
67
+ end
68
+
69
+ it "should not call @twitter#http_connect when passing a value Hash argument that has no :status key-value in :reply case" do
70
+ @twitter.should_not_receive(:http_connect)
71
+ @twitter.status(:reply, {})
72
+ end
73
+
74
+ it "should not call @twitter#http_connect when passing nil for value argument in :reply case" do
75
+ @twitter.should_not_receive(:http_connect)
76
+ @twitter.status(:reply, nil)
77
+ end
78
+
79
+ it "should create expected HTTP POST request for :reply case" do
80
+ @twitter.should_receive(:create_http_post_request).with(@uris[:reply]).and_return(@request)
81
+ @connection.should_receive(:request).with(@request, {:status => @message, :source => @source, :in_reply_to_status_id => @reply_to_status_id}.to_http_str).and_return(@response)
82
+ @twitter.status(:reply, :status => @message, :in_reply_to_status_id => @reply_to_status_id)
83
+ end
84
+
58
85
  it "should return nil if nil is passed as value argument for :delete case" do
59
86
  status = @twitter.status(:delete, nil)
60
87
  status.should be_nil