package orchestration import ( "context" "data-terminal-cloud/internal/database" "data-terminal-cloud/internal/deviceauth" "os" "strings" "testing" "time" ) func TestVikingStartupContextRequiresMatchingSubject(t *testing.T) { db := os.Getenv("TEST_DATABASE_URL") if db == "" { t.Skip("TEST_DATABASE_URL required") } ctx := context.Background() pool, err := database.Open(ctx, db, "viking-context-test") if err != nil { t.Fatal(err) } defer pool.Close() for _, matches := range []bool{true, false} { tx, err := pool.Begin(ctx) if err != nil { t.Fatal(err) } identity := deviceauth.Identity{ID: "10000000-0000-0000-0000-000000000501", PublicID: "10000000-0000-0000-0000-000000000511", TenantID: "10000000-0000-0000-0000-000000000001", Status: "registered"} subject := "10000000-0000-0000-0000-000000000401" if !matches { subject = "10000000-0000-0000-0000-000000000402" } _, err = tx.Exec(ctx, `UPDATE consent_snapshot SET effective_consents='{"voice_chat":true,"transcript_storage":true,"story_extraction":true,"personalized_memory":true}' WHERE tenant_id=$1::uuid`, identity.TenantID) if err != nil { t.Fatal(err) } now := time.Now().UTC() _, internalID, err := NewRepository().Create(ctx, tx, identity, CreateInput{RequestedGoal: "open_conversation"}, AllocationOptions{Now: now, AllocationExpires: now.Add(time.Minute), TokenExpires: now.Add(5 * time.Minute), RTCAppID: "test-app", EngineMode: "s2s_hybrid", HeartbeatInterval: 15, VikingSubjectID: subject, VikingContext: "独立记忆测试:喜欢茉莉花茶"}) if err != nil { tx.Rollback(ctx) t.Fatal(err) } var summary string err = tx.QueryRow(ctx, `SELECT cx.sanitized_summary FROM conversation c JOIN context_snapshot cx ON cx.id=c.context_snapshot_id WHERE c.id=$1::uuid`, internalID).Scan(&summary) tx.Rollback(ctx) if err != nil || strings.Contains(summary, "独立记忆测试") != matches { t.Fatalf("matches=%v summary=%s err=%v", matches, summary, err) } } }