Files
pixa/internal/handlers/unsupported_source_internal_test.go
T
clawbot efbf05a6fa
check / check (push) Canceled after 0s
Support SVG sources (closes #68)
The fetcher accepts image/svg+xml and internal/magic detects SVG. orig
of an SVG at the orig size is the SVG unchanged, cached as a variant; at
another size it is ErrSVGNotOriginalSize (400). Any other format renders
it with libvips' thumbnail at the least size covering the output, at
most 8192 on a side, so it stays sharp. An SVG's own size is not
limited; one with a side over 8192 times the other is ErrSVGTooThin
(415). The cache reads up to 1024 first bytes to find a file's format.
Tests that pinned the SVG refusal now expect SVG to be read. Render time
and memory are unbounded: P1 in TODO.md until the owner decides on
#68.

Model: opus-5-5
2026-11-11 13:21:12 +00:00

77 lines
2.4 KiB
Go

package handlers
import (
"fmt"
"log/slog"
"net/http"
"net/http/httptest"
"strings"
"testing"
"sneak.berlin/go/pixa/internal/httpfetcher"
"sneak.berlin/go/pixa/internal/imageprocessor"
"sneak.berlin/go/pixa/internal/imagerequest"
)
// TestUnsupportedSourceFormatAnswers415 checks that respondImageError, which
// answers the errors of both image routes, answers 415 with a clear error when
// the upstream answers with a content type pixa does not accept, such as TIFF,
// and when libvips does not read a source as the format its first bytes
// show, wrapped as the service wraps them.
func TestUnsupportedSourceFormatAnswers415(t *testing.T) {
t.Parallel()
h := &Handlers{log: slog.New(slog.DiscardHandler)}
req := &imagerequest.Request{
Source: imagerequest.Source{Host: "img.example.com", Path: "/a.tiff"},
}
for _, err := range []error{
fmt.Errorf("upstream fetch failed: %w: image/tiff",
httpfetcher.ErrInvalidContentType),
fmt.Errorf("image processing failed: %w: libvips does not read the input as avif",
imageprocessor.ErrUnsupportedInputFormat),
} {
rec := httptest.NewRecorder()
h.respondImageError(rec, req, err)
t.Logf("for %v: %d %s", err, rec.Code, rec.Body.String())
if rec.Code != http.StatusUnsupportedMediaType {
t.Errorf("for %v: status = %d, want %d",
err, rec.Code, http.StatusUnsupportedMediaType)
}
if !strings.Contains(rec.Body.String(), "unsupported source format") {
t.Errorf("for %v: body = %q, want the unsupported source format error",
err, rec.Body.String())
}
}
}
// TestSVGTooThinAnswers415 checks that respondImageError answers 415 with a
// clear error for an SVG source too thin to render, wrapped as the service
// wraps it.
func TestSVGTooThinAnswers415(t *testing.T) {
t.Parallel()
h := &Handlers{log: slog.New(slog.DiscardHandler)}
req := &imagerequest.Request{
Source: imagerequest.Source{Host: "svg.example.com", Path: "/a.svg"},
}
err := fmt.Errorf("image processing failed: %w: 81930x10",
imageprocessor.ErrSVGTooThin)
rec := httptest.NewRecorder()
h.respondImageError(rec, req, err)
t.Logf("for %v: %d %s", err, rec.Code, rec.Body.String())
if rec.Code != http.StatusUnsupportedMediaType {
t.Errorf("status = %d, want %d", rec.Code,
http.StatusUnsupportedMediaType)
}
if !strings.Contains(rec.Body.String(), "SVG source too thin to render") {
t.Errorf("body = %q, want the SVG too thin error", rec.Body.String())
}
}