pypsyc/mjacob2/tests/test_client/test_controller.py

681 lines
24 KiB
Python

"""
: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',)]