92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package logic
|
||
|
||
import (
|
||
"testing"
|
||
|
||
"tool-api/internal/consts"
|
||
)
|
||
|
||
// ============================================================================
|
||
// 头像上传校验单测(T02.4)
|
||
//
|
||
// 覆盖:体积 / 扩展名 / 内容魔数校验分支不依赖 DB;4017 必带可读中文提示。
|
||
// ============================================================================
|
||
|
||
func pngBytes() []byte {
|
||
b := make([]byte, 16)
|
||
copy(b, []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A})
|
||
return b
|
||
}
|
||
|
||
func jpgBytes() []byte {
|
||
b := make([]byte, 16)
|
||
copy(b, []byte{0xFF, 0xD8, 0xFF, 0xE0})
|
||
return b
|
||
}
|
||
|
||
func webpBytes() []byte {
|
||
b := make([]byte, 16)
|
||
copy(b[0:4], []byte("RIFF"))
|
||
copy(b[8:12], []byte("WEBP"))
|
||
return b
|
||
}
|
||
|
||
func TestIsImageBytes(t *testing.T) {
|
||
cases := []struct {
|
||
name string
|
||
data []byte
|
||
want bool
|
||
}{
|
||
{"png", pngBytes(), true},
|
||
{"jpg", jpgBytes(), true},
|
||
{"webp", webpBytes(), true},
|
||
{"纯文本", []byte("hello world!!!"), false},
|
||
{"过短", []byte{0xFF, 0xD8}, false},
|
||
{"空", []byte{}, false},
|
||
}
|
||
for _, c := range cases {
|
||
if got := isImageBytes(c.data); got != c.want {
|
||
t.Errorf("%s: isImageBytes=%v want %v", c.name, got, c.want)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestValidateAvatarUpload(t *testing.T) {
|
||
big := make([]byte, AvatarMaxBytes+1)
|
||
copy(big, pngBytes())
|
||
|
||
cases := []struct {
|
||
name string
|
||
file string
|
||
data []byte
|
||
wantCode int // 0 = 通过
|
||
}{
|
||
{"合法 png", "a.png", pngBytes(), 0},
|
||
{"合法 jpg(大写扩展名)", "a.JPG", jpgBytes(), 0},
|
||
{"合法 jpeg", "a.jpeg", jpgBytes(), 0},
|
||
{"合法 webp", "a.webp", webpBytes(), 0},
|
||
{"空内容", "a.png", []byte{}, consts.CodeUploadInvalid},
|
||
{"超 5MB", "a.png", big, consts.CodeUploadInvalid},
|
||
{"扩展名不支持", "a.gif", pngBytes(), consts.CodeUploadInvalid},
|
||
{"无扩展名", "a", pngBytes(), consts.CodeUploadInvalid},
|
||
{"内容非图片", "a.jpg", []byte("not an image at all"), consts.CodeUploadInvalid},
|
||
}
|
||
for _, c := range cases {
|
||
err := validateAvatarUpload(c.file, c.data)
|
||
if got := codeOf(err); got != c.wantCode {
|
||
t.Errorf("%s: code=%d want %d (err=%v)", c.name, got, c.wantCode, err)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestUploadFailedReadable 4017 必须是可读中文提示、不得静默失败(U1)。
|
||
func TestUploadFailedReadable(t *testing.T) {
|
||
err := errUploadFailed("头像上传失败,请重试")
|
||
if codeOf(err) != consts.CodeUploadFailed {
|
||
t.Fatalf("上传失败应返回 4017,实得 code=%d", codeOf(err))
|
||
}
|
||
if err.Error() == "" {
|
||
t.Fatalf("4017 必须带可读提示,不得为空")
|
||
}
|
||
}
|