Files
tamabox/internal/imagecheck/imagecheck_test.go
T
2026-09-08 10:10:44 +08:00

127 lines
4.1 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 imagecheck
import (
"bytes"
"encoding/binary"
"errors"
"image"
"image/color"
"image/png"
"testing"
)
// buildGIFHeader 构造仅含文件头与逻辑屏幕描述符的最小 GIF(无像素数据),
// 用于让 image.DecodeConfig 读取出宽高。GIF 无 CRC,构造简单可靠。
func buildGIFHeader(t *testing.T, width, height uint16) []byte {
t.Helper()
var buf bytes.Buffer
buf.WriteString("GIF89a")
// Logical Screen Descriptor: width(2 LE) + height(2 LE) + packed(1) + bgcolor(1) + aspect(1)
if err := binary.Write(&buf, binary.LittleEndian, width); err != nil {
t.Fatalf("write width: %v", err)
}
if err := binary.Write(&buf, binary.LittleEndian, height); err != nil {
t.Fatalf("write height: %v", err)
}
buf.Write([]byte{0x00, 0x00, 0x00}) // 无全局颜色表
return buf.Bytes()
}
func TestCheckPixelLimit_NormalPNG(t *testing.T) {
img := image.NewRGBA(image.Rect(0, 0, 100, 100))
for x := 0; x < 100; x++ {
for y := 0; y < 100; y++ {
img.Set(x, y, color.RGBA{R: 255, A: 255})
}
}
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
t.Fatalf("encode png: %v", err)
}
if err := CheckPixelLimit(bytes.NewReader(buf.Bytes())); err != nil {
t.Fatalf("normal image should pass, got %v", err)
}
}
func TestCheckPixelLimit_AtLimit(t *testing.T) {
// 恰好等于上限 4096×4096,应通过(校验为严格大于才拒绝)。
data := buildGIFHeader(t, 4096, 4096)
if err := CheckPixelLimit(bytes.NewReader(data)); err != nil {
t.Fatalf("4096×4096 should pass, got %v", err)
}
}
func TestCheckPixelLimit_TooLarge(t *testing.T) {
// 4096×4097 超过上限,应拒绝并返回统一错误。
data := buildGIFHeader(t, 4096, 4097)
err := CheckPixelLimit(bytes.NewReader(data))
if err == nil {
t.Fatal("oversized image should be rejected, got nil")
}
if !errors.Is(err, ErrImageTooLarge) {
t.Fatalf("expected ErrImageTooLarge, got %v", err)
}
}
func TestCheckPixelLimit_InvalidData(t *testing.T) {
err := CheckPixelLimit(bytes.NewReader([]byte("this is not an image")))
if err == nil {
t.Fatal("invalid data should error, got nil")
}
if errors.Is(err, ErrImageTooLarge) {
t.Fatal("invalid data should not be classified as ErrImageTooLarge")
}
}
// encodePNG 生成指定宽高的纯色 PNG,供比例校验测试使用。
func encodePNG(t *testing.T, width, height int) []byte {
t.Helper()
img := image.NewRGBA(image.Rect(0, 0, width, height))
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
t.Fatalf("encode png: %v", err)
}
return buf.Bytes()
}
func TestCheckAspectRatio_Pass(t *testing.T) {
// 1920×1080 精确 16:9
if err := CheckAspectRatio(bytes.NewReader(encodePNG(t, 1920, 1080)), 16, 9, DefaultAspectTolerance); err != nil {
t.Fatalf("1920×1080 should pass 16:9, got %v", err)
}
// 1:1 正方形
if err := CheckAspectRatio(bytes.NewReader(encodePNG(t, 512, 512)), 1, 1, DefaultAspectTolerance); err != nil {
t.Fatalf("512×512 should pass 1:1, got %v", err)
}
// 容差内的微小偏差(1281×720 ≈ 1.779,仍属 16:9)
if err := CheckAspectRatio(bytes.NewReader(encodePNG(t, 1281, 720)), 16, 9, DefaultAspectTolerance); err != nil {
t.Fatalf("1281×720 should pass within tolerance, got %v", err)
}
}
func TestCheckAspectRatio_Reject(t *testing.T) {
// 4:3 直传背景图应被拒绝
err := CheckAspectRatio(bytes.NewReader(encodePNG(t, 800, 600)), 16, 9, DefaultAspectTolerance)
if err == nil {
t.Fatal("800×600 should be rejected as 16:9")
}
if !errors.Is(err, ErrBadAspectRatio) {
t.Fatalf("expected ErrBadAspectRatio, got %v", err)
}
// 竖长条不能当头像
if err := CheckAspectRatio(bytes.NewReader(encodePNG(t, 300, 500)), 1, 1, DefaultAspectTolerance); err == nil {
t.Fatal("300×500 should be rejected as 1:1")
}
}
func TestCheckAspectRatio_InvalidData(t *testing.T) {
// 无法解码的数据不应误判为比例不符
err := CheckAspectRatio(bytes.NewReader([]byte("this is not an image")), 1, 1, DefaultAspectTolerance)
if err == nil {
t.Fatal("invalid data should error, got nil")
}
if errors.Is(err, ErrBadAspectRatio) {
t.Fatal("invalid data should not be classified as ErrBadAspectRatio")
}
}