instagram 0.11.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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