irssi (and other IRC clients) only open a channel window when they see a JOIN from their own nick. The synthetic JOINs were using the network nick (e.g. pagumowa) but the client registered as tester -- mismatch. Three changes: - Synthetic JOIN prefix is now client_nick!user@bouncer - 001 welcome uses the client's registered nick - encode_nick/encode_message accept client_nick param to rewrite own nicks from any network to the client's nick, so irssi recognizes all self-actions consistently Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
169 lines
5.3 KiB
Python
169 lines
5.3 KiB
Python
"""Tests for network namespace encoding/decoding."""
|
|
|
|
from bouncer.irc import IRCMessage
|
|
from bouncer.namespace import (
|
|
decode_channel,
|
|
decode_target,
|
|
encode_channel,
|
|
encode_message,
|
|
encode_nick,
|
|
encode_prefix,
|
|
)
|
|
|
|
OWN = {"libera": "mybot", "oftc": "mybot2"}
|
|
|
|
|
|
class TestEncodeChannel:
|
|
def test_basic(self):
|
|
assert encode_channel("#libera", "libera") == "#libera/libera"
|
|
|
|
def test_preserves_prefix(self):
|
|
assert encode_channel("&local", "net") == "&local/net"
|
|
|
|
|
|
class TestDecodeChannel:
|
|
def test_basic(self):
|
|
assert decode_channel("#libera/libera") == ("#libera", "libera")
|
|
|
|
def test_no_separator(self):
|
|
assert decode_channel("#libera") == ("#libera", None)
|
|
|
|
def test_channel_with_slash_in_name(self):
|
|
# Edge: channel name itself contains slash -- rfind picks the last one
|
|
assert decode_channel("#a/b/net") == ("#a/b", "net")
|
|
|
|
|
|
class TestEncodeNick:
|
|
def test_foreign_nick(self):
|
|
assert encode_nick("user123", "libera", OWN) == "user123/libera"
|
|
|
|
def test_own_nick_bare(self):
|
|
assert encode_nick("mybot", "libera", OWN) == "mybot"
|
|
|
|
def test_own_nick_other_network(self):
|
|
# Own nick on another network still shown bare
|
|
assert encode_nick("mybot2", "libera", OWN) == "mybot2"
|
|
|
|
def test_own_nick_rewritten_to_client_nick(self):
|
|
assert encode_nick("mybot", "libera", OWN, client_nick="tester") == "tester"
|
|
|
|
def test_foreign_nick_unaffected_by_client_nick(self):
|
|
assert encode_nick("user123", "libera", OWN, client_nick="tester") == "user123/libera"
|
|
|
|
|
|
class TestEncodePrefix:
|
|
def test_full_prefix(self):
|
|
result = encode_prefix("user!ident@host", "libera", OWN)
|
|
assert result == "user/libera!ident@host"
|
|
|
|
def test_own_prefix(self):
|
|
result = encode_prefix("mybot!ident@host", "libera", OWN)
|
|
assert result == "mybot!ident@host"
|
|
|
|
def test_nick_only(self):
|
|
result = encode_prefix("server.example.com", "libera", OWN)
|
|
assert result == "server.example.com/libera"
|
|
|
|
|
|
class TestDecodeTarget:
|
|
def test_channel(self):
|
|
assert decode_target("#libera/libera") == ("#libera", "libera")
|
|
|
|
def test_nick(self):
|
|
assert decode_target("user123/libera") == ("user123", "libera")
|
|
|
|
def test_bare(self):
|
|
assert decode_target("#libera") == ("#libera", None)
|
|
|
|
|
|
class TestEncodeMessage:
|
|
def test_privmsg_channel(self):
|
|
msg = IRCMessage(
|
|
command="PRIVMSG",
|
|
params=["#test", "hello"],
|
|
prefix="user!ident@host",
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
assert out.params[0] == "#test/libera"
|
|
assert out.prefix == "user/libera!ident@host"
|
|
|
|
def test_privmsg_own_prefix(self):
|
|
msg = IRCMessage(
|
|
command="PRIVMSG",
|
|
params=["#test", "hello"],
|
|
prefix="mybot!ident@host",
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
assert out.prefix == "mybot!ident@host"
|
|
|
|
def test_namreply(self):
|
|
msg = IRCMessage(
|
|
command="353",
|
|
params=["mybot", "=", "#test", "@op +voice regular mybot"],
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
assert out.params[2] == "#test/libera"
|
|
names = out.params[3].split()
|
|
assert names[0] == "@op/libera"
|
|
assert names[1] == "+voice/libera"
|
|
assert names[2] == "regular/libera"
|
|
assert names[3] == "mybot" # own nick stays bare
|
|
|
|
def test_nick_change(self):
|
|
msg = IRCMessage(
|
|
command="NICK",
|
|
params=["newnick"],
|
|
prefix="oldnick!user@host",
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
assert out.params[0] == "newnick/libera"
|
|
assert out.prefix == "oldnick/libera!user@host"
|
|
|
|
def test_join(self):
|
|
msg = IRCMessage(
|
|
command="JOIN",
|
|
params=["#test"],
|
|
prefix="user!ident@host",
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
assert out.params[0] == "#test/libera"
|
|
|
|
def test_non_channel_target_untouched(self):
|
|
msg = IRCMessage(
|
|
command="PRIVMSG",
|
|
params=["someuser", "hi"],
|
|
prefix="other!ident@host",
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
# Private message to a nick -- params[0] is not a channel, left as-is
|
|
assert out.params[0] == "someuser"
|
|
|
|
def test_no_raw_preserved(self):
|
|
msg = IRCMessage(
|
|
command="PRIVMSG",
|
|
params=["#test", "hello"],
|
|
prefix="user!ident@host",
|
|
raw=b":user!ident@host PRIVMSG #test :hello\r\n",
|
|
)
|
|
out = encode_message(msg, "libera", OWN)
|
|
assert out.raw is None # raw must not carry over
|
|
|
|
def test_own_prefix_rewritten_to_client_nick(self):
|
|
msg = IRCMessage(
|
|
command="PRIVMSG",
|
|
params=["#test", "hello"],
|
|
prefix="mybot!ident@host",
|
|
)
|
|
out = encode_message(msg, "libera", OWN, client_nick="tester")
|
|
assert out.prefix == "tester!ident@host"
|
|
|
|
def test_namreply_own_nick_rewritten(self):
|
|
msg = IRCMessage(
|
|
command="353",
|
|
params=["mybot", "=", "#test", "@op mybot"],
|
|
)
|
|
out = encode_message(msg, "libera", OWN, client_nick="tester")
|
|
names = out.params[3].split()
|
|
assert names[0] == "@op/libera"
|
|
assert names[1] == "tester"
|