twitter 5.8.0 → 5.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/README.md +10 -36
  4. data/lib/twitter/base.rb +20 -3
  5. data/lib/twitter/basic_user.rb +6 -4
  6. data/lib/twitter/client.rb +2 -1
  7. data/lib/twitter/configuration.rb +1 -1
  8. data/lib/twitter/cursor.rb +1 -1
  9. data/lib/twitter/entities.rb +10 -6
  10. data/lib/twitter/enumerable.rb +2 -2
  11. data/lib/twitter/error.rb +7 -0
  12. data/lib/twitter/geo_results.rb +1 -1
  13. data/lib/twitter/list.rb +3 -2
  14. data/lib/twitter/media/photo.rb +1 -1
  15. data/lib/twitter/place.rb +13 -15
  16. data/lib/twitter/profile.rb +1 -1
  17. data/lib/twitter/profile_banner.rb +1 -1
  18. data/lib/twitter/rest/client.rb +17 -2
  19. data/lib/twitter/rest/friends_and_followers.rb +1 -1
  20. data/lib/twitter/rest/lists.rb +4 -2
  21. data/lib/twitter/rest/spam_reporting.rb +1 -1
  22. data/lib/twitter/rest/tweets.rb +17 -17
  23. data/lib/twitter/rest/users.rb +77 -13
  24. data/lib/twitter/rest/utils.rb +10 -6
  25. data/lib/twitter/search_results.rb +1 -1
  26. data/lib/twitter/settings.rb +4 -3
  27. data/lib/twitter/source_user.rb +3 -2
  28. data/lib/twitter/streaming/client.rb +7 -2
  29. data/lib/twitter/streaming/connection.rb +9 -2
  30. data/lib/twitter/streaming/response.rb +3 -3
  31. data/lib/twitter/suggestion.rb +1 -1
  32. data/lib/twitter/target_user.rb +1 -1
  33. data/lib/twitter/trend.rb +2 -1
  34. data/lib/twitter/trend_results.rb +1 -1
  35. data/lib/twitter/tweet.rb +4 -4
  36. data/lib/twitter/user.rb +60 -19
  37. data/lib/twitter/utils.rb +12 -5
  38. data/lib/twitter/version.rb +1 -1
  39. data/spec/fixtures/following.json +1 -1
  40. data/spec/fixtures/sferik.json +1 -1
  41. data/spec/helper.rb +14 -5
  42. data/spec/twitter/base_spec.rb +16 -4
  43. data/spec/twitter/direct_message_spec.rb +12 -13
  44. data/spec/twitter/entity/uri_spec.rb +2 -2
  45. data/spec/twitter/error_spec.rb +2 -2
  46. data/spec/twitter/media/photo_spec.rb +4 -4
  47. data/spec/twitter/oembed_spec.rb +3 -3
  48. data/spec/twitter/place_spec.rb +1 -1
  49. data/spec/twitter/rest/client_spec.rb +54 -14
  50. data/spec/twitter/rest/friends_and_followers_spec.rb +76 -76
  51. data/spec/twitter/rest/lists_spec.rb +85 -64
  52. data/spec/twitter/rest/timelines_spec.rb +2 -2
  53. data/spec/twitter/rest/tweets_spec.rb +20 -16
  54. data/spec/twitter/rest/undocumented_spec.rb +17 -17
  55. data/spec/twitter/rest/users_spec.rb +101 -17
  56. data/spec/twitter/streaming/client_spec.rb +1 -1
  57. data/spec/twitter/streaming/connection_spec.rb +32 -0
  58. data/spec/twitter/streaming/response_spec.rb +21 -0
  59. data/spec/twitter/trend_spec.rb +1 -1
  60. data/spec/twitter/tweet_spec.rb +14 -23
  61. data/spec/twitter/user_spec.rb +120 -13
  62. data/twitter.gemspec +3 -3
  63. metadata +8 -4
@@ -21,7 +21,7 @@ module Twitter
21
21
  # @return [Twitter::TrendResults]
22
22
  def initialize(attrs = {})
23
23
  @attrs = attrs
24
- @collection = Array(@attrs[:trends]).collect do |trend|
24
+ @collection = @attrs.fetch(:trends, []).collect do |trend|
25
25
  Trend.new(trend)
26
26
  end
27
27
  end
@@ -6,10 +6,9 @@ module Twitter
6
6
  class Tweet < Twitter::Identity
7
7
  include Twitter::Creatable
8
8
  include Twitter::Entities
9
- attr_reader :favorite_count, :favorited, :filter_level,
10
- :in_reply_to_screen_name, :in_reply_to_attrs_id,
11
- :in_reply_to_status_id, :in_reply_to_user_id, :lang,
12
- :retweet_count, :retweeted, :source, :text, :truncated
9
+ attr_reader :favorite_count, :filter_level, :in_reply_to_screen_name,
10
+ :in_reply_to_attrs_id, :in_reply_to_status_id, :in_reply_to_user_id,
11
+ :lang, :retweet_count, :source, :text
13
12
  deprecate_alias :favorites_count, :favorite_count
14
13
  deprecate_alias :favoriters_count, :favorite_count
15
14
  alias_method :in_reply_to_tweet_id, :in_reply_to_status_id
@@ -23,6 +22,7 @@ module Twitter
23
22
  alias_method :retweet?, :retweeted_status?
24
23
  alias_method :retweeted_tweet?, :retweeted_status?
25
24
  object_attr_reader :User, :user, :status
25
+ predicate_attr_reader :favorited, :retweeted, :truncated
26
26
 
27
27
  # @note May be > 140 characters.
28
28
  # @return [String]
@@ -10,36 +10,73 @@ module Twitter
10
10
  include Twitter::Creatable
11
11
  include Twitter::Profile
12
12
  include Memoizable
13
- attr_reader :connections, :contributors_enabled, :default_profile,
14
- :default_profile_image, :description, :favourites_count,
15
- :follow_request_sent, :followers_count, :friends_count,
16
- :geo_enabled, :is_translator, :lang, :listed_count, :location,
17
- :name, :notifications, :profile_background_color,
13
+ attr_reader :connections, :description, :favourites_count,
14
+ :followers_count, :friends_count, :lang, :listed_count,
15
+ :location, :name, :profile_background_color,
18
16
  :profile_background_image_url,
19
- :profile_background_image_url_https, :profile_background_tile,
20
- :profile_link_color, :profile_sidebar_border_color,
21
- :profile_sidebar_fill_color, :profile_text_color,
22
- :profile_use_background_image, :protected, :statuses_count,
23
- :time_zone, :utc_offset, :verified
17
+ :profile_background_image_url_https, :profile_link_color,
18
+ :profile_sidebar_border_color, :profile_sidebar_fill_color,
19
+ :profile_text_color, :statuses_count, :time_zone, :utc_offset
24
20
  alias_method :favorites_count, :favourites_count
25
21
  remove_method :favourites_count
26
22
  alias_method :profile_background_image_uri, :profile_background_image_url
27
23
  alias_method :profile_background_image_uri_https, :profile_background_image_url_https
28
- alias_method :translator?, :is_translator
29
24
  alias_method :tweets_count, :statuses_count
30
25
  object_attr_reader :Tweet, :status, :user
31
26
  alias_method :tweet, :status
32
27
  alias_method :tweet?, :status?
33
28
  alias_method :tweeted?, :status?
29
+ predicate_attr_reader :contributors_enabled, :default_profile,
30
+ :default_profile_image, :follow_request_sent,
31
+ :geo_enabled, :muting, :needs_phone_verification,
32
+ :notifications, :protected, :profile_background_tile,
33
+ :profile_use_background_image, :suspended, :verified
34
+ define_predicate_method :translator, :is_translator
35
+ define_predicate_method :translation_enabled, :is_translation_enabled
34
36
 
35
- # @return [Array<Twitter::Entity::URI>]
36
- def description_uris
37
- Array(@attrs[:entities][:description][:urls]).collect do |entity|
38
- Entity::URI.new(entity)
37
+ class << self
38
+ private
39
+
40
+ # Dynamically define a method for entity URIs
41
+ #
42
+ # @param key1 [Symbol]
43
+ # @param key2 [Symbol]
44
+ def define_entity_uris_methods(key1, key2)
45
+ array = key1.to_s.split('_')
46
+ index = array.index('uris')
47
+ array[index] = 'urls'
48
+ url_key = array.join('_').to_sym
49
+ define_entity_uris_method(key1, key2)
50
+ alias_method(url_key, key1)
51
+ define_entity_uris_predicate_method(key1)
52
+ alias_method(:"#{url_key}?", :"#{key1}?")
53
+ end
54
+
55
+ def define_entity_uris_method(key1, key2)
56
+ define_method(key1) do ||
57
+ @attrs.fetch(:entities, {}).fetch(key2, {}).fetch(:urls, []).collect do |url|
58
+ Entity::URI.new(url)
59
+ end
60
+ end
61
+ memoize(key1)
62
+ end
63
+
64
+ def define_entity_uris_predicate_method(key1)
65
+ define_method(:"#{key1}?") do ||
66
+ send(:"#{key1}").any?
67
+ end
68
+ memoize(:"#{key1}?")
39
69
  end
40
70
  end
41
- memoize :description_uris
42
- alias_method :description_urls, :description_uris
71
+
72
+ define_entity_uris_methods :description_uris, :description
73
+ define_entity_uris_methods :website_uris, :url
74
+
75
+ # @return [Boolean]
76
+ def entities?
77
+ !@attrs[:entities].nil? && @attrs[:entities].any? { |_, hash| hash[:urls].any? }
78
+ end
79
+ memoize :entities?
43
80
 
44
81
  # @return [String] The URL to the user.
45
82
  def uri
@@ -50,12 +87,16 @@ module Twitter
50
87
 
51
88
  # @return [String] The URL to the user's website.
52
89
  def website
53
- Addressable::URI.parse(@attrs[:url]) unless @attrs[:url].nil?
90
+ if website_urls?
91
+ website_urls.first.expanded_url
92
+ elsif @attrs[:url]
93
+ Addressable::URI.parse(@attrs[:url])
94
+ end
54
95
  end
55
96
  memoize :website
56
97
 
57
98
  def website?
58
- !!@attrs[:url]
99
+ !!(website_uris? || @attrs[:url])
59
100
  end
60
101
  memoize :website?
61
102
  end
@@ -8,9 +8,13 @@ module Twitter
8
8
 
9
9
  module ClassMethods
10
10
  def deprecate_alias(new_name, old_name)
11
- define_method(new_name) do |*args, &block|
11
+ define_method(new_name) do |*args|
12
12
  warn "#{Kernel.caller.first}: [DEPRECATION] ##{new_name} is deprecated. Use ##{old_name} instead."
13
- send(old_name, *args, &block)
13
+ if block_given?
14
+ send(old_name, *args, &Proc.new)
15
+ else
16
+ send(old_name, *args)
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -20,9 +24,12 @@ module Twitter
20
24
  #
21
25
  # @param enumerable [Enumerable]
22
26
  # @return [Array, Enumerator]
23
- def flat_pmap(enumerable, &block)
24
- return to_enum(:flat_pmap, enumerable) unless block_given?
25
- pmap(enumerable, &block).flatten(1)
27
+ def flat_pmap(enumerable)
28
+ if block_given?
29
+ pmap(enumerable, &Proc.new).flatten(1)
30
+ else
31
+ to_enum(:flat_pmap, enumerable)
32
+ end
26
33
  end
27
34
  module_function :flat_pmap
28
35
 
@@ -1,7 +1,7 @@
1
1
  module Twitter
2
2
  class Version
3
3
  MAJOR = 5
4
- MINOR = 8
4
+ MINOR = 9
5
5
  PATCH = 0
6
6
  PRE = nil
7
7
 
@@ -1 +1 @@
1
- {"relationship":{"target":{"followed_by":true,"id_str":"14100886","following":false,"screen_name":"pengwynn","id":14100886},"source":{"marked_spam":false,"notifications_enabled":false,"followed_by":false,"want_retweets":true,"id_str":"7505382","blocking":false,"all_replies":false,"following":true,"screen_name":"sferik","id":7505382}}}
1
+ {"relationship":{"target":{"followed_by":true,"id_str":"14100886","following":false,"screen_name":"pengwynn","id":14100886},"source":{"marked_spam":false,"notifications_enabled":false,"muting":false,"followed_by":false,"want_retweets":true,"id_str":"7505382","blocking":false,"all_replies":false,"following":true,"screen_name":"sferik","id":7505382}}}
@@ -1 +1 @@
1
- {"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"San Francisco","description":"An ingredient in your recipe.","url":"https:\/\/github.com\/sferik","entities":{"url":{"urls":[{"url":"https:\/\/github.com\/sferik","expanded_url":null,"indices":[0,25]}]},"description":{"urls":[]}},"protected":false,"followers_count":2449,"friends_count":203,"listed_count":130,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":4306,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":8554,"lang":"en","status":{"created_at":"Tue Oct 02 23:21:06 +0000 2012","id":253273430739283969,"id_str":"253273430739283969","text":"@dakami RAM drives are the new SSDs","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":253272860473298944,"in_reply_to_status_id_str":"253272860473298944","in_reply_to_user_id":8917142,"in_reply_to_user_id_str":"8917142","in_reply_to_screen_name":"dakami","geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"dakami","name":"Dan Kaminsky","id":8917142,"id_str":"8917142","indices":[0,7]}]},"favorited":false,"retweeted":false},"contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/665875854\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/665875854\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_banner_url":"https:\/\/si0.twimg.com\/profile_banners\/7505382\/1348266581","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false}
1
+ {"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"","description":"May contain forward-looking statements.","url":"https:\/\/t.co\/L2xIBazMPf","entities":{"url":{"urls":[{"url":"https:\/\/t.co\/L2xIBazMPf","expanded_url":"https:\/\/github.com\/sferik","display_url":"github.com\/sferik","indices":[0,23]}]},"description":{"urls":[]}},"protected":false,"followers_count":4051,"friends_count":361,"listed_count":238,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":8976,"utc_offset":3600,"time_zone":"Berlin","geo_enabled":true,"verified":false,"statuses_count":13844,"lang":"en","status":{"created_at":"Wed Mar 19 00:50:35 +0000 2014","id":446086297866993665,"id_str":"446086297866993665","text":"RT @AntonWSJ: Okean Elzy, #Ukraine's biggest rock band, performed in Berlin tonight amid many \"Glory to Ukraine!\" chants http:\/\/t.co\/dkIF8X\u2026","source":"\u003ca href=\"http:\/\/itunes.apple.com\/us\/app\/twitter\/id409789998?mt=12\" rel=\"nofollow\"\u003eTwitter for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"retweeted_status":{"created_at":"Tue Mar 18 23:56:08 +0000 2014","id":446072592227909632,"id_str":"446072592227909632","text":"Okean Elzy, #Ukraine's biggest rock band, performed in Berlin tonight amid many \"Glory to Ukraine!\" chants http:\/\/t.co\/dkIF8XvFyw","source":"\u003ca href=\"http:\/\/www.apple.com\" rel=\"nofollow\"\u003eiOS\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":4,"favorite_count":2,"entities":{"hashtags":[{"text":"Ukraine","indices":[12,20]}],"symbols":[],"urls":[],"user_mentions":[],"media":[{"id":446072592047538176,"id_str":"446072592047538176","indices":[107,129],"media_url":"http:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","url":"http:\/\/t.co\/dkIF8XvFyw","display_url":"pic.twitter.com\/dkIF8XvFyw","expanded_url":"http:\/\/twitter.com\/AntonWSJ\/status\/446072592227909632\/photo\/1","type":"photo","sizes":{"medium":{"w":600,"h":450,"resize":"fit"},"large":{"w":1024,"h":768,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":340,"h":255,"resize":"fit"}}}]},"favorited":true,"retweeted":true,"possibly_sensitive":false,"lang":"en"},"retweet_count":4,"favorite_count":0,"entities":{"hashtags":[{"text":"Ukraine","indices":[26,34]}],"symbols":[],"urls":[],"user_mentions":[{"screen_name":"AntonWSJ","name":"Anton Troianovski","id":76773876,"id_str":"76773876","indices":[3,12]}],"media":[{"id":446072592047538176,"id_str":"446072592047538176","indices":[139,140],"media_url":"http:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/BjDEqLkIAAAIpE4.jpg","url":"http:\/\/t.co\/dkIF8XvFyw","display_url":"pic.twitter.com\/dkIF8XvFyw","expanded_url":"http:\/\/twitter.com\/AntonWSJ\/status\/446072592227909632\/photo\/1","type":"photo","sizes":{"medium":{"w":600,"h":450,"resize":"fit"},"large":{"w":1024,"h":768,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":340,"h":255,"resize":"fit"}}}]},"favorited":true,"retweeted":true,"possibly_sensitive":false,"lang":"en"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/378800000757402331\/d8dfba561e2e94112a737f17e7d138ca_normal.jpeg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/378800000757402331\/d8dfba561e2e94112a737f17e7d138ca_normal.jpeg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/7505382\/1385736840","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false,"suspended":false,"needs_phone_verification":false}
@@ -1,14 +1,11 @@
1
1
  require 'simplecov'
2
2
  require 'coveralls'
3
3
 
4
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
- SimpleCov::Formatter::HTMLFormatter,
6
- Coveralls::SimpleCov::Formatter
7
- ]
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
8
5
 
9
6
  SimpleCov.start do
10
7
  add_filter '/spec/'
11
- minimum_coverage(99.39)
8
+ minimum_coverage(99.15)
12
9
  end
13
10
 
14
11
  require 'twitter'
@@ -65,3 +62,15 @@ end
65
62
  def fixture(file)
66
63
  File.new(fixture_path + '/' + file)
67
64
  end
65
+
66
+ def capture_warning
67
+ begin
68
+ old_stderr = $stderr
69
+ $stderr = StringIO.new
70
+ yield
71
+ result = $stderr.string
72
+ ensure
73
+ $stderr = old_stderr
74
+ end
75
+ result
76
+ end
@@ -7,14 +7,26 @@ describe Twitter::Base do
7
7
 
8
8
  describe '#[]' do
9
9
  it 'calls methods using [] with symbol' do
10
- expect(@base[:object_id]).to be_an Integer
10
+ capture_warning do
11
+ expect(@base[:object_id]).to be_an Integer
12
+ end
11
13
  end
12
14
  it 'calls methods using [] with string' do
13
- expect(@base['object_id']).to be_an Integer
15
+ capture_warning do
16
+ expect(@base['object_id']).to be_an Integer
17
+ end
14
18
  end
15
19
  it 'returns nil for missing method' do
16
- expect(@base[:foo]).to be_nil
17
- expect(@base['foo']).to be_nil
20
+ capture_warning do
21
+ expect(@base[:foo]).to be_nil
22
+ expect(@base['foo']).to be_nil
23
+ end
24
+ end
25
+ it 'outputs a warning' do
26
+ warning = capture_warning do
27
+ @base[:object_id]
28
+ end
29
+ expect(warning).to match(/\[DEPRECATION\] #\[:object_id\] is deprecated. Use #object_id to fetch the value./)
18
30
  end
19
31
  end
20
32
 
@@ -53,27 +53,26 @@ describe Twitter::DirectMessage do
53
53
  end
54
54
 
55
55
  describe '#entities?' do
56
- it 'returns false if there are no entities set' do
57
- tweet = Twitter::DirectMessage.new(:id => 1_825_786_345)
58
- expect(tweet.entities?).to be false
59
- end
60
-
61
- it 'returns false if there are blank lists of entities set' do
62
- tweet = Twitter::DirectMessage.new(:id => 1_825_786_345, :entities => {:urls => []})
63
- expect(tweet.entities?).to be false
64
- end
65
56
  it 'returns true if there are entities set' do
66
57
  urls_array = [
67
58
  {
68
- :url => 'http://example.com/t.co',
59
+ :url => 'https://t.co/L2xIBazMPf',
69
60
  :expanded_url => 'http://example.com/expanded',
70
- :display_url => 'example.com/expandedâ¦',
61
+ :display_url => 'example.com/expanded',
71
62
  :indices => [10, 33],
72
63
  }
73
64
  ]
74
65
  tweet = Twitter::DirectMessage.new(:id => 1_825_786_345, :entities => {:urls => urls_array})
75
66
  expect(tweet.entities?).to be true
76
67
  end
68
+ it 'returns false if there are blank lists of entities set' do
69
+ tweet = Twitter::DirectMessage.new(:id => 1_825_786_345, :entities => {:urls => []})
70
+ expect(tweet.entities?).to be false
71
+ end
72
+ it 'returns false if there are no entities set' do
73
+ tweet = Twitter::DirectMessage.new(:id => 1_825_786_345)
74
+ expect(tweet.entities?).to be false
75
+ end
77
76
  end
78
77
 
79
78
  describe '#recipient' do
@@ -187,7 +186,7 @@ describe Twitter::DirectMessage do
187
186
  it 'returns an array of Entity::URIs when entities are set' do
188
187
  urls_array = [
189
188
  {
190
- :url => 'http://example.com/t.co',
189
+ :url => 'https://t.co/L2xIBazMPf',
191
190
  :expanded_url => 'http://example.com/expanded',
192
191
  :display_url => 'example.com/expanded…',
193
192
  :indices => [10, 33],
@@ -211,7 +210,7 @@ describe Twitter::DirectMessage do
211
210
  it 'can handle strange urls' do
212
211
  urls_array = [
213
212
  {
214
- :url => 'http://with_underscore.example.com/t.co',
213
+ :url => 'https://t.co/L2xIBazMPf',
215
214
  :expanded_url => 'http://with_underscore.example.com/expanded',
216
215
  :display_url => 'with_underscore.example.com/expanded…',
217
216
  :indices => [10, 33],
@@ -29,7 +29,7 @@ describe Twitter::Entity::URI do
29
29
  describe '#expanded_uri' do
30
30
  it 'returns a URI when the expanded_url is set' do
31
31
  uri = Twitter::Entity::URI.new(:expanded_url => 'https://github.com/sferik')
32
- expect(uri.expanded_uri).to be_a Addressable::URI
32
+ expect(uri.expanded_uri).to be_an Addressable::URI
33
33
  expect(uri.expanded_uri.to_s).to eq('https://github.com/sferik')
34
34
  end
35
35
  it 'returns nil when the expanded_url is not set' do
@@ -52,7 +52,7 @@ describe Twitter::Entity::URI do
52
52
  describe '#uri' do
53
53
  it 'returns a URI when the url is set' do
54
54
  uri = Twitter::Entity::URI.new(:url => 'https://github.com/sferik')
55
- expect(uri.uri).to be_a Addressable::URI
55
+ expect(uri.uri).to be_an Addressable::URI
56
56
  expect(uri.uri.to_s).to eq('https://github.com/sferik')
57
57
  end
58
58
  it 'returns nil when the url is not set' do
@@ -31,7 +31,7 @@ describe Twitter::Error do
31
31
  context "when JSON body contains #{key.inspect}" do
32
32
  before do
33
33
  body = "{\"#{key}\":\"Internal Server Error\"}" unless body.nil?
34
- stub_get('/1.1/statuses/user_timeline.json').with(:query => {:screen_name => 'sferik'}).to_return(:status => 500, :body => body)
34
+ stub_get('/1.1/statuses/user_timeline.json').with(:query => {:screen_name => 'sferik'}).to_return(:status => 500, :body => body, :headers => {:content_type => 'application/json; charset=utf-8'})
35
35
  end
36
36
  it 'raises an exception with the proper message' do
37
37
  expect { @client.user_timeline('sferik') }.to raise_error(Twitter::Error::InternalServerError)
@@ -42,7 +42,7 @@ describe Twitter::Error do
42
42
  Twitter::Error.errors.each do |status, exception|
43
43
  context "when HTTP status is #{status}" do
44
44
  before do
45
- stub_get('/1.1/statuses/user_timeline.json').with(:query => {:screen_name => 'sferik'}).to_return(:status => status, :body => '{}')
45
+ stub_get('/1.1/statuses/user_timeline.json').with(:query => {:screen_name => 'sferik'}).to_return(:status => status, :body => '{}', :headers => {:content_type => 'application/json; charset=utf-8'})
46
46
  end
47
47
  it "raises #{exception}" do
48
48
  expect { @client.user_timeline('sferik') }.to raise_error(exception)
@@ -59,7 +59,7 @@ describe Twitter::Media::Photo do
59
59
  describe '#expanded_uri' do
60
60
  it 'returns a URI when the expanded_url is set' do
61
61
  photo = Twitter::Media::Photo.new(:id => 1, :expanded_url => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
62
- expect(photo.expanded_uri).to be_a Addressable::URI
62
+ expect(photo.expanded_uri).to be_an Addressable::URI
63
63
  expect(photo.expanded_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
64
64
  end
65
65
  it 'returns nil when the expanded_url is not set' do
@@ -82,7 +82,7 @@ describe Twitter::Media::Photo do
82
82
  describe '#media_uri' do
83
83
  it 'returns a URI when the media_url is set' do
84
84
  photo = Twitter::Media::Photo.new(:id => 1, :media_url => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
85
- expect(photo.media_uri).to be_a Addressable::URI
85
+ expect(photo.media_uri).to be_an Addressable::URI
86
86
  expect(photo.media_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
87
87
  end
88
88
  it 'returns nil when the media_url is not set' do
@@ -105,7 +105,7 @@ describe Twitter::Media::Photo do
105
105
  describe '#media_uri_https' do
106
106
  it 'returns a URI when the media_url_https is set' do
107
107
  photo = Twitter::Media::Photo.new(:id => 1, :media_url_https => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
108
- expect(photo.media_uri_https).to be_a Addressable::URI
108
+ expect(photo.media_uri_https).to be_an Addressable::URI
109
109
  expect(photo.media_uri_https.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
110
110
  end
111
111
  it 'returns nil when the media_url_https is not set' do
@@ -128,7 +128,7 @@ describe Twitter::Media::Photo do
128
128
  describe '#uri' do
129
129
  it 'returns a URI when the url is set' do
130
130
  photo = Twitter::Media::Photo.new(:id => 1, :url => 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
131
- expect(photo.uri).to be_a Addressable::URI
131
+ expect(photo.uri).to be_an Addressable::URI
132
132
  expect(photo.uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png')
133
133
  end
134
134
  it 'returns nil when the url is not set' do
@@ -5,7 +5,7 @@ describe Twitter::OEmbed do
5
5
  describe '#author_uri' do
6
6
  it 'returns a URI when the author_url is set' do
7
7
  oembed = Twitter::OEmbed.new(:author_url => 'https://twitter.com/sferik')
8
- expect(oembed.author_uri).to be_a Addressable::URI
8
+ expect(oembed.author_uri).to be_an Addressable::URI
9
9
  expect(oembed.author_uri.to_s).to eq('https://twitter.com/sferik')
10
10
  end
11
11
  it 'returns nil when the author_uri is not set' do
@@ -87,7 +87,7 @@ describe Twitter::OEmbed do
87
87
  describe '#provider_uri' do
88
88
  it 'returns a URI when the provider_url is set' do
89
89
  oembed = Twitter::OEmbed.new(:provider_url => 'http://twitter.com')
90
- expect(oembed.provider_uri).to be_a Addressable::URI
90
+ expect(oembed.provider_uri).to be_an Addressable::URI
91
91
  expect(oembed.provider_uri.to_s).to eq('http://twitter.com')
92
92
  end
93
93
  it 'returns nil when the provider_uri is not set' do
@@ -136,7 +136,7 @@ describe Twitter::OEmbed do
136
136
  describe '#uri' do
137
137
  it 'returns a URI when the url is set' do
138
138
  oembed = Twitter::OEmbed.new(:url => 'https://twitter.com/twitterapi/status/133640144317198338')
139
- expect(oembed.uri).to be_a Addressable::URI
139
+ expect(oembed.uri).to be_an Addressable::URI
140
140
  expect(oembed.uri.to_s).to eq('https://twitter.com/twitterapi/status/133640144317198338')
141
141
  end
142
142
  it 'returns nil when the url is not set' do
@@ -137,7 +137,7 @@ describe Twitter::Place do
137
137
  describe '#uri' do
138
138
  it 'returns a URI when the url is set' do
139
139
  place = Twitter::Place.new(:woeid => '247f43d441defc03', :url => 'https://api.twitter.com/1.1/geo/id/247f43d441defc03.json')
140
- expect(place.uri).to be_a Addressable::URI
140
+ expect(place.uri).to be_an Addressable::URI
141
141
  expect(place.uri.to_s).to eq('https://api.twitter.com/1.1/geo/id/247f43d441defc03.json')
142
142
  end
143
143
  it 'returns nil when the url is not set' do
@@ -65,6 +65,52 @@ describe Twitter::REST::Client do
65
65
  end
66
66
  end
67
67
 
68
+ describe '#connection_options=' do
69
+ it 'sets connection options' do
70
+ capture_warning do
71
+ @client.connection_options = 'connection options'
72
+ end
73
+ expect(@client.connection_options).to eq('connection options')
74
+ end
75
+ it 'outputs a warning' do
76
+ warning = capture_warning do
77
+ @client.connection_options = nil
78
+ end
79
+ expect(warning).to match(/\[DEPRECATION\] Twitter::REST::Client#connection_options= is deprecated and will be removed in version 6\.0\.0\.$/)
80
+ end
81
+ end
82
+
83
+ describe '#connection_options' do
84
+ it 'returns the connection options hash with proxy and user_agent' do
85
+ client = Twitter::REST::Client.new do |config|
86
+ config.consumer_key = 'CK'
87
+ config.consumer_secret = 'CS'
88
+ config.access_token = 'AT'
89
+ config.access_token_secret = 'ATS'
90
+ config.proxy = 'http://localhost:99'
91
+ config.user_agent = 'My Twitter Ruby Gem'
92
+ end
93
+
94
+ expect(client.connection_options[:proxy]).to eql('http://localhost:99')
95
+ expect(client.connection_options[:headers][:user_agent]).to eql('My Twitter Ruby Gem')
96
+ end
97
+ end
98
+
99
+ describe '#middleware=' do
100
+ it 'sets middleware' do
101
+ capture_warning do
102
+ @client.middleware = 'middleware'
103
+ end
104
+ expect(@client.middleware).to eq 'middleware'
105
+ end
106
+ it 'outputs a warning' do
107
+ warning = capture_warning do
108
+ @client.middleware = nil
109
+ end
110
+ expect(warning).to match(/\[DEPRECATION\] Twitter::REST::Client#middleware= is deprecated and will be removed in version 6\.0\.0\.$/)
111
+ end
112
+ end
113
+
68
114
  describe '#credentials?' do
69
115
  it 'returns true if all credentials are present' do
70
116
  client = Twitter::REST::Client.new(:consumer_key => 'CK', :consumer_secret => 'CS', :access_token => 'AT', :access_token_secret => 'AS')
@@ -128,29 +174,23 @@ describe Twitter::REST::Client do
128
174
  end
129
175
  it 'submits the correct auth header when no media is present' do
130
176
  # We use static values for nounce and timestamp to get a stable signature
131
- secret = {:consumer_key => 'CK', :consumer_secret => 'CS',
132
- :token => 'OT', :token_secret => 'OS',
133
- :nonce => 'b6ebe4c2a11af493f8a2290fe1296965', :timestamp => '1370968658'}
134
- header = {'Authorization' => /oauth_signature="FbthwmgGq02iQw%2FuXGEWaL6V6eM%3D"/}
177
+ secret = {:consumer_key => 'CK', :consumer_secret => 'CS', :token => 'OT', :token_secret => 'OS', :nonce => 'b6ebe4c2a11af493f8a2290fe1296965', :timestamp => '1370968658'}
178
+ headers = {:authorization => /oauth_signature="FbthwmgGq02iQw%2FuXGEWaL6V6eM%3D"/, :content_type => 'application/json; charset=utf-8'}
135
179
 
136
180
  allow(@client).to receive(:credentials).and_return(secret)
137
- stub_post('/1.1/statuses/update.json').with(:body => {:status => 'Just a test'}).to_return(:body => fixture('status.json'), :headers => {:content_type => 'application/json; charset=utf-8'})
181
+ stub_post('/1.1/statuses/update.json').with(:body => {:status => 'Just a test'}).to_return(:body => fixture('status.json'), :headers => headers)
138
182
  @client.update('Just a test')
139
- expect(a_post('/1.1/statuses/update.json').
140
- with(:headers => header)).to have_been_made
183
+ expect(a_post('/1.1/statuses/update.json').with(:headers => {:authorization => headers[:authorization]})).to have_been_made
141
184
  end
142
185
  it 'submits the correct auth header when media is present' do
143
186
  # We use static values for nounce and timestamp to get a stable signature
144
- secret = {:consumer_key => 'CK', :consumer_secret => 'CS',
145
- :token => 'OT', :token_secret => 'OS',
146
- :nonce => 'e08201ad0dab4897c99445056feefd95', :timestamp => '1370967652'}
147
- header = {'Authorization' => /oauth_signature="9ziouUPwZT9IWWRbJL8r0BerKYA%3D"/}
187
+ secret = {:consumer_key => 'CK', :consumer_secret => 'CS', :token => 'OT', :token_secret => 'OS', :nonce => 'e08201ad0dab4897c99445056feefd95', :timestamp => '1370967652'}
188
+ headers = {:authorization => /oauth_signature="9ziouUPwZT9IWWRbJL8r0BerKYA%3D"/, :content_type => 'application/json; charset=utf-8'}
148
189
 
149
190
  allow(@client).to receive(:credentials).and_return(secret)
150
- stub_post('/1.1/statuses/update_with_media.json').to_return(:body => fixture('status.json'), :headers => header)
191
+ stub_post('/1.1/statuses/update_with_media.json').to_return(:body => fixture('status.json'), :headers => headers)
151
192
  @client.update_with_media('Just a test', fixture('pbjt.gif'))
152
- expect(a_post('/1.1/statuses/update_with_media.json').
153
- with(:headers => header)).to have_been_made
193
+ expect(a_post('/1.1/statuses/update_with_media.json').with(:headers => {:authorization => headers[:authorization]})).to have_been_made
154
194
  end
155
195
  end
156
196