79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
package itemimage
|
|
|
|
import (
|
|
"bytes"
|
|
"image"
|
|
"image/color"
|
|
"image/png"
|
|
"strings"
|
|
"testing"
|
|
|
|
"printer.backend/internal/model"
|
|
)
|
|
|
|
const sampleItemSVG = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-13 -13 106 106">
|
|
<defs>
|
|
<clipPath id="item-mask">
|
|
<rect x="0" y="0" width="80" height="80" rx="5" ry="5" />
|
|
</clipPath>
|
|
</defs>
|
|
<g clip-path="url(#item-mask)">
|
|
<rect x="-2" y="-2" width="84" height="84" fill="#00FF00" opacity="0.7" />
|
|
</g>
|
|
</svg>`
|
|
|
|
func testPNG(w, h int) []byte {
|
|
img := image.NewRGBA(image.Rect(0, 0, w, h))
|
|
for y := 0; y < h; y++ {
|
|
for x := 0; x < w; x++ {
|
|
img.Set(x, y, color.RGBA{uint8(x % 256), uint8(y % 256), 128, 255})
|
|
}
|
|
}
|
|
var buf bytes.Buffer
|
|
_ = png.Encode(&buf, img)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func TestEmbedReplacesGreenMask(t *testing.T) {
|
|
spec := model.ItemSpec{WidthMM: 80, HeightMM: 80, BleedMM: 2, MarginMM: 5, PaddingMM: 3}
|
|
out, err := Embed([]byte(sampleItemSVG), spec, testPNG(1, 1), "image/png")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s := string(out)
|
|
if strings.Contains(s, "#00FF00") || strings.Contains(s, "#00ff00") {
|
|
t.Fatal("green placeholder should be replaced")
|
|
}
|
|
if !strings.Contains(s, `<image `) || !strings.Contains(s, `preserveAspectRatio="xMidYMid slice"`) {
|
|
t.Fatalf("expected embedded image, got: %s", s)
|
|
}
|
|
if !strings.Contains(s, `x="-2.0000"`) {
|
|
t.Fatal("expected bleed-aligned image placement")
|
|
}
|
|
if !strings.Contains(s, "data:image/jpeg;base64,") {
|
|
t.Fatal("expected downscaled jpeg data uri")
|
|
}
|
|
}
|
|
|
|
func TestEmbedDownscalesLargeImage(t *testing.T) {
|
|
spec := model.ItemSpec{WidthMM: 80, HeightMM: 80, BleedMM: 2, MarginMM: 5, PaddingMM: 3}
|
|
huge := testPNG(4000, 3000)
|
|
out, err := Embed([]byte(sampleItemSVG), spec, huge, "image/png")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
const maxSVG = 600_000 // ~600 KB embedded payload is plenty for rsvg
|
|
if len(out) > maxSVG {
|
|
t.Fatalf("embedded svg too large: %d bytes", len(out))
|
|
}
|
|
}
|
|
|
|
func TestEmbedInvalidSVG(t *testing.T) {
|
|
spec := model.ItemSpec{WidthMM: 80, HeightMM: 80, BleedMM: 2, MarginMM: 5}
|
|
_, err := Embed([]byte("<svg></svg>"), spec, testPNG(1, 1), "image/png")
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
}
|