koala 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ v0.6.0
2
+ -- Added support for the old REST API thanks to cbaclig's great work
3
+ -- Updated tests to conform to RSpec standards
4
+ -- Updated changelog, readme, etc.
5
+
6
+ v0.5.1
7
+ -- Documentation is now on the wiki, updated readme accordingly.
8
+
1
9
  v0.5.0
2
10
  -- Added several new OAuth methods for making and parsing access token requests
3
11
  -- Added test suite for the OAuth class
data/Manifest CHANGED
@@ -2,11 +2,15 @@ CHANGELOG
2
2
  Manifest
3
3
  Rakefile
4
4
  init.rb
5
+ lib/graph_api.rb
5
6
  lib/http_services.rb
6
7
  lib/koala.rb
8
+ lib/rest_api.rb
7
9
  readme.md
8
- test/facebook_data.yml
9
- test/koala/facebook_no_access_token_tests.rb
10
- test/koala/facebook_oauth_tests.rb
11
- test/koala/facebook_with_access_token_tests.rb
12
- test/koala_tests.rb
10
+ spec/facebook_data.yml
11
+ spec/koala/facebook_no_access_token_tests.rb
12
+ spec/koala/facebook_oauth_tests.rb
13
+ spec/koala/facebook_rest_api_no_access_token_test.rb
14
+ spec/koala/facebook_rest_api_with_access_token_test.rb
15
+ spec/koala/facebook_with_access_token_tests.rb
16
+ spec/koala_spec.rb
data/Rakefile CHANGED
@@ -4,11 +4,11 @@ require 'rake'
4
4
  require 'echoe'
5
5
 
6
6
  # gem management
7
- Echoe.new('koala', '0.5.0') do |p|
7
+ Echoe.new('koala', '0.6.0') do |p|
8
8
  p.summary = "A lightweight, flexible library for Facebook's new Graph API"
9
- p.description = "Koala is a lightweight, flexible Ruby SDK for Facebook's new Graph API. It allows read/write access to the Facebook Graph and provides OAuth URLs and cookie validation for Facebook Connect sites. Koala supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services."
9
+ p.description = "Koala is a lightweight, flexible Ruby SDK for Facebook's new Graph API. It allows read/write access to the Facebook Graph and provides OAuth URLs and cookie validation for Facebook Connect sites; it also supports access-token based interaction with the old REST API. Koala 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
- p.author = ["Alex Koppel", "Rafi Jacoby", "Context Optional"]
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
14
  p.development_dependencies = []
@@ -2,15 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{koala}
5
- s.version = "0.5.0"
5
+ s.version = "0.6.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Alex Koppel, Rafi Jacoby, Context Optional"]
9
- s.date = %q{2010-05-08}
10
- s.description = %q{Koala is a lightweight, flexible Ruby SDK for Facebook's new Graph API. It allows read/write access to the Facebook Graph and provides OAuth URLs and cookie validation for Facebook Connect sites. Koala supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.}
8
+ s.authors = ["Alex Koppel, Chris Baclig, Rafi Jacoby, Context Optional"]
9
+ s.date = %q{2010-05-17}
10
+ s.description = %q{Koala is a lightweight, flexible Ruby SDK for Facebook's new Graph API. It allows read/write access to the Facebook Graph and provides OAuth URLs and cookie validation for Facebook Connect sites; it also supports access-token based interaction with the old REST API. Koala 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", "lib/http_services.rb", "lib/koala.rb"]
13
- s.files = ["CHANGELOG", "Manifest", "Rakefile", "init.rb", "lib/http_services.rb", "lib/koala.rb", "readme.md", "test/facebook_data.yml", "test/koala/facebook_no_access_token_tests.rb", "test/koala/facebook_oauth_tests.rb", "test/koala/facebook_with_access_token_tests.rb", "test/koala_tests.rb", "koala.gemspec"]
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/graph_api.rb", "lib/http_services.rb", "lib/koala.rb", "lib/rest_api.rb"]
13
+ s.files = ["CHANGELOG", "Manifest", "Rakefile", "init.rb", "lib/graph_api.rb", "lib/http_services.rb", "lib/koala.rb", "lib/rest_api.rb", "readme.md", "spec/facebook_data.yml", "spec/koala/facebook_no_access_token_tests.rb", "spec/koala/facebook_oauth_tests.rb", "spec/koala/facebook_rest_api_no_access_token_test.rb", "spec/koala/facebook_rest_api_with_access_token_test.rb", "spec/koala/facebook_with_access_token_tests.rb", "spec/koala_spec.rb", "koala.gemspec"]
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"]
@@ -0,0 +1,126 @@
1
+ module Koala
2
+ module Facebook
3
+ GRAPH_SERVER = "graph.facebook.com"
4
+
5
+ module GraphAPIMethods
6
+ # A client for the Facebook Graph API.
7
+ #
8
+ # See http://developers.facebook.com/docs/api for complete documentation
9
+ # for the API.
10
+ #
11
+ # The Graph API is made up of the objects in Facebook (e.g., people, pages,
12
+ # events, photos) and the connections between them (e.g., friends,
13
+ # photo tags, and event RSVPs). This client provides access to those
14
+ # primitive types in a generic way. For example, given an OAuth access
15
+ # token, this will fetch the profile of the active user and the list
16
+ # of the user's friends:
17
+ #
18
+ # graph = Koala::Facebook::GraphAPI.new(access_token)
19
+ # user = graph.get_object("me")
20
+ # friends = graph.get_connections(user["id"], "friends")
21
+ #
22
+ # You can see a list of all of the objects and connections supported
23
+ # by the API at http://developers.facebook.com/docs/reference/api/.
24
+ #
25
+ # You can obtain an access token via OAuth or by using the Facebook
26
+ # JavaScript SDK. See http://developers.facebook.com/docs/authentication/
27
+ # for details.
28
+ #
29
+ # If you are using the JavaScript SDK, you can use the
30
+ # Koala::Facebook::OAuth.get_user_from_cookie() method below to get the OAuth access token
31
+ # for the active user from the cookie saved by the SDK.
32
+
33
+ def get_object(id, args = {})
34
+ # Fetchs the given object from the graph.
35
+ api(id, args)
36
+ end
37
+
38
+ def get_objects(ids, args = {})
39
+ # Fetchs all of the given object from the graph.
40
+ # We return a map from ID to object. If any of the IDs are invalid,
41
+ # we raise an exception.
42
+ api("", args.merge("ids" => ids.join(",")))
43
+ end
44
+
45
+ def get_connections(id, connection_name, args = {})
46
+ # Fetchs the connections for given object.
47
+ api("#{id}/#{connection_name}", args)
48
+ end
49
+
50
+ def put_object(parent_object, connection_name, args = {})
51
+ # Writes the given object to the graph, connected to the given parent.
52
+ #
53
+ # For example,
54
+ #
55
+ # graph.put_object("me", "feed", :message => "Hello, world")
56
+ #
57
+ # writes "Hello, world" to the active user's wall. Likewise, this
58
+ # will comment on a the first post of the active user's feed:
59
+ #
60
+ # feed = graph.get_connections("me", "feed")
61
+ # post = feed["data"][0]
62
+ # graph.put_object(post["id"], "comments", :message => "First!")
63
+ #
64
+ # See http://developers.facebook.com/docs/api#publishing for all of
65
+ # the supported writeable objects.
66
+ #
67
+ # Most write operations require extended permissions. For example,
68
+ # publishing wall posts requires the "publish_stream" permission. See
69
+ # http://developers.facebook.com/docs/authentication/ for details about
70
+ # extended permissions.
71
+
72
+ raise APIError.new({"type" => "KoalaMissingAccessToken", "message" => "Write operations require an access token"}) unless @access_token
73
+ api("#{parent_object}/#{connection_name}", args, "post")
74
+ end
75
+
76
+ def put_wall_post(message, attachment = {}, profile_id = "me")
77
+ # Writes a wall post to the given profile's wall.
78
+ #
79
+ # We default to writing to the authenticated user's wall if no
80
+ # profile_id is specified.
81
+ #
82
+ # attachment adds a structured attachment to the status message being
83
+ # posted to the Wall. It should be a dictionary of the form:
84
+ #
85
+ # {"name": "Link name"
86
+ # "link": "http://www.example.com/",
87
+ # "caption": "{*actor*} posted a new review",
88
+ # "description": "This is a longer description of the attachment",
89
+ # "picture": "http://www.example.com/thumbnail.jpg"}
90
+
91
+ self.put_object(profile_id, "feed", attachment.merge({:message => message}))
92
+ end
93
+
94
+ def put_comment(object_id, message)
95
+ # Writes the given comment on the given post.
96
+ self.put_object(object_id, "comments", {:message => message})
97
+ end
98
+
99
+ def put_like(object_id)
100
+ # Likes the given post.
101
+ self.put_object(object_id, "likes")
102
+ end
103
+
104
+ def delete_object(id)
105
+ # Deletes the object with the given ID from the graph.
106
+ api(id, {}, "delete")
107
+ end
108
+
109
+ def search(search_terms, args = {})
110
+ # Searches for a given term
111
+ api("search", args.merge({:q => search_terms}))
112
+ end
113
+
114
+ def api(*args)
115
+ response = super
116
+
117
+ # check for errors
118
+ if response.is_a?(Hash) && error_details = response["error"]
119
+ raise APIError.new(error_details)
120
+ end
121
+
122
+ response
123
+ end
124
+ end
125
+ end
126
+ end
@@ -6,14 +6,15 @@ module Koala
6
6
  require 'net/http' unless defined?(Net::HTTP)
7
7
  require 'net/https'
8
8
 
9
- def self.make_request(path, args, verb)
9
+ def self.make_request(path, args, verb, options = {})
10
10
  # We translate args to a valid query string. If post is specified,
11
11
  # we send a POST request to the given path with the given arguments.
12
12
 
13
13
  # if the verb isn't get or post, send it as a post argument
14
14
  args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"
15
15
 
16
- http = Net::HTTP.new(Facebook::GRAPH_SERVER, 443)
16
+ server = options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER
17
+ http = Net::HTTP.new(server, 443)
17
18
  http.use_ssl = true
18
19
  # we turn off certificate validation to avoid the
19
20
  # "warning: peer certificate won't be verified in this SSL session" warning
@@ -46,13 +47,14 @@ module Koala
46
47
  base.class_eval do
47
48
  require 'typhoeus' unless defined?(Typhoeus)
48
49
  include Typhoeus
49
-
50
- def self.make_request(path, args, verb)
50
+
51
+ def self.make_request(path, args, verb, options = {})
51
52
  # if the verb isn't get or post, send it as a post argument
52
53
  args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"
53
- self.send(verb, "https://#{Facebook::GRAPH_SERVER}/#{path}", :params => args).body
54
+ server = options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER
55
+ self.send(verb, "https://#{server}/#{path}", :params => args).body
54
56
  end
55
- end
57
+ end # class_eval
56
58
  end
57
59
  end
58
60
  end
@@ -8,6 +8,12 @@ require 'json'
8
8
  # include default http services
9
9
  require 'http_services'
10
10
 
11
+ # add Graph API methods
12
+ require 'graph_api'
13
+
14
+ # add REST API methods
15
+ require 'rest_api'
16
+
11
17
  module Koala
12
18
 
13
19
  module Facebook
@@ -32,151 +38,50 @@ module Koala
32
38
  # http://developers.facebook.com/docs/api. You can download the Facebook
33
39
  # JavaScript SDK at http://github.com/facebook/connect-js/.
34
40
 
35
- GRAPH_SERVER = "graph.facebook.com"
36
-
37
- class GraphAPI
38
- # A client for the Facebook Graph API.
39
- #
40
- # See http://developers.facebook.com/docs/api for complete documentation
41
- # for the API.
42
- #
43
- # The Graph API is made up of the objects in Facebook (e.g., people, pages,
44
- # events, photos) and the connections between them (e.g., friends,
45
- # photo tags, and event RSVPs). This client provides access to those
46
- # primitive types in a generic way. For example, given an OAuth access
47
- # token, this will fetch the profile of the active user and the list
48
- # of the user's friends:
49
- #
50
- # graph = Koala::Facebook::GraphAPI.new(access_token)
51
- # user = graph.get_object("me")
52
- # friends = graph.get_connections(user["id"], "friends")
53
- #
54
- # You can see a list of all of the objects and connections supported
55
- # by the API at http://developers.facebook.com/docs/reference/api/.
56
- #
57
- # You can obtain an access token via OAuth or by using the Facebook
58
- # JavaScript SDK. See http://developers.facebook.com/docs/authentication/
59
- # for details.
60
- #
61
- # If you are using the JavaScript SDK, you can use the
62
- # Koala::Facebook::OAuth.get_user_from_cookie() method below to get the OAuth access token
63
- # for the active user from the cookie saved by the SDK.
64
-
41
+ class API
65
42
  # initialize with an access token
66
43
  def initialize(access_token = nil)
67
44
  @access_token = access_token
68
45
  end
69
-
70
- def get_object(id, args = {})
71
- # Fetchs the given object from the graph.
72
- api(id, args)
73
- end
74
-
75
- def get_objects(ids, args = {})
76
- # Fetchs all of the given object from the graph.
77
- # We return a map from ID to object. If any of the IDs are invalid,
78
- # we raise an exception.
79
- api("", args.merge("ids" => ids.join(",")))
80
- end
81
-
82
- def get_connections(id, connection_name, args = {})
83
- # Fetchs the connections for given object.
84
- api("#{id}/#{connection_name}", args)
85
- end
86
-
87
- def put_object(parent_object, connection_name, args = {})
88
- # Writes the given object to the graph, connected to the given parent.
89
- #
90
- # For example,
91
- #
92
- # graph.put_object("me", "feed", :message => "Hello, world")
93
- #
94
- # writes "Hello, world" to the active user's wall. Likewise, this
95
- # will comment on a the first post of the active user's feed:
96
- #
97
- # feed = graph.get_connections("me", "feed")
98
- # post = feed["data"][0]
99
- # graph.put_object(post["id"], "comments", :message => "First!")
100
- #
101
- # See http://developers.facebook.com/docs/api#publishing for all of
102
- # the supported writeable objects.
103
- #
104
- # Most write operations require extended permissions. For example,
105
- # publishing wall posts requires the "publish_stream" permission. See
106
- # http://developers.facebook.com/docs/authentication/ for details about
107
- # extended permissions.
108
-
109
- raise GraphAPIError.new({"type" => "KoalaMissingAccessToken", "message" => "Write operations require an access token"}) unless @access_token
110
- api("#{parent_object}/#{connection_name}", args, "post")
111
- end
112
-
113
- def put_wall_post(message, attachment = {}, profile_id = "me")
114
- # Writes a wall post to the given profile's wall.
115
- #
116
- # We default to writing to the authenticated user's wall if no
117
- # profile_id is specified.
118
- #
119
- # attachment adds a structured attachment to the status message being
120
- # posted to the Wall. It should be a dictionary of the form:
121
- #
122
- # {"name": "Link name"
123
- # "link": "http://www.example.com/",
124
- # "caption": "{*actor*} posted a new review",
125
- # "description": "This is a longer description of the attachment",
126
- # "picture": "http://www.example.com/thumbnail.jpg"}
127
-
128
- self.put_object(profile_id, "feed", attachment.merge({:message => message}))
129
- end
130
-
131
- def put_comment(object_id, message)
132
- # Writes the given comment on the given post.
133
- self.put_object(object_id, "comments", {:message => message})
134
- end
135
-
136
- def put_like(object_id)
137
- # Likes the given post.
138
- self.put_object(object_id, "likes")
139
- end
140
-
141
- def delete_object(id)
142
- # Deletes the object with the given ID from the graph.
143
- api(id, {}, "delete")
144
- end
145
-
146
- def search(search_terms, args = {})
147
- # Searches for a given term
148
- api("search", args.merge({:q => search_terms}))
149
- end
150
-
151
- def api(path, args = {}, verb = "get")
46
+
47
+ def api(path, args = {}, verb = "get", options = {})
152
48
  # Fetches the given path in the Graph API.
153
49
  args["access_token"] = @access_token if @access_token
154
50
 
155
51
  # make the request via the provided service
156
- result = Koala.make_request(path, args, verb)
52
+ result = Koala.make_request(path, args, verb, options)
157
53
 
158
54
  # Facebook sometimes sends results like "true" and "false", which aren't strictly object
159
55
  # and cause JSON.parse to fail
160
56
  # so we account for that
161
57
  response = JSON.parse("[#{result}]")[0]
162
58
 
163
- # check for errors
164
- if response.is_a?(Hash) && error_details = response["error"]
165
- raise GraphAPIError.new(error_details)
166
- end
167
-
168
59
  response
169
60
  end
170
61
  end
171
-
172
- class GraphAPIError < Exception
62
+
63
+ class GraphAPI < API
64
+ include GraphAPIMethods
65
+ end
66
+
67
+ class RestAPI < API
68
+ include RestAPIMethods
69
+ end
70
+
71
+ class GraphAndRestAPI < API
72
+ include GraphAPIMethods
73
+ include RestAPIMethods
74
+ end
75
+
76
+ class APIError < Exception
173
77
  attr_accessor :fb_error_type
174
78
  def initialize(details = {})
175
79
  self.fb_error_type = details["type"]
176
80
  super("#{fb_error_type}: #{details["message"]}")
177
81
  end
178
82
  end
179
-
83
+
84
+
180
85
  class OAuth
181
86
  attr_accessor :app_id, :app_secret, :oauth_callback_url
182
87
  def initialize(app_id, app_secret, oauth_callback_url = nil)
@@ -260,7 +165,7 @@ module Koala
260
165
  result = fetch_token_string(code)
261
166
 
262
167
  # if we have an error, parse the error JSON and raise an error
263
- raise GraphAPIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/
168
+ raise APIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/
264
169
  # otherwise, parse the access token
265
170
  parse_access_token(result)
266
171
  end
@@ -280,4 +185,4 @@ module Koala
280
185
  rescue LoadError
281
186
  Koala.http_service = NetHTTPService
282
187
  end
283
- end
188
+ end
@@ -0,0 +1,28 @@
1
+ module Koala
2
+ module Facebook
3
+ REST_SERVER = "api.facebook.com"
4
+
5
+ module RestAPIMethods
6
+ def fql_query(fql)
7
+ args = {
8
+ "query" => fql,
9
+ "format" => "json",
10
+ }
11
+
12
+ api('method/fql.query', args, 'get', :rest_api => true)
13
+ end
14
+
15
+ def api(*args)
16
+ response = super
17
+
18
+ # check for REST API-specific errors
19
+ if response.is_a?(Hash) && response["error_code"]
20
+ raise APIError.new("type" => response["error_code"], "message" => response["error_msg"])
21
+ end
22
+
23
+ response
24
+ end
25
+ end
26
+
27
+ end # module Facebook
28
+ end # module Koala
data/readme.md CHANGED
@@ -18,9 +18,19 @@ If you're using Koala within a web application with the Facebook
18
18
  [JavaScript SDK](http://github.com/facebook/connect-js), you can use the Koala::Facebook::OAuth class
19
19
  to parse the cookies set by the JavaScript SDK for logged in users.
20
20
 
21
+ FQL and the old-school REST API
22
+ -----
23
+ 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 -- including fql.query -- that can't yet be done via the Graph.
24
+
25
+ Koala now supports the old-school REST API using OAuth access tokens; to use this, instantiate your class using the GraphAndRestAPI class:
26
+
27
+ api = Koala::Facebook::GraphAndRestAPI.new(oauth_access_token)
28
+
29
+ The GraphAndRestAPI class provides access to all the Graph API methods, as well as an fql method that you can use to make FQL calls. (You can pass the :rest\_api => true option to the api method to make REST API calls; check out lib/rest\_api.rb to see how it's done.) We reserve the right to expand the built-in REST API coverage to additional methods in the future, depending on how fast Facebook moves to fill in the gaps.
30
+
21
31
  Examples and More Details
22
32
  -----
23
- There's a very detailed description and walkthrough of Koala at <a href="http://blog.twoalex.com/2010/05/03/introducing-koala-a-new-gem-for-facebooks-new-graph-api/">http://blog.twoalex.com/2010/05/03/introducing-koala-a-new-gem-for-facebooks-new-graph-api/</a>.
33
+ Complete Koala documentation can now be found <a href="http://wiki.github.com/arsduo/koala/">on the wiki</a>!
24
34
 
25
35
  You can easily generate OAuth access tokens and any other data needed to play with the Graph API or OAuth at the Koala-powered <a href="http://oauth.twoalex.com" target="_blank">OAuth Playground</a>.
26
36
 
@@ -28,17 +38,15 @@ You can easily generate OAuth access tokens and any other data needed to play wi
28
38
  Testing
29
39
  -----
30
40
 
31
- Unit tests are provided for Graph API methods. However, because the Graph API uses access tokens, which expire, you have to provide your own token with stream publishing permissions for the tests. Insert the token value into the file test/facebook_data.yml, then run the test as follows:
41
+ Unit tests are provided for all of Koala's methods; however, because the OAuth access tokens and cookies expire, 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. (The file also provides valid values for other tests, which you're welcome to sub out for data specific to your own application.)
42
+
43
+ Insert the required values into the file test/facebook_data.yml, then run the test as follows:
32
44
  spec koala_tests.rb
33
45
 
34
- Unit tests for cookie validation and other methods in the OAuth class will be provided shortly. (You'll also need to add that information into the yml.)
35
-
36
46
 
37
47
  Coming Soon
38
48
  -----
39
- 1. OAuth class methods to parse the results of the access token call
40
- 2. OAuth class method to directly fetch the access token when given a code value
41
-
49
+ * Support for real-time updates
42
50
 
43
51
  Known Issues
44
52
  -----
@@ -1,19 +1,17 @@
1
- # Check out http://oauth.twoalex.com to easily generate tokens, cookies, etc.
1
+ # Check out http://oauth.twoalex.com/ to easily generate tokens, cookies, etc.
2
2
  # Those values will work with the default settings in this yaml.
3
3
  # Of course, you can change this to work with your own app.
4
4
  # Just remember to update all fields!
5
-
6
- # for testing the GraphAPI class
7
- # OAuth token should have publish_stream and read_stream permissions
8
- oauth_token: 119908831367602|2.8VK0rWWLe3y4L8JfrpBupA__.3600.1273370400-2905623|u-QAARJz9UeZrF6ef2qu-Fk4UH0.
5
+
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:
9
9
 
10
10
  # for testing the OAuth class
11
11
  # baseline app
12
- oauth_test_data:
13
- # You must supply these values yourself, since they will expire.
14
- valid_cookies: # note: the tests stub the time class so these default cookies are always valid
15
- fbs_119908831367602: '"access_token=119908831367602|2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623|CMpi0AYbn03Oukzv94AUha2qbO4.&expires=1273363200&secret=lT_9zm5r5IbJ6Aa5O54nFw__&session_key=2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623&sig=9515e93113921f9476a4efbdd4a3c746&uid=2905623"'
16
- code: 2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|vdiZmnxKxh4WVSnxBxoEvcBfamU.
12
+ oauth_test_data:
13
+ # You must supply this value yourself, since they will expire.
14
+ code:
17
15
 
18
16
  # These values will work out of the box
19
17
  app_id: 119908831367602
@@ -21,6 +19,10 @@ oauth_test_data:
21
19
  callback_url: http://oauth.twoalex.com/
22
20
  raw_token_string: "access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.&expires=6621"
23
21
  raw_offline_access_token_string: access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.
22
+ valid_cookies:
23
+ # note: the tests stub the time class so these default cookies are always valid (if you're using the default app)
24
+ # if not you may want to remove the stubbing to test expiration
25
+ fbs_119908831367602: '"access_token=119908831367602|2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623|CMpi0AYbn03Oukzv94AUha2qbO4.&expires=1273363200&secret=lT_9zm5r5IbJ6Aa5O54nFw__&session_key=2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623&sig=9515e93113921f9476a4efbdd4a3c746&uid=2905623"'
24
26
  expired_cookies:
25
27
  fbs_119908831367602: '"access_token=119908831367602|2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623|yVt5WH_S6J5p3gFa5_5lBzckhws.&expires=1273287600&secret=V_E79ovQnXqxGctFuC_n5A__&session_key=2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623&sig=eeef60838c0c800258d89b7e6ddddddb&uid=2905623"'
26
28
  offline_access_cookies:
@@ -25,12 +25,7 @@ class FacebookNoAccessTokenTests < Test::Unit::TestCase
25
25
  end
26
26
 
27
27
  it "should not be able to get data about 'me'" do
28
- begin
29
- @graph.get_object("me")
30
- rescue Koala::Facebook::GraphAPIError => @right_err
31
- rescue Exception => wrong_err
32
- end
33
- @right_err.should_not be_nil
28
+ lambda { @graph.get_object("me") }.should raise_error(Koala::Facebook::APIError)
34
29
  end
35
30
 
36
31
  it "should be able to get multiple objects" do
@@ -39,12 +34,7 @@ class FacebookNoAccessTokenTests < Test::Unit::TestCase
39
34
  end
40
35
 
41
36
  it "shouldn't be able to access connections from users" do
42
- begin
43
- @graph.get_connections("lukeshepard", "likes")
44
- rescue Koala::Facebook::GraphAPIError => @right_err
45
- rescue Exception => wrong_err
46
- end
47
- @right_err.should_not be_nil
37
+ lambda { @graph.get_connections("lukeshepard", "likes") }.should raise_error(Koala::Facebook::APIError)
48
38
  end
49
39
 
50
40
  it "should be able to access connections from public Pages" do
@@ -53,53 +43,34 @@ class FacebookNoAccessTokenTests < Test::Unit::TestCase
53
43
  end
54
44
 
55
45
  it "should not be able to put an object" do
56
- begin
57
- @result = @graph.put_object("lukeshepard", "feed", :message => "Hello, world")
58
- rescue Koala::Facebook::GraphAPIError => @right_err
59
- rescue Exception => wrong_err
60
- end
61
- @right_err.should_not be_nil
46
+ lambda { @result = @graph.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
47
+ puts "Error! Object #{@result.inspect} somehow put onto Luke Shepard's wall!" if @result
62
48
  end
63
49
 
64
50
  # these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
65
51
  it "should not be able to post to a feed" do
66
- begin
67
- @result = @graph.put_wall_post("Hello, world", {:name => "Context Optional", :link => "http://www.contextoptional.com/"}, "contextoptional")
68
- rescue Koala::Facebook::GraphAPIError => @right_err
69
- rescue Exception => wrong_err
70
- end
71
- @right_err.should_not be_nil
52
+ (lambda do
53
+ attachment = {:name => "Context Optional", :link => "http://www.contextoptional.com/"}
54
+ @result = @graph.put_wall_post("Hello, world", attachment, "contextoptional")
55
+ end).should raise_error(Koala::Facebook::APIError)
56
+ puts "Error! Object #{@result.inspect} somehow put onto Context Optional's wall!" if @result
72
57
  end
73
58
 
74
59
  it "should not be able to comment on an object" do
75
- begin
76
- # random public post on the ContextOptional wall
77
- @result = @graph.put_comment("7204941866_119776748033392", "The hackathon was great!")
78
- rescue Koala::Facebook::GraphAPIError => @right_err
79
- rescue Exception => wrong_err
80
- end
81
- @right_err.should_not be_nil
60
+ # random public post on the ContextOptional wall
61
+ lambda { @result = @graph.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
62
+ puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
82
63
  end
83
64
 
84
65
  it "should not be able to like an object" do
85
- begin
86
- @result = @graph.put_like("7204941866_119776748033392")
87
- rescue Koala::Facebook::GraphAPIError => @right_err
88
- rescue Exception => wrong_err
89
- end
90
- @right_err.should_not be_nil
66
+ lambda { @graph.put_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
91
67
  end
92
68
 
93
69
 
94
70
  # DELETE
95
71
  it "should not be able to delete posts" do
96
- begin
97
- # test post on the Ruby SDK Test application
98
- @result = @graph.delete_object("115349521819193_113815981982767")
99
- rescue Koala::Facebook::GraphAPIError => @right_err
100
- rescue Exception => wrong_err
101
- end
102
- @right_err.should_not be_nil
72
+ # test post on the Ruby SDK Test application
73
+ lambda { @result = @graph.delete_object("115349521819193_113815981982767") }.should raise_error(Koala::Facebook::APIError)
103
74
  end
104
75
 
105
76
  # SEARCH
@@ -123,13 +123,7 @@ class FacebookOAuthTests < Test::Unit::TestCase
123
123
 
124
124
  it "should raise an exception if no callback is given in initialization or the call" do
125
125
  oauth2 = Koala::Facebook::OAuth.new(@app_id, @secret)
126
- begin
127
- url = oauth2.url_for_oauth_code
128
- rescue ArgumentError => @right_err
129
- rescue
130
- end
131
-
132
- @right_err.should
126
+ lambda { oauth2.url_for_oauth_code }.should raise_error(ArgumentError)
133
127
  end
134
128
 
135
129
  # url_for_access_token
@@ -190,12 +184,7 @@ class FacebookOAuthTests < Test::Unit::TestCase
190
184
  end
191
185
 
192
186
  it "should raise an error when get_access_token is called with a bad code" do
193
- begin
194
- result = @oauth.get_access_token("foo")
195
- rescue Koala::Facebook::GraphAPIError => @right_err
196
- rescue
197
- end
198
- @right_err.should
187
+ lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
199
188
  end
200
189
  end # describe
201
190
 
@@ -0,0 +1,20 @@
1
+ class FacebookRestAPINoAccessTokenTest < Test::Unit::TestCase
2
+
3
+ describe "Koala RestAPI without an access token" do
4
+ before :each do
5
+ @graph = Koala::Facebook::RestAPI.new
6
+ end
7
+
8
+ # FQL
9
+ it "should be able to access public information via FQL" do
10
+ @result = @graph.fql_query('select first_name from user where uid = 216743')
11
+ @result.size.should == 1
12
+ @result.first['first_name'].should == 'Chris'
13
+ end
14
+
15
+ it "should not be able to access protected information via FQL" do
16
+ lambda { @graph.fql_query("select read_stream from permissions where uid = 216743") }.should raise_error(Koala::Facebook::APIError)
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,33 @@
1
+ class FacebookRestAPIWithAccessTokenTests < Test::Unit::TestCase
2
+ describe "Koala RestAPI with an access token" do
3
+ before :each do
4
+ @token = $testing_data["oauth_token"]
5
+ raise Exception, "Must supply access token to run FacebookRestAPIWithAccessTokenTests!" unless @token
6
+ @rest = Koala::Facebook::RestAPI.new(@token)
7
+ end
8
+
9
+ # FQL
10
+ it "should be able to access public information via FQL" do
11
+ result = @rest.fql_query('select first_name from user where uid = 216743')
12
+ result.size.should == 1
13
+ result.first['first_name'].should == 'Chris'
14
+ end
15
+
16
+ it "should be able to access protected information via FQL" do
17
+ # Tests agains the permissions fql table
18
+
19
+ # get the current user's ID
20
+ # we're sneakily using the Graph API, which should be okay since it has its own tests
21
+ g = Koala::Facebook::GraphAPI.new(@token)
22
+ id = g.get_object("me", :fields => "id")["id"]
23
+
24
+ # now send a query about your permissions
25
+ result = @rest.fql_query("select read_stream from permissions where uid = #{id}")
26
+
27
+ result.size.should == 1
28
+ # we assume that you have read_stream permissions, so we can test against that
29
+ # (should we keep this?)
30
+ result.first["read_stream"].should == 1
31
+ end
32
+ end
33
+ end
@@ -9,6 +9,8 @@ require 'koala'
9
9
  require 'koala/facebook_no_access_token_tests'
10
10
  require 'koala/facebook_with_access_token_tests'
11
11
  require 'koala/facebook_oauth_tests'
12
+ require 'koala/facebook_rest_api_with_access_token_test'
13
+ require 'koala/facebook_rest_api_no_access_token_test'
12
14
 
13
15
  class FacebookTestSuite
14
16
  def self.suite
@@ -16,6 +18,8 @@ class FacebookTestSuite
16
18
  suite << FacebookNoAccessTokenTests.suite
17
19
  suite << FacebookWithAccessTokenTests.suite
18
20
  suite << FacebookOAuthTests.suite
21
+ suite << FacebookRestAPIWithAccessTokenTests.suite
22
+ suite << FacebookRestAPINoAccessTokenTest.suite
19
23
  suite
20
24
  end
21
25
  end
@@ -29,7 +33,6 @@ unless $testing_data["oauth_token"]
29
33
  puts "Access token tests will fail until you store a valid token in facebook_data.yml"
30
34
  end
31
35
 
32
- # TODO finish tests for OAuth class
33
- # unless $testing_data["cookie_hash"] && $testing_data["app_id"] && $testing_data["secret"]
34
- # puts "Cookie tests will fail until you store valid data for the cookie hash, app_id, and app secret in facebook_data.yml"
35
- # end
36
+ unless $testing_data["oauth_test_data"] && $testing_data["oauth_test_data"]["code"] && $testing_data["oauth_test_data"]["secret"]
37
+ puts "Cookie tests will fail until you store valid data for the cookie hash, app_id, and app secret in facebook_data.yml"
38
+ end
metadata CHANGED
@@ -4,21 +4,21 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
7
+ - 6
8
8
  - 0
9
- version: 0.5.0
9
+ version: 0.6.0
10
10
  platform: ruby
11
11
  authors:
12
- - Alex Koppel, Rafi Jacoby, Context Optional
12
+ - Alex Koppel, Chris Baclig, Rafi Jacoby, Context Optional
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-08 00:00:00 -07:00
17
+ date: 2010-05-17 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
21
- description: Koala is a lightweight, flexible Ruby SDK for Facebook's new Graph API. It allows read/write access to the Facebook Graph and provides OAuth URLs and cookie validation for Facebook Connect sites. Koala supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.
21
+ description: Koala is a lightweight, flexible Ruby SDK for Facebook's new Graph API. It allows read/write access to the Facebook Graph and provides OAuth URLs and cookie validation for Facebook Connect sites; it also supports access-token based interaction with the old REST API. Koala supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.
22
22
  email: alex@alexkoppel.com
23
23
  executables: []
24
24
 
@@ -26,21 +26,27 @@ extensions: []
26
26
 
27
27
  extra_rdoc_files:
28
28
  - CHANGELOG
29
+ - lib/graph_api.rb
29
30
  - lib/http_services.rb
30
31
  - lib/koala.rb
32
+ - lib/rest_api.rb
31
33
  files:
32
34
  - CHANGELOG
33
35
  - Manifest
34
36
  - Rakefile
35
37
  - init.rb
38
+ - lib/graph_api.rb
36
39
  - lib/http_services.rb
37
40
  - lib/koala.rb
41
+ - lib/rest_api.rb
38
42
  - readme.md
39
- - test/facebook_data.yml
40
- - test/koala/facebook_no_access_token_tests.rb
41
- - test/koala/facebook_oauth_tests.rb
42
- - test/koala/facebook_with_access_token_tests.rb
43
- - test/koala_tests.rb
43
+ - spec/facebook_data.yml
44
+ - spec/koala/facebook_no_access_token_tests.rb
45
+ - spec/koala/facebook_oauth_tests.rb
46
+ - spec/koala/facebook_rest_api_no_access_token_test.rb
47
+ - spec/koala/facebook_rest_api_with_access_token_test.rb
48
+ - spec/koala/facebook_with_access_token_tests.rb
49
+ - spec/koala_spec.rb
44
50
  - koala.gemspec
45
51
  has_rdoc: true
46
52
  homepage: http://github.com/arsduo/koala