require File.expand_path(File.dirname(__FILE__) + '/test_helper') require 'net/http_multipart_post' class TestFacebooker < Test::Unit::TestCase def setup @api_key = "95a71599e8293s66f1f0a6f4aeab3df7" @secret_key = "3e4du8eea435d8e205a6c9b5d095bed1" ENV["FACEBOOK_API_KEY"] = @api_key ENV["FACEBOOK_SECRET_KEY"] = @secret_key @session = Facebooker::Session.create(@api_key, @secret_key) @desktop_session = Facebooker::Session::Desktop.create(@api_key, @secret_key) @service = Facebooker::Service.new('http://apibase.com', '/api/path', @api_key) @desktop_session.instance_variable_set("@service", @service) end def test_asset_host_callback_url Facebooker.set_asset_host_to_callback_url = true assert_equal true, Facebooker.set_asset_host_to_callback_url Facebooker.set_asset_host_to_callback_url = false assert_equal false, Facebooker.set_asset_host_to_callback_url end def test_session_must_be_created_from_api_key_and_secret_key assert_kind_of(Facebooker::Session, @session) end def test_session_can_tell_you_its_login_url assert_not_nil(@session.login_url) assert_equal("http://www.facebook.com/login.php?api_key=#{@api_key}&v=1.0", @session.login_url) end def test_desktop_session_returns_auth_toke_as_part_of_login_url @service = flexmock(@service).should_receive(:post).at_least.once.and_return(123) assert_kind_of(Facebooker::Session::Desktop, @desktop_session) assert_match(/auth_token=[a-z0-9A-Z]/, @desktop_session.login_url) end def test_service_posts_data_to_http_location flexmock(Net::HTTP).should_receive(:post_form).and_return(example_auth_token_xml) assert_equal("http://www.facebook.com/login.php?api_key=#{@api_key}&v=1.0&auth_token=3e4a22bb2f5ed75114b0fc9995ea85f1", @desktop_session.login_url) end # def test_serivce_post_file_delegates_to_post_multipart_form # # flexmock(@service).should_receive(:url).and_return('url') # # flexmock(Net::HTTP).expects(:post_multipart_form).with('url', {:method => 'facebook.auth.createToken'}).returns(example_auth_token_xml) # # res = mock(:content_type => 'text/html', :code => '200', :body => 'my blog') # Net::HTTP.stubs(:get_response).once.with(uri).returns res # # @service.post_file(:method => 'facebook.auth.createToken') # end def test_desktop_session_be_secured_and_activated_after_receiving_auth_token_and_logging_in establish_session assert_equal("5f34e11bfb97c762e439e6a5-8055", @session.instance_variable_get("@session_key")) end def test_desktop_session_uses_secret_api_key_for_hashing_until_user_authenticates assert_equal(@secret_key, @desktop_session.secret_for_method('facebook.auth.createToken')) establish_session(@desktop_session) assert_equal("ohairoflamao12345", @desktop_session.secret_for_method('anyNonAuthMethodName')) end def test_session_can_get_current_logged_in_user_id_and_will_cache establish_session flexmock(Net::HTTP).should_receive(:post_form).and_return(example_get_logged_in_user_xml) assert_equal(8055, @session.user.id) end def test_can_get_current_users_friends expect_http_posts_with_responses(example_friends_xml) assert_equal([222333, 1240079], @session.user.friends.map{|friend| friend.id}) end def test_can_get_current_users_friend_lists expect_http_posts_with_responses(example_friend_lists_xml) assert_equal([12089150545, 16361710545], @session.user.friend_lists.map{|friend_list| friend_list.flid}) end def test_can_get_info_for_instance_of_user populate_user_info @session.user.first_name = "Dave" end def test_can_get_info_for_one_or_more_users friends = populate_session_friends friend = friends.detect{|f| f.id == 222333} assert_equal('This field perpetuates the glorification of the ego. Also, it has a character limit.', friend.about_me) assert_equal('Facebook Developers', friend.affiliations.first.name) assert_equal('Friendship', friend.meeting_for.first) assert_equal('94303', friend.current_location.zip) assert_equal('York', friend.hometown_location.city) assert_equal('Harvard', friend.education_history.first.name) assert(friend.education_history.first.concentrations.include?("Computer Science")) assert_equal('Central York High School', friend.hs_info.hs1_name) assert_equal('female', friend.meeting_sex.first) assert_equal('I rule', friend.status.message) end def test_can_get_specific_info_for_one_or_more_users friends = populate_session_friends_with_limited_fields friend = friends.detect{|f| f.id == 222333} assert_equal('I rule', friend.status.message) assert_equal(nil, friend.hometown_location) end def test_can_handle_nil_data friends = populate_session_friends_with_nil_data friend = friends.detect{|f| f.id == 222333} assert_equal(nil,friend.current_location) assert_equal(nil,friend.pic) end def test_session_can_expire_on_server_and_client_handles_appropriately expect_http_posts_with_responses(example_session_expired_error_response) assert_raises(Facebooker::Session::SessionExpired) { @session.user.friends } end def test_can_publish_story_to_users_feed expect_http_posts_with_responses(example_publish_story_xml) assert_nothing_raised { assert(@session.user.publish_story((s = Facebooker::Feed::Story.new; s.title = 'o hai'; s.body = '4srsly'; s))) } end def test_can_publish_action_to_users_feed expect_http_posts_with_responses(example_publish_action_xml) assert_nothing_raised { assert(@session.user.publish_action((s = Facebooker::Feed::Action.new; s.title = 'o hai'; s.body = '4srsly'; s))) } end def test_can_publish_templatized_action_to_users_feed expect_http_posts_with_responses(example_publish_templatized_action_xml) assert_nothing_raised { action = Facebooker::Feed::TemplatizedAction.new action.title_template = "{actor} did something" assert(@session.user.publish_templatized_action(action)) } end def test_can_publish_templatized_action_to_users_feed_with_params_as_string json_data="{\"move\": \"punch\"}" action = Facebooker::Feed::TemplatizedAction.new action.title_template = "{actor} did something " action.title_data=json_data assert_equal action.to_params[:title_data],json_data end def test_can_publish_templatized_action_to_users_feed_with_params_as_hash json_data="{\"move\": \"punch\"}" hash={:move=>"punch"} hash.expects(:to_json).returns(json_data) action = Facebooker::Feed::TemplatizedAction.new action.title_template = "{actor} did something " action.title_data=hash assert_equal action.to_params[:title_data],json_data end def test_can_deactivate_template_bundle_by_id expect_http_posts_with_responses(example_deactivate_template_bundle_by_id_xml) assert_equal true, @session.post('facebook.feed.deactivateTemplateBundleByID', :template_bundle_id => 123) end def test_can_get_notifications_for_logged_in_user expect_http_posts_with_responses(example_notifications_get_xml) assert_equal("1", @session.user.notifications.messages.unread) assert_equal("0", @session.user.notifications.pokes.unread) assert_equal("1", @session.user.notifications.shares.unread) end def test_can_send_notifications expect_http_posts_with_responses(example_notifications_send_xml) assert_nothing_raised { user_ids = [123, 321] notification_fbml = "O HAI!!!" optional_email_fbml = "This would be in the email. If this is not passed, facebook sends no mailz!" assert_equal('http://www.facebook.com/send_email.php?from=211031&id=52', @session.send_notification(user_ids, notification_fbml, optional_email_fbml)) } end def test_can_send_emails expect_http_posts_with_responses(example_notifications_send_email_xml) assert_nothing_raised { user_ids = [123, 321] text = "Hi I am the text part of the email." fbml = "Hi I am the fbml version of the email" subject = "Somethign you should really pay attention to." assert_equal('123,321', @session.send_email(user_ids, subject,text,fbml )) } end def test_can_find_friends_who_have_installed_app expect_http_posts_with_responses(example_app_users_xml) assert_equal(2, @session.user.friends_with_this_app.size) assert_equal([222333, 1240079], @session.user.friends_with_this_app.map{|f| f.id}) end def test_when_marshaling_a_session_object_only_enough_data_to_stay_authenticated_is_stored populate_session_friends assert_equal(2, @session.user.friends.size) reloaded_session = Marshal.load(Marshal.dump(@session)) %w(@session_key @uid @expires @secret_from_session @auth_token).each do |iv_name| assert_not_nil(reloaded_session.instance_variable_get(iv_name)) end assert_nil(reloaded_session.user.instance_variable_get("@friends")) end def test_sessions_can_be_infinite_or_can_expire establish_session assert(@session.expired?, "Session with expiry time #{@session.instance_variable_get('@expires')} occurred in the past and should be expired.") @session.instance_variable_set("@expires", 0) assert(@session.infinite?) assert(!@session.expired?) end def test_session_can_tell_you_if_it_has_been_secured mock = flexmock(Net::HTTP).should_receive(:post_form).and_return(example_auth_token_xml).once.ordered(:posts) mock.should_receive(:post_form).and_return(example_get_session_xml.sub(/1173309298/, (Time.now + 60).to_i.to_s)).once.ordered(:posts) @session.secure! assert(@session.secured?) end def test_can_get_photos_by_pids expect_http_posts_with_responses(example_get_photo_xml) photos = @session.get_photos([97503428461115590, 97503428461115573]) assert_equal 2, photos.size assert_equal "Rooftop barbecues make me act funny", photos.first.caption assert_equal "97503428461115590", photos[0].id end def test_can_get_photos_by_subject_and_album expect_http_posts_with_responses(example_get_photo_xml) photos = @session.get_photos(nil, 22701786, 97503428432802022 ) assert_equal '97503428432802022', photos.first.aid end def test_getting_photos_requires_arguments mock_http = establish_session assert_raise(ArgumentError) { @session.get_photos() } end def test_can_get_albums_for_user expect_http_posts_with_responses(example_user_albums_xml) assert_equal('Summertime is Best', @session.user.albums.first.name) assert_equal(2, @session.user.albums.size) end def test_can_get_albums_by_album_ids expect_http_posts_with_responses(example_user_albums_xml) albums = @session.get_albums([97503428432802022, 97503428432797817] ) assert_equal('Summertime is Best', albums[0].name) assert_equal('Bonofon\'s Recital', albums[1].name) end def test_can_create_album expect_http_posts_with_responses(example_new_album_xml) assert_equal "My Empty Album", @session.user.create_album(:name => "My Empty Album", :location => "Limboland").name end def test_can_upload_photo mock_http = establish_session mock_http.should_receive(:post_multipart_form).and_return(example_upload_photo_xml).once.ordered(:posts) f = Net::HTTP::MultipartPostFile.new("image.jpg", "image/jpeg", "RAW DATA") assert_equal "Under the sunset", @session.user.upload_photo(f).caption end def test_can_get_photo_tags expect_http_posts_with_responses(example_photo_tags_xml) assert_instance_of Facebooker::Tag, @session.get_tags(:pids => 97503428461115571 ).first end # TODO: how to test that tags were created properly? Response doesn't contain much def test_can_tag_a_user_in_a_photo expect_http_posts_with_responses(example_add_tag_xml) assert !@session.add_tags(pid = 97503428461115571, x= 30.0, y = 62.5, tag_uid = 1234567890).nil? end def test_can_add_multiple_tags_to_photos end def test_can_get_coordinates_for_photo_tags expect_http_posts_with_responses(example_photo_tags_xml) tag = @session.get_tags([97503428461115571]).first assert_equal ['65.4248', '16.8627'], tag.coordinates end def test_can_upload_video mock_http = establish_session mock_http.should_receive(:post_multipart_form).and_return(example_upload_video_xml).once f = Net::HTTP::MultipartPostFile.new("party.mp4", "video/mpeg", "RAW DATA") assert_equal "Some Epic", @session.user.upload_video(f).title end def test_can_get_app_profile_fbml_for_user expect_http_posts_with_responses(example_get_fbml_xml) assert_match(/My profile!/, @session.user.profile_fbml) end def test_can_set_app_profile_fbml_for_user expect_http_posts_with_responses(example_set_fbml_xml) assert_nothing_raised { @session.user.profile_fbml = 'aha!' } end def test_get_logged_in_user expect_http_posts_with_responses(example_get_logged_in_user_xml) assert_equal 1240077, @session.post('facebook.users.getLoggedInUser', :session_key => @session.session_key) end def test_pages_get_info expect_http_posts_with_responses(example_pages_get_info_xml) info = { 'page_id' => '4846711747', 'name' => 'Kronos Quartet', 'website' => 'http://www.kronosquartet.org', 'company_overview' => "" } assert_equal [info], @session.post('facebook.pages.getInfo', :fields => ['company_overview', 'website', 'name', 'page_id'].join(','), :page_ids => [4846711747].join(',')) end def test_pages_is_admin_true expect_http_posts_with_responses(example_pages_is_admin_true_xml) assert_equal true, @session.post('facebook.pages.isAdmin', :page_id => 123) end def test_pages_is_admin_false expect_http_posts_with_responses(example_pages_is_admin_false_xml) assert_equal false, @session.post('facebook.pages.isAdmin', :page_id => 123) end def test_pages_is_fan_true expect_http_posts_with_responses(example_pages_is_fan_true_xml) assert_equal true, @session.post('facebook.pages.isFan', :page_id => 123) end def test_pages_is_fan_false expect_http_posts_with_responses(example_pages_is_fan_false_xml) assert_equal false, @session.post('facebook.pages.isFan', :page_id => 123) end def test_users_set_status_true expect_http_posts_with_responses(example_users_set_status_true_xml) assert_equal true, @session.post('facebook.users.setStatus', :uid => 123, :status => 'message') end def test_users_set_status_false expect_http_posts_with_responses(example_users_set_status_false_xml) assert_equal false, @session.post('facebook.users.setStatus', :uid => 123, :status => 'message') end def test_desktop_apps_cannot_request_to_get_or_set_profile_fbml_for_any_user_other_than_logged_in_user mock_http = establish_session(@desktop_session) mock_http.should_receive(:post_form).and_return(example_friends_xml).once.ordered(:posts) assert_raises(Facebooker::NonSessionUser) { @desktop_session.user.friends.first.profile_fbml } assert_raises(Facebooker::NonSessionUser) { @desktop_session.user.friends.first.profile_fbml = "O rly" } end def test_revoke_authorization_true expect_http_posts_with_responses(example_revoke_authorization_true) assert_equal true, @session.post('facebook.auth.revokeAuthorization', :uid => 123) end def test_revoke_authorization_false expect_http_posts_with_responses(example_revoke_authorization_false) assert_equal false, @session.post('facebook.auth.revokeAuthorization', :uid => 123) end private def populate_user_info mock_http = establish_session mock_http.should_receive(:post_form).and_return(example_user_info_xml).once @session.user.populate end def populate_user_info_with_limited_fields expect_http_posts_with_responses(example_limited_user_info_xml) @session.user.populate(:affiliations, :status, :meeting_for) end def populate_session_friends expect_http_posts_with_responses(example_friends_xml, example_user_info_xml) @session.user.friends! end def populate_session_friends_with_limited_fields expect_http_posts_with_responses(example_friends_xml, example_limited_user_info_xml) @session.user.friends!(:affiliations, :status, :meeting_for) end def populate_session_friends_with_nil_data expect_http_posts_with_responses(example_friends_xml, example_nil_user_info_xml) @session.user.friends!(:name, :current_location, :pic) end def sample_args_to_post {:method=>"facebook.auth.createToken", :sig=>"18b3dc4f5258a63c0ad641eebd3e3930"} end def example_pages_get_info_xml <<-XML 4846711747 Kronos Quartet http://www.kronosquartet.org XML end def example_pages_is_admin_true_xml <<-XML 1 XML end def example_pages_is_admin_false_xml <<-XML 0 XML end def example_pages_is_fan_true_xml <<-XML 1 XML end def example_pages_is_fan_false_xml <<-XML 0 XML end def example_users_set_status_true_xml <<-XML 1 XML end def example_users_set_status_false_xml <<-XML 0 XML end def example_set_fbml_xml <<-XML 1 XML end def example_get_fbml_xml <<-XML <fb:if-is-own-profile>My profile! <fb:else> Not my profile!</fb:else> </fb:if-is-own-profile> XML end def example_notifications_send_xml <<-XML http://www.facebook.com/send_email.php?from=211031&id=52 XML end def example_notifications_send_email_xml <<-XML 123,321 XML end def example_request_send_xml <<-XML http://www.facebook.com/send_req.php?from=211031&id=6 XML end def example_notifications_get_xml <<-XML 1 1170644932 0 0 1 1170657686 2231342839 2231511925 2239284527 XML end def example_publish_story_xml <<-XML 1 XML end def example_publish_action_xml <<-XML 1 XML end def example_publish_templatized_action_xml <<-XML 1 XML end def example_deactivate_template_bundle_by_id_xml <<-XML 1 XML end def example_user_info_xml <<-XML 222333 This field perpetuates the glorification of the ego. Also, it has a character limit. Here: facebook, etc. There: Glee Club, a capella, teaching. 50453093 Facebook Developers work November 3 The Brothers K, GEB, Ken Wilber, Zen and the Art, Fitzgerald, The Emporer's New Mind, The Wonderful Story of Henry Sugar Palo Alto CA United States 94303 Harvard 2003 Applied Mathematics Computer Science Masters Dave York PA United States 0 Central York High School 1999 21846 0 1 1 coffee, computers, the funny, architecture, code breaking,snowboarding, philosophy, soccer, talking to strangers Fetterman Friendship female Tommy Boy, Billy Madison, Fight Club, Dirty Work, Meet the Parents, My Blue Heaven, Office Space New Found Glory, Daft Punk, Weezer, The Crystal Method, Rage, the KLF, Green Day, Live, Coldplay, Panic at the Disco, Family Force 5 Dave Fetterman 0 http://photos-055.facebook.com/ip007/profile3/1271/65/s8055_39735.jpg http://photos-055.facebook.com/ip007/profile3/1271/65/n8055_39735.jpg http://photos-055.facebook.com/ip007/profile3/1271/65/t8055_39735.jpg http://photos-055.facebook.com/ip007/profile3/1271/65/q8055_39735.jpg Moderate 1170414620 In a Relationship male I rule -8 cf. Bob Trahan 121 Palo Alto CA United States Facebook Software Engineer Tech Lead, Facebook Platform 2006-01 1240079 I am here. Party. XML end def example_limited_user_info_xml <<-XML 222333 50453093 Facebook Developers work Friendship I rule 1240079 Party. XML end def example_nil_user_info_xml <<-XML 222333 Kevin Lochner XML end def example_friends_xml <<-XML 222333 1240079 XML end def example_friend_lists_xml <<-XML 12089150545 Family 16361710545 Entrepreneuer XML end def example_get_logged_in_user_xml <<-XML 1240077 XML end def example_invalid_api_key_error_response <<-XML 101 Invalid API key v 1.0 method facebook.auth.createToken sig 611f5f44e55f3fe17f858a8de84a4b0a call_id 1186088346.82142 XML end def example_session_expired_error_response <<-XML 102 Session Expired v 1.0 method facebook.auth.createToken sig 611f5f44e55f3fe17f858a8de84a4b0a call_id 1186088346.82142 XML end def example_app_users_xml <<-XML 222333 1240079 XML end def example_user_albums_xml <<-XML 97503428432802022 97503428461115574 22701786 Summertime is Best 1184120648 1185465771 Happenings on or around Summer '07 Brooklyn, New York http://www.facebook.com/album.php?aid=2011366&id=22701786 49 97503428432797817 97503428460977993 22701786 Bonofon's Recital 1165356279 1165382364 The whole Ewing fam flies out to flatland to watch the Bonofon's senior recital. That boy sure can tinkle them ivories. Grinnell College, Grinnell Iowa http://www.facebook.com/album.php?aid=2007161&id=22701786 14 XML end def example_upload_photo_xml <<-XML 940915697041656 940915667462717 219074 http://ip002.facebook.com/v67/161/72/219074/s219074_31637752_5455.jpg http://ip002.facebook.com/v67/161/72/219074/n219074_31637752_5455.jpg http://ip002.facebook.com/v67/161/72/219074/t219074_31637752_5455.jpg http://www.facebook.com/photo.php?pid=31637752&id=219074 Under the sunset XML end def example_new_album_xml <<-XML 34595963571485 0 8055 My Empty Album 1132553109 1132553363 No I will not make out with you York, PA http://www.facebook.com/album.php?aid=2002205&id=8055 0 XML end def example_photo_tags_xml <<-XML 97503428461115571 570070524 65.4248 16.8627 XML end def example_add_tag_xml <<-XML 1 XML end def example_get_photo_xml <<-XML 97503428461115590 97503428432802022 22701786 http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324934_7816.jpg http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/n22701786_30324934_7816.jpg http://photos-c.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/t22701786_30324934_7816.jpg http://www.facebook.com/photo.php?pid=30324934&id=22701786 Rooftop barbecues make me act funny 1184120987 97503428461115573 97503428432802022 22701786 http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/s22701786_30324917_4555.jpg http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/n22701786_30324917_4555.jpg http://photos-b.ak.facebook.com/photos-ak-sf2p/v77/74/112/22701786/t22701786_30324917_4555.jpg http://www.facebook.com/photo.php?pid=30324917&id=22701786 1184120654 XML end def example_upload_video_xml <<-XML 15943367753 Some Epic Check it out http://www.facebook.com/video/video.php?v=15943367753 XML end def example_revoke_authorization_true "1" end def example_revoke_authorization_false "0" end end