Skip to content

Commit 339392d

Browse files
committed
feat: add uwu top yappers
1 parent 7f90494 commit 339392d

File tree

8 files changed

+453
-13
lines changed

8 files changed

+453
-13
lines changed

ash.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ func (app *App) dispatchBotCommand(evCtx context.Context, ev *event.Event, msgDa
683683

684684
// Run the command in a goroutine to avoid blocking other messages.
685685
go func() {
686-
resp, err := FetchBotCommand(evCtx, &cmdCfg, app.Cfg.LinkstashURL, ev, app.Client, app.Cfg.GroqAPIKey, label)
686+
resp, err := FetchBotCommand(evCtx, &cmdCfg, app.Cfg.LinkstashURL, ev, app.Client, app.Cfg.GroqAPIKey, label, app.MessagesDB)
687687
var body string
688688
if err != nil {
689689
log.Error().Err(err).Str("cmd", cmd).Msg("failed to execute bot command")

ash_test.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
package main
22

33
import (
4+
"context"
5+
"database/sql"
6+
"fmt"
7+
"strings"
48
"testing"
9+
"time"
10+
11+
_ "github.com/mattn/go-sqlite3"
12+
"maunium.net/go/mautrix/event"
13+
"maunium.net/go/mautrix/id"
514
)
615

716
func TestExtractLinks(t *testing.T) {
@@ -289,3 +298,150 @@ func splitLines(s string) []string {
289298
}
290299
return lines
291300
}
301+
302+
func TestUwuify(t *testing.T) {
303+
tests := []struct {
304+
name string
305+
input string
306+
check func(string) bool
307+
desc string
308+
}{
309+
{
310+
"replaces r/l with w",
311+
"really cool",
312+
func(s string) bool { return strings.Contains(s, "w") },
313+
"should replace r and l with w",
314+
},
315+
{
316+
"replaces th with d",
317+
"the weather",
318+
func(s string) bool { return strings.Contains(s, "da") && strings.Contains(s, "wead") },
319+
"should replace 'the ' with 'da ' and 'th' with 'd'",
320+
},
321+
{
322+
"replaces love with wuv",
323+
"I love you",
324+
func(s string) bool { return strings.Contains(s, "wuv") },
325+
"should replace love with wuv",
326+
},
327+
{
328+
"appends kaomoji",
329+
"hello world",
330+
func(s string) bool {
331+
faces := []string{"uwu", "owo", ">w<", "^w^", "◕ᴗ◕✿", "✧w✧", "~nyaa"}
332+
for _, f := range faces {
333+
if strings.HasSuffix(s, f) {
334+
return true
335+
}
336+
}
337+
return false
338+
},
339+
"should end with a kaomoji",
340+
},
341+
}
342+
for _, tt := range tests {
343+
t.Run(tt.name, func(t *testing.T) {
344+
got := uwuify(tt.input)
345+
if !tt.check(got) {
346+
t.Errorf("uwuify(%q) = %q: %s", tt.input, got, tt.desc)
347+
}
348+
})
349+
}
350+
}
351+
352+
func TestQueryTopYappers(t *testing.T) {
353+
db, err := sql.Open("sqlite3", ":memory:")
354+
if err != nil {
355+
t.Fatalf("open db: %v", err)
356+
}
357+
defer db.Close()
358+
359+
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS messages (
360+
id TEXT PRIMARY KEY,
361+
room_id TEXT,
362+
sender TEXT,
363+
ts_ms INTEGER,
364+
body TEXT,
365+
msgtype TEXT,
366+
raw_json TEXT
367+
)`)
368+
if err != nil {
369+
t.Fatalf("create table: %v", err)
370+
}
371+
372+
now := time.Now().UnixMilli()
373+
room := "!testroom:example.com"
374+
375+
// Insert test messages: alice=5, bob=3, carol=1, plus some bot messages that should be excluded.
376+
for i := 0; i < 5; i++ {
377+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
378+
fmt.Sprintf("alice-%d", i), room, "@alice:example.com", now-int64(i*1000), fmt.Sprintf("hello %d", i), "m.text")
379+
}
380+
for i := 0; i < 3; i++ {
381+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
382+
fmt.Sprintf("bob-%d", i), room, "@bob:example.com", now-int64(i*1000), fmt.Sprintf("hey %d", i), "m.text")
383+
}
384+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
385+
"carol-0", room, "@carol:example.com", now, "sup", "m.text")
386+
387+
// Bot messages — should be excluded.
388+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
389+
"bot-1", room, "@bot:example.com", now, "[BOT] hello", "m.text")
390+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
391+
"bot-2", room, "@bot:example.com", now, "/bot help", "m.text")
392+
393+
// Old message — should be excluded (>24h ago).
394+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
395+
"old-1", room, "@old:example.com", now-100000000, "ancient msg", "m.text")
396+
397+
// Different room — should be excluded.
398+
_, _ = db.Exec(`INSERT INTO messages(id, room_id, sender, ts_ms, body, msgtype) VALUES (?, ?, ?, ?, ?, ?)`,
399+
"other-1", "!otherroom:example.com", "@other:example.com", now, "wrong room", "m.text")
400+
401+
ev := &event.Event{
402+
RoomID: id.RoomID(room),
403+
}
404+
405+
ctx := context.Background()
406+
407+
// Test default (top 5).
408+
result, err := queryTopYappers(ctx, db, nil, ev, "", "", false)
409+
if err != nil {
410+
t.Fatalf("queryTopYappers: %v", err)
411+
}
412+
if !strings.Contains(result, "alice") {
413+
t.Errorf("expected alice in result, got: %s", result)
414+
}
415+
if !strings.Contains(result, "5 msgs") {
416+
t.Errorf("expected '5 msgs' for alice, got: %s", result)
417+
}
418+
if !strings.Contains(result, "bob") {
419+
t.Errorf("expected bob in result, got: %s", result)
420+
}
421+
// alice should be ranked #1.
422+
if !strings.Contains(result, "1. alice") {
423+
t.Errorf("expected alice at rank 1, got: %s", result)
424+
}
425+
426+
// Test with limit.
427+
result2, err := queryTopYappers(ctx, db, nil, ev, "2", "", false)
428+
if err != nil {
429+
t.Fatalf("queryTopYappers with limit: %v", err)
430+
}
431+
lines := strings.Split(strings.TrimSpace(result2), "\n")
432+
// Header line + 2 results.
433+
if len(lines) != 3 {
434+
t.Errorf("expected 3 lines (header + 2 results), got %d: %s", len(lines), result2)
435+
}
436+
437+
// Bot and old messages should not appear.
438+
if strings.Contains(result, "bot") {
439+
t.Errorf("bot messages should be excluded, got: %s", result)
440+
}
441+
if strings.Contains(result, "old") {
442+
t.Errorf("old messages should be excluded, got: %s", result)
443+
}
444+
if strings.Contains(result, "other") {
445+
t.Errorf("messages from other rooms should be excluded, got: %s", result)
446+
}
447+
}

0 commit comments

Comments
 (0)