package platepdf import ( "bytes" "fmt" "os" "strings" "testing" "printer.backend/internal/layout" "printer.backend/internal/model" "printer.backend/internal/svgtemplate" ) const sampleItemSVG = ` ` func requireRsvg(t *testing.T) { t.Helper() if !rsvgAvailable() { t.Skip("rsvg-convert not available") } } func TestBuildCompositeSVG(t *testing.T) { requireRsvg(t) plate := model.Plate{ WidthMM: 300, HeightMM: 400, MarginTop: 10, MarginRight: 10, MarginBottom: 10, MarginLeft: 10, } spec := model.ItemSpec{WidthMM: 80, HeightMM: 80, BleedMM: 2, MarginMM: 5, PaddingMM: 3} preview := layout.Pack(plate, spec, 2) out, err := BuildCompositeSVG(plate, spec, []byte(sampleItemSVG), preview) if err != nil { t.Fatal(err) } s := string(out) if !strings.Contains(s, `viewBox="0 0 300`) { t.Fatalf("expected plate viewBox, got: %s", s[:min(200, len(s))]) } if preview.Count > 0 && !strings.Contains(s, ` 0 && !strings.Contains(s, `x="10.0000"`) { t.Fatal("expected items at plate margin (canvas origin)") } if preview.Count > 0 && !strings.Contains(s, fmt.Sprintf(`width="%.4f"`, preview.CanvasWidthMM)) { t.Fatal("expected full canvas width on placed images") } } func TestBuildCompositeSVGInvalid(t *testing.T) { requireRsvg(t) _, err := BuildCompositeSVG(model.Plate{}, model.ItemSpec{}, []byte("not svg"), model.LayoutPreview{}) if err == nil { t.Fatal("expected error for invalid svg") } } func TestGeneratePDF(t *testing.T) { requireRsvg(t) plate := model.Plate{ WidthMM: 200, HeightMM: 200, MarginLeft: 10, MarginTop: 10, MarginRight: 10, MarginBottom: 10, } spec := model.ItemSpec{WidthMM: 80, HeightMM: 80, BleedMM: 2, MarginMM: 5, PaddingMM: 3} preview := layout.Pack(plate, spec, 2) var buf bytes.Buffer if err := svgtemplate.Write(&buf, svgtemplate.Build( spec.WidthMM, spec.HeightMM, spec.BleedMM, spec.MarginMM, spec.PaddingMM, spec.CornerRadiusMM, )); err != nil { t.Fatal(err) } path := t.TempDir() + "/item.svg" if err := os.WriteFile(path, buf.Bytes(), 0o644); err != nil { t.Fatal(err) } pdf, err := Generate(plate, spec, path, preview) if err != nil { t.Fatal(err) } if len(pdf) < 4 || string(pdf[:4]) != "%PDF" { t.Fatalf("expected PDF header, got %d bytes", len(pdf)) } } func TestGenerateRequiresRsvg(t *testing.T) { if rsvgAvailable() { t.Skip("rsvg-convert is available") } _, err := Generate(model.Plate{}, model.ItemSpec{}, "/nonexistent", model.LayoutPreview{}) if err == nil || !strings.Contains(err.Error(), "rsvg-convert") { t.Fatalf("expected rsvg error, got: %v", err) } }