Files
ttstd-infinite-canvas/backend/internal/service/task_output_test.go

81 lines
3.9 KiB
Go

package service
import (
"encoding/json"
"testing"
"infinite-canvas/backend/internal/model"
)
func TestTaskForOutputRedactsRoutingAndSecrets(t *testing.T) {
task := model.Task{
InputJSON: `{"mode":"image","metadata":{"source":"create-page"},"config":{"apiKey":"secret"},"resourceId":"resource-1"}`,
LogicalModelRevisionID: "revision-1",
RouteID: "route-1",
ChannelModelID: "channel-model-1",
}
output := taskForOutput(task)
if output.LogicalModelRevisionID != "" || output.RouteID != "" || output.ChannelModelID != "" {
t.Fatalf("internal routing fields leaked: %+v", output)
}
var input map[string]any
if err := json.Unmarshal([]byte(output.InputJSON), &input); err != nil {
t.Fatalf("public input is not valid JSON: %v", err)
}
if _, exists := input["config"]; exists {
t.Fatal("provider config must not be exposed")
}
if input["resourceId"] != "resource-1" {
t.Fatalf("resource identity was not preserved: %#v", input)
}
}
func TestTaskMediaPreviewUsesSafeMediaURLs(t *testing.T) {
previewURL, previewKind := taskMediaPreview(`{"images":["data:image/png;base64,AAAA","/api/resources/resource-1/file"],"video":"https://cdn.example.com/output.mp4"}`, "video")
if previewURL != "/api/resources/resource-1/file" || previewKind != "image" {
t.Fatalf("unexpected preview: url=%q kind=%q", previewURL, previewKind)
}
if previewURL, _ := taskMediaPreview(`{"url":"file:///tmp/output.mp4"}`, "video"); previewURL != "" {
t.Fatalf("unsafe local URL was exposed: %q", previewURL)
}
}
func TestTaskClientContextRequiresCreatePageMetadata(t *testing.T) {
valid := taskClientContext(`{"metadata":{"source":"create-page","conversationId":"conversation-1","messageId":"message-1","batchIndex":2,"batchCount":4}}`)
if valid == nil || valid.ConversationID != "conversation-1" || valid.BatchIndex != 2 {
t.Fatalf("valid client context was not decoded: %+v", valid)
}
if context := taskClientContext(`{"metadata":{"source":"other","conversationId":"conversation-1","messageId":"message-1"}}`); context != nil {
t.Fatalf("unexpected context for non-create-page task: %+v", context)
}
}
func TestTaskClientContextProjectsChapterOperations(t *testing.T) {
characters := taskClientContext(`{"metadata":{"domainProjectId":"project-1","chapterId":"chapter-1","operation":"chapter_character_breakdown"}}`)
if characters == nil || characters.DomainProjectID != "project-1" || characters.ChapterID != "chapter-1" || characters.ChapterOperation != "characters" {
t.Fatalf("character task context was not decoded: %+v", characters)
}
storyboard := taskClientContext(`{"metadata":{"source":"short-drama-chapter-storyboard","domainProjectId":"project-1","chapterId":"chapter-2"}}`)
if storyboard == nil || storyboard.ChapterID != "chapter-2" || storyboard.ChapterOperation != "storyboard" {
t.Fatalf("storyboard task context was not decoded: %+v", storyboard)
}
if context := taskClientContext(`{"metadata":{"domainProjectId":"project-1","chapterId":"chapter-1","operation":"unrelated"}}`); context != nil {
t.Fatalf("unexpected context for unrelated project task: %+v", context)
}
}
func TestTaskClientContextProjectsShotWorkflow(t *testing.T) {
context := taskClientContext(`{"metadata":{"domainProjectId":"project-1","shotId":"shot-1","workflowStepId":"step-1","artifactType":"video"}}`)
if context == nil || context.DomainProjectID != "project-1" || context.ShotID != "shot-1" || context.WorkflowStepID != "step-1" || context.ArtifactType != "video" {
t.Fatalf("shot task context was not decoded: %+v", context)
}
}
func TestTaskOutputResourceReadsPersistedMedia(t *testing.T) {
id, mediaType := taskOutputResource(`{"mode":"video","video":{"resourceId":"resource-1","storageKey":"resource:resource-1"}}`, "canvas_video")
if id != "resource-1" || mediaType != "video" {
t.Fatalf("unexpected task output resource: id=%q mediaType=%q", id, mediaType)
}
}