Files
Maven/internal/dialogue/session_test.go
T
kami da60c14399 chore: docker, config, delivery sinks, dialogue, and agent docs
- Dockerfile: multi-stage build with CGO_ENABLED=0, embedder model copy,
  non-root user, healthcheck, and /data volume.
- docker-compose.yml: mavend + mavweb services with shared volume, health
  checks, and restart policy.
- .gitignore: ignore models/llm/*.gguf, deploy/telegram.env, tmp artifacts.
- deploy/mavend.json: add LLM, phraser, voice sections (embedder, model
  paths, wake sensitivity). Add telegram token env-var expansion.
- deploy/telegram.env.example: template for telegram bot token.
- internal/config/config.go: add LLM config struct, voice config struct
  (embedder, llama, wake sensitivity), telegram token loading.
- telegramsink: add chat intent delivery support alongside existing types.
- voicesink: skip empty payloads in delivery.
- dialogue/session: add chat intent to anaphora resolution, test coverage.
- AGENTS.md: update with LLM embedder, LFM model download/configure steps,
  new UI conventions.
- REARCH.md: architecture research document.
- cmd/mavend/main.go: wire LLM config, phraser, embedder, telegram config,
  WebAuthn, IPC event/routine handlers, and reactive notes.
2026-07-10 15:49:27 +04:00

117 lines
3.4 KiB
Go

package dialogue
import (
"testing"
"time"
)
func TestSessionExpiry(t *testing.T) {
now := time.Date(2026, 7, 6, 12, 0, 0, 0, time.UTC)
sess := &Session{
Intent: IntentQuery,
Timestamp: now,
TTL: 2 * time.Minute,
}
if sess.IsExpired(now) {
t.Error("session should not be expired at creation time")
}
if sess.IsExpired(now.Add(1 * time.Minute)) {
t.Error("session should not be expired after 1 minute")
}
if !sess.IsExpired(now.Add(3 * time.Minute)) {
t.Error("session should be expired after 3 minutes")
}
}
func TestSessionStorePutGet(t *testing.T) {
now := time.Date(2026, 7, 6, 12, 0, 0, 0, time.UTC)
store := NewSessionStore(2 * time.Minute)
if s := store.Get("nonexistent", now); s != nil {
t.Error("expected nil for non-existent session")
}
sess := &Session{Intent: IntentQuery, Timestamp: now}
store.Put("user1", sess)
got := store.Get("user1", now)
if got == nil {
t.Fatal("expected session after Put")
}
if got.Intent != IntentQuery {
t.Errorf("intent = %q, want query", got.Intent)
}
later := now.Add(5 * time.Minute)
if s := store.Get("user1", later); s != nil {
t.Error("expected nil for expired session")
}
}
func TestSessionStoreDefaultTTL(t *testing.T) {
store := NewSessionStore(0)
if store.defaultTTL != 2*time.Minute {
t.Errorf("defaultTTL = %v, want 2m", store.defaultTTL)
}
}
func TestSessionStoreCustomTTL(t *testing.T) {
// A session with an explicit TTL should use that instead of the default.
now := time.Date(2026, 7, 6, 12, 0, 0, 0, time.UTC)
store := NewSessionStore(2 * time.Minute)
sess := &Session{Intent: IntentQuery, Timestamp: now, TTL: 15 * time.Minute}
store.Put("chatty", sess)
// Should still be alive at 10 minutes (past the 2m default).
if s := store.Get("chatty", now.Add(10*time.Minute)); s == nil {
t.Error("chat session with 15m TTL expired at 10m — custom TTL not applied")
}
// Should be expired after 20 minutes.
if s := store.Get("chatty", now.Add(20*time.Minute)); s != nil {
t.Error("chat session with 15m TTL should be expired at 20m")
}
}
func TestInheritSlots(t *testing.T) {
now := time.Date(2026, 7, 6, 0, 0, 0, 0, time.UTC)
prev := Slots{Text: "Moscow", HasKey: true, Key: "location"}
cur := Slots{}
inherited := InheritSlots(prev, cur)
if !inherited.HasKey || inherited.Key != "location" {
t.Error("should inherit key from previous")
}
cur2 := Slots{HasKey: true, Key: "London"}
inherited2 := InheritSlots(prev, cur2)
if inherited2.Key != "London" {
t.Error("should keep current key when present")
}
prevTime := Slots{HasTime: true, Time: now}
inherited3 := InheritSlots(prevTime, Slots{})
if !inherited3.HasTime || !inherited3.Time.Equal(now) {
t.Error("should inherit time")
}
prevFn := Slots{HasFn: true, Fn: "status", Args: []string{"nginx"}}
inherited4 := InheritSlots(prevFn, Slots{})
if !inherited4.HasFn || inherited4.Fn != "status" {
t.Error("should inherit fn")
}
if len(inherited4.Args) != 1 || inherited4.Args[0] != "nginx" {
t.Error("should inherit args")
}
inherited5 := InheritSlots(prevFn, Slots{HasFn: true, Fn: "restart", Args: []string{"docker"}})
if len(inherited5.Args) != 1 || inherited5.Args[0] != "docker" {
t.Error("should keep current args")
}
prevText := Slots{Text: "какая погода в москве"}
inherited6 := InheritSlots(prevText, Slots{Text: ""})
if inherited6.Text != "какая погода в москве" {
t.Error("should inherit text when current is empty")
}
}