twitter 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. data/CHANGELOG.md +673 -0
  2. data/LICENSE.md +20 -0
  3. data/README.md +415 -0
  4. data/Rakefile +11 -0
  5. data/lib/twitter.rb +29 -0
  6. data/lib/twitter/action/favorite.rb +19 -0
  7. data/lib/twitter/action/follow.rb +31 -0
  8. data/lib/twitter/action/list_member_added.rb +41 -0
  9. data/lib/twitter/action/mention.rb +48 -0
  10. data/lib/twitter/action/reply.rb +27 -0
  11. data/lib/twitter/action/retweet.rb +27 -0
  12. data/lib/twitter/action/tweet.rb +22 -0
  13. data/lib/twitter/action_factory.rb +22 -0
  14. data/lib/twitter/api.rb +2442 -0
  15. data/lib/twitter/base.rb +119 -0
  16. data/lib/twitter/basic_user.rb +8 -0
  17. data/lib/twitter/client.rb +96 -0
  18. data/lib/twitter/configurable.rb +67 -0
  19. data/lib/twitter/configuration.rb +20 -0
  20. data/lib/twitter/core_ext/array.rb +7 -0
  21. data/lib/twitter/core_ext/enumerable.rb +11 -0
  22. data/lib/twitter/core_ext/hash.rb +100 -0
  23. data/lib/twitter/core_ext/kernel.rb +15 -0
  24. data/lib/twitter/core_ext/string.rb +10 -0
  25. data/lib/twitter/creatable.rb +20 -0
  26. data/lib/twitter/cursor.rb +87 -0
  27. data/lib/twitter/default.rb +101 -0
  28. data/lib/twitter/direct_message.rb +21 -0
  29. data/lib/twitter/entity.rb +7 -0
  30. data/lib/twitter/entity/hashtag.rb +9 -0
  31. data/lib/twitter/entity/url.rb +9 -0
  32. data/lib/twitter/entity/user_mention.rb +9 -0
  33. data/lib/twitter/error.rb +34 -0
  34. data/lib/twitter/error/bad_gateway.rb +11 -0
  35. data/lib/twitter/error/bad_request.rb +10 -0
  36. data/lib/twitter/error/client_error.rb +35 -0
  37. data/lib/twitter/error/decode_error.rb +9 -0
  38. data/lib/twitter/error/forbidden.rb +10 -0
  39. data/lib/twitter/error/gateway_timeout.rb +11 -0
  40. data/lib/twitter/error/identity_map_key_error.rb +9 -0
  41. data/lib/twitter/error/internal_server_error.rb +11 -0
  42. data/lib/twitter/error/not_acceptable.rb +10 -0
  43. data/lib/twitter/error/not_found.rb +10 -0
  44. data/lib/twitter/error/rate_limited.rb +11 -0
  45. data/lib/twitter/error/server_error.rb +28 -0
  46. data/lib/twitter/error/service_unavailable.rb +11 -0
  47. data/lib/twitter/error/unauthorized.rb +10 -0
  48. data/lib/twitter/factory.rb +21 -0
  49. data/lib/twitter/geo.rb +15 -0
  50. data/lib/twitter/geo/point.rb +22 -0
  51. data/lib/twitter/geo/polygon.rb +8 -0
  52. data/lib/twitter/geo_factory.rb +18 -0
  53. data/lib/twitter/identity.rb +50 -0
  54. data/lib/twitter/identity_map.rb +22 -0
  55. data/lib/twitter/language.rb +7 -0
  56. data/lib/twitter/list.rb +18 -0
  57. data/lib/twitter/media/photo.rb +22 -0
  58. data/lib/twitter/media_factory.rb +17 -0
  59. data/lib/twitter/metadata.rb +7 -0
  60. data/lib/twitter/oembed.rb +8 -0
  61. data/lib/twitter/place.rb +34 -0
  62. data/lib/twitter/rate_limit.rb +45 -0
  63. data/lib/twitter/relationship.rb +36 -0
  64. data/lib/twitter/request/multipart_with_file.rb +41 -0
  65. data/lib/twitter/response/parse_json.rb +25 -0
  66. data/lib/twitter/response/raise_error.rb +30 -0
  67. data/lib/twitter/saved_search.rb +9 -0
  68. data/lib/twitter/search_results.rb +48 -0
  69. data/lib/twitter/settings.rb +17 -0
  70. data/lib/twitter/size.rb +24 -0
  71. data/lib/twitter/source_user.rb +15 -0
  72. data/lib/twitter/suggestion.rb +22 -0
  73. data/lib/twitter/target_user.rb +8 -0
  74. data/lib/twitter/trend.rb +14 -0
  75. data/lib/twitter/tweet.rb +145 -0
  76. data/lib/twitter/user.rb +97 -0
  77. data/lib/twitter/version.rb +18 -0
  78. data/spec/fixtures/about_me.json +1 -0
  79. data/spec/fixtures/activity_summary.json +1 -0
  80. data/spec/fixtures/all.json +1 -0
  81. data/spec/fixtures/bad_gateway.json +1 -0
  82. data/spec/fixtures/bad_request.json +1 -0
  83. data/spec/fixtures/by_friends.json +1 -0
  84. data/spec/fixtures/category.json +1 -0
  85. data/spec/fixtures/configuration.json +1 -0
  86. data/spec/fixtures/contributees.json +1 -0
  87. data/spec/fixtures/contributors.json +1 -0
  88. data/spec/fixtures/direct_message.json +1 -0
  89. data/spec/fixtures/direct_messages.json +1 -0
  90. data/spec/fixtures/end_session.json +1 -0
  91. data/spec/fixtures/enhance_your_calm.text +11 -0
  92. data/spec/fixtures/favorites.json +1 -0
  93. data/spec/fixtures/following.json +1 -0
  94. data/spec/fixtures/forbidden.json +1 -0
  95. data/spec/fixtures/friendships.json +1 -0
  96. data/spec/fixtures/ids.json +1 -0
  97. data/spec/fixtures/ids_list.json +1 -0
  98. data/spec/fixtures/ids_list2.json +1 -0
  99. data/spec/fixtures/image_facets.json +1 -0
  100. data/spec/fixtures/internal_server_error.json +1 -0
  101. data/spec/fixtures/languages.json +1 -0
  102. data/spec/fixtures/list.json +1 -0
  103. data/spec/fixtures/lists.json +1 -0
  104. data/spec/fixtures/locations.json +1 -0
  105. data/spec/fixtures/matching_trends.json +1 -0
  106. data/spec/fixtures/me.jpeg +0 -0
  107. data/spec/fixtures/media_timeline.json +1 -0
  108. data/spec/fixtures/members.json +1 -0
  109. data/spec/fixtures/no_user_matches.json +1 -0
  110. data/spec/fixtures/not_acceptable.json +1 -0
  111. data/spec/fixtures/not_following.json +1 -0
  112. data/spec/fixtures/not_found.json +1 -0
  113. data/spec/fixtures/oembed.json +1 -0
  114. data/spec/fixtures/pbjt.gif +0 -0
  115. data/spec/fixtures/pengwynn.json +1 -0
  116. data/spec/fixtures/phoenix_search.phoenix +1 -0
  117. data/spec/fixtures/place.json +1 -0
  118. data/spec/fixtures/places.json +1 -0
  119. data/spec/fixtures/privacy.json +1 -0
  120. data/spec/fixtures/profile_image.text +24 -0
  121. data/spec/fixtures/rate_limit_status.json +1 -0
  122. data/spec/fixtures/recommendations.json +1 -0
  123. data/spec/fixtures/related_results.json +1 -0
  124. data/spec/fixtures/resolve.json +1 -0
  125. data/spec/fixtures/retweet.json +1 -0
  126. data/spec/fixtures/retweeted_status.json +1 -0
  127. data/spec/fixtures/retweeters_of.json +1 -0
  128. data/spec/fixtures/retweets.json +1 -0
  129. data/spec/fixtures/saved_search.json +1 -0
  130. data/spec/fixtures/saved_searches.json +1 -0
  131. data/spec/fixtures/search.json +1 -0
  132. data/spec/fixtures/search_malformed.json +1 -0
  133. data/spec/fixtures/service_unavailable.json +1 -0
  134. data/spec/fixtures/settings.json +1 -0
  135. data/spec/fixtures/sferik.json +1 -0
  136. data/spec/fixtures/status.json +1 -0
  137. data/spec/fixtures/status_with_media.json +104 -0
  138. data/spec/fixtures/statuses.json +1 -0
  139. data/spec/fixtures/suggestions.json +1 -0
  140. data/spec/fixtures/tos.json +1 -0
  141. data/spec/fixtures/totals.json +1 -0
  142. data/spec/fixtures/trends.json +1 -0
  143. data/spec/fixtures/trends_current.json +1 -0
  144. data/spec/fixtures/trends_daily.json +1 -0
  145. data/spec/fixtures/trends_weekly.json +1 -0
  146. data/spec/fixtures/unauthorized.json +1 -0
  147. data/spec/fixtures/user_search.json +1 -0
  148. data/spec/fixtures/user_timeline.json +1 -0
  149. data/spec/fixtures/users.json +1 -0
  150. data/spec/fixtures/users_list.json +1 -0
  151. data/spec/fixtures/video_facets.json +1 -0
  152. data/spec/fixtures/we_concept_bg2.png +0 -0
  153. data/spec/fixtures/wildcomet2.jpe +0 -0
  154. data/spec/helper.rb +53 -0
  155. data/spec/twitter/action/favorite_spec.rb +29 -0
  156. data/spec/twitter/action/follow_spec.rb +29 -0
  157. data/spec/twitter/action/list_member_added_spec.rb +41 -0
  158. data/spec/twitter/action/mention_spec.rb +52 -0
  159. data/spec/twitter/action/reply_spec.rb +41 -0
  160. data/spec/twitter/action/retweet_spec.rb +41 -0
  161. data/spec/twitter/action_factory_spec.rb +37 -0
  162. data/spec/twitter/action_spec.rb +16 -0
  163. data/spec/twitter/api/account_spec.rb +148 -0
  164. data/spec/twitter/api/activity_spec.rb +41 -0
  165. data/spec/twitter/api/blocks_spec.rb +167 -0
  166. data/spec/twitter/api/direct_messages_spec.rb +142 -0
  167. data/spec/twitter/api/friendships_spec.rb +567 -0
  168. data/spec/twitter/api/geo_spec.rb +100 -0
  169. data/spec/twitter/api/help_spec.rb +76 -0
  170. data/spec/twitter/api/lists_spec.rb +900 -0
  171. data/spec/twitter/api/report_spam_spec.rb +29 -0
  172. data/spec/twitter/api/saved_searches_spec.rb +100 -0
  173. data/spec/twitter/api/search_spec.rb +68 -0
  174. data/spec/twitter/api/statuses_spec.rb +559 -0
  175. data/spec/twitter/api/trends_spec.rb +80 -0
  176. data/spec/twitter/api/users_spec.rb +419 -0
  177. data/spec/twitter/base_spec.rb +113 -0
  178. data/spec/twitter/basic_user_spec.rb +23 -0
  179. data/spec/twitter/client_spec.rb +175 -0
  180. data/spec/twitter/configuration_spec.rb +17 -0
  181. data/spec/twitter/cursor_spec.rb +102 -0
  182. data/spec/twitter/direct_message_spec.rb +56 -0
  183. data/spec/twitter/error/client_error_spec.rb +40 -0
  184. data/spec/twitter/error/server_error_spec.rb +24 -0
  185. data/spec/twitter/error_spec.rb +20 -0
  186. data/spec/twitter/geo/point_spec.rb +41 -0
  187. data/spec/twitter/geo/polygon_spec.rb +29 -0
  188. data/spec/twitter/geo_factory_spec.rb +21 -0
  189. data/spec/twitter/geo_spec.rb +29 -0
  190. data/spec/twitter/identifiable_spec.rb +54 -0
  191. data/spec/twitter/list_spec.rb +45 -0
  192. data/spec/twitter/media/photo_spec.rb +35 -0
  193. data/spec/twitter/media_factory_spec.rb +17 -0
  194. data/spec/twitter/oembed_spec.rb +146 -0
  195. data/spec/twitter/place_spec.rb +75 -0
  196. data/spec/twitter/rate_limit_spec.rb +76 -0
  197. data/spec/twitter/relationship_spec.rb +35 -0
  198. data/spec/twitter/saved_search_spec.rb +34 -0
  199. data/spec/twitter/search_results_spec.rb +89 -0
  200. data/spec/twitter/settings_spec.rb +16 -0
  201. data/spec/twitter/size_spec.rb +38 -0
  202. data/spec/twitter/source_user_spec.rb +23 -0
  203. data/spec/twitter/suggestion_spec.rb +50 -0
  204. data/spec/twitter/target_user_spec.rb +23 -0
  205. data/spec/twitter/trend_spec.rb +38 -0
  206. data/spec/twitter/tweet_spec.rb +307 -0
  207. data/spec/twitter/user_spec.rb +127 -0
  208. data/spec/twitter_spec.rb +93 -0
  209. data/twitter.gemspec +30 -0
  210. metadata +584 -0
@@ -0,0 +1,113 @@
1
+ require 'helper'
2
+
3
+ describe Twitter::Base do
4
+
5
+ context 'identity map enabled' do
6
+ before do
7
+ Twitter.identity_map = Twitter::IdentityMap
8
+ object = Twitter::Base.new(:id => 1)
9
+ @base = Twitter::Base.store(object)
10
+ end
11
+
12
+ after do
13
+ Twitter.identity_map = false
14
+ end
15
+
16
+ describe '.identity_map' do
17
+ it 'returns an instance of the identity map' do
18
+ Twitter::Base.identity_map.should be_a Twitter::IdentityMap
19
+ end
20
+ end
21
+
22
+ describe '.fetch' do
23
+ it 'returns existing objects' do
24
+ Twitter::Base.fetch(:id => 1).should be
25
+ end
26
+
27
+ it "raises an error on objects that don't exist" do
28
+ lambda {
29
+ Twitter::Base.fetch(:id => 6)
30
+ }.should raise_error(Twitter::Error::IdentityMapKeyError)
31
+ end
32
+ end
33
+
34
+ describe '.store' do
35
+ it 'stores Twitter::Base objects' do
36
+ object = Twitter::Base.new(:id => 4)
37
+ Twitter::Base.store(object).should be_a Twitter::Base
38
+ end
39
+ end
40
+
41
+ describe '.fetch_or_new' do
42
+ it 'returns existing objects' do
43
+ Twitter::Base.fetch_or_new(:id => 1).should be
44
+ end
45
+ it 'creates new objects and stores them' do
46
+ Twitter::Base.fetch_or_new(:id => 2).should be
47
+ Twitter::Base.fetch(:id => 2).should be
48
+ end
49
+ end
50
+
51
+ describe "#[]" do
52
+ it "calls methods using [] with symbol" do
53
+ @base[:object_id].should be_an Integer
54
+ end
55
+ it "calls methods using [] with string" do
56
+ @base['object_id'].should be_an Integer
57
+ end
58
+ it "returns nil for missing method" do
59
+ @base[:foo].should be_nil
60
+ @base['foo'].should be_nil
61
+ end
62
+ end
63
+
64
+ describe "#to_hash" do
65
+ it "returns a hash" do
66
+ @base.to_hash.should be_a Hash
67
+ @base.to_hash[:id].should eq 1
68
+ end
69
+ end
70
+
71
+ describe "identical objects" do
72
+ it "have the same object_id" do
73
+ @base.object_id.should eq Twitter::Base.fetch(:id => 1).object_id
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ context 'identity map disabled' do
80
+ before(:all) do
81
+ Twitter.identity_map = false
82
+ end
83
+ after(:all) do
84
+ Twitter.identity_map = Twitter::IdentityMap
85
+ end
86
+
87
+ describe '.identity_map' do
88
+ it 'returns nil' do
89
+ Twitter::Base.identity_map.should be_nil
90
+ end
91
+ end
92
+
93
+ describe '.fetch' do
94
+ it 'returns nil' do
95
+ Twitter::Base.fetch(:id => 1).should be_nil
96
+ end
97
+ end
98
+
99
+ describe '.store' do
100
+ it 'returns an instance of the object' do
101
+ Twitter::Base.store(Twitter::Base.new(:id => 1)).should be_a Twitter::Base
102
+ end
103
+ end
104
+
105
+ describe '.fetch_or_new' do
106
+ it 'creates new objects' do
107
+ Twitter::Base.fetch_or_new(:id => 2).should be
108
+ Twitter.identity_map.should be_false
109
+ end
110
+ end
111
+ end
112
+
113
+ end
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+
3
+ describe Twitter::BasicUser do
4
+
5
+ describe "#==" do
6
+ it "returns true when objects IDs are the same" do
7
+ saved_search = Twitter::BasicUser.new(:id => 1, :name => "foo")
8
+ other = Twitter::BasicUser.new(:id => 1, :name => "bar")
9
+ (saved_search == other).should be_true
10
+ end
11
+ it "returns false when objects IDs are different" do
12
+ saved_search = Twitter::BasicUser.new(:id => 1)
13
+ other = Twitter::BasicUser.new(:id => 2)
14
+ (saved_search == other).should be_false
15
+ end
16
+ it "returns false when classes are different" do
17
+ saved_search = Twitter::BasicUser.new(:id => 1)
18
+ other = Twitter::Identity.new(:id => 1)
19
+ (saved_search == other).should be_false
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,175 @@
1
+ require 'helper'
2
+
3
+ describe Twitter::Client do
4
+
5
+ subject do
6
+ client = Twitter::Client.new(:consumer_key => "CK", :consumer_secret => "CS", :oauth_token => "OT", :oauth_token_secret => "OS")
7
+ client.class_eval{public *Twitter::Client.private_instance_methods}
8
+ client
9
+ end
10
+
11
+ context "with module configuration" do
12
+
13
+ before do
14
+ Twitter.configure do |config|
15
+ Twitter::Configurable.keys.each do |key|
16
+ config.send("#{key}=", key)
17
+ end
18
+ end
19
+ end
20
+
21
+ after do
22
+ Twitter.reset!
23
+ end
24
+
25
+ it "inherits the module configuration" do
26
+ client = Twitter::Client.new
27
+ Twitter::Configurable.keys.each do |key|
28
+ client.instance_variable_get(:"@#{key}").should eq key
29
+ end
30
+ end
31
+
32
+ context "with class configuration" do
33
+
34
+ before do
35
+ @configuration = {
36
+ :connection_options => {:timeout => 10},
37
+ :consumer_key => 'CK',
38
+ :consumer_secret => 'CS',
39
+ :endpoint => 'http://tumblr.com/',
40
+ :middleware => Proc.new{},
41
+ :oauth_token => 'OT',
42
+ :oauth_token_secret => 'OS',
43
+ :identity_map => ::Hash
44
+ }
45
+ end
46
+
47
+ context "during initialization" do
48
+ it "overrides the module configuration" do
49
+ client = Twitter::Client.new(@configuration)
50
+ Twitter::Configurable.keys.each do |key|
51
+ client.instance_variable_get(:"@#{key}").should eq @configuration[key]
52
+ end
53
+ end
54
+ end
55
+
56
+ context "after initilization" do
57
+ it "overrides the module configuration after initialization" do
58
+ client = Twitter::Client.new
59
+ client.configure do |config|
60
+ @configuration.each do |key, value|
61
+ config.send("#{key}=", value)
62
+ end
63
+ end
64
+ Twitter::Configurable.keys.each do |key|
65
+ client.instance_variable_get(:"@#{key}").should eq @configuration[key]
66
+ end
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+
73
+ it "does not cache the screen name across clients" do
74
+ stub_get("/1.1/account/verify_credentials.json").
75
+ to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
76
+ client1 = Twitter::Client.new
77
+ client1.verify_credentials.id.should eq 7505382
78
+ stub_get("/1.1/account/verify_credentials.json").
79
+ to_return(:body => fixture("pengwynn.json"), :headers => {:content_type => "application/json; charset=utf-8"})
80
+ client2 = Twitter::Client.new
81
+ client2.verify_credentials.id.should eq 14100886
82
+ end
83
+
84
+ describe "#delete" do
85
+ before do
86
+ stub_delete("/custom/delete").
87
+ with(:query => {:deleted => "object"})
88
+ end
89
+ it "allows custom put requests" do
90
+ subject.delete("/custom/delete", {:deleted => "object"})
91
+ a_delete("/custom/delete").
92
+ with(:query => {:deleted => "object"}).
93
+ should have_been_made
94
+ end
95
+ end
96
+
97
+ describe "#put" do
98
+ before do
99
+ stub_put("/custom/put").
100
+ with(:body => {:updated => "object"})
101
+ end
102
+ it "allows custom put requests" do
103
+ subject.put("/custom/put", {:updated => "object"})
104
+ a_put("/custom/put").
105
+ with(:body => {:updated => "object"}).
106
+ should have_been_made
107
+ end
108
+ end
109
+
110
+ describe "#credentials?" do
111
+ it "returns true if all credentials are present" do
112
+ client = Twitter::Client.new(:consumer_key => 'CK', :consumer_secret => 'CS', :oauth_token => 'OT', :oauth_token_secret => 'OS')
113
+ client.credentials?.should be_true
114
+ end
115
+ it "returns false if any credentials are missing" do
116
+ client = Twitter::Client.new(:consumer_key => 'CK', :consumer_secret => 'CS', :oauth_token => 'OT')
117
+ client.credentials?.should be_false
118
+ end
119
+ end
120
+
121
+ describe "#connection" do
122
+ it "looks like Faraday connection" do
123
+ subject.connection.should respond_to(:run_request)
124
+ end
125
+ it "memoizes the connection" do
126
+ c1, c2 = subject.connection, subject.connection
127
+ c1.object_id.should eq c2.object_id
128
+ end
129
+ end
130
+
131
+ describe "#request" do
132
+ it "encodes the entire body when no uploaded media is present" do
133
+ stub_post("/1.1/statuses/update.json").
134
+ with(:body => {:status => "Update"}).
135
+ to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
136
+ subject.update("Update")
137
+ a_post("/1.1/statuses/update.json").
138
+ with(:body => {:status => "Update"}).
139
+ should have_been_made
140
+ end
141
+ it "encodes none of the body when uploaded media is present" do
142
+ stub_post("/1.1/statuses/update_with_media.json").
143
+ to_return(:body => fixture("status_with_media.json"), :headers => {:content_type => "application/json; charset=utf-8"})
144
+ subject.update_with_media("Update", fixture("pbjt.gif"))
145
+ a_post("/1.1/statuses/update_with_media.json").
146
+ should have_been_made
147
+ end
148
+ it "catches Faraday errors" do
149
+ subject.stub!(:connection).and_raise(Faraday::Error::ClientError.new("Oups"))
150
+ lambda do
151
+ subject.request(:get, "/path")
152
+ end.should raise_error(Twitter::Error::ClientError, "Oups")
153
+ end
154
+ it "catches MultiJson::DecodeError errors" do
155
+ subject.stub!(:connection).and_raise(MultiJson::DecodeError.new("unexpected token", [], "<!DOCTYPE html>"))
156
+ lambda do
157
+ subject.request(:get, "/path")
158
+ end.should raise_error(Twitter::Error::DecodeError, "unexpected token")
159
+ end
160
+ end
161
+
162
+ describe "#auth_header" do
163
+ it "creates the correct auth headers" do
164
+ uri = URI("https://api.twitter.com/1.1/direct_messages.json")
165
+ authorization = subject.auth_header(:get, uri)
166
+ authorization.options[:signature_method].should eq "HMAC-SHA1"
167
+ authorization.options[:version].should eq "1.0"
168
+ authorization.options[:consumer_key].should eq "CK"
169
+ authorization.options[:consumer_secret].should eq "CS"
170
+ authorization.options[:token].should eq "OT"
171
+ authorization.options[:token_secret].should eq "OS"
172
+ end
173
+ end
174
+
175
+ end
@@ -0,0 +1,17 @@
1
+ require 'helper'
2
+
3
+ describe Twitter::Configuration do
4
+
5
+ describe "#photo_sizes" do
6
+ it "returns a hash of sizes when photo_sizes is set" do
7
+ photo_sizes = Twitter::Configuration.new(:photo_sizes => {:small => {:h => 226, :w => 340, :resize => 'fit'}, :large => {:h => 466, :w => 700, :resize => 'fit'}, :medium => {:h => 399, :w => 600, :resize => 'fit'}, :thumb => {:h => 150, :w => 150, :resize => 'crop'}}).photo_sizes
8
+ photo_sizes.should be_a Hash
9
+ photo_sizes[:small].should be_a Twitter::Size
10
+ end
11
+ it "is empty when photo_sizes is not set" do
12
+ photo_sizes = Twitter::Configuration.new.photo_sizes
13
+ photo_sizes.should be_empty
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,102 @@
1
+ require 'helper'
2
+
3
+ describe Twitter::Cursor do
4
+
5
+ describe "#collection" do
6
+ it "returns a collection" do
7
+ collection = Twitter::Cursor.new({:ids => [1, 2, 3, 4, 5]}, :ids, nil, Twitter::Client.new, :follower_ids, {}).collection
8
+ collection.should be_an Array
9
+ collection.first.should be_a Fixnum
10
+ end
11
+ end
12
+
13
+ describe "#all" do
14
+ before do
15
+ @client = Twitter::Client.new
16
+ stub_get("/1.1/followers/ids.json").
17
+ with(:query => {:cursor => "-1", :screen_name => "sferik"}).
18
+ to_return(:body => fixture("ids_list.json"), :headers => {:content_type => "application/json; charset=utf-8"})
19
+ stub_get("/1.1/followers/ids.json").
20
+ with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"}).
21
+ to_return(:body => fixture("ids_list2.json"), :headers => {:content_type => "application/json; charset=utf-8"})
22
+ end
23
+ it "requests the correct resources" do
24
+ @client.follower_ids("sferik").all
25
+ a_get("/1.1/followers/ids.json").
26
+ with(:query => {:cursor => "-1", :screen_name => "sferik"}).
27
+ should have_been_made
28
+ a_get("/1.1/followers/ids.json").
29
+ with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"}).
30
+ should have_been_made
31
+ end
32
+ it "fetches all" do
33
+ follower_ids = @client.follower_ids("sferik").all
34
+ follower_ids.size.should == 5993
35
+ end
36
+ end
37
+
38
+ describe "#each" do
39
+ before do
40
+ @client = Twitter::Client.new
41
+ stub_get("/1.1/followers/ids.json").
42
+ with(:query => {:cursor => "-1", :screen_name => "sferik"}).
43
+ to_return(:body => fixture("ids_list.json"), :headers => {:content_type => "application/json; charset=utf-8"})
44
+ stub_get("/1.1/followers/ids.json").
45
+ with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"}).
46
+ to_return(:body => fixture("ids_list2.json"), :headers => {:content_type => "application/json; charset=utf-8"})
47
+ end
48
+ it "requests the correct resources" do
49
+ @client.follower_ids("sferik").each{}
50
+ a_get("/1.1/followers/ids.json").
51
+ with(:query => {:cursor => "-1", :screen_name => "sferik"}).
52
+ should have_been_made
53
+ a_get("/1.1/followers/ids.json").
54
+ with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"}).
55
+ should have_been_made
56
+ end
57
+ it "iterates" do
58
+ count = 0
59
+ @client.follower_ids("sferik").each{count += 1}
60
+ count.should == 5993
61
+ end
62
+ end
63
+
64
+ describe "#first?" do
65
+ context "when previous cursor equals zero" do
66
+ before do
67
+ @cursor = Twitter::Cursor.new({:previous_cursor => 0}, :ids, nil, Twitter::Client.new, :follower_ids, {})
68
+ end
69
+ it "returns true" do
70
+ @cursor.first?.should be_true
71
+ end
72
+ end
73
+ context "when previous cursor does not equal zero" do
74
+ before do
75
+ @cursor = Twitter::Cursor.new({:previous_cursor => 1}, :ids, nil, Twitter::Client.new, :follower_ids, {})
76
+ end
77
+ it "returns true" do
78
+ @cursor.first?.should be_false
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "#last?" do
84
+ context "when next cursor equals zero" do
85
+ before do
86
+ @cursor = Twitter::Cursor.new({:next_cursor => 0}, :ids, nil, Twitter::Client.new, :follower_ids, {})
87
+ end
88
+ it "returns true" do
89
+ @cursor.last?.should be_true
90
+ end
91
+ end
92
+ context "when next cursor does not equal zero" do
93
+ before do
94
+ @cursor = Twitter::Cursor.new({:next_cursor => 1}, :ids, nil, Twitter::Client.new, :follower_ids, {})
95
+ end
96
+ it "returns false" do
97
+ @cursor.last?.should be_false
98
+ end
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,56 @@
1
+ require 'helper'
2
+
3
+ describe Twitter::DirectMessage do
4
+
5
+ describe "#==" do
6
+ it "returns true when objects IDs are the same" do
7
+ direct_message = Twitter::DirectMessage.new(:id => 1, :text => "foo")
8
+ other = Twitter::DirectMessage.new(:id => 1, :text => "bar")
9
+ (direct_message == other).should be_true
10
+ end
11
+ it "returns false when objects IDs are different" do
12
+ direct_message = Twitter::DirectMessage.new(:id => 1)
13
+ other = Twitter::DirectMessage.new(:id => 2)
14
+ (direct_message == other).should be_false
15
+ end
16
+ it "returns false when classes are different" do
17
+ direct_message = Twitter::DirectMessage.new(:id => 1)
18
+ other = Twitter::Identity.new(:id => 1)
19
+ (direct_message == other).should be_false
20
+ end
21
+ end
22
+
23
+ describe "#created_at" do
24
+ it "returns a Time when created_at is set" do
25
+ direct_message = Twitter::DirectMessage.new(:id => 1825786345, :created_at => "Mon Jul 16 12:59:01 +0000 2007")
26
+ direct_message.created_at.should be_a Time
27
+ end
28
+ it "returns nil when created_at is not set" do
29
+ direct_message = Twitter::DirectMessage.new(:id => 1825786345)
30
+ direct_message.created_at.should be_nil
31
+ end
32
+ end
33
+
34
+ describe "#recipient" do
35
+ it "returns a User when recipient is set" do
36
+ recipient = Twitter::DirectMessage.new(:id => 1825786345, :recipient => {:id => 7505382}).recipient
37
+ recipient.should be_a Twitter::User
38
+ end
39
+ it "returns nil when recipient is not set" do
40
+ recipient = Twitter::DirectMessage.new(:id => 1825786345).recipient
41
+ recipient.should be_nil
42
+ end
43
+ end
44
+
45
+ describe "#sender" do
46
+ it "returns a User when sender is set" do
47
+ sender = Twitter::DirectMessage.new(:id => 1825786345, :sender => {:id => 7505382}).sender
48
+ sender.should be_a Twitter::User
49
+ end
50
+ it "returns nil when sender is not set" do
51
+ sender = Twitter::DirectMessage.new(:id => 1825786345).sender
52
+ sender.should be_nil
53
+ end
54
+ end
55
+
56
+ end