Files
2026-07-10 00:55:13 +07:00

91 lines
3.1 KiB
Go

//go:build sqlite || sqliteonly
package sqlitestore
import (
"context"
"testing"
"time"
"github.com/google/uuid"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
func TestSQLiteEpisodicSearch_TimeFiltersAndExpiry(t *testing.T) {
db := openTestDB(t)
if err := EnsureSchema(db); err != nil {
t.Fatalf("EnsureSchema: %v", err)
}
s := NewSQLiteEpisodicStore(db)
tenantID := uuid.New()
agentID := uuid.New()
userID := "time-user"
ctx := store.WithTenantID(context.Background(), tenantID)
base := time.Date(2026, 7, 9, 12, 0, 0, 0, time.UTC)
if _, err := db.ExecContext(ctx, `INSERT INTO tenants (id, name, slug, status) VALUES (?, ?, ?, ?)`, tenantID.String(), "Test Tenant", "test-tenant", "active"); err != nil {
t.Fatalf("seed tenant: %v", err)
}
if _, err := db.ExecContext(ctx, `INSERT INTO agents (id, agent_key, display_name, owner_id, model, tenant_id) VALUES (?, ?, ?, ?, ?, ?)`, agentID.String(), "test-agent", "Test Agent", "owner", "test-model", tenantID.String()); err != nil {
t.Fatalf("seed agent: %v", err)
}
items := []struct {
sourceID string
summary string
createdAt time.Time
expiresAt *time.Time
}{
{sourceID: "old", summary: "Project Alpha old planning note", createdAt: base.Add(-48 * time.Hour)},
{sourceID: "recent", summary: "Project Alpha recent planning note", createdAt: base.Add(-2 * time.Hour)},
{sourceID: "expired", summary: "Project Alpha expired planning note", createdAt: base.Add(-time.Hour), expiresAt: sqliteEpisodicTimePtr(base.Add(-30 * time.Minute))},
}
for _, item := range items {
ep := &store.EpisodicSummary{
TenantID: tenantID,
AgentID: agentID,
UserID: userID,
SessionKey: "time-sess",
Summary: item.summary,
KeyTopics: []string{"project-alpha", "planning"},
SourceType: "session",
SourceID: "time-filter-" + item.sourceID,
ExpiresAt: item.expiresAt,
}
if err := s.Create(ctx, ep); err != nil {
t.Fatalf("Create %s: %v", item.sourceID, err)
}
if _, err := db.ExecContext(ctx, `UPDATE episodic_summaries SET created_at = ? WHERE id = ?`, item.createdAt.UTC().Format(time.RFC3339Nano), ep.ID.String()); err != nil {
t.Fatalf("set created_at %s: %v", item.sourceID, err)
}
}
createdAfter := base.Add(-24 * time.Hour)
results, err := s.Search(ctx, "*", agentID.String(), userID, store.EpisodicSearchOptions{
MaxResults: 10,
CreatedAfter: &createdAfter,
})
if err != nil {
t.Fatalf("Search recent: %v", err)
}
if len(results) != 1 {
t.Fatalf("recent non-expired results = %d, want 1", len(results))
}
if results[0].L0Abstract != "Project Alpha recent planning note" {
t.Fatalf("recent result = %q, want non-expired recent note", results[0].L0Abstract)
}
results, err = s.Search(ctx, "planning", agentID.String(), userID, store.EpisodicSearchOptions{
MaxResults: 10,
CreatedAfter: &createdAfter,
IncludeExpired: true,
})
if err != nil {
t.Fatalf("Search include expired: %v", err)
}
if len(results) != 2 {
t.Fatalf("include expired results = %d, want 2", len(results))
}
}
func sqliteEpisodicTimePtr(t time.Time) *time.Time { return &t }