feat: file_save_disk, file_delete, file_serve, upload_parse, upload_handler, thumbnail_generate (issue 0014 fase 3)
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package infra
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// genPNG crea un PNG cuadrado de size pixeles en path.
|
||||
func genPNG(t *testing.T, path string, size int) {
|
||||
t.Helper()
|
||||
img := image.NewRGBA(image.Rect(0, 0, size, size))
|
||||
for y := 0; y < size; y++ {
|
||||
for x := 0; x < size; x++ {
|
||||
img.Set(x, y, color.RGBA{R: uint8(x % 255), G: uint8(y % 255), B: 100, A: 255})
|
||||
}
|
||||
}
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
t.Fatalf("create: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := png.Encode(f, img); err != nil {
|
||||
t.Fatalf("encode: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestThumbnailGenerate(t *testing.T) {
|
||||
t.Run("genera thumbnail PNG mas pequeno que el original", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
src := filepath.Join(dir, "src.png")
|
||||
dst := filepath.Join(dir, "thumb.png")
|
||||
genPNG(t, src, 400)
|
||||
|
||||
if err := ThumbnailGenerate(src, dst, 100, 100); err != nil {
|
||||
t.Fatalf("ThumbnailGenerate: %v", err)
|
||||
}
|
||||
|
||||
f, err := os.Open(dst)
|
||||
if err != nil {
|
||||
t.Fatalf("open dst: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
img, _, err := image.Decode(f)
|
||||
if err != nil {
|
||||
t.Fatalf("decode dst: %v", err)
|
||||
}
|
||||
b := img.Bounds()
|
||||
if b.Dx() > 100 || b.Dy() > 100 {
|
||||
t.Errorf("thumbnail %dx%d, want <= 100x100", b.Dx(), b.Dy())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("preserva aspect ratio", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
src := filepath.Join(dir, "src.png")
|
||||
dst := filepath.Join(dir, "thumb.png")
|
||||
|
||||
// Imagen 400x200 (aspect 2:1)
|
||||
img := image.NewRGBA(image.Rect(0, 0, 400, 200))
|
||||
f, _ := os.Create(src)
|
||||
png.Encode(f, img)
|
||||
f.Close()
|
||||
|
||||
if err := ThumbnailGenerate(src, dst, 100, 100); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
f2, _ := os.Open(dst)
|
||||
defer f2.Close()
|
||||
thumb, _, _ := image.Decode(f2)
|
||||
b := thumb.Bounds()
|
||||
// Aspect 2:1 mantenido: 100x50
|
||||
if b.Dx() != 100 || b.Dy() != 50 {
|
||||
t.Errorf("thumbnail %dx%d, want 100x50 (aspect 2:1)", b.Dx(), b.Dy())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("rechaza extension de salida no soportada", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
src := filepath.Join(dir, "src.png")
|
||||
dst := filepath.Join(dir, "thumb.webp")
|
||||
genPNG(t, src, 200)
|
||||
err := ThumbnailGenerate(src, dst, 100, 100)
|
||||
if err == nil {
|
||||
t.Error("got nil err, want extension no soportada")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("no agranda imagenes ya pequenas", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
src := filepath.Join(dir, "src.png")
|
||||
dst := filepath.Join(dir, "thumb.png")
|
||||
genPNG(t, src, 50)
|
||||
|
||||
if err := ThumbnailGenerate(src, dst, 200, 200); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
f, _ := os.Open(dst)
|
||||
defer f.Close()
|
||||
thumb, _, _ := image.Decode(f)
|
||||
b := thumb.Bounds()
|
||||
if b.Dx() != 50 || b.Dy() != 50 {
|
||||
t.Errorf("thumbnail %dx%d, want 50x50 (sin agrandar)", b.Dx(), b.Dy())
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user