diff --git a/docs/changelog/v0.2.17.md b/docs/changelog/v0.2.17.md index a6afbbc..c81331b 100644 --- a/docs/changelog/v0.2.17.md +++ b/docs/changelog/v0.2.17.md @@ -6,4 +6,4 @@ ## Bug Fixes -- **IRC multi-line messages** — sending a message with line breaks from the TUI now correctly delivers each line as a separate PRIVMSG to IRC clients. Previously newlines were embedded raw in the IRC frame, which could create invalid messages. +- **IRC multi-line messages** — sending a message with line breaks from the TUI now correctly delivers each line as a separate PRIVMSG to IRC clients. Previously newlines were embedded raw in the IRC frame, so IRC clients silently dropped everything after the first line — most visibly, a link on its own line disappeared while its embed preview still showed. diff --git a/src/EchoHub.Tests/Irc/IrcMessageFormatterTests.cs b/src/EchoHub.Tests/Irc/IrcMessageFormatterTests.cs index c393397..5a44d86 100644 --- a/src/EchoHub.Tests/Irc/IrcMessageFormatterTests.cs +++ b/src/EchoHub.Tests/Irc/IrcMessageFormatterTests.cs @@ -242,6 +242,36 @@ public class IrcMessageFormatterTests Assert.Equal("", chunks[0]); } + [Fact] + public void FormatMessage_UrlOnOwnLine_EmitsUrlAsItsOwnPrivmsg() + { + // Regression: multi-line content used to go out as ONE line with a raw \n + // embedded. IRC clients drop everything after the newline as a malformed + // frame, so a URL on its own line silently vanished while the embed lines + // (separate, valid PRIVMSGs) still rendered. + var embeds = new List + { + new("Example Site", "Page Title", "Description", null, "https://example.com") + }; + var msg = CreateTextMessage("check this out\nhttps://example.com", embeds: embeds); + var lines = IrcMessageFormatter.FormatMessage(msg); + + Assert.Contains(lines, l => l.EndsWith("PRIVMSG #general :check this out")); + Assert.Contains(lines, l => l.EndsWith("PRIVMSG #general :https://example.com")); + Assert.All(lines, l => Assert.DoesNotContain('\n', l)); + Assert.All(lines, l => Assert.DoesNotContain('\r', l)); + } + + [Fact] + public void SplitMessage_MultiLineContent_SplitsOnNewlines() + { + var chunks = IrcMessageFormatter.SplitMessage("line one\nhttps://example.com/page", 400); + + Assert.Equal(2, chunks.Count); + Assert.Equal("line one", chunks[0]); + Assert.Equal("https://example.com/page", chunks[1]); + } + [Fact] public void SplitMessage_UnicodeContent_CountsUtf8Bytes() {