check / check (push) Waiting to run
The relay dropped every PRIVMSG, NOTICE, JOIN, PART, NICK, QUIT, TOPIC, MODE and KICK sent under the connection's own nick, so an IRC listener connection never saw what its session did from another client. The relay now drops nothing by nick. Instead, the service methods that fan out a user's own command take the client whose queue to skip: the IRC listener passes its own client, which has already written the echo, and the HTTP API passes 0. Channel messages and PARTs now also go to the sender's own session, so the HTTP handler no longer queues the channel-message echo itself, SendChannelMessage no longer returns the message's row ID, and neoirc-cli ignores the PART event for its own part, which it has already shown. Model: opus-5-5
117 lines
2.3 KiB
Go
117 lines
2.3 KiB
Go
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) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
member api.Member
|
|
want string
|
|
}{
|
|
{
|
|
name: "operator",
|
|
member: api.Member{Nick: "alice", IsOperator: true},
|
|
want: "@",
|
|
},
|
|
{
|
|
name: "voiced member",
|
|
member: api.Member{Nick: "bob", IsVoiced: true},
|
|
want: "+",
|
|
},
|
|
{
|
|
name: "voiced operator",
|
|
member: api.Member{
|
|
Nick: "Carol", IsOperator: true, IsVoiced: true,
|
|
},
|
|
want: "@",
|
|
},
|
|
{
|
|
name: "plain member",
|
|
member: api.Member{Nick: "dave"},
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := memberPrefix(test.member)
|
|
if got != test.want {
|
|
t.Fatalf("got %q, want %q", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// 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: "alice", 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: "alice"}
|
|
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)
|
|
}
|
|
})
|
|
}
|