facebooker 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG.txt +0 -0
  2. data/COPYING +19 -0
  3. data/History.txt +3 -0
  4. data/Manifest.txt +60 -0
  5. data/README +44 -0
  6. data/README.txt +79 -0
  7. data/Rakefile +38 -0
  8. data/TODO.txt +10 -0
  9. data/facebooker.yml.tpl +36 -0
  10. data/init.rb +52 -0
  11. data/install.rb +5 -0
  12. data/lib/facebooker.rb +63 -0
  13. data/lib/facebooker/affiliation.rb +10 -0
  14. data/lib/facebooker/album.rb +11 -0
  15. data/lib/facebooker/cookie.rb +10 -0
  16. data/lib/facebooker/data.rb +38 -0
  17. data/lib/facebooker/education_info.rb +11 -0
  18. data/lib/facebooker/event.rb +26 -0
  19. data/lib/facebooker/feed.rb +65 -0
  20. data/lib/facebooker/group.rb +35 -0
  21. data/lib/facebooker/location.rb +8 -0
  22. data/lib/facebooker/model.rb +118 -0
  23. data/lib/facebooker/notifications.rb +17 -0
  24. data/lib/facebooker/parser.rb +386 -0
  25. data/lib/facebooker/photo.rb +9 -0
  26. data/lib/facebooker/rails/controller.rb +174 -0
  27. data/lib/facebooker/rails/facebook_asset_path.rb +18 -0
  28. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  29. data/lib/facebooker/rails/facebook_request_fix.rb +14 -0
  30. data/lib/facebooker/rails/facebook_session_handling.rb +58 -0
  31. data/lib/facebooker/rails/facebook_url_rewriting.rb +31 -0
  32. data/lib/facebooker/rails/helpers.rb +535 -0
  33. data/lib/facebooker/rails/routing.rb +49 -0
  34. data/lib/facebooker/rails/test_helpers.rb +11 -0
  35. data/lib/facebooker/rails/utilities.rb +22 -0
  36. data/lib/facebooker/server_cache.rb +24 -0
  37. data/lib/facebooker/service.rb +25 -0
  38. data/lib/facebooker/session.rb +385 -0
  39. data/lib/facebooker/tag.rb +12 -0
  40. data/lib/facebooker/user.rb +200 -0
  41. data/lib/facebooker/version.rb +9 -0
  42. data/lib/facebooker/work_info.rb +9 -0
  43. data/lib/net/http_multipart_post.rb +123 -0
  44. data/lib/tasks/facebooker.rake +16 -0
  45. data/lib/tasks/tunnel.rake +39 -0
  46. data/setup.rb +1585 -0
  47. data/test/event_test.rb +15 -0
  48. data/test/facebook_cache_test.rb +43 -0
  49. data/test/facebook_data_test.rb +50 -0
  50. data/test/facebooker_test.rb +766 -0
  51. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  52. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  53. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  54. data/test/http_multipart_post_test.rb +54 -0
  55. data/test/model_test.rb +79 -0
  56. data/test/rails_integration_test.rb +732 -0
  57. data/test/session_test.rb +396 -0
  58. data/test/test_helper.rb +54 -0
  59. data/test/user_test.rb +101 -0
  60. metadata +130 -0
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class EventTest< Test::Unit::TestCase
4
+ def test_attendance_will_query_for_event_when_asked_for_full_event_object
5
+ session = flexmock("a session object")
6
+ eid = 123
7
+ attendance = Facebooker::Event::Attendance.new
8
+ attendance.eid = eid
9
+ attendance.session = session
10
+ event = Facebooker::Event.new
11
+ event.eid = eid
12
+ session.should_receive(:post).once.with('facebook.events.get', :eids => [eid]).and_return([{:eid => eid}])
13
+ assert_equal(123, attendance.event.eid)
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class FacebookCacheTest < Test::Unit::TestCase
4
+ def setup
5
+ @session = Facebooker::Session.create('apikey', 'secretkey')
6
+ end
7
+
8
+ def test_can_ask_facebook_to_store_fbml_in_a_named_reference
9
+ expect_http_posts_with_responses(example_set_ref_handle_xml)
10
+ assert(@session.server_cache.set_ref_handle('a_handle_name', '<h2>Some FBML</h2>'))
11
+ end
12
+
13
+ def test_can_ask_facebook_to_recache_content_stored_from_a_given_url
14
+ expect_http_posts_with_responses(example_refresh_ref_url_xml)
15
+ assert(@session.server_cache.refresh_ref_url('http://localhost/roflmao'))
16
+ end
17
+
18
+ def test_can_ask_facebook_to_recache_an_img
19
+ expect_http_posts_with_responses(example_refresh_img_xml)
20
+ assert(@session.server_cache.refresh_img_src('http://localhost/roflmao.jpg'))
21
+ end
22
+
23
+ private
24
+ def example_set_ref_handle_xml
25
+ <<-XML
26
+ <?xml version="1.0" encoding="UTF-8"?>
27
+ <fbml_setRefHandle_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</fbml_setRefHandle_response>
28
+ XML
29
+ end
30
+
31
+ def example_refresh_ref_url_xml
32
+ <<-XML
33
+ <?xml version="1.0" encoding="UTF-8"?>
34
+ <fbml_refreshRefUrl_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</fbml_refreshRefUrl_response>
35
+ XML
36
+ end
37
+ def example_refresh_img_xml
38
+ <<-XML
39
+ <?xml version="1.0" encoding="UTF-8"?>
40
+ <fbml_refreshImgSrc_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</fbml_refreshImgSrc_response>
41
+ XML
42
+ end
43
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class FacebookDataTest < Test::Unit::TestCase
4
+ def setup
5
+ @session = Facebooker::Session.create('apikey', 'secretkey')
6
+ end
7
+
8
+ def test_can_ask_facebook_to_set_a_cookies
9
+ expect_http_posts_with_responses(example_set_cookie_xml)
10
+ assert(@session.data.set_cookie(12345, 'name', 'value'))
11
+ end
12
+
13
+ def test_can_ask_facebook_to_get_cookies
14
+ expect_http_posts_with_responses(example_get_cookies_xml)
15
+ assert(@session.data.get_cookies(12345))
16
+ end
17
+
18
+ def test_can_get_cookies_for_user
19
+ mock_http = establish_session
20
+ mock_http.should_receive(:post_form).and_return(example_get_cookies_xml).once.ordered(:posts)
21
+ cookies = @session.data.get_cookies(508508326)
22
+ assert_equal 'Foo', cookies.first.name
23
+ assert_equal 'Bar', cookies.first.value
24
+ end
25
+
26
+ private
27
+ def example_set_cookie_xml
28
+ <<-XML
29
+ <?xml version="1.0" encoding="UTF-8"?>
30
+ <data_setCookie_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
31
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</data_setCookie_response>
32
+ XML
33
+ end
34
+
35
+ def example_get_cookies_xml
36
+ <<-XML
37
+ <?xml version="1.0" encoding="UTF-8"?>
38
+ <data_getCookie_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
39
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
40
+ <cookies>
41
+ <uid>508508326</uid>
42
+ <name>Foo</name>
43
+ <value>Bar</value>
44
+ <expires>0</expires>
45
+ <path>/tmp/</path>
46
+ </cookies>
47
+ </data_getCookie_response>
48
+ XML
49
+ end
50
+ end
@@ -0,0 +1,766 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ class TestFacebooker < Test::Unit::TestCase
3
+
4
+ def setup
5
+ @api_key = "95a71599e8293s66f1f0a6f4aeab3df7"
6
+ @secret_key = "3e4du8eea435d8e205a6c9b5d095bed1"
7
+ @session = Facebooker::Session.create(@api_key, @secret_key)
8
+ @desktop_session = Facebooker::Session::Desktop.create(@api_key, @secret_key)
9
+ @service = Facebooker::Service.new('http://apibase.com', '/api/path', @api_key)
10
+ @desktop_session.instance_variable_set("@service", @service)
11
+ end
12
+
13
+ def test_session_must_be_created_from_api_key_and_secret_key
14
+ assert_kind_of(Facebooker::Session, @session)
15
+ end
16
+
17
+ def test_session_can_tell_you_its_login_url
18
+ assert_not_nil(@session.login_url)
19
+ assert_equal("http://www.facebook.com/login.php?api_key=#{@api_key}&v=1.0", @session.login_url)
20
+ end
21
+
22
+ def test_desktop_session_returns_auth_toke_as_part_of_login_url
23
+ @service = flexmock(@service).should_receive(:post).at_least.once.and_return(123)
24
+ assert_kind_of(Facebooker::Session::Desktop, @desktop_session)
25
+ assert_match(/auth_token=[a-z0-9A-Z]/, @desktop_session.login_url)
26
+ end
27
+
28
+ def test_service_posts_data_to_http_location
29
+ flexmock(Net::HTTP).should_receive(:post_form).and_return(example_auth_token_xml)
30
+ assert_equal("http://www.facebook.com/login.php?api_key=#{@api_key}&v=1.0&auth_token=3e4a22bb2f5ed75114b0fc9995ea85f1", @desktop_session.login_url)
31
+ end
32
+
33
+ def test_serivce_post_file_delegates_to_post_multipart_form
34
+ # flexmock(@service).should_receive(:url).and_return('url')
35
+ # flexmock(Net::HTTP).expects(:post_multipart_form).with('url', {:method => 'facebook.auth.createToken'}).returns(example_auth_token_xml)
36
+
37
+ res = mock(:content_type => 'text/html', :code => '200', :body => '<html><body>my blog</body></html>')
38
+ Net::HTTP.stubs(:get_response).once.with(uri).returns res
39
+
40
+ @service.post_file(:method => 'facebook.auth.createToken')
41
+ end
42
+
43
+ def test_desktop_session_be_secured_and_activated_after_receiving_auth_token_and_logging_in
44
+ establish_session
45
+ assert_equal("5f34e11bfb97c762e439e6a5-8055", @session.instance_variable_get("@session_key"))
46
+ end
47
+
48
+ def test_desktop_session_uses_secret_api_key_for_hashing_until_user_authenticates
49
+ assert_equal(@secret_key, @desktop_session.secret_for_method('facebook.auth.createToken'))
50
+ establish_session(@desktop_session)
51
+ assert_equal("ohairoflamao12345", @desktop_session.secret_for_method('anyNonAuthMethodName'))
52
+ end
53
+
54
+ def test_session_can_get_current_logged_in_user_id_and_will_cache
55
+ establish_session
56
+ flexmock(Net::HTTP).should_receive(:post_form).and_return(example_get_logged_in_user_xml)
57
+ assert_equal(8055, @session.user.id)
58
+ end
59
+
60
+ def test_can_get_current_users_friends
61
+ mock_http = establish_session
62
+ mock_http.should_receive(:post_form).and_return(example_friends_xml).once.ordered(:posts)
63
+ assert_equal([222333, 1240079], @session.user.friends.map{|friend| friend.id})
64
+ end
65
+
66
+ def test_can_get_info_for_instance_of_user
67
+ populate_user_info
68
+ @session.user.first_name = "Dave"
69
+ end
70
+
71
+ def test_can_get_info_for_one_or_more_users
72
+ friends = populate_session_friends
73
+ friend = friends.detect{|f| f.id == 222333}
74
+ assert_equal('This field perpetuates the glorification of the ego. Also, it has a character limit.',
75
+ friend.about_me)
76
+ assert_equal('Facebook Developers', friend.affiliations.first.name)
77
+ assert_equal('Friendship', friend.meeting_for.first)
78
+ assert_equal('94303', friend.current_location.zip)
79
+ assert_equal('York', friend.hometown_location.city)
80
+ assert_equal('Harvard', friend.education_history.first.name)
81
+ assert(friend.education_history.first.concentrations.include?("Computer Science"))
82
+ assert_equal('Central York High School', friend.hs_info.hs1_name)
83
+ assert_equal('female', friend.meeting_sex.first)
84
+ assert_equal('I rule', friend.status.message)
85
+ end
86
+
87
+ def test_can_get_specific_info_for_one_or_more_users
88
+ friends = populate_session_friends_with_limited_fields
89
+ friend = friends.detect{|f| f.id == 222333}
90
+ assert_equal('I rule', friend.status.message)
91
+ assert_equal(nil, friend.hometown_location)
92
+ end
93
+
94
+ def test_session_can_expire_on_server_and_client_handles_appropriately
95
+ mock_http = establish_session
96
+ mock_http.should_receive(:post_form).and_return(example_session_expired_error_response).once.ordered(:posts)
97
+ assert_raises(Facebooker::Session::SessionExpired) {
98
+ @session.user.friends
99
+ }
100
+ end
101
+
102
+
103
+ def test_can_publish_story_to_users_feed
104
+ mock_http = establish_session
105
+ mock_http.should_receive(:post_form).and_return(example_publish_story_xml).once.ordered(:posts)
106
+ assert_nothing_raised {
107
+ assert(@session.user.publish_story((s = Facebooker::Feed::Story.new; s.title = 'o hai'; s.body = '4srsly'; s)))
108
+ }
109
+ end
110
+
111
+
112
+ def test_can_publish_action_to_users_feed
113
+ mock_http = establish_session
114
+ mock_http.should_receive(:post_form).and_return(example_publish_action_xml).once.ordered(:posts)
115
+ assert_nothing_raised {
116
+ assert(@session.user.publish_action((s = Facebooker::Feed::Action.new; s.title = 'o hai'; s.body = '4srsly'; s)))
117
+ }
118
+ end
119
+
120
+ def test_can_publish_templatized_action_to_users_feed
121
+ mock_http = establish_session
122
+ mock_http.should_receive(:post_form).and_return(example_publish_templatized_action_xml).once.ordered(:posts)
123
+ assert_nothing_raised {
124
+ action = Facebooker::Feed::TemplatizedAction.new
125
+ action.actor_id = '12345'
126
+ action.title_template = "{actor} did something"
127
+ assert(@session.user.publish_templatized_action(action))
128
+ }
129
+ end
130
+
131
+ def test_can_publish_templatized_action_to_users_feed_with_params_as_string
132
+ json_data="{\"move\": \"punch\"}"
133
+ action = Facebooker::Feed::TemplatizedAction.new
134
+ action.title_template = "{actor} did something "
135
+ action.title_data=json_data
136
+ assert_equal action.to_params[:title_data],json_data
137
+ end
138
+
139
+ def test_can_publish_templatized_action_to_users_feed_with_params_as_hash
140
+ json_data="{\"move\": \"punch\"}"
141
+ hash={:move=>"punch"}
142
+ hash.expects(:to_json).returns(json_data)
143
+ action = Facebooker::Feed::TemplatizedAction.new
144
+ action.title_template = "{actor} did something "
145
+ action.title_data=hash
146
+ assert_equal action.to_params[:title_data],json_data
147
+ end
148
+
149
+ def test_can_get_notifications_for_logged_in_user
150
+ mock_http = establish_session
151
+ mock_http.should_receive(:post_form).and_return(example_notifications_get_xml).once.ordered(:posts)
152
+ assert_equal("1", @session.user.notifications.messages.unread)
153
+ assert_equal("0", @session.user.notifications.pokes.unread)
154
+ assert_equal("1", @session.user.notifications.shares.unread)
155
+ end
156
+
157
+ def test_can_send_notifications
158
+ mock_http = establish_session
159
+ mock_http.should_receive(:post_form).and_return(example_notifications_send_xml).once.ordered(:posts)
160
+ assert_nothing_raised {
161
+ user_ids = [123, 321]
162
+ notification_fbml = "O HAI!!!"
163
+ optional_email_fbml = "This would be in the email. If this is not passed, facebook sends no mailz!"
164
+ assert_equal('http://www.facebook.com/send_email.php?from=211031&id=52', @session.send_notification(user_ids, notification_fbml, optional_email_fbml))
165
+ }
166
+ end
167
+
168
+ def test_can_send_emails
169
+ mock_http = establish_session
170
+ mock_http.should_receive(:post_form).and_return(example_notifications_send_email_xml).once.ordered(:posts)
171
+ assert_nothing_raised {
172
+ user_ids = [123, 321]
173
+ text = "Hi I am the text part of the email."
174
+ fbml = "Hi I am the fbml version of the <b>email</a>"
175
+ subject = "Somethign you should really pay attention to."
176
+ assert_equal('123,321', @session.send_email(user_ids, subject,text,fbml ))
177
+ }
178
+ end
179
+
180
+ def test_can_find_friends_who_have_installed_app
181
+ mock_http = establish_session
182
+ mock_http.should_receive(:post_form).and_return(example_app_users_xml).once.ordered(:posts)
183
+ assert_equal(2, @session.user.friends_with_this_app.size)
184
+ assert_equal([222333, 1240079], @session.user.friends_with_this_app.map{|f| f.id})
185
+ end
186
+
187
+ def test_when_marshaling_a_session_object_only_enough_data_to_stay_authenticated_is_stored
188
+ populate_session_friends
189
+ assert_equal(2, @session.user.friends.size)
190
+ reloaded_session = Marshal.load(Marshal.dump(@session))
191
+ %w(@session_key @uid @expires @secret_from_session @auth_token).each do |iv_name|
192
+ assert_not_nil(reloaded_session.instance_variable_get(iv_name))
193
+ end
194
+ assert_nil(reloaded_session.user.instance_variable_get("@friends"))
195
+ end
196
+
197
+ def test_sessions_can_be_infinite_or_can_expire
198
+ establish_session
199
+ assert(@session.expired?, "Session with expiry time #{@session.instance_variable_get('@expires')} occurred in the past and should be expired.")
200
+ @session.instance_variable_set("@expires", 0)
201
+ assert(@session.infinite?)
202
+ assert(!@session.expired?)
203
+ end
204
+
205
+ def test_session_can_tell_you_if_it_has_been_secured
206
+ mock = flexmock(Net::HTTP).should_receive(:post_form).and_return(example_auth_token_xml).once.ordered(:posts)
207
+ mock.should_receive(:post_form).and_return(example_get_session_xml.sub(/1173309298/, (Time.now + 60).to_i.to_s)).once.ordered(:posts)
208
+ @session.secure!
209
+ assert(@session.secured?)
210
+ end
211
+
212
+ def test_can_get_photos_by_pids
213
+ mock_http = establish_session
214
+ mock_http.should_receive(:post_form).and_return(example_get_photo_xml).once.ordered(:posts)
215
+ photos = @session.get_photos([97503428461115590, 97503428461115573])
216
+ assert_equal 2, photos.size
217
+ assert_equal "Rooftop barbecues make me act funny", photos.first.caption
218
+ end
219
+
220
+ def test_can_get_photos_by_subject_and_album
221
+ mock_http = establish_session
222
+ mock_http.should_receive(:post_form).and_return(example_get_photo_xml).once.ordered(:posts)
223
+ photos = @session.get_photos(nil, 22701786, 97503428432802022 )
224
+ assert_equal '97503428432802022', photos.first.aid
225
+ end
226
+
227
+ def test_getting_photos_requires_arguments
228
+ mock_http = establish_session
229
+ assert_raise(ArgumentError) { @session.get_photos() }
230
+ end
231
+
232
+ def test_can_get_albums_for_user
233
+ mock_http = establish_session
234
+ mock_http.should_receive(:post_form).and_return(example_user_albums_xml).once.ordered(:posts)
235
+ assert_equal('Summertime is Best', @session.user.albums.first.name)
236
+ assert_equal(2, @session.user.albums.size)
237
+ end
238
+
239
+ def test_can_get_albums_by_album_ids
240
+ mock_http = establish_session
241
+ mock_http.should_receive(:post_form).and_return(example_user_albums_xml).once.ordered(:posts)
242
+ albums = @session.get_albums([97503428432802022, 97503428432797817] )
243
+ assert_equal('Summertime is Best', albums[0].name)
244
+ assert_equal('Bonofon\'s Recital', albums[1].name)
245
+ end
246
+
247
+ def test_can_create_album
248
+ mock_http = establish_session
249
+ mock_http.should_receive(:post_form).and_return(example_new_album_xml).once.ordered(:posts)
250
+ assert_equal "My Empty Album", @session.user.create_album(:name => "My Empty Album", :location => "Limboland").name
251
+ end
252
+
253
+ def test_can_upload_photo
254
+ mock_http = establish_session
255
+ mock_http.should_receive(:post_multipart_form).and_return(example_upload_photo_xml).once.ordered(:posts)
256
+ f = Net::HTTP::MultipartPostFile.new("image.jpg", "image/jpeg", "RAW DATA")
257
+ assert_equal "Under the sunset", @session.user.upload_photo(f).caption
258
+ end
259
+
260
+ def test_can_get_photo_tags
261
+ mock_http = establish_session
262
+ mock_http.should_receive(:post_form).and_return(example_photo_tags_xml).once.ordered(:posts)
263
+ assert_instance_of Facebooker::Tag, @session.get_tags(:pids => 97503428461115571 ).first
264
+ end
265
+
266
+ # TODO: how to test that tags were created properly? Response doesn't contain much
267
+ def test_can_tag_a_user_in_a_photo
268
+ mock_http = establish_session
269
+ mock_http.should_receive(:post_form).and_return(example_add_tag_xml).once.ordered(:posts)
270
+ assert !@session.add_tags(pid = 97503428461115571, x= 30.0, y = 62.5, tag_uid = 1234567890).nil?
271
+ end
272
+
273
+ def test_can_add_multiple_tags_to_photos
274
+ end
275
+
276
+ def test_can_get_coordinates_for_photo_tags
277
+ mock_http = establish_session
278
+ mock_http.should_receive(:post_form).and_return(example_photo_tags_xml).once.ordered(:posts)
279
+ tag = @session.get_tags([97503428461115571]).first
280
+ assert_equal ['65.4248', '16.8627'], tag.coordinates
281
+ end
282
+
283
+ def test_can_get_app_profile_fbml_for_user
284
+ mock_http = establish_session
285
+ mock_http.should_receive(:post_form).and_return(example_get_fbml_xml).once.ordered(:posts)
286
+ assert_match(/My profile!/, @session.user.profile_fbml)
287
+ end
288
+
289
+ def test_can_set_app_profile_fbml_for_user
290
+ mock_http = establish_session
291
+ mock_http.should_receive(:post_form).and_return(example_set_fbml_xml).once.ordered(:posts)
292
+ assert_nothing_raised {
293
+ @session.user.profile_fbml = 'aha!'
294
+ }
295
+ end
296
+
297
+ def test_desktop_apps_cannot_request_to_get_or_set_profile_fbml_for_any_user_other_than_logged_in_user
298
+ mock_http = establish_session(@desktop_session)
299
+ mock_http.should_receive(:post_form).and_return(example_friends_xml).once.ordered(:posts)
300
+ assert_raises(Facebooker::NonSessionUser) {
301
+ @desktop_session.user.friends.first.profile_fbml
302
+ }
303
+ assert_raises(Facebooker::NonSessionUser) {
304
+ @desktop_session.user.friends.first.profile_fbml = "O rly"
305
+ }
306
+ end
307
+
308
+ private
309
+ def populate_user_info
310
+ mock_http = establish_session
311
+ mock_http.should_receive(:post_form).and_return(example_user_info_xml).once
312
+ @session.user.populate
313
+ end
314
+
315
+ def populate_user_info_with_limited_fields
316
+ mock_http = establish_session
317
+ mock_http.should_receive(:post_form).and_return(example_limited_user_info_xml).once.ordered(:posts)
318
+ @session.user.populate(:affiliations, :status, :meeting_for)
319
+ end
320
+
321
+ def populate_session_friends
322
+ mock_http = establish_session
323
+ mock_http.should_receive(:post_form).and_return(example_friends_xml).once.ordered(:posts)
324
+ mock_http.should_receive(:post_form).and_return(example_user_info_xml).once.ordered(:posts)
325
+ @session.user.friends!
326
+ end
327
+
328
+ def populate_session_friends_with_limited_fields
329
+ mock_http = establish_session
330
+ mock_http.should_receive(:post_form).and_return(example_friends_xml).once.ordered(:posts)
331
+ mock_http.should_receive(:post_form).and_return(example_limited_user_info_xml).once.ordered(:posts)
332
+ @session.user.friends!(:affiliations, :status, :meeting_for)
333
+ end
334
+
335
+ def sample_args_to_post
336
+ {:method=>"facebook.auth.createToken", :sig=>"18b3dc4f5258a63c0ad641eebd3e3930"}
337
+ end
338
+
339
+ def example_set_fbml_xml
340
+ <<-XML
341
+ <?xml version="1.0" encoding="UTF-8"?>
342
+ <profile_setFBML_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</profile_setFBML_response>
343
+ XML
344
+ end
345
+
346
+ def example_get_fbml_xml
347
+ <<-XML
348
+ <?xml version="1.0" encoding="UTF-8"?>
349
+ <profile_getFBML_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
350
+ &lt;fb:if-is-own-profile&gt;My profile!
351
+ &lt;fb:else&gt; Not my profile!&lt;/fb:else&gt;
352
+ &lt;/fb:if-is-own-profile&gt;
353
+ </profile_getFBML_response>
354
+ XML
355
+ end
356
+
357
+ def example_notifications_send_xml
358
+ <<-XML
359
+ <?xml version="1.0" encoding="UTF-8"?>
360
+ <notifications_send_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">http://www.facebook.com/send_email.php?from=211031&id=52</notifications_send_response>
361
+ XML
362
+ end
363
+
364
+ def example_notifications_send_email_xml
365
+ <<-XML
366
+ <?xml version="1.0" encoding="UTF-8"?>
367
+ <notifications_sendEmail_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">123,321</notifications_sendEmail_response>
368
+ XML
369
+ end
370
+
371
+ def example_request_send_xml
372
+ <<-XML
373
+ <?xml version="1.0" encoding="UTF-8"?>
374
+ <notifications_sendRequest_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">http://www.facebook.com/send_req.php?from=211031&id=6</notifications_sendRequest_response>
375
+ XML
376
+ end
377
+
378
+ def example_notifications_get_xml
379
+ <<-XML
380
+ <?xml version="1.0" encoding="UTF-8"?>
381
+ <notifications_get_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
382
+ <messages>
383
+ <unread>1</unread>
384
+ <most_recent>1170644932</most_recent>
385
+ </messages>
386
+ <pokes>
387
+ <unread>0</unread>
388
+ <most_recent>0</most_recent>
389
+ </pokes>
390
+ <shares>
391
+ <unread>1</unread>
392
+ <most_recent>1170657686</most_recent>
393
+ </shares>
394
+ <friend_requests list="true">
395
+ <uid>2231342839</uid>
396
+ <uid>2231511925</uid>
397
+ <uid>2239284527</uid>
398
+ </friend_requests>
399
+ <group_invites list="true"/>
400
+ <event_invites list="true"/>
401
+ </notifications_get_response>
402
+ XML
403
+ end
404
+
405
+ def example_publish_story_xml
406
+ <<-XML
407
+ <?xml version="1.0" encoding="UTF-8"?>
408
+ <feed_publishStoryToUser_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</feed_publishStoryToUser_response>
409
+ XML
410
+ end
411
+
412
+ def example_publish_action_xml
413
+ <<-XML
414
+ <?xml version="1.0" encoding="UTF-8"?>
415
+ <feed_publishActionOfUser_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</feed_publishActionOfUser_response>
416
+ XML
417
+ end
418
+
419
+ def example_publish_templatized_action_xml
420
+ <<-XML
421
+ <?xml version="1.0" encoding="UTF-8"?>
422
+ <feed_publishTemplatizedAction_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
423
+ <feed_publishTemplatizedAction_response_elt>1</feed_publishTemplatizedAction_response_elt>
424
+ </feed_publishTemplatizedAction_response>
425
+ XML
426
+ end
427
+
428
+ def example_user_info_xml
429
+ <<-XML
430
+ <?xml version="1.0" encoding="UTF-8"?>
431
+ <users_getInfo_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
432
+ <user>
433
+ <uid>222333</uid>
434
+ <about_me>This field perpetuates the glorification of the ego. Also, it has a character limit.</about_me>
435
+ <activities>Here: facebook, etc. There: Glee Club, a capella, teaching.</activities>
436
+ <affiliations list="true">
437
+ <affiliation>
438
+ <nid>50453093</nid>
439
+ <name>Facebook Developers</name>
440
+ <type>work</type>
441
+ <status/>
442
+ <year/>
443
+ </affiliation>
444
+ </affiliations>
445
+ <birthday>November 3</birthday>
446
+ <books>The Brothers K, GEB, Ken Wilber, Zen and the Art, Fitzgerald, The Emporer's New Mind, The Wonderful Story of Henry Sugar</books>
447
+ <current_location>
448
+ <city>Palo Alto</city>
449
+ <state>CA</state>
450
+ <country>United States</country>
451
+ <zip>94303</zip>
452
+ </current_location>
453
+ <education_history list="true">
454
+ <education_info>
455
+ <name>Harvard</name>
456
+ <year>2003</year>
457
+ <concentrations list="true">
458
+ <concentration>Applied Mathematics</concentration>
459
+ <concentration>Computer Science</concentration>
460
+ </concentrations>
461
+ <degree>Masters</degree>
462
+ </education_info>
463
+ </education_history>
464
+ <first_name>Dave</first_name>
465
+ <hometown_location>
466
+ <city>York</city>
467
+ <state>PA</state>
468
+ <country>United States</country>
469
+ <zip>0</zip>
470
+ </hometown_location>
471
+ <hs_info>
472
+ <hs1_name>Central York High School</hs1_name>
473
+ <hs2_name/>
474
+ <grad_year>1999</grad_year>
475
+ <hs1_id>21846</hs1_id>
476
+ <hs2_id>0</hs2_id>
477
+ </hs_info>
478
+ <is_app_user>1</is_app_user>
479
+ <has_added_app>1</has_added_app>
480
+ <interests>coffee, computers, the funny, architecture, code breaking,snowboarding, philosophy, soccer, talking to strangers</interests>
481
+ <last_name>Fetterman</last_name>
482
+ <meeting_for list="true">
483
+ <seeking>Friendship</seeking>
484
+ </meeting_for>
485
+ <meeting_sex list="true">
486
+ <sex>female</sex>
487
+ </meeting_sex>
488
+ <movies>Tommy Boy, Billy Madison, Fight Club, Dirty Work, Meet the Parents, My Blue Heaven, Office Space </movies>
489
+ <music>New Found Glory, Daft Punk, Weezer, The Crystal Method, Rage, the KLF, Green Day, Live, Coldplay, Panic at the Disco, Family Force 5</music>
490
+ <name>Dave Fetterman</name>
491
+ <notes_count>0</notes_count>
492
+ <pic>http://photos-055.facebook.com/ip007/profile3/1271/65/s8055_39735.jpg</pic>
493
+ <pic_big>http://photos-055.facebook.com/ip007/profile3/1271/65/n8055_39735.jpg</pic_big>
494
+ <pic_small>http://photos-055.facebook.com/ip007/profile3/1271/65/t8055_39735.jpg</pic_small>
495
+ <pic_square>http://photos-055.facebook.com/ip007/profile3/1271/65/q8055_39735.jpg</pic_square>
496
+ <political>Moderate</political>
497
+ <profile_update_time>1170414620</profile_update_time>
498
+ <quotes/>
499
+ <relationship_status>In a Relationship</relationship_status>
500
+ <religion/>
501
+ <sex>male</sex>
502
+ <significant_other_id xsi:nil="true"/>
503
+ <status>
504
+ <message>I rule</message>
505
+ <time>0</time>
506
+ </status>
507
+ <timezone>-8</timezone>
508
+ <tv>cf. Bob Trahan</tv>
509
+ <wall_count>121</wall_count>
510
+ <work_history list="true">
511
+ <work_info>
512
+ <location>
513
+ <city>Palo Alto</city>
514
+ <state>CA</state>
515
+ <country>United States</country>
516
+ </location>
517
+ <company_name>Facebook</company_name>
518
+ <position>Software Engineer</position>
519
+ <description>Tech Lead, Facebook Platform</description>
520
+ <start_date>2006-01</start_date>
521
+ <end_date/>
522
+ </work_info>
523
+ </work_history>
524
+ </user>
525
+ <user>
526
+ <uid>1240079</uid>
527
+ <about_me>I am here.</about_me>
528
+ <activities>Party.</activities>
529
+ </user>
530
+ </users_getInfo_response>
531
+ XML
532
+ end
533
+
534
+ def example_limited_user_info_xml
535
+ <<-XML
536
+ <?xml version="1.0" encoding="UTF-8"?>
537
+ <users_getInfo_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
538
+ <user>
539
+ <uid>222333</uid>
540
+ <affiliations list="true">
541
+ <affiliation>
542
+ <nid>50453093</nid>
543
+ <name>Facebook Developers</name>
544
+ <type>work</type>
545
+ <status/>
546
+ <year/>
547
+ </affiliation>
548
+ </affiliations>
549
+ <meeting_for list="true">
550
+ <seeking>Friendship</seeking>
551
+ </meeting_for>
552
+ <status>
553
+ <message>I rule</message>
554
+ <time>0</time>
555
+ </status>
556
+ </user>
557
+ <user>
558
+ <uid>1240079</uid>
559
+ <activities>Party.</activities>
560
+ </user>
561
+ </users_getInfo_response>
562
+ XML
563
+ end
564
+
565
+
566
+ def example_friends_xml
567
+ <<-XML
568
+ <?xml version="1.0" encoding="UTF-8"?>
569
+ <friends_get_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
570
+ <uid>222333</uid>
571
+ <uid>1240079</uid>
572
+ </friends_get_response>
573
+ XML
574
+ end
575
+
576
+ def example_get_logged_in_user_xml
577
+ <<-XML
578
+ <?xml version="1.0" encoding="UTF-8"?>
579
+ <users_getLoggedInUser_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">1240077</users_getLoggedInUser_response>
580
+ XML
581
+ end
582
+
583
+ def example_invalid_api_key_error_response
584
+ <<-XML
585
+ <?xml version="1.0" encoding="UTF-8"?>
586
+ <error_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
587
+ <error_code>101</error_code>
588
+ <error_msg>Invalid API key</error_msg>
589
+ <request_args list="true">
590
+ <arg>
591
+ <key>v</key>
592
+ <value>1.0</value>
593
+ </arg>
594
+ <arg>
595
+ <key>method</key>
596
+ <value>facebook.auth.createToken</value>
597
+ </arg>
598
+ <arg>
599
+ <key>sig</key>
600
+ <value>611f5f44e55f3fe17f858a8de84a4b0a</value>
601
+ </arg>
602
+ <arg>
603
+ <key>call_id</key>
604
+ <value>1186088346.82142</value>
605
+ </arg>
606
+ </request_args>
607
+ </error_response>
608
+ XML
609
+ end
610
+
611
+ def example_session_expired_error_response
612
+ <<-XML
613
+ <?xml version="1.0" encoding="UTF-8"?>
614
+ <error_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
615
+ <error_code>102</error_code>
616
+ <error_msg>Session Expired</error_msg>
617
+ <request_args list="true">
618
+ <arg>
619
+ <key>v</key>
620
+ <value>1.0</value>
621
+ </arg>
622
+ <arg>
623
+ <key>method</key>
624
+ <value>facebook.auth.createToken</value>
625
+ </arg>
626
+ <arg>
627
+ <key>sig</key>
628
+ <value>611f5f44e55f3fe17f858a8de84a4b0a</value>
629
+ </arg>
630
+ <arg>
631
+ <key>call_id</key>
632
+ <value>1186088346.82142</value>
633
+ </arg>
634
+ </request_args>
635
+ </error_response>
636
+ XML
637
+ end
638
+
639
+ def example_app_users_xml
640
+ <<-XML
641
+ <?xml version="1.0" encoding="UTF-8"?>
642
+ <friends_getAppUsers_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
643
+ <uid>222333</uid>
644
+ <uid>1240079</uid>
645
+ </friends_getAppUsers_response>
646
+ XML
647
+ end
648
+
649
+ def example_user_albums_xml
650
+ <<-XML
651
+ <?xml version="1.0" encoding="UTF-8"?>
652
+ <photos_getAlbums_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
653
+ <album>
654
+ <aid>97503428432802022</aid>
655
+ <cover_pid>97503428461115574</cover_pid>
656
+ <owner>22701786</owner>
657
+ <name>Summertime is Best</name>
658
+ <created>1184120648</created>
659
+ <modified>1185465771</modified>
660
+ <description>Happenings on or around Summer '07</description>
661
+ <location>Brooklyn, New York</location>
662
+ <link>http://www.facebook.com/album.php?aid=2011366&amp;id=22701786</link>
663
+ <size>49</size>
664
+ </album>
665
+ <album>
666
+ <aid>97503428432797817</aid>
667
+ <cover_pid>97503428460977993</cover_pid>
668
+ <owner>22701786</owner>
669
+ <name>Bonofon's Recital</name>
670
+ <created>1165356279</created>
671
+ <modified>1165382364</modified>
672
+ <description>The whole Ewing fam flies out to flatland to watch the Bonofon's senior recital. That boy sure can tinkle them ivories.</description>
673
+ <location>Grinnell College, Grinnell Iowa</location>
674
+ <link>http://www.facebook.com/album.php?aid=2007161&amp;id=22701786</link>
675
+ <size>14</size>
676
+ </album>
677
+ </photos_getAlbums_response>
678
+ XML
679
+ end
680
+
681
+ def example_upload_photo_xml
682
+ <<-XML
683
+ <?xml version="1.0" encoding="UTF-8"?>
684
+ <photos_upload_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
685
+ <pid>940915697041656</pid>
686
+ <aid>940915667462717</aid>
687
+ <owner>219074</owner>
688
+ <src>http://ip002.facebook.com/v67/161/72/219074/s219074_31637752_5455.jpg</src>
689
+ <src_big>http://ip002.facebook.com/v67/161/72/219074/n219074_31637752_5455.jpg</src_big>
690
+ <src_small>http://ip002.facebook.com/v67/161/72/219074/t219074_31637752_5455.jpg</src_small>
691
+ <link>http://www.facebook.com/photo.php?pid=31637752&id=219074</link>
692
+ <caption>Under the sunset</caption>
693
+ </photos_upload_response>
694
+ XML
695
+ end
696
+
697
+ def example_new_album_xml
698
+ <<-XML
699
+ <?xml version="1.0" encoding="UTF-8"?>
700
+ <photos_createAlbum_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
701
+ <aid>34595963571485</aid>
702
+ <cover_pid>0</cover_pid>
703
+ <owner>8055</owner>
704
+ <name>My Empty Album</name>
705
+ <created>1132553109</created>
706
+ <modified>1132553363</modified>
707
+ <description>No I will not make out with you</description>
708
+ <location>York, PA</location>
709
+ <link>http://www.facebook.com/album.php?aid=2002205&id=8055</link>
710
+ <size>0</size>
711
+ </photos_createAlbum_response>
712
+ XML
713
+ end
714
+
715
+ def example_photo_tags_xml
716
+ <<-XML
717
+ <?xml version="1.0" encoding="UTF-8"?>
718
+ <photos_getTags_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
719
+ <photo_tag>
720
+ <pid>97503428461115571</pid>
721
+ <subject>570070524</subject>
722
+ <xcoord>65.4248</xcoord>
723
+ <ycoord>16.8627</ycoord>
724
+ </photo_tag>
725
+ </photos_getTags_response>
726
+ XML
727
+ end
728
+
729
+ def example_add_tag_xml
730
+ <<-XML
731
+ <?xml version="1.0" encoding="UTF-8"?>
732
+ <photos_addTag_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</photos_addTag_response>
733
+ XML
734
+ end
735
+
736
+ def example_get_photo_xml
737
+ <<-XML
738
+ <?xml version="1.0" encoding="UTF-8"?>
739
+ <photos_get_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
740
+ <photo>
741
+ <pid>97503428461115590</pid>
742
+ <aid>97503428432802022</aid>
743
+ <owner>22701786</owner>
744
+ <src>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324934_7816.jpg</src>
745
+ <src_big>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/n22701786_30324934_7816.jpg</src_big>
746
+ <src_small>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/t22701786_30324934_7816.jpg</src_small>
747
+ <link>http://www.facebook.com/photo.php?pid=30324934&amp;id=22701786</link>
748
+ <caption>Rooftop barbecues make me act funny</caption>
749
+ <created>1184120987</created>
750
+ </photo>
751
+ <photo>
752
+ <pid>97503428461115573</pid>
753
+ <aid>97503428432802022</aid>
754
+ <owner>22701786</owner>
755
+ <src>http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324917_4555.jpg</src>
756
+ <src_big>http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/n22701786_30324917_4555.jpg</src_big>
757
+ <src_small>http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/t22701786_30324917_4555.jpg</src_small>
758
+ <link>http://www.facebook.com/photo.php?pid=30324917&amp;id=22701786</link>
759
+ <caption/>
760
+ <created>1184120654</created>
761
+ </photo>
762
+ </photos_get_response>
763
+ XML
764
+ end
765
+
766
+ end