Files
foundry-core/internal/codex/canvas_artifacts_test.go
T
codex-bot d6ee8942f1
Foundry Go checks / check (push) Successful in 2m40s
Foundry Go checks / check (pull_request) Successful in 2m36s
Implement Canvas V2 subgraphs, assets and asynchronous AI execution
2026-11-06 18:36:00 +08:00

63 lines
2.3 KiB
Go

package codex
import (
"encoding/base64"
"os"
"path/filepath"
"testing"
)
func TestCanvasArtifactDirectoryIsolation(t *testing.T) {
root := t.TempDir()
generated := filepath.Join(root, "generated_images")
if err := os.Mkdir(generated, 0700); err != nil {
t.Fatal(err)
}
// A minimal PNG header is sufficient for the worker's transport sniff. Core
// performs full decode/dimension validation before accepting it as an asset.
encoded, _ := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+j1WQAAAAASUVORK5CYII=")
if err := os.WriteFile(filepath.Join(root, "unrelated.png"), encoded, 0600); err != nil {
t.Fatal(err)
}
if _, err := readCanvasGeneratedImage(generated); err == nil {
t.Fatal("unrelated image used as generated output")
}
if err := os.WriteFile(filepath.Join(generated, "result.png"), encoded, 0600); err != nil {
t.Fatal(err)
}
result, err := readCanvasGeneratedImage(generated)
if err != nil || result.MIME != "image/png" || len(result.Data) != len(encoded) {
t.Fatalf("generated output: %v", err)
}
if err := os.WriteFile(filepath.Join(generated, "second.png"), encoded, 0600); err != nil {
t.Fatal(err)
}
if _, err := readCanvasGeneratedImage(generated); err == nil {
t.Fatal("multiple images silently dropped")
}
if err := os.Remove(filepath.Join(generated, "second.png")); err != nil {
t.Fatal(err)
}
if err := os.Remove(filepath.Join(generated, "result.png")); err != nil {
t.Fatal(err)
}
if err := os.Symlink(filepath.Join(root, "unrelated.png"), filepath.Join(generated, "escape.png")); err != nil {
t.Fatal(err)
}
if _, err := readCanvasGeneratedImage(generated); err == nil {
t.Fatal("symlink escaped job output directory")
}
}
func TestCanvasAgentCompletionRequiresSuccessfulTurn(t *testing.T) {
if _, ok := canvasAgentText([]byte("{\"type\":\"item.completed\",\"item\":{\"type\":\"agent_message\",\"text\":\"partial\"}}\n")); ok {
t.Fatal("partial generation accepted")
}
if _, ok := canvasAgentText([]byte("{\"type\":\"turn.completed\"}\n{\"type\":\"error\"}\n")); ok {
t.Fatal("failed generation accepted")
}
text, ok := canvasAgentText([]byte("{\"type\":\"item.completed\",\"item\":{\"type\":\"agent_message\",\"text\":\"done\"}}\n{\"type\":\"turn.completed\"}\n"))
if !ok || text != "done" {
t.Fatal("successful generation rejected")
}
}