ollie/cmd/olliesrv/internal/session/session_test.go

162 lines
3.5 KiB
Go

package session
import (
"context"
"fmt"
"os"
"testing"
"time"
)
func TestSetCwd_ExpandsTilde(t *testing.T) {
home, err := os.UserHomeDir()
if err != nil || home == "" {
t.Skip("cannot determine home directory")
}
s := &Session{}
s.SetCwd("~/projects")
want := home + "/projects"
if got := s.Cwd(); got != want {
t.Errorf("SetCwd(~/projects): got %q, want %q", got, want)
}
}
func TestSetCwd_ExpandsEnvVars(t *testing.T) {
t.Setenv("OLLIE_TEST_DIR", "/tmp/testdir")
s := &Session{}
s.SetCwd("$OLLIE_TEST_DIR/sub")
want := "/tmp/testdir/sub"
if got := s.Cwd(); got != want {
t.Errorf("SetCwd($OLLIE_TEST_DIR/sub): got %q, want %q", got, want)
}
}
func TestSetCwd_AbsolutePathUnchanged(t *testing.T) {
s := &Session{}
s.SetCwd("/usr/local/bin")
want := "/usr/local/bin"
if got := s.Cwd(); got != want {
t.Errorf("SetCwd(/usr/local/bin): got %q, want %q", got, want)
}
}
func TestEventSubscription(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := SubscribeEvents(ctx)
// Give subscription time to register
time.Sleep(10 * time.Millisecond)
// Publish events
for i := 0; i < 5; i++ {
PublishEvent(fmt.Sprintf("test.event.%d", i), fmt.Sprintf("payload%d", i))
}
// Collect events
timeout := time.After(1 * time.Second)
var received []Event
for {
select {
case ev := <-ch:
received = append(received, ev)
if len(received) >= 5 {
goto done
}
case <-timeout:
goto done
}
}
done:
if len(received) < 5 {
t.Errorf("Expected 5 events, got %d", len(received))
for i, ev := range received {
t.Logf(" [%d] topic=%s payload=%s", i, ev.Topic, ev.Payload)
}
}
}
func TestEventSubscriptionFiltered(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := SubscribeEventsFiltered(ctx, "*")
// Give subscription time to register
time.Sleep(10 * time.Millisecond)
// Publish events
for i := 0; i < 5; i++ {
PublishEvent(fmt.Sprintf("test.event.%d", i), fmt.Sprintf("payload%d", i))
}
// Collect events
timeout := time.After(1 * time.Second)
var received []Event
for {
select {
case ev := <-ch:
received = append(received, ev)
if len(received) >= 5 {
goto done
}
case <-timeout:
goto done
}
}
done:
if len(received) < 5 {
t.Errorf("Expected 5 events, got %d", len(received))
for i, ev := range received {
t.Logf(" [%d] topic=%s payload=%s", i, ev.Topic, ev.Payload)
}
}
}
func TestEventSubscriptionRapidFire(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := SubscribeEventsFiltered(ctx, "*")
// Give subscription time to register
time.Sleep(50 * time.Millisecond)
// Rapid-fire publish (simulating state changes during a turn)
states := []string{"thinking", "calling: shell", "thinking", "calling: file_read", "thinking", "idle"}
for _, state := range states {
PublishEvent("session.abc.agent.xyz.state", state)
}
// Collect events
timeout := time.After(2 * time.Second)
var received []Event
for {
select {
case ev := <-ch:
received = append(received, ev)
t.Logf("Received: topic=%s payload=%s", ev.Topic, ev.Payload)
if len(received) >= len(states) {
goto done
}
case <-timeout:
goto done
}
}
done:
if len(received) != len(states) {
t.Errorf("Expected %d events, got %d", len(states), len(received))
}
for i, ev := range received {
if i < len(states) && ev.Payload != states[i] {
t.Errorf("Event %d: expected payload %q, got %q", i, states[i], ev.Payload)
}
}
}