Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7360b449d |
No files matched your search
@@ -268,15 +268,12 @@ rules). Case-sensitive comparison is unambiguous.
|
|||||||
A single user session can have multiple clients (phone, laptop, terminal).
|
A single user session can have multiple clients (phone, laptop, terminal).
|
||||||
|
|
||||||
- Each client gets a **separate server-to-client (S2C) message queue**.
|
- Each client gets a **separate server-to-client (S2C) message queue**.
|
||||||
- The server fans out messages and events from other users to every client queue
|
- The server fans out messages and events from other users, and those the user
|
||||||
for that user session.
|
sends from any of its clients, to every client queue for that user session.
|
||||||
- When the user sends a `PRIVMSG`, `NOTICE`, `JOIN`, `PART`, `NICK`, `TOPIC`,
|
The one exception is an IRC listener connection, which gets nothing queued for
|
||||||
`MODE` or `KICK` from one of its clients, the resulting event goes to every
|
a command it sent itself: it has already sent its user the echo, or, for
|
||||||
client queue of the user's own session, as well as to the other users it is
|
`PRIVMSG` and `NOTICE`, IRC sends none. Replies to a command (numerics) go
|
||||||
meant for. The one exception is an IRC listener connection that sent the
|
only to the client that sent it.
|
||||||
command, which gets nothing queued for it: it has already sent its user the
|
|
||||||
echo, or, for `PRIVMSG` and `NOTICE`, IRC sends none.
|
|
||||||
- Replies to a command (numerics) go only to the client that sent it.
|
|
||||||
- `GET /api/v1/messages` delivers from the calling client's specific queue,
|
- `GET /api/v1/messages` delivers from the calling client's specific queue,
|
||||||
identified by the auth cookie.
|
identified by the auth cookie.
|
||||||
- Client queues have **independent expiry/pruning** — one client going offline
|
- Client queues have **independent expiry/pruning** — one client going offline
|
||||||
@@ -749,7 +746,7 @@ Leave a channel.
|
|||||||
{"command": "PART", "to": "#general", "body": ["goodbye"]}
|
{"command": "PART", "to": "#general", "body": ["goodbye"]}
|
||||||
```
|
```
|
||||||
|
|
||||||
**S2C (broadcast to all channel members, including the departing user):**
|
**S2C (broadcast to the other channel members):**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-7
@@ -757,7 +757,7 @@ func (a *App) handleServerMessage(msg *api.Message) {
|
|||||||
case irc.CmdJoin:
|
case irc.CmdJoin:
|
||||||
a.handleJoinEvent(msg, timestamp)
|
a.handleJoinEvent(msg, timestamp)
|
||||||
case irc.CmdPart:
|
case irc.CmdPart:
|
||||||
a.handlePartEvent(msg, timestamp, myNick)
|
a.handlePartEvent(msg, timestamp)
|
||||||
case irc.CmdQuit:
|
case irc.CmdQuit:
|
||||||
a.handleQuitEvent(msg, timestamp)
|
a.handleQuitEvent(msg, timestamp)
|
||||||
case irc.CmdNick:
|
case irc.CmdNick:
|
||||||
@@ -813,14 +813,10 @@ 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(
|
func (a *App) handlePartEvent(
|
||||||
msg *api.Message, timestamp, myNick string,
|
msg *api.Message, timestamp string,
|
||||||
) {
|
) {
|
||||||
if msg.To == "" || msg.From == myNick {
|
if msg.To == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ package cli
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
|
||||||
api "sneak.berlin/go/neoirc/internal/cli/api"
|
api "sneak.berlin/go/neoirc/internal/cli/api"
|
||||||
"sneak.berlin/go/neoirc/pkg/irc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMemberPrefix(t *testing.T) {
|
func TestMemberPrefix(t *testing.T) {
|
||||||
@@ -51,66 +49,3 @@ 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: "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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user