koala 0.10.0 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -142,7 +142,7 @@ module Koala
142
142
  # Writes a wall post to the given profile's wall.
143
143
  #
144
144
  # We default to writing to the authenticated user's wall if no
145
- # profile_id is specified.
145
+ # profile_id is specified.
146
146
  #
147
147
  # attachment adds a structured attachment to the status message being
148
148
  # posted to the Wall. It should be a dictionary of the form:
@@ -155,7 +155,14 @@ module Koala
155
155
 
156
156
  self.put_object(profile_id, "feed", attachment.merge({:message => message}))
157
157
  end
158
-
158
+
159
+ def put_picture(file_hash, args = {}, target_id = "me")
160
+ raise APIError.new("type" => "KoalaInvaliFileFormat", "message" => "put_picture requires a hash describing the File to upload (see HTTPService::is_valid_file_hash?") unless file_hash.kind_of?(Hash)
161
+
162
+ args["source"] = file_hash
163
+ self.put_object(target_id, "photos", args)
164
+ end
165
+
159
166
  def put_comment(object_id, message)
160
167
  # Writes the given comment on the given post.
161
168
  self.put_object(object_id, "comments", {:message => message})
@@ -165,9 +172,15 @@ module Koala
165
172
  # Likes the given post.
166
173
  self.put_object(object_id, "likes")
167
174
  end
175
+
176
+ def delete_like(object_id)
177
+ raise APIError.new({"type" => "KoalaMissingAccessToken", "message" => "Unliking requires an access token"}) unless @access_token
178
+ graph_call("#{object_id}/likes", {}, "delete")
179
+ end
168
180
 
169
181
  def delete_object(id)
170
182
  # Deletes the object with the given ID from the graph.
183
+ raise APIError.new({"type" => "KoalaMissingAccessToken", "message" => "Unliking requires an access token"}) unless @access_token
171
184
  graph_call(id, {}, "delete")
172
185
  end
173
186
 
@@ -189,4 +202,4 @@ module Koala
189
202
  end
190
203
  end
191
204
  end
192
- end
205
+ end
@@ -8,62 +8,146 @@ module Koala
8
8
  end
9
9
  end
10
10
 
11
+ module HTTPService
12
+ # common functionality for all HTTP services
13
+ def self.included(base)
14
+ base.class_eval do
15
+ class << self
16
+ attr_accessor :always_use_ssl
17
+ end
18
+
19
+ protected
20
+ def self.params_require_multipart?(param_hash)
21
+ param_hash.any? { |key, value| is_valid_file_hash?(value) }
22
+ end
23
+
24
+ # A file hash can take two forms:
25
+ # - A hash with "content_type" and "path" keys where "path" is the local path
26
+ # to the file to be uploaded.
27
+ # - A hash with the "file" key containing an already-opened IO that responds to "read"
28
+ # as well as "content_type" and the "path" key to the original file
29
+ # ("path"" is required by multipart-post even for opened files)
30
+ #
31
+ # Valid inputs for a file to be posted via multipart/form-data
32
+ # are based on the criteria for an UploadIO to be created
33
+ # See : https://github.com/nicksieger/multipart-post/blob/master/lib/composite_io.rb
34
+ def self.is_valid_file_hash?(value)
35
+ value.kind_of?(Hash) and value.key?("content_type") and value.key?("path") and (
36
+ !value.key?("file") or value["file"].respond_to?(:read)
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
42
+
11
43
  module NetHTTPService
12
44
  # this service uses Net::HTTP to send requests to the graph
13
45
  def self.included(base)
14
46
  base.class_eval do
15
- require 'net/http' unless defined?(Net::HTTP)
16
- require 'net/https'
47
+ require "net/http" unless defined?(Net::HTTP)
48
+ require "net/https"
49
+ require "net/http/post/multipart"
50
+
51
+ include Koala::HTTPService
17
52
 
18
53
  def self.make_request(path, args, verb, options = {})
19
54
  # We translate args to a valid query string. If post is specified,
20
55
  # we send a POST request to the given path with the given arguments.
21
56
 
57
+ # by default, we use SSL only for private requests
58
+ # this makes public requests faster
59
+ private_request = args["access_token"] || @always_use_ssl || options[:use_ssl]
60
+
22
61
  # if the verb isn't get or post, send it as a post argument
23
62
  args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"
24
63
 
25
64
  server = options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER
26
- http = Net::HTTP.new(server, 443)
27
- http.use_ssl = true
28
- # we turn off certificate validation to avoid the
65
+ http = Net::HTTP.new(server, private_request ? 443 : nil)
66
+ http.use_ssl = true if private_request
67
+
68
+ # we turn off certificate validation to avoid the
29
69
  # "warning: peer certificate won't be verified in this SSL session" warning
30
70
  # not sure if this is the right way to handle it
31
71
  # see http://redcorundum.blogspot.com/2008/03/ssl-certificates-and-nethttps.html
32
72
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
33
73
 
34
- result = http.start { |http|
35
- response, body = (verb == "post" ? http.post(path, encode_params(args)) : http.get("#{path}?#{encode_params(args)}"))
74
+ result = http.start do |http|
75
+ response, body = if verb == "post"
76
+ if params_require_multipart? args
77
+ http.request Net::HTTP::Post::Multipart.new path, encode_multipart_params(args)
78
+ else
79
+ http.post(path, encode_params(args))
80
+ end
81
+ else
82
+ http.get("#{path}?#{encode_params(args)}")
83
+ end
84
+
36
85
  Koala::Response.new(response.code.to_i, body, response)
37
- }
86
+ end
38
87
  end
39
88
 
40
89
  protected
41
90
  def self.encode_params(param_hash)
42
91
  # unfortunately, we can't use to_query because that's Rails, not Ruby
43
92
  # if no hash (e.g. no auth token) return empty string
44
- ((param_hash || {}).collect do |key_and_value|
93
+ ((param_hash || {}).collect do |key_and_value|
45
94
  key_and_value[1] = key_and_value[1].to_json if key_and_value[1].class != String
46
95
  "#{key_and_value[0].to_s}=#{CGI.escape key_and_value[1]}"
47
96
  end).join("&")
48
97
  end
98
+
99
+ def self.encode_multipart_params(param_hash)
100
+ Hash[*param_hash.collect do |key, value|
101
+ if is_valid_file_hash?(value)
102
+ if value.key?("file")
103
+ value = UploadIO.new(value["file"], value["content_type"], value["path"])
104
+ else
105
+ value = UploadIO.new(value["path"], value['content_type'])
106
+ end
107
+ end
108
+
109
+ [key, value]
110
+ end.flatten]
111
+ end
49
112
  end
50
113
  end
51
114
  end
52
115
 
53
116
  module TyphoeusService
54
117
  # this service uses Typhoeus to send requests to the graph
118
+
119
+ # used for multipart file uploads (see below)
120
+ class NetHTTPInterface
121
+ include NetHTTPService
122
+ end
123
+
55
124
  def self.included(base)
56
125
  base.class_eval do
57
- require 'typhoeus' unless defined?(Typhoeus)
126
+ require "typhoeus" unless defined?(Typhoeus)
58
127
  include Typhoeus
128
+
129
+ include Koala::HTTPService
59
130
 
60
131
  def self.make_request(path, args, verb, options = {})
61
- # if the verb isn't get or post, send it as a post argument
62
- args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"
63
- server = options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER
64
- typhoeus_options = {:params => args}.merge(options[:typhoeus_options] || {})
65
- response = self.send(verb, "https://#{server}#{path}", typhoeus_options)
66
- Koala::Response.new(response.code, response.body, response.headers_hash)
132
+ unless params_require_multipart?(args)
133
+ # if the verb isn't get or post, send it as a post argument
134
+ args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"
135
+ server = options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER
136
+
137
+ # you can pass arguments directly to Typhoeus using the :typhoeus_options key
138
+ typhoeus_options = {:params => args}.merge(options[:typhoeus_options] || {})
139
+
140
+ # by default, we use SSL only for private requests (e.g. with access token)
141
+ # this makes public requests faster
142
+ prefix = (args["access_token"] || @always_use_ssl || options[:use_ssl]) ? "https" : "http"
143
+
144
+ response = self.send(verb, "#{prefix}://#{server}#{path}", typhoeus_options)
145
+ Koala::Response.new(response.code, response.body, response.headers_hash)
146
+ else
147
+ # we have to use NetHTTPService for multipart for file uploads
148
+ # until Typhoeus integrates support
149
+ Koala::TyphoeusService::NetHTTPInterface.make_request(path, args, verb, options)
150
+ end
67
151
  end
68
152
  end # class_eval
69
153
  end
@@ -1,23 +1,90 @@
1
1
  module Koala
2
2
  module Facebook
3
3
  REST_SERVER = "api.facebook.com"
4
-
4
+
5
5
  module RestAPIMethods
6
6
  def fql_query(fql)
7
7
  rest_call('fql.query', 'query' => fql)
8
8
  end
9
-
10
- def rest_call(method, args = {})
11
- response = api("method/#{method}", args.merge('format' => 'json'), 'get', :rest_api => true) do |response|
9
+
10
+ def rest_call(method, args = {}, options = {})
11
+ options = options.merge!(:rest_api => true, :read_only => READ_ONLY_METHODS.include?(method))
12
+
13
+ response = api("method/#{method}", args.merge('format' => 'json'), 'get', options) do |response|
12
14
  # check for REST API-specific errors
13
15
  if response.is_a?(Hash) && response["error_code"]
14
16
  raise APIError.new("type" => response["error_code"], "message" => response["error_msg"])
15
17
  end
16
18
  end
17
-
19
+
18
20
  response
19
21
  end
22
+
23
+ # read-only methods for which we can use API-read
24
+ # taken directly from the FB PHP library (https://github.com/facebook/php-sdk/blob/master/src/facebook.php)
25
+ READ_ONLY_METHODS = [
26
+ 'admin.getallocation',
27
+ 'admin.getappproperties',
28
+ 'admin.getbannedusers',
29
+ 'admin.getlivestreamvialink',
30
+ 'admin.getmetrics',
31
+ 'admin.getrestrictioninfo',
32
+ 'application.getpublicinfo',
33
+ 'auth.getapppublickey',
34
+ 'auth.getsession',
35
+ 'auth.getsignedpublicsessiondata',
36
+ 'comments.get',
37
+ 'connect.getunconnectedfriendscount',
38
+ 'dashboard.getactivity',
39
+ 'dashboard.getcount',
40
+ 'dashboard.getglobalnews',
41
+ 'dashboard.getnews',
42
+ 'dashboard.multigetcount',
43
+ 'dashboard.multigetnews',
44
+ 'data.getcookies',
45
+ 'events.get',
46
+ 'events.getmembers',
47
+ 'fbml.getcustomtags',
48
+ 'feed.getappfriendstories',
49
+ 'feed.getregisteredtemplatebundlebyid',
50
+ 'feed.getregisteredtemplatebundles',
51
+ 'fql.multiquery',
52
+ 'fql.query',
53
+ 'friends.arefriends',
54
+ 'friends.get',
55
+ 'friends.getappusers',
56
+ 'friends.getlists',
57
+ 'friends.getmutualfriends',
58
+ 'gifts.get',
59
+ 'groups.get',
60
+ 'groups.getmembers',
61
+ 'intl.gettranslations',
62
+ 'links.get',
63
+ 'notes.get',
64
+ 'notifications.get',
65
+ 'pages.getinfo',
66
+ 'pages.isadmin',
67
+ 'pages.isappadded',
68
+ 'pages.isfan',
69
+ 'permissions.checkavailableapiaccess',
70
+ 'permissions.checkgrantedapiaccess',
71
+ 'photos.get',
72
+ 'photos.getalbums',
73
+ 'photos.gettags',
74
+ 'profile.getinfo',
75
+ 'profile.getinfooptions',
76
+ 'stream.get',
77
+ 'stream.getcomments',
78
+ 'stream.getfilters',
79
+ 'users.getinfo',
80
+ 'users.getloggedinuser',
81
+ 'users.getstandardinfo',
82
+ 'users.hasapppermission',
83
+ 'users.isappuser',
84
+ 'users.isverified',
85
+ 'video.getuploadlimits'
86
+ ]
20
87
  end
21
-
88
+
22
89
  end # module Facebook
23
90
  end # module Koala
data/readme.md CHANGED
@@ -1,28 +1,28 @@
1
1
  Koala
2
2
  ====
3
- Koala (<a href="http://github.com/arsduo/koala" target="_blank">http://github.com/arsduo/koala</a>) is a new Facebook library for Ruby, supporting the Graph API, the old REST API, realtime updates, and OAuth validation. We wrote Koala with four goals:
3
+ Koala (<a href="http://github.com/arsduo/koala" target="_blank">http://github.com/arsduo/koala</a>) is a new Facebook library for Ruby, supporting the Graph API, the old REST API, realtime updates, and OAuth validation. We wrote Koala with four goals:
4
4
 
5
- * Lightweight: Koala should be as light and simple as Facebook’s own new libraries, providing API accessors and returning simple JSON. (We clock in, with comments, just over 500 lines of code.)
5
+ * Lightweight: Koala should be as light and simple as Facebook’s own new libraries, providing API accessors and returning simple JSON. (We clock in, with comments, just over 750 lines of code.)
6
6
  * Fast: Koala should, out of the box, be quick. In addition to supporting the vanilla Ruby networking libraries, it natively supports Typhoeus, our preferred gem for making fast HTTP requests. Of course, That brings us to our next topic:
7
7
  * Flexible: Koala should be useful to everyone, regardless of their current configuration. (We have no dependencies beyond the JSON gem. Koala also has a built-in mechanism for using whichever HTTP library you prefer to make requests against the graph.)
8
8
  * Tested: Koala should have complete test coverage, so you can rely on it. (Our complete test coverage can be run against either mocked responses or the live Facebook servers.)
9
9
 
10
10
  Graph API
11
11
  ----
12
- The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
12
+ The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
13
13
 
14
14
  graph = Koala::Facebook::GraphAPI.new(oauth_access_token)
15
15
  profile = graph.get_object("me")
16
16
  friends = graph.get_connections("me", "friends")
17
17
  graph.put_object("me", "feed", :message => "I am writing on my wall!")
18
18
 
19
- The response of most requests is the JSON data returned from the Facebook servers as a Hash.
19
+ The response of most requests is the JSON data returned from the Facebook servers as a Hash.
20
20
 
21
21
  When retrieving data that returns an array of results (for example, when calling GraphAPI#get_connections or GraphAPI#search) a GraphCollection object (a sub-class of Array) will be returned, which contains added methods for getting the next and previous page of results:
22
-
22
+
23
23
  # Returns the feed items for the currently logged-in user as a GraphCollection
24
24
  feed = graph.get_connections("me", "feed")
25
-
25
+
26
26
  # GraphCollection is a sub-class of Array, so you can use it as a usual Array
27
27
  first_entry = feed[0]
28
28
  last_entry = feed.last
@@ -33,7 +33,7 @@ When retrieving data that returns an array of results (for example, when calling
33
33
  # Returns an array describing the URL for the next page: [path, arguments]
34
34
  # This is useful for paging across multiple requests
35
35
  next_path, next_args = feed.next_page_params
36
-
36
+
37
37
  # You can use those params to easily get the next (or prevous) page
38
38
  page = graph.get_page(feed.next_page_params)
39
39
 
@@ -41,15 +41,15 @@ Check out the wiki for more examples.
41
41
 
42
42
  The old-school REST API
43
43
  -----
44
- Where the Graph API and the old REST API overlap, you should choose the Graph API. Unfortunately, that overlap is far from complete, and there are many important API calls that can't yet be done via the Graph.
44
+ Where the Graph API and the old REST API overlap, you should choose the Graph API. Unfortunately, that overlap is far from complete, and there are many important API calls that can't yet be done via the Graph.
45
45
 
46
46
  Koala now supports the old-school REST API using OAuth access tokens; to use this, instantiate your class using the RestAPI class:
47
47
 
48
48
  @rest = Koala::Facebook::RestAPI.new(oauth_access_token)
49
49
  @rest.fql_query(my_fql_query) # convenience method
50
50
  @rest.rest_call("stream.publish", arguments_hash) # generic version
51
-
52
- We reserve the right to expand the built-in REST API coverage to additional convenience methods in the future, depending on how fast Facebook moves to fill in the gaps.
51
+
52
+ We reserve the right to expand the built-in REST API coverage to additional convenience methods in the future, depending on how fast Facebook moves to fill in the gaps.
53
53
 
54
54
  (If you want the power of both APIs in the palm of your hand, try out the GraphAndRestAPI class.)
55
55
 
@@ -119,7 +119,7 @@ Some resources to help you as you play with Koala and the Graph API:
119
119
  Testing
120
120
  -----
121
121
 
122
- Unit tests are provided for all of Koala's methods. By default, these tests run against mock responses and hence are ready out of the box:
122
+ Unit tests are provided for all of Koala's methods. By default, these tests run against mock responses and hence are ready out of the box:
123
123
  # From the spec directory
124
124
  spec koala_spec.rb
125
125
 
@@ -4,7 +4,7 @@
4
4
  # Just remember to update all fields!
5
5
 
6
6
  # You must supply this value yourself to test the GraphAPI class.
7
- # Your OAuth token should have publish_stream and read_stream permissions.
7
+ # Your OAuth token should have publish_stream, read_stream, and user_photos permissions.
8
8
  oauth_token:
9
9
 
10
10
  # for testing the OAuth class
@@ -44,8 +44,14 @@ oauth_test_data:
44
44
  signed_request_result:
45
45
  "0": payload
46
46
  algorithm: HMAC-SHA256
47
-
48
-
47
+ # signed params
48
+ # examples from http://developers.facebook.com/docs/authentication/canvas/encryption_proposal
49
+ signed_params: t63pZQ4Q3ZTHJt0hOsKrY2pb28xRlduW0pg4lL_Zhl4.eyJhbGdvcml0aG0iOiJBRVMtMjU2LUNCQyBITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTI4NzYwMTk4OCwiaXYiOiJmRExKQ1cteWlYbXVOYTI0ZVNhckpnIiwicGF5bG9hZCI6IllHeW00cG9Rbk1UckVnaUFPa0ZUVkk4NWxsNVJ1VWlFbC1JZ3FmeFRPVEhRTkl2VlZJOFk4a1Z1T29lS2FXT2Vhc3NXRlRFdjBRZ183d0NDQkVlbjdsVUJCemxGSjFWNjNISjNBZjBTSW5nY3hXVEo3TDZZTGF0TW13WGdEQXZXbjVQc2ZxeldrNG1sOWg5RExuWXB0V0htREdMNmlCaU9oTjdXeUk3cDZvRXBWcmlGdUp3X2NoTG9QYjhhM3ZHRG5vVzhlMlN4eDA2QTJ4MnhraWFwdmcifQ
50
+ signed_params_secret: 13750c9911fec5865d01f3bd00bdf4db
51
+ signed_params_result:
52
+ access_token: "101244219942650|2.wdrSr7KyE_VwQ0fjwOfW9A__.3600.1287608400-499091902|XzxMQd-_4tjlC2VEgide4rmg6LI"
53
+ expires_in: 6412
54
+ user_id: "499091902"
49
55
 
50
56
  subscription_test_data:
51
57
  subscription_path: http://oauth.twoalex.com/subscriptions
@@ -3,8 +3,12 @@ class GraphAndRestAPINoTokenTests < Test::Unit::TestCase
3
3
  before(:each) do
4
4
  @api = Koala::Facebook::GraphAndRestAPI.new
5
5
  end
6
-
6
+
7
+ it_should_behave_like "Koala RestAPI"
7
8
  it_should_behave_like "Koala RestAPI without an access token"
9
+
10
+ it_should_behave_like "Koala GraphAPI"
8
11
  it_should_behave_like "Koala GraphAPI without an access token"
12
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
9
13
  end
10
14
  end
@@ -1,11 +1,16 @@
1
1
  class GraphAndRestAPIWithTokenTests < Test::Unit::TestCase
2
2
  describe "Koala GraphAndRestAPI without an access token" do
3
3
  include LiveTestingDataHelper
4
- it_should_behave_like "Koala RestAPI with an access token"
5
- it_should_behave_like "Koala GraphAPI with an access token"
6
-
4
+
7
5
  before(:each) do
8
6
  @api = Koala::Facebook::GraphAndRestAPI.new(@token)
9
7
  end
8
+
9
+ it_should_behave_like "Koala RestAPI"
10
+ it_should_behave_like "Koala RestAPI with an access token"
11
+
12
+ it_should_behave_like "Koala GraphAPI"
13
+ it_should_behave_like "Koala GraphAPI with an access token"
14
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
10
15
  end
11
16
  end
@@ -1,9 +1,4 @@
1
1
  shared_examples_for "Koala GraphAPI without an access token" do
2
- it "should get public data about a user" do
3
- result = @api.get_object("koppel")
4
- # the results should have an ID and a name, among other things
5
- (result["id"] && result["name"]).should
6
- end
7
2
 
8
3
  it "should not get private data about a user" do
9
4
  result = @api.get_object("koppel")
@@ -11,46 +6,14 @@ shared_examples_for "Koala GraphAPI without an access token" do
11
6
  result["updated_time"].should be_nil
12
7
  end
13
8
 
14
- it "should get public data about a Page" do
15
- result = @api.get_object("contextoptional")
16
- # the results should have an ID and a name, among other things
17
- (result["id"] && result["name"]).should
18
- end
19
-
20
9
  it "should not be able to get data about 'me'" do
21
10
  lambda { @api.get_object("me") }.should raise_error(Koala::Facebook::APIError)
22
11
  end
23
12
 
24
- it "should be able to get multiple objects" do
25
- results = @api.get_objects(["contextoptional", "naitik"])
26
- results.length.should == 2
27
- end
28
-
29
13
  it "shouldn't be able to access connections from users" do
30
14
  lambda { @api.get_connections("lukeshepard", "likes") }.should raise_error(Koala::Facebook::APIError)
31
15
  end
32
16
 
33
- it "should be able to access a user's picture" do
34
- @api.get_picture("chris.baclig").should =~ /http\:\/\//
35
- end
36
-
37
- it "should be able to access a user's picture, given a picture type" do
38
- @api.get_picture("chris.baclig", {:type => 'large'}).should =~ /^http\:\/\//
39
- end
40
-
41
- it "should be able to access connections from public Pages" do
42
- result = @api.get_connections("contextoptional", "photos")
43
- result.should be_a(Array)
44
- end
45
-
46
- # paging
47
- # see also graph_collection_tests
48
- it "should make a request for a page when provided a specific set of page params" do
49
- query = [1, 2]
50
- @api.should_receive(:graph_call).with(*query)
51
- @api.get_page(query)
52
- end
53
-
54
17
  it "should not be able to put an object" do
55
18
  lambda { @result = @api.put_object("lukeshepard", "feed", :message => "Hello, world") }.should raise_error(Koala::Facebook::APIError)
56
19
  puts "Error! Object #{@result.inspect} somehow put onto Luke Shepard's wall!" if @result
@@ -60,7 +23,7 @@ shared_examples_for "Koala GraphAPI without an access token" do
60
23
  it "should not be able to post to a feed" do
61
24
  (lambda do
62
25
  attachment = {:name => "Context Optional", :link => "http://www.contextoptional.com/"}
63
- @result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
26
+ @result = @api.put_wall_post("Hello, world", attachment, "contextoptional")
64
27
  end).should raise_error(Koala::Facebook::APIError)
65
28
  puts "Error! Object #{@result.inspect} somehow put onto Context Optional's wall!" if @result
66
29
  end
@@ -68,7 +31,7 @@ shared_examples_for "Koala GraphAPI without an access token" do
68
31
  it "should not be able to comment on an object" do
69
32
  # random public post on the ContextOptional wall
70
33
  lambda { @result = @api.put_comment("7204941866_119776748033392", "The hackathon was great!") }.should raise_error(Koala::Facebook::APIError)
71
- puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
34
+ puts "Error! Object #{@result.inspect} somehow commented on post 7204941866_119776748033392!" if @result
72
35
  end
73
36
 
74
37
  it "should not be able to like an object" do
@@ -76,29 +39,13 @@ shared_examples_for "Koala GraphAPI without an access token" do
76
39
  end
77
40
 
78
41
  # DELETE
79
- it "should not be able to delete posts" do
42
+ it "should not be able to delete posts" do
80
43
  # test post on the Ruby SDK Test application
81
44
  lambda { @result = @api.delete_object("115349521819193_113815981982767") }.should raise_error(Koala::Facebook::APIError)
82
45
  end
83
-
84
- # SEARCH
85
- it "should be able to search" do
86
- result = @api.search("facebook")
87
- result.length.should be_an(Integer)
88
- end
89
-
90
- it_should_behave_like "Koala GraphAPI with GraphCollection"
91
46
 
92
- # API
93
- it "should never use the rest api server" do
94
- Koala.should_receive(:make_request).with(
95
- anything,
96
- anything,
97
- anything,
98
- hash_not_including(:rest_api => true)
99
- ).and_return(Koala::Response.new(200, "", {}))
100
-
101
- @api.api("anything")
47
+ it "should not be able to delete a like" do
48
+ lambda { @api.delete_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
102
49
  end
103
50
  end
104
51
 
@@ -106,9 +53,11 @@ class FacebookNoAccessTokenTests < Test::Unit::TestCase
106
53
  describe "Koala GraphAPI without an access token" do
107
54
  before :each do
108
55
  @api = Koala::Facebook::GraphAPI.new
109
- end
110
-
56
+ end
57
+
58
+ it_should_behave_like "Koala GraphAPI"
111
59
  it_should_behave_like "Koala GraphAPI without an access token"
60
+ it_should_behave_like "Koala GraphAPI with GraphCollection"
61
+
112
62
  end
113
63
  end
114
-