djanowski-mmangino-facebooker 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/CHANGELOG.txt +0 -0
  2. data/COPYING +19 -0
  3. data/History.txt +16 -0
  4. data/Manifest.txt +110 -0
  5. data/README +46 -0
  6. data/README.txt +81 -0
  7. data/Rakefile +76 -0
  8. data/TODO.txt +10 -0
  9. data/generators/facebook/facebook_generator.rb +14 -0
  10. data/generators/facebook/templates/config/facebooker.yml +41 -0
  11. data/generators/facebook/templates/public/javascripts/facebooker.js +106 -0
  12. data/generators/facebook_controller/USAGE +33 -0
  13. data/generators/facebook_controller/facebook_controller_generator.rb +40 -0
  14. data/generators/facebook_controller/templates/controller.rb +7 -0
  15. data/generators/facebook_controller/templates/functional_test.rb +11 -0
  16. data/generators/facebook_controller/templates/helper.rb +2 -0
  17. data/generators/facebook_controller/templates/view.fbml.erb +2 -0
  18. data/generators/facebook_controller/templates/view.html.erb +2 -0
  19. data/generators/facebook_publisher/facebook_publisher_generator.rb +14 -0
  20. data/generators/facebook_publisher/templates/create_facebook_templates.rb +15 -0
  21. data/generators/facebook_publisher/templates/publisher.rb +3 -0
  22. data/generators/facebook_scaffold/USAGE +27 -0
  23. data/generators/facebook_scaffold/facebook_scaffold_generator.rb +118 -0
  24. data/generators/facebook_scaffold/templates/controller.rb +93 -0
  25. data/generators/facebook_scaffold/templates/facebook_style.css +2579 -0
  26. data/generators/facebook_scaffold/templates/functional_test.rb +89 -0
  27. data/generators/facebook_scaffold/templates/helper.rb +2 -0
  28. data/generators/facebook_scaffold/templates/layout.fbml.erb +6 -0
  29. data/generators/facebook_scaffold/templates/layout.html.erb +17 -0
  30. data/generators/facebook_scaffold/templates/style.css +74 -0
  31. data/generators/facebook_scaffold/templates/view_edit.fbml.erb +13 -0
  32. data/generators/facebook_scaffold/templates/view_edit.html.erb +18 -0
  33. data/generators/facebook_scaffold/templates/view_index.fbml.erb +24 -0
  34. data/generators/facebook_scaffold/templates/view_index.html.erb +24 -0
  35. data/generators/facebook_scaffold/templates/view_new.fbml.erb +12 -0
  36. data/generators/facebook_scaffold/templates/view_new.html.erb +17 -0
  37. data/generators/facebook_scaffold/templates/view_show.fbml.erb +10 -0
  38. data/generators/facebook_scaffold/templates/view_show.html.erb +10 -0
  39. data/generators/publisher/publisher_generator.rb +14 -0
  40. data/init.rb +70 -0
  41. data/install.rb +12 -0
  42. data/lib/facebooker.rb +143 -0
  43. data/lib/facebooker/adapters/adapter_base.rb +87 -0
  44. data/lib/facebooker/adapters/bebo_adapter.rb +75 -0
  45. data/lib/facebooker/adapters/facebook_adapter.rb +48 -0
  46. data/lib/facebooker/admin.rb +28 -0
  47. data/lib/facebooker/batch_request.rb +44 -0
  48. data/lib/facebooker/data.rb +57 -0
  49. data/lib/facebooker/feed.rb +78 -0
  50. data/lib/facebooker/logging.rb +51 -0
  51. data/lib/facebooker/model.rb +123 -0
  52. data/lib/facebooker/models/affiliation.rb +10 -0
  53. data/lib/facebooker/models/album.rb +11 -0
  54. data/lib/facebooker/models/applicationproperties.rb +39 -0
  55. data/lib/facebooker/models/cookie.rb +10 -0
  56. data/lib/facebooker/models/education_info.rb +11 -0
  57. data/lib/facebooker/models/event.rb +26 -0
  58. data/lib/facebooker/models/friend_list.rb +14 -0
  59. data/lib/facebooker/models/group.rb +35 -0
  60. data/lib/facebooker/models/info_item.rb +10 -0
  61. data/lib/facebooker/models/info_section.rb +10 -0
  62. data/lib/facebooker/models/location.rb +8 -0
  63. data/lib/facebooker/models/notifications.rb +17 -0
  64. data/lib/facebooker/models/page.rb +27 -0
  65. data/lib/facebooker/models/photo.rb +10 -0
  66. data/lib/facebooker/models/tag.rb +12 -0
  67. data/lib/facebooker/models/user.rb +367 -0
  68. data/lib/facebooker/models/work_info.rb +9 -0
  69. data/lib/facebooker/parser.rb +547 -0
  70. data/lib/facebooker/rails/controller.rb +246 -0
  71. data/lib/facebooker/rails/facebook_asset_path.rb +18 -0
  72. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  73. data/lib/facebooker/rails/facebook_pretty_errors.rb +14 -0
  74. data/lib/facebooker/rails/facebook_request_fix.rb +24 -0
  75. data/lib/facebooker/rails/facebook_session_handling.rb +69 -0
  76. data/lib/facebooker/rails/facebook_url_rewriting.rb +39 -0
  77. data/lib/facebooker/rails/helpers.rb +615 -0
  78. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  79. data/lib/facebooker/rails/publisher.rb +497 -0
  80. data/lib/facebooker/rails/routing.rb +49 -0
  81. data/lib/facebooker/rails/test_helpers.rb +88 -0
  82. data/lib/facebooker/rails/utilities.rb +22 -0
  83. data/lib/facebooker/server_cache.rb +24 -0
  84. data/lib/facebooker/service.rb +31 -0
  85. data/lib/facebooker/session.rb +564 -0
  86. data/lib/facebooker/version.rb +9 -0
  87. data/lib/net/http_multipart_post.rb +123 -0
  88. data/lib/tasks/facebooker.rake +18 -0
  89. data/lib/tasks/tunnel.rake +46 -0
  90. data/rails/init.rb +1 -0
  91. data/setup.rb +1585 -0
  92. data/templates/layout.erb +24 -0
  93. data/test/adapters_test.rb +98 -0
  94. data/test/batch_request_test.rb +82 -0
  95. data/test/event_test.rb +15 -0
  96. data/test/facebook_admin_test.rb +75 -0
  97. data/test/facebook_cache_test.rb +43 -0
  98. data/test/facebook_data_test.rb +84 -0
  99. data/test/facebooker_test.rb +855 -0
  100. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  101. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  102. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  103. data/test/http_multipart_post_test.rb +54 -0
  104. data/test/logging_test.rb +43 -0
  105. data/test/model_test.rb +91 -0
  106. data/test/publisher_test.rb +436 -0
  107. data/test/rails_integration_test.rb +1126 -0
  108. data/test/session_test.rb +587 -0
  109. data/test/test_helper.rb +60 -0
  110. data/test/user_test.rb +253 -0
  111. metadata +181 -0
@@ -0,0 +1,24 @@
1
+ <fb:fbml>
2
+ <style>
3
+ body { background-color: #fff; color: #333; }
4
+
5
+ body, p, ol, ul, td {
6
+ font-family: verdana, arial, helvetica, sans-serif;
7
+ font-size: 13px;
8
+ line-height: 18px;
9
+ }
10
+
11
+ pre {
12
+ background-color: #eee;
13
+ padding: 10px;
14
+ font-size: 11px;
15
+ }
16
+
17
+ a { color: #000; }
18
+ a:visited { color: #666; }
19
+ a:hover { color: #fff; background-color:#000; }
20
+ </style>
21
+
22
+ <%= @contents %>
23
+
24
+ </fb:fbml>
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ require 'facebooker'
3
+ class SessionTest < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ ENV['FACEBOOK_API_KEY'] = '1234567'
8
+ ENV['FACEBOOK_SECRET_KEY'] = '7654321'
9
+ Facebooker.current_adapter = nil
10
+ @bebo_api_key = "bebo_api_key"; @bebo_secret_key = "bebo_secret_key"
11
+ end
12
+
13
+ def teardown
14
+ flexmock_close
15
+ end
16
+
17
+ def test_load_default_adapter
18
+ session = Facebooker::CanvasSession.create(ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_SECRET_KEY'])
19
+ assert_equal(ENV['FACEBOOK_API_KEY'], Facebooker::Session.api_key)
20
+ assert( Facebooker::FacebookAdapter === Facebooker.current_adapter)
21
+
22
+ ENV['FACEBOOK_API_KEY'] = nil
23
+ ENV['FACEBOOK_SECRET_KEY'] = nil
24
+ Facebooker.current_adapter = nil
25
+ Facebooker::AdapterBase.stubs(:facebooker_config).returns({"api_key" => "facebook_key", "secret_key" => "facebook_secret" })
26
+ assert( Facebooker::FacebookAdapter === Facebooker.current_adapter)
27
+ assert_equal("facebook_key", Facebooker::Session.api_key)
28
+ end
29
+
30
+ def test_load_bebo_adapter
31
+
32
+ load_bebo_adapter
33
+ assert_equal(@bebo_api_key, Facebooker::Session.api_key)
34
+ assert_equal(@bebo_secret_key, Facebooker::Session.secret_key)
35
+ assert(Facebooker::BeboAdapter === Facebooker.current_adapter, " Bebo adapter not loaded correctly.")
36
+ end
37
+
38
+ def load_bebo_adapter
39
+ @bebo_api_key = "bebo_api_key"; @bebo_secret_key = "bebo_secret_key"
40
+
41
+ Facebooker::AdapterBase.stubs(:facebooker_config).returns({"bebo_api_key" => @bebo_api_key, "bebo_adapter" => "BeboAdapter", "bebo_secret_key" => @bebo_secret_key, "foo" => "bar"})
42
+ Facebooker.load_adapter(:config_key_base => "bebo")
43
+ @session = Facebooker::CanvasSession.create(@bebo_api_key, @bebo_secret_key)
44
+ end
45
+
46
+ def test_adapter_details
47
+ test_load_default_adapter
48
+
49
+ assert_equal("apps.facebook.com", Facebooker.canvas_server_base)
50
+ assert_equal("api.facebook.com", Facebooker.api_server_base)
51
+ assert_equal("www.facebook.com", Facebooker.www_server_base_url)
52
+ assert_equal("http://api.facebook.com", Facebooker.api_server_base_url)
53
+ assert(Facebooker.is_for?(:facebook))
54
+ load_bebo_adapter
55
+
56
+ assert_equal("apps.bebo.com", Facebooker.canvas_server_base)
57
+ assert_equal("apps.bebo.com", Facebooker.api_server_base)
58
+ assert_equal("www.bebo.com", Facebooker.www_server_base_url)
59
+ assert_equal("http://apps.bebo.com", Facebooker.api_server_base_url)
60
+ assert_equal("http://www.bebo.com/SignIn.jsp?ApiKey=bebo_api_key&v=1.0&canvas=true", @session.login_url)
61
+ assert_equal("http://www.bebo.com/c/apps/add?ApiKey=bebo_api_key&v=1.0", @session.install_url)
62
+ assert(Facebooker.is_for?(:bebo))
63
+
64
+ end
65
+
66
+ def test_adapter_failures
67
+ Facebooker::AdapterBase.stubs(:facebooker_config).returns({})
68
+
69
+ assert_raises(Facebooker::AdapterBase::UnableToLoadAdapter){
70
+ Facebooker.load_adapter(:config_key_base => "bebo")
71
+ }
72
+ end
73
+
74
+ def test_bebo_specific_issues
75
+ load_bebo_adapter
76
+
77
+ # @session.send(:service).stubs(:post).returns([{:name => "foo"}])
78
+ Net::HTTP.stubs(:post_form).returns("<profile_setFBML_response></profile_setFBML_response>")
79
+ user = Facebooker::User.new(:uid => "123456")
80
+ user.session = @session
81
+ user.set_profile_fbml("foo","bar","foo")
82
+ assert(true)
83
+ Net::HTTP.stubs(:post_form).returns("<users_getInfo_response> <user><uid>123456</uid><name>foo</name></user></users_getInfo_response>")
84
+ user.populate(:name)
85
+ assert(true)
86
+ assert_equal("foo", user.name)
87
+ action = Facebooker::Feed::TemplatizedAction.new()
88
+ action.title_template = "foo"
89
+ Net::HTTP.stubs(:post_form).returns("<feed_publishTemplatizedAction_response>1</feed_publishTemplatizedAction_response>")
90
+ user.publish_templatized_action(action)
91
+ end
92
+
93
+ def test_bebo_process_data
94
+
95
+ end
96
+
97
+
98
+ end
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ class BatchRequestTest < Test::Unit::TestCase
3
+
4
+ def setup
5
+ @proc_called=false
6
+ @batch_request=Facebooker::BatchRequest.new({:params=>true},nil)
7
+ end
8
+
9
+ def test_can_set_result
10
+
11
+ end
12
+
13
+ def test_can_set_result_with_proc_and_have_proc_called
14
+ p=Proc.new {@proc_called=true}
15
+
16
+ @batch_request=Facebooker::BatchRequest.new({:params=>true},p)
17
+ @batch_request.result="Mike"
18
+ assert @proc_called
19
+ end
20
+ def test_can_set_result_with_proc_and_use_proc_result
21
+ p=Proc.new {@proc_called=true}
22
+
23
+ @batch_request=Facebooker::BatchRequest.new({:params=>true},p)
24
+ @batch_request.result="Mike"
25
+ assert @batch_request
26
+ end
27
+
28
+ def test_proxies_methods
29
+ @batch_request.result="Mike"
30
+ assert @batch_request == "Mike"
31
+ end
32
+
33
+ def test_threequal_works
34
+ @batch_request.result="Mike"
35
+ assert @batch_request === String
36
+ end
37
+
38
+ def test_can_set_exception_and_check_it
39
+ @batch_request.exception_raised=ArgumentError.new
40
+ assert_raises(ArgumentError) {
41
+ @batch_request.exception_raised?
42
+ }
43
+ end
44
+ def test_can_set_exception_and_have_it_raised_on_access
45
+ @batch_request.exception_raised=ArgumentError.new
46
+ assert_raises(ArgumentError) {
47
+ @batch_request == true
48
+ }
49
+ end
50
+ def test_exception_raised_false_when_no_exception
51
+ @batch_request.result="Mike"
52
+ assert ! @batch_request.exception_raised?
53
+ end
54
+
55
+ # def test_case_works
56
+ # @batch_request.result="Mike"
57
+ # case @batch_request
58
+ # when String
59
+ # else
60
+ # fail("case failed")
61
+ # end
62
+ #
63
+ # end
64
+
65
+ def test_calling_method_without_result_raises_exception
66
+ assert_raises(Facebooker::BatchRequest::UnexecutedRequest) {
67
+ @batch_request.to_s
68
+ }
69
+ end
70
+
71
+ def test_respond_to
72
+ @batch_request.result=[]
73
+ assert @batch_request.respond_to?(:empty?)
74
+ end
75
+
76
+ def test_calling_method_after_exception_re_raises_exception
77
+ @batch_request.result="String"
78
+ assert_raises(NoMethodError) {
79
+ @batch_request.fake
80
+ }
81
+ end
82
+ end
@@ -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,75 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class FacebookAdminTest < Test::Unit::TestCase
4
+ def setup
5
+ @session = Facebooker::Session.create('apikey', 'secretkey')
6
+ end
7
+
8
+ def test_can_ask_facebook_to_set_app_properties
9
+ expect_http_posts_with_responses(example_set_properties_xml)
10
+ properties = { :application_name => "Video Jukebox", :dev_mode => 0 }
11
+ assert(@session.admin.set_app_properties(properties))
12
+ end
13
+
14
+ def test_set_app_properties_json_conversion
15
+ properties = { :application_name => "Video Jukebox", :dev_mode => 0 }
16
+ flexmock(@session).should_receive(:post).with('facebook.admin.setAppProperties', :properties => properties.to_json).and_return('1').once
17
+ assert(@session.admin.set_app_properties(properties))
18
+ end
19
+
20
+ def test_can_ask_facebook_to_get_app_properties
21
+ expect_http_posts_with_responses(example_get_properties_xml)
22
+ properties = [ :application_name, :dev_mode ]
23
+ assert(@session.admin.get_app_properties(properties))
24
+ end
25
+
26
+ def test_can_get_properties
27
+ mock_http = establish_session
28
+ mock_http.should_receive(:post_form).and_return(example_get_properties_xml).once.ordered(:posts)
29
+ p = @session.admin.get_app_properties(:application_name, :dev_mode, :canvas_name)
30
+ assert_equal 'Video Jukebox', p.application_name
31
+ assert_equal 0, p.dev_mode
32
+ assert_equal 'my_canvas', p.canvas_name
33
+ end
34
+
35
+ def test_can_get_allocation
36
+ mock_http = establish_session
37
+ mock_http.should_receive(:post_form).and_return(example_get_allocation_xml).once.ordered(:posts)
38
+ alloc = @session.admin.get_allocation(:notifications_per_day)
39
+ assert_equal 40, alloc
40
+ end
41
+
42
+ private
43
+ def example_set_properties_xml
44
+ <<-XML
45
+ <?xml version="1.0" encoding="UTF-8"?>
46
+ <admin_setAppProperties_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
47
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</admin_setAppProperties_response>
48
+ XML
49
+ end
50
+
51
+ def example_get_properties_xml
52
+ <<-XML
53
+ <?xml version="1.0" encoding="UTF-8"?>
54
+ <admin_getAppProperties_response
55
+ xmlns="http://api.facebook.com/1.0/"
56
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
57
+ xsi:schemaLocation="http://api.facebook.com/1.0/http://api.facebook.com/1.0/facebook.xsd">
58
+ {&quot;application_name&quot;:&quot;Video Jukebox&quot;,&quot;callback_url&quot;:&quot;http:\/\/67.207.144.245\/&quot;,&quot;dev_mode&quot;:0,&quot;canvas_name&quot;:&quot;my_canvas&quot;}
59
+ </admin_getAppProperties_response>
60
+ XML
61
+ end
62
+
63
+ def example_get_allocation_xml
64
+ <<-XML
65
+ <?xml version="1.0" encoding="UTF-8"?>
66
+ <admin_getAllocation_response
67
+ xmlns="http://api.facebook.com/1.0/"
68
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
69
+ xsi:schemaLocation="http://api.facebook.com/1.0/http://api.facebook.com/1.0/facebook.xsd">
70
+ 40
71
+ </admin_getAllocation_response>
72
+ XML
73
+ end
74
+
75
+ 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,84 @@
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
+ def test_can_ask_facebook_to_set_a_preference
27
+ expect_http_posts_with_responses(example_set_preference_xml)
28
+ assert(@session.data.set_preference(0, 'hello'))
29
+ end
30
+
31
+ def test_can_ask_facebook_to_get_preference
32
+ expect_http_posts_with_responses(example_get_preference_xml)
33
+ assert(@session.data.get_preference(0))
34
+ end
35
+
36
+ def test_can_get_preference
37
+ mock_http = establish_session
38
+ mock_http.should_receive(:post_form).and_return(example_get_preference_xml).once.ordered(:posts)
39
+ assert_equal 'hello', @session.data.get_preference(0)
40
+ end
41
+
42
+ private
43
+ def example_set_cookie_xml
44
+ <<-XML
45
+ <?xml version="1.0" encoding="UTF-8"?>
46
+ <data_setCookie_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
47
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">1</data_setCookie_response>
48
+ XML
49
+ end
50
+
51
+ def example_get_cookies_xml
52
+ <<-XML
53
+ <?xml version="1.0" encoding="UTF-8"?>
54
+ <data_getCookie_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
55
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
56
+ <cookies>
57
+ <uid>508508326</uid>
58
+ <name>Foo</name>
59
+ <value>Bar</value>
60
+ <expires>0</expires>
61
+ <path>/tmp/</path>
62
+ </cookies>
63
+ </data_getCookie_response>
64
+ XML
65
+ end
66
+
67
+ def example_set_preference_xml
68
+ <<-XML
69
+ <?xml version="1.0" encoding="UTF-8"?>
70
+ <data_setUserPreference_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
71
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd"/>
72
+ XML
73
+ end
74
+
75
+ def example_get_preference_xml
76
+ <<-XML
77
+ <?xml version="1.0" encoding="UTF-8"?>
78
+ <data_getUserPreference_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
79
+ xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
80
+ hello
81
+ </data_getUserPreference_response>
82
+ XML
83
+ end
84
+ end
@@ -0,0 +1,855 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ require 'net/http_multipart_post'
3
+ class TestFacebooker < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @api_key = "95a71599e8293s66f1f0a6f4aeab3df7"
7
+ @secret_key = "3e4du8eea435d8e205a6c9b5d095bed1"
8
+ ENV["FACEBOOK_API_KEY"] = @api_key
9
+ ENV["FACEBOOK_SECRET_KEY"] = @secret_key
10
+ @session = Facebooker::Session.create(@api_key, @secret_key)
11
+ @desktop_session = Facebooker::Session::Desktop.create(@api_key, @secret_key)
12
+ @service = Facebooker::Service.new('http://apibase.com', '/api/path', @api_key)
13
+ @desktop_session.instance_variable_set("@service", @service)
14
+ end
15
+
16
+ def test_session_must_be_created_from_api_key_and_secret_key
17
+ assert_kind_of(Facebooker::Session, @session)
18
+ end
19
+
20
+ def test_session_can_tell_you_its_login_url
21
+ assert_not_nil(@session.login_url)
22
+ assert_equal("http://www.facebook.com/login.php?api_key=#{@api_key}&v=1.0", @session.login_url)
23
+ end
24
+
25
+ def test_desktop_session_returns_auth_toke_as_part_of_login_url
26
+ @service = flexmock(@service).should_receive(:post).at_least.once.and_return(123)
27
+ assert_kind_of(Facebooker::Session::Desktop, @desktop_session)
28
+ assert_match(/auth_token=[a-z0-9A-Z]/, @desktop_session.login_url)
29
+ end
30
+
31
+ def test_service_posts_data_to_http_location
32
+ flexmock(Net::HTTP).should_receive(:post_form).and_return(example_auth_token_xml)
33
+ assert_equal("http://www.facebook.com/login.php?api_key=#{@api_key}&v=1.0&auth_token=3e4a22bb2f5ed75114b0fc9995ea85f1", @desktop_session.login_url)
34
+ end
35
+
36
+ # def test_serivce_post_file_delegates_to_post_multipart_form
37
+ # # flexmock(@service).should_receive(:url).and_return('url')
38
+ # # flexmock(Net::HTTP).expects(:post_multipart_form).with('url', {:method => 'facebook.auth.createToken'}).returns(example_auth_token_xml)
39
+ #
40
+ # res = mock(:content_type => 'text/html', :code => '200', :body => '<html><body>my blog</body></html>')
41
+ # Net::HTTP.stubs(:get_response).once.with(uri).returns res
42
+ #
43
+ # @service.post_file(:method => 'facebook.auth.createToken')
44
+ # end
45
+
46
+ def test_desktop_session_be_secured_and_activated_after_receiving_auth_token_and_logging_in
47
+ establish_session
48
+ assert_equal("5f34e11bfb97c762e439e6a5-8055", @session.instance_variable_get("@session_key"))
49
+ end
50
+
51
+ def test_desktop_session_uses_secret_api_key_for_hashing_until_user_authenticates
52
+ assert_equal(@secret_key, @desktop_session.secret_for_method('facebook.auth.createToken'))
53
+ establish_session(@desktop_session)
54
+ assert_equal("ohairoflamao12345", @desktop_session.secret_for_method('anyNonAuthMethodName'))
55
+ end
56
+
57
+ def test_session_can_get_current_logged_in_user_id_and_will_cache
58
+ establish_session
59
+ flexmock(Net::HTTP).should_receive(:post_form).and_return(example_get_logged_in_user_xml)
60
+ assert_equal(8055, @session.user.id)
61
+ end
62
+
63
+ def test_can_get_current_users_friends
64
+ expect_http_posts_with_responses(example_friends_xml)
65
+ assert_equal([222333, 1240079], @session.user.friends.map{|friend| friend.id})
66
+ end
67
+
68
+ def test_can_get_current_users_friend_lists
69
+ expect_http_posts_with_responses(example_friend_lists_xml)
70
+ assert_equal([12089150545, 16361710545], @session.user.friend_lists.map{|friend_list| friend_list.flid})
71
+ end
72
+
73
+ def test_can_get_info_for_instance_of_user
74
+ populate_user_info
75
+ @session.user.first_name = "Dave"
76
+ end
77
+
78
+ def test_can_get_info_for_one_or_more_users
79
+ friends = populate_session_friends
80
+ friend = friends.detect{|f| f.id == 222333}
81
+ assert_equal('This field perpetuates the glorification of the ego. Also, it has a character limit.',
82
+ friend.about_me)
83
+ assert_equal('Facebook Developers', friend.affiliations.first.name)
84
+ assert_equal('Friendship', friend.meeting_for.first)
85
+ assert_equal('94303', friend.current_location.zip)
86
+ assert_equal('York', friend.hometown_location.city)
87
+ assert_equal('Harvard', friend.education_history.first.name)
88
+ assert(friend.education_history.first.concentrations.include?("Computer Science"))
89
+ assert_equal('Central York High School', friend.hs_info.hs1_name)
90
+ assert_equal('female', friend.meeting_sex.first)
91
+ assert_equal('I rule', friend.status.message)
92
+ end
93
+
94
+ def test_can_get_specific_info_for_one_or_more_users
95
+ friends = populate_session_friends_with_limited_fields
96
+ friend = friends.detect{|f| f.id == 222333}
97
+ assert_equal('I rule', friend.status.message)
98
+ assert_equal(nil, friend.hometown_location)
99
+ end
100
+
101
+ def test_session_can_expire_on_server_and_client_handles_appropriately
102
+ expect_http_posts_with_responses(example_session_expired_error_response)
103
+ assert_raises(Facebooker::Session::SessionExpired) {
104
+ @session.user.friends
105
+ }
106
+ end
107
+
108
+
109
+ def test_can_publish_story_to_users_feed
110
+ expect_http_posts_with_responses(example_publish_story_xml)
111
+ assert_nothing_raised {
112
+ assert(@session.user.publish_story((s = Facebooker::Feed::Story.new; s.title = 'o hai'; s.body = '4srsly'; s)))
113
+ }
114
+ end
115
+
116
+
117
+ def test_can_publish_action_to_users_feed
118
+ expect_http_posts_with_responses(example_publish_action_xml)
119
+ assert_nothing_raised {
120
+ assert(@session.user.publish_action((s = Facebooker::Feed::Action.new; s.title = 'o hai'; s.body = '4srsly'; s)))
121
+ }
122
+ end
123
+
124
+ def test_can_publish_templatized_action_to_users_feed
125
+ expect_http_posts_with_responses(example_publish_templatized_action_xml)
126
+ assert_nothing_raised {
127
+ action = Facebooker::Feed::TemplatizedAction.new
128
+ action.title_template = "{actor} did something"
129
+ assert(@session.user.publish_templatized_action(action))
130
+ }
131
+ end
132
+
133
+ def test_can_publish_templatized_action_to_users_feed_with_params_as_string
134
+ json_data="{\"move\": \"punch\"}"
135
+ action = Facebooker::Feed::TemplatizedAction.new
136
+ action.title_template = "{actor} did something "
137
+ action.title_data=json_data
138
+ assert_equal action.to_params[:title_data],json_data
139
+ end
140
+
141
+ def test_can_publish_templatized_action_to_users_feed_with_params_as_hash
142
+ json_data="{\"move\": \"punch\"}"
143
+ hash={:move=>"punch"}
144
+ hash.expects(:to_json).returns(json_data)
145
+ action = Facebooker::Feed::TemplatizedAction.new
146
+ action.title_template = "{actor} did something "
147
+ action.title_data=hash
148
+ assert_equal action.to_params[:title_data],json_data
149
+ end
150
+
151
+ def test_can_deactivate_template_bundle_by_id
152
+ expect_http_posts_with_responses(example_deactivate_template_bundle_by_id_xml)
153
+ assert_equal true, @session.post('facebook.feed.deactivateTemplateBundleByID', :template_bundle_id => 123)
154
+ end
155
+
156
+ def test_can_get_notifications_for_logged_in_user
157
+ expect_http_posts_with_responses(example_notifications_get_xml)
158
+ assert_equal("1", @session.user.notifications.messages.unread)
159
+ assert_equal("0", @session.user.notifications.pokes.unread)
160
+ assert_equal("1", @session.user.notifications.shares.unread)
161
+ end
162
+
163
+ def test_can_send_notifications
164
+ expect_http_posts_with_responses(example_notifications_send_xml)
165
+ assert_nothing_raised {
166
+ user_ids = [123, 321]
167
+ notification_fbml = "O HAI!!!"
168
+ optional_email_fbml = "This would be in the email. If this is not passed, facebook sends no mailz!"
169
+ assert_equal('http://www.facebook.com/send_email.php?from=211031&id=52', @session.send_notification(user_ids, notification_fbml, optional_email_fbml))
170
+ }
171
+ end
172
+
173
+ def test_can_send_emails
174
+ expect_http_posts_with_responses(example_notifications_send_email_xml)
175
+ assert_nothing_raised {
176
+ user_ids = [123, 321]
177
+ text = "Hi I am the text part of the email."
178
+ fbml = "Hi I am the fbml version of the <b>email</a>"
179
+ subject = "Somethign you should really pay attention to."
180
+ assert_equal('123,321', @session.send_email(user_ids, subject,text,fbml ))
181
+ }
182
+ end
183
+
184
+ def test_can_find_friends_who_have_installed_app
185
+ expect_http_posts_with_responses(example_app_users_xml)
186
+ assert_equal(2, @session.user.friends_with_this_app.size)
187
+ assert_equal([222333, 1240079], @session.user.friends_with_this_app.map{|f| f.id})
188
+ end
189
+
190
+ def test_when_marshaling_a_session_object_only_enough_data_to_stay_authenticated_is_stored
191
+ populate_session_friends
192
+ assert_equal(2, @session.user.friends.size)
193
+ reloaded_session = Marshal.load(Marshal.dump(@session))
194
+ %w(@session_key @uid @expires @secret_from_session @auth_token).each do |iv_name|
195
+ assert_not_nil(reloaded_session.instance_variable_get(iv_name))
196
+ end
197
+ assert_nil(reloaded_session.user.instance_variable_get("@friends"))
198
+ end
199
+
200
+ def test_sessions_can_be_infinite_or_can_expire
201
+ establish_session
202
+ assert(@session.expired?, "Session with expiry time #{@session.instance_variable_get('@expires')} occurred in the past and should be expired.")
203
+ @session.instance_variable_set("@expires", 0)
204
+ assert(@session.infinite?)
205
+ assert(!@session.expired?)
206
+ end
207
+
208
+ def test_session_can_tell_you_if_it_has_been_secured
209
+ mock = flexmock(Net::HTTP).should_receive(:post_form).and_return(example_auth_token_xml).once.ordered(:posts)
210
+ mock.should_receive(:post_form).and_return(example_get_session_xml.sub(/1173309298/, (Time.now + 60).to_i.to_s)).once.ordered(:posts)
211
+ @session.secure!
212
+ assert(@session.secured?)
213
+ end
214
+
215
+ def test_can_get_photos_by_pids
216
+ expect_http_posts_with_responses(example_get_photo_xml)
217
+ photos = @session.get_photos([97503428461115590, 97503428461115573])
218
+ assert_equal 2, photos.size
219
+ assert_equal "Rooftop barbecues make me act funny", photos.first.caption
220
+ end
221
+
222
+ def test_can_get_photos_by_subject_and_album
223
+ expect_http_posts_with_responses(example_get_photo_xml)
224
+ photos = @session.get_photos(nil, 22701786, 97503428432802022 )
225
+ assert_equal '97503428432802022', photos.first.aid
226
+ end
227
+
228
+ def test_getting_photos_requires_arguments
229
+ mock_http = establish_session
230
+ assert_raise(ArgumentError) { @session.get_photos() }
231
+ end
232
+
233
+ def test_can_get_albums_for_user
234
+ expect_http_posts_with_responses(example_user_albums_xml)
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
+ expect_http_posts_with_responses(example_user_albums_xml)
241
+ albums = @session.get_albums([97503428432802022, 97503428432797817] )
242
+ assert_equal('Summertime is Best', albums[0].name)
243
+ assert_equal('Bonofon\'s Recital', albums[1].name)
244
+ end
245
+
246
+ def test_can_create_album
247
+ expect_http_posts_with_responses(example_new_album_xml)
248
+ assert_equal "My Empty Album", @session.user.create_album(:name => "My Empty Album", :location => "Limboland").name
249
+ end
250
+
251
+ def test_can_upload_photo
252
+ mock_http = establish_session
253
+ mock_http.should_receive(:post_multipart_form).and_return(example_upload_photo_xml).once.ordered(:posts)
254
+ f = Net::HTTP::MultipartPostFile.new("image.jpg", "image/jpeg", "RAW DATA")
255
+ assert_equal "Under the sunset", @session.user.upload_photo(f).caption
256
+ end
257
+
258
+ def test_can_get_photo_tags
259
+ expect_http_posts_with_responses(example_photo_tags_xml)
260
+ assert_instance_of Facebooker::Tag, @session.get_tags(:pids => 97503428461115571 ).first
261
+ end
262
+
263
+ # TODO: how to test that tags were created properly? Response doesn't contain much
264
+ def test_can_tag_a_user_in_a_photo
265
+ expect_http_posts_with_responses(example_add_tag_xml)
266
+ assert !@session.add_tags(pid = 97503428461115571, x= 30.0, y = 62.5, tag_uid = 1234567890).nil?
267
+ end
268
+
269
+ def test_can_add_multiple_tags_to_photos
270
+ end
271
+
272
+ def test_can_get_coordinates_for_photo_tags
273
+ expect_http_posts_with_responses(example_photo_tags_xml)
274
+ tag = @session.get_tags([97503428461115571]).first
275
+ assert_equal ['65.4248', '16.8627'], tag.coordinates
276
+ end
277
+
278
+ def test_can_get_app_profile_fbml_for_user
279
+ expect_http_posts_with_responses(example_get_fbml_xml)
280
+ assert_match(/My profile!/, @session.user.profile_fbml)
281
+ end
282
+
283
+ def test_can_set_app_profile_fbml_for_user
284
+ expect_http_posts_with_responses(example_set_fbml_xml)
285
+ assert_nothing_raised {
286
+ @session.user.profile_fbml = 'aha!'
287
+ }
288
+ end
289
+
290
+ def test_get_logged_in_user
291
+ expect_http_posts_with_responses(example_get_logged_in_user_xml)
292
+ assert_equal 1240077, @session.post('facebook.users.getLoggedInUser', :session_key => @session.session_key)
293
+ end
294
+
295
+ def test_pages_get_info
296
+ expect_http_posts_with_responses(example_pages_get_info_xml)
297
+ info = {
298
+ 'page_id' => '4846711747',
299
+ 'name' => 'Kronos Quartet',
300
+ 'website' => 'http://www.kronosquartet.org',
301
+ 'company_overview' => ""
302
+ }
303
+ assert_equal [info], @session.post('facebook.pages.getInfo', :fields => ['company_overview', 'website', 'name', 'page_id'].join(','), :page_ids => [4846711747].join(','))
304
+ end
305
+
306
+ def test_pages_is_admin_true
307
+ expect_http_posts_with_responses(example_pages_is_admin_true_xml)
308
+ assert_equal true, @session.post('facebook.pages.isAdmin', :page_id => 123)
309
+ end
310
+
311
+ def test_pages_is_admin_false
312
+ expect_http_posts_with_responses(example_pages_is_admin_false_xml)
313
+ assert_equal false, @session.post('facebook.pages.isAdmin', :page_id => 123)
314
+ end
315
+
316
+ def test_users_set_status_true
317
+ expect_http_posts_with_responses(example_users_set_status_true_xml)
318
+ assert_equal true, @session.post('facebook.users.setStatus', :uid => 123, :status => 'message')
319
+ end
320
+
321
+ def test_users_set_status_false
322
+ expect_http_posts_with_responses(example_users_set_status_false_xml)
323
+ assert_equal false, @session.post('facebook.users.setStatus', :uid => 123, :status => 'message')
324
+ end
325
+
326
+ def test_desktop_apps_cannot_request_to_get_or_set_profile_fbml_for_any_user_other_than_logged_in_user
327
+ mock_http = establish_session(@desktop_session)
328
+ mock_http.should_receive(:post_form).and_return(example_friends_xml).once.ordered(:posts)
329
+ assert_raises(Facebooker::NonSessionUser) {
330
+ @desktop_session.user.friends.first.profile_fbml
331
+ }
332
+ assert_raises(Facebooker::NonSessionUser) {
333
+ @desktop_session.user.friends.first.profile_fbml = "O rly"
334
+ }
335
+ end
336
+
337
+ private
338
+ def populate_user_info
339
+ mock_http = establish_session
340
+ mock_http.should_receive(:post_form).and_return(example_user_info_xml).once
341
+ @session.user.populate
342
+ end
343
+
344
+ def populate_user_info_with_limited_fields
345
+ expect_http_posts_with_responses(example_limited_user_info_xml)
346
+ @session.user.populate(:affiliations, :status, :meeting_for)
347
+ end
348
+
349
+ def populate_session_friends
350
+ expect_http_posts_with_responses(example_friends_xml, example_user_info_xml)
351
+ @session.user.friends!
352
+ end
353
+
354
+ def populate_session_friends_with_limited_fields
355
+ expect_http_posts_with_responses(example_friends_xml, example_limited_user_info_xml)
356
+ @session.user.friends!(:affiliations, :status, :meeting_for)
357
+ end
358
+
359
+ def sample_args_to_post
360
+ {:method=>"facebook.auth.createToken", :sig=>"18b3dc4f5258a63c0ad641eebd3e3930"}
361
+ end
362
+
363
+ def example_pages_get_info_xml
364
+ <<-XML
365
+ <?xml version="1.0" encoding="UTF-8"?>
366
+ <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">
367
+ <page>
368
+ <page_id>4846711747</page_id>
369
+ <name>Kronos Quartet</name>
370
+ <website>http://www.kronosquartet.org</website>
371
+ <company_overview/>
372
+ </page>
373
+ </pages_getInfo_response>
374
+ XML
375
+ end
376
+
377
+ def example_pages_is_admin_true_xml
378
+ <<-XML
379
+ <?xml version="1.0" encoding="UTF-8"?>
380
+ <pages_isAdmin_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</pages_isAdmin_response>
381
+ XML
382
+ end
383
+
384
+ def example_pages_is_admin_false_xml
385
+ <<-XML
386
+ <?xml version="1.0" encoding="UTF-8"?>
387
+ <pages_isAdmin_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">0</pages_isAdmin_response>
388
+ XML
389
+ end
390
+
391
+ def example_users_set_status_true_xml
392
+ <<-XML
393
+ <?xml version="1.0" encoding="UTF-8"?>
394
+ <users_setStatus_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</users_setStatus_response>
395
+ XML
396
+ end
397
+
398
+ def example_users_set_status_false_xml
399
+ <<-XML
400
+ <?xml version="1.0" encoding="UTF-8"?>
401
+ <users_setStatus_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">0</users_setStatus_response>
402
+ XML
403
+ end
404
+
405
+ def example_set_fbml_xml
406
+ <<-XML
407
+ <?xml version="1.0" encoding="UTF-8"?>
408
+ <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>
409
+ XML
410
+ end
411
+
412
+ def example_get_fbml_xml
413
+ <<-XML
414
+ <?xml version="1.0" encoding="UTF-8"?>
415
+ <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">
416
+ &lt;fb:if-is-own-profile&gt;My profile!
417
+ &lt;fb:else&gt; Not my profile!&lt;/fb:else&gt;
418
+ &lt;/fb:if-is-own-profile&gt;
419
+ </profile_getFBML_response>
420
+ XML
421
+ end
422
+
423
+ def example_notifications_send_xml
424
+ <<-XML
425
+ <?xml version="1.0" encoding="UTF-8"?>
426
+ <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>
427
+ XML
428
+ end
429
+
430
+ def example_notifications_send_email_xml
431
+ <<-XML
432
+ <?xml version="1.0" encoding="UTF-8"?>
433
+ <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>
434
+ XML
435
+ end
436
+
437
+ def example_request_send_xml
438
+ <<-XML
439
+ <?xml version="1.0" encoding="UTF-8"?>
440
+ <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>
441
+ XML
442
+ end
443
+
444
+ def example_notifications_get_xml
445
+ <<-XML
446
+ <?xml version="1.0" encoding="UTF-8"?>
447
+ <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">
448
+ <messages>
449
+ <unread>1</unread>
450
+ <most_recent>1170644932</most_recent>
451
+ </messages>
452
+ <pokes>
453
+ <unread>0</unread>
454
+ <most_recent>0</most_recent>
455
+ </pokes>
456
+ <shares>
457
+ <unread>1</unread>
458
+ <most_recent>1170657686</most_recent>
459
+ </shares>
460
+ <friend_requests list="true">
461
+ <uid>2231342839</uid>
462
+ <uid>2231511925</uid>
463
+ <uid>2239284527</uid>
464
+ </friend_requests>
465
+ <group_invites list="true"/>
466
+ <event_invites list="true"/>
467
+ </notifications_get_response>
468
+ XML
469
+ end
470
+
471
+ def example_publish_story_xml
472
+ <<-XML
473
+ <?xml version="1.0" encoding="UTF-8"?>
474
+ <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>
475
+ XML
476
+ end
477
+
478
+ def example_publish_action_xml
479
+ <<-XML
480
+ <?xml version="1.0" encoding="UTF-8"?>
481
+ <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>
482
+ XML
483
+ end
484
+
485
+ def example_publish_templatized_action_xml
486
+ <<-XML
487
+ <?xml version="1.0" encoding="UTF-8"?>
488
+ <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">
489
+ <feed_publishTemplatizedAction_response_elt>1</feed_publishTemplatizedAction_response_elt>
490
+ </feed_publishTemplatizedAction_response>
491
+ XML
492
+ end
493
+
494
+ def example_deactivate_template_bundle_by_id_xml
495
+ <<-XML
496
+ <?xml version="1.0" encoding="UTF-8"?>
497
+ <feed_deactivateTemplateBundleByID_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/">1</feed_deactivateTemplateBundleByID_response>
498
+ XML
499
+ end
500
+
501
+ def example_user_info_xml
502
+ <<-XML
503
+ <?xml version="1.0" encoding="UTF-8"?>
504
+ <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">
505
+ <user>
506
+ <uid>222333</uid>
507
+ <about_me>This field perpetuates the glorification of the ego. Also, it has a character limit.</about_me>
508
+ <activities>Here: facebook, etc. There: Glee Club, a capella, teaching.</activities>
509
+ <affiliations list="true">
510
+ <affiliation>
511
+ <nid>50453093</nid>
512
+ <name>Facebook Developers</name>
513
+ <type>work</type>
514
+ <status/>
515
+ <year/>
516
+ </affiliation>
517
+ </affiliations>
518
+ <birthday>November 3</birthday>
519
+ <books>The Brothers K, GEB, Ken Wilber, Zen and the Art, Fitzgerald, The Emporer's New Mind, The Wonderful Story of Henry Sugar</books>
520
+ <current_location>
521
+ <city>Palo Alto</city>
522
+ <state>CA</state>
523
+ <country>United States</country>
524
+ <zip>94303</zip>
525
+ </current_location>
526
+ <education_history list="true">
527
+ <education_info>
528
+ <name>Harvard</name>
529
+ <year>2003</year>
530
+ <concentrations list="true">
531
+ <concentration>Applied Mathematics</concentration>
532
+ <concentration>Computer Science</concentration>
533
+ </concentrations>
534
+ <degree>Masters</degree>
535
+ </education_info>
536
+ </education_history>
537
+ <first_name>Dave</first_name>
538
+ <hometown_location>
539
+ <city>York</city>
540
+ <state>PA</state>
541
+ <country>United States</country>
542
+ <zip>0</zip>
543
+ </hometown_location>
544
+ <hs_info>
545
+ <hs1_name>Central York High School</hs1_name>
546
+ <hs2_name/>
547
+ <grad_year>1999</grad_year>
548
+ <hs1_id>21846</hs1_id>
549
+ <hs2_id>0</hs2_id>
550
+ </hs_info>
551
+ <is_app_user>1</is_app_user>
552
+ <has_added_app>1</has_added_app>
553
+ <interests>coffee, computers, the funny, architecture, code breaking,snowboarding, philosophy, soccer, talking to strangers</interests>
554
+ <last_name>Fetterman</last_name>
555
+ <meeting_for list="true">
556
+ <seeking>Friendship</seeking>
557
+ </meeting_for>
558
+ <meeting_sex list="true">
559
+ <sex>female</sex>
560
+ </meeting_sex>
561
+ <movies>Tommy Boy, Billy Madison, Fight Club, Dirty Work, Meet the Parents, My Blue Heaven, Office Space </movies>
562
+ <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>
563
+ <name>Dave Fetterman</name>
564
+ <notes_count>0</notes_count>
565
+ <pic>http://photos-055.facebook.com/ip007/profile3/1271/65/s8055_39735.jpg</pic>
566
+ <pic_big>http://photos-055.facebook.com/ip007/profile3/1271/65/n8055_39735.jpg</pic_big>
567
+ <pic_small>http://photos-055.facebook.com/ip007/profile3/1271/65/t8055_39735.jpg</pic_small>
568
+ <pic_square>http://photos-055.facebook.com/ip007/profile3/1271/65/q8055_39735.jpg</pic_square>
569
+ <political>Moderate</political>
570
+ <profile_update_time>1170414620</profile_update_time>
571
+ <quotes/>
572
+ <relationship_status>In a Relationship</relationship_status>
573
+ <religion/>
574
+ <sex>male</sex>
575
+ <significant_other_id xsi:nil="true"/>
576
+ <status>
577
+ <message>I rule</message>
578
+ <time>0</time>
579
+ </status>
580
+ <timezone>-8</timezone>
581
+ <tv>cf. Bob Trahan</tv>
582
+ <wall_count>121</wall_count>
583
+ <work_history list="true">
584
+ <work_info>
585
+ <location>
586
+ <city>Palo Alto</city>
587
+ <state>CA</state>
588
+ <country>United States</country>
589
+ </location>
590
+ <company_name>Facebook</company_name>
591
+ <position>Software Engineer</position>
592
+ <description>Tech Lead, Facebook Platform</description>
593
+ <start_date>2006-01</start_date>
594
+ <end_date/>
595
+ </work_info>
596
+ </work_history>
597
+ </user>
598
+ <user>
599
+ <uid>1240079</uid>
600
+ <about_me>I am here.</about_me>
601
+ <activities>Party.</activities>
602
+ </user>
603
+ </users_getInfo_response>
604
+ XML
605
+ end
606
+
607
+ def example_limited_user_info_xml
608
+ <<-XML
609
+ <?xml version="1.0" encoding="UTF-8"?>
610
+ <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">
611
+ <user>
612
+ <uid>222333</uid>
613
+ <affiliations list="true">
614
+ <affiliation>
615
+ <nid>50453093</nid>
616
+ <name>Facebook Developers</name>
617
+ <type>work</type>
618
+ <status/>
619
+ <year/>
620
+ </affiliation>
621
+ </affiliations>
622
+ <meeting_for list="true">
623
+ <seeking>Friendship</seeking>
624
+ </meeting_for>
625
+ <status>
626
+ <message>I rule</message>
627
+ <time>0</time>
628
+ </status>
629
+ </user>
630
+ <user>
631
+ <uid>1240079</uid>
632
+ <activities>Party.</activities>
633
+ </user>
634
+ </users_getInfo_response>
635
+ XML
636
+ end
637
+
638
+
639
+ def example_friends_xml
640
+ <<-XML
641
+ <?xml version="1.0" encoding="UTF-8"?>
642
+ <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">
643
+ <uid>222333</uid>
644
+ <uid>1240079</uid>
645
+ </friends_get_response>
646
+ XML
647
+ end
648
+
649
+ def example_friend_lists_xml
650
+ <<-XML
651
+ <?xml version="1.0" encoding="UTF-8"?>
652
+ <friends_getLists_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
+ <friendlist>
654
+ <flid>12089150545</flid>
655
+ <name>Family</name>
656
+ </friendlist>
657
+ <friendlist>
658
+ <flid>16361710545</flid>
659
+ <name>Entrepreneuer</name>
660
+ </friendlist>
661
+ </friends_getLists_response>
662
+ XML
663
+ end
664
+
665
+ def example_get_logged_in_user_xml
666
+ <<-XML
667
+ <?xml version="1.0" encoding="UTF-8"?>
668
+ <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>
669
+ XML
670
+ end
671
+
672
+ def example_invalid_api_key_error_response
673
+ <<-XML
674
+ <?xml version="1.0" encoding="UTF-8"?>
675
+ <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">
676
+ <error_code>101</error_code>
677
+ <error_msg>Invalid API key</error_msg>
678
+ <request_args list="true">
679
+ <arg>
680
+ <key>v</key>
681
+ <value>1.0</value>
682
+ </arg>
683
+ <arg>
684
+ <key>method</key>
685
+ <value>facebook.auth.createToken</value>
686
+ </arg>
687
+ <arg>
688
+ <key>sig</key>
689
+ <value>611f5f44e55f3fe17f858a8de84a4b0a</value>
690
+ </arg>
691
+ <arg>
692
+ <key>call_id</key>
693
+ <value>1186088346.82142</value>
694
+ </arg>
695
+ </request_args>
696
+ </error_response>
697
+ XML
698
+ end
699
+
700
+ def example_session_expired_error_response
701
+ <<-XML
702
+ <?xml version="1.0" encoding="UTF-8"?>
703
+ <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">
704
+ <error_code>102</error_code>
705
+ <error_msg>Session Expired</error_msg>
706
+ <request_args list="true">
707
+ <arg>
708
+ <key>v</key>
709
+ <value>1.0</value>
710
+ </arg>
711
+ <arg>
712
+ <key>method</key>
713
+ <value>facebook.auth.createToken</value>
714
+ </arg>
715
+ <arg>
716
+ <key>sig</key>
717
+ <value>611f5f44e55f3fe17f858a8de84a4b0a</value>
718
+ </arg>
719
+ <arg>
720
+ <key>call_id</key>
721
+ <value>1186088346.82142</value>
722
+ </arg>
723
+ </request_args>
724
+ </error_response>
725
+ XML
726
+ end
727
+
728
+ def example_app_users_xml
729
+ <<-XML
730
+ <?xml version="1.0" encoding="UTF-8"?>
731
+ <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">
732
+ <uid>222333</uid>
733
+ <uid>1240079</uid>
734
+ </friends_getAppUsers_response>
735
+ XML
736
+ end
737
+
738
+ def example_user_albums_xml
739
+ <<-XML
740
+ <?xml version="1.0" encoding="UTF-8"?>
741
+ <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">
742
+ <album>
743
+ <aid>97503428432802022</aid>
744
+ <cover_pid>97503428461115574</cover_pid>
745
+ <owner>22701786</owner>
746
+ <name>Summertime is Best</name>
747
+ <created>1184120648</created>
748
+ <modified>1185465771</modified>
749
+ <description>Happenings on or around Summer '07</description>
750
+ <location>Brooklyn, New York</location>
751
+ <link>http://www.facebook.com/album.php?aid=2011366&amp;id=22701786</link>
752
+ <size>49</size>
753
+ </album>
754
+ <album>
755
+ <aid>97503428432797817</aid>
756
+ <cover_pid>97503428460977993</cover_pid>
757
+ <owner>22701786</owner>
758
+ <name>Bonofon's Recital</name>
759
+ <created>1165356279</created>
760
+ <modified>1165382364</modified>
761
+ <description>The whole Ewing fam flies out to flatland to watch the Bonofon's senior recital. That boy sure can tinkle them ivories.</description>
762
+ <location>Grinnell College, Grinnell Iowa</location>
763
+ <link>http://www.facebook.com/album.php?aid=2007161&amp;id=22701786</link>
764
+ <size>14</size>
765
+ </album>
766
+ </photos_getAlbums_response>
767
+ XML
768
+ end
769
+
770
+ def example_upload_photo_xml
771
+ <<-XML
772
+ <?xml version="1.0" encoding="UTF-8"?>
773
+ <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">
774
+ <pid>940915697041656</pid>
775
+ <aid>940915667462717</aid>
776
+ <owner>219074</owner>
777
+ <src>http://ip002.facebook.com/v67/161/72/219074/s219074_31637752_5455.jpg</src>
778
+ <src_big>http://ip002.facebook.com/v67/161/72/219074/n219074_31637752_5455.jpg</src_big>
779
+ <src_small>http://ip002.facebook.com/v67/161/72/219074/t219074_31637752_5455.jpg</src_small>
780
+ <link>http://www.facebook.com/photo.php?pid=31637752&id=219074</link>
781
+ <caption>Under the sunset</caption>
782
+ </photos_upload_response>
783
+ XML
784
+ end
785
+
786
+ def example_new_album_xml
787
+ <<-XML
788
+ <?xml version="1.0" encoding="UTF-8"?>
789
+ <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">
790
+ <aid>34595963571485</aid>
791
+ <cover_pid>0</cover_pid>
792
+ <owner>8055</owner>
793
+ <name>My Empty Album</name>
794
+ <created>1132553109</created>
795
+ <modified>1132553363</modified>
796
+ <description>No I will not make out with you</description>
797
+ <location>York, PA</location>
798
+ <link>http://www.facebook.com/album.php?aid=2002205&id=8055</link>
799
+ <size>0</size>
800
+ </photos_createAlbum_response>
801
+ XML
802
+ end
803
+
804
+ def example_photo_tags_xml
805
+ <<-XML
806
+ <?xml version="1.0" encoding="UTF-8"?>
807
+ <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">
808
+ <photo_tag>
809
+ <pid>97503428461115571</pid>
810
+ <subject>570070524</subject>
811
+ <xcoord>65.4248</xcoord>
812
+ <ycoord>16.8627</ycoord>
813
+ </photo_tag>
814
+ </photos_getTags_response>
815
+ XML
816
+ end
817
+
818
+ def example_add_tag_xml
819
+ <<-XML
820
+ <?xml version="1.0" encoding="UTF-8"?>
821
+ <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>
822
+ XML
823
+ end
824
+
825
+ def example_get_photo_xml
826
+ <<-XML
827
+ <?xml version="1.0" encoding="UTF-8"?>
828
+ <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">
829
+ <photo>
830
+ <pid>97503428461115590</pid>
831
+ <aid>97503428432802022</aid>
832
+ <owner>22701786</owner>
833
+ <src>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324934_7816.jpg</src>
834
+ <src_big>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/n22701786_30324934_7816.jpg</src_big>
835
+ <src_small>http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/t22701786_30324934_7816.jpg</src_small>
836
+ <link>http://www.facebook.com/photo.php?pid=30324934&amp;id=22701786</link>
837
+ <caption>Rooftop barbecues make me act funny</caption>
838
+ <created>1184120987</created>
839
+ </photo>
840
+ <photo>
841
+ <pid>97503428461115573</pid>
842
+ <aid>97503428432802022</aid>
843
+ <owner>22701786</owner>
844
+ <src>http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324917_4555.jpg</src>
845
+ <src_big>http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/n22701786_30324917_4555.jpg</src_big>
846
+ <src_small>http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/t22701786_30324917_4555.jpg</src_small>
847
+ <link>http://www.facebook.com/photo.php?pid=30324917&amp;id=22701786</link>
848
+ <caption/>
849
+ <created>1184120654</created>
850
+ </photo>
851
+ </photos_get_response>
852
+ XML
853
+ end
854
+
855
+ end