koala 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ v0.5.0
2
+ -- Added several new OAuth methods for making and parsing access token requests
3
+ -- Added test suite for the OAuth class
4
+ -- Made second argument to url_for_access_token a hash (strings still work but trigger a deprecation warning)
5
+ -- Added fields to facebook_data.yml
6
+ -- Updated readme
7
+
1
8
  v0.4.1
2
9
  -- Encapsulated GraphAPI and OAuth classes in the Koala::Facebook module for clarity (and to avoid claiming the global Facebook class)
3
10
  -- Moved make_request method to Koala class from GraphAPI instance (for use by future OAuth class functionality)
data/Manifest CHANGED
@@ -2,11 +2,11 @@ CHANGELOG
2
2
  Manifest
3
3
  Rakefile
4
4
  init.rb
5
- koala.gemspec
6
5
  lib/http_services.rb
7
6
  lib/koala.rb
8
7
  readme.md
9
8
  test/facebook_data.yml
10
9
  test/koala/facebook_no_access_token_tests.rb
10
+ test/koala/facebook_oauth_tests.rb
11
11
  test/koala/facebook_with_access_token_tests.rb
12
12
  test/koala_tests.rb
data/Rakefile CHANGED
@@ -4,10 +4,10 @@ require 'rake'
4
4
  require 'echoe'
5
5
 
6
6
  # gem management
7
- Echoe.new('koala', '0.4.1') do |p|
7
+ Echoe.new('koala', '0.5.0') do |p|
8
8
  p.summary = "A lightweight, flexible library for Facebook's new Graph API"
9
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."
10
- p.url = "http://github.com/arsduo/ruby-sdk"
10
+ p.url = "http://github.com/arsduo/koala"
11
11
  p.author = ["Alex Koppel", "Rafi Jacoby", "Context Optional"]
12
12
  p.email = "alex@alexkoppel.com"
13
13
  p.ignore_pattern = ["tmp/*", "script/*", "pkg/*"]
data/init.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  # init.rb
2
- require 'facebook_graph'
2
+ require 'koala'
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{koala}
5
- s.version = "0.4.1"
5
+ s.version = "0.5.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, Rafi Jacoby, Context Optional"]
9
- s.date = %q{2010-05-03}
9
+ s.date = %q{2010-05-08}
10
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.}
11
11
  s.email = %q{alex@alexkoppel.com}
12
12
  s.extra_rdoc_files = ["CHANGELOG", "lib/http_services.rb", "lib/koala.rb"]
13
- s.files = ["CHANGELOG", "Manifest", "Rakefile", "init.rb", "koala.gemspec", "lib/http_services.rb", "lib/koala.rb", "readme.md", "test/facebook_data.yml", "test/koala/facebook_no_access_token_tests.rb", "test/koala/facebook_with_access_token_tests.rb", "test/koala_tests.rb"]
14
- s.homepage = %q{http://github.com/arsduo/ruby-sdk}
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"]
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"]
17
17
  s.rubyforge_project = %q{koala}
@@ -46,7 +46,7 @@ module Koala
46
46
  base.class_eval do
47
47
  require 'typhoeus' unless defined?(Typhoeus)
48
48
  include Typhoeus
49
-
49
+
50
50
  def self.make_request(path, args, verb)
51
51
  # if the verb isn't get or post, send it as a post argument
52
52
  args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"
@@ -106,7 +106,7 @@ module Koala
106
106
  # http://developers.facebook.com/docs/authentication/ for details about
107
107
  # extended permissions.
108
108
 
109
- raise GraphAPIError.new(nil, "Write operations require an access token") unless @access_token
109
+ raise GraphAPIError.new({"type" => "KoalaMissingAccessToken", "message" => "Write operations require an access token"}) unless @access_token
110
110
  api("#{parent_object}/#{connection_name}", args, "post")
111
111
  end
112
112
 
@@ -161,8 +161,8 @@ module Koala
161
161
  response = JSON.parse("[#{result}]")[0]
162
162
 
163
163
  # check for errors
164
- if response.is_a?(Hash) && error = response["error"]
165
- raise GraphAPIError.new(error["code"], error["message"])
164
+ if response.is_a?(Hash) && error_details = response["error"]
165
+ raise GraphAPIError.new(error_details)
166
166
  end
167
167
 
168
168
  response
@@ -170,14 +170,15 @@ module Koala
170
170
  end
171
171
 
172
172
  class GraphAPIError < Exception
173
- attr_accessor :code
174
- def initialize(code, message)
175
- super(message)
176
- self.code = code
173
+ attr_accessor :fb_error_type
174
+ def initialize(details = {})
175
+ self.fb_error_type = details["type"]
176
+ super("#{fb_error_type}: #{details["message"]}")
177
177
  end
178
178
  end
179
179
 
180
- class OAuth
180
+ class OAuth
181
+ attr_accessor :app_id, :app_secret, :oauth_callback_url
181
182
  def initialize(app_id, app_secret, oauth_callback_url = nil)
182
183
  @app_id = app_id
183
184
  @app_secret = app_secret
@@ -207,12 +208,13 @@ module Koala
207
208
  components = {}
208
209
  fb_cookie.split("&").map {|param| param = param.split("="); components[param[0]] = param[1]}
209
210
 
211
+ # generate the signature and make sure it matches what we expect
210
212
  auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
211
- sig = Digest::MD5.hexdigest(auth_string + @app_secret)
212
-
213
- sig == components["sig"] && (components["expires"].to_i == 0 || Time.now.to_i < components["expires"].to_i) ? components : nil
213
+ sig = Digest::MD5.hexdigest(auth_string + @app_secret)
214
+ sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
214
215
  end
215
216
  end
217
+ alias_method :get_user_from_cookies, :get_user_from_cookie
216
218
 
217
219
  def url_for_oauth_code(options = {})
218
220
  # for permissions, see http://developers.facebook.com/docs/authentication/permissions
@@ -220,15 +222,48 @@ module Koala
220
222
  scope = permissions ? "&scope=#{permissions.is_a?(Array) ? permissions.join(",") : permissions}" : ""
221
223
 
222
224
  callback = options[:callback] || @oauth_callback_url
225
+ raise ArgumentError, "url_for_oauth_code must get a callback either from the OAuth object or in the options!" unless callback
223
226
 
224
227
  # Creates the URL for oauth authorization for a given callback and optional set of permissions
225
228
  "https://#{GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}#{scope}"
226
229
  end
227
230
 
228
- def url_for_access_token(code, callback = @oauth_callback_url)
231
+ def url_for_access_token(code, options = {})
229
232
  # Creates the URL for the token corresponding to a given code generated by Facebook
233
+ if options.is_a?(String) # changing the arguments
234
+ puts "Deprecation warning: url_for_access_token now takes an options hash as the second argument; pass the callback as :callback."
235
+ options = {:callback => options}
236
+ end
237
+ callback = options[:callback] || @oauth_callback_url
238
+ raise ArgumentError, "url_for_access_token must get a callback either from the OAuth object or in the parameters!" unless callback
230
239
  "https://#{GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@app_secret}&code=#{code}"
231
240
  end
241
+
242
+ def parse_access_token(response_text)
243
+ components = response_text.split("&").inject({}) do |hash, bit|
244
+ key, value = bit.split("=")
245
+ hash.merge!(key => value)
246
+ end
247
+ components
248
+ end
249
+
250
+ def fetch_token_string(code)
251
+ Koala.make_request("oauth/access_token", {
252
+ :client_id => @app_id,
253
+ :redirect_uri => @oauth_callback_url,
254
+ :client_secret => @app_secret,
255
+ :code => code
256
+ }, "get")
257
+ end
258
+
259
+ def get_access_token(code)
260
+ result = fetch_token_string(code)
261
+
262
+ # 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/
264
+ # otherwise, parse the access token
265
+ parse_access_token(result)
266
+ end
232
267
  end
233
268
  end
234
269
 
data/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  Koala
2
2
  ====
3
- Koala (<a href="http://github.com/arsduo/ruby-sdk" target="_blank">http://github.com/arsduo/ruby-sdk</a>) is a new Facebook Graph library for Ruby. 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 Graph library for Ruby. We wrote Koala with four goals:
4
4
 
5
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 300 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:
@@ -20,7 +20,9 @@ to parse the cookies set by the JavaScript SDK for logged in users.
20
20
 
21
21
  Examples and More Details
22
22
  -----
23
- There's a very detailed description and walkthrough of Koala at http://blog.twoalex.com/2010/05/03/introducing-koala-a-new-gem-for-facebooks-new-graph-api/.
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>.
24
+
25
+ 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>.
24
26
 
25
27
 
26
28
  Testing
@@ -1,9 +1,28 @@
1
- # for testing the GraphAPI classs
2
- # OAuth token should have stream_publish permissions
3
- oauth_token:
1
+ # Check out http://oauth.twoalex.com to easily generate tokens, cookies, etc.
2
+ # Those values will work with the default settings in this yaml.
3
+ # Of course, you can change this to work with your own app.
4
+ # Just remember to update all fields!
4
5
 
5
- # for testing the OAuth class
6
- app_id:
7
- secret:
8
- callback_url:
9
- cookie_hash:
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.
9
+
10
+ # for testing the OAuth class
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.
17
+
18
+ # These values will work out of the box
19
+ app_id: 119908831367602
20
+ secret: e45e55a333eec232d4206d2703de1307
21
+ callback_url: http://oauth.twoalex.com/
22
+ raw_token_string: "access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.&expires=6621"
23
+ raw_offline_access_token_string: access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.
24
+ expired_cookies:
25
+ 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
+ offline_access_cookies:
27
+ # note: I've revoked the offline access for security reasons, so you can't make calls against this :)
28
+ fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
@@ -0,0 +1,202 @@
1
+ # stub the Time class to always return a time for which the valid cookie is still valid
2
+ class Time
3
+ def self.now
4
+ self
5
+ end
6
+
7
+ def self.to_i
8
+ 1273363199
9
+ end
10
+ end
11
+
12
+ class FacebookOAuthTests < Test::Unit::TestCase
13
+ describe "Koala GraphAPI without an access token" do
14
+ before :each do
15
+ # make the relevant test data easily accessible
16
+ @oauth_data = $testing_data["oauth_test_data"]
17
+ @app_id = @oauth_data["app_id"]
18
+ @secret = @oauth_data["secret"]
19
+ @code = @oauth_data["code"]
20
+ @callback_url = @oauth_data["callback_url"]
21
+ @raw_token_string = @oauth_data["raw_token_string"]
22
+ @raw_offline_access_token_string = @oauth_data["raw_offline_access_token_string"]
23
+
24
+ # this should expanded to cover all variables
25
+ raise Exception, "Must supply app data to run FacebookOAuthTests!" unless @app_id && @secret && @callback_url &&
26
+ @code && @raw_token_string &&
27
+ @raw_offline_access_token_string
28
+
29
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret, @callback_url)
30
+ end
31
+
32
+ # initialization
33
+ it "should properly initialize" do
34
+ @oauth.should
35
+ end
36
+
37
+ it "should properly set attributes" do
38
+ (@oauth.app_id == @app_id &&
39
+ @oauth.app_secret == @secret &&
40
+ @oauth.oauth_callback_url == @callback_url).should be_true
41
+ end
42
+
43
+ it "should properly initialize without a callback_url" do
44
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
45
+ end
46
+
47
+ it "should properly set attributes without a callback URL" do
48
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
49
+ (@oauth.app_id == @app_id &&
50
+ @oauth.app_secret == @secret &&
51
+ @oauth.oauth_callback_url == nil).should be_true
52
+ end
53
+
54
+ # cookie parsing
55
+ it "should properly parse valid cookies" do
56
+ result = @oauth.get_user_from_cookie(@oauth_data["valid_cookies"])
57
+ result["uid"].should
58
+ end
59
+
60
+ it "should return all the cookie components from valid cookie string" do
61
+ cookie_data = @oauth_data["valid_cookies"]
62
+ parsing_results = @oauth.get_user_from_cookie(cookie_data)
63
+ number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
64
+ parsing_results.length.should == number_of_components
65
+ end
66
+
67
+ it "should properly parse valid offline access cookies (e.g. no expiration)" do
68
+ result = @oauth.get_user_from_cookie(@oauth_data["offline_access_cookies"])
69
+ result["uid"].should
70
+ end
71
+
72
+ it "should return all the cookie components from offline access cookies" do
73
+ cookie_data = @oauth_data["offline_access_cookies"]
74
+ parsing_results = @oauth.get_user_from_cookie(cookie_data)
75
+ number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
76
+ parsing_results.length.should == number_of_components
77
+ end
78
+
79
+ it "shouldn't parse expired cookies" do
80
+ result = @oauth.get_user_from_cookie(@oauth_data["expired_cookies"])
81
+ result.should be_nil
82
+ end
83
+
84
+ it "shouldn't parse invalid cookies" do
85
+ # make an invalid string by replacing some values
86
+ bad_cookie_hash = @oauth_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
87
+ result = @oauth.get_user_from_cookie(bad_cookie_hash)
88
+ result.should be_nil
89
+ end
90
+
91
+ # OAuth URLs
92
+
93
+ # url_for_oauth_code
94
+ it "should generate a properly formatted OAuth code URL with the default values" do
95
+ url = @oauth.url_for_oauth_code
96
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}"
97
+ end
98
+
99
+ it "should generate a properly formatted OAuth code URL when a callback is given" do
100
+ callback = "foo.com"
101
+ url = @oauth.url_for_oauth_code(:callback => callback)
102
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}"
103
+ end
104
+
105
+ it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
106
+ permissions = "publish_stream,read_stream"
107
+ url = @oauth.url_for_oauth_code(:permissions => permissions)
108
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions}"
109
+ end
110
+
111
+ it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
112
+ permissions = ["publish_stream", "read_stream"]
113
+ url = @oauth.url_for_oauth_code(:permissions => permissions)
114
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions.join(",")}"
115
+ end
116
+
117
+ it "should generate a properly formatted OAuth code URL when both permissions and callback are provided" do
118
+ permissions = "publish_stream,read_stream"
119
+ callback = "foo.com"
120
+ url = @oauth.url_for_oauth_code(:callback => callback, :permissions => permissions)
121
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}&scope=#{permissions}"
122
+ end
123
+
124
+ it "should raise an exception if no callback is given in initialization or the call" do
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
133
+ end
134
+
135
+ # url_for_access_token
136
+ it "should generate a properly formatted OAuth token URL when provided a code" do
137
+ url = @oauth.url_for_access_token(@code)
138
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{@callback_url}&client_secret=#{@secret}&code=#{@code}"
139
+ end
140
+
141
+ it "should generate a properly formatted OAuth token URL when provided a callback" do
142
+ callback = "foo.com"
143
+ url = @oauth.url_for_access_token(@code, :callback => callback)
144
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@secret}&code=#{@code}"
145
+ end
146
+
147
+ it "should output a deprecation warning but generate a properly formatted OAuth token URL when provided a callback in the deprecated fashion" do
148
+ callback = "foo.com"
149
+ url = out = nil
150
+
151
+ begin
152
+ # we want to capture the deprecation warning as well as the output
153
+ # credit to http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/ for the technique
154
+ out = StringIO.new
155
+ $stdout = out
156
+ url = @oauth.url_for_access_token(@code, callback)
157
+ ensure
158
+ $stdout = STDOUT
159
+ end
160
+
161
+ # two assertions may be bad test writing, but this is for a deprecated method
162
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@secret}&code=#{@code}"
163
+ out.should_not be_nil
164
+ end
165
+
166
+ # parse_access_token
167
+ it "should properly parse access token results" do
168
+ result = @oauth.parse_access_token(@raw_token_string)
169
+ has_both_parts = result["access_token"] && result["expires"]
170
+ has_both_parts.should
171
+ end
172
+
173
+ it "should properly parse offline access token results" do
174
+ result = @oauth.parse_access_token(@raw_offline_access_token_string)
175
+ has_both_parts = result["access_token"] && !result["expires"]
176
+ has_both_parts.should
177
+ end
178
+
179
+ # fetch_token_string
180
+ # note -- we just test that this looks right, since get_access_token tests the parsing too
181
+ it "should fetch a proper token string from Facebook when given a code" do
182
+ result = @oauth.fetch_token_string(@code)
183
+ result.should =~ /^access_token/
184
+ end
185
+
186
+ # get_access_token
187
+ it "should properly get and parse an access token token results" do
188
+ result = @oauth.get_access_token(@code)
189
+ result["access_token"].should
190
+ end
191
+
192
+ 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
199
+ end
200
+ end # describe
201
+
202
+ end #class
@@ -10,7 +10,8 @@ class FacebookWithAccessTokenTests < Test::Unit::TestCase
10
10
  # clean up any temporary objects
11
11
  if @temporary_object_id
12
12
  puts "\nCleaning up temporary object #{@temporary_object_id.to_s}"
13
- @graph.delete_object(@temporary_object_id)
13
+ result = @graph.delete_object(@temporary_object_id)
14
+ raise "Unable to clean up temporary Graph object #{@temporary_object_id}!" unless result
14
15
  end
15
16
  end
16
17
 
@@ -53,26 +54,47 @@ class FacebookWithAccessTokenTests < Test::Unit::TestCase
53
54
  end
54
55
 
55
56
  # PUT
56
- it "should be able to put an object" do
57
+ it "should be able to write an object to the graph" do
57
58
  result = @graph.put_wall_post("Hello, world, from the test suite!")
58
59
  @temporary_object_id = result["id"]
59
60
  @temporary_object_id.should_not be_nil
60
61
  end
61
62
 
62
63
  # DELETE
63
- it "should not be able to delete posts" do
64
+ it "should be able to delete posts" do
64
65
  result = @graph.put_wall_post("Hello, world, from the test suite delete method!")
65
66
  object_id_to_delete = result["id"]
66
67
  delete_result = @graph.delete_object(object_id_to_delete)
67
68
  delete_result.should == true
68
69
  end
69
70
 
70
- # these are not strictly necessary as the other put methods resolve to put_object, but are here for completeness
71
- it "should be able to post to a feed" do
71
+ # additional put tests
72
+ it "should be able to verify messages posted to a wall" do
73
+ message = "the cats are asleep"
74
+ put_result = @graph.put_wall_post(message)
75
+ @temporary_object_id = put_result["id"]
76
+ get_result = @graph.get_object(@temporary_object_id)
77
+
78
+ # make sure the message we sent is the message that got posted
79
+ get_result["message"].should == message
80
+ end
81
+
82
+ it "should be able to post a message with an attachment to a feed" do
72
83
  result = @graph.put_wall_post("Hello, world, from the test suite again!", {:name => "Context Optional", :link => "http://www.contextoptional.com/"})
73
84
  @temporary_object_id = result["id"]
74
85
  @temporary_object_id.should_not be_nil
75
86
  end
87
+
88
+ it "should be able to verify a message with an attachment posted to a feed" do
89
+ attachment = {"name" => "Context Optional", "link" => "http://www.contextoptional.com/"}
90
+ result = @graph.put_wall_post("Hello, world, from the test suite again!", attachment)
91
+ @temporary_object_id = result["id"]
92
+ get_result = @graph.get_object(@temporary_object_id)
93
+
94
+ # make sure the result we fetch includes all the parameters we sent
95
+ it_matches = attachment.inject(true) {|valid, param| valid && (get_result[param[0]] == attachment[param[0]])}
96
+ it_matches.should == true
97
+ end
76
98
 
77
99
  it "should be able to comment on an object" do
78
100
  result = @graph.put_wall_post("Hello, world, from the test suite, testing comments!")
@@ -82,6 +104,20 @@ class FacebookWithAccessTokenTests < Test::Unit::TestCase
82
104
  comment_result = @graph.put_comment(@temporary_object_id, "it's my comment!")
83
105
  comment_result.should_not be_nil
84
106
  end
107
+
108
+ it "should be able to verify a comment posted about an object" do
109
+ message_text = "Hello, world, from the test suite, testing comments!"
110
+ result = @graph.put_wall_post(message_text)
111
+ @temporary_object_id = result["id"]
112
+
113
+ # this will be deleted when the post gets deleted
114
+ comment_text = "it's my comment!"
115
+ comment_result = @graph.put_comment(@temporary_object_id, comment_text)
116
+ get_result = @graph.get_object(comment_result["id"])
117
+
118
+ # make sure the text of the comment matches what we sent
119
+ get_result["message"].should == comment_text
120
+ end
85
121
 
86
122
  it "should be able to like an object" do
87
123
  result = @graph.put_wall_post("Hello, world, from the test suite, testing comments!")
@@ -2,16 +2,20 @@ require 'test/unit'
2
2
  require 'rubygems'
3
3
  require 'spec/test/unit'
4
4
 
5
+ # load the libraries
5
6
  require 'koala'
7
+
8
+ # load the tests
6
9
  require 'koala/facebook_no_access_token_tests'
7
10
  require 'koala/facebook_with_access_token_tests'
11
+ require 'koala/facebook_oauth_tests'
8
12
 
9
13
  class FacebookTestSuite
10
14
  def self.suite
11
15
  suite = Test::Unit::TestSuite.new
12
16
  suite << FacebookNoAccessTokenTests.suite
13
17
  suite << FacebookWithAccessTokenTests.suite
14
- #suite << FacebookCookieTest.suite
18
+ suite << FacebookOAuthTests.suite
15
19
  suite
16
20
  end
17
21
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
8
- - 1
9
- version: 0.4.1
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Alex Koppel, Rafi Jacoby, Context Optional
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-03 00:00:00 -07:00
17
+ date: 2010-05-08 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -33,16 +33,17 @@ files:
33
33
  - Manifest
34
34
  - Rakefile
35
35
  - init.rb
36
- - koala.gemspec
37
36
  - lib/http_services.rb
38
37
  - lib/koala.rb
39
38
  - readme.md
40
39
  - test/facebook_data.yml
41
40
  - test/koala/facebook_no_access_token_tests.rb
41
+ - test/koala/facebook_oauth_tests.rb
42
42
  - test/koala/facebook_with_access_token_tests.rb
43
43
  - test/koala_tests.rb
44
+ - koala.gemspec
44
45
  has_rdoc: true
45
- homepage: http://github.com/arsduo/ruby-sdk
46
+ homepage: http://github.com/arsduo/koala
46
47
  licenses: []
47
48
 
48
49
  post_install_message: