test: make FakeClient profile dependent and add some tools to test MUC
This commit is contained in:
parent
cd45ede2d2
commit
ddcfdd99ac
4 changed files with 335 additions and 9 deletions
|
|
@ -23,10 +23,14 @@ from twisted.words.protocols.jabber import jid
|
|||
|
||||
class Const(object):
|
||||
|
||||
PROFILE = ['test_profile', 'test_profile2', 'test_profile3', 'test_profile4']
|
||||
JID_STR = [u"test@example.org/SàT", u"sender@example.net/house", u"sender@example.net/work", u"test@server.net/res"]
|
||||
PROFILE = ['test_profile', 'test_profile2', 'test_profile3', 'test_profile4', 'test_profile5']
|
||||
JID_STR = [u"test@example.org/SàT", u"sender@example.net/house", u"sender@example.net/work", u"sender@server.net/res", u"xxx@server.net/res"]
|
||||
JID = [jid.JID(jid_s) for jid_s in JID_STR]
|
||||
|
||||
PROFILE_DICT = {}
|
||||
for i in xrange(0, len(PROFILE)):
|
||||
PROFILE_DICT[PROFILE[i]] = JID[i]
|
||||
|
||||
MUC_STR = [u"room@chat.server.domain", u"sat_game@chat.server.domain"]
|
||||
MUC = [jid.JID(jid_s) for jid_s in MUC_STR]
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,12 @@ class FakeSAT(object):
|
|||
self.init()
|
||||
|
||||
def init(self):
|
||||
"""This can be called by tests that check for sent and stored messages"""
|
||||
"""This can be called by tests that check for sent and stored messages,
|
||||
uses FakeClient or get/set some other data that need to be cleaned"""
|
||||
self.sent_messages = []
|
||||
self.stored_messages = []
|
||||
self.plugins = {}
|
||||
self.profiles = {}
|
||||
|
||||
def delContact(self, to, profile_key):
|
||||
#TODO
|
||||
|
|
@ -81,6 +84,8 @@ class FakeSAT(object):
|
|||
self.sendAndStoreMessage({"to": JID(to_s)})
|
||||
|
||||
def sendAndStoreMessage(self, mess_data, skip_send=False, profile=None):
|
||||
"""Save the information to check later to whom messages have been sent and
|
||||
if entries have been added to the history"""
|
||||
if not skip_send:
|
||||
self.sent_messages.append(mess_data["to"])
|
||||
self.stored_messages.append(mess_data["to"])
|
||||
|
|
@ -104,12 +109,50 @@ class FakeSAT(object):
|
|||
return defer.succeed(jid_ if self.memory.hasServerFeature(feature, jid_, profile_key) else None)
|
||||
|
||||
def getClientHostJid(self, profile_key):
|
||||
return JID(Const.JID[0].host)
|
||||
return Const.PROFILE_DICT[profile_key].host
|
||||
|
||||
def getClient(self, profile_key):
|
||||
"""Convenient method to get client from profile key
|
||||
@return: client or None if it doesn't exist"""
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
return None
|
||||
if profile not in self.profiles:
|
||||
self.profiles[profile] = FakeClient(self, profile)
|
||||
self.profiles[profile].client_initialized.callback(None)
|
||||
return self.profiles[profile]
|
||||
|
||||
def getJidNStream(self, profile_key):
|
||||
"""Convenient method to get jid and stream from profile key
|
||||
@return: tuple (jid, xmlstream) from profile, can be None"""
|
||||
return (Const.PROFILE_DICT[profile_key], None)
|
||||
|
||||
def isConnected(self, profile):
|
||||
return True
|
||||
|
||||
def getSentMessage(self, message_index, profile_index):
|
||||
"""Called by tests. FakeClient instances associated to each profile must have
|
||||
been previously initialized with the method FakeSAT.getClient.
|
||||
@return: XML representation of the <message_index>th sent message for given profile"""
|
||||
return self.profiles[Const.PROFILE[profile_index]].xmlstream.sent[message_index]
|
||||
|
||||
def countSentMessages(self, profiles=Const.PROFILE):
|
||||
"""Called by tests. FakeClient instances associated to each profile must have
|
||||
been previously initialized with the method FakeSAT.getClient.
|
||||
@param profiles: list of profiles
|
||||
@return: a list containing the number of sent messages for each of the specified profiles"""
|
||||
result = []
|
||||
for profile in profiles:
|
||||
result.append(len(self.profiles[profile].xmlstream.sent))
|
||||
return result
|
||||
|
||||
|
||||
class FakeBridge(object):
|
||||
"""Class to simulate and test bridge calls"""
|
||||
|
||||
def __init__(self):
|
||||
self.methods = {}
|
||||
|
||||
def expectCall(self, name, *check_args, **check_kwargs):
|
||||
def checkCall(*args, **kwargs):
|
||||
if args != check_args or kwargs != check_kwargs:
|
||||
|
|
@ -128,6 +171,13 @@ class FakeBridge(object):
|
|||
def addSignal(self, name, int_suffix, signature):
|
||||
pass
|
||||
|
||||
def addTestCallback(self, name, method):
|
||||
"""This can be used to register callbacks for bridge methods AND signals.
|
||||
Contrary to expectCall, this will not check if the method or signal is
|
||||
called/sent with the correct arguments, it will instead run the callback
|
||||
of your choice."""
|
||||
setattr(self, name, method)
|
||||
|
||||
|
||||
class FakeParams(Params):
|
||||
"""Class to simulate and test params object. The methods of Params that could
|
||||
|
|
@ -168,6 +218,7 @@ class FakeMemory(Memory):
|
|||
# manipulating basic stuff, the others should be overwritten when needed
|
||||
self.host = host
|
||||
self.params = FakeParams(host, None)
|
||||
self.config = self.parseMainConf()
|
||||
self.init()
|
||||
|
||||
def init(self):
|
||||
|
|
@ -218,11 +269,12 @@ class FakeTriggerManager(object):
|
|||
|
||||
|
||||
class FakeRosterProtocol(SatRosterProtocol):
|
||||
"""This class is used by FakeClient (one instance per profile)"""
|
||||
|
||||
def __init__(self, host, parent):
|
||||
SatRosterProtocol.__init__(self, host)
|
||||
self.parent = parent
|
||||
self.addItem(Const.JID[0])
|
||||
self.addItem(parent.jid)
|
||||
|
||||
def addItem(self, jid, *args, **kwargs):
|
||||
if not args and not kwargs:
|
||||
|
|
@ -237,15 +289,30 @@ class FakeRosterProtocol(SatRosterProtocol):
|
|||
self.onRosterSet(roster_item)
|
||||
|
||||
|
||||
class FakeClient(object):
|
||||
def __init__(self, host):
|
||||
self.host = host
|
||||
self.profile = 'test_profile'
|
||||
self.jid = Const.JID[0]
|
||||
self.roster = FakeRosterProtocol(host, self)
|
||||
class FakeXmlStream(object):
|
||||
"""This class is used by FakeClient (one instance per profile)"""
|
||||
|
||||
def __init__(self):
|
||||
self.sent = []
|
||||
|
||||
def send(self, obj):
|
||||
pass
|
||||
"""Save the sent messages to compare them later"""
|
||||
self.sent.append(obj.toXml())
|
||||
|
||||
|
||||
class FakeClient(object):
|
||||
"""Tests involving more than one profile need one instance of this class per profile"""
|
||||
|
||||
def __init__(self, host, profile=None):
|
||||
self.host = host
|
||||
self.profile = profile if profile else Const.PROFILE[0]
|
||||
self.jid = Const.PROFILE_DICT[self.profile]
|
||||
self.roster = FakeRosterProtocol(host, self)
|
||||
self.client_initialized = defer.Deferred()
|
||||
self.xmlstream = FakeXmlStream()
|
||||
|
||||
def send(self, obj):
|
||||
self.xmlstream.send(obj)
|
||||
|
||||
|
||||
class SatTestCase(unittest.TestCase):
|
||||
|
|
|
|||
138
src/test/helpers_plugins.py
Normal file
138
src/test/helpers_plugins.py
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SAT: a jabber client
|
||||
# Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org)
|
||||
# Copyright (C) 2013 Adrien Cossa (souliane@mailoo.org)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" Helpers class for plugin dependencies """
|
||||
|
||||
from constants import Const
|
||||
from sat.plugins.plugin_xep_0045 import XEP_0045
|
||||
from twisted.internet import defer
|
||||
from wokkel.muc import Room, User
|
||||
|
||||
|
||||
class FakeMUCClient(object):
|
||||
def __init__(self, plugin_parent):
|
||||
self.plugin_parent = plugin_parent
|
||||
self.host = plugin_parent.host
|
||||
self.joined_rooms = {}
|
||||
|
||||
def join(self, roomJID, nick, profile):
|
||||
roster = {}
|
||||
|
||||
# ask the other profiles to fill our roster
|
||||
for i in xrange(0, len(Const.PROFILE)):
|
||||
other_profile = Const.PROFILE[i]
|
||||
if other_profile == profile:
|
||||
continue
|
||||
try:
|
||||
other_room = self.plugin_parent.clients[other_profile].joined_rooms[roomJID.userhost()]
|
||||
roster.setdefault(other_room.nick, User(other_room.nick, Const.PROFILE_DICT[other_profile]))
|
||||
for other_nick in other_room.roster:
|
||||
roster.setdefault(other_nick, other_room.roster[other_nick])
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
|
||||
# rename our nick if it already exists
|
||||
while nick in roster.keys():
|
||||
if Const.PROFILE_DICT[profile].userhost() == roster[nick].entity.userhost():
|
||||
break # same user with different resource --> same nickname
|
||||
nick = nick + "_"
|
||||
|
||||
room = Room(roomJID, nick)
|
||||
room.roster = roster
|
||||
self.joined_rooms[roomJID.userhost()] = room
|
||||
|
||||
# fill the other rosters with the new entry
|
||||
for i in xrange(0, len(Const.PROFILE)):
|
||||
other_profile = Const.PROFILE[i]
|
||||
if other_profile == profile:
|
||||
continue
|
||||
try:
|
||||
other_room = self.plugin_parent.clients[other_profile].joined_rooms[roomJID.userhost()]
|
||||
other_room.roster.setdefault(room.nick, User(room.nick, Const.PROFILE_DICT[profile]))
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
|
||||
return room
|
||||
|
||||
|
||||
class FakeXEP_0045(XEP_0045):
|
||||
|
||||
def __init__(self, host):
|
||||
self.host = host
|
||||
self.clients = {}
|
||||
for profile in Const.PROFILE:
|
||||
self.clients[profile] = FakeMUCClient(self)
|
||||
|
||||
def join(self, room_jid, nick, options={}, profile_key='@DEFAULT@'):
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
room_jid_s = room_jid.userhost()
|
||||
if room_jid_s in self.clients[profile].joined_rooms:
|
||||
return defer.succeed(None)
|
||||
room = self.clients[profile].join(room_jid, nick, profile)
|
||||
return defer.succeed(room)
|
||||
|
||||
def joinRoom(self, muc_index, user_index):
|
||||
"""Called by tests
|
||||
@return: the nickname of the user in the joined room"""
|
||||
muc = Const.MUC[muc_index]
|
||||
nick = Const.JID[user_index].user
|
||||
profile = Const.PROFILE[user_index]
|
||||
self.join(muc, nick, profile_key=profile)
|
||||
return self.getNick(muc_index, user_index)
|
||||
|
||||
def getRoom(self, muc_index, user_index):
|
||||
"""Called by tests
|
||||
@return: a wokkel.muc.Room instance"""
|
||||
profile = Const.PROFILE[user_index]
|
||||
muc_s = Const.MUC_STR[muc_index]
|
||||
try:
|
||||
return self.clients[profile].joined_rooms[muc_s]
|
||||
except (AttributeError, KeyError):
|
||||
return None
|
||||
|
||||
def getNick(self, muc_index, user_index):
|
||||
try:
|
||||
return self.getRoomNick(Const.MUC_STR[muc_index], Const.PROFILE[user_index])
|
||||
except (KeyError, AttributeError):
|
||||
return ''
|
||||
|
||||
def getNickOfUser(self, muc_index, user_index, profile_index, secure=True):
|
||||
try:
|
||||
room = self.clients[Const.PROFILE[profile_index]].joined_rooms[Const.MUC_STR[muc_index]]
|
||||
return self.getRoomNickOfUser(room, Const.JID_STR[user_index])
|
||||
except (KeyError, AttributeError):
|
||||
return None
|
||||
|
||||
|
||||
class FakeXEP_0249(object):
|
||||
|
||||
def __init__(self, host):
|
||||
self.host = host
|
||||
|
||||
def invite(self, target, room, options={}, profile_key='@DEFAULT@'):
|
||||
"""
|
||||
Invite a user to a room. To accept the invitation from a test,
|
||||
just call FakeXEP_0045.joinRoom (no need to have a dedicated method).
|
||||
@param target: jid of the user to invite
|
||||
@param room: jid of the room where the user is invited
|
||||
@options: attribute with extra info (reason, password) as in #XEP-0249
|
||||
@profile_key: %(doc_profile_key)s
|
||||
"""
|
||||
pass
|
||||
117
src/test/test_helpers_plugins.py
Normal file
117
src/test/test_helpers_plugins.py
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SAT: a jabber client
|
||||
# Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org)
|
||||
# Copyright (C) 2013 Adrien Cossa (souliane@mailoo.org)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" Test the helper classes to see if they behave well"""
|
||||
|
||||
import helpers
|
||||
import helpers_plugins
|
||||
|
||||
|
||||
class FakeXEP_0045Test(helpers.SatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.host = helpers.FakeSAT()
|
||||
self.plugin = helpers_plugins.FakeXEP_0045(self.host)
|
||||
|
||||
def test_joinRoom(self):
|
||||
self.plugin.joinRoom(0, 0)
|
||||
self.assertEqual('test', self.plugin.getNick(0, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 0))
|
||||
self.assertEqual('', self.plugin.getNick(0, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 1))
|
||||
self.assertEqual('', self.plugin.getNick(0, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 2))
|
||||
self.assertEqual('', self.plugin.getNick(0, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 3))
|
||||
self.plugin.joinRoom(0, 1)
|
||||
self.assertEqual('test', self.plugin.getNick(0, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 0))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 0))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 0))
|
||||
self.assertEqual('sender', self.plugin.getNick(0, 1))
|
||||
self.assertEqual('test', self.plugin.getNickOfUser(0, 0, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 1))
|
||||
self.assertEqual('', self.plugin.getNick(0, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 2))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 2))
|
||||
self.assertEqual('', self.plugin.getNick(0, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 3))
|
||||
self.plugin.joinRoom(0, 2)
|
||||
self.assertEqual('test', self.plugin.getNick(0, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 0))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 0))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 0))
|
||||
self.assertEqual('sender', self.plugin.getNick(0, 1))
|
||||
self.assertEqual('test', self.plugin.getNickOfUser(0, 0, 1))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 1)) # Const.JID[2] is in the roster for Const.PROFILE[1]
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 1))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 1))
|
||||
self.assertEqual('sender', self.plugin.getNick(0, 2))
|
||||
self.assertEqual('test', self.plugin.getNickOfUser(0, 0, 2))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 2))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 2)) # Const.JID[1] is in the roster for Const.PROFILE[2]
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 2))
|
||||
self.assertEqual('', self.plugin.getNick(0, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 1, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 2, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 3))
|
||||
self.plugin.joinRoom(0, 3)
|
||||
self.assertEqual('test', self.plugin.getNick(0, 0))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 0, 0))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 0))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 0))
|
||||
self.assertEqual('sender_', self.plugin.getNickOfUser(0, 3, 0))
|
||||
self.assertEqual('sender', self.plugin.getNick(0, 1))
|
||||
self.assertEqual('test', self.plugin.getNickOfUser(0, 0, 1))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 1)) # Const.JID[2] is in the roster for Const.PROFILE[1]
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 1))
|
||||
self.assertEqual('sender_', self.plugin.getNickOfUser(0, 3, 1))
|
||||
self.assertEqual('sender', self.plugin.getNick(0, 2))
|
||||
self.assertEqual('test', self.plugin.getNickOfUser(0, 0, 2))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 2))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 2)) # Const.JID[1] is in the roster for Const.PROFILE[2]
|
||||
self.assertEqual('sender_', self.plugin.getNickOfUser(0, 3, 2))
|
||||
self.assertEqual('sender_', self.plugin.getNick(0, 3))
|
||||
self.assertEqual('test', self.plugin.getNickOfUser(0, 0, 3))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 1, 3))
|
||||
self.assertEqual('sender', self.plugin.getNickOfUser(0, 2, 3))
|
||||
self.assertEqual(None, self.plugin.getNickOfUser(0, 3, 3))
|
||||
Loading…
Reference in a new issue