Show an IRC listener user what their session sends from other clients (closes #179)
check / check (push) Waiting to run
check / check (push) Waiting to run
The IRC listener's relay dropped every line sent under the connection's own nick, so a user on the web client and an IRC client at once never saw on IRC what they did from the web client. The relay now drops nothing by nick. Instead the fan-out skips only the sending client's own queue: the IRC listener passes its own client, whose handler already wrote the echo, and the HTTP API skips none. Channel messages and PARTs now reach the sender's other clients, so an HTTP client gets its own PART event; neoirc-cli ignores it, as it already shows its own part. README.md names the commands covered. Judgement call: a PRIVMSG or NOTICE sent on an IRC connection is not echoed back to it, as in IRC. Model: opus-5-5
This commit was merged in pull request #183.
This commit is contained in:
+7
-3
@@ -757,7 +757,7 @@ func (a *App) handleServerMessage(msg *api.Message) {
|
||||
case irc.CmdJoin:
|
||||
a.handleJoinEvent(msg, timestamp)
|
||||
case irc.CmdPart:
|
||||
a.handlePartEvent(msg, timestamp)
|
||||
a.handlePartEvent(msg, timestamp, myNick)
|
||||
case irc.CmdQuit:
|
||||
a.handleQuitEvent(msg, timestamp)
|
||||
case irc.CmdNick:
|
||||
@@ -813,10 +813,14 @@ func (a *App) handleJoinEvent(
|
||||
))
|
||||
}
|
||||
|
||||
// handlePartEvent shows another user's part. The server
|
||||
// also sends the user's own part back to it, which cmdPart
|
||||
// has already shown; showing it again would add a second
|
||||
// line and mark the channel just left as unread.
|
||||
func (a *App) handlePartEvent(
|
||||
msg *api.Message, timestamp string,
|
||||
msg *api.Message, timestamp, myNick string,
|
||||
) {
|
||||
if msg.To == "" {
|
||||
if msg.To == "" || msg.From == myNick {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ package cli
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
api "sneak.berlin/go/neoirc/internal/cli/api"
|
||||
"sneak.berlin/go/neoirc/pkg/irc"
|
||||
)
|
||||
|
||||
func TestMemberPrefix(t *testing.T) {
|
||||
@@ -49,3 +51,66 @@ func TestMemberPrefix(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPartEvent checks that a PART event adds a line to the
|
||||
// channel's buffer and marks it unread, except for the
|
||||
// user's own part, which cmdPart has already shown.
|
||||
func TestPartEvent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
from string
|
||||
wantLines int
|
||||
wantUnread int
|
||||
}{
|
||||
{name: "own part", from: "erin", wantLines: 0, wantUnread: 0},
|
||||
{name: "other member", from: "bob", wantLines: 1, wantUnread: 1},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app := &App{ui: NewUI(), nick: "erin"}
|
||||
runUI(t, app.ui)
|
||||
|
||||
app.handleServerMessage(&api.Message{
|
||||
Command: irc.CmdPart, From: test.from, To: "#chan",
|
||||
})
|
||||
|
||||
var lines, unread int
|
||||
|
||||
app.ui.app.QueueUpdate(func() {
|
||||
buf := app.ui.getOrCreateBuffer("#chan")
|
||||
lines = len(buf.Lines)
|
||||
unread = buf.Unread
|
||||
})
|
||||
|
||||
if lines != test.wantLines || unread != test.wantUnread {
|
||||
t.Fatalf("got %d lines and %d unread, want %d and %d",
|
||||
lines, unread, test.wantLines, test.wantUnread)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// runUI runs ui on a simulated screen until the test ends.
|
||||
func runUI(t *testing.T, ui *UI) {
|
||||
t.Helper()
|
||||
|
||||
ui.app.SetScreen(tcell.NewSimulationScreen(""))
|
||||
|
||||
done := make(chan error)
|
||||
|
||||
go func() { done <- ui.Run() }()
|
||||
|
||||
t.Cleanup(func() {
|
||||
ui.Stop()
|
||||
|
||||
err := <-done
|
||||
if err != nil {
|
||||
t.Errorf("run ui: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user