Files
story/internal/dataexport/direct_story_integration_test.go
T

77 lines
3.9 KiB
Go
Raw Normal View History

package dataexport
import (
"context"
"encoding/json"
"os"
"testing"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
)
func TestDirectStoryExportIncludesNativeEvidenceAndHonorsAvailability(t *testing.T) {
url := os.Getenv("TEST_DATABASE_URL")
if url == "" {
t.Skip("TEST_DATABASE_URL required")
}
ctx := context.Background()
pool, err := pgxpool.New(ctx, url)
if err != nil {
t.Fatal(err)
}
defer pool.Close()
exec := func(query string, args ...any) {
t.Helper()
if _, err := pool.Exec(ctx, query, args...); err != nil {
t.Fatal(err)
}
}
subject, session, story, revision := uuid.NewString(), uuid.NewString(), uuid.NewString(), uuid.NewString()
const tenant = "10000000-0000-0000-0000-000000000001"
exec(`INSERT INTO subject_profile(id,tenant_id,household_id,preferred_name,status) VALUES($1::uuid,$2::uuid,'10000000-0000-0000-0000-000000000201','native-export','active')`, subject, tenant)
exec(`INSERT INTO memory_user_state(subject_id,tenant_id) VALUES($1::uuid,$2::uuid)`, subject, tenant)
exec(`INSERT INTO consent_record(tenant_id,subject_id,consent_type,scope,policy_version,notice_digest,actor_user_id,evidence_ref) SELECT tenant_id,$1::uuid,consent_type,scope,policy_version,notice_digest,actor_user_id,evidence_ref FROM consent_record WHERE subject_id='10000000-0000-0000-0000-000000000401' AND withdrawn_at IS NULL`, subject)
exec(`INSERT INTO call_session(id,device_id,tenant_id,subject_id,boot_id,hook_event_id,call_generation,binding_generation,call_state,transcript_state,transcript_revision,budget_snapshot,ended_at) VALUES($1::uuid,'10000000-0000-0000-0000-000000000501',$2::uuid,$3::uuid,$1::uuid,$1,0,0,'ENDED','COMPLETE',1,'{"protocol":"DIRECT-CHAT-1","story_extraction_allowed":true}',now())`, session, tenant, subject)
exec(`INSERT INTO call_utterance(session_id,utterance_id,source_revision,speaker,text_content,interrupted,source_at) VALUES($1::uuid,'native-evidence',1,'USER','小时候和爷爷一起种树。',false,now())`, session)
exec(`INSERT INTO story_draft(id,tenant_id,subject_id,call_session_id,call_privacy_epoch,title,generation_version) VALUES($1::uuid,$2::uuid,$3::uuid,$4::uuid,0,'和爷爷种树',1)`, story, tenant, subject, session)
exec(`INSERT INTO story_revision(id,story_id,revision_no,content,author_type) VALUES($1::uuid,$2::uuid,1,'小时候和爷爷一起种树。','model')`, revision, story)
exec(`INSERT INTO story_source(story_revision_id,call_session_id,call_utterance_id,call_source_revision,source_role) VALUES($1::uuid,$2::uuid,'native-evidence',1,'subject')`, revision, session)
exec(`UPDATE story_draft SET current_revision_id=$2::uuid WHERE id=$1::uuid`, story, revision)
processor, err := NewProcessor(pool, &exportTestStore{}, time.Hour)
if err != nil {
t.Fatal(err)
}
type exportedStory struct {
Session string `json:"call_session_id"`
Conversation *string `json:"conversation_id"`
Sources []struct {
Session string `json:"call_session_id"`
Utterance string `json:"utterance_id"`
Revision int64 `json:"source_revision"`
Text string `json:"text"`
} `json:"sources"`
}
read := func() []exportedStory {
t.Helper()
raw, err := processor.collectCategory(ctx, "stories", tenant, subject)
if err != nil {
t.Fatal(err)
}
var items []exportedStory
if err := json.Unmarshal(raw, &items); err != nil {
t.Fatal(err)
}
return items
}
items := read()
if len(items) != 1 || items[0].Session != session || items[0].Conversation != nil || len(items[0].Sources) != 1 || items[0].Sources[0].Session != session || items[0].Sources[0].Utterance != "native-evidence" || items[0].Sources[0].Revision != 1 || items[0].Sources[0].Text != "小时候和爷爷一起种树。" {
t.Fatalf("native export=%+v", items)
}
exec(`UPDATE call_utterance SET source_revision=2 WHERE session_id=$1::uuid`, session)
if items := read(); len(items) != 0 {
t.Fatalf("stale source export=%+v", items)
}
}