Files
gotenberg/test/integration/scenario/images_test.go
2026-10-05 13:32:59 +02:00

107 lines
3.0 KiB
Go

package scenario
import (
"fmt"
"strings"
"testing"
)
func TestCheckImageXObjectReuse(t *testing.T) {
t.Parallel()
const header = `page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
`
imageRow := func(page, object, generation int) string {
return fmt.Sprintf("%d %d image 32 32 rgb 3 8 image no %d %d 96 96 3104B 101%%\n", page, page-1, object, generation)
}
tests := []struct {
name string
output string
pages int
wantErr string
}{
{
name: "one page baseline",
output: header + imageRow(1, 7, 0),
pages: 1,
},
{
name: "three pages share one image object",
output: header + imageRow(1, 7, 0) + imageRow(2, 7, 0) + imageRow(3, 7, 0),
pages: 3,
},
{
name: "regression embeds a different object per page",
output: header + imageRow(1, 7, 0) + imageRow(2, 8, 0) + imageRow(3, 9, 0),
pages: 3,
wantErr: "expected 1 unique image XObject(s) shared across 3 page(s), but actual is 3",
},
{
name: "object generation is part of its identity",
output: header + imageRow(1, 7, 0) + imageRow(2, 7, 1) + imageRow(3, 7, 0),
pages: 3,
wantErr: "expected 1 unique image XObject(s) shared across 3 page(s), but actual is 2",
},
{
name: "image missing from a page",
output: header + imageRow(1, 7, 0) + imageRow(3, 7, 0),
pages: 3,
wantErr: "expected 1 image appearance(s) on page 2, but actual is 0",
},
{
name: "no image cannot pass",
output: header,
pages: 1,
wantErr: "expected 1 image appearance(s) on page 1, but actual is 0",
},
{
name: "repeated image only on first page cannot pass",
output: header + imageRow(1, 7, 0) + imageRow(1, 7, 0) + imageRow(1, 7, 0),
pages: 3,
wantErr: "expected 1 image appearance(s) on page 1, but actual is 3",
},
{
name: "image on unexpected page",
output: header + imageRow(1, 7, 0) + imageRow(2, 7, 0),
pages: 1,
wantErr: "image on page 2 outside expected range 1-1",
},
{
name: "tool error cannot pass",
output: "Syntax Error: Couldn't find trailer dictionary",
pages: 1,
wantErr: "invalid pdfimages -list output:",
},
{
name: "malformed image row",
output: header + "1 0 image\n",
pages: 1,
wantErr: "invalid pdfimages -list row:",
},
{
name: "inline image has no reusable object ID",
output: header + "1 0 image 32 32 rgb 3 8 image no [inline] - 96 96 3104B 101%\n",
pages: 1,
wantErr: "parse image object ID",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := checkImageXObjectReuse(tt.output, 1, tt.pages)
if tt.wantErr == "" {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
return
}
if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
t.Fatalf("expected error containing %q, got %v", tt.wantErr, err)
}
})
}
}