facebooker-lite 1.0.67

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.autotest +15 -0
  2. data/CHANGELOG.rdoc +24 -0
  3. data/COPYING.rdoc +19 -0
  4. data/Manifest.txt +114 -0
  5. data/README.rdoc +120 -0
  6. data/Rakefile +94 -0
  7. data/TODO.rdoc +4 -0
  8. data/facebooker.gemspec +42 -0
  9. data/generators/xd_receiver/templates/xd_receiver.html +10 -0
  10. data/generators/xd_receiver/templates/xd_receiver_ssl.html +10 -0
  11. data/generators/xd_receiver/xd_receiver_generator.rb +10 -0
  12. data/init.rb +25 -0
  13. data/install.rb +12 -0
  14. data/lib/facebooker.rb +261 -0
  15. data/lib/facebooker/adapters/adapter_base.rb +91 -0
  16. data/lib/facebooker/adapters/bebo_adapter.rb +77 -0
  17. data/lib/facebooker/adapters/facebook_adapter.rb +60 -0
  18. data/lib/facebooker/admin.rb +42 -0
  19. data/lib/facebooker/application.rb +37 -0
  20. data/lib/facebooker/attachment.rb +51 -0
  21. data/lib/facebooker/batch_request.rb +45 -0
  22. data/lib/facebooker/data.rb +57 -0
  23. data/lib/facebooker/feed.rb +78 -0
  24. data/lib/facebooker/logging.rb +44 -0
  25. data/lib/facebooker/mobile.rb +20 -0
  26. data/lib/facebooker/mock/service.rb +50 -0
  27. data/lib/facebooker/mock/session.rb +18 -0
  28. data/lib/facebooker/model.rb +139 -0
  29. data/lib/facebooker/models/affiliation.rb +10 -0
  30. data/lib/facebooker/models/album.rb +11 -0
  31. data/lib/facebooker/models/applicationproperties.rb +39 -0
  32. data/lib/facebooker/models/applicationrestrictions.rb +10 -0
  33. data/lib/facebooker/models/comment.rb +9 -0
  34. data/lib/facebooker/models/cookie.rb +10 -0
  35. data/lib/facebooker/models/education_info.rb +11 -0
  36. data/lib/facebooker/models/event.rb +28 -0
  37. data/lib/facebooker/models/family_relative_info.rb +7 -0
  38. data/lib/facebooker/models/friend_list.rb +16 -0
  39. data/lib/facebooker/models/group.rb +36 -0
  40. data/lib/facebooker/models/info_item.rb +10 -0
  41. data/lib/facebooker/models/info_section.rb +10 -0
  42. data/lib/facebooker/models/location.rb +8 -0
  43. data/lib/facebooker/models/message_thread.rb +89 -0
  44. data/lib/facebooker/models/notifications.rb +17 -0
  45. data/lib/facebooker/models/page.rb +46 -0
  46. data/lib/facebooker/models/photo.rb +19 -0
  47. data/lib/facebooker/models/tag.rb +12 -0
  48. data/lib/facebooker/models/user.rb +751 -0
  49. data/lib/facebooker/models/video.rb +9 -0
  50. data/lib/facebooker/models/work_info.rb +10 -0
  51. data/lib/facebooker/parser.rb +970 -0
  52. data/lib/facebooker/rails/backwards_compatible_param_checks.rb +31 -0
  53. data/lib/facebooker/rails/controller.rb +353 -0
  54. data/lib/facebooker/rails/extensions/action_controller.rb +47 -0
  55. data/lib/facebooker/rails/extensions/rack_setup.rb +16 -0
  56. data/lib/facebooker/rails/extensions/routing.rb +15 -0
  57. data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
  58. data/lib/facebooker/rails/facebook_request_fix.rb +28 -0
  59. data/lib/facebooker/rails/facebook_request_fix_2-3.rb +31 -0
  60. data/lib/facebooker/rails/facebook_session_handling.rb +68 -0
  61. data/lib/facebooker/rails/facebook_url_rewriting.rb +60 -0
  62. data/lib/facebooker/rails/helpers/fb_connect.rb +75 -0
  63. data/lib/facebooker/rails/integration_session.rb +38 -0
  64. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  65. data/lib/facebooker/rails/publisher.rb +608 -0
  66. data/lib/facebooker/rails/routing.rb +49 -0
  67. data/lib/facebooker/rails/test_helpers.rb +68 -0
  68. data/lib/facebooker/rails/utilities.rb +22 -0
  69. data/lib/facebooker/server_cache.rb +24 -0
  70. data/lib/facebooker/service.rb +103 -0
  71. data/lib/facebooker/service/base_service.rb +19 -0
  72. data/lib/facebooker/service/curl_service.rb +44 -0
  73. data/lib/facebooker/service/net_http_service.rb +12 -0
  74. data/lib/facebooker/service/typhoeus_multi_service.rb +27 -0
  75. data/lib/facebooker/service/typhoeus_service.rb +17 -0
  76. data/lib/facebooker/session.rb +786 -0
  77. data/lib/facebooker/stream_post.rb +19 -0
  78. data/lib/facebooker/version.rb +9 -0
  79. data/lib/net/http_multipart_post.rb +123 -0
  80. data/lib/rack/facebook.rb +89 -0
  81. data/lib/rack/facebook_session.rb +21 -0
  82. data/lib/tasks/facebooker.rake +19 -0
  83. data/lib/tasks/facebooker.rb +2 -0
  84. data/lib/tasks/tunnel.rake +46 -0
  85. data/rails/init.rb +1 -0
  86. data/setup.rb +1585 -0
  87. data/templates/layout.erb +24 -0
  88. data/test/facebooker/adapters_test.rb +191 -0
  89. data/test/facebooker/admin_test.rb +102 -0
  90. data/test/facebooker/application_test.rb +110 -0
  91. data/test/facebooker/attachment_test.rb +72 -0
  92. data/test/facebooker/batch_request_test.rb +83 -0
  93. data/test/facebooker/data_test.rb +86 -0
  94. data/test/facebooker/logging_test.rb +43 -0
  95. data/test/facebooker/mobile_test.rb +45 -0
  96. data/test/facebooker/model_test.rb +133 -0
  97. data/test/facebooker/models/event_test.rb +15 -0
  98. data/test/facebooker/models/page_test.rb +56 -0
  99. data/test/facebooker/models/photo_test.rb +16 -0
  100. data/test/facebooker/models/user_test.rb +1074 -0
  101. data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +25 -0
  102. data/test/facebooker/rails/facebook_url_rewriting_test.rb +76 -0
  103. data/test/facebooker/rails/integration_session_test.rb +13 -0
  104. data/test/facebooker/rails/publisher_test.rb +538 -0
  105. data/test/facebooker/rails_integration_test.rb +1543 -0
  106. data/test/facebooker/server_cache_test.rb +44 -0
  107. data/test/facebooker/service_test.rb +58 -0
  108. data/test/facebooker/session_test.rb +883 -0
  109. data/test/facebooker_test.rb +1263 -0
  110. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  111. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  112. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  113. data/test/net/http_multipart_post_test.rb +52 -0
  114. data/test/rack/facebook_session_test.rb +34 -0
  115. data/test/rack/facebook_test.rb +73 -0
  116. data/test/rails_test_helper.rb +36 -0
  117. data/test/test_helper.rb +74 -0
  118. metadata +278 -0
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class FacebookCacheTest < Test::Unit::TestCase
4
+ def setup
5
+ @session = Facebooker::Session.create('apikey', 'secretkey')
6
+ Facebooker.use_curl=false
7
+ end
8
+
9
+ def test_can_ask_facebook_to_store_fbml_in_a_named_reference
10
+ expect_http_posts_with_responses(example_set_ref_handle_xml)
11
+ assert(@session.server_cache.set_ref_handle('a_handle_name', '<h2>Some FBML</h2>'))
12
+ end
13
+
14
+ def test_can_ask_facebook_to_recache_content_stored_from_a_given_url
15
+ expect_http_posts_with_responses(example_refresh_ref_url_xml)
16
+ assert(@session.server_cache.refresh_ref_url('http://localhost/roflmao'))
17
+ end
18
+
19
+ def test_can_ask_facebook_to_recache_an_img
20
+ expect_http_posts_with_responses(example_refresh_img_xml)
21
+ assert(@session.server_cache.refresh_img_src('http://localhost/roflmao.jpg'))
22
+ end
23
+
24
+ private
25
+ def example_set_ref_handle_xml
26
+ <<-XML
27
+ <?xml version="1.0" encoding="UTF-8"?>
28
+ <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>
29
+ XML
30
+ end
31
+
32
+ def example_refresh_ref_url_xml
33
+ <<-XML
34
+ <?xml version="1.0" encoding="UTF-8"?>
35
+ <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>
36
+ XML
37
+ end
38
+ def example_refresh_img_xml
39
+ <<-XML
40
+ <?xml version="1.0" encoding="UTF-8"?>
41
+ <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>
42
+ XML
43
+ end
44
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+ require 'active_support'
3
+ # make sure the class exists
4
+ class ::Facebooker::Service::CurlService < Facebooker::Service::BaseService
5
+ end
6
+
7
+ class ::Facebooker::Service::TyphoeusMultiService
8
+ def process
9
+ end
10
+ end
11
+
12
+ class Facebooker::ServiceTest < Test::Unit::TestCase
13
+
14
+ def test_should_use_the_curl_service
15
+ Facebooker.use_curl = true
16
+ Facebooker::Service.active_service= nil
17
+ assert(Facebooker::Service::CurlService === Facebooker::Service.active_service)
18
+ ensure
19
+ Facebooker::Service.active_service= nil
20
+ end
21
+
22
+ def test_should_allow_changing_the_service_in_a_block
23
+ Facebooker::Service.with_service("MyService") do
24
+ assert_equal(Facebooker::Service.active_service,"MyService")
25
+ end
26
+
27
+ end
28
+
29
+ def test_should_restore_the_original_service_even_with_an_exception
30
+ original_service = Facebooker::Service.active_service
31
+ begin
32
+ Facebooker::Service.with_service("MyService") do
33
+ raise "This is a test"
34
+ end
35
+ fail("Should have raised")
36
+ rescue
37
+ end
38
+ assert_equal(original_service,Facebooker::Service.active_service)
39
+ end
40
+
41
+ def test_should_allow_using_the_async_service
42
+ Facebooker::Service.with_async do
43
+ assert(Facebooker::Service::TyphoeusMultiService === Facebooker::Service.active_service)
44
+ @called = true
45
+ end
46
+ assert @called
47
+ end
48
+
49
+ def test_should_call_process_at_the_end_of_the_block
50
+ Facebooker::Service.with_async do
51
+ Facebooker::Service.active_service.expects(:process)
52
+ @called = true
53
+ end
54
+ assert @called
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,883 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+ require 'active_support'
3
+
4
+ class Facebooker::SessionTest < Test::Unit::TestCase
5
+
6
+
7
+ def setup
8
+ ENV['FACEBOOK_API_KEY'] = '1234567'
9
+ ENV['FACEBOOK_SECRET_KEY'] = '7654321'
10
+ Facebooker.current_adapter = nil
11
+ @session = Facebooker::Session.create('whatever', 'doesnotmatterintest')
12
+ Facebooker.use_curl=false
13
+ end
14
+
15
+ def teardown
16
+ Facebooker::Session.configuration_file_path = nil
17
+ super
18
+ end
19
+
20
+ def test_install_url_escapes_optional_next_parameter
21
+ session = Facebooker::CanvasSession.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
22
+ assert_equal("http://www.facebook.com/install.php?api_key=1234567&v=1.0&next=next_url%3Fa%3D1%26b%3D2", session.install_url(:next => "next_url?a=1&b=2"))
23
+ end
24
+
25
+ def test_permission_url_returns_correct_url_and_parameters
26
+ fb_url = "http://www.facebook.com/connect/prompt_permissions.php?api_key=#{ENV['FACEBOOK_API_KEY']}&v=1.0&next=next_url&ext_perm=publish_stream,email"
27
+ url = Facebooker::Session.new(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY']).connect_permission_url('publish_stream,email', {:next => 'next_url'})
28
+ assert_equal url, fb_url
29
+ end
30
+
31
+ def test_login_url_skips_all_parameters_when_not_passed_or_false
32
+ session = Facebooker::Session.new(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
33
+ url = session.login_url({:fbconnect => false})
34
+ expected_url = Facebooker.login_url_base
35
+ assert_equal url, expected_url
36
+ end
37
+
38
+ def test_login_url_adds_all_parameters_when_passed
39
+ login_options = {:skipcookie => true,
40
+ :hide_checkbox => true,
41
+ :canvas => true,
42
+ :fbconnect => true,
43
+ :req_perms => 'publish_stream',
44
+ :next => 'http://example.com'}
45
+
46
+ session = Facebooker::Session.new(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
47
+ url = session.login_url(login_options)
48
+ expected_url = "#{Facebooker.login_url_base}&next=#{CGI.escape(login_options[:next])}&hide_checkbox=true&canvas=true&fbconnect=true&req_perms=publish_stream"
49
+ assert_equal url, expected_url
50
+ end
51
+
52
+ def test_can_get_api_and_secret_key_from_environment
53
+ assert_equal('1234567', Facebooker::Session.api_key)
54
+ assert_equal('7654321', Facebooker::Session.secret_key)
55
+ end
56
+
57
+ def test_if_keys_are_not_available_via_environment_then_they_are_gotten_from_a_file
58
+ ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'] = nil
59
+ Facebooker.instance_variable_set('@facebooker_configuration', nil)
60
+ flexmock(File).should_receive(:read).with(File.expand_path("~/.facebookerrc")).once.and_return('{:api => "foo"}')
61
+ assert_equal('foo', Facebooker::Session.api_key)
62
+ end
63
+
64
+ def test_if_environment_and_file_fail_to_match_then_an_exception_is_raised
65
+ ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'] = nil
66
+ Facebooker.instance_variable_set('@facebooker_configuration', nil)
67
+ flexmock(File).should_receive(:read).with(File.expand_path("~/.facebookerrc")).once.and_return {raise Errno::ENOENT, "No such file"}
68
+ assert_raises(Facebooker::Session::ConfigurationMissing) {
69
+ Facebooker::Session.api_key
70
+ }
71
+ end
72
+
73
+ def test_marshal_stores_api_key
74
+ data = Marshal.dump(@session)
75
+ loaded_session = Marshal.load(data)
76
+ assert_equal 'whatever', loaded_session.instance_variable_get("@api_key")
77
+ end
78
+
79
+ def test_marshal_stores_secret_key
80
+ data = Marshal.dump(@session)
81
+ loaded_session = Marshal.load(data)
82
+ assert_equal 'doesnotmatterintest', loaded_session.instance_variable_get("@secret_key")
83
+ end
84
+
85
+ def test_configuration_file_path_can_be_set_explicitly
86
+ Facebooker::Session.configuration_file_path = '/tmp/foo'
87
+ assert_equal('/tmp/foo', Facebooker::Session.configuration_file_path)
88
+ end
89
+
90
+ def test_session_can_be_secured_with_existing_values
91
+ session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
92
+ session.secure_with!("a session key", "123456", Time.now.to_i + 60)
93
+ assert(session.secured?)
94
+ assert_equal 'a session key', session.session_key
95
+ assert_equal 123456, session.user.to_i
96
+ end
97
+
98
+ def test_session_can_be_secured_with_existing_values_and_a_nil_uid
99
+ flexmock(session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY']))
100
+ session.should_receive(:post).with('facebook.users.getLoggedInUser', :session_key => 'a session key').returns(321)
101
+ session.secure_with!("a session key", nil, Time.now.to_i + 60)
102
+ assert(session.secured?)
103
+ assert_equal 'a session key', session.session_key
104
+ assert_equal 321, session.user.to_i
105
+ end
106
+
107
+ # The Facebook API for this is hideous. Oh well.
108
+ def test_can_ask_session_to_check_friendship_between_pairs_of_users
109
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
110
+ mock_http = establish_session
111
+ mock_http.should_receive(:post_form).and_return(example_check_friendship_xml).once.ordered(:posts)
112
+ assert_equal({[222332, 222333] => true, [1240077, 1240079] => false}, @session.check_friendship([[222332, 222333], [1240077, 1240079]]))
113
+ end
114
+
115
+ def test_facebook_can_claim_ignorance_as_to_friend_relationships
116
+ mock_http = establish_session
117
+ mock_http.should_receive(:post_form).and_return(example_check_friendship_with_unknown_result).once.ordered(:posts)
118
+ assert_equal({[1240077, 1240079] => nil}, @session.check_friendship([[1240077, 1240079]]))
119
+ end
120
+
121
+ def test_can_query_with_fql
122
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
123
+ expect_http_posts_with_responses(example_fql_for_multiple_photos_xml)
124
+ response = @session.fql_query('Lets be frank. We are not testing the query here')
125
+ assert_kind_of(Facebooker::Photo, response.first)
126
+ end
127
+
128
+ def test_anonymous_fql_results_get_put_in_a_positioned_array_on_the_model
129
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
130
+ expect_http_posts_with_responses(example_fql_for_multiple_photos_with_anon_xml)
131
+ response = @session.fql_query('Lets be frank. We are not testing the query here')
132
+ assert_kind_of(Facebooker::Photo, response.first)
133
+ response.each do |photo|
134
+ assert_equal(['first', 'second'], photo.anonymous_fields)
135
+ end
136
+ end
137
+ def test_no_results_returns_empty_array
138
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
139
+ expect_http_posts_with_responses(no_results_fql)
140
+ response = @session.fql_query('Lets be frank. We are not testing the query here')
141
+ assert_equal [],response
142
+ end
143
+
144
+ def test_can_fql_query_for_event_members
145
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
146
+ expect_http_posts_with_responses(example_fql_query_event_members_xml)
147
+ response = @session.fql_query("DOES NOT REALLY MATTER FOR TEST")
148
+ assert_kind_of(Facebooker::Event::Attendance, response.first)
149
+ assert_equal('attending', response.first.rsvp_status)
150
+ end
151
+
152
+ def test_can_fql_query_for_events
153
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
154
+ expect_http_posts_with_responses(example_fql_query_events_xml)
155
+ response = @session.fql_query("DOES NOT REALLY MATTER FOR TEST")
156
+ assert_kind_of(Facebooker::Event, response.first)
157
+ assert_equal('Technology Tasting', response.first.name)
158
+ end
159
+
160
+ def test_can_fql_query_for_albums
161
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
162
+ expect_http_posts_with_responses(example_fql_query_albums_xml)
163
+ response = @session.fql_query("DOES NOT REALLY MATTER FOR TEST")
164
+ assert_kind_of(Facebooker::Album, response.first)
165
+ assert_equal('Films you will never see', response.first.name)
166
+ end
167
+
168
+ def test_can_query_for_event_members
169
+ expect_http_posts_with_responses(example_event_members_xml)
170
+ event_attendances = @session.event_members(69)
171
+ assert_equal Facebooker::Event::Attendance, event_attendances.first.class
172
+ assert_equal 'attending', event_attendances.first.rsvp_status
173
+ assert_equal(["1240077", "222332", "222333", "222335", "222336"], event_attendances.map{|ea| ea.uid}.sort)
174
+ assert_equal 5, event_attendances.size
175
+ end
176
+
177
+ def test_query_for_event_members_caching_honors_params
178
+ @session.expects(:post).returns(["1"])
179
+ assert_equal ["1"], @session.event_members(100)
180
+ @session.expects(:post).returns(["2"])
181
+ assert_equal ["2"],@session.event_members(200)
182
+ @session.expects(:post).never
183
+ assert_equal ["1"],@session.event_members(100)
184
+ end
185
+
186
+ def test_can_create_events
187
+ mock_http = establish_session
188
+ mock_http.should_receive(:post_multipart_form).and_return(example_event_create_xml).once
189
+ event_id = @session.create_event(:name => 'foo', :category => 'bar')
190
+ assert_equal '34444349712', event_id
191
+ end
192
+
193
+ def test_can_create_events_with_time_zones
194
+ mock_http = establish_session
195
+ mock_session = flexmock(@session)
196
+
197
+ # Start time is Jan 1, 2012 at 12:30pm EST
198
+ # This should be sent to Facebook as 12:30pm PST, or 1325449800 in Epoch time
199
+ start_time = ActiveSupport::TimeZone["Eastern Time (US & Canada)"].parse("2012-01-01 12:30:00")
200
+
201
+ # End time is July 4, 2012 at 3:00pm CDT
202
+ # Should be sent to Facebook as 3:00pm PDT, or 1341439200 in Epoch time
203
+ end_time = ActiveSupport::TimeZone["Central Time (US & Canada)"].parse("2012-07-04 15:00:00")
204
+
205
+ expected_info = {
206
+ 'name' => 'foo',
207
+ 'category' => 'bar',
208
+ 'start_time' => 1325449800,
209
+ 'end_time' => 1341439200
210
+ }.to_json
211
+
212
+ mock_session.should_receive(:post_file).once.with('facebook.events.create', {:event_info => expected_info, nil => nil}).and_return(example_event_create_xml).once
213
+ mock_session.create_event('name' => 'foo', 'category' => 'bar', :start_time => start_time, :end_time => end_time)
214
+ end
215
+
216
+ def test_can_cancel_events
217
+ expect_http_posts_with_responses(example_event_cancel_xml)
218
+ assert @session.cancel_event("12345", :cancel_message => "It's raining")
219
+ end
220
+
221
+ def test_can_query_for_events
222
+ expect_http_posts_with_responses(example_events_get_xml)
223
+ events = @session.events
224
+ assert_equal 'Technology Tasting', events.first.name
225
+ end
226
+
227
+ def test_query_for_events_caching_honors_params
228
+ @session.expects(:post).returns([{:eid=>1}])
229
+ assert_equal 1, @session.events.first[:eid]
230
+ @session.expects(:post).returns([{:eid=>2}])
231
+ assert_equal 2,@session.events(:start_time=>1.day.ago).first[:eid]
232
+ @session.expects(:post).never
233
+ assert_equal 1,@session.events.first[:eid]
234
+ end
235
+
236
+ def test_can_query_for_groups
237
+ expect_http_posts_with_responses(example_groups_get_xml)
238
+ groups = @session.user.groups
239
+ assert_equal 'Donald Knuth Is My Homeboy', groups.first.name
240
+ end
241
+
242
+ def test_can_query_for_group_memberships
243
+ expect_http_posts_with_responses(example_group_members_xml)
244
+ example_group = Facebooker::Group.new({:gid => 123, :session => @session})
245
+ group_memberships = example_group.memberships
246
+ assert_equal('officers', group_memberships.last.position)
247
+ assert_equal(123, group_memberships.last.gid)
248
+ assert_equal(1240078, example_group.members.last.id)
249
+ end
250
+
251
+ def test_can_fql_query_for_users_and_pictures
252
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
253
+ mock_http = establish_session
254
+ mock_http.should_receive(:post_form).and_return(example_fql_for_multiple_users_and_pics).once.ordered(:posts)
255
+ response = @session.fql_query('SELECT name, pic FROM user WHERE uid=211031 OR uid=4801660')
256
+ assert_kind_of Array, response
257
+ assert_kind_of Facebooker::User, response.first
258
+ assert_equal "Ari Steinberg", response.first.name
259
+ end
260
+
261
+ def test_can_fql_multiquery_for_users_and_pictures
262
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
263
+ mock_http = establish_session
264
+ mock_http.should_receive(:post_form).and_return(example_fql_multiquery_xml).once.ordered(:posts)
265
+ response = @session.fql_multiquery({:query => 'SELECT name, pic FROM user WHERE uid=211031 OR uid=4801660'})
266
+ assert_kind_of Array, response["query1"]
267
+ assert_kind_of Facebooker::User, response["query1"].first
268
+ assert_equal "Ari Steinberg", response["query1"].first.name
269
+ end
270
+
271
+ def test_can_send_notification_with_object
272
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
273
+ @session.expects(:post).with('facebook.notifications.send',{:to_ids=>"1",:notification=>"a",:type=>"user_to_user"},true)
274
+ @session.send(:instance_variable_set,"@uid",3)
275
+ user=flexmock("user")
276
+ user.should_receive(:facebook_id).and_return("1").once
277
+ @session.send_notification([user],"a")
278
+ end
279
+ def test_can_send_notification_with_string
280
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
281
+ @session.send(:instance_variable_set,"@uid",3)
282
+ @session.expects(:post).with('facebook.notifications.send',{:to_ids=>"1",:notification=>"a", :type=>"user_to_user"},true)
283
+ @session.send_notification(["1"],"a")
284
+ end
285
+
286
+ def test_can_send_announcement_notification
287
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
288
+ @session.expects(:post).with('facebook.notifications.send',{:to_ids=>"1",:notification=>"a", :type=>"app_to_user"},false)
289
+ @session.send_notification(["1"],"a")
290
+ end
291
+
292
+ def test_can_register_template_bundle
293
+ expect_http_posts_with_responses(example_register_template_bundle_return_xml)
294
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
295
+ assert_equal 17876842716, @session.register_template_bundle("{*actor*} did something")
296
+ end
297
+
298
+ def test_can_register_template_bundle_with_action_links
299
+ expect_http_posts_with_responses(example_register_template_bundle_return_xml)
300
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
301
+ assert_equal 17876842716, @session.register_template_bundle("{*actor*} did something",nil,nil,[{:text=>"text",:href=>"href"}])
302
+ end
303
+
304
+ def test_can_register_template_bundle_with_short_story
305
+ one_line = "{*actor*} did something"
306
+ short_story = { :title => 'title', :body => 'body' }
307
+
308
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
309
+ @session.expects(:post).with(
310
+ 'facebook.feed.registerTemplateBundle',
311
+ {:one_line_story_templates => [one_line].to_json, :short_story_templates => [short_story].to_json},
312
+ false
313
+ )
314
+ @session.register_template_bundle(one_line, short_story)
315
+ end
316
+
317
+ def test_can_register_template_bundle_with_short_story_for_several_templates
318
+ one_line = ["{*actor*} did something", "{*actor*} did something again"]
319
+ short_story = [{ :title => 'title', :body => 'body' }, { :title => 'title2', :body => 'body2' }]
320
+
321
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
322
+ @session.expects(:post).with(
323
+ 'facebook.feed.registerTemplateBundle',
324
+ {:one_line_story_templates => one_line.to_json, :short_story_templates => short_story.to_json},
325
+ false
326
+ )
327
+ @session.register_template_bundle(one_line, short_story)
328
+ end
329
+
330
+ def test_can_register_template_bundle_with_full_story_for_several_templates
331
+ one_line = ["{*actor*} did something", "{*actor*} did something again"]
332
+ short_story = [{ :title => 'title', :body => 'body' }, { :title => 'title2', :body => 'body2' }]
333
+ full_story = { :title => 'title', :body => 'body' }
334
+
335
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
336
+ @session.expects(:post).with(
337
+ 'facebook.feed.registerTemplateBundle',
338
+ {:one_line_story_templates => one_line.to_json, :short_story_templates => short_story.to_json, :full_story_template => full_story.to_json},
339
+ false
340
+ )
341
+ @session.register_template_bundle(one_line, short_story, full_story)
342
+ end
343
+
344
+ def test_can_deactivate_template_bundle_by_id
345
+ @session = Facebooker::Session.create(ENV['FACBEOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
346
+ @session.expects(:post).with(
347
+ 'facebook.feed.deactivateTemplateBundleByID',
348
+ {:template_bundle_id => '999'},
349
+ false
350
+ )
351
+ @session.deactivate_template_bundle_by_id(999)
352
+ end
353
+
354
+ def test_can_publish_user_action
355
+ expect_http_posts_with_responses(publish_user_action_return_xml)
356
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
357
+ assert @session.publish_user_action(17876842716,{})
358
+ end
359
+
360
+ def test_logs_api_calls
361
+ call_name = 'sample.api.call'
362
+ params = { :param1 => true, :param2 => 'value' }
363
+ flexmock(Facebooker::Logging, :Logging).should_receive(:log_fb_api).once.with(
364
+ call_name, params, Proc)
365
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
366
+ @session.post(call_name, params)
367
+ end
368
+
369
+ def test_requests_inside_batch_are_added_to_batch
370
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
371
+ @session.send(:service).expects(:post).once
372
+ @session.batch do
373
+ @session.send_notification(["1"],"a")
374
+ @session.send_notification(["1"],"a")
375
+ end
376
+
377
+ end
378
+
379
+ def test_parses_batch_response
380
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
381
+ expect_http_posts_with_responses(example_batch_run_xml)
382
+ @session.batch do
383
+ @fql_response = @session.fql_query('SELECT name, pic FROM user WHERE uid=211031 OR uid=4801660')
384
+ end
385
+ assert_kind_of(Facebooker::Event::Attendance, @fql_response.first)
386
+ assert_equal('attending', @fql_response.first.rsvp_status)
387
+ end
388
+
389
+ def test_parses_batch_response_with_escaped_chars
390
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
391
+ expect_http_posts_with_responses(example_batch_run_with_escaped_chars_xml)
392
+ @session.batch do
393
+ @response = @session.events(:start_time => Time.now.to_i)
394
+ end
395
+ assert_kind_of(Facebooker::Event, @response.first)
396
+ assert_equal('Wolf & Crow', @response.first.name)
397
+ end
398
+
399
+ def test_parses_batch_response_sets_exception
400
+ @session = Facebooker::Session.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
401
+ expect_http_posts_with_responses(example_batch_run_xml)
402
+ Facebooker::FqlQuery.expects(:process).raises(NoMethodError.new)
403
+
404
+ @session.batch do
405
+ @fql_response = @session.fql_query('SELECT name, pic FROM user WHERE uid=211031 OR uid=4801660')
406
+ end
407
+ assert_raises(NoMethodError) {
408
+ @fql_response.first
409
+ }
410
+ end
411
+
412
+ def test_can_set_and_get_current_batch
413
+ Facebooker::BatchRun.current_batch=4
414
+ assert_equal 4,Facebooker::BatchRun.current_batch
415
+ end
416
+
417
+ def test_can_get_stanard_info
418
+ expect_http_posts_with_responses(standard_info_xml)
419
+ result = @session.users_standard([4])
420
+ assert_equal "Mike Mangino",result.first.name
421
+ end
422
+
423
+ def test_can_query_for_pages
424
+ expect_http_posts_with_responses(example_pages_xml)
425
+ example_page = Facebooker::Page.new(
426
+ :page_id => 4846711747,
427
+ :name => "Kronos Quartet",
428
+ :website => "http://www.kronosquartet.org",
429
+ :company_overview => "",
430
+ :session => @session)
431
+ pages = @session.pages(:fields => %w[ page_id name website company_overview ])
432
+
433
+ assert_equal 1, pages.size
434
+
435
+ page = pages.first
436
+ assert_equal "4846711747", page.page_id
437
+ assert_equal "Kronos Quartet", page.name
438
+ assert_equal "http://www.kronosquartet.org", page.website
439
+
440
+ # TODO we really need a way to differentiate between hash/list and text attributes
441
+ # assert_equal({}, page.company_overview)
442
+
443
+ # sakkaoui : as a fix to the parser, I replace empty text node by "" instead of {}
444
+ # we have child.attributes['list'] == 'true' that let us know that we have a hash/list.
445
+ assert_equal("", page.company_overview)
446
+
447
+ genre = page.genre
448
+ assert_equal false, genre.dance
449
+ assert_equal true, genre.party
450
+ end
451
+
452
+ private
453
+
454
+ def example_fql_multiquery_xml
455
+ <<-XML
456
+ <?xml version="1.0" encoding="UTF-8"?>
457
+ <fql_multiquery_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">
458
+ <fql_result>
459
+ <name>query1</name>
460
+ <results list="true">
461
+ <user>
462
+ <name>Ari Steinberg</name>
463
+ <uid>46903192</uid>
464
+ <rsvp_status xsi:nil="true"/>
465
+ </user>
466
+ </results>
467
+ </fql_result>
468
+ <fql_result>
469
+ <name>query2</name>
470
+ <results list="true">
471
+ <user>
472
+ <name>Lisa Petrovskaia</name>
473
+ <pic xsi:nil="true"/>
474
+ </user>
475
+ </results>
476
+ </fql_result>
477
+ </fql_multiquery_response>
478
+ XML
479
+ end
480
+
481
+ def example_groups_get_xml
482
+ <<-XML
483
+ <?xml version="1.0" encoding="UTF-8"?>
484
+ <groups_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">
485
+ <group>
486
+ <gid>2206609142</gid>
487
+ <name>Donald Knuth Is My Homeboy</name>
488
+ <nid>0</nid>
489
+ <description>Donald Ervin Knuth (born January 10, 1938) is a renowned computer scientist and professor emeritus at Stanford University.
490
+
491
+ Knuth is best known as the author of the multi-volume The Art of Computer Programming, one of the most highly respected references in the computer science field. He practically created the field of rigorous analysis of algorithms, and made many seminal contributions to several branches of theoretical computer science. He is also the creator of the TeX typesetting system and of the METAFONT font design system, and pioneered the concept of literate programming.
492
+
493
+ That's how he ROLLS, y0.</description>
494
+ <group_type>Just for Fun</group_type>
495
+ <group_subtype>Fan Clubs</group_subtype>
496
+ <recent_news/>
497
+ <pic>http://photos-142.facebook.com/ip006/object/543/95/s2206609142_32530.jpg</pic>
498
+ <pic_big>http://photos-142.facebook.com/ip006/object/543/95/n2206609142_32530.jpg</pic_big>
499
+ <pic_small>http://photos-142.facebook.com/ip006/object/543/95/t2206609142_32530.jpg</pic_small>
500
+ <creator>1240077</creator>
501
+ <update_time>1156543965</update_time>
502
+ <office/>
503
+ <website/>
504
+ <venue>
505
+ <street/>
506
+ <city/>
507
+ <state>CA</state>
508
+ <country>United States</country>
509
+ </venue>
510
+ </group>
511
+ </groups_get_response>
512
+ XML
513
+ end
514
+
515
+ def example_event_create_xml
516
+ <<-XML
517
+ <?xml version="1.0" encoding="UTF-8"?>
518
+ <events_create_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">
519
+ 34444349712
520
+ </events_create_response>
521
+ XML
522
+ end
523
+
524
+ def example_event_cancel_xml
525
+ <<-XML
526
+ <?xml version="1.0" encoding="UTF-8"?>
527
+ <events_cancel_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">
528
+ 1
529
+ </events_cancel_response>
530
+ XML
531
+ end
532
+
533
+ def example_events_get_xml
534
+ <<-XML
535
+ <?xml version="1.0" encoding="UTF-8"?>
536
+ <events_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">
537
+ <event>
538
+ <eid>1037629024</eid>
539
+ <name>Technology Tasting</name>
540
+ <tagline>Who said Engineering can't be delicious?</tagline>
541
+ <nid>12409987</nid>
542
+ <pic>http://photos-628.facebook.com/ip006/object/1345/48/s1037629024_30775.jpg</pic>
543
+ <pic_big>http://photos-628.facebook.com/ip006/object/1345/48/n1037629024_30775.jpg</pic_big>
544
+ <pic_small>http://photos-628.facebook.com/ip006/object/1345/48/t1037629024_30775.jpg</pic_small>
545
+ <host>Facebook</host>
546
+ <description>Facebook will be hosting technology thought leaders and avid software engineers for a social evening of technology tasting. We invite you to connect with some of our newest technologies and innovative people over hors d'oeuvres and wine. Come share ideas, ask questions, and challenge existing technology paradigms in the spirit of the open source community.</description>
547
+ <event_type>Party</event_type>
548
+ <event_subtype>Cocktail Party</event_subtype>
549
+ <start_time>1172107800</start_time>
550
+ <end_time>1172115000</end_time>
551
+ <creator>1078</creator>
552
+ <update_time>1170096157</update_time>
553
+ <location>Facebook's New Office</location>
554
+ <venue>
555
+ <city>Palo Alto</city>
556
+ <state>CA</state>
557
+ <country>United States</country>
558
+ </venue>
559
+ </event>
560
+ </events_get_response>
561
+ XML
562
+ end
563
+
564
+ def example_fql_query_event_members_xml
565
+ <<-XML
566
+ <?xml version="1.0" encoding="UTF-8"?>
567
+ <fql_query_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" list="true">
568
+ <event_member>
569
+ <uid>517961878</uid>
570
+ <eid>2454827764</eid>
571
+ <rsvp_status>attending</rsvp_status>
572
+ </event_member>
573
+ <event_member>
574
+ <uid>744961110</uid>
575
+ <eid>2454827764</eid>
576
+ <rsvp_status>declined</rsvp_status>
577
+ </event_member>
578
+ </fql_query_response>
579
+ XML
580
+ end
581
+
582
+ def example_fql_query_events_xml
583
+ <<-XML
584
+ <?xml version="1.0" encoding="UTF-8"?>
585
+ <fql_query_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">
586
+ <event>
587
+ <eid>1037629024</eid>
588
+ <name>Technology Tasting</name>
589
+ <tagline>Who said Engineering can't be delicious?</tagline>
590
+ <nid>12409987</nid>
591
+ <pic>http://photos-628.facebook.com/ip006/object/1345/48/s1037629024_30775.jpg</pic>
592
+ <pic_big>http://photos-628.facebook.com/ip006/object/1345/48/n1037629024_30775.jpg</pic_big>
593
+ <pic_small>http://photos-628.facebook.com/ip006/object/1345/48/t1037629024_30775.jpg</pic_small>
594
+ <host>Facebook</host>
595
+ <description>Facebook will be hosting technology thought leaders and avid software engineers for a social evening of technology tasting. We invite you to connect with some of our newest technologies and innovative people over hors d'oeuvres and wine. Come share ideas, ask questions, and challenge existing technology paradigms in the spirit of the open source community.</description>
596
+ <event_type>Party</event_type>
597
+ <event_subtype>Cocktail Party</event_subtype>
598
+ <start_time>1172107800</start_time>
599
+ <end_time>1172115000</end_time>
600
+ <creator>1078</creator>
601
+ <update_time>1170096157</update_time>
602
+ <location>Facebook's New Office</location>
603
+ <venue>
604
+ <street>156 University Ave.</street>
605
+ <city>Palo Alto</city>
606
+ <state>CA</state>
607
+ <country>United States</country>
608
+ </venue>
609
+ </event>
610
+ </fql_query_response>
611
+ XML
612
+ end
613
+
614
+ def example_fql_query_albums_xml
615
+ <<-XML
616
+ <?xml version="1.0" encoding="UTF-8"?>
617
+ <fql_query_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">
618
+ <album>
619
+ <aid>34595963571485</aid>
620
+ <cover_pid>34595991612812</cover_pid>
621
+ <owner>8055</owner>
622
+ <name>Films you will never see</name>
623
+ <created>1132553109</created>
624
+ <modified>1132553363</modified>
625
+ <description>No I will not make out with you</description>
626
+ <location>York, PA</location>
627
+ <link>http://www.facebook.com/album.php?aid=2002205&amp;id=8055</link>
628
+ <size>30</size>
629
+ <visible>friends</visible>
630
+ <modified_major>1241834423</modified_major>
631
+ </album>
632
+ </fql_query_response>
633
+ XML
634
+ end
635
+
636
+ def example_check_friendship_xml
637
+ <<-XML
638
+ <?xml version="1.0" encoding="UTF-8"?>
639
+ <friends_areFriends_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">
640
+ <friend_info>
641
+ <uid1>222332</uid1>
642
+ <uid2>222333</uid2>
643
+ <are_friends>1</are_friends>
644
+ </friend_info>
645
+ <friend_info>
646
+ <uid1>1240077</uid1>
647
+ <uid2>1240079</uid2>
648
+ <are_friends>0</are_friends>
649
+ </friend_info>
650
+ </friends_areFriends_response>
651
+ XML
652
+ end
653
+
654
+ def example_check_friendship_with_unknown_result
655
+ <<-XML
656
+ <?xml version="1.0" encoding="UTF-8"?>
657
+ <friends_areFriends_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">
658
+ <friend_info>
659
+ <uid1>1240077</uid1>
660
+ <uid2>1240079</uid2>
661
+ <are_friends xsi:nil="true"/>
662
+ </friend_info>
663
+ </friends_areFriends_response>
664
+ XML
665
+ end
666
+
667
+ def example_fql_for_multiple_users_and_pics
668
+ <<-XML
669
+ <?xml version="1.0" encoding="UTF-8"?>
670
+ <fql_query_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" list="true">
671
+ <user>
672
+ <name>Ari Steinberg</name>
673
+ <pic>http://profile.ak.facebook.com/profile2/1805/47/s211031_26434.jpg</pic>
674
+ </user>
675
+ <user>
676
+ <name>Ruchi Sanghvi</name>
677
+ <pic>http://profile.ak.facebook.com/v52/870/125/s4801660_2498.jpg</pic>
678
+ </user>
679
+ </fql_query_response>
680
+ XML
681
+ end
682
+
683
+ def example_fql_for_multiple_photos_xml
684
+ <<-XML
685
+ <?xml version="1.0" encoding="UTF-8"?>
686
+ <fql_query_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" list="true">
687
+ <photo>
688
+ <src>http://photos-c.ak.facebook.com/photos-ak-sf2p/v108/212/118/22700225/s22700225_30345986_2713.jpg</src>
689
+ <caption>Nottttt. get ready for some museumz</caption>
690
+ <caption>Nottttt. get ready for some museumz</caption>
691
+ </photo>
692
+ <photo>
693
+ <src>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324934_7816.jpg</src>
694
+ <caption>Rooftop barbecues make me act funny</caption>
695
+ <caption>Rooftop barbecues make me act funny</caption>
696
+ </photo>
697
+ <photo>
698
+ <src>http://photos-c.ak.facebook.com/photos-ak-sctm/v96/154/56/22700188/s22700188_30321538_17.jpg</src>
699
+ <caption>An epic shot of Patrick getting ready for a run to second.</caption>
700
+ <caption>An epic shot of Patrick getting ready for a run to second.</caption>
701
+ </photo>
702
+ </fql_query_response>
703
+ XML
704
+ end
705
+
706
+ def example_fql_for_multiple_photos_with_anon_xml
707
+ <<-XML
708
+ <?xml version="1.0" encoding="UTF-8"?>
709
+ <fql_query_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" list="true">
710
+ <photo>
711
+ <src>http://photos-c.ak.facebook.com/photos-ak-sf2p/v108/212/118/22700225/s22700225_30345986_2713.jpg</src>
712
+ <caption>Nottttt. get ready for some museumz</caption>
713
+ <caption>Nottttt. get ready for some museumz</caption>
714
+ <anon>first</anon>
715
+ <anon>second</anon>
716
+ </photo>
717
+ <photo>
718
+ <src>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324934_7816.jpg</src>
719
+ <caption>Rooftop barbecues make me act funny</caption>
720
+ <caption>Rooftop barbecues make me act funny</caption>
721
+ <anon>first</anon>
722
+ <anon>second</anon>
723
+ </photo>
724
+ <photo>
725
+ <src>http://photos-c.ak.facebook.com/photos-ak-sctm/v96/154/56/22700188/s22700188_30321538_17.jpg</src>
726
+ <caption>An epic shot of Patrick getting ready for a run to second.</caption>
727
+ <caption>An epic shot of Patrick getting ready for a run to second.</caption>
728
+ <anon>first</anon>
729
+ <anon>second</anon>
730
+ </photo>
731
+ </fql_query_response>
732
+ XML
733
+ end
734
+
735
+ def no_results_fql
736
+ <<-XML
737
+ <?xml version="1.0" encoding="UTF-8"?>
738
+ <fql_query_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" list="true">
739
+ </fql_query_response>
740
+ XML
741
+
742
+ end
743
+
744
+ def example_group_members_xml
745
+ <<-XML
746
+ <?xml version="1.0" encoding="UTF-8"?>
747
+ <groups_getMembers_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">
748
+ <members list="true">
749
+ <uid>1240077</uid>
750
+ <uid>1240078</uid>
751
+ <uid>222332</uid>
752
+ <uid>222333</uid>
753
+ </members>
754
+ <admins list="true">
755
+ <uid>1240077</uid>
756
+ <uid>222333</uid>
757
+ </admins>
758
+ <officers list="true">
759
+ <uid>1240078</uid>
760
+ </officers>
761
+ <not_replied list="true"/>
762
+ </groups_getMembers_response>
763
+ XML
764
+ end
765
+
766
+ def example_batch_run_xml
767
+ <<-XML
768
+ <?xml version="1.0" encoding="UTF-8"?>
769
+ <batch_run_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">
770
+ <batch_run_response_elt>
771
+ #{CGI.escapeHTML(example_fql_query_event_members_xml)}
772
+ </batch_run_response_elt>
773
+ </batch_run_response>
774
+ XML
775
+ end
776
+
777
+ def example_batch_run_with_escaped_chars_xml
778
+ <<-XML
779
+ <?xml version="1.0" encoding="UTF-8"?>
780
+ <batch_run_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">
781
+ <batch_run_response_elt>
782
+ #{CGI.escapeHTML(event_with_amp_in_xml)}
783
+ </batch_run_response_elt>
784
+ </batch_run_response>
785
+ XML
786
+ end
787
+ def event_with_amp_in_xml
788
+ <<-XML
789
+ <?xml version="1.0" encoding="UTF-8"?>
790
+ <events_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">
791
+ <event>
792
+ <eid>1</eid>
793
+ <name>Wolf &amp; Crow</name>
794
+ </event>
795
+ </events_get_response>
796
+ XML
797
+ end
798
+
799
+
800
+ def example_event_members_xml
801
+ <<-XML
802
+ <?xml version="1.0" encoding="UTF-8"?>
803
+ <events_getMembers_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">
804
+ <attending list="true">
805
+ <uid>222332</uid>
806
+ <uid>222333</uid>
807
+ </attending>
808
+ <unsure list="true">
809
+ <uid>1240077</uid>
810
+ </unsure>
811
+ <declined list="true"/>
812
+ <not_replied list="true">
813
+ <uid>222335</uid>
814
+ <uid>222336</uid>
815
+ </not_replied>
816
+ </events_getMembers_response>
817
+ XML
818
+ end
819
+
820
+ def example_register_template_bundle_return_xml
821
+ <<-XML
822
+ <?xml version="1.0" encoding="UTF-8"?>
823
+ <feed_registerTemplateBundle_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/">
824
+ 17876842716
825
+ </feed_registerTemplateBundle_response>
826
+ XML
827
+ end
828
+
829
+ def example_pages_xml
830
+ <<-XML
831
+ <?xml version="1.0" encoding="UTF-8"?>
832
+ <pages_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">
833
+ <page>
834
+ <page_id>4846711747</page_id>
835
+ <name>Kronos Quartet</name>
836
+ <website>http://www.kronosquartet.org</website>
837
+ <company_overview/>
838
+ <genre>
839
+ <dance>0</dance>
840
+ <party>1</party>
841
+ </genre>
842
+ </page>
843
+ </pages_getInfo_response>
844
+ XML
845
+ end
846
+
847
+ def publish_user_action_return_xml
848
+ <<-XML
849
+ <?xml version="1.0" encoding="UTF-8"?>
850
+ <feed_publishUserAction_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">
851
+ <feed_publishUserAction_response_elt>1</feed_publishUserAction_response_elt>
852
+ </feed_publishUserAction_response>
853
+ XML
854
+ end
855
+
856
+ def standard_info_xml
857
+ <<-XML
858
+ <?xml version="1.0" encoding="UTF-8"?>
859
+ <?xml version="1.0" encoding="UTF-8"?>
860
+
861
+ <users_getStandardInfo_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">
862
+ <standard_user_info>
863
+ <uid>12451752</uid>
864
+ <name>Mike Mangino</name>
865
+ </standard_user_info>
866
+ </users_getStandardInfo_response>
867
+ XML
868
+ end
869
+
870
+ end
871
+
872
+
873
+ class CanvasSessionTest < Test::Unit::TestCase
874
+ def setup
875
+ ENV['FACEBOOK_API_KEY'] = '1234567'
876
+ ENV['FACEBOOK_SECRET_KEY'] = '7654321'
877
+ end
878
+
879
+ def test_login_url_will_display_callback_url_in_canvas
880
+ session = Facebooker::CanvasSession.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
881
+ assert_equal("http://www.facebook.com/login.php?api_key=1234567&v=1.0&canvas=true", session.login_url)
882
+ end
883
+ end