koala 1.0.0 → 1.1.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.
Files changed (39) hide show
  1. data/.autotest +12 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG +26 -2
  5. data/Gemfile +4 -0
  6. data/autotest/discover.rb +1 -0
  7. data/koala.gemspec +8 -8
  8. data/lib/koala/batch_operation.rb +74 -0
  9. data/lib/koala/graph_api.rb +103 -102
  10. data/lib/koala/graph_batch_api.rb +87 -0
  11. data/lib/koala/graph_collection.rb +54 -0
  12. data/lib/koala/http_services/net_http_service.rb +92 -0
  13. data/lib/koala/http_services/typhoeus_service.rb +37 -0
  14. data/lib/koala/http_services.rb +13 -113
  15. data/lib/koala/oauth.rb +181 -0
  16. data/lib/koala/realtime_updates.rb +5 -14
  17. data/lib/koala/rest_api.rb +13 -8
  18. data/lib/koala/uploadable_io.rb +137 -77
  19. data/lib/koala.rb +36 -196
  20. data/readme.md +51 -32
  21. data/spec/cases/api_base_spec.rb +4 -4
  22. data/spec/cases/graph_api_batch_spec.rb +609 -0
  23. data/spec/cases/http_services/http_service_spec.rb +87 -12
  24. data/spec/cases/http_services/net_http_service_spec.rb +259 -77
  25. data/spec/cases/http_services/typhoeus_service_spec.rb +29 -21
  26. data/spec/cases/koala_spec.rb +55 -0
  27. data/spec/cases/oauth_spec.rb +1 -1
  28. data/spec/cases/realtime_updates_spec.rb +3 -3
  29. data/spec/cases/test_users_spec.rb +1 -1
  30. data/spec/cases/uploadable_io_spec.rb +56 -14
  31. data/spec/fixtures/cat.m4v +0 -0
  32. data/spec/fixtures/mock_facebook_responses.yml +100 -5
  33. data/spec/spec_helper.rb +2 -1
  34. data/spec/support/graph_api_shared_examples.rb +106 -35
  35. data/spec/support/json_testing_fix.rb +18 -0
  36. data/spec/support/mock_http_service.rb +57 -56
  37. data/spec/support/rest_api_shared_examples.rb +131 -7
  38. data/spec/support/setup_mocks_or_live.rb +3 -4
  39. metadata +34 -47
data/readme.md CHANGED
@@ -1,37 +1,38 @@
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 (including photo uploads), the old REST API, realtime updates, and OAuth validation. We wrote Koala with four goals:
3
+ [Koala](http://github.com/arsduo/koala) is a new Facebook library for Ruby, supporting the Graph API (including the batch requests and photo uploads), the REST API, realtime updates, test users, 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 750 lines of code.)
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
- * 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.)
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, at just over 750 lines of code.)
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
+ * Flexible: Koala should be useful to everyone, regardless of their current configuration. (In addition to vanilla Ruby, we support JRuby, Rubinius, and REE, and provide built-in mechanism for using whichever HTTP library you prefer.)
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
10
+ Installation
11
11
  ---
12
- Version 1.0 is due out on May 1st, 2011 with a ton of great features.
13
-
14
- sudo gem install koala
15
12
 
16
- Until then, you can install the release candidate like so:
13
+ Easy:
14
+
15
+ [sudo|rvm] gem install koala
16
+
17
+ Or in Bundler:
17
18
 
18
- sudo gem install koala --pre
19
+ gem "koala"
19
20
 
20
21
  Graph API
21
22
  ----
22
23
  The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
23
24
 
24
- graph = Koala::Facebook::GraphAPI.new(oauth_access_token)
25
- profile = graph.get_object("me")
26
- friends = graph.get_connections("me", "friends")
27
- graph.put_object("me", "feed", :message => "I am writing on my wall!")
25
+ @graph = Koala::Facebook::GraphAPI.new(oauth_access_token)
26
+ profile = @graph.get_object("me")
27
+ friends = @graph.get_connections("me", "friends")
28
+ @graph.put_object("me", "feed", :message => "I am writing on my wall!")
28
29
 
29
30
  The response of most requests is the JSON data returned from the Facebook servers as a Hash.
30
31
 
31
32
  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:
32
33
 
33
34
  # Returns the feed items for the currently logged-in user as a GraphCollection
34
- feed = graph.get_connections("me", "feed")
35
+ feed = @graph.get_connections("me", "feed")
35
36
 
36
37
  # GraphCollection is a sub-class of Array, so you can use it as a usual Array
37
38
  first_entry = feed[0]
@@ -44,20 +45,29 @@ When retrieving data that returns an array of results (for example, when calling
44
45
  # This is useful for paging across multiple requests
45
46
  next_path, next_args = feed.next_page_params
46
47
 
47
- # You can use those params to easily get the next (or prevous) page
48
- page = graph.get_page(feed.next_page_params)
48
+ # You can use those params to easily get the next (or previous) page
49
+ page = @graph.get_page(feed.next_page_params)
50
+
51
+ You can make multiple calls at once using Facebook's batch API:
52
+
53
+ # Returns an array of results as if they were called non-batch
54
+ @graph.batch do |batch_api|
55
+ batch_api.get_object('me')
56
+ batch_api.get_object('koppel')
57
+ end
49
58
 
50
59
  Check out the wiki for more examples.
51
60
 
52
- The old-school REST API
61
+ The REST API
53
62
  -----
54
63
  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.
55
64
 
56
65
  Koala now supports the old-school REST API using OAuth access tokens; to use this, instantiate your class using the RestAPI class:
57
66
 
58
- @rest = Koala::Facebook::RestAPI.new(oauth_access_token)
59
- @rest.fql_query(my_fql_query) # convenience method
60
- @rest.rest_call("stream.publish", arguments_hash) # generic version
67
+ @rest = Koala::Facebook::RestAPI.new(oauth_access_token)
68
+ @rest.fql_query(my_fql_query) # convenience method
69
+ @rest.fql_multiquery(fql_query_hash) # convenience method
70
+ @rest.rest_call("stream.publish", arguments_hash) # generic version
61
71
 
62
72
  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.
63
73
 
@@ -70,7 +80,7 @@ You can use the Graph and REST APIs without an OAuth access token, but the real
70
80
 
71
81
  If your application uses Koala and the Facebook [JavaScript SDK](http://github.com/facebook/connect-js) (formerly Facebook Connect), you can use the OAuth class to parse the cookies:
72
82
  @oauth.get_user_from_cookies(cookies) # gets the user's ID
73
- @oauth.get_user_info_from_cookies(cookies) # parses and returns the entire hash
83
+ @oauth.get_user_info_from_cookies(cookies) # parses and returns the entire hash
74
84
 
75
85
  And if you have to use the more complicated [redirect-based OAuth process](http://developers.facebook.com/docs/authentication/), Koala helps out there, too:
76
86
  # generate authenticating URL
@@ -81,20 +91,18 @@ And if you have to use the more complicated [redirect-based OAuth process](http:
81
91
  You can also get your application's own access token, which can be used without a user session for subscriptions and certain other requests:
82
92
  @oauth.get_app_access_token
83
93
 
84
- That's it! It's pretty simple once you get the hang of it. If you're new to OAuth, though, check out the wiki and the OAuth Playground example site (see below).
85
-
86
- *Signed Requests:* Excited to try out the new signed request authentication scheme? Good news! Koala now supports parsing those parameters:
94
+ For those building apps on Facebook, parsing signed requests is simple:
87
95
  @oauth.parse_signed_request(request)
88
96
 
89
- *Exchanging session keys:* Stuck building tab applications on Facebook? Wishing you had an OAuth token so you could use the Graph API? You're in luck! Koala now allows you to exchange session keys for OAuth access tokens:
97
+ Or, if for some horrible reason, you're still using session keys, despair not! It's easy to turn them into shiny, modern OAuth tokens:
90
98
  @oauth.get_token_from_session_key(session_key)
91
99
  @oauth.get_tokens_from_session_keys(array_of_session_keys)
92
100
 
101
+ That's it! It's pretty simple once you get the hang of it. If you're new to OAuth, though, check out the wiki and the OAuth Playground example site (see below).
102
+
93
103
  Real-time Updates
94
104
  -----
95
- The Graph API now allows your application to subscribe to real-time updates for certain objects in the graph.
96
-
97
- Currently, Facebook only supports subscribing to users, permissions and errors. On top of that, there are limitations on what attributes and connections for each of these objects you can subscribe to updates for. Check the [official Facebook documentation](http://developers.facebook.com/docs/api/realtime) for more details.
105
+ Sometimes, reaching out to Facebook is a pain -- let it reach out to you instead. The Graph API allows your application to subscribe to real-time updates for certain objects in the graph; check the [official Facebook documentation](http://developers.facebook.com/docs/api/realtime) for more details on what objects you can subscribe to and what limitations may apply.
98
106
 
99
107
  Koala makes it easy to interact with your applications using the RealtimeUpdates class:
100
108
 
@@ -118,6 +126,17 @@ And to top it all off, RealtimeUpdates provides a static method to respond to Fa
118
126
 
119
127
  For more information about meet_challenge and the RealtimeUpdates class, check out the Real-Time Updates page on the wiki.
120
128
 
129
+ Test Users
130
+ -----
131
+
132
+ We also support the test users API, allowing you to conjure up fake users and command them to do your bidding using the Graph or REST API:
133
+
134
+ @test_users = Koala::Facebook::TestUsers.new(:app_id => id, :secret => secret)
135
+ user = @test_users.create(is_app_installed, desired_permissions)
136
+ user_graph_api = Koala::Facebook::GraphAPI.new(user["access_token"])
137
+ # or, if you want to make a whole community:
138
+ @test_users.create_network(network_size, is_app_installed, common_permissions)
139
+
121
140
  See examples, ask questions
122
141
  -----
123
142
  Some resources to help you as you play with Koala and the Graph API:
@@ -132,12 +151,12 @@ Testing
132
151
  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:
133
152
 
134
153
  # From anywhere in the project directory:
135
- rake spec
154
+ bundle exec rake spec
136
155
 
137
156
 
138
157
  You can also run live tests against Facebook's servers:
139
158
 
140
159
  # Again from anywhere in the project directory:
141
- LIVE=true rake spec
160
+ LIVE=true bundle exec rake spec
142
161
 
143
- Important Note: to run the live tests, you have to provide some of your own data in spec/fixtures/facebook_data.yml: 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 thisdata 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.)
162
+ Important Note: to run the live tests, you have to provide some of your own data in spec/fixtures/facebook_data.yml: 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 this 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.)
@@ -52,21 +52,21 @@ describe "Koala::Facebook::API" do
52
52
  Koala.stub(:make_request).and_return(response)
53
53
 
54
54
  json_body = mock('JSON body')
55
- JSON.stub(:parse).and_return([json_body])
55
+ MultiJson.stub(:decode).and_return([json_body])
56
56
 
57
57
  @service.api('anything').should == json_body
58
58
  end
59
59
 
60
- it "should execute a block with the response body if passed one" do
60
+ it "should execute an error checking block if provided" do
61
61
  body = '{}'
62
62
  Koala.stub(:make_request).and_return(Koala::Response.new(200, body, {}))
63
63
 
64
64
  yield_test = mock('Yield Tester')
65
65
  yield_test.should_receive(:pass)
66
66
 
67
- @service.api('anything') do |arg|
67
+ @service.api('anything', {}, "get") do |arg|
68
68
  yield_test.pass
69
- arg.should == JSON.parse(body)
69
+ arg.should == MultiJson.decode(body)
70
70
  end
71
71
  end
72
72