koala 0.9.0 → 0.10.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 (37) hide show
  1. data/CHANGELOG +10 -0
  2. data/Manifest +2 -14
  3. data/Rakefile +2 -1
  4. data/koala.gemspec +7 -4
  5. data/lib/koala/test_users.rb +72 -0
  6. data/lib/koala.rb +15 -1
  7. data/readme.md +3 -2
  8. data/spec/facebook_data.yml +5 -5
  9. data/spec/koala/api_base_tests.rb +7 -0
  10. data/spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb +1 -1
  11. data/spec/koala/graph_api/graph_api_with_access_token_tests.rb +1 -1
  12. data/spec/koala/graph_api/graph_collection_tests.rb +2 -2
  13. data/spec/koala/live_testing_data_helper.rb +40 -12
  14. data/spec/koala/net_http_service_tests.rb +164 -159
  15. data/spec/koala/oauth/oauth_tests.rb +9 -11
  16. data/spec/koala/rest_api/rest_api_no_access_token_tests.rb +5 -5
  17. data/spec/koala/rest_api/rest_api_with_access_token_tests.rb +1 -1
  18. data/spec/koala/test_users/test_users_tests.rb +215 -0
  19. data/spec/koala_spec_helper.rb +21 -4
  20. data/spec/koala_spec_without_mocks.rb +1 -1
  21. data/spec/mock_facebook_responses.yml +49 -1
  22. data/spec/mock_http_service.rb +1 -0
  23. metadata +20 -19
  24. data/examples/oauth_playground/Capfile +0 -2
  25. data/examples/oauth_playground/LICENSE +0 -22
  26. data/examples/oauth_playground/Rakefile +0 -4
  27. data/examples/oauth_playground/config/deploy.rb +0 -39
  28. data/examples/oauth_playground/config/facebook.yml +0 -13
  29. data/examples/oauth_playground/config.ru +0 -27
  30. data/examples/oauth_playground/lib/load_facebook.rb +0 -3
  31. data/examples/oauth_playground/lib/oauth_playground.rb +0 -187
  32. data/examples/oauth_playground/readme.md +0 -8
  33. data/examples/oauth_playground/spec/oauth_playground_spec.rb +0 -35
  34. data/examples/oauth_playground/spec/spec_helper.rb +0 -36
  35. data/examples/oauth_playground/tmp/restart.txt +0 -0
  36. data/examples/oauth_playground/views/index.erb +0 -206
  37. data/examples/oauth_playground/views/layout.erb +0 -39
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ v0.10.0
2
+ -- Added test user module
3
+ -- Fixed bug when raising APIError after Facebook fails to exchange session keys
4
+ -- Made access_token accessible via the readonly access_token property on all our API classes
5
+
6
+ v0.9.1
7
+ -- Tests are now compatible with Ruby 1.9.2
8
+ -- Added JSON to runtime dependencies
9
+ -- Removed examples directory (referenced from github instead)
10
+
1
11
  v0.9.0
2
12
  -- Added parse_signed_request to handle Facebook's new authentication scheme
3
13
  -- note: creates dependency on OpenSSL (OpenSSL::HMAC) for decryption
data/Manifest CHANGED
@@ -2,20 +2,6 @@ CHANGELOG
2
2
  LICENSE
3
3
  Manifest
4
4
  Rakefile
5
- examples/oauth_playground/Capfile
6
- examples/oauth_playground/LICENSE
7
- examples/oauth_playground/Rakefile
8
- examples/oauth_playground/config.ru
9
- examples/oauth_playground/config/deploy.rb
10
- examples/oauth_playground/config/facebook.yml
11
- examples/oauth_playground/lib/load_facebook.rb
12
- examples/oauth_playground/lib/oauth_playground.rb
13
- examples/oauth_playground/readme.md
14
- examples/oauth_playground/spec/oauth_playground_spec.rb
15
- examples/oauth_playground/spec/spec_helper.rb
16
- examples/oauth_playground/tmp/restart.txt
17
- examples/oauth_playground/views/index.erb
18
- examples/oauth_playground/views/layout.erb
19
5
  init.rb
20
6
  koala.gemspec
21
7
  lib/koala.rb
@@ -23,6 +9,7 @@ lib/koala/graph_api.rb
23
9
  lib/koala/http_services.rb
24
10
  lib/koala/realtime_updates.rb
25
11
  lib/koala/rest_api.rb
12
+ lib/koala/test_users.rb
26
13
  readme.md
27
14
  spec/facebook_data.yml
28
15
  spec/koala/api_base_tests.rb
@@ -37,6 +24,7 @@ spec/koala/oauth/oauth_tests.rb
37
24
  spec/koala/realtime_updates/realtime_updates_tests.rb
38
25
  spec/koala/rest_api/rest_api_no_access_token_tests.rb
39
26
  spec/koala/rest_api/rest_api_with_access_token_tests.rb
27
+ spec/koala/test_users/test_users_tests.rb
40
28
  spec/koala_spec.rb
41
29
  spec/koala_spec_helper.rb
42
30
  spec/koala_spec_without_mocks.rb
data/Rakefile CHANGED
@@ -4,13 +4,14 @@ require 'rake'
4
4
  require 'echoe'
5
5
 
6
6
  # gem management
7
- Echoe.new('koala', '0.9.0') do |p|
7
+ Echoe.new('koala', '0.10.0') do |p|
8
8
  p.summary = "A lightweight, flexible library for Facebook with support for the Graph API, the old REST API, realtime updates, and OAuth validation."
9
9
  p.description = "Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write access to the social graph via the Graph API and the older REST API, as well as support for realtime updates and OAuth and Facebook Connect authentication. Koala is fully tested and supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services."
10
10
  p.url = "http://github.com/arsduo/koala"
11
11
  p.author = ["Alex Koppel", "Chris Baclig", "Rafi Jacoby", "Context Optional"]
12
12
  p.email = "alex@alexkoppel.com"
13
13
  p.ignore_pattern = ["tmp/*", "script/*", "pkg/*"]
14
+ p.runtime_dependencies = ["json >=1.0"]
14
15
  p.development_dependencies = []
15
16
  p.retain_gemspec = true
16
17
  end
data/koala.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{koala}
5
- s.version = "0.9.0"
5
+ s.version = "0.10.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Alex Koppel, Chris Baclig, Rafi Jacoby, Context Optional"]
9
- s.date = %q{2010-09-30}
9
+ s.date = %q{2010-12-15}
10
10
  s.description = %q{Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write access to the social graph via the Graph API and the older REST API, as well as support for realtime updates and OAuth and Facebook Connect authentication. Koala is fully tested and supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.}
11
11
  s.email = %q{alex@alexkoppel.com}
12
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "lib/koala.rb", "lib/koala/graph_api.rb", "lib/koala/http_services.rb", "lib/koala/realtime_updates.rb", "lib/koala/rest_api.rb"]
13
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "Rakefile", "examples/oauth_playground/Capfile", "examples/oauth_playground/LICENSE", "examples/oauth_playground/Rakefile", "examples/oauth_playground/config.ru", "examples/oauth_playground/config/deploy.rb", "examples/oauth_playground/config/facebook.yml", "examples/oauth_playground/lib/load_facebook.rb", "examples/oauth_playground/lib/oauth_playground.rb", "examples/oauth_playground/readme.md", "examples/oauth_playground/spec/oauth_playground_spec.rb", "examples/oauth_playground/spec/spec_helper.rb", "examples/oauth_playground/tmp/restart.txt", "examples/oauth_playground/views/index.erb", "examples/oauth_playground/views/layout.erb", "init.rb", "koala.gemspec", "lib/koala.rb", "lib/koala/graph_api.rb", "lib/koala/http_services.rb", "lib/koala/realtime_updates.rb", "lib/koala/rest_api.rb", "readme.md", "spec/facebook_data.yml", "spec/koala/api_base_tests.rb", "spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb", "spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb", "spec/koala/graph_api/graph_api_no_access_token_tests.rb", "spec/koala/graph_api/graph_api_with_access_token_tests.rb", "spec/koala/graph_api/graph_collection_tests.rb", "spec/koala/live_testing_data_helper.rb", "spec/koala/net_http_service_tests.rb", "spec/koala/oauth/oauth_tests.rb", "spec/koala/realtime_updates/realtime_updates_tests.rb", "spec/koala/rest_api/rest_api_no_access_token_tests.rb", "spec/koala/rest_api/rest_api_with_access_token_tests.rb", "spec/koala_spec.rb", "spec/koala_spec_helper.rb", "spec/koala_spec_without_mocks.rb", "spec/mock_facebook_responses.yml", "spec/mock_http_service.rb"]
12
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "lib/koala.rb", "lib/koala/graph_api.rb", "lib/koala/http_services.rb", "lib/koala/realtime_updates.rb", "lib/koala/rest_api.rb", "lib/koala/test_users.rb"]
13
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "Rakefile", "init.rb", "koala.gemspec", "lib/koala.rb", "lib/koala/graph_api.rb", "lib/koala/http_services.rb", "lib/koala/realtime_updates.rb", "lib/koala/rest_api.rb", "lib/koala/test_users.rb", "readme.md", "spec/facebook_data.yml", "spec/koala/api_base_tests.rb", "spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb", "spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb", "spec/koala/graph_api/graph_api_no_access_token_tests.rb", "spec/koala/graph_api/graph_api_with_access_token_tests.rb", "spec/koala/graph_api/graph_collection_tests.rb", "spec/koala/live_testing_data_helper.rb", "spec/koala/net_http_service_tests.rb", "spec/koala/oauth/oauth_tests.rb", "spec/koala/realtime_updates/realtime_updates_tests.rb", "spec/koala/rest_api/rest_api_no_access_token_tests.rb", "spec/koala/rest_api/rest_api_with_access_token_tests.rb", "spec/koala/test_users/test_users_tests.rb", "spec/koala_spec.rb", "spec/koala_spec_helper.rb", "spec/koala_spec_without_mocks.rb", "spec/mock_facebook_responses.yml", "spec/mock_http_service.rb"]
14
14
  s.homepage = %q{http://github.com/arsduo/koala}
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Koala", "--main", "readme.md"]
16
16
  s.require_paths = ["lib"]
@@ -23,8 +23,11 @@ Gem::Specification.new do |s|
23
23
  s.specification_version = 3
24
24
 
25
25
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<json>, [">= 1.0"])
26
27
  else
28
+ s.add_dependency(%q<json>, [">= 1.0"])
27
29
  end
28
30
  else
31
+ s.add_dependency(%q<json>, [">= 1.0"])
29
32
  end
30
33
  end
@@ -0,0 +1,72 @@
1
+ require 'koala'
2
+
3
+ module Koala
4
+ module Facebook
5
+ module TestUserMethods
6
+
7
+ def initialize(options = {})
8
+ @app_id = options[:app_id]
9
+ @app_access_token = options[:app_access_token]
10
+ @secret = options[:secret]
11
+ unless @app_id && (@app_access_token || @secret) # make sure we have what we need
12
+ raise ArgumentError, "Initialize must receive a hash with :app_id and either :app_access_token or :secret! (received #{options.inspect})"
13
+ end
14
+
15
+ # fetch the access token if we're provided a secret
16
+ if @secret && !@app_access_token
17
+ oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
18
+ @app_access_token = oauth.get_app_access_token
19
+ end
20
+ @graph_api = GraphAPI.new(@app_access_token)
21
+ end
22
+
23
+ def create(installed, permissions = nil)
24
+ # Creates and returns a test user
25
+ args = {'installed' => installed}
26
+ args['permissions'] = (permissions.is_a?(Array) ? permissions.join(",") : permissions) if installed
27
+ result = @graph_api.graph_call(accounts_path, args, "post")
28
+ end
29
+
30
+ def list
31
+ @graph_api.graph_call(accounts_path)["data"]
32
+ end
33
+
34
+ def delete(test_user)
35
+ test_user = test_user["id"] if test_user.is_a?(Hash)
36
+ @graph_api.delete_object(test_user)
37
+ end
38
+
39
+ def delete_all
40
+ list.each {|u| delete u }
41
+ end
42
+
43
+ def befriend(user1, user2)
44
+ user1 = user1["id"] if user1.is_a?(Hash)
45
+ user2 = user2["id"] if user2.is_a?(Hash)
46
+ @graph_api.graph_call("/#{user1}/friends/#{user2}") && @graph_api.graph_call("/#{user2}/friends/#{user1}")
47
+ end
48
+
49
+ def create_network(network_size, installed = true, permissions = '')
50
+ network_size = 50 if network_size > 50 # FB's max is 50
51
+ users = (0...network_size).collect { create(installed, permissions) }
52
+ friends = users.clone
53
+ users.each do |user|
54
+ # Remove this user from list of friends
55
+ friends.delete_at(0)
56
+ # befriend all the others
57
+ friends.each do |friend|
58
+ befriend(user, friend)
59
+ end
60
+ end
61
+ return users
62
+ end
63
+
64
+ protected
65
+
66
+ def accounts_path
67
+ @accounts_path ||= "/#{@app_id}/accounts/test-users"
68
+ end
69
+
70
+ end # TestUserMethods
71
+ end # Facebook
72
+ end # Koala
data/lib/koala.rb CHANGED
@@ -17,8 +17,12 @@ require 'koala/graph_api'
17
17
  # add REST API methods
18
18
  require 'koala/rest_api'
19
19
 
20
+ # add realtime update methods
20
21
  require 'koala/realtime_updates'
21
22
 
23
+ # add test user methods
24
+ require 'koala/test_users'
25
+
22
26
  module Koala
23
27
 
24
28
  module Facebook
@@ -48,6 +52,7 @@ module Koala
48
52
  def initialize(access_token = nil)
49
53
  @access_token = access_token
50
54
  end
55
+ attr_reader :access_token
51
56
 
52
57
  def api(path, args = {}, verb = "get", options = {}, &error_checking_block)
53
58
  # Fetches the given path in the Graph API.
@@ -98,6 +103,12 @@ module Koala
98
103
  include RealtimeUpdateMethods
99
104
  end
100
105
 
106
+ class TestUsers < API
107
+ include TestUserMethods
108
+ # make the Graph API accessible in case someone wants to make other calls to interact with their users
109
+ attr_reader :graph_api
110
+ end
111
+
101
112
  class APIError < Exception
102
113
  attr_accessor :fb_error_type
103
114
  def initialize(details = {})
@@ -223,7 +234,10 @@ module Koala
223
234
 
224
235
  # Facebook returns an empty body in certain error conditions
225
236
  if response == ""
226
- raise APIError.new("ArgumentError", "get_token_from_session_key received an error (empty response body) for sessions #{sessions.inspect}!")
237
+ raise APIError.new({
238
+ "type" => "ArgumentError",
239
+ "message" => "get_token_from_session_key received an error (empty response body) for sessions #{sessions.inspect}!"
240
+ })
227
241
  end
228
242
 
229
243
  JSON.parse(response)
data/readme.md CHANGED
@@ -56,10 +56,11 @@ We reserve the right to expand the built-in REST API coverage to additional conv
56
56
  OAuth
57
57
  -----
58
58
  You can use the Graph and REST APIs without an OAuth access token, but the real magic happens when you provide Facebook an OAuth token to prove you're authenticated. Koala provides an OAuth class to make that process easy:
59
- @oauth = Koala::Facebook::OAuth.new(app_id, code, callback_url)
59
+ @oauth = Koala::Facebook::OAuth.new(app_id, app_secret, callback_url)
60
60
 
61
61
  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:
62
- @oauth.get_user_from_cookie(cookies)
62
+ @oauth.get_user_from_cookies(cookies) # gets the user's ID
63
+ @oauth.get_user_info_from_cookies(cookies) # parses and returns the entire hash
63
64
 
64
65
  And if you have to use the more complicated [redirect-based OAuth process](http://developers.facebook.com/docs/authentication/), Koala helps out there, too:
65
66
  # generate authenticating URL
@@ -5,18 +5,18 @@
5
5
 
6
6
  # You must supply this value yourself to test the GraphAPI class.
7
7
  # Your OAuth token should have publish_stream and read_stream permissions.
8
- oauth_token: 119908831367602|2.K0IVdhrRngS7VQM4Z_s6_g__.3600.1285844400-2905623|Q3VNUb9haS3s29X4SYPk6VL1f9A
8
+ oauth_token:
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: 2.K0IVdhrRngS7VQM4Z_s6_g__.3600.1285844400-2905623|b5PCXOhEMe2FJXPHAg_mY3Psl6M
14
+ code:
15
15
  # easiest way to get session keys: use multiple test accounts with the Javascript login at http://oauth.twoalex.com
16
- session_key: 2.K0IVdhrRngS7VQM4Z_s6_g__.3600.1285844400-2905623
16
+ session_key:
17
17
  multiple_session_keys:
18
- - 2.K0IVdhrRngS7VQM4Z_s6_g__.3600.1285844400-2905623
19
- - 2.K0IVdhrRngS7VQM4Z_s6_g__.3600.1285844400-2905623
18
+ -
19
+ -
20
20
 
21
21
  # These values will work out of the box
22
22
  app_id: 119908831367602
@@ -1,4 +1,5 @@
1
1
  class ApiBaseTests < Test::Unit::TestCase
2
+
2
3
  describe "Koala API base class" do
3
4
  before(:each) do
4
5
  @service = Koala::Facebook::API.new
@@ -29,6 +30,12 @@ class ApiBaseTests < Test::Unit::TestCase
29
30
  service.api('anything')
30
31
  end
31
32
 
33
+ it "should have an attr_reader for access token" do
34
+ token = 'adfadf'
35
+ service = Koala::Facebook::API.new token
36
+ service.access_token.should == token
37
+ end
38
+
32
39
  it "should get the attribute of a Koala::Response given by the http_component parameter" do
33
40
  http_component = :method_name
34
41
 
@@ -1,6 +1,6 @@
1
1
  class GraphAndRestAPIWithTokenTests < Test::Unit::TestCase
2
2
  describe "Koala GraphAndRestAPI without an access token" do
3
- it_should_behave_like "live testing examples"
3
+ include LiveTestingDataHelper
4
4
  it_should_behave_like "Koala RestAPI with an access token"
5
5
  it_should_behave_like "Koala GraphAPI with an access token"
6
6
 
@@ -140,7 +140,7 @@ end
140
140
 
141
141
  class FacebookWithAccessTokenTests < Test::Unit::TestCase
142
142
  describe "Koala GraphAPI with an access token" do
143
- it_should_behave_like "live testing examples"
143
+ include LiveTestingDataHelper
144
144
  it_should_behave_like "Koala GraphAPI with an access token"
145
145
 
146
146
  before :each do
@@ -65,7 +65,7 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
65
65
  @api.should_receive(:graph_call).with(@base, @args).and_return(@second_page)
66
66
  Koala::Facebook::GraphCollection.should_receive(:new).with(@second_page, @api).and_return(@page_of_results)
67
67
 
68
- @result.previous_page(@api).should == @page_of_results
68
+ @result.previous_page.should == @page_of_results
69
69
  end
70
70
 
71
71
  it "should return the next page of results" do
@@ -79,7 +79,7 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
79
79
  it "should return nil it there are no other pages" do
80
80
  %w{next previous}.each do |this|
81
81
  @result.should_receive("#{this}_page_params".to_sym).and_return(nil)
82
- @result.send("#{this}_page", @api).should == nil
82
+ @result.send("#{this}_page").should == nil
83
83
  end
84
84
  end
85
85
  end
@@ -1,15 +1,43 @@
1
- shared_examples_for "live testing examples" do
2
- before :each do
3
- @token = $testing_data["oauth_token"]
4
- raise Exception, "Must supply access token to run FacebookWithAccessTokenTests!" unless @token
5
- end
6
-
7
- after :each do
8
- # clean up any temporary objects
9
- if @temporary_object_id
10
- puts "\nCleaning up temporary object #{@temporary_object_id.to_s}"
11
- result = @api.delete_object(@temporary_object_id)
12
- raise "Unable to clean up temporary Graph object #{@temporary_object_id}!" unless result
1
+ module LiveTestingDataHelper
2
+ # in RSpec 2, included example groups no longer share any hooks or state with outside examples
3
+ # even if in the same block
4
+ # so we have to use a module to provide setup and teardown hooks for live testing
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ before :each do
9
+ @token = $testing_data["oauth_token"]
10
+ raise Exception, "Must supply access token to run FacebookWithAccessTokenTests!" unless @token
11
+ # track temporary objects created
12
+ @temporary_object_ids = []
13
+ end
14
+
15
+ after :each do
16
+ # clean up any temporary objects
17
+ @temporary_object_ids << @temporary_object_id if @temporary_object_id
18
+ count = @temporary_object_ids.length
19
+ errors = []
20
+
21
+ if count > 0
22
+ print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object"}..."
23
+ @temporary_object_ids.each do |id|
24
+ # get our API
25
+ api = @api || (@test_users ? @test_users.graph_api : nil)
26
+ raise "Unable to locate API when passed temporary object to delete!" unless api
27
+
28
+ # delete the object
29
+ result = (api.delete_object(id) rescue false)
30
+ # if we errored out or Facebook returned false, track that
31
+ errors << id unless result
32
+ end
33
+
34
+ if errors.length == 0
35
+ puts "done."
36
+ else
37
+ puts "cleaned up #{count - errors.length} objects, but errored out on the following:\n #{errors.join(", ")}"
38
+ end
39
+ end
13
40
  end
14
41
  end
42
+ end
15
43
  end