""" :copyright: 2010 by Manuel Jacob :license: MIT """ from mock import Mock, MagicMock from nose.tools import assert_raises from tests.constants import (SERVER1, USER1_UNI, USER2_UNI, USER1_NICK, USER2_NICK, PLACE_UNI, SERVER2_UNI, MESSAGE, PRESENCE_OFFLINE, PRESENCE_ONLINE, ERROR, EXCEPTION) from tests.helpers import mockified, AsyncMethod, PlaceHolder, iter_ from pypsyc.client.controller import (ListBinding, AccountsController, ConversationController, ConferenceController, TabsController, FriendListController, DumpController, MainController) from pypsyc.client.model import Message from pypsyc.client.observable import ObsList, ObsDict, ObsObj, ObsAttr from pypsyc.util import Event def _check_obs_list(obs_list): assert obs_list.setitem_evt.observers == [] assert obs_list.delitem_evt.observers == [] assert obs_list.insert_evt.observers == [] assert obs_list.update_evt.observers == [] return True def _check_obs_dict(obs_dict): assert obs_dict.setitem_evt.observers == [] assert obs_dict.delitem_evt.observers == [] assert obs_dict.update_evt.observers == [] return True def _check_obs_obj(obs_obj): assert obs_obj.update_evt != {} for evt in obs_obj.update_evt.itervalues(): assert evt.observers == [] return True class TestListBinding(object): def setup(self): self.model = Mock() self.model_list = ObsList([self.model]) self.view_list = [] self.make_row = Mock() self.binding = ListBinding(self.model_list, self.view_list, self.make_row) def test_bind(self): assert self.make_row.call_args_list == [((self.model,),)] assert self.view_list == [self.make_row.return_value] def test_add(self): assert self.make_row.call_args_list == [((self.model,),)] self.make_row.reset_mock() model2 = Mock() self.model_list.append(model2) assert self.make_row.call_args_list == [((model2,),)] assert self.view_list == [self.make_row.return_value] * 2 def test_update(self): assert self.make_row.call_args_list == [((self.model,),)] self.make_row.reset_mock() self.model_list.updated_item(self.model) assert self.make_row.call_args_list == [((self.model,),)] assert self.view_list == [self.make_row.return_value] def test_delete(self): del self.model_list[0] assert self.view_list == [] def test_unbind(self): self.binding.unbind() assert _check_obs_list(self.model_list) assert self.view_list == [] class _List(list): def __init__(self, *args, **kwds): list.__init__(self, *args, **kwds) self.updated_item = Mock() class TestAccountsController(object): @mockified('pypsyc.client.controller', ['ListBinding']) def setup(self, ListBinding): self.ListBinding = ListBinding self.account = Mock() self.client = Mock() self.client.accounts = _List([self.account]) self.view = Mock() self.controller = AccountsController(self.client, self.view) def test_binding(self): make_row_ph = PlaceHolder() assert self.ListBinding.call_args_list == [ ((self.client.accounts, self.view.accounts, make_row_ph),)] account = Mock() row = make_row_ph.obj(account) assert row == (account.uni, account.active) @mockified('pypsyc.client.controller', ['Account']) def test_add_account(self, Account): account = Account.return_value callback_ph = PlaceHolder() self.controller.add_account() assert Account.call_args_list == [ ((self.client, '', '', '', False, False),)] assert self.view.method_calls == [ ('show_addedit_dialog', (account.__dict__, True, callback_ph))] callback_ph.obj() assert self.client.accounts == [self.account, account] assert self.client.method_calls == [('save_accounts',)] def test_edit_account(self): callback_ph = PlaceHolder() self.controller.edit_account(0) assert self.view.method_calls == [ ('show_addedit_dialog', (self.account.__dict__, False, callback_ph))] callback_ph.obj() assert self.client.accounts.updated_item.call_args_list == [ ((self.account,),)] assert self.client.method_calls == [('save_accounts',)] def test_remove_account(self): assert_raises(IndexError, self.controller.remove_account, 1) self.controller.remove_account(0) assert self.client.accounts == [] assert self.client.method_calls == [('save_accounts',)] def test_set_active(self): self.controller.set_active(0, True) assert self.account.active == True assert self.client.accounts.updated_item.call_args_list == [ ((self.account,),)] assert self.client.method_calls == [('save_accounts',)] def test_closed(self): self.controller.closed() assert self.ListBinding.return_value.method_calls == [('unbind',)] IN = 'i' OUT = 'o' LINE = 'line' class _StubAccount(ObsObj): circuit = ObsAttr('circuit') class TestDumpController: def setup(self): self.circuit = Mock() self.circuit.dump_evt = Event() self.account = _StubAccount() self.account.uni = USER1_UNI self.client = Mock() self.client.accounts = ObsList() self.view = Mock() def test_connected(self): self.account.circuit = self.circuit self.client.accounts.append(self.account) DumpController(self.client, self.view) self.circuit.dump_evt(IN, LINE) assert self.view.method_calls == [('show_line', (IN, LINE, USER1_UNI))] def test_connect(self): DumpController(self.client, self.view) self.client.accounts.append(self.account) self.account.circuit = self.circuit self.circuit.dump_evt(IN, LINE) assert self.view.method_calls == [('show_line', (IN, LINE, USER1_UNI))] def test_disconnect(self): self.account.circuit = self.circuit self.client.accounts.append(self.account) DumpController(self.client, self.view) del self.account.circuit assert self.circuit.dump_evt.observers == [] def test_reconnect(self): DumpController(self.client, self.view) self.account.circuit = self.circuit self.client.accounts.append(self.account) circuit2 = Mock() circuit2.dump_evt = Event() self.account.circuit = circuit2 assert self.circuit.dump_evt.observers == [] circuit2.dump_evt(OUT, LINE) assert self.view.method_calls == [ ('show_line', (OUT, LINE, USER1_UNI))] def test_remove(self): self.client.accounts.append(self.account) self.account.circuit = self.circuit DumpController(self.client, self.view) self.client.accounts.remove(self.account) assert _check_obs_obj(self.account) assert self.circuit.dump_evt.observers == [] def test_remove_nocircuit(self): self.client.accounts.append(self.account) DumpController(self.client, self.view) self.client.accounts.remove(self.account) assert _check_obs_obj(self.account) def test_closed(self): self.client.accounts.append(self.account) self.account.circuit = self.circuit dump_controller = DumpController(self.client, self.view) dump_controller.closed() assert _check_obs_list(self.client.accounts) assert _check_obs_obj(self.account) assert self.circuit.dump_evt.observers == [] class TestConversationController(object): def setup(self): self.tabs_controller = Mock() self.conversation = Mock() self.conversation.messages = ObsList() self.conversation.unknown_target_evt = Event() self.conversation.delivery_failed_evt = Event() self.view = Mock() self.controller = ConversationController(self.tabs_controller, self.conversation, self.view) def test_message(self): MESSAGE_OBJ = Message(USER2_UNI, MESSAGE) MESSAGE_LINE = "(%s) <%s> %s" % ( MESSAGE_OBJ.time.strftime("%H:%M:%S"), USER2_UNI, MESSAGE) self.conversation.messages.append(MESSAGE_OBJ) assert self.view.method_calls == [('show_message', (MESSAGE_LINE,))] def test_unknown_target(self): self.conversation.unknown_target_evt() assert self.view.method_calls == [('show_unknown_target',)] def test_delivery_failed(self): self.conversation.delivery_failed_evt(ERROR) assert self.view.method_calls == [('show_delivery_failed', (ERROR,))] def test_enter_message(self): self.controller.enter(MESSAGE) assert self.conversation.method_calls == [('send_message', (MESSAGE,))] def test_enter_command(self): self.controller.enter("/command") assert self.view.method_calls == [('show_unknown_command',)] assert self.conversation.method_calls == [] def test_closed(self): self.conversation.messages.append(Message(None, None)) self.controller.closed() assert _check_obs_list(self.conversation.messages) assert self.conversation.unknown_target_evt.observers == [] assert self.conversation.delivery_failed_evt.observers == [] class TestConferenceController(object): @mockified('pypsyc.client.controller', ['ListBinding']) def setup(self, ListBinding): self.ListBinding = ListBinding self.tabs_controller = Mock() self.conference = Mock() self.conference.members = [] self.conference.messages = ObsList() self.conference.unknown_target_evt = Event() self.conference.delivery_failed_evt = Event() self.view = Mock() self.controller = ConferenceController(self.tabs_controller, self.conference, self.view) def test_binding(self): makerow_ph = PlaceHolder() assert self.ListBinding.call_args_list == [ ((self.conference.members, self.view.members, makerow_ph),)] member = Mock() row = makerow_ph.obj(member) assert row == (member.uni, member.nick) def test_open_conversation(self): member = Mock() self.conference.members.append(member) account = self.conference.conferencing.account conversation = account.get_conversation.return_value self.controller.open_conversation(0) assert self.conference.conferencing.account.method_calls == [ ('get_conversation', (member.uni,))] assert self.tabs_controller.method_calls == [ ('focus_conversation', (conversation,))] def test_closed(self): self.controller.closed() assert self.ListBinding.return_value.method_calls == [('unbind',)] assert _check_obs_list(self.conference.messages) assert self.conference.unknown_target_evt.observers == [] assert self.conference.delivery_failed_evt.observers == [] class TestTabsController(object): def setup(self): self.client = Mock() self.client.accounts = ObsList() self.view = Mock() self.account = Mock() self.account.conversations = ObsDict() self.account.conferences = ObsDict() self.client.accounts.append(self.account) @mockified('pypsyc.client.controller', ['ConversationController', 'ConferenceController']) def test_deleted_account(self, ConversationController, ConferenceController): self.account.conversations[USER2_UNI] = Mock() self.account.conferences[PLACE_UNI] = Mock() conv_view = self.view.show_conversation.return_value conv_controller = ConversationController.return_value conf_view = self.view.show_conference.return_value conf_controller = ConferenceController.return_value TabsController(self.client, self.view) self.view.reset_mock() del self.client.accounts[0] assert _check_obs_dict(self.account.conversations) assert _check_obs_dict(self.account.conferences) assert self.view.method_calls == [('remove_tab', (conv_view,)), ('remove_tab', (conf_view,))] assert conv_controller.method_calls == [('closed',)] assert conf_controller.method_calls == [('closed',)] @mockified('pypsyc.client.controller', ['ConversationController']) def test_conversation(self, ConversationController): conversation = Mock() conversation.uni = USER2_UNI conv_view = self.view.show_conversation.return_value conv_controller = ConversationController.return_value controller = TabsController(self.client, self.view) self.account.conversations[USER2_UNI] = conversation assert self.view.method_calls == [('show_conversation', (USER2_UNI,))] assert ConversationController.call_args_list == [ ((controller, conversation, conv_view),)] self.view.reset_mock() controller.focus_conversation(conversation) assert self.view.method_calls == [('focus_tab', (conv_view,))] self.view.reset_mock() controller.close_tab(conv_view) assert self.account.conversations == {} assert self.view.method_calls == [('remove_tab', (conv_view,))] assert conv_controller.method_calls == [('closed',)] @mockified('pypsyc.client.controller', ['ConferenceController']) def test_conference(self, ConferenceController): conference = Mock() conference.uni = PLACE_UNI conf_view = self.view.show_conference.return_value conf_controller = ConferenceController.return_value self.account.conferences[PLACE_UNI] = conference controller = TabsController(self.client, self.view) assert self.view.method_calls == [ ('show_conference', (PLACE_UNI,),)] assert ConferenceController.call_args_list == [ ((controller, conference, conf_view),)] self.view.reset_mock() controller.focus_conversation(conference) assert self.view.method_calls == [('focus_tab', (conf_view,))] self.view.reset_mock() controller.close_tab(conf_view) assert self.account.conferences == {} assert self.view.method_calls == [('remove_tab', (conf_view,))] assert conf_controller.method_calls == [('closed',)] class TestFriendListController(object): @mockified('pypsyc.client.controller', ['ListBinding']) def setup(self, ListBinding): self.ListBinding = ListBinding model_list_ph = PlaceHolder() make_row_ph = PlaceHolder() self.client = Mock() self.client.accounts = ObsList() self.view = Mock() self.tabs_controller = Mock() self.controller = FriendListController(self.client, self.view, self.tabs_controller) assert self.ListBinding.call_args_list == [ ((model_list_ph, self.view.friends, make_row_ph),)] self.model_list = model_list_ph.obj self.make_row = make_row_ph.obj def test_binding(self): EXTERN_FRIEND_UNI = SERVER2_UNI.chain('~friend') friend = Mock() friend.account.server = SERVER1 friend.uni = USER1_UNI friend.presence = PRESENCE_OFFLINE row = self.make_row(friend) assert row == (USER1_NICK, False, friend.state) friend.uni = EXTERN_FRIEND_UNI friend.presence = PRESENCE_ONLINE row = self.make_row(friend) assert row == (EXTERN_FRIEND_UNI, True, friend.state) def test_account(self): update_evt = Mock() friend1 = Mock() friend2 = Mock() account = Mock() account.friends = ObsDict({USER1_UNI: friend1}) self.model_list.update_evt += update_evt assert self.model_list == [] self.client.accounts.append(account) assert self.model_list == [friend1] account.friends[USER2_UNI] = friend2 assert self.model_list == [friend1, friend2] account.friends.updated_item(USER2_UNI) assert update_evt.call_args_list == [((1, friend2),)] del account.friends[USER1_UNI] assert self.model_list == [friend2] del self.client.accounts[0] assert _check_obs_dict(account.friends) assert self.model_list == [] def test_open_conversation(self): friend = Mock() friend.uni = USER2_UNI self.model_list.append(friend) conversation = friend.account.get_conversation.return_value self.controller.open_conversation(0) assert friend.account.method_calls == [ ('get_conversation', (USER2_UNI,))] assert self.tabs_controller.method_calls == [ ('focus_conversation', (conversation,))] def test_accept_friendship(self): friend = Mock() friend.uni = USER2_UNI friend.account.add_friend.side_effect = AsyncMethod() self.model_list.append(friend) self.controller.accept_friendship(0) assert friend.account.method_calls == [('add_friend', (USER2_UNI,))] def test_cancel_friendship(self): friend = Mock() friend.uni = USER2_UNI friend.account.remove_friend.side_effect = AsyncMethod() self.model_list.append(friend) self.controller.cancel_friendship(0) assert friend.account.method_calls == [('remove_friend', (USER2_UNI,))] class TestMainController(object): @mockified('pypsyc.client.controller', ['TabsController', 'FriendListController']) def setup(self, TabsController, FriendListController): self.client = Mock() self.client.accounts = ObsList() self.view = Mock() self.controller = MainController(self.client, self.view) self.TabsController = TabsController self.FriendListController = FriendListController def test_main_controller(self): tabs_controller = self.TabsController.return_value assert self.TabsController.call_args_list == [ ((self.client, self.view.tabs_view),)] assert self.FriendListController.call_args_list == [ ((self.client, self.view.friends_view, tabs_controller),)] def test_no_password(self): account = self._make_account() self.client.accounts.append(account) callback_ph = PlaceHolder() update_evt = Mock() self.client.accounts.update_evt += update_evt account.no_password_evt() assert self.view.method_calls == [ ('show_password_dialog', (account.uni, account.__dict__, callback_ph))] callback_ph.obj() assert account.active == True assert update_evt.call_args_list == [((0, account),)] assert self.client.method_calls == [('save_accounts',)] del self.client.accounts[0] assert account.no_password_evt.observers == [] def test_connection_error(self): account = self._make_account() self.client.accounts.append(account) account.connection_error_evt(EXCEPTION) assert self.view.method_calls == [ ('show_conn_error', (account.uni, ERROR))] del self.client.accounts[0] assert account.connection_error_evt.observers == [] def test_no_such_user(self): account = self._make_account() self.client.accounts.append(account) account.no_such_user_evt(EXCEPTION) assert self.view.method_calls == [('show_no_such_user', (ERROR,))] del self.client.accounts[0] assert account.no_such_user_evt.observers == [] def test_auth_error(self): account = self._make_account() self.client.accounts.append(account) account.auth_error_evt(EXCEPTION) assert self.view.method_calls == [ ('show_auth_error', (account.uni, ERROR))] del self.client.accounts[0] assert account.auth_error_evt.observers == [] def _make_account(self, active=False): account = Mock() account.active = active account.no_password_evt = Event() account.connection_error_evt = Event() account.no_such_user_evt = Event() account.auth_error_evt = Event() return account @mockified('pypsyc.client.controller', ['AccountsController']) def test_open_accounts(self, AccountsController): self.controller.open_accounts() assert AccountsController.call_args_list == [ ((self.client, self.view.show_accounts.return_value),)] @mockified('pypsyc.client.controller', ['DumpController']) def test_open_dump(self, DumpController): self.controller.open_dump() assert DumpController.call_args_list == [ ((self.client, self.view.show_dump_win.return_value),)] def test_open_conversation(self): account1 = Mock() account1.active = False account2 = Mock() account2.active = True self.client.accounts = [account1, account2] callback_ph = PlaceHolder() conversation = account2.get_conversation.return_value self.controller.open_conversation() assert self.view.method_calls == [ ('show_open_conv_dialog', (iter_(account2.uni), callback_ph))] callback_ph.obj(0, SERVER1, USER2_NICK) assert account2.method_calls == [('get_conversation', (USER2_UNI,))] assert self.TabsController.return_value.method_calls == [ ('focus_conversation', (conversation,))] def test_open_conference(self): account1 = Mock() account1.active = False account2 = Mock() account2.active = True self.client.accounts = [account1, account2] callback_ph = PlaceHolder() conference = account2.get_conference.return_value self.controller.open_conference() assert self.view.method_calls == [ ('show_open_conf_dialog', (iter_(account2.uni), callback_ph))] callback_ph.obj(0, SERVER1, 'place') assert account2.method_calls == [ ('get_conference', (PLACE_UNI,), {'subscribe': True})] assert self.TabsController.return_value.method_calls == [ ('focus_conversation', (conference,))] def test_add_friend(self): account1 = Mock() account1.active = False account2 = Mock() account2.active = True account2.add_friend.side_effect = AsyncMethod() callback_ph = PlaceHolder() self.client.accounts = [account1, account2] self.controller.add_friend() assert self.view.method_calls == [ ('show_add_friend_dialog', (iter_(account2.uni), callback_ph))] callback_ph.obj(0, SERVER1, USER2_NICK) assert account2.method_calls == [('add_friend', (USER2_UNI,))] def test_show_active_accounts(self): account1 = self._make_account(active=True) account2 = self._make_account(active=True) self.client.accounts.append(account1) assert self.view.method_calls == [('show_active_accounts', (True,))] self.view.reset_mock() self.client.accounts.append(account2) assert self.view.method_calls == [] self.client.accounts.remove(account1) assert self.view.method_calls == [] self.client.accounts.remove(account2) assert self.view.method_calls == [('show_active_accounts', (False,))] def test_show_active_accounts_updated(self): account = self._make_account(active=False) self.client.accounts.append(account) assert self.view.method_calls == [] account.active = True self.client.accounts.updated_item(account) assert self.view.method_calls == [('show_active_accounts', (True,))] self.view.reset_mock() self.client.accounts.updated_item(account) assert self.view.method_calls == [] account.active = False self.client.accounts.updated_item(account) assert self.view.method_calls == [('show_active_accounts', (False,))] self.view.reset_mock() self.client.accounts.updated_item(account) assert self.view.method_calls == [] del self.client.accounts[0] assert self.view.method_calls == [] def test_quit(self): self.controller.quit() assert _check_obs_list(self.client.accounts) assert self.client.method_calls == [('quit',)]