Split all the e2e tests in their own files

Some duplication is avoided, but most importantly: it’s much much cleaner,
easier to find, functions have been cleaned up (functools.partial usages are
now hidden), etc.
This commit is contained in:
louiz’
2019-10-31 02:27:42 +01:00
parent cec396f6eb
commit bd41bc8b02
87 changed files with 2693 additions and 3096 deletions
File diff suppressed because it is too large Load Diff
+166
View File
@@ -0,0 +1,166 @@
from functools import partial
import collections
import datetime
import asyncio
import time
import lxml
import io
common_replacements = {
'irc_server_one': 'irc.localhost@biboumi.localhost',
'irc_server_two': 'localhost@biboumi.localhost',
'irc_host_one': 'irc.localhost',
'irc_host_two': 'localhost',
'biboumi_host': 'biboumi.localhost',
'resource_one': 'resource1',
'resource_two': 'resource2',
'nick_one': 'Nick',
'jid_one': 'first@example.com',
'jid_two': 'second@example.com',
'jid_admin': 'admin@example.com',
'nick_two': 'Bobby',
'nick_three': 'Bernard',
'lower_nick_one': 'nick',
'lower_nick_two': 'bobby',
}
class SkipStepError(Exception):
"""
Raised by a step when it needs to be skiped, by running
the next available step immediately.
"""
pass
class StanzaError(Exception):
"""
Raised when a step fails.
"""
pass
def match(stanza, xpath):
tree = lxml.etree.parse(io.StringIO(str(stanza)))
matched = tree.xpath(xpath, namespaces={'re': 'http://exslt.org/regular-expressions',
'muc_user': 'http://jabber.org/protocol/muc#user',
'muc_owner': 'http://jabber.org/protocol/muc#owner',
'muc': 'http://jabber.org/protocol/muc',
'disco_info': 'http://jabber.org/protocol/disco#info',
'muc_traffic': 'http://jabber.org/protocol/muc#traffic',
'disco_items': 'http://jabber.org/protocol/disco#items',
'commands': 'http://jabber.org/protocol/commands',
'dataform': 'jabber:x:data',
'version': 'jabber:iq:version',
'mam': 'urn:xmpp:mam:2',
'rms': 'http://jabber.org/protocol/rsm',
'delay': 'urn:xmpp:delay',
'forward': 'urn:xmpp:forward:0',
'client': 'jabber:client',
'rsm': 'http://jabber.org/protocol/rsm',
'carbon': 'urn:xmpp:carbons:2',
'hints': 'urn:xmpp:hints',
'stanza': 'urn:ietf:params:xml:ns:xmpp-stanzas',
'stable_id': 'urn:xmpp:sid:0'})
return matched
def check_xpath(xpaths, xmpp, after, stanza):
for xpath in xpaths:
expected = True
real_xpath = xpath
# We can check that a stanza DOESN’T match, by adding a ! before it.
if xpath.startswith('!'):
expected = False
xpath = xpath[1:]
matched = match(stanza, xpath)
if (expected and not matched) or (not expected and matched):
raise StanzaError("Received stanza\n%s\ndid not match expected xpath\n%s" % (stanza, real_xpath))
if after:
if isinstance(after, collections.Iterable):
for af in after:
af(stanza, xmpp)
else:
after(stanza, xmpp)
def check_xpath_optional(xpaths, xmpp, after, stanza):
try:
check_xpath(xpaths, xmpp, after, stanza)
except StanzaError:
raise SkipStepError()
def all_xpaths_match(stanza, xpaths):
try:
check_xpath(xpaths, None, None, stanza)
except StanzaError:
return False
return True
def check_list_of_xpath(list_of_xpaths, xmpp, stanza):
found = False
for i, xpaths in enumerate(list_of_xpaths):
if all_xpaths_match(stanza, xpaths):
found = True
list_of_xpaths.pop(i)
break
if not found:
raise StanzaError("Received stanza “%s” did not match any of the expected xpaths:\n%s" % (stanza, list_of_xpaths))
if list_of_xpaths:
step = partial(expect_unordered_already_formatted, list_of_xpaths)
xmpp.scenario.steps.insert(0, step)
def extract_attribute(xpath, name):
def f(xpath, name, stanza):
matched = match(stanza, xpath)
return matched[0].get(name)
return partial(f, xpath, name)
def extract_text(xpath, stanza):
matched = match(stanza, xpath)
return matched[0].text
def save_value(name, func):
def f(name, func, stanza, xmpp):
xmpp.saved_values[name] = func(stanza)
return partial(f, name, func)
def expect_stanza(*args, optional=False, after=None):
def f(*xpaths, xmpp, biboumi, optional, after):
replacements = common_replacements
replacements.update(xmpp.saved_values)
check_func = check_xpath if not optional else check_xpath_optional
xmpp.stanza_checker = partial(check_func, [xpath.format_map(replacements) for xpath in xpaths], xmpp, after)
return partial(f, *args, optional=optional, after=after)
def send_stanza(stanza):
def internal(stanza, xmpp, biboumi):
replacements = common_replacements
replacements.update(xmpp.saved_values)
xmpp.send_raw(stanza.format_map(replacements))
asyncio.get_event_loop().call_soon(xmpp.run_scenario)
return partial(internal, stanza)
def expect_unordered(*args):
def f(*lists_of_xpaths, xmpp, biboumi):
formatted_list_of_xpaths = []
for list_of_xpaths in lists_of_xpaths:
formatted_xpaths = []
for xpath in list_of_xpaths:
formatted_xpath = xpath.format_map(common_replacements)
formatted_xpaths.append(formatted_xpath)
formatted_list_of_xpaths.append(tuple(formatted_xpaths))
expect_unordered_already_formatted(formatted_list_of_xpaths, xmpp, biboumi)
return partial(f, *args)
def expect_unordered_already_formatted(formatted_list_of_xpaths, xmpp, biboumi):
xmpp.stanza_checker = partial(check_list_of_xpath, formatted_list_of_xpaths, xmpp)
def sleep_for(duration):
def f(duration, xmpp, biboumi):
time.sleep(duration)
asyncio.get_event_loop().call_soon(xmpp.run_scenario)
return partial(f, duration)
def save_current_timestamp_plus_delta(key, delta):
def f(key, delta, message, xmpp):
now_plus_delta = datetime.datetime.utcnow() + delta
xmpp.saved_values[key] = now_plus_delta.strftime("%FT%T.967Z")
return partial(f, key, delta)
+10
View File
@@ -0,0 +1,10 @@
# Do "from scenarios import *" instead of repeating these imports everytime in every scenario
from functions import expect_stanza, send_stanza, expect_unordered, save_value, extract_attribute, extract_text, sleep_for, save_current_timestamp_plus_delta
import datetime
import sequences
import scenarios.simple_channel_join
import scenarios.channel_join_with_two_users
import scenarios.simple_channel_join_fixed
import scenarios.channel_join_on_fixed_irc_server
import scenarios.multiple_channels_join
@@ -0,0 +1,5 @@
from scenarios import *
scenario = (
sequences.handshake(),
)
@@ -0,0 +1,23 @@
from scenarios import *
scenario = (
sequences.handshake(),
# Mutual subscription exchange
send_stanza("<presence from='{jid_one}' to='{biboumi_host}' type='subscribe' id='subid1' />"),
expect_stanza("/presence[@type='subscribed'][@id='subid1']"),
# Get the current presence of the biboumi gateway
expect_stanza("/presence"),
expect_stanza("/presence[@type='subscribe']"),
send_stanza("<presence from='{jid_one}' to='{biboumi_host}' type='subscribed' />"),
# Unsubscribe
send_stanza("<presence from='{jid_one}' to='{biboumi_host}' type='unsubscribe' id='unsubid1' />"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unsubscribed']"),
expect_stanza("/presence[@type='unsubscribe']"),
send_stanza("<presence from='{jid_one}' to='{biboumi_host}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}' to='{biboumi_host}' type='unsubscribed' />"),
)
@@ -0,0 +1,30 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
# First user sets the topic
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><subject>TOPIC TEST</subject></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat'][@to='{jid_one}/{resource_one}']/subject[text()='TOPIC TEST']"),
# Second user joins
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_unordered(
[
"/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']"
],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"
],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/subject[text()='TOPIC TEST']"
]
)
)
@@ -0,0 +1,45 @@
from scenarios import *
import scenarios.channel_join_with_two_users
scenario = (
scenarios.channel_join_with_two_users.scenario,
# Here we simulate a desynchronization of a client: The client thinks it’s
# disconnected from the room, but biboumi still thinks it’s in the room. The
# client thus sends a join presence, and biboumi should send everything
# (user list, history, etc) in response.
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_three}'><x xmlns='http://jabber.org/protocol/muc'/></presence>"),
expect_unordered(
[
"/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost']"
],
[
"/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"
]
),
# And also, that was not the same nickname, so everyone receives a nick change
expect_unordered(
[
"/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
"/presence/muc_user:x/muc_user:status[@code='303']",
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_two}/{resource_one}']",
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
"/presence/muc_user:x/muc_user:status[@code='303']",
"/presence/muc_user:x/muc_user:status[@code='110']",
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_one}/{resource_one}']",
"/presence/muc_user:x/muc_user:status[@code='110']",
],
),
)
@@ -0,0 +1,18 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send one channel message
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"),
# Second user joins
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='{lower_nick_one}%{irc_server_one}/~{nick_one}@localhost'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
# Receive the history message
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}']/body[text()='coucou']",
"/message/delay:delay[@from='#foo%{irc_server_one}']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,20 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
scenarios.channel_join_on_fixed_irc_server.scenario,
# Send one channel message
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@from='#foo@{biboumi_host}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"),
# Second user joins
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo@{biboumi_host}/{nick_one}' />"),
expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='{lower_nick_one}@{biboumi_host}/~{nick_one}@localhost'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
# Receive the history message
expect_stanza("/message[@from='#foo@{biboumi_host}/{nick_one}']/body[text()='coucou']",
"/message/delay:delay[@from='#foo@{biboumi_host}']"),
expect_stanza("/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,13 @@
from scenarios import *
conf = "fixed_server"
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}', fixed_irc_server=True),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,15 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#foo", nick = "{nick_one}"),
# The same resource joins a different channel with a different nick
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bar%{irc_server_one}/{nick_two}' />"),
# We must receive a join presence in response, without any nick change (nick_two) must be ignored
expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#bar", nick = "{nick_one}"),
)
@@ -0,0 +1,35 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
# Set a password in the room, by using /mode +k
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>/mode +k SECRET</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='Mode #foo [+k SECRET] by {nick_one}']"),
# Second user tries to join, without a password (error ensues)
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}'/>"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_stanza("/message/body[text()='{irc_host_one}: #foo: Cannot join channel (+k) - bad key']"),
expect_stanza("/presence[@type='error'][@from='#foo%{irc_server_one}/{nick_two}']/error[@type='auth']/stanza:not-authorized"),
# Second user joins, with the correct password (success)
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}'> <x xmlns='http://jabber.org/protocol/muc'><password>SECRET</password></x></presence>"),
expect_unordered(
[
"/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost']"
],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"
],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"
]
)
)
@@ -0,0 +1,25 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Second user joins
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_unordered(
[
"/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost']"
],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"
],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"
]
)
)
@@ -0,0 +1,12 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#true\\2ffalse%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #true/false [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#true\\2ffalse%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#true\\2ffalse%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,67 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bar%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message/body[text()='Mode #bar [+nt] by {irc_host_one}']"),
expect_stanza("/presence"),
expect_stanza("/message[@from='#bar%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#coucou%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message/body[text()='Mode #coucou [+nt] by {irc_host_one}']"),
expect_stanza("/presence"),
expect_stanza("/message[@from='#coucou%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
# Ask for 0 item
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><max>0</max></set></query></iq>"),
# Get 0 item
expect_stanza("/iq[@type='result']/disco_items:query"),
# Ask for 2 (of 3) items We don’t have the count,
# because biboumi doesn’t have the complete list when
# it sends us the 2 items
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><max>2</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#bar%{irc_server_one}'][@index='0']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#coucou%{irc_server_one}']"),
# Ask for 12 (of 3) items. We get the whole list, and thus we have the count included.
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><max>12</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#bar%{irc_server_one}'][@index='0']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#foo%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:count[text()='3']"),
# Ask for 1 item, AFTER the first item (so,
# the second). Since we don’t invalidate the cache
# with this request, we should have the count
# included.
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><after>#bar%{irc_server_one}</after><max>1</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#coucou%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#coucou%{irc_server_one}'][@index='1']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#coucou%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:count[text()='3']"),
# Ask for 1 item, AFTER the second item (so,
# the third).
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><after>#coucou%{irc_server_one}</after><max>1</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#foo%{irc_server_one}'][@index='2']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#foo%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:count[text()='3']"),
# Ask for 1 item, AFTER the third item (so,
# the fourth). Since it doesn't exist, we get 0 item
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><after>#foo%{irc_server_one}</after><max>1</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/rsm:set/rsm:count[text()='3']"),
)
@@ -0,0 +1,70 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
# Second user joins
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
# Our presence, sent to the other user, and ourself
expect_unordered(
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']"],
["/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
["/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"],
),
# Send a channel message
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
# Receive the message, forwarded to the two users
expect_unordered(
[
"/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"
],
[
"/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"
]
),
# Send a private message, to a in-room JID
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' type='chat'><body>coucou in private</body></message>"),
# Message is received with a server-wide JID
expect_stanza("/message[@from='{lower_nick_one}%{irc_server_one}'][@to='{jid_two}/{resource_one}'][@type='chat']/body[text()='coucou in private']"),
# Respond to the message, to the server-wide JID
send_stanza("<message from='{jid_two}/{resource_one}' to='{lower_nick_one}%{irc_server_one}' type='chat'><body>yes</body></message>"),
# The response is received from the in-room JID
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='yes']",
"/message/muc_user:x"),
# Do the exact same thing, from a different chan,
# to check if the response comes from the right JID
send_stanza("<presence from='{jid_one}/{resource_one}' to='#dummy%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#dummy%{irc_server_one}'][@type='groupchat']/subject"),
# Send a private message, to a in-room JID
send_stanza("<message from='{jid_one}/{resource_one}' to='#dummy%{irc_server_one}/{nick_two}' type='chat'><body>re in private</body></message>"),
# Message is received with a server-wide JID
expect_stanza("/message[@from='{lower_nick_one}%{irc_server_one}'][@to='{jid_two}/{resource_one}'][@type='chat']/body[text()='re in private']"),
# Respond to the message, to the server-wide JID
send_stanza("<message from='{jid_two}/{resource_one}' to='{lower_nick_one}%{irc_server_one}' type='chat'><body>re</body></message>"),
# The response is received from the in-room JID
expect_stanza("/message[@from='#dummy%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='re']"),
# Now we leave the room, to check if the subsequent private messages are still received properly
send_stanza("<presence from='{jid_one}/{resource_one}' to='#dummy%{irc_server_one}/{nick_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']/muc_user:x/muc_user:status[@code='110']"),
# The private messages from this nick should now come (again) from the server-wide JID
send_stanza("<message from='{jid_two}/{resource_one}' to='{lower_nick_one}%{irc_server_one}' type='chat'><body>hihihoho</body></message>"),
expect_stanza("/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}']"),
)
@@ -0,0 +1,16 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Second resource, same channel
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"),
# Now the first resource has an error
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%%{irc_server_one}/{nick_one}' type='error'><error type='cancel'><recipient-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></message>"),
# Receive a leave only to the leaving resource
expect_stanza("/presence[@type='unavailable'][@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:status[@code='110']",
"/presence/status[text()='Biboumi note: 1 resources are still in this channel.']"),
)
@@ -0,0 +1,108 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#aaa%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bbb%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#ccc%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#ddd%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#eee%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#fff%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#ggg%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#hhh%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#iii%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#jjj%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<iq from='{jid_one}/{resource_one}' id='id' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><max>3</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#aaa%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#bbb%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#ccc%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#aaa%{irc_server_one}'][@index='0']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#ccc%{irc_server_one}']"),
send_stanza("<iq from='{jid_one}/{resource_one}' id='id' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><after>#ccc%{irc_server_one}</after><max>3</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#ddd%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#eee%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#fff%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#ddd%{irc_server_one}'][@index='3']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#fff%{irc_server_one}']"),
send_stanza("<iq from='{jid_one}/{resource_one}' id='id' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><after>#fff%{irc_server_one}</after><max>3</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#ggg%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#hhh%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#iii%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#ggg%{irc_server_one}'][@index='6']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#iii%{irc_server_one}']"),
send_stanza("<iq from='{jid_one}/{resource_one}' id='id' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'><set xmlns='http://jabber.org/protocol/rsm'><after>#iii%{irc_server_one}</after><max>3</max></set></query></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/disco_items:item[@jid='#jjj%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:first[text()='#jjj%{irc_server_one}'][@index='9']",
"/iq/disco_items:query/rsm:set/rsm:last[text()='#jjj%{irc_server_one}']",
"/iq/disco_items:query/rsm:set/rsm:count[text()='10']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#aaa%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bbb%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#ccc%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#ddd%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#eee%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#fff%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#ggg%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#hhh%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#iii%{irc_server_one}/{nick_one}' type='unavailable' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#jjj%{irc_server_one}/{nick_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
expect_stanza("/presence[@type='unavailable']"),
)
@@ -0,0 +1,54 @@
from scenarios import *
def incr_counter():
counter = -1
def f(stanza):
nonlocal counter
counter += 1
return counter
return f
counter = incr_counter()
scenario = (
sequences.handshake(),
# Disable the throttling, otherwise it’s way too long
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='next'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports'><value>6667</value></field>"
"<field var='tls_ports'><value>6697</value><value>6670</value></field>"
"<field var='throttle_limit'><value>9999</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']",
after = save_value("counter", counter)),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection(),
scenarios.simple_channel_join.expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#foo", nick = "{nick_one}"),
(
send_stanza("<presence from='{jid_one}/{resource_one}' to='#{counter}%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence",
after = save_value("counter", counter)),
expect_stanza("/message"),
) * 110,
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'/></iq>"),
# charybdis sends the list in alphabetic order, so #foo is the last, and #99 is after #120
expect_stanza("/iq/disco_items:query/disco_items:item[@jid='#0%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#1%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#109%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#9%{irc_server_one}']",
"!/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']",
"!/iq/disco_items:query/disco_items:item[@jid='#99%{irc_server_one}']",
"!/iq/disco_items:query/disco_items:item[@jid='#90%{irc_server_one}']"),
)
@@ -0,0 +1,107 @@
from scenarios import *
scenario = (
sequences.handshake(),
# Disable the throttling, otherwise it’s way too long
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='next'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports'><value>6667</value></field>"
"<field var='tls_ports'><value>6697</value><value>6670</value></field>"
"<field var='throttle_limit'><value>9999</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]",
after = save_value("counter", lambda x: 0)),
(
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>{counter}</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='{counter}']",
after = save_value("counter", lambda stanza: str(1 + int(extract_text("/message/body", stanza))))),
) * 150,
# Retrieve the archive, without any restriction
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id1'><query xmlns='urn:xmpp:mam:2' queryid='qid1' /></iq>"),
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='0']"),
# followed by 98 more messages
(
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body"),
) * 98,
# and finally the message "99"
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='99']",
after = save_value("last_uuid", extract_attribute("/message/mam:result", "id"))),
# And it should not be marked as complete
expect_stanza("/iq[@type='result'][@id='id1'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin/rsm:set/rsm:last[text()='{last_uuid}']",
"!/iq//mam:fin[@complete='true']",
"/iq//mam:fin"),
# Retrieve the next page, using the “after” thingy
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id2'><query xmlns='urn:xmpp:mam:2' queryid='qid2' ><set xmlns='http://jabber.org/protocol/rsm'><after>{last_uuid}</after></set></query></iq>"),
expect_stanza("/message/mam:result[@queryid='qid2']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid2']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='100']"),
(
expect_stanza("/message/mam:result[@queryid='qid2']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid2']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body"),
) * 48,
expect_stanza("/message/mam:result[@queryid='qid2']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid2']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='149']",
after = save_value("last_uuid", extract_attribute("/message/mam:result", "id"))),
expect_stanza("/iq[@type='result'][@id='id2'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin/rsm:set/rsm:last[text()='{last_uuid}']",
"/iq//mam:fin[@complete='true']",
"/iq//mam:fin"),
# Send a request with a non-existing ID set as the “after” value.
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id3'><query xmlns='urn:xmpp:mam:2' queryid='qid3' ><set xmlns='http://jabber.org/protocol/rsm'><after>DUMMY_ID</after></set></query></iq>"),
expect_stanza("/iq[@id='id3'][@type='error']/error[@type='cancel']/stanza:item-not-found"),
# Request the last page just BEFORE the last message in the archive
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id3'><query xmlns='urn:xmpp:mam:2' queryid='qid3' ><set xmlns='http://jabber.org/protocol/rsm'><before></before></set></query></iq>"),
expect_stanza("/message/mam:result[@queryid='qid3']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid3']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='50']"),
(
expect_stanza("/message/mam:result[@queryid='qid3']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid3']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body"),
) * 98,
expect_stanza("/message/mam:result[@queryid='qid3']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid3']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='149']",
after = save_value("last_uuid", extract_attribute("/message/mam:result", "id"))),
expect_stanza("/iq[@type='result'][@id='id3'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin/rsm:set/rsm:last[text()='{last_uuid}']",
"!/iq//mam:fin[@complete='true']",
"/iq//mam:fin"),
# Do the same thing, but with a limit value.
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id4'><query xmlns='urn:xmpp:mam:2' queryid='qid4' ><set xmlns='http://jabber.org/protocol/rsm'><before>{last_uuid}</before><max>2</max></set></query></iq>"),
expect_stanza("/message/mam:result[@queryid='qid4']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid4']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='147']"),
expect_stanza("/message/mam:result[@queryid='qid4']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid4']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='148']",
after = save_value("last_uuid", extract_attribute("/message/mam:result", "id"))),
expect_stanza("/iq[@type='result'][@id='id4'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin/rsm:set/rsm:last[text()='{last_uuid}']",
"!/iq/mam:fin[@complete='true']"),
# Test if everything is fine even with weird max value: 0
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id5'><query xmlns='urn:xmpp:mam:2' queryid='qid5' ><set xmlns='http://jabber.org/protocol/rsm'><before></before><max>0</max></set></query></iq>"),
expect_stanza("/iq[@type='result'][@id='id5'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"!/iq/mam:fin[@complete='true']"),
)
@@ -0,0 +1,11 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#biboumi\\40louiz.org\\3a80%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #biboumi@louiz.org:80 [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#biboumi\\40louiz.org\\3a80%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#biboumi\\40louiz.org\\3a80%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,70 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
# Admin connects to first server
send_stanza("<presence from='{jid_admin}/{resource_one}' to='#bar%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_admin}/{resource_one}'),
expect_self_join_presence(jid = '{jid_admin}/{resource_one}', chan = "#bar", nick = "{nick_one}"),
# Non-Admin connects to first server
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#foo", nick = "{nick_two}"),
# Non-admin connects to second server
send_stanza("<presence from='{jid_one}/{resource_two}' to='#bon%{irc_server_two}/{nick_three}' />"),
sequences.connection("{irc_host_two}", '{jid_one}/{resource_two}'),
expect_self_join_presence(jid = '{jid_one}/{resource_two}', chan = "#bon", nick = "{nick_three}", irc_server = "{irc_server_two}"),
# Execute as admin
send_stanza("<iq type='set' id='command1' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-from-irc-server' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='disconnect-from-irc-server'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='jid'][@type='list-single']/dataform:option[@label='{jid_one}']/dataform:value[text()='{jid_one}']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='jid'][@type='list-single']/dataform:option[@label='{jid_admin}']/dataform:value[text()='{jid_admin}']",
"/iq/commands:command/commands:actions/commands:next",
after = save_value("sessionid", extract_attribute("/iq/commands:command[@node='disconnect-from-irc-server']", "sessionid"))
),
send_stanza("<iq type='set' id='command2' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-from-irc-server' sessionid='{sessionid}' action='next'><x xmlns='jabber:x:data' type='submit'><field var='jid'><value>{jid_one}</value></field><field var='quit-message'><value>e2e test one</value></field></x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='disconnect-from-irc-server'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='quit-message'][@type='text-single']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='irc-servers'][@type='list-multi']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='irc-servers']/dataform:option[@label='localhost']/dataform:value[text()='localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='irc-servers']/dataform:option[@label='irc.localhost']/dataform:value[text()='irc.localhost']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq/commands:command[@node='disconnect-from-irc-server']", "sessionid"))
),
# Command is successfull
send_stanza("<iq type='set' id='command3' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-from-irc-server' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'><field var='irc-servers'><value>localhost</value></field><field var='quit-message'><value>Disconnected by e2e</value></field></x></command></iq>"),
# User is being disconnected
expect_unordered(
[
"/presence[@type='unavailable'][@to='{jid_one}/{resource_two}'][@from='#bon%{irc_server_two}/{nick_three}']",
"/presence/status[text()='Disconnected by e2e']"
],
[
"/iq[@type='result']/commands:command[@node='disconnect-from-irc-server'][@status='completed']/commands:note[@type='info'][text()='{jid_one} was disconnected from 1 IRC server.']",
]),
# Execute as non-admin (this skips the first step)
send_stanza("<iq type='set' id='command4' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-from-irc-server' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='disconnect-from-irc-server'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='quit-message'][@type='text-single']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='irc-servers'][@type='list-multi']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='irc-servers']/dataform:option[@label='irc.localhost']/dataform:value[text()='irc.localhost']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq/commands:command[@node='disconnect-from-irc-server']", "sessionid"))
),
send_stanza("<iq type='set' id='command5' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-from-irc-server' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'><field var='irc-servers'><value>irc.localhost</value></field><field var='quit-message'><value>Disconnected by e2e</value></field></x></command></iq>"),
expect_unordered(
[
"/presence[@type='unavailable'][@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']",
"/presence/status[text()='Disconnected by e2e']"
],
[
"/iq[@type='result']/commands:command[@node='disconnect-from-irc-server'][@status='completed']/commands:note[@type='info'][text()='{jid_one}/{resource_one} was disconnected from 1 IRC server.']",
]),
)
@@ -0,0 +1,20 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_admin}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_admin}/{resource_one}'),
expect_self_join_presence(jid = '{jid_admin}/{resource_one}', chan = "#foo", nick = "{nick_one}"),
send_stanza("<iq type='set' id='command1' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-user' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='disconnect-user'][@sessionid][@status='executing']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq/commands:command[@node='disconnect-user']", "sessionid"))
),
send_stanza("<iq type='set' id='command2' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-user' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'><field var='jids'><value>{jid_admin}</value></field><field var='quit-message'><value>Disconnected by e2e</value></field></x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='disconnect-user'][@status='completed']/commands:note[@type='info'][text()='1 user has been disconnected.']"),
# Note, charybdis ignores our QUIT message, so we can't test it
expect_stanza("/presence[@type='unavailable'][@to='{jid_admin}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']"),
)
@@ -0,0 +1,8 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='command1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='disconnect-user' action='execute' /></iq>"),
expect_stanza("/iq[@type='error'][@id='command1']/commands:command[@node='disconnect-user']",
"/iq/commands:command/commands:error[@type='cancel']/stanza:forbidden"),
)
@@ -0,0 +1,15 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='hello-command1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='hello' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='hello'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure your name.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Please provide your name.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single']/dataform:required",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='hello']", "sessionid"))
),
send_stanza("<iq type='set' id='hello-command2' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='hello' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'><field var='name'><value>COUCOU</value></field></x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='hello'][@status='completed']/commands:note[@type='info'][text()='Hello COUCOU!']")
)
@@ -0,0 +1,12 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='hello-command1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='hello' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='hello'][@sessionid][@status='executing']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='hello']", "sessionid"))
),
send_stanza("<iq type='set' id='hello-command2' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='hello' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'></x></command></iq>"),
expect_stanza("/iq[@type='error']")
)
@@ -0,0 +1,7 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='ping-command1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='ping' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='ping'][@status='completed']/commands:note[@type='info'][text()='Pong']")
)
@@ -0,0 +1,7 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='ping-command1' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='reload' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='reload'][@status='completed']/commands:note[@type='info'][text()='Configuration reloaded.']"),
)
@@ -0,0 +1,9 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
sequences.handshake(),
send_stanza("<presence type='subscribe' from='{jid_one}/{resource_one}' to='{biboumi_host}' id='sub1' />"),
expect_stanza("/presence[@to='{jid_one}'][@from='{biboumi_host}'][@type='subscribed']")
)
@@ -0,0 +1,16 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
sequences.handshake(),
send_stanza("<iq from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}' id='1' type='get'><query xmlns='http://jabber.org/protocol/disco#info'/></iq>"),
expect_stanza("/iq[@from='#foo@{biboumi_host}'][@to='{jid_one}/{resource_one}'][@type='result']/disco_info:query",
"/iq[@type='result']/disco_info:query/disco_info:identity[@category='conference'][@type='irc'][@name='#foo on {irc_host_one}']",
"/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']",
"/iq/disco_info:query/disco_info:feature[@var='http://jabber.org/protocol/commands']",
"/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:ping']",
"/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:mam:2']",
"/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']"),
)
@@ -0,0 +1,17 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='command1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='get-irc-connection-info' action='execute' /></iq>"),
expect_stanza("/iq/commands:command/commands:note[text()='You are not connected to the IRC server irc.localhost']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<iq type='set' id='command2' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='get-irc-connection-info' action='execute' /></iq>"),
expect_stanza(r"/iq/commands:command/commands:note[re:test(text(), 'Connected to IRC server irc.localhost on port 6667 since \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d \(\d+ seconds ago\)\.\n#foo from 1 resource: {resource_one}.*')]"),
)
@@ -0,0 +1,19 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='command1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='get-irc-connection-info' action='execute' /></iq>"),
expect_stanza("/iq/commands:command/commands:note[text()='You are not connected to the IRC server irc.localhost']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}', fixed_irc_server=True),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<iq type='set' id='command2' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='get-irc-connection-info' action='execute' /></iq>"),
expect_stanza(r"/iq/commands:command/commands:note[re:test(text(), 'Connected to IRC server irc.localhost on port 6667 since \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d \(\d+ seconds ago\)\.\n#foo from 1 resource: {resource_one}.*')]"),
)
@@ -0,0 +1,28 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='20']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='true']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='false']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'><field var='record_history'><value>0</value></field><field var='max_history_length'><value>42</value></field></x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='42']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='false']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='false']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))),
send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='configure' sessionid='{sessionid}' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"),
)
@@ -0,0 +1,33 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='global-configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='global-configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='20']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='true']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='false']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='global-configure']", "sessionid"))),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='global-configure' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'><field var='record_history'><value>0</value></field><field var='max_history_length'><value>42</value></field></x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='global-configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='global-configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='global-configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='42']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='false']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='false']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='global-configure']", "sessionid"))),
send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='global-configure' sessionid='{sessionid}' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='global-configure'][@status='canceled']"),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='server-configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='server-configure'][@sessionid][@status='executing']"),
)
@@ -0,0 +1,16 @@
from scenarios import *
conf='persistent_by_default'
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='20']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='true']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='true']",
"/iq/commands:command/commands:actions/commands:complete",
),
)
@@ -0,0 +1,22 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_two}/{resource_two}' to='#bar%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_two}'),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><x xmlns='http://jabber.org/protocol/muc#user'><invite to='{nick_two}'/></x></message>"),
expect_stanza("/message/body[text()='{nick_two} has been invited to #foo']"),
expect_stanza("/message[@to='{jid_two}/{resource_two}'][@from='#foo%{irc_server_one}']/muc_user:x/muc_user:invite[@from='#foo%{irc_server_one}/{nick_one}']"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><x xmlns='http://jabber.org/protocol/muc#user'><invite to='bertrand@example.com'/></x></message>"),
expect_stanza("/message[@to='bertrand@example.com'][@from='#foo%{irc_server_one}']/muc_user:x/muc_user:invite[@from='{jid_one}/{resource_one}']"),
)
@@ -0,0 +1,36 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute'><dummy/></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='list-single'][@var='record_history']/dataform:value[text()='unset']",
"!/iq/commands:command/commands:dummy",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='complete'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports' />"
"<field var='encoding_out'><value>UTF-8</value></field>"
"<field var='encoding_in'><value>latin-1</value></field>"
"<field var='record_history'><value>true</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC channel #foo on server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='list-single'][@var='record_history']/dataform:value[text()='true']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='configure' sessionid='{sessionid}' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"),
)
@@ -0,0 +1,34 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='complete'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports' />"
"<field var='encoding_out'><value>UTF-8</value></field>"
"<field var='encoding_in'><value>latin-1</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC channel #foo on server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='configure' sessionid='{sessionid}' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"),
)
@@ -0,0 +1,21 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='id1' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>"),
expect_stanza("/iq[@type='result']/muc_owner:query",
"/iq/muc_owner:query/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
"/iq/muc_owner:query/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']",
),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'>"
"<query xmlns='http://jabber.org/protocol/muc#owner'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports' />"
"<field var='encoding_out'><value>UTF-8</value></field>"
"<field var='encoding_in'><value>latin-1</value></field>"
"</x></query></iq>"),
expect_stanza("/iq[@type='result']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><query xmlns='http://jabber.org/protocol/muc#owner'> <x xmlns='jabber:x:data' type='cancel'/></query></iq>"),
expect_stanza("/iq[@type='result']"),
)
@@ -0,0 +1,103 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure the settings of the IRC server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='ports']/dataform:value[text()='6667']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6670']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6697']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='verify_cert']/dataform:value[text()='true']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='throttle_limit']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='nick']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='complete'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports' />"
"<field var='tls_ports'><value>6697</value><value>6698</value></field>"
"<field var='verify_cert'><value>1</value></field>"
"<field var='fingerprint'><value>12:12:12</value></field>"
"<field var='pass'><value>coucou</value></field>"
"<field var='after_connect_commands'><value>first command</value><value>second command</value></field>"
"<field var='nick'><value>my_nickname</value></field>"
"<field var='username'><value>username</value></field>"
"<field var='throttle_limit'><value>42</value></field>"
"<field var='realname'><value>realname</value></field>"
"<field var='encoding_out'><value>UTF-8</value></field>"
"<field var='encoding_in'><value>latin-1</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure the settings of the IRC server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6697']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='tls_ports']/dataform:value[text()='6698']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='verify_cert']/dataform:value[text()='true']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']/dataform:value[text()='12:12:12']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']/dataform:value[text()='coucou']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='nick']/dataform:value[text()='my_nickname']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']/dataform:value[text()='first command']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']/dataform:value[text()='second command']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']/dataform:value[text()='username']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']/dataform:value[text()='realname']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='throttle_limit']/dataform:value[text()='42']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']",
"/iq/commands:command/commands:actions/commands:complete",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='configure' sessionid='{sessionid}' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"),
# Same thing, but try to empty some values
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='complete'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='pass'><value></value></field>"
"<field var='after_connect_commands'></field>"
"<field var='username'><value></value></field>"
"<field var='realname'><value></value></field>"
"<field var='throttle_limit'><value></value></field>"
"<field var='encoding_out'><value></value></field>"
"<field var='encoding_in'><value></value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
"/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure the IRC server irc.localhost']",
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure the settings of the IRC server irc.localhost']",
"!/iq/commands:command/dataform:x/dataform:field[@var='tls_ports']/dataform:value",
"!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='pass']/dataform:value",
"!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='after_connect_commands']/dataform:value",
"!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='username']/dataform:value",
"!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='realname']/dataform:value",
"!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='encoding_in']/dataform:value",
"!/iq/commands:command/dataform:x[@type='form']/dataform:field[@var='encoding_out']/dataform:value",
"/iq/commands:command/commands:actions/commands:complete",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='throttle_limit']/dataform:value[text()='-1']", # An invalid value sets this field to -1, aka disabled
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
),
send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='configure' sessionid='{sessionid}' /></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"),
)
@@ -0,0 +1,8 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection(),
)
@@ -0,0 +1,12 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%doesnotexist@{biboumi_host}/{nick_one}' />"),
expect_stanza("/message/body[text()='Connecting to doesnotexist:6697 (encrypted)']"),
expect_stanza("/message/body[re:test(text(), 'Connection failed: (Domain name not found|Name or service not known)')]"),
expect_stanza("/presence[@from='#foo%doesnotexist@{biboumi_host}/{nick_one}']/muc:x",
"/presence/error[@type='cancel']/stanza:item-not-found",
"/presence/error[@type='cancel']/stanza:text[re:test(text(), '(Domain name not found|Name or service not known)')]",
),
)
@@ -0,0 +1,27 @@
from scenarios import *
scenario = (
sequences.handshake(),
# Mutual subscription exchange
send_stanza("<presence from='{jid_one}' to='{irc_server_one}' type='subscribe' id='subid1' />"),
expect_stanza("/presence[@type='subscribed'][@id='subid1']"),
expect_stanza("/presence[@type='subscribe']"),
send_stanza("<presence from='{jid_one}' to='{irc_server_one}' type='subscribed' />"),
# Join a channel on that server
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
# We must receive the IRC server presence, in the connection sequence
sequences.connection("irc.localhost", '{jid_one}/{resource_one}', expected_irc_presence=True),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
# Leave the channel, and thus the IRC server
send_stanza("<presence type='unavailable' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
expect_stanza("/presence[@type='unavailable'][@from='#foo%{irc_server_one}/{nick_one}']"),
expect_stanza("/presence[@from='{irc_server_one}'][@to='{jid_one}'][@type='unavailable']"),
)
@@ -0,0 +1,7 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence type='subscribe' from='{jid_one}/{resource_one}' to='{irc_server_one}' id='sub1' />"),
expect_stanza("/presence[@to='{jid_one}'][@from='{irc_server_one}'][@type='subscribed']"),
)
@@ -0,0 +1,26 @@
from scenarios import *
scenario = (
sequences.handshake(),
# First, use an adhoc command to configure how we connect to the irc server, configure
# only one TLS port, and disable the cert verification.
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='next'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports' />"
"<field var='tls_ports'><value>7778</value></field>"
"<field var='verify_cert'><value>0</value></field>"
"<field var='nick'><value>my_special_nickname</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection_tls("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/my_special_nickname']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,110 @@
from scenarios import *
scenario = (
sequences.handshake(),
# Disable the throttling because the test is based on timings
send_stanza("<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
expect_stanza("/iq[@type='result']",
after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))),
send_stanza("<iq type='set' id='id2' from='{jid_one}/{resource_one}' to='{irc_server_one}'>"
"<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='next'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='ports'><value>6667</value></field>"
"<field var='tls_ports'><value>6697</value><value>6670</value></field>"
"<field var='throttle_limit'><value>9999</value></field>"
"</x></command></iq>"),
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
# Send two channel messages
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 2</body></message>"),
# Record the current time
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']",
after = save_current_timestamp_plus_delta("first_timestamp", datetime.timedelta(seconds=1))),
# Wait two seconds before sending two new messages
sleep_for(2),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 3</body></message>"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 4</body></message>"),
expect_stanza("/message[@type='groupchat']/body[text()='coucou 3']"),
expect_stanza("/message[@type='groupchat']/body[text()='coucou 4']",
after = save_current_timestamp_plus_delta("second_timestamp", datetime.timedelta(seconds=1))),
# join some other channel, to stay connected to the server even after leaving #foo
send_stanza("<presence from='{jid_one}/{resource_one}' to='#DUMMY%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message/subject"),
# Leave #foo
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
sleep_for(0.2),
# Rejoin #foo, with some history limit
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><x xmlns='http://jabber.org/protocol/muc'><history maxchars='0'/></x></presence>"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message/subject"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
sleep_for(0.2),
# Rejoin #foo, with some history limit
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><x xmlns='http://jabber.org/protocol/muc'><history maxstanzas='3'/></x></presence>"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 2']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 3']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 4']"),
expect_stanza("/message/subject"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
# Rejoin #foo, with some history limit
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><x xmlns='http://jabber.org/protocol/muc'><history since='{first_timestamp}'/></x></presence>"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 3']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 4']"),
expect_stanza("/message/subject"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
# Rejoin #foo, with some history limit
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><x xmlns='http://jabber.org/protocol/muc'><history seconds='1'/></x></presence>"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 3']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 4']"),
expect_stanza("/message/subject"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
# Rejoin #foo, with some history limit
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><x xmlns='http://jabber.org/protocol/muc'><history seconds='5'/></x></presence>"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou']"), expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 2']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 3']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='coucou 4']"),
expect_stanza("/message/subject"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable']"),
)
@@ -0,0 +1,17 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<presence from='{jid_two}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection_begin("irc.localhost", '{jid_two}/{resource_two}'),
expect_stanza("/message[@to='{jid_two}/{resource_two}'][@type='chat']/body[text()='irc.localhost: {nick_one}: Nickname is already in use.']"),
expect_stanza("/presence[@type='error']/error[@type='cancel'][@code='409']/stanza:conflict"),
send_stanza("<presence from='{jid_two}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' type='unavailable' />")
)
+11
View File
@@ -0,0 +1,11 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='idwhatever' from='{jid_one}/{resource_one}' to='{biboumi_host}'><query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/commands' /></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']",
"/iq/disco_items:query/disco_items:item[@node='configure']",
"/iq/disco_items:query/disco_items:item[4]",
"!/iq/disco_items:query/disco_items:item[5]"),
)
@@ -0,0 +1,13 @@
from scenarios import *
conf = "fixed_server"
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='idwhatever' from='{jid_one}/{resource_one}' to='{biboumi_host}'><query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/commands' /></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']",
"/iq/disco_items:query/disco_items:item[@node='global-configure']",
"/iq/disco_items:query/disco_items:item[@node='server-configure']",
"/iq/disco_items:query/disco_items:item[6]",
"!/iq/disco_items:query/disco_items:item[7]"),
)
@@ -0,0 +1,9 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='idwhatever' from='{jid_one}/{resource_one}' to='{irc_host_one}@{biboumi_host}'><query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/commands' /></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']",
"/iq/disco_items:query/disco_items:item[2]",
"!/iq/disco_items:query/disco_items:item[3]"),
)
@@ -0,0 +1,10 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='idwhatever' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/commands' /></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']",
"/iq/disco_items:query/disco_items:item[@node='configure']",
"/iq/disco_items:query/disco_items:item[6]",
"!/iq/disco_items:query/disco_items:item[7]"),
)
@@ -0,0 +1,13 @@
from scenarios import *
conf = "fixed_server"
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='idwhatever' from='{jid_admin}/{resource_one}' to='{biboumi_host}'><query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/commands' /></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query[@node='http://jabber.org/protocol/commands']",
"/iq/disco_items:query/disco_items:item[@node='global-configure']",
"/iq/disco_items:query/disco_items:item[@node='server-configure']",
"/iq/disco_items:query/disco_items:item[8]",
"!/iq/disco_items:query/disco_items:item[9]"),
)
@@ -0,0 +1,7 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='idwhatever' from='{jid_admin}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/commands' /></iq>"),
expect_stanza("/iq[@type='error']/error[@type='cancel']/stanza:feature-not-implemented"),
)
@@ -0,0 +1,21 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
scenarios.channel_join_on_fixed_irc_server.scenario,
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@from='#foo@{biboumi_host}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}' type='groupchat'><body>coucou 2</body></message>"),
expect_stanza("/message[@from='#foo@{biboumi_host}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']"),
# Retrieve the complete archive
send_stanza("<iq to='#foo@{biboumi_host}' from='{jid_one}/{resource_one}' type='set' id='id1'><query xmlns='urn:xmpp:mam:2' queryid='qid1' /></iq>"),
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo@{biboumi_host}/{nick_one}'][@type='groupchat']/client:body[text()='coucou']"),
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo@{biboumi_host}/{nick_one}'][@type='groupchat']/client:body[text()='coucou 2']"),
)
@@ -0,0 +1,43 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send two channel messages
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 2</body></message>"),
# Record the current time
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']",
after = save_current_timestamp_plus_delta("first_timestamp", datetime.timedelta(seconds=1))),
# Wait two seconds before sending two new messages
sleep_for(2),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 3</body></message>"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 4</body></message>"),
expect_stanza("/message[@type='groupchat']/body[text()='coucou 3']"),
expect_stanza("/message[@type='groupchat']/body[text()='coucou 4']",
after = save_current_timestamp_plus_delta("second_timestamp", datetime.timedelta(seconds=1))),
# Retrieve the archive, after our saved datetime
send_stanza("""<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id8'>
<query xmlns='urn:xmpp:mam:2' queryid='qid16'>
<x type='submit' xmlns='jabber:x:data'>
<field var='FORM_TYPE' xmlns='jabber:x:data'><value xmlns='jabber:x:data'>urn:xmpp:mam:2</value></field>
<field var='start' xmlns='jabber:x:data'><value xmlns='jabber:x:data'>{first_timestamp}</value></field>
<field var='end' xmlns='jabber:x:data'><value xmlns='jabber:x:data'>{second_timestamp}</value></field>
</x>
</query>
</iq>"""),
expect_stanza("/message/mam:result[@queryid='qid16']/forward:forwarded/delay:delay",
"/message/mam:result/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou 3']"),
expect_stanza("/message/mam:result[@queryid='qid16']/forward:forwarded/delay:delay",
"/message/mam:result/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou 4']"),
expect_stanza("/iq[@type='result'][@id='id8'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin[@complete='true']/rsm:set"),
)
+52
View File
@@ -0,0 +1,52 @@
from scenarios import *
scenario = (
scenarios.channel_join_with_two_users.scenario,
# Change a user mode with a message starting with /mode
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>/mode +v {nick_two}</body></message>"),
expect_unordered(
["/message[@to='{jid_one}/{resource_one}']/body[text()='Mode #foo [+v {nick_two}] by {nick_one}']"],
["/message[@to='{jid_two}/{resource_one}']/body[text()='Mode #foo [+v {nick_two}] by {nick_one}']"],
["/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='member'][@role='participant']"],
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='member'][@role='participant']"],
),
# using an iq
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item affiliation='admin' nick='{nick_two}'/></query></iq>"),
expect_unordered(
["/message[@to='{jid_one}/{resource_one}']/body[text()='Mode #foo [+o {nick_two}] by {nick_one}']"],
["/message[@to='{jid_two}/{resource_one}']/body[text()='Mode #foo [+o {nick_two}] by {nick_one}']"],
["/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"],
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"],
["/iq[@id='id1'][@type='result'][@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}']"],
),
# remove the mode
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item affiliation='member' nick='{nick_two}' role='participant'/></query></iq>"),
expect_unordered(
["/message[@to='{jid_one}/{resource_one}']/body[text()='Mode #foo [+v-o {nick_two} {nick_two}] by {nick_one}']"],
["/message[@to='{jid_two}/{resource_one}']/body[text()='Mode #foo [+v-o {nick_two} {nick_two}] by {nick_one}']"],
["/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='member'][@role='participant']"],
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='member'][@role='participant']"],
["/iq[@id='id1'][@type='result'][@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}']"],
),
# using an iq, an a non-existant nick
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item affiliation='admin' nick='blectre'/></query></iq>"),
expect_stanza("/iq[@type='error']"),
# using an iq, without the rights to do it
send_stanza("<iq from='{jid_two}/{resource_one}' id='id1' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item affiliation='admin' nick='{nick_one}'/></query></iq>"),
expect_unordered(
["/iq[@type='error']"],
["/message[@type='chat'][@to='{jid_two}/{resource_one}']"]
),
# using an iq, with an unknown mode
send_stanza("<iq from='{jid_two}/{resource_one}' id='id1' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item affiliation='owner' nick='{nick_one}'/></query></iq>"),
expect_unordered(
["/iq[@type='error']"],
["/message[@type='chat'][@to='{jid_two}/{resource_one}']"],
),
)
@@ -0,0 +1,30 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' id='1' type='get'><query xmlns='http://jabber.org/protocol/disco#info'/></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='result']/disco_info:query",
"/iq[@type='result']/disco_info:query/disco_info:identity[@category='conference'][@type='irc'][@name='#foo on {irc_host_one}']",
"/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']",
"/iq/disco_info:query/disco_info:feature[@var='http://jabber.org/protocol/commands']",
"/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:ping']",
"/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:mam:2']",
"/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']",
"/iq/disco_info:query/disco_info:feature[@var='muc_nonanonymous']",
"!/iq/disco_info:query/dataform:x/dataform:field[@var='muc#roominfo_occupants']"),
# Join the channel, and re-do the same query
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
send_stanza("<iq from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' id='2' type='get'><query xmlns='http://jabber.org/protocol/disco#info'/></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='result']/disco_info:query",
"/iq/disco_info:query/dataform:x/dataform:field[@var='muc#roominfo_occupants']/dataform:value[text()='1']",
"/iq/disco_info:query/dataform:x/dataform:field[@var='FORM_TYPE'][@type='hidden']/dataform:value[text()='http://jabber.org/protocol/muc#roominfo']"),
)
@@ -0,0 +1,16 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send a channel message
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
# Receive the message
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"),
# Send a message from a resource that is not joined
send_stanza("<message from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@type='error']/error[@type='modify']/stanza:text[text()='You are not a participant in this room.']",
"/message/error/stanza:not-acceptable"
),
)
@@ -0,0 +1,8 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' id='1' type='get'><query xmlns='http://jabber.org/protocol/disco#info' node='http://jabber.org/protocol/muc#traffic'/></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='result']/disco_info:query[@node='http://jabber.org/protocol/muc#traffic']"),
)
@@ -0,0 +1,62 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
# Send a multi-line channel message
send_stanza("<message id='the-message-id' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>un\ndeux\ntrois</body></message>"),
# Receive multiple messages, in order
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id='the-message-id'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='un']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='deux']"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='trois']"),
# Send a simple message, with no id
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>hello</body></message>"),
# Expect a non-empty id as a result (should be a uuid)
expect_stanza("!/message[@id='']",
"/message[@id]/body[text()='hello']"),
# even though we reflect the message to XMPP only
# when we send it to IRC, there’s still a race
# condition if the XMPP client receives the
# reflection (and the IRC server didn’t yet receive
# it), then the new user joins the room, and then
# finally the IRC server sends the message to “all
# participants of the channel”, including the new
# one, that was not supposed to be there when the
# message was sent in the first place by the first
# XMPP user. There’s nothing we can do about it until
# all servers support the echo-message IRCv3
# extension… So, we just sleep a little bit before
# joining the room with the new user.
sleep_for(0.2),
# Second user joins
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
# Our presence, sent to the other user
expect_unordered(
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']"],
["/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='{lower_nick_two}%{irc_server_one}/~{nick_two}@localhost'][@role='participant']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
["/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"]
),
# Send a multi-line channel message
send_stanza("<message id='the-message-id' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>a\nb\nc</body></message>"),
# Receive multiple messages, for each user
expect_unordered(
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id='the-message-id'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='a']"],
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='b']"],
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='c']"],
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='a']"],
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='b']"],
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='c']"],
)
)
@@ -0,0 +1,11 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
# User tries to set a multiline topic
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><subject>FIRST LINE\nSECOND LINE.</subject></message>"),
# Server converts the newline into spaces, because IRC can’t have them in the topic
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat'][@to='{jid_one}/{resource_one}']/subject[text()='FIRST LINE SECOND LINE.']")
)
@@ -0,0 +1,20 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
# Join 3 rooms, on the same server, with three different nicks
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bar%{irc_server_one}/{nick_two}' />"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#baz%{irc_server_one}/{nick_three}'> <x xmlns='http://jabber.org/protocol/muc'><password>SECRET</password></x></presence>"),
sequences.connection(),
# The first nick we specified should be the only one we receive, the rest was ignored
expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#foo", nick="{nick_one}"),
expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#bar", nick="{nick_one}"),
expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#baz", nick="{nick_one}"),
)
@@ -0,0 +1,46 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Second user joins, from two resources
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_unordered(
["/presence/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']"],
["/presence/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"],
["/presence/muc_user:x/muc_user:status[@code='110']"],
["/message/subject"]
),
# Second resource
send_stanza("<presence from='{jid_two}/{resource_two}' to='#foo%{irc_server_one}/{nick_two}' />"),
expect_stanza("/presence[@to='{jid_two}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']"),
expect_stanza("/presence[@to='{jid_two}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}']",
"/presence/muc_user:x/muc_user:status[@code='110']"
),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_two}/{resource_two}']/subject[not(text())]"),
# Moderator kicks participant
send_stanza("<iq id='kick1' to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item nick='{nick_two}' role='none'><reason>reported</reason></item></query></iq>"),
expect_unordered(
[
"/presence[@type='unavailable'][@to='{jid_two}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']",
"/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']",
"/presence/muc_user:x/muc_user:status[@code='307']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/presence[@type='unavailable'][@to='{jid_two}/{resource_two}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']",
"/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']",
"/presence/muc_user:x/muc_user:status[@code='307']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
["/presence[@type='unavailable']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']",
"/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']",
"/presence/muc_user:x/muc_user:status[@code='307']",
],
[
"/iq[@id='kick1'][@type='result']"
]
),
)
@@ -0,0 +1,127 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
# Resource one joins a channel
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection(),
expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#foo", nick = "{nick_one}"),
# The other resources joins the same room, with the same nick
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
# We receive our own join
expect_unordered(
[
"/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"
]
),
# A different user joins the same room
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_unordered(
# The new user’s presence is sent to the the existing occupant (two resources)
[
"/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']"
],
[
"/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}']"
],
# the new user receives her own presence
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
# the new user receives the presence of the existing occupant
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']",
],
[
"/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]",
],
),
# That second user sends a private message to the first one
send_stanza("<message from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' type='chat'><body>RELLO</body></message>"),
# Message is received with a server-wide JID, by the two resources behind nick_one
expect_unordered(
[
"/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='RELLO']",
"/message/hints:no-copy",
"/message/carbon:private",
"!/message/muc_user:x",
],
[
"/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='RELLO']",
"/message/hints:no-copy",
"/message/carbon:private",
"!/message/muc_user:x",
]
),
# First occupant (with the two resources) changes her/his nick to a conflicting one
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
expect_unordered(
["/message[@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='irc.localhost: Bobby: Nickname is already in use.']"],
["/message[@to='{jid_one}/{resource_two}'][@type='chat']/body[text()='irc.localhost: Bobby: Nickname is already in use.']"],
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}'][@type='error']"],
["/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_two}'][@type='error']"]
),
# First occupant (with the two resources) changes her/his nick
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_three}' />"),
expect_unordered(
[
"/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
"/presence/muc_user:x/muc_user:status[@code='303']"
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_two}/{resource_one}']"
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
"/presence/muc_user:x/muc_user:status[@code='303']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_one}/{resource_one}']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_two}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
"/presence/muc_user:x/muc_user:status[@code='303']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_one}/{resource_two}']",
"/presence/muc_user:x/muc_user:status[@code='110']"
]
),
# One resource leaves the server entirely.
send_stanza("<presence type='unavailable' from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
# The leave is forwarded only to that resource
expect_stanza("/presence[@type='unavailable']/muc_user:x/muc_user:status[@code='110']",
"/presence/status[text()='Biboumi note: 1 resources are still in this channel.']",
),
# The second user sends two new private messages to the first user
send_stanza("<message from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_three}' type='chat'><body>first</body></message>"),
send_stanza("<message from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_three}' type='chat'><body>second</body></message>"),
# The first user receives the two messages, on the connected resource, once each
expect_unordered(
["/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='first']"],
["/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='second']"]
),
)
@@ -0,0 +1,19 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection(),
expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#foo", nick = "{nick_one}"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bar%{irc_server_one}/{nick_two}' />"),
expect_stanza("/message/body[text()='Mode #bar [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#bar%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']",
"/presence/muc_user:x/muc_user:status[@code='210']", # This status signals that the server forced our nick to NOT be the one we asked
),
expect_stanza("/message[@from='#bar%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,13 @@
from scenarios import *
from scenarios.simple_channel_join import expect_self_join_presence
scenario = (
sequences.handshake(),
send_stanza("<presence type='unavailable' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
# Fixme: what is the purpose of this test? Check that we don’t receive anything here…?
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection(),
expect_self_join_presence(jid='{jid_one}/{resource_one}', chan="#foo", nick="{nick_one}"),
)
+10
View File
@@ -0,0 +1,10 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
send_stanza("<message from='{jid_one}/{resource_one}' to='{irc_server_one}' type='chat'><body>NOTICE {nick_one} :[#foo] Hello in a notice.</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/body[text()='[notice] [#foo] Hello in a notice.']"),
)
@@ -0,0 +1,48 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
# Join the channel with user 1
scenarios.simple_channel_join.scenario,
# Make it persistent for user 1
send_stanza("<iq from='{jid_one}/{resource_one}' id='conf1' to='#foo%{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>"),
expect_stanza("/iq[@type='result']/muc_owner:query/dataform:x/dataform:field[@var='persistent'][@type='boolean']/dataform:value[text()='false']"),
send_stanza("<iq from='{jid_one}/{resource_one}' id='conf2' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#owner'><x type='submit' xmlns='jabber:x:data'><field var='persistent' xmlns='jabber:x:data'><value>true</value></field></x></query></iq>"),
expect_stanza("/iq[@type='result']"),
# Check that the value is now effectively true
send_stanza("<iq from='{jid_one}/{resource_one}' id='conf1' to='#foo%{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>"),
expect_stanza("/iq[@type='result']/muc_owner:query/dataform:x/dataform:field[@var='persistent'][@type='boolean']/dataform:value[text()='true']"),
# A second user joins the same channel
send_stanza("<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_unordered(
["/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']"],
[
"/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
["/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']"],
),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
# First user leaves the room (but biboumi will stay in the channel)
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' type='unavailable' />"),
# Only user 1 receives the unavailable presence
expect_stanza("/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:status[@code='110']",
"/presence/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"),
# Second user sends a channel message
send_stanza("<message type='groupchat' from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}'><body>coucou</body></message>"),
# Message should only be received by user 2, since user 1 has no resource in the room
expect_stanza("/message[@type='groupchat'][@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']"),
# Second user leaves the channel
send_stanza("<presence type='unavailable' from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
expect_stanza("/presence[@type='unavailable'][@from='#foo%{irc_server_one}/{nick_two}']"),
)
+12
View File
@@ -0,0 +1,12 @@
from scenarios import *
import scenarios.simple_channel_join
scenario = (
scenarios.simple_channel_join.scenario,
# Send a raw QUIT message
send_stanza("<message from='{jid_one}/{resource_one}' to='{irc_server_one}' type='chat'><body>QUIT bye bye</body></message>"),
expect_stanza("/presence[@from='#foo%{irc_server_one}/{nick_one}'][@type='unavailable']/muc_user:x/muc_user:status[@code='110']"),
)
+13
View File
@@ -0,0 +1,13 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<message from='{jid_one}/{resource_one}' to='{irc_server_one}' type='chat'><body>WHOIS {nick_one}</body></message>"),
expect_stanza("/message[@from='{irc_server_one}'][@type='chat']/body[text()='irc.localhost: {nick_one} ~{nick_one} localhost * {nick_one}']"),
)
@@ -0,0 +1,17 @@
from scenarios import *
conf = 'fixed_server'
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}', fixed_irc_server=True),
expect_stanza("/message"),
expect_stanza("/presence"),
expect_stanza("/message"),
send_stanza("<message from='{jid_one}/{resource_one}' to='{biboumi_host}' type='chat'><body>WHOIS {nick_one}</body></message>"),
expect_stanza("/message[@from='{biboumi_host}'][@type='chat']/body[text()='irc.localhost: {nick_one} ~{nick_one} localhost * {nick_one}']"),
)
@@ -0,0 +1,13 @@
from functions import send_stanza, expect_stanza
import scenarios.simple_channel_join
join_channel = scenarios.simple_channel_join.scenario
scenario = (
join_channel,
send_stanza("<message type='chat' from='{jid_one}/{resource_one}' to='{irc_server_one}'><body>NAMES</body></message>"),
expect_stanza("/message/body[text()='irc.localhost: = #foo @{nick_one} ']"),
expect_stanza("/message/body[text()='irc.localhost: * End of /NAMES list. ']"),
)
@@ -0,0 +1,43 @@
from scenarios import *
scenario = (
# Join the channel
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_one}']/subject[not(text())]"),
# Make it persistent
send_stanza("<iq from='{jid_one}/{resource_one}' id='conf1' to='#foo%{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>"),
expect_stanza("/iq[@type='result']/muc_owner:query/dataform:x/dataform:field[@var='persistent'][@type='boolean']/dataform:value[text()='false']"),
send_stanza("<iq from='{jid_one}/{resource_one}' id='conf2' to='#foo%{irc_server_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#owner'><x type='submit' xmlns='jabber:x:data'><field var='persistent' xmlns='jabber:x:data'><value>true</value></field></x></query></iq>"),
expect_stanza("/iq[@type='result']"),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' type='unavailable' />"),
expect_stanza("/presence[@type='unavailable'][@from='#foo%{irc_server_one}/{nick_one}']"),
# Join the same channel, with the same JID, but a different resource
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"),
# Join some other channel with someone else
send_stanza("<presence from='{jid_two}/{resource_one}' to='#bar%{irc_server_one}/{nick_two}' />"),
sequences.connection("irc.localhost", '{jid_two}/{resource_one}'),
expect_stanza("/message/body[text()='Mode #bar [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_two}/{resource_one}'][@from='#bar%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#bar%{irc_server_one}'][@type='groupchat'][@to='{jid_two}/{resource_one}']/subject[not(text())]"),
# Send two messages from the second user to the first one
send_stanza("<message from='{jid_two}/{resource_one}' to='{lower_nick_one}%{irc_server_one}' type='chat'><body>kikoo</body></message>"),
send_stanza("<message from='{jid_two}/{resource_one}' to='{lower_nick_one}%{irc_server_one}' type='chat'><body>second kikoo</body></message>"),
# We must receive each message only once, no duplicate
expect_stanza("/message/body[text()='kikoo']"),
expect_stanza("/message/body[text()='second kikoo']"),
)
@@ -0,0 +1,12 @@
from scenarios import *
scenario = (
sequences.handshake(),
send_stanza("<iq type='get' id='get1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><query xmlns='http://jabber.org/protocol/disco#info'/></iq>"),
expect_stanza("/iq[@type='result']/disco_info:query/disco_info:identity[@category='conference'][@type='irc'][@name='Biboumi XMPP-IRC gateway']",
"/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']",
"/iq/disco_info:query/disco_info:feature[@var='http://jabber.org/protocol/commands']",
"/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:ping']",
"/iq/disco_info:query/disco_info:feature[@var='urn:xmpp:mam:2']",
"/iq/disco_info:query/disco_info:feature[@var='jabber:iq:version']"),
)
@@ -0,0 +1,7 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><x xmlns='http://jabber.org/protocol/muc#user'><invite to='{nick_one}'/></x></message>"),
expect_stanza("/message/body[text()='{nick_one} is already on channel #foo']")
)
@@ -0,0 +1,11 @@
from scenarios import *
conf = "fixed_server"
scenario = (
scenarios.simple_channel_join_fixed.scenario,
# Send a ping to ourself
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_ping' to='#foo@{biboumi_host}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
expect_stanza("/iq[@from='#foo@{biboumi_host}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_ping']"),
)
@@ -0,0 +1,15 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send a ping to ourself, in a muc where we’re not
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_ping' to='#nil%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
# Immediately receive an error
expect_stanza("/iq[@from='#nil%{irc_server_one}/{nick_one}'][@type='error'][@to='{jid_one}/{resource_one}'][@id='first_ping']/error/stanza:not-acceptable"),
# Send a ping to ourself, in a muc where we are, but not this resource
send_stanza("<iq type='get' from='{jid_one}/{resource_two}' id='first_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
# Immediately receive an error
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='error'][@to='{jid_one}/{resource_two}'][@id='first_ping']/error/stanza:not-acceptable"),
)
@@ -0,0 +1,23 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send a ping to ourself
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_ping']"),
# Now join the same room, from the same bare JID, behind the same nick
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"),
# And re-send a self ping
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='second_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_ping']"),
## And re-do exactly the same thing, just change the resource initiating the self ping
send_stanza("<iq type='get' from='{jid_one}/{resource_two}' id='third_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_two}'][@id='third_ping']"),
)
@@ -0,0 +1,13 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send a ping to ourself
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_ping']"),
# Send a ping to ourself
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_ping']"),
)
@@ -0,0 +1,39 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send a version request to ourself
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_version' to='#foo%{irc_server_one}/{nick_one}'><query xmlns='jabber:iq:version' /></iq>"),
# We receive our own request,
expect_stanza("/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to='{jid_one}/{resource_one}']",
after = save_value("id", extract_attribute("/iq", 'id'))),
# Respond to the request, and receive our own response
send_stanza("<iq type='result' to='{lower_nick_one}%{irc_server_one}' id='{id}' from='{jid_one}/{resource_one}'><query xmlns='jabber:iq:version'><name>e2e test</name><version>1.0</version><os>Fedora</os></query></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_version']/version:query/version:name[text()='e2e test (through the biboumi gateway) 1.0 Fedora']"),
# Now join the same room, from the same bare JID, behind the same nick
send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"),
# And re-send a self ping
send_stanza("<iq type='get' from='{jid_one}/{resource_two}' id='second_version' to='#foo%{irc_server_one}/{nick_one}'><query xmlns='jabber:iq:version' /></iq>"),
# We receive our own request. Note that we don't know the `to` value, it could be one of our two resources.
expect_stanza("/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to]",
after = (save_value("to", extract_attribute("/iq", "to")),
save_value("id", extract_attribute("/iq", "id")))),
# Respond to the request, using the extracted 'to' value as our 'from'
send_stanza("<iq type='result' to='{lower_nick_one}%{irc_server_one}' id='{id}' from='{to}'><query xmlns='jabber:iq:version'><name>e2e test</name><version>1.0</version><os>Fedora</os></query></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_two}'][@id='second_version']"),
# And do exactly the same thing, but initiated by the other resource
send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='second_version' to='#foo%{irc_server_one}/{nick_one}'><query xmlns='jabber:iq:version' /></iq>"),
expect_stanza("/iq[@from='{lower_nick_one}%{irc_server_one}'][@type='get'][@to]",
after = (save_value("to", extract_attribute("/iq", "to")),
save_value("id", extract_attribute("/iq", "id")))),
# Respond to the request, using the extracted 'to' value as our 'from'
send_stanza("<iq type='result' to='{lower_nick_one}%{irc_server_one}' id='{id}' from='{to}'><query xmlns='jabber:iq:version'><name>e2e test</name><version>1.0</version><os>Fedora</os></query></iq>"),
expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_version']"),
)
@@ -0,0 +1,22 @@
from scenarios import *
def expect_self_join_presence(jid, chan, nick, irc_server="{irc_server_one}"):
return (
expect_stanza("/message/body[text()='Mode " + chan + " [+nt] by irc.localhost']"),
expect_stanza("/presence[@to='" + jid +"'][@from='" + chan + "%" + irc_server + "/" + nick + "']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='100']", # Rooms are all non-anonymous
"/presence/muc_user:x/muc_user:status[@code='110']",
),
expect_stanza("/message[@from='" + chan + "%" + irc_server + "'][@type='groupchat']/subject[not(text())]"),
)
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
sequences.connection(),
expect_self_join_presence(jid = '{jid_one}/{resource_one}', chan = "#foo", nick = "{nick_one}"),
)
@@ -0,0 +1,13 @@
from scenarios import *
conf = "fixed_server"
scenario = (
sequences.handshake(),
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}/{nick_one}' />"),
sequences.connection("irc.localhost", '{jid_one}/{resource_one}', fixed_irc_server=True),
expect_stanza("/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
expect_stanza("/presence[@to='{jid_one}/{resource_one}'][@from='#foo@{biboumi_host}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
"/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@from='#foo@{biboumi_host}'][@type='groupchat']/subject[not(text())]"),
)
@@ -0,0 +1,14 @@
from scenarios import *
scenario = (
scenarios.multiple_channels_join.scenario,
send_stanza("<iq from='{jid_one}/{resource_one}' id='id1' to='{irc_server_one}' type='get'><query xmlns='http://jabber.org/protocol/disco#items'/></iq>"),
expect_stanza("/iq[@type='result']/disco_items:query",
"/iq/disco_items:query/rsm:set/rsm:count[text()='3']",
"/iq/disco_items:query/rsm:set/rsm:first",
"/iq/disco_items:query/rsm:set/rsm:last",
"/iq/disco_items:query/disco_items:item[@jid='#foo%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#bar%{irc_server_one}']",
"/iq/disco_items:query/disco_items:item[@jid='#baz%{irc_server_one}']"),
)
+49
View File
@@ -0,0 +1,49 @@
from scenarios import *
scenario = (
scenarios.channel_join_with_two_users.scenario,
# demonstrate bug https://lab.louiz.org/louiz/biboumi/issues/3291
# First user joins an other channel
send_stanza("<presence from='{jid_one}/{resource_one}' to='#bar%{irc_server_one}/{nick_one}' />"),
expect_stanza("/message"),
expect_stanza("/presence/muc_user:x/muc_user:status[@code='110']"),
expect_stanza("/message[@type='groupchat']/subject"),
# Second user joins
send_stanza("<presence from='{jid_two}/{resource_one}' to='#bar%{irc_server_one}/{nick_two}' />"),
expect_unordered(
["/presence[@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']"],
[
"/presence[@to='{jid_two}/{resource_one}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
["/presence[@to='{jid_two}/{resource_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']"],
["/message/subject"]
),
# Moderator kicks participant
send_stanza("<iq id='kick1' to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set'><query xmlns='http://jabber.org/protocol/muc#admin'><item nick='{nick_two}' role='none'><reason>reported</reason></item></query></iq>"),
expect_unordered(
[
"/presence[@type='unavailable'][@to='{jid_two}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']",
"/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']",
"/presence/muc_user:x/muc_user:status[@code='307']",
"/presence/muc_user:x/muc_user:status[@code='110']"
],
[
"/presence[@type='unavailable'][@to='{jid_one}/{resource_one}']/muc_user:x/muc_user:item[@role='none']/muc_user:actor[@nick='{nick_one}']",
"/presence/muc_user:x/muc_user:item/muc_user:reason[text()='reported']",
"/presence/muc_user:x/muc_user:status[@code='307']",
],
["/iq[@id='kick1'][@type='result']"]
),
# Bug 3291, suite. We must not receive any presence from #foo, here
send_stanza("<message from='{jid_two}/{resource_one}' to='{irc_server_one}' type='chat'><body>QUIT bye bye</body></message>"),
expect_unordered(
["/presence[@from='#bar%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}']"],
["/presence[@from='#bar%{irc_server_one}/{nick_two}'][@to='{jid_two}/{resource_one}']"],
["/message"],
["/message"],
),
)
+60
View File
@@ -0,0 +1,60 @@
from scenarios import *
scenario = (
scenarios.simple_channel_join.scenario,
# Send two channel messages
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"),
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou 2</body></message>"),
expect_stanza("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou 2']"),
# Retrieve the complete archive
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id1'><query xmlns='urn:xmpp:mam:2' queryid='qid1' /></iq>"),
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou']"),
expect_stanza("/message/mam:result[@queryid='qid1']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid1']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou 2']"),
expect_stanza("/iq[@type='result'][@id='id1'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin/rms:set/rsm:last",
"/iq/mam:fin/rsm:set/rsm:first",
"/iq/mam:fin[@complete='true']"),
# Retrieve an empty archive by specifying an early “end” date
send_stanza("""<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id2'>
<query xmlns='urn:xmpp:mam:2' queryid='qid2'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'> <value>urn:xmpp:mam:2</value></field>
<field var='end'><value>2000-06-07T00:00:00Z</value></field>
</x>
</query></iq>"""),
expect_stanza("/iq[@type='result'][@id='id2'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin[@complete='true']/rsm:set"),
# Retrieve an empty archive by specifying a late “start” date
# (note that this test will break in ~1000 years)
send_stanza("""<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id3'>
<query xmlns='urn:xmpp:mam:2' queryid='qid3'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'> <value>urn:xmpp:mam:2</value></field>
<field var='start'><value>3016-06-07T00:00:00Z</value></field>
</x>
</query></iq>"""),
expect_stanza("/iq[@type='result'][@id='id3'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"/iq/mam:fin[@complete='true']/rsm:set"),
# Retrieve the whole archive, but limit the response to one elemet
send_stanza("<iq to='#foo%{irc_server_one}' from='{jid_one}/{resource_one}' type='set' id='id4'><query xmlns='urn:xmpp:mam:2' queryid='qid4'><set xmlns='http://jabber.org/protocol/rsm'><max>1</max></set></query></iq>"),
expect_stanza("/message/mam:result[@queryid='qid4']/forward:forwarded/delay:delay",
"/message/mam:result[@queryid='qid4']/forward:forwarded/client:message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat']/client:body[text()='coucou']"),
expect_stanza("/iq[@type='result'][@id='id4'][@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}']",
"!/iq/mam:fin[@complete='true']/rsm:set"),
)
@@ -0,0 +1,18 @@
from scenarios import *
scenario = (
scenarios.channel_join_with_two_users.scenario,
# Send a channel message
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>/me rit en IRC</body></message>"),
# Receive the message, forwarded to the two users
expect_unordered(
[
"/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='/me rit en IRC']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"
],
[
"/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='/me rit en IRC']",
"/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"
],
),
)
+108
View File
@@ -0,0 +1,108 @@
from functions import expect_stanza, send_stanza, common_replacements
def handshake():
return (
expect_stanza("//handshake"),
send_stanza("<handshake xmlns='jabber:component:accept'/>")
)
def connection_begin(irc_host, jid, expected_irc_presence=False, fixed_irc_server=False):
jid = jid.format_map(common_replacements)
if fixed_irc_server:
xpath = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[text()='%s']"
xpath_re = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[re:test(text(), '%s')]"
else:
xpath = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[text()='%s']"
xpath_re = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[re:test(text(), '%s')]"
result = (
expect_stanza(xpath % ('Connecting to %s:6697 (encrypted)' % irc_host),
"/message/hints:no-copy",
"/message/carbon:private"
),
expect_stanza(xpath % 'Connection failed: Connection refused'),
expect_stanza(xpath % ('Connecting to %s:6670 (encrypted)' % irc_host)),
expect_stanza(xpath % 'Connection failed: Connection refused'),
expect_stanza(xpath % ('Connecting to %s:6667 (not encrypted)' % irc_host)),
expect_stanza(xpath % 'Connected to IRC server.'))
if expected_irc_presence:
result += (expect_stanza("/presence[@from='" + irc_host + "@biboumi.localhost']"),)
# These five messages can be receive in any order
result += (
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % 'irc.localhost')),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % 'irc.localhost')),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % 'irc.localhost')),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % 'irc.localhost')),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % 'irc.localhost')),
)
return result
def connection_tls_begin(irc_host, jid, fixed_irc_server):
jid = jid.format_map(common_replacements)
if fixed_irc_server:
xpath = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[text()='%s']"
xpath_re = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[re:test(text(), '%s')]"
else:
xpath = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[text()='%s']"
xpath_re = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[re:test(text(), '%s')]"
irc_host = 'irc.localhost'
return (
expect_stanza(xpath % ('Connecting to %s:7778 (encrypted)' % irc_host),
"/message/hints:no-copy",
"/message/carbon:private",
),
expect_stanza(xpath % 'Connected to IRC server (encrypted).'),
# These five messages can be receive in any order
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: (\*\*\* Checking Ident|\*\*\* Looking up your hostname\.\.\.|\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* Got Ident response)$' % irc_host)),
)
def connection_end(irc_host, jid, fixed_irc_server=False):
jid = jid.format_map(common_replacements)
if fixed_irc_server:
xpath = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[text()='%s']"
xpath_re = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[re:test(text(), '%s')]"
else:
xpath = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[text()='%s']"
xpath_re = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[re:test(text(), '%s')]"
irc_host = 'irc.localhost'
return (
expect_stanza(xpath_re % (r'^%s: Your host is .*$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: This server was created .*$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: There are \d+ users and \d+ invisible on \d+ servers$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: \d+ unknown connection\(s\)$' % irc_host), optional=True),
expect_stanza(xpath_re % (r'^%s: \d+ channels formed$' % irc_host), optional=True),
expect_stanza(xpath_re % (r'^%s: I have \d+ clients and \d+ servers$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: \d+ \d+ Current local users \d+, max \d+$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: \d+ \d+ Current global users \d+, max \d+$' % irc_host)),
expect_stanza(xpath_re % (r'^%s: Highest connection count: \d+ \(\d+ clients\) \(\d+ connections received\)$' % irc_host)),
expect_stanza(xpath % "- This is charybdis MOTD you might replace it, but if not your friends will\n- laugh at you.\n"),
expect_stanza(xpath_re % r'^User mode for \w+ is \[\+Z?i\]$'),
)
def connection_middle(irc_host, jid, fixed_irc_server=False):
if fixed_irc_server:
xpath_re = "/message[@to='" + jid + "'][@from='biboumi.localhost']/body[re:test(text(), '%s')]"
else:
xpath_re = "/message[@to='" + jid + "'][@from='" + irc_host + "@biboumi.localhost']/body[re:test(text(), '%s')]"
irc_host = 'irc.localhost'
return (
expect_stanza(xpath_re % (r'^%s: \*\*\* You are exempt from flood limits$' % irc_host)),
)
def connection(irc_host="irc.localhost", jid="{jid_one}/{resource_one}", expected_irc_presence=False, fixed_irc_server=False):
return connection_begin(irc_host, jid, expected_irc_presence, fixed_irc_server=fixed_irc_server) + \
connection_middle(irc_host, jid, fixed_irc_server=fixed_irc_server) + \
connection_end(irc_host, jid, fixed_irc_server=fixed_irc_server)
def connection_tls(irc_host="irc.localhost", jid="{jid_one}/{resource_one}", fixed_irc_server=False):
return connection_tls_begin(irc_host, jid, fixed_irc_server) + \
connection_middle(irc_host, jid, fixed_irc_server) +\
connection_end(irc_host, jid, fixed_irc_server)