koala 0.10.0 → 1.0.0.beta2.1

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 (34) hide show
  1. data/CHANGELOG +34 -7
  2. data/Manifest +8 -1
  3. data/Rakefile +4 -4
  4. data/koala.gemspec +10 -8
  5. data/lib/koala/graph_api.rb +188 -123
  6. data/lib/koala/http_services.rb +92 -22
  7. data/lib/koala/rest_api.rb +73 -6
  8. data/lib/koala/test_users.rb +18 -5
  9. data/lib/koala/uploadable_io.rb +115 -0
  10. data/lib/koala.rb +81 -72
  11. data/readme.md +18 -12
  12. data/spec/facebook_data.yml +18 -14
  13. data/spec/koala/assets/beach.jpg +0 -0
  14. data/spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb +5 -1
  15. data/spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb +8 -3
  16. data/spec/koala/graph_api/graph_api_no_access_token_tests.rb +13 -62
  17. data/spec/koala/graph_api/graph_api_tests.rb +85 -0
  18. data/spec/koala/graph_api/graph_api_with_access_token_tests.rb +167 -123
  19. data/spec/koala/http_services/http_service_tests.rb +51 -0
  20. data/spec/koala/http_services/net_http_service_tests.rb +339 -0
  21. data/spec/koala/http_services/typhoeus_service_tests.rb +162 -0
  22. data/spec/koala/live_testing_data_helper.rb +1 -1
  23. data/spec/koala/oauth/oauth_tests.rb +19 -85
  24. data/spec/koala/rest_api/rest_api_no_access_token_tests.rb +5 -74
  25. data/spec/koala/rest_api/rest_api_tests.rb +118 -0
  26. data/spec/koala/rest_api/rest_api_with_access_token_tests.rb +5 -3
  27. data/spec/koala/test_users/test_users_tests.rb +49 -48
  28. data/spec/koala/uploadable_io/uploadable_io_tests.rb +246 -0
  29. data/spec/koala_spec_helper.rb +32 -6
  30. data/spec/koala_spec_without_mocks.rb +3 -3
  31. data/spec/mock_facebook_responses.yml +43 -20
  32. data/spec/mock_http_service.rb +16 -3
  33. metadata +39 -8
  34. data/spec/koala/net_http_service_tests.rb +0 -186
data/lib/koala.rb CHANGED
@@ -5,8 +5,9 @@ require 'digest/md5'
5
5
  require 'rubygems'
6
6
  require 'json'
7
7
 
8
- # openssl is required to support signed_request
8
+ # OpenSSL and Base64 are required to support signed_request
9
9
  require 'openssl'
10
+ require 'base64'
10
11
 
11
12
  # include default http services
12
13
  require 'koala/http_services'
@@ -23,8 +24,11 @@ require 'koala/realtime_updates'
23
24
  # add test user methods
24
25
  require 'koala/test_users'
25
26
 
27
+ # add KoalaIO class
28
+ require 'koala/uploadable_io'
29
+
26
30
  module Koala
27
-
31
+
28
32
  module Facebook
29
33
  # Ruby client library for the Facebook Platform.
30
34
  # Copyright 2010 Facebook
@@ -40,7 +44,7 @@ module Koala
40
44
  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
41
45
  # License for the specific language governing permissions and limitations
42
46
  # under the License.
43
- #
47
+ #
44
48
  # This client library is designed to support the Graph API and the official
45
49
  # Facebook JavaScript SDK, which is the canonical way to implement
46
50
  # Facebook authentication. Read more about the Graph API at
@@ -53,7 +57,7 @@ module Koala
53
57
  @access_token = access_token
54
58
  end
55
59
  attr_reader :access_token
56
-
60
+
57
61
  def api(path, args = {}, verb = "get", options = {}, &error_checking_block)
58
62
  # Fetches the given path in the Graph API.
59
63
  args["access_token"] = @access_token || @app_access_token if @access_token || @app_access_token
@@ -63,20 +67,20 @@ module Koala
63
67
 
64
68
  # make the request via the provided service
65
69
  result = Koala.make_request(path, args, verb, options)
66
-
70
+
67
71
  # Check for any 500 errors before parsing the body
68
72
  # since we're not guaranteed that the body is valid JSON
69
73
  # in the case of a server error
70
74
  raise APIError.new({"type" => "HTTP #{result.status.to_s}", "message" => "Response body: #{result.body}"}) if result.status >= 500
71
-
72
- # Parse the body as JSON and check for errors if provided a mechanism to do so
75
+
76
+ # Parse the body as JSON and check for errors if provided a mechanism to do so
73
77
  # Note: Facebook sometimes sends results like "true" and "false", which aren't strictly objects
74
78
  # and cause JSON.parse to fail -- so we account for that by wrapping the result in []
75
79
  body = response = JSON.parse("[#{result.body.to_s}]")[0]
76
80
  if error_checking_block
77
81
  yield(body)
78
82
  end
79
-
83
+
80
84
  # now return the desired information
81
85
  if options[:http_component]
82
86
  result.send(options[:http_component])
@@ -85,57 +89,57 @@ module Koala
85
89
  end
86
90
  end
87
91
  end
88
-
92
+
89
93
  class GraphAPI < API
90
94
  include GraphAPIMethods
91
95
  end
92
-
96
+
93
97
  class RestAPI < API
94
98
  include RestAPIMethods
95
99
  end
96
-
100
+
97
101
  class GraphAndRestAPI < API
98
102
  include GraphAPIMethods
99
103
  include RestAPIMethods
100
104
  end
101
-
105
+
102
106
  class RealtimeUpdates < API
103
107
  include RealtimeUpdateMethods
104
108
  end
105
-
109
+
106
110
  class TestUsers < API
107
111
  include TestUserMethods
108
112
  # make the Graph API accessible in case someone wants to make other calls to interact with their users
109
113
  attr_reader :graph_api
110
114
  end
111
-
112
- class APIError < Exception
115
+
116
+ class APIError < StandardError
113
117
  attr_accessor :fb_error_type
114
118
  def initialize(details = {})
115
- self.fb_error_type = details["type"]
119
+ self.fb_error_type = details["type"]
116
120
  super("#{fb_error_type}: #{details["message"]}")
117
121
  end
118
122
  end
119
-
120
-
123
+
124
+
121
125
  class OAuth
122
126
  attr_reader :app_id, :app_secret, :oauth_callback_url
123
127
  def initialize(app_id, app_secret, oauth_callback_url = nil)
124
128
  @app_id = app_id
125
129
  @app_secret = app_secret
126
- @oauth_callback_url = oauth_callback_url
130
+ @oauth_callback_url = oauth_callback_url
127
131
  end
128
132
 
129
133
  def get_user_info_from_cookie(cookie_hash)
130
134
  # Parses the cookie set by the official Facebook JavaScript SDK.
131
- #
135
+ #
132
136
  # cookies should be a Hash, like the one Rails provides
133
- #
137
+ #
134
138
  # If the user is logged in via Facebook, we return a dictionary with the
135
139
  # keys "uid" and "access_token". The former is the user's Facebook ID,
136
140
  # and the latter can be used to make authenticated requests to the Graph API.
137
141
  # If the user is not logged in, we return None.
138
- #
142
+ #
139
143
  # Download the official Facebook JavaScript SDK at
140
144
  # http://github.com/facebook/connect-js/. Read more about Facebook
141
145
  # authentication at http://developers.facebook.com/docs/authentication/.
@@ -150,21 +154,21 @@ module Koala
150
154
 
151
155
  # generate the signature and make sure it matches what we expect
152
156
  auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
153
- sig = Digest::MD5.hexdigest(auth_string + @app_secret)
157
+ sig = Digest::MD5.hexdigest(auth_string + @app_secret)
154
158
  sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
155
159
  end
156
160
  end
157
161
  alias_method :get_user_info_from_cookies, :get_user_info_from_cookie
158
-
162
+
159
163
  def get_user_from_cookie(cookies)
160
164
  if info = get_user_info_from_cookies(cookies)
161
165
  string = info["uid"]
162
166
  end
163
167
  end
164
168
  alias_method :get_user_from_cookies, :get_user_from_cookie
165
-
169
+
166
170
  # URLs
167
-
171
+
168
172
  def url_for_oauth_code(options = {})
169
173
  # for permissions, see http://developers.facebook.com/docs/authentication/permissions
170
174
  permissions = options[:permissions]
@@ -174,54 +178,57 @@ module Koala
174
178
  raise ArgumentError, "url_for_oauth_code must get a callback either from the OAuth object or in the options!" unless callback
175
179
 
176
180
  # Creates the URL for oauth authorization for a given callback and optional set of permissions
177
- "https://#{GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}#{scope}"
181
+ "https://#{GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}#{scope}"
178
182
  end
179
-
183
+
180
184
  def url_for_access_token(code, options = {})
181
185
  # Creates the URL for the token corresponding to a given code generated by Facebook
182
186
  callback = options[:callback] || @oauth_callback_url
183
187
  raise ArgumentError, "url_for_access_token must get a callback either from the OAuth object or in the parameters!" unless callback
184
188
  "https://#{GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@app_secret}&code=#{code}"
185
189
  end
186
-
190
+
187
191
  def get_access_token_info(code)
188
192
  # convenience method to get a parsed token from Facebook for a given code
189
193
  # should this require an OAuth callback URL?
190
194
  get_token_from_server(:code => code, :redirect_uri => @oauth_callback_url)
191
195
  end
192
-
196
+
193
197
  def get_access_token(code)
194
198
  # upstream methods will throw errors if needed
195
- if info = get_access_token_info(code)
196
- string = info["access_token"]
199
+ if info = get_access_token_info(code)
200
+ string = info["access_token"]
197
201
  end
198
202
  end
199
-
203
+
200
204
  def get_app_access_token_info
201
- # convenience method to get a the application's sessionless access token
205
+ # convenience method to get a the application's sessionless access token
202
206
  get_token_from_server({:type => 'client_cred'}, true)
203
207
  end
204
-
208
+
205
209
  def get_app_access_token
206
210
  if info = get_app_access_token_info
207
- string = info["access_token"]
211
+ string = info["access_token"]
208
212
  end
209
213
  end
210
-
211
- # signed_request
212
- def parse_signed_request(request)
213
- # Facebook's signed requests come in two parts -- the signature and the data payload
214
- # see http://developers.facebook.com/docs/authentication/canvas
215
- encoded_sig, payload = request.split(".")
216
-
217
- sig = base64_url_decode(encoded_sig)
218
-
219
- # if the signature matches, return the data, decoded and parsed as JSON
220
- if OpenSSL::HMAC.digest("sha256", @app_secret, payload) == sig
221
- JSON.parse(base64_url_decode(payload))
222
- else
223
- nil
224
- end
214
+
215
+ # Originally provided directly by Facebook, however this has changed
216
+ # as their concept of crypto changed. For historic purposes, this is their proposal:
217
+ # https://developers.facebook.com/docs/authentication/canvas/encryption_proposal/
218
+ # Currently see https://github.com/facebook/php-sdk/blob/master/src/facebook.php#L758
219
+ # for a more accurate reference implementation strategy.
220
+ def parse_signed_request(input)
221
+ encoded_sig, encoded_envelope = input.split('.', 2)
222
+ signature = base64_url_decode(encoded_sig).unpack("H*").first
223
+ envelope = JSON.parse(base64_url_decode(encoded_envelope))
224
+
225
+ raise "SignedRequest: Unsupported algorithm #{envelope['algorithm']}" if envelope['algorithm'] != 'HMAC-SHA256'
226
+
227
+ # now see if the signature is valid (digest, key, data)
228
+ hmac = OpenSSL::HMAC.hexdigest('sha256', @app_secret, encoded_envelope.tr("-_", "+/"))
229
+ raise 'SignedRequest: Invalid signature' if (signature != hmac)
230
+
231
+ return envelope
225
232
  end
226
233
 
227
234
  # from session keys
@@ -231,69 +238,70 @@ module Koala
231
238
  :type => 'client_cred',
232
239
  :sessions => sessions.join(",")
233
240
  }, true, "exchange_sessions")
234
-
241
+
235
242
  # Facebook returns an empty body in certain error conditions
236
- if response == ""
243
+ if response == ""
237
244
  raise APIError.new({
238
- "type" => "ArgumentError",
245
+ "type" => "ArgumentError",
239
246
  "message" => "get_token_from_session_key received an error (empty response body) for sessions #{sessions.inspect}!"
240
247
  })
241
248
  end
242
-
249
+
243
250
  JSON.parse(response)
244
251
  end
245
-
252
+
246
253
  def get_tokens_from_session_keys(sessions)
247
254
  # get the original hash results
248
255
  results = get_token_info_from_session_keys(sessions)
249
256
  # now recollect them as just the access tokens
250
257
  results.collect { |r| r ? r["access_token"] : nil }
251
258
  end
252
-
259
+
253
260
  def get_token_from_session_key(session)
254
261
  # convenience method for a single key
255
262
  # gets the overlaoded strings automatically
256
263
  get_tokens_from_session_keys([session])[0]
257
264
  end
258
-
265
+
259
266
  protected
260
-
267
+
261
268
  def get_token_from_server(args, post = false)
262
269
  # fetch the result from Facebook's servers
263
270
  result = fetch_token_string(args, post)
264
-
271
+
265
272
  # if we have an error, parse the error JSON and raise an error
266
273
  raise APIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/
267
274
 
268
275
  # otherwise, parse the access token
269
- parse_access_token(result)
276
+ parse_access_token(result)
270
277
  end
271
-
278
+
272
279
  def parse_access_token(response_text)
273
280
  components = response_text.split("&").inject({}) do |hash, bit|
274
281
  key, value = bit.split("=")
275
282
  hash.merge!(key => value)
276
283
  end
277
- components
284
+ components
278
285
  end
279
286
 
280
287
  def fetch_token_string(args, post = false, endpoint = "access_token")
281
288
  Koala.make_request("/oauth/#{endpoint}", {
282
- :client_id => @app_id,
289
+ :client_id => @app_id,
283
290
  :client_secret => @app_secret
284
- }.merge!(args), post ? "post" : "get").body
291
+ }.merge!(args), post ? "post" : "get", :use_ssl => true).body
285
292
  end
286
-
293
+
287
294
  # base 64
288
- def base64_url_decode(string)
289
- # to properly decode what Facebook provides, we need to add == to the end
290
- # and translate certain characters to others before running the actual decoding
291
- # see http://developers.facebook.com/docs/authentication/canvas
292
- "#{string}==".tr("-_", "+/").unpack("m")[0]
295
+ # directly from https://github.com/facebook/crypto-request-examples/raw/master/sample.rb
296
+ def base64_url_decode(str)
297
+ str += '=' * (4 - str.length.modulo(4))
298
+ Base64.decode64(str.tr('-_', '+/'))
293
299
  end
294
300
  end
295
301
  end
296
302
 
303
+ class KoalaError< StandardError; end
304
+
297
305
  # finally, set up the http service Koala methods used to make requests
298
306
  # you can use your own (for HTTParty, etc.) by calling Koala.http_service = YourModule
299
307
  def self.http_service=(service)
@@ -301,8 +309,9 @@ module Koala
301
309
  end
302
310
 
303
311
  # by default, try requiring Typhoeus -- if that works, use it
312
+ # if you have Typheous and don't want to use it (or want another service),
313
+ # you can run Koala.http_service = NetHTTPService (or MyHTTPService)
304
314
  begin
305
- require 'typhoeus'
306
315
  Koala.http_service = TyphoeusService
307
316
  rescue LoadError
308
317
  Koala.http_service = NetHTTPService
data/readme.md CHANGED
@@ -1,28 +1,34 @@
1
1
  Koala
2
2
  ====
3
- Koala (<a href="http://github.com/arsduo/koala" target="_blank">http://github.com/arsduo/koala</a>) is a new Facebook library for Ruby, supporting the Graph API, the old REST API, realtime updates, and OAuth validation. We wrote Koala with four goals:
3
+ Koala (<a href="http://github.com/arsduo/koala" target="_blank">http://github.com/arsduo/koala</a>) is a new Facebook library for Ruby, supporting the Graph API (including photo uploads), the old REST API, realtime updates, and OAuth validation. We wrote Koala with four goals:
4
4
 
5
- * Lightweight: Koala should be as light and simple as Facebook’s own new libraries, providing API accessors and returning simple JSON. (We clock in, with comments, just over 500 lines of code.)
5
+ * Lightweight: Koala should be as light and simple as Facebook’s own new libraries, providing API accessors and returning simple JSON. (We clock in, with comments, just over 750 lines of code.)
6
6
  * Fast: Koala should, out of the box, be quick. In addition to supporting the vanilla Ruby networking libraries, it natively supports Typhoeus, our preferred gem for making fast HTTP requests. Of course, That brings us to our next topic:
7
7
  * Flexible: Koala should be useful to everyone, regardless of their current configuration. (We have no dependencies beyond the JSON gem. Koala also has a built-in mechanism for using whichever HTTP library you prefer to make requests against the graph.)
8
8
  * Tested: Koala should have complete test coverage, so you can rely on it. (Our complete test coverage can be run against either mocked responses or the live Facebook servers.)
9
9
 
10
+ 1.0 beta
11
+ ---
12
+ Version 1.0 is currently in beta, chock-full of great new features. To download the beta, just add --pre when installing the gem:
13
+
14
+ sudo gem install koala --pre
15
+
10
16
  Graph API
11
17
  ----
12
- The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
18
+ The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
13
19
 
14
20
  graph = Koala::Facebook::GraphAPI.new(oauth_access_token)
15
21
  profile = graph.get_object("me")
16
22
  friends = graph.get_connections("me", "friends")
17
23
  graph.put_object("me", "feed", :message => "I am writing on my wall!")
18
24
 
19
- The response of most requests is the JSON data returned from the Facebook servers as a Hash.
25
+ The response of most requests is the JSON data returned from the Facebook servers as a Hash.
20
26
 
21
27
  When retrieving data that returns an array of results (for example, when calling GraphAPI#get_connections or GraphAPI#search) a GraphCollection object (a sub-class of Array) will be returned, which contains added methods for getting the next and previous page of results:
22
-
28
+
23
29
  # Returns the feed items for the currently logged-in user as a GraphCollection
24
30
  feed = graph.get_connections("me", "feed")
25
-
31
+
26
32
  # GraphCollection is a sub-class of Array, so you can use it as a usual Array
27
33
  first_entry = feed[0]
28
34
  last_entry = feed.last
@@ -33,7 +39,7 @@ When retrieving data that returns an array of results (for example, when calling
33
39
  # Returns an array describing the URL for the next page: [path, arguments]
34
40
  # This is useful for paging across multiple requests
35
41
  next_path, next_args = feed.next_page_params
36
-
42
+
37
43
  # You can use those params to easily get the next (or prevous) page
38
44
  page = graph.get_page(feed.next_page_params)
39
45
 
@@ -41,15 +47,15 @@ Check out the wiki for more examples.
41
47
 
42
48
  The old-school REST API
43
49
  -----
44
- Where the Graph API and the old REST API overlap, you should choose the Graph API. Unfortunately, that overlap is far from complete, and there are many important API calls that can't yet be done via the Graph.
50
+ Where the Graph API and the old REST API overlap, you should choose the Graph API. Unfortunately, that overlap is far from complete, and there are many important API calls that can't yet be done via the Graph.
45
51
 
46
52
  Koala now supports the old-school REST API using OAuth access tokens; to use this, instantiate your class using the RestAPI class:
47
53
 
48
54
  @rest = Koala::Facebook::RestAPI.new(oauth_access_token)
49
55
  @rest.fql_query(my_fql_query) # convenience method
50
56
  @rest.rest_call("stream.publish", arguments_hash) # generic version
51
-
52
- We reserve the right to expand the built-in REST API coverage to additional convenience methods in the future, depending on how fast Facebook moves to fill in the gaps.
57
+
58
+ We reserve the right to expand the built-in REST API coverage to additional convenience methods in the future, depending on how fast Facebook moves to fill in the gaps.
53
59
 
54
60
  (If you want the power of both APIs in the palm of your hand, try out the GraphAndRestAPI class.)
55
61
 
@@ -119,7 +125,7 @@ Some resources to help you as you play with Koala and the Graph API:
119
125
  Testing
120
126
  -----
121
127
 
122
- Unit tests are provided for all of Koala's methods. By default, these tests run against mock responses and hence are ready out of the box:
128
+ Unit tests are provided for all of Koala's methods. By default, these tests run against mock responses and hence are ready out of the box:
123
129
  # From the spec directory
124
130
  spec koala_spec.rb
125
131
 
@@ -127,4 +133,4 @@ You can also run live tests against Facebook's servers:
127
133
  # Again from the spec directory
128
134
  spec koala_spec_without_mocks.rb
129
135
 
130
- Important Note: to run the live tests, you have to provide some of your own data: a valid OAuth access token with publish\_stream and read\_stream permissions and an OAuth code that can be used to generate an access token. You can get these data at the OAuth Playground; if you want to use your own app, remember to swap out the app ID, secret, and other values. (The file also provides valid values for other tests, which you're welcome to swap out for data specific to your own application.)
136
+ Important Note: to run the live tests, you have to provide some of your own data: a valid OAuth access token with publish\_stream, read\_stream, and user\_photos permissions and an OAuth code that can be used to generate an access token. You can get these data at the OAuth Playground; if you want to use your own app, remember to swap out the app ID, secret, and other values. (The file also provides valid values for other tests, which you're welcome to swap out for data specific to your own application.)
@@ -4,19 +4,19 @@
4
4
  # Just remember to update all fields!
5
5
 
6
6
  # You must supply this value yourself to test the GraphAPI class.
7
- # Your OAuth token should have publish_stream and read_stream permissions.
8
- oauth_token:
7
+ # Your OAuth token should have publish_stream, read_stream, and user_photos permissions.
8
+ oauth_token: 119908831367602|2.SzVOt20se6d7VnLzsG3USg__.3600.1302102000-2905623|Qxhc8NPxIQFKuNOaL1XdYNcztAM
9
9
 
10
10
  # for testing the OAuth class
11
11
  # baseline app
12
12
  oauth_test_data:
13
13
  # You must supply this value yourself, since they will expire.
14
- code:
14
+ code: 2.SzVOt20se6d7VnLzsG3USg__.3600.1302102000-2905623|Z5x3PcJgROjfj6DOwVQpb714nkQ
15
15
  # easiest way to get session keys: use multiple test accounts with the Javascript login at http://oauth.twoalex.com
16
- session_key:
16
+ session_key: 2.SzVOt20se6d7VnLzsG3USg__.3600.1302102000-2905623
17
17
  multiple_session_keys:
18
- -
19
- -
18
+ - 2.SzVOt20se6d7VnLzsG3USg__.3600.1302102000-2905623
19
+ - 2.SzVOt20se6d7VnLzsG3USg__.3600.1302102000-2905623
20
20
 
21
21
  # These values will work out of the box
22
22
  app_id: 119908831367602
@@ -35,17 +35,21 @@ oauth_test_data:
35
35
  # note: I've revoked the offline access for security reasons, so you can't make calls against this :)
36
36
  fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
37
37
 
38
- # These values will work out of the box
39
- # They're from Facebook's example at http://developers.facebook.com/docs/authentication/canvas
38
+ # These values from the OAuth Playground (see above) will work out of the box
40
39
  # You can update this to live data if desired
41
40
  # request_secret is optional and will fall back to the secret above if absent
42
- request_secret: "secret"
43
- signed_request: "vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsIjAiOiJwYXlsb2FkIn0"
44
- signed_request_result:
45
- "0": payload
41
+ signed_params: "zWRm0gd5oHW_jzXP_WA9CirO7c5CLHotn-SKRqH2NmU.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjEzMDE5MjIwMDAsImlzc3VlZF9hdCI6MTMwMTkxNzI5OSwib2F1dGhfdG9rZW4iOiIxMTk5MDg4MzEzNjc2MDJ8Mi56VkZfNk5yTUVMSHVKYTRnSVU5dEt3X18uMzYwMC4xMzAxOTIyMDAwLTI5MDU2MjN8emdxUHNyMkJHOUxvT0s5a2VrR2dSVVJaeDBrIiwidXNlciI6eyJjb3VudHJ5IjoiZGUiLCJsb2NhbGUiOiJkZV9ERSIsImFnZSI6eyJtaW4iOjIxfX0sInVzZXJfaWQiOiIyOTA1NjIzIn0"
42
+ signed_params_result:
43
+ expires: 1301922000
46
44
  algorithm: HMAC-SHA256
47
-
48
-
45
+ user_id: "2905623"
46
+ oauth_token: 119908831367602|2.zVF_6NrMELHuJa4gIU9tKw__.3600.1301922000-2905623|zgqPsr2BG9LoOK9kekGgRURZx0k
47
+ user:
48
+ country: de
49
+ locale: de_DE
50
+ age:
51
+ min: 21
52
+ issued_at: 1301917299
49
53
 
50
54
  subscription_test_data:
51
55
  subscription_path: http://oauth.twoalex.com/subscriptions
Binary file
@@ -3,8 +3,12 @@ class GraphAndRestAPINoTokenTests < Test::Unit::TestCase
3
3
  before(:each) do
4
4
  @api = Koala::Facebook::GraphAndRestAPI.new
5
5
  end
6
-
6
+
7
+ it_should_behave_like "Koala RestAPI"
7
8
  it_should_behave_like "Koala RestAPI without an access token"
9
+
10
+ it_should_behave_like "Koala GraphAPI"
8
11
  it_should_behave_like "Koala GraphAPI without an access token"
12
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
9
13
  end
10
14
  end
@@ -1,11 +1,16 @@
1
1
  class GraphAndRestAPIWithTokenTests < Test::Unit::TestCase
2
2
  describe "Koala GraphAndRestAPI without an access token" do
3
3
  include LiveTestingDataHelper
4
- it_should_behave_like "Koala RestAPI with an access token"
5
- it_should_behave_like "Koala GraphAPI with an access token"
6
-
4
+
7
5
  before(:each) do
8
6
  @api = Koala::Facebook::GraphAndRestAPI.new(@token)
9
7
  end
8
+
9
+ it_should_behave_like "Koala RestAPI"
10
+ it_should_behave_like "Koala RestAPI with an access token"
11
+
12
+ it_should_behave_like "Koala GraphAPI"
13
+ it_should_behave_like "Koala GraphAPI with an access token"
14
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
10
15
  end
11
16
  end
@@ -1,9 +1,4 @@
1
1
  shared_examples_for "Koala GraphAPI without an access token" do
2
- it "should get public data about a user" do
3
- result = @api.get_object("koppel")
4
- # the results should have an ID and a name, among other things
5
- (result["id"] && result["name"]).should
6
- end
7
2
 
8
3
  it "should not get private data about a user" do
9
4
  result = @api.get_object("koppel")
@@ -11,46 +6,14 @@ shared_examples_for "Koala GraphAPI without an access token" do
11
6
  result["updated_time"].should be_nil
12
7
  end
13
8
 
14
- it "should get public data about a Page" do
15
- result = @api.get_object("contextoptional")
16
- # the results should have an ID and a name, among other things
17
- (result["id"] && result["name"]).should
18
- end
19
-
20
9
  it "should not be able to get data about 'me'" do
21
10
  lambda { @api.get_object("me") }.should raise_error(Koala::Facebook::APIError)
22
11
  end
23
12
 
24
- it "should be able to get multiple objects" do
25
- results = @api.get_objects(["contextoptional", "naitik"])
26
- results.length.should == 2
27
- end
28
-
29
13
  it "shouldn't be able to access connections from users" do
30
14
  lambda { @api.get_connections("lukeshepard", "likes") }.should raise_error(Koala::Facebook::APIError)
31
15
  end
32
16
 
33
- it "should be able to access a user's picture" do
34
- @api.get_picture("chris.baclig").should =~ /http\:\/\//
35
- end
36
-
37
- it "should be able to access a user's picture, given a picture type" do
38
- @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
39
- end
40
-
41
- it "should be able to access connections from public Pages" do
42
- result = @api.get_connections("contextoptional", "photos")
43
- result.should be_a(Array)
44
- end
45
-
46
- # paging
47
- # see also graph_collection_tests
48
- it "should make a request for a page when provided a specific set of page params" do
49
- query = [1, 2]
50
- @api.should_receive(:graph_call).with(*query)
51
- @api.get_page(query)
52
- end
53
-
54
17
  it "should not be able to put an object" do
55
18
  lambda { @result = @api.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
56
19
  puts "Error! Object #{@result.inspect} somehow put onto Luke Shepard's wall!" if @result
@@ -59,8 +22,8 @@ shared_examples_for "Koala GraphAPI without an access token" do
59
22
  # these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
60
23
  it "should not be able to post to a feed" do
61
24
  (lambda do
62
- attachment = {:name => "Context Optional", :link => "http://www.contextoptional.com/"}
63
- @result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
25
+ attachment = {:name => "OAuth Playground", :link => "http://www.oauth.twoalex.com/"}
26
+ @result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
64
27
  end).should raise_error(Koala::Facebook::APIError)
65
28
  puts "Error! Object #{@result.inspect} somehow put onto Context Optional's wall!" if @result
66
29
  end
@@ -68,7 +31,7 @@ shared_examples_for "Koala GraphAPI without an access token" do
68
31
  it "should not be able to comment on an object" do
69
32
  # random public post on the ContextOptional wall
70
33
  lambda { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
71
- puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
34
+ puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
72
35
  end
73
36
 
74
37
  it "should not be able to like an object" do
@@ -76,39 +39,27 @@ shared_examples_for "Koala GraphAPI without an access token" do
76
39
  end
77
40
 
78
41
  # DELETE
79
- it "should not be able to delete posts" do
42
+ it "should not be able to delete posts" do
80
43
  # test post on the Ruby SDK Test application
81
44
  lambda { @result = @api.delete_object("115349521819193_113815981982767") }.should raise_error(Koala::Facebook::APIError)
82
45
  end
83
-
84
- # SEARCH
85
- it "should be able to search" do
86
- result = @api.search("facebook")
87
- result.length.should be_an(Integer)
88
- end
89
-
90
- it_should_behave_like "Koala GraphAPI with GraphCollection"
91
46
 
92
- # API
93
- it "should never use the rest api server" do
94
- Koala.should_receive(:make_request).with(
95
- anything,
96
- anything,
97
- anything,
98
- hash_not_including(:rest_api => true)
99
- ).and_return(Koala::Response.new(200, "", {}))
100
-
101
- @api.api("anything")
47
+ it "should not be able to delete a like" do
48
+ lambda { @api.delete_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
102
49
  end
103
50
  end
104
51
 
105
52
  class FacebookNoAccessTokenTests < Test::Unit::TestCase
106
53
  describe "Koala GraphAPI without an access token" do
54
+ include LiveTestingDataHelper
55
+
107
56
  before :each do
108
57
  @api = Koala::Facebook::GraphAPI.new
109
- end
110
-
58
+ end
59
+
60
+ it_should_behave_like "Koala GraphAPI"
111
61
  it_should_behave_like "Koala GraphAPI without an access token"
62
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
63
+
112
64
  end
113
65
  end
114
-