package api import ( "archive/tar" "bytes" "os" "path/filepath" "testing" "jiggablend/internal/storage" "jiggablend/pkg/executils" ) func TestExtractTar_ExtractsRegularFile(t *testing.T) { var buf bytes.Buffer tw := tar.NewWriter(&buf) _ = tw.WriteHeader(&tar.Header{Name: "ctx/scene.blend", Mode: 0644, Size: 4, Typeflag: tar.TypeReg}) _, _ = tw.Write([]byte("data")) _ = tw.Close() tarPath := filepath.Join(t.TempDir(), "ctx.tar") if err := os.WriteFile(tarPath, buf.Bytes(), 0644); err != nil { t.Fatalf("write tar: %v", err) } dest := t.TempDir() m := &Manager{} if err := m.extractTar(tarPath, dest); err != nil { t.Fatalf("extractTar failed: %v", err) } if _, err := os.Stat(filepath.Join(dest, "ctx", "scene.blend")); err != nil { t.Fatalf("expected extracted file: %v", err) } } func TestExtractTar_RejectsTraversal(t *testing.T) { var buf bytes.Buffer tw := tar.NewWriter(&buf) _ = tw.WriteHeader(&tar.Header{Name: "../evil.txt", Mode: 0644, Size: 1, Typeflag: tar.TypeReg}) _, _ = tw.Write([]byte("x")) _ = tw.Close() tarPath := filepath.Join(t.TempDir(), "bad.tar") if err := os.WriteFile(tarPath, buf.Bytes(), 0644); err != nil { t.Fatalf("write tar: %v", err) } m := &Manager{} if err := m.extractTar(tarPath, t.TempDir()); err == nil { t.Fatal("expected path traversal error") } } func TestExtractMetadataFromContext_UsesCommandSeam(t *testing.T) { base := t.TempDir() st, err := storage.NewStorage(base) if err != nil { t.Fatalf("new storage: %v", err) } jobID := int64(42) jobDir := st.JobPath(jobID) if err := os.MkdirAll(jobDir, 0755); err != nil { t.Fatalf("mkdir job dir: %v", err) } var buf bytes.Buffer tw := tar.NewWriter(&buf) _ = tw.WriteHeader(&tar.Header{Name: "scene.blend", Mode: 0644, Size: 4, Typeflag: tar.TypeReg}) _, _ = tw.Write([]byte("fake")) _ = tw.Close() if err := os.WriteFile(filepath.Join(jobDir, "context.tar"), buf.Bytes(), 0644); err != nil { t.Fatalf("write context tar: %v", err) } origResolve := resolveMetadataBlenderPath origRun := runMetadataCommand resolveMetadataBlenderPath = func(_ string) (string, error) { return "/usr/bin/blender", nil } runMetadataCommand = func(_ string, _ []string, _ string, _ []string, _ int64, _ *executils.ProcessTracker) (*executils.CommandResult, error) { return &executils.CommandResult{ Stdout: `noise {"frame_start":1,"frame_end":3,"has_negative_frames":false,"render_settings":{"resolution_x":1920,"resolution_y":1080,"frame_rate":24,"output_format":"PNG","engine":"CYCLES"},"scene_info":{"camera_count":1,"object_count":2,"material_count":3}} done`, }, nil } defer func() { resolveMetadataBlenderPath = origResolve runMetadataCommand = origRun }() m := &Manager{storage: st} meta, err := m.extractMetadataFromContext(jobID) if err != nil { t.Fatalf("extractMetadataFromContext failed: %v", err) } if meta.FrameStart != 1 || meta.FrameEnd != 3 { t.Fatalf("unexpected metadata: %+v", *meta) } }