axe/internal/handlers/photos_test.go
2026-10-18 22:07:25 +03:00

85 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"strings"
"testing"
)
// TestSniffImage — белый список форматов по сигнатуре: только фото.
func TestSniffImage(t *testing.T) {
jpeg := []byte{0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10}
png := []byte{0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A, 0x00}
webp := []byte("RIFF\x24\x00\x00\x00WEBPVP8 ")
cases := []struct {
name string
data []byte
contentType string
ext string
}{
{"jpeg", jpeg, "image/jpeg", "jpg"},
{"png", png, "image/png", "png"},
{"webp", webp, "image/webp", "webp"},
{"gif is not photo", []byte("GIF89a"), "", ""},
{"bmp is not photo", []byte("BM\x00\x00"), "", ""},
{"svg text", []byte(`<svg xmlns="http://www.w3.org/2000/svg"></svg>`), "", ""},
{"empty", nil, "", ""},
{"truncated jpeg", []byte{0xFF, 0xD8}, "", ""},
{"riff but not webp", []byte("RIFF\x00\x00\x00\x00WAVEfmt "), "", ""},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
contentType, ext, ok := sniffImage(tc.data)
if tc.contentType == "" {
if ok {
t.Errorf("sniff = (%q, %q, true), want reject", contentType, ext)
}
return
}
if !ok || contentType != tc.contentType || ext != tc.ext {
t.Errorf("sniff = (%q, %q, %v), want (%q, %q, true)",
contentType, ext, ok, tc.contentType, tc.ext)
}
})
}
}
// TestPhotoName — имя файла из multipart: без путей, управляющих
// символов и без бесконечных строк (оно уходит в журнал событий).
func TestPhotoName(t *testing.T) {
cases := []struct {
in string
want string
}{
{"photo.jpg", "photo.jpg"},
{`C:\Users\me\photo.jpg`, "photo.jpg"}, // имя с Windows-путём
{"../../etc/passwd", "passwd"}, // path traversal вырезается
{"a\x00b\x1fc.png", "abc.png"}, // управляющие символы
{"", ""}, // имя не передали
{".", ""}, // path.Base(".") = "."
{strings.Repeat("я", 150) + ".jpg", strings.Repeat("я", 100)}, // обрезка по рунам
}
for _, tc := range cases {
if got := photoName(tc.in); got != tc.want {
t.Errorf("photoName(%q) = %q, want %q", tc.in, got, tc.want)
}
}
}
// TestNewPhotoHandlerDefaults — лимиты из env могли быть нулём
// (не заданы): хендлер обязан подставить дефолты, а не считать с нулём.
func TestNewPhotoHandlerDefaults(t *testing.T) {
h := NewPhotoHandler(nil, nil, nil, nil, 0, -1)
if h.maxBytes != photoDefaultMaxBytes {
t.Errorf("maxBytes = %d, want %d", h.maxBytes, photoDefaultMaxBytes)
}
if h.maxPer != photoDefaultMaxPer {
t.Errorf("maxPer = %d, want %d", h.maxPer, photoDefaultMaxPer)
}
custom := NewPhotoHandler(nil, nil, nil, nil, 4096, 3)
if custom.maxBytes != 4096 || custom.maxPer != 3 {
t.Errorf("custom limits = %d/%d, want 4096/3", custom.maxBytes, custom.maxPer)
}
}