twitter 4.1.2 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +9 -1
- data/README.md +1 -1
- data/lib/twitter/api.rb +95 -23
- data/lib/twitter/basic_user.rb +3 -0
- data/lib/twitter/core_ext/enumerable.rb +14 -6
- data/lib/twitter/error/already_favorited.rb +10 -0
- data/lib/twitter/error/already_retweeted.rb +10 -0
- data/lib/twitter/version.rb +2 -2
- data/spec/fixtures/already_favorited.json +1 -0
- data/spec/fixtures/already_retweeted.json +1 -0
- data/spec/twitter/api/statuses_spec.rb +85 -5
- metadata +8 -2
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
4.2.0
|
2
|
+
-----
|
3
|
+
* [Use new resource for `Twitter::API#retweets_of_me`](https://github.com/sferik/twitter/commit/d88ca1e91af06e748c31dcda287326028cf28258)
|
4
|
+
* [`Twitter::API#favorite` no longer raises `Twitter::Error::Forbidden`](https://github.com/sferik/twitter/commit/65c01133a96106a6b0c61bc16cb2ffec38fa5e25)
|
5
|
+
* [`Twitter::API#retweet` no longer raises `Twitter::Error::Forbidden`](https://github.com/sferik/twitter/commit/f1322ab12c573229ea3dc8decda2e2ea8b36fc31)
|
6
|
+
* [Add `Twitter::Error::AlreadyFavorited`](https://github.com/sferik/twitter/commit/34710927e00d4dc5abc049bfc198bdd337fba1bd)
|
7
|
+
* [Add `Twitter::Error::AlreadyRetweeted`](https://github.com/sferik/twitter/commit/2a231a0888dcd65dbef2dc92571e06d50f845cca)
|
8
|
+
|
1
9
|
4.1.2
|
2
10
|
-----
|
3
|
-
* [Add abort_on_exception to threaded_map](https://github.com/sferik/twitter/commit/15c9a7c221f24226c1003b76b287d2b2ed9306cb)
|
11
|
+
* [Add abort_on_exception to `Enumerable#threaded_map`](https://github.com/sferik/twitter/commit/15c9a7c221f24226c1003b76b287d2b2ed9306cb) ([@aheaven87](http://twitter.com/aheaven87))
|
4
12
|
|
5
13
|
4.1.1
|
6
14
|
-----
|
data/README.md
CHANGED
@@ -216,7 +216,7 @@ Twitter.update("I'm tweeting with @gem!")
|
|
216
216
|
Applications that make requests on behalf of multiple Twitter users should
|
217
217
|
avoid using global configuration. In this case, you may still specify the
|
218
218
|
`consumer_key` and `consumer_secret` globally. (In a Rails application, this
|
219
|
-
could go in `config/
|
219
|
+
could go in `config/initializers/twitter.rb`.)
|
220
220
|
|
221
221
|
```ruby
|
222
222
|
Twitter.configure do |config|
|
data/lib/twitter/api.rb
CHANGED
@@ -6,6 +6,8 @@ require 'twitter/core_ext/hash'
|
|
6
6
|
require 'twitter/core_ext/kernel'
|
7
7
|
require 'twitter/cursor'
|
8
8
|
require 'twitter/direct_message'
|
9
|
+
require 'twitter/error/already_favorited'
|
10
|
+
require 'twitter/error/already_retweeted'
|
9
11
|
require 'twitter/error/forbidden'
|
10
12
|
require 'twitter/error/not_found'
|
11
13
|
require 'twitter/language'
|
@@ -1372,7 +1374,7 @@ module Twitter
|
|
1372
1374
|
# @option options [String] :until Optional. Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD.
|
1373
1375
|
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available.
|
1374
1376
|
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
|
1375
|
-
# @option options [Boolean, String, Integer] :include_entities
|
1377
|
+
# @option options [Boolean, String, Integer] :include_entities The tweet entities node will be disincluded when set to false.
|
1376
1378
|
# @return [Twitter::SearchResults] Return tweets that match a specified query with search metadata
|
1377
1379
|
# @example Returns tweets related to twitter
|
1378
1380
|
# Twitter.search('twitter')
|
@@ -1443,13 +1445,50 @@ module Twitter
|
|
1443
1445
|
def favorite(*args)
|
1444
1446
|
options = args.extract_options!
|
1445
1447
|
args.flatten.threaded_map do |id|
|
1446
|
-
|
1447
|
-
|
1448
|
+
begin
|
1449
|
+
object_from_response(Twitter::Tweet, :post, "/1.1/favorites/create.json", options.merge(:id => id))
|
1450
|
+
rescue Twitter::Error::Forbidden => error
|
1451
|
+
raise unless error.message == Twitter::Error::AlreadyFavorited::MESSAGE
|
1452
|
+
end
|
1453
|
+
end.compact
|
1448
1454
|
end
|
1449
1455
|
alias fav favorite
|
1450
1456
|
alias fave favorite
|
1451
1457
|
alias favorite_create favorite
|
1452
1458
|
|
1459
|
+
# Favorites the specified Tweets as the authenticating user and raises an error if one has already been favorited
|
1460
|
+
#
|
1461
|
+
# @see https://dev.twitter.com/docs/api/1.1/post/favorites/create
|
1462
|
+
# @rate_limited No
|
1463
|
+
# @authentication_required Requires user context
|
1464
|
+
# @raise [Twitter::Error::AlreadyFavorited] Error raised when tweet has already been favorited.
|
1465
|
+
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
1466
|
+
# @return [Array<Twitter::Tweet>] The favorited Tweets.
|
1467
|
+
# @overload favorite(*ids)
|
1468
|
+
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
|
1469
|
+
# @example Favorite the Tweet with the ID 25938088801
|
1470
|
+
# Twitter.favorite(25938088801)
|
1471
|
+
# @overload favorite(*ids, options)
|
1472
|
+
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
|
1473
|
+
# @param options [Hash] A customizable set of options.
|
1474
|
+
def favorite!(*args)
|
1475
|
+
options = args.extract_options!
|
1476
|
+
args.flatten.threaded_map do |id|
|
1477
|
+
begin
|
1478
|
+
object_from_response(Twitter::Tweet, :post, "/1.1/favorites/create.json", options.merge(:id => id))
|
1479
|
+
rescue Twitter::Error::Forbidden => error
|
1480
|
+
if error.message == "You have already favorited this status"
|
1481
|
+
raise Twitter::Error::AlreadyFavorited.new("Tweet with the ID #{id} has already been favorited by the authenticated user.")
|
1482
|
+
else
|
1483
|
+
raise
|
1484
|
+
end
|
1485
|
+
end
|
1486
|
+
end
|
1487
|
+
end
|
1488
|
+
alias fav! favorite!
|
1489
|
+
alias fave! favorite!
|
1490
|
+
alias favorite_create! favorite!
|
1491
|
+
|
1453
1492
|
# Un-favorites the specified Tweets as the authenticating user
|
1454
1493
|
#
|
1455
1494
|
# @see https://dev.twitter.com/docs/api/1.1/post/favorites/destroy
|
@@ -1488,7 +1527,7 @@ module Twitter
|
|
1488
1527
|
# @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
|
1489
1528
|
# @option options [Boolean, String, Integer] :include_rts Specifies that the timeline should include native retweets in addition to regular tweets. Note: If you're using the trim_user parameter in conjunction with include_rts, the retweets will no longer contain a full user object.
|
1490
1529
|
# @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
|
1491
|
-
# @option options [Boolean, String, Integer] :include_entities
|
1530
|
+
# @option options [Boolean, String, Integer] :include_entities The tweet entities node will be disincluded when set to false.
|
1492
1531
|
# @example Return the 20 most recent Tweets, including retweets if they exist, posted by the authenticating user and the users they follow
|
1493
1532
|
# Twitter.home_timeline
|
1494
1533
|
def home_timeline(options={})
|
@@ -1583,7 +1622,7 @@ module Twitter
|
|
1583
1622
|
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
1584
1623
|
# @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
|
1585
1624
|
# @option options [Boolean, String, Integer] :contributor_details Specifies that the contributors element should be enhanced to include the screen_name of the contributor.
|
1586
|
-
# @option options [Boolean, String, Integer] :include_entities
|
1625
|
+
# @option options [Boolean, String, Integer] :include_entities The tweet entities node will be disincluded when set to false.
|
1587
1626
|
# @example Return the 20 most recent retweets posted by users followed by the authenticating user
|
1588
1627
|
# Twitter.retweeted_to_me
|
1589
1628
|
def retweeted_to_me(options={})
|
@@ -1596,27 +1635,22 @@ module Twitter
|
|
1596
1635
|
|
1597
1636
|
# Returns the 20 most recent tweets of the authenticated user that have been retweeted by others
|
1598
1637
|
#
|
1599
|
-
# @see https://dev.twitter.com/docs/api/1.1/get/statuses/
|
1600
|
-
# @note This method can only return up to 3,200 Tweets.
|
1638
|
+
# @see https://dev.twitter.com/docs/api/1.1/get/statuses/retweets_of_me
|
1601
1639
|
# @rate_limited Yes
|
1602
1640
|
# @authentication_required Requires user context
|
1603
1641
|
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
1604
1642
|
# @return [Array<Twitter::Tweet>]
|
1605
1643
|
# @param options [Hash] A customizable set of options.
|
1644
|
+
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
|
1606
1645
|
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
|
1607
1646
|
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
|
1608
|
-
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
|
1609
1647
|
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
1610
|
-
# @option options [Boolean, String, Integer] :
|
1611
|
-
# @option options [Boolean, String, Integer] :
|
1648
|
+
# @option options [Boolean, String, Integer] :include_entities The tweet entities node will be disincluded when set to false.
|
1649
|
+
# @option options [Boolean, String, Integer] :include_user_entities The user entities node will be disincluded when set to false.
|
1612
1650
|
# @example Return the 20 most recent tweets of the authenticated user that have been retweeted by others
|
1613
1651
|
# Twitter.retweets_of_me
|
1614
1652
|
def retweets_of_me(options={})
|
1615
|
-
|
1616
|
-
count = options[:count] || DEFAULT_TWEETS_PER_REQUEST
|
1617
|
-
collect_with_count(count) do |count_options|
|
1618
|
-
user_timeline(options.merge(count_options)).select{|tweet| tweet.retweet_count.to_i > 0}
|
1619
|
-
end
|
1653
|
+
collection_from_response(Twitter::Tweet, :get, "/1.1/statuses/retweets_of_me.json", options)
|
1620
1654
|
end
|
1621
1655
|
|
1622
1656
|
# Returns the 20 most recent Tweets posted by the specified user
|
@@ -1847,12 +1881,11 @@ module Twitter
|
|
1847
1881
|
end
|
1848
1882
|
alias tweet_destroy status_destroy
|
1849
1883
|
|
1850
|
-
# Retweets
|
1884
|
+
# Retweets the specified Tweets as the authenticating user
|
1851
1885
|
#
|
1852
1886
|
# @see https://dev.twitter.com/docs/api/1.1/post/statuses/retweet/:id
|
1853
1887
|
# @rate_limited Yes
|
1854
1888
|
# @authentication_required Requires user context
|
1855
|
-
# @raise [Twitter::Error::Forbidden] Error raised when tweet has already been retweeted.
|
1856
1889
|
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
1857
1890
|
# @return [Array<Twitter::Tweet>] The original tweets with retweet details embedded.
|
1858
1891
|
# @overload retweet(*ids)
|
@@ -1866,12 +1899,51 @@ module Twitter
|
|
1866
1899
|
def retweet(*args)
|
1867
1900
|
options = args.extract_options!
|
1868
1901
|
args.flatten.threaded_map do |id|
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1902
|
+
begin
|
1903
|
+
response = post("/1.1/statuses/retweet/#{id}.json", options)
|
1904
|
+
retweeted_status = response.dup
|
1905
|
+
retweeted_status[:body] = response[:body].delete(:retweeted_status)
|
1906
|
+
retweeted_status[:body][:retweeted_status] = response[:body]
|
1907
|
+
Twitter::Tweet.from_response(retweeted_status)
|
1908
|
+
rescue Twitter::Error::Forbidden => error
|
1909
|
+
raise unless error.message == Twitter::Error::AlreadyRetweeted::MESSAGE
|
1910
|
+
end
|
1911
|
+
end.compact
|
1912
|
+
end
|
1913
|
+
|
1914
|
+
# Retweets the specified Tweets as the authenticating user and raises an error if one has already been retweeted
|
1915
|
+
#
|
1916
|
+
# @see https://dev.twitter.com/docs/api/1.1/post/statuses/retweet/:id
|
1917
|
+
# @rate_limited Yes
|
1918
|
+
# @authentication_required Requires user context
|
1919
|
+
# @raise [Twitter::Error::AlreadyRetweeted] Error raised when tweet has already been retweeted.
|
1920
|
+
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
|
1921
|
+
# @return [Array<Twitter::Tweet>] The original tweets with retweet details embedded.
|
1922
|
+
# @overload retweet(*ids)
|
1923
|
+
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
|
1924
|
+
# @example Retweet the Tweet with the ID 28561922516
|
1925
|
+
# Twitter.retweet(28561922516)
|
1926
|
+
# @overload retweet(*ids, options)
|
1927
|
+
# @param ids [Array<Integer>, Set<Integer>] An array of Tweet IDs.
|
1928
|
+
# @param options [Hash] A customizable set of options.
|
1929
|
+
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
|
1930
|
+
def retweet!(*args)
|
1931
|
+
options = args.extract_options!
|
1932
|
+
args.flatten.threaded_map do |id|
|
1933
|
+
begin
|
1934
|
+
response = post("/1.1/statuses/retweet/#{id}.json", options)
|
1935
|
+
retweeted_status = response.dup
|
1936
|
+
retweeted_status[:body] = response[:body].delete(:retweeted_status)
|
1937
|
+
retweeted_status[:body][:retweeted_status] = response[:body]
|
1938
|
+
Twitter::Tweet.from_response(retweeted_status)
|
1939
|
+
rescue Twitter::Error::Forbidden => error
|
1940
|
+
if error.message == "sharing is not permissible for this status (Share validations failed)"
|
1941
|
+
raise Twitter::Error::AlreadyRetweeted.new("Tweet with the ID #{id} has already been retweeted by the authenticated user.")
|
1942
|
+
else
|
1943
|
+
raise
|
1944
|
+
end
|
1945
|
+
end
|
1946
|
+
end.compact
|
1875
1947
|
end
|
1876
1948
|
|
1877
1949
|
# Updates the authenticating user's status
|
data/lib/twitter/basic_user.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
module Enumerable
|
2
2
|
|
3
3
|
def threaded_map
|
4
|
+
abort_on_exception do
|
5
|
+
threads = []
|
6
|
+
each do |object|
|
7
|
+
threads << Thread.new { yield object }
|
8
|
+
end
|
9
|
+
threads.map(&:value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def abort_on_exception
|
4
16
|
initial_abort_on_exception = Thread.abort_on_exception
|
5
17
|
Thread.abort_on_exception ||= true
|
6
|
-
|
7
|
-
each do |object|
|
8
|
-
threads << Thread.new { yield object }
|
9
|
-
end
|
10
|
-
values = threads.map(&:value)
|
18
|
+
value = yield
|
11
19
|
Thread.abort_on_exception = initial_abort_on_exception
|
12
|
-
|
20
|
+
value
|
13
21
|
end
|
14
22
|
|
15
23
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'twitter/error/forbidden'
|
2
|
+
|
3
|
+
module Twitter
|
4
|
+
class Error
|
5
|
+
# Raised when a Tweet has already been retweeted
|
6
|
+
class AlreadyRetweeted < Twitter::Error::Forbidden
|
7
|
+
MESSAGE = "sharing is not permissible for this status (Share validations failed)"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/lib/twitter/version.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Twitter
|
2
2
|
class Version
|
3
3
|
MAJOR = 4 unless defined? Twitter::MAJOR
|
4
|
-
MINOR =
|
5
|
-
PATCH =
|
4
|
+
MINOR = 2 unless defined? Twitter::MINOR
|
5
|
+
PATCH = 0 unless defined? Twitter::PATCH
|
6
6
|
PRE = nil unless defined? Twitter::PRE
|
7
7
|
|
8
8
|
class << self
|
@@ -0,0 +1 @@
|
|
1
|
+
{"errors":[{"message":"You have already favorited this status","code":139}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"errors":"sharing is not permissible for this status (Share validations failed)"}
|
@@ -53,6 +53,46 @@ describe Twitter::API do
|
|
53
53
|
expect(tweets.first).to be_a Twitter::Tweet
|
54
54
|
expect(tweets.first.text).to eq "The problem with your code is that it's doing exactly what you told it to do."
|
55
55
|
end
|
56
|
+
context "already favorited" do
|
57
|
+
before do
|
58
|
+
stub_post("/1.1/favorites/create.json").with(:body => {:id => "25938088801"}).to_return(:status => 403, :body => fixture("already_favorited.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
59
|
+
end
|
60
|
+
it "does not raises an error" do
|
61
|
+
expect{@client.favorite(25938088801)}.not_to raise_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#favorite!" do
|
67
|
+
before do
|
68
|
+
stub_post("/1.1/favorites/create.json").with(:body => {:id => "25938088801"}).to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
69
|
+
end
|
70
|
+
it "requests the correct resource" do
|
71
|
+
@client.favorite!(25938088801)
|
72
|
+
expect(a_post("/1.1/favorites/create.json").with(:body => {:id => "25938088801"})).to have_been_made
|
73
|
+
end
|
74
|
+
it "returns an array of favorited Tweets" do
|
75
|
+
tweets = @client.favorite!(25938088801)
|
76
|
+
expect(tweets).to be_an Array
|
77
|
+
expect(tweets.first).to be_a Twitter::Tweet
|
78
|
+
expect(tweets.first.text).to eq "The problem with your code is that it's doing exactly what you told it to do."
|
79
|
+
end
|
80
|
+
context "forbidden" do
|
81
|
+
before do
|
82
|
+
stub_post("/1.1/favorites/create.json").with(:body => {:id => "25938088801"}).to_return(:status => 403, :headers => {:content_type => "application/json; charset=utf-8"})
|
83
|
+
end
|
84
|
+
it "raises a Forbidden error" do
|
85
|
+
expect{@client.favorite!(25938088801)}.to raise_error(Twitter::Error::Forbidden)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
context "already favorited" do
|
89
|
+
before do
|
90
|
+
stub_post("/1.1/favorites/create.json").with(:body => {:id => "25938088801"}).to_return(:status => 403, :body => fixture("already_favorited.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
91
|
+
end
|
92
|
+
it "raises an AlreadyFavorited error" do
|
93
|
+
expect{@client.favorite!(25938088801)}.to raise_error(Twitter::Error::AlreadyFavorited, "Tweet with the ID 25938088801 has already been favorited by the authenticated user.")
|
94
|
+
end
|
95
|
+
end
|
56
96
|
end
|
57
97
|
|
58
98
|
describe "#unfavorite" do
|
@@ -159,19 +199,17 @@ describe Twitter::API do
|
|
159
199
|
|
160
200
|
describe "#retweets_of_me" do
|
161
201
|
before do
|
162
|
-
stub_get("/1.1/statuses/
|
163
|
-
stub_get("/1.1/statuses/user_timeline.json").with(:query => {:include_rts => "false", :count => "200", :max_id => "244102490646278145"}).to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
202
|
+
stub_get("/1.1/statuses/retweets_of_me.json").to_return(:body => fixture("statuses.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
164
203
|
end
|
165
204
|
it "requests the correct resource" do
|
166
205
|
@client.retweets_of_me
|
167
|
-
expect(a_get("/1.1/statuses/
|
168
|
-
expect(a_get("/1.1/statuses/user_timeline.json").with(:query => {:include_rts => "false", :count => "200", :max_id => "244102490646278145"})).to have_been_made
|
206
|
+
expect(a_get("/1.1/statuses/retweets_of_me.json")).to have_been_made
|
169
207
|
end
|
170
208
|
it "returns the 20 most recent tweets of the authenticated user that have been retweeted by others" do
|
171
209
|
tweets = @client.retweets_of_me
|
172
210
|
expect(tweets).to be_an Array
|
173
211
|
expect(tweets.first).to be_a Twitter::Tweet
|
174
|
-
expect(tweets.first.text).to eq "
|
212
|
+
expect(tweets.first.text).to eq "Happy Birthday @imdane. Watch out for those @rally pranksters!"
|
175
213
|
end
|
176
214
|
end
|
177
215
|
|
@@ -371,6 +409,48 @@ describe Twitter::API do
|
|
371
409
|
expect(tweets.first.retweeted_tweet.text).to eq "RT @gruber: As for the Series, I'm for the Giants. Fuck Texas, fuck Nolan Ryan, fuck George Bush."
|
372
410
|
expect(tweets.first.retweeted_tweet.id).not_to eq tweets.first.id
|
373
411
|
end
|
412
|
+
context "already retweeted" do
|
413
|
+
before do
|
414
|
+
stub_post("/1.1/statuses/retweet/28561922516.json").to_return(:status => 403, :body => fixture("already_retweeted.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
415
|
+
end
|
416
|
+
it "does not raise an error" do
|
417
|
+
expect{@client.retweet(28561922516)}.not_to raise_error
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
describe "#retweet!" do
|
423
|
+
before do
|
424
|
+
stub_post("/1.1/statuses/retweet/28561922516.json").to_return(:body => fixture("retweet.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
425
|
+
end
|
426
|
+
it "requests the correct resource" do
|
427
|
+
@client.retweet!(28561922516)
|
428
|
+
expect(a_post("/1.1/statuses/retweet/28561922516.json")).to have_been_made
|
429
|
+
end
|
430
|
+
it "returns an array of Tweets with retweet details embedded" do
|
431
|
+
tweets = @client.retweet!(28561922516)
|
432
|
+
expect(tweets).to be_an Array
|
433
|
+
expect(tweets.first).to be_a Twitter::Tweet
|
434
|
+
expect(tweets.first.text).to eq "As for the Series, I'm for the Giants. Fuck Texas, fuck Nolan Ryan, fuck George Bush."
|
435
|
+
expect(tweets.first.retweeted_tweet.text).to eq "RT @gruber: As for the Series, I'm for the Giants. Fuck Texas, fuck Nolan Ryan, fuck George Bush."
|
436
|
+
expect(tweets.first.retweeted_tweet.id).not_to eq tweets.first.id
|
437
|
+
end
|
438
|
+
context "fobidden" do
|
439
|
+
before do
|
440
|
+
stub_post("/1.1/statuses/retweet/28561922516.json").to_return(:status => 403, :headers => {:content_type => "application/json; charset=utf-8"})
|
441
|
+
end
|
442
|
+
it "raises a Forbidden error" do
|
443
|
+
expect{@client.retweet!(28561922516)}.to raise_error(Twitter::Error::Forbidden)
|
444
|
+
end
|
445
|
+
end
|
446
|
+
context "already retweeted" do
|
447
|
+
before do
|
448
|
+
stub_post("/1.1/statuses/retweet/28561922516.json").to_return(:status => 403, :body => fixture("already_retweeted.json"), :headers => {:content_type => "application/json; charset=utf-8"})
|
449
|
+
end
|
450
|
+
it "raises an AlreadyRetweeted error" do
|
451
|
+
expect{@client.retweet!(28561922516)}.to raise_error(Twitter::Error::AlreadyRetweeted, "Tweet with the ID 28561922516 has already been retweeted by the authenticated user.")
|
452
|
+
end
|
453
|
+
end
|
374
454
|
end
|
375
455
|
|
376
456
|
describe "#tweet" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twitter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-10-
|
15
|
+
date: 2012-10-30 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: faraday
|
@@ -248,6 +248,8 @@ files:
|
|
248
248
|
- lib/twitter/entity/url.rb
|
249
249
|
- lib/twitter/entity/user_mention.rb
|
250
250
|
- lib/twitter/entity.rb
|
251
|
+
- lib/twitter/error/already_favorited.rb
|
252
|
+
- lib/twitter/error/already_retweeted.rb
|
251
253
|
- lib/twitter/error/bad_gateway.rb
|
252
254
|
- lib/twitter/error/bad_request.rb
|
253
255
|
- lib/twitter/error/client_error.rb
|
@@ -298,6 +300,8 @@ files:
|
|
298
300
|
- spec/fixtures/about_me.json
|
299
301
|
- spec/fixtures/activity_summary.json
|
300
302
|
- spec/fixtures/all.json
|
303
|
+
- spec/fixtures/already_favorited.json
|
304
|
+
- spec/fixtures/already_retweeted.json
|
301
305
|
- spec/fixtures/bad_gateway.json
|
302
306
|
- spec/fixtures/bad_request.json
|
303
307
|
- spec/fixtures/by_friends.json
|
@@ -457,6 +461,8 @@ test_files:
|
|
457
461
|
- spec/fixtures/about_me.json
|
458
462
|
- spec/fixtures/activity_summary.json
|
459
463
|
- spec/fixtures/all.json
|
464
|
+
- spec/fixtures/already_favorited.json
|
465
|
+
- spec/fixtures/already_retweeted.json
|
460
466
|
- spec/fixtures/bad_gateway.json
|
461
467
|
- spec/fixtures/bad_request.json
|
462
468
|
- spec/fixtures/by_friends.json
|