ScuttleBot

scuttlebot / cmd / gemini-relay / main_test.go
Blame History Raw 129 lines
1
package main
2
3
import (
4
"bytes"
5
"path/filepath"
6
"testing"
7
"time"
8
9
"github.com/conflicthq/scuttlebot/pkg/sessionrelay"
10
)
11
12
func TestFilterMessages(t *testing.T) {
13
now := time.Now()
14
nick := "gemini-test"
15
messages := []message{
16
{Nick: "operator", Text: "gemini-test: hello", At: now},
17
{Nick: "gemini-test", Text: "i am gemini", At: now}, // self
18
{Nick: "other", Text: "not for me", At: now}, // no mention
19
{Nick: "bridge", Text: "system message", At: now}, // service bot
20
}
21
22
filtered, _ := filterMessages(messages, now.Add(-time.Minute), nick, "worker")
23
if len(filtered) != 1 {
24
t.Errorf("expected 1 filtered message, got %d", len(filtered))
25
}
26
if filtered[0].Nick != "operator" {
27
t.Errorf("expected operator message, got %s", filtered[0].Nick)
28
}
29
}
30
31
func TestLoadConfig(t *testing.T) {
32
t.Setenv("SCUTTLEBOT_CONFIG_FILE", filepath.Join(t.TempDir(), "scuttlebot-relay.env"))
33
t.Setenv("SCUTTLEBOT_URL", "http://test:8080")
34
t.Setenv("SCUTTLEBOT_TOKEN", "test-token")
35
t.Setenv("GEMINI_SESSION_ID", "abc")
36
t.Setenv("SCUTTLEBOT_TRANSPORT", "irc")
37
t.Setenv("SCUTTLEBOT_IRC_ADDR", "127.0.0.1:7667")
38
t.Setenv("SCUTTLEBOT_SESSION_ID", "")
39
t.Setenv("SCUTTLEBOT_NICK", "")
40
41
cfg, err := loadConfig([]string{"--cd", "../.."})
42
if err != nil {
43
t.Fatal(err)
44
}
45
46
if cfg.URL != "http://test:8080" {
47
t.Errorf("expected URL http://test:8080, got %s", cfg.URL)
48
}
49
if cfg.Token != "test-token" {
50
t.Errorf("expected token test-token, got %s", cfg.Token)
51
}
52
if cfg.SessionID != "abc" {
53
t.Errorf("expected session ID abc, got %s", cfg.SessionID)
54
}
55
if cfg.Nick != "gemini-scuttlebot-abc" {
56
t.Errorf("expected nick gemini-scuttlebot-abc, got %s", cfg.Nick)
57
}
58
if cfg.Transport != sessionrelay.TransportIRC {
59
t.Errorf("expected transport irc, got %s", cfg.Transport)
60
}
61
if cfg.IRCAddr != "127.0.0.1:7667" {
62
t.Errorf("expected irc addr 127.0.0.1:7667, got %s", cfg.IRCAddr)
63
}
64
}
65
66
func TestRelayStateShouldInterruptOnlyWhenRecentlyBusy(t *testing.T) {
67
t.Helper()
68
69
var state relayState
70
now := time.Date(2026, 3, 31, 21, 47, 0, 0, time.UTC)
71
state.observeOutput([]byte("Working (1s • esc to interrupt)"), now)
72
73
if !state.shouldInterrupt(now.Add(defaultBusyWindow / 2)) {
74
t.Fatal("shouldInterrupt = false, want true for recent busy session")
75
}
76
if state.shouldInterrupt(now.Add(defaultBusyWindow + time.Millisecond)) {
77
t.Fatal("shouldInterrupt = true, want false after busy window expires")
78
}
79
}
80
81
func TestInjectMessagesIdleSkipsCtrlCAndSubmits(t *testing.T) {
82
t.Helper()
83
84
var writer bytes.Buffer
85
cfg := config{
86
Nick: "gemini-scuttlebot-1234",
87
InterruptOnMessage: true,
88
}
89
state := &relayState{}
90
batch := []message{{
91
Nick: "glengoolie",
92
Text: "gemini-scuttlebot-1234: check README.md",
93
}}
94
95
if err := injectMessages(&writer, cfg, state, "#general", batch); err != nil {
96
t.Fatal(err)
97
}
98
99
want := bracketedPasteStart + "[IRC operator messages]\n[general] glengoolie: check README.md\n" + bracketedPasteEnd + "\r"
100
if writer.String() != want {
101
t.Fatalf("injectMessages idle = %q, want %q", writer.String(), want)
102
}
103
}
104
105
func TestInjectMessagesBusySendsCtrlCBeforeSubmit(t *testing.T) {
106
t.Helper()
107
108
var writer bytes.Buffer
109
cfg := config{
110
Nick: "gemini-scuttlebot-1234",
111
InterruptOnMessage: true,
112
}
113
state := &relayState{}
114
state.observeOutput([]byte("Working (2s • esc to interrupt)"), time.Now())
115
batch := []message{{
116
Nick: "glengoolie",
117
Text: "gemini-scuttlebot-1234: stop and re-read bridge.go",
118
}}
119
120
if err := injectMessages(&writer, cfg, state, "#general", batch); err != nil {
121
t.Fatal(err)
122
}
123
124
want := string([]byte{3}) + bracketedPasteStart + "[IRC operator messages]\n[general] glengoolie: stop and re-read bridge.go\n" + bracketedPasteEnd + "\r"
125
if writer.String() != want {
126
t.Fatalf("injectMessages busy = %q, want %q", writer.String(), want)
127
}
128
}
129

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button