1 from org.maemo.hermes.engine.facebook.service import Service
2 from org.maemo.hermes.engine.facebook.api import FacebookApi
3 from org.maemo.hermes.engine.names import canonical
4 from org.maemo.hermes.engine.friend import Friend
10 def __init__(self, name, addr, id=None):
13 self.id = id or FakeContact.id_counter
14 FakeContact.id_counter = FakeContact.id_counter + 1;
19 def get_identifiers(self):
20 return [canonical(self.name)]
22 class FakeFacebookApi():
25 def get_friends(self):
26 return FakeFacebookApi.friends
29 def authorise(self, authorise_url, access_token_url, args = None):
32 def request(self, url, args = None):
33 if url == 'https://graph.facebook.com/me':
34 return '{"id":"1234567","name":"Maemo Hermes"}'
36 elif url == 'https://graph.facebook.com/me/friends':
37 return '{"data":[{"id":"1","name":"J Smith","website":"http:\/\/www.example.org"},{"id":"2","name":"P Barnum","picture":"http://fbcn.example.com/32939012.jpg"}]}'
40 raise Exception("Unknown URL: %s" % (url))
42 def get_access_token(self):
46 class TestFacebookService(unittest.TestCase):
49 self.testee = Service("facebook", FakeFacebookApi())
52 def test_that_get_friends_to_create_contacts_for_works(self):
53 def run_test(expected_length):
54 self._fake_server_response([{'id':'123456','name':'Facebook Junkie', 'birthday':'now'}])
56 friends = self.testee.get_friends_to_create_contacts_for()
57 assert len(friends) == expected_length
59 # default is to NOT create contacts
60 self.testee = Service("facebook", FakeFacebookApi())
63 # passing False explicitly
64 self.testee = Service("facebook", FakeFacebookApi(), False)
67 # passing True to constructor
68 self.testee = Service("facebook", FakeFacebookApi(), True)
72 def test_that_gftccf_returns_friends_with_birth_date(self):
73 self.testee = Service("facebook", FakeFacebookApi(), True)
75 props_with_bday = {'id':'123456','name':'Facebook Junkie', 'birthday':bday}
76 props_without = {'id':'123457','name':'Johnny Secret'}
77 self._fake_server_response([props_with_bday, props_without])
80 assert len(self.testee.get_friends()) == 2
81 friends = self.testee.get_friends_to_create_contacts_for()
82 assert len(friends) == 1
83 assert friends[0].has_birthday_date()
84 assert friends[0].get_birthday_date() == bday
87 def test_that_process_contact_returns_friend_object_for_known_contact(self):
88 known_url = 'http://www.facebook.com/profile.php?id=123456'
89 known_contact = FakeContact('Facebook Junkie', [known_url])
90 self._fake_server_response([{'id':'123456','name':'Facebook Junkie'}])
92 self.testee.process_friends()
93 result = self.testee.process_contact(known_contact)
94 assert isinstance(result, Friend)
97 def test_that_process_contact_returns_None_for_unknown_contact(self):
98 known_contact = FakeContact('Facebook Junkie', [])
99 self._fake_server_response([])
101 self.testee.process_friends()
102 result = self.testee.process_contact(known_contact)
103 assert result is None
106 def test_main_flow_one_match_by_url_one_by_name(self):
108 self.existing_address = 'http://www.facebook.com/profile.php?id=123456'
109 self.existing_contact = FakeContact("Facebook Person", [self.existing_address])
110 existing_fake = {'id':'123456','name':'Name Doesnt Match but URL Does'}
112 self.other_address = 'http://twitter.com/not/correct/site'
113 self.other_contact = FakeContact("Twitter Person", [self.other_address])
114 other_fake = {'id':'123','name':self.other_contact.get_name()}
116 self.none_contact = FakeContact("No URLson", [])
118 fake_data = [existing_fake, other_fake]
119 self._fake_server_response(fake_data)
122 self._run_service([self.existing_contact, self.other_contact, self.none_contact])
125 friends = self.testee.get_friends()
126 contacts = self.testee.get_contacts_with_match()
127 assert len(friends) == 2
128 assert len(contacts) == 2
129 assert self.other_contact in contacts
130 assert self.other_contact == contacts[self.other_contact].get_contact()
131 assert self.existing_contact in contacts
132 assert self.existing_contact == contacts[self.existing_contact].get_contact()
133 assert self.none_contact not in contacts
136 def test_name_collision_avoided_by_previous_matching(self):
138 contact_do_match = FakeContact(name, ["http://www.facebook.com/profile.php?id=123"], 1);
139 contact_no_match = FakeContact(name, [None], 2)
141 data = [{'id':'123','name':name}]
142 self._fake_server_response(data)
144 self._run_service([contact_no_match, contact_do_match])
146 assert len(self.testee.get_unmatched_friends()) == 0
147 matchers = self.testee.get_contacts_with_match().keys()
148 assert len(matchers) == 1
149 assert matchers[0].id == 1
152 def test_name_collision_avoided_only_one_person_matched(self):
154 contact_do_match = FakeContact(name, ["Contact 1"]);
155 contact_no_match = FakeContact(name, ["Contact 2"])
157 data = [{'id':'123','name':name}]
158 self._fake_server_response(data)
160 self._run_service([contact_no_match, contact_do_match])
162 matchers = self.testee.get_contacts_with_match().keys()
163 assert len(matchers) == 1
164 assert len(self.testee.get_unmatched_friends()) == 0
167 def _run_service(self, contacts):
168 for contact in contacts:
169 self.testee.pre_process_contact(contact)
170 self.testee.process_friends()
171 for contact in contacts:
172 self.testee.process_contact(contact)
174 def _fake_server_response(self, data):
175 FakeFacebookApi.friends = data
178 class TestFacebookAPI(unittest.TestCase):
181 self.oauth = FakeOAuth()
182 self.api = FacebookApi(self.oauth)
184 def test_authenticate(self):
188 def test_get_user(self):
189 assert self.api.get_user() == 'Maemo Hermes'
192 def test_get_friends(self):
193 friends = self.api.get_friends()
194 assert len(friends) == 2
195 assert friends[0]['name'] == 'J Smith'
196 assert friends[1]['id'] == '2'
197 assert friends[1]['picture'] == 'https://graph.facebook.com/2/picture?type=large&access_token=XXX'
200 if __name__ == '__main__':