instagram 0.11.0 → 1.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.
@@ -11,7 +11,7 @@ module Instagram
11
11
  :headers => {'Accept' => "application/#{format}; charset=utf-8", 'User-Agent' => user_agent},
12
12
  :proxy => proxy,
13
13
  :url => endpoint,
14
- }
14
+ }.merge(connection_options)
15
15
 
16
16
  Faraday::Connection.new(options) do |connection|
17
17
  connection.use FaradayMiddleware::InstagramOAuth2, client_id, access_token
@@ -11,9 +11,15 @@ module Instagram
11
11
  # Raised when Instagram returns the HTTP status code 500
12
12
  class InternalServerError < Error; end
13
13
 
14
+ # Raised when Instagram returns the HTTP status code 502
15
+ class BadGateway < Error; end
16
+
14
17
  # Raised when Instagram returns the HTTP status code 503
15
18
  class ServiceUnavailable < Error; end
16
19
 
20
+ # Raised when Instagram returns the HTTP status code 504
21
+ class GatewayTimeout < Error; end
22
+
17
23
  # Raised when a subscription payload hash is invalid
18
24
  class InvalidSignature < Error; end
19
25
  end
@@ -5,6 +5,7 @@ module Instagram
5
5
  def authorize_url(options={})
6
6
  options[:response_type] ||= "code"
7
7
  options[:scope] ||= scope if !scope.nil? && !scope.empty?
8
+ options[:redirect_uri] ||= self.redirect_uri
8
9
  params = authorization_params.merge(options)
9
10
  connection.build_url("/oauth/authorize/", params).to_s
10
11
  end
@@ -12,6 +13,7 @@ module Instagram
12
13
  # Return an access token from authorization
13
14
  def get_access_token(code, options={})
14
15
  options[:grant_type] ||= "authorization_code"
16
+ options[:redirect_uri] ||= self.redirect_uri
15
17
  params = access_token_params.merge(options)
16
18
  post("/oauth/access_token/", params.merge(:code => code), raw=false, unformatted=true, no_response_wrapper=true)
17
19
  end
@@ -2,22 +2,22 @@ module Instagram
2
2
  # Defines HTTP request methods
3
3
  module Request
4
4
  # Perform an HTTP GET request
5
- def get(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
5
+ def get(path, options={}, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper)
6
6
  request(:get, path, options, raw, unformatted, no_response_wrapper)
7
7
  end
8
8
 
9
9
  # Perform an HTTP POST request
10
- def post(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
10
+ def post(path, options={}, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper)
11
11
  request(:post, path, options, raw, unformatted, no_response_wrapper)
12
12
  end
13
13
 
14
14
  # Perform an HTTP PUT request
15
- def put(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
15
+ def put(path, options={}, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper)
16
16
  request(:put, path, options, raw, unformatted, no_response_wrapper)
17
17
  end
18
18
 
19
19
  # Perform an HTTP DELETE request
20
- def delete(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
20
+ def delete(path, options={}, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper)
21
21
  request(:delete, path, options, raw, unformatted, no_response_wrapper)
22
22
  end
23
23
 
@@ -1,3 +1,3 @@
1
1
  module Instagram
2
- VERSION = '0.11.0'.freeze unless defined?(::Instagram::VERSION)
2
+ VERSION = '1.0.0'.freeze unless defined?(::Instagram::VERSION)
3
3
  end
@@ -39,4 +39,34 @@ describe Faraday::Response do
39
39
  end.to raise_error(Instagram::BadRequest, /Bad words are bad./)
40
40
  end
41
41
  end
42
+
43
+ context 'when a 502 is raised with an HTML response' do
44
+ before do
45
+ stub_get('users/self/feed.json').to_return(
46
+ :body => '<html><body><h1>502 Bad Gateway</h1> The server returned an invalid or incomplete response. </body></html>',
47
+ :status => 502
48
+ )
49
+ end
50
+
51
+ it 'should raise an Instagram::BadGateway' do
52
+ lambda do
53
+ @client.user_media_feed()
54
+ end.should raise_error(Instagram::BadGateway)
55
+ end
56
+ end
57
+
58
+ context 'when a 504 is raised with an HTML response' do
59
+ before do
60
+ stub_get('users/self/feed.json').to_return(
61
+ :body => '<html> <head><title>504 Gateway Time-out</title></head> <body bgcolor="white"> <center><h1>504 Gateway Time-out</h1></center> <hr><center>nginx</center> </body> </html>',
62
+ :status => 504
63
+ )
64
+ end
65
+
66
+ it 'should raise an Instagram::GatewayTimeout' do
67
+ lambda do
68
+ @client.user_media_feed()
69
+ end.should raise_error(Instagram::GatewayTimeout)
70
+ end
71
+ end
42
72
  end
@@ -30,15 +30,18 @@ describe Instagram::API do
30
30
 
31
31
  before do
32
32
  @configuration = {
33
- :client_id => 'CID',
34
- :client_secret => 'CS',
35
- :scope => 'comments relationships',
36
33
  :access_token => 'AT',
37
34
  :adapter => :typhoeus,
35
+ :client_id => 'CID',
36
+ :client_secret => 'CS',
37
+ :connection_options => { :ssl => { :verify => true } },
38
+ :redirect_uri => 'http://http://localhost:4567/oauth/callback',
38
39
  :endpoint => 'http://tumblr.com/',
39
40
  :format => :xml,
40
41
  :proxy => 'http://shayne:sekret@proxy.example.com:8080',
42
+ :scope => 'comments relationships',
41
43
  :user_agent => 'Custom User Agent',
44
+ :no_response_wrapper => true,
42
45
  }
43
46
  end
44
47
 
@@ -53,16 +56,42 @@ describe Instagram::API do
53
56
 
54
57
  context "after initilization" do
55
58
 
56
- it "should override module configuration after initialization" do
57
- api = Instagram::API.new
59
+ let(:api) { Instagram::API.new }
60
+
61
+ before do
58
62
  @configuration.each do |key, value|
59
63
  api.send("#{key}=", value)
60
64
  end
65
+ end
66
+
67
+ it "should override module configuration after initialization" do
61
68
  @keys.each do |key|
62
69
  api.send(key).should == @configuration[key]
63
70
  end
64
71
  end
72
+
73
+ describe "#connection" do
74
+ it "should use the connection_options" do
75
+ Faraday::Connection.should_receive(:new).with(include(:ssl => { :verify => true }))
76
+ api.send(:connection)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ describe '#config' do
84
+ subject { Instagram::API.new }
85
+
86
+ let(:config) do
87
+ c = {}; @keys.each {|key| c[key] = key }; c
88
+ end
89
+
90
+ it "returns a hash representing the configuration" do
91
+ @keys.each do |key|
92
+ subject.send("#{key}=", key)
65
93
  end
94
+ subject.config.should == config
66
95
  end
67
96
  end
68
97
 
@@ -112,29 +141,76 @@ describe Instagram::API do
112
141
  url.should_not include("scope")
113
142
  end
114
143
  end
144
+
145
+ describe "redirect_uri" do
146
+ it "should fall back to configuration redirect_uri if not passed as option" do
147
+ redirect_uri = 'http://localhost:4567/oauth/callback'
148
+ params = { :redirect_uri => redirect_uri }
149
+ client = Instagram::Client.new(params)
150
+ url = client.authorize_url()
151
+ url.should =~ /redirect_uri=#{URI.escape(redirect_uri, Regexp.union('/',':'))}/
152
+ end
153
+
154
+ it "should override configuration redirect_uri if passed as option" do
155
+ redirect_uri_config = 'http://localhost:4567/oauth/callback_config'
156
+ params = { :redirect_uri => redirect_uri_config }
157
+ client = Instagram::Client.new(params)
158
+ redirect_uri_option = 'http://localhost:4567/oauth/callback_option'
159
+ options = { :redirect_uri => redirect_uri_option }
160
+ url = client.authorize_url(options)
161
+ url.should =~ /redirect_uri=#{URI.escape(redirect_uri_option, Regexp.union('/',':'))}/
162
+ end
163
+ end
115
164
  end
116
165
 
117
166
  describe ".get_access_token" do
118
167
 
119
- before do
120
- @client = Instagram::Client.new(:client_id => "CID", :client_secret => "CS")
121
- @url = @client.send(:connection).build_url("/oauth/access_token/").to_s
122
- stub_request(:post, @url).
123
- with(:body => {:client_id => "CID", :client_secret => "CS", :redirect_uri => "http://localhost:4567/oauth/callback", :grant_type => "authorization_code", :code => "C"}).
124
- to_return(:status => 200, :body => fixture("access_token.json"), :headers => {})
125
- end
168
+ describe "common functionality" do
169
+ before do
170
+ @client = Instagram::Client.new(:client_id => "CID", :client_secret => "CS")
171
+ @url = @client.send(:connection).build_url("/oauth/access_token/").to_s
172
+ stub_request(:post, @url).
173
+ with(:body => {:client_id => "CID", :client_secret => "CS", :redirect_uri => "http://localhost:4567/oauth/callback", :grant_type => "authorization_code", :code => "C"}).
174
+ to_return(:status => 200, :body => fixture("access_token.json"), :headers => {})
175
+ end
176
+
177
+ it "should get the correct resource" do
178
+ @client.get_access_token(code="C", :redirect_uri => "http://localhost:4567/oauth/callback")
179
+ a_request(:post, @url).
180
+ with(:body => {:client_id => "CID", :client_secret => "CS", :redirect_uri => "http://localhost:4567/oauth/callback", :grant_type => "authorization_code", :code => "C"}).
181
+ should have_been_made
182
+ end
126
183
 
127
- it "should get the correct resource" do
128
- @client.get_access_token(code="C", :redirect_uri => "http://localhost:4567/oauth/callback")
129
- a_request(:post, @url).
130
- with(:body => {:client_id => "CID", :client_secret => "CS", :redirect_uri => "http://localhost:4567/oauth/callback", :grant_type => "authorization_code", :code => "C"}).
131
- should have_been_made
184
+ it "should return a hash with an access_token and user data" do
185
+ response = @client.get_access_token(code="C", :redirect_uri => "http://localhost:4567/oauth/callback")
186
+ response.access_token.should == "at"
187
+ response.user.username.should == "mikeyk"
188
+ end
132
189
  end
133
190
 
134
- it "should return a hash with an access_token and user data" do
135
- response = @client.get_access_token(code="C", :redirect_uri => "http://localhost:4567/oauth/callback")
136
- response.access_token.should == "at"
137
- response.user.username.should == "mikeyk"
191
+ describe "redirect_uri param" do
192
+
193
+ before do
194
+ @redirect_uri_config = "http://localhost:4567/oauth/callback_config"
195
+ @client = Instagram::Client.new(:client_id => "CID", :client_secret => "CS", :redirect_uri => @redirect_uri_config)
196
+ @url = @client.send(:connection).build_url("/oauth/access_token/").to_s
197
+ stub_request(:post, @url)
198
+ end
199
+
200
+ it "should fall back to configuration redirect_uri if not passed as option" do
201
+ @client.get_access_token(code="C")
202
+ a_request(:post, @url).
203
+ with(:body => hash_including({:redirect_uri => @redirect_uri_config})).
204
+ should have_been_made
205
+ end
206
+
207
+ it "should override configuration redirect_uri if passed as option" do
208
+ redirect_uri_option = "http://localhost:4567/oauth/callback_option"
209
+ @client.get_access_token(code="C", :redirect_uri => redirect_uri_option)
210
+ a_request(:post, @url).
211
+ with(:body => hash_including({:redirect_uri => redirect_uri_option})).
212
+ should have_been_made
213
+ end
138
214
  end
139
215
  end
140
216
  end
@@ -74,6 +74,30 @@ describe Instagram::Client do
74
74
  end
75
75
  end
76
76
 
77
+ describe ".location_search_lat_lng_distance" do
78
+
79
+ before do
80
+ stub_get("locations/search.#{format}").
81
+ with(:query => {:access_token => @client.access_token}).
82
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632", :distance => "5000"}).
83
+ to_return(:body => fixture("location_search.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8"})
84
+ end
85
+
86
+ it "should get the correct resource by lat/lng/distance" do
87
+ @client.location_search("37.7808851", "-122.3948632", "5000")
88
+ a_get("locations/search.#{format}").
89
+ with(:query => {:access_token => @client.access_token}).
90
+ with(:query => {:lat => "37.7808851", :lng => "-122.3948632", :distance => "5000"}).
91
+ should have_been_made
92
+ end
93
+
94
+ it "should return an array of user search results" do
95
+ locations = @client.location_search("37.7808851", "-122.3948632", "5000")
96
+ locations.should be_a Array
97
+ locations.first.name.should == "Instagram"
98
+ end
99
+ end
100
+
77
101
  describe ".location_search_foursquare_v2_id" do
78
102
 
79
103
  before do
@@ -136,11 +136,14 @@ describe Instagram::Client do
136
136
  end
137
137
 
138
138
  it "should raise an Instagram::InvalidSignature error" do
139
- lambda do
140
- @client.process_subscription(@json, :signature => "31337H4X0R") do |handler|
141
- # hi
142
- end
143
- end.should raise_error(Instagram::InvalidSignature)
139
+ invalid_signatures = ["31337H4X0R", nil]
140
+ invalid_signatures.each do |signature|
141
+ lambda do
142
+ @client.process_subscription(@json, :signature => signature ) do |handler|
143
+ # hi
144
+ end
145
+ end.should raise_error(Instagram::InvalidSignature)
146
+ end
144
147
  end
145
148
  end
146
149
  end
@@ -48,6 +48,7 @@ describe Instagram::Client do
48
48
  media.should be_a Array
49
49
  media.first.user.username.should == "amandavan"
50
50
  end
51
+
51
52
  end
52
53
 
53
54
  describe ".tag_search" do
@@ -5,7 +5,7 @@ describe Instagram::Client do
5
5
  client = Instagram::Client.new
6
6
  endpoint = URI.parse(client.endpoint)
7
7
  connection = client.send(:connection).build_url(nil).to_s
8
- (connection + '/').should == endpoint.to_s
8
+ (connection).should == endpoint.to_s
9
9
  end
10
10
 
11
11
  it "should not cache the user account across clients" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instagram
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shayne Sweeney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-13 00:00:00.000000000 Z
11
+ date: 2014-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -61,7 +61,7 @@ dependencies:
61
61
  version: '0.7'
62
62
  - - <
63
63
  - !ruby/object:Gem::Version
64
- version: '0.9'
64
+ version: '0.10'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,21 +71,27 @@ dependencies:
71
71
  version: '0.7'
72
72
  - - <
73
73
  - !ruby/object:Gem::Version
74
- version: '0.9'
74
+ version: '0.10'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: faraday_middleware
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ~>
79
+ - - ! '>='
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0.8'
82
+ - - <
83
+ - !ruby/object:Gem::Version
84
+ version: '0.10'
82
85
  type: :runtime
83
86
  prerelease: false
84
87
  version_requirements: !ruby/object:Gem::Requirement
85
88
  requirements:
86
- - - ~>
89
+ - - ! '>='
87
90
  - !ruby/object:Gem::Version
88
91
  version: '0.8'
92
+ - - <
93
+ - !ruby/object:Gem::Version
94
+ version: '0.10'
89
95
  - !ruby/object:Gem::Dependency
90
96
  name: multi_json
91
97
  requirement: !ruby/object:Gem::Requirement
@@ -132,6 +138,7 @@ files:
132
138
  - .yardopts
133
139
  - Gemfile
134
140
  - LICENSE.md
141
+ - PATENTS.md
135
142
  - README.md
136
143
  - Rakefile
137
144
  - instagram.gemspec
@@ -213,9 +220,16 @@ files:
213
220
  homepage: https://github.com/Instagram/instagram-ruby-gem
214
221
  licenses: []
215
222
  metadata: {}
216
- post_install_message: ! "********************************************************************************\n\n
217
- \ Follow @instagramapi on Twitter for announcements, updates, and news.\n https://twitter.com/instagramapi\n\n
218
- \ Join the mailing list!\n https://groups.google.com/group/instagram-ruby-gem\n\n********************************************************************************\n"
223
+ post_install_message: ! "********************************************************************************\n\nInstagram
224
+ REST and Search APIs\n------------------------------\nOur developer site documents
225
+ all the Instagram REST and Search APIs.\n(http://instagram.com/developer)\n\nBlog\n----------------------------\nThe
226
+ Developer Blog features news and important announcements about the Instagram Platform.
227
+ \nYou will also find tutorials and best practices to help you build great platform
228
+ integrations.\nMake sure to subscribe to the RSS feed so you don't miss out on new
229
+ posts: \n(http://developers.instagram.com).\n\nCommunity\n----------------------\nThe
230
+ Stack Overflow community is a great place to ask API related questions or if you
231
+ need help with your code.\nMake sure to tag your questions with the Instagram tag
232
+ to get fast answers from other fellow developers and members of the Instagram team.\n(http://stackoverflow.com/questions/tagged/instagram/)\n\n********************************************************************************\n"
219
233
  rdoc_options: []
220
234
  require_paths:
221
235
  - lib