Files
noitu/server/internal/wsapi/report_test.go
T
tiennm99 f4acc12668 refactor(wsapi): split wsapi_test.go by topic, delete hub_test.go
wsapi_test.go was 2688 lines and 82 tests spanning every topic in the
package. Pure moves: wsapi_test.go keeps the harness (the hand-built
dictionary, the server-over-a-real-socket helpers, and the client-side
driving methods every topic file below uses); game_test.go,
presence_test.go, resume_test.go, lobby_test.go, protocol_test.go,
ratelimit_test.go, bot_board_test.go, chat_test.go, deadend_test.go
and report_test.go each hold one topic's tests. Three tests about
sanitizing and distinguishing nicknames moved into the existing
nickname_test.go alongside its fuzz target.

hub_test.go was three lines of comment pointing at hub.go; the note
now lives there instead, next to roomCount.

Verified by counting: the wsapi package's declaration count is
unchanged, `go test -list` finds the same tests it did before the
split, and go build/vet/test -race and golangci-lint stay clean.
2026-09-21 16:32:57 +07:00

64 lines
2.0 KiB
Go

package wsapi
import (
"fmt"
"testing"
noituv1 "github.com/tiennm99dev/noitu/server/gen/noitu/v1"
)
// Reporting a word the dictionary should have accepted.
// TestReportWordAcceptsAndEchoes needs no room at all: filing a report is a
// session-level fact, which is also what a direct wire client per the README
// would exercise.
func TestReportWordAcceptsAndEchoes(t *testing.T) {
_, url := newTestServer(t, chainDict(), Config{})
c := dial(t, url)
c.hello("Người chơi")
c.reportWord("bình tâm")
got := c.await("word_reported").GetWordReported()
if got.GetWord() != "bình tâm" {
t.Errorf("echoed word = %q, want %q", got.GetWord(), "bình tâm")
}
}
func TestReportWordRefusesOneSyllable(t *testing.T) {
_, url := newTestServer(t, chainDict(), Config{})
c := dial(t, url)
c.hello("Người chơi")
c.reportWord("một")
if code := c.await("error").GetError().GetCode(); code != "word_report_refused" {
t.Errorf("code = %q, want word_report_refused", code)
}
}
// TestReportWordEnforcesPerSessionCap drives the cap directly against the
// session rather than through a real socket: 21 reports through the chat rate
// limiter (chatBurst=5) would be a test of two budgets fighting each other
// rather than of the cap itself.
func TestReportWordEnforcesPerSessionCap(t *testing.T) {
s := offlineSession(t, maxWordReportsPerSession+8)
for i := range maxWordReportsPerSession {
s.handleReportWord(&noituv1.ReportWord{Word: fmt.Sprintf("từ số %d", i)})
}
accepted := queued(t, s)
if len(accepted) != maxWordReportsPerSession {
t.Fatalf("got %d replies for %d distinct reports, want one each", len(accepted), maxWordReportsPerSession)
}
for _, m := range accepted {
if m.GetWordReported() == nil {
t.Errorf("a report inside the cap was refused: %+v", m)
}
}
s.handleReportWord(&noituv1.ReportWord{Word: "một từ khác nữa"})
overflow := queued(t, s)
if len(overflow) != 1 || overflow[0].GetError().GetCode() != "word_report_limit" {
t.Fatalf("the report past the cap = %+v, want a single word_report_limit error", overflow)
}
}