101 lines
2.7 KiB
Go
101 lines
2.7 KiB
Go
package infra
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
// buildPNGMultipart crea un multipart con un campo "file" cuyo contenido tiene
|
|
// los magic bytes de PNG (suficientes para que FileValidateType los reconozca).
|
|
func buildPNGMultipart(t *testing.T, filename string, body string) (string, *bytes.Buffer) {
|
|
t.Helper()
|
|
var buf bytes.Buffer
|
|
w := multipart.NewWriter(&buf)
|
|
part, err := w.CreateFormFile("file", filename)
|
|
if err != nil {
|
|
t.Fatalf("CreateFormFile: %v", err)
|
|
}
|
|
// Magic bytes PNG: 89 50 4E 47 0D 0A 1A 0A
|
|
part.Write([]byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A})
|
|
part.Write([]byte(body))
|
|
w.Close()
|
|
return w.FormDataContentType(), &buf
|
|
}
|
|
|
|
func TestUploadHandler(t *testing.T) {
|
|
t.Run("acepta upload con imagen y responde JSON", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cfg := StorageConfig{
|
|
BaseDir: dir,
|
|
MaxFileSize: 1 << 20,
|
|
AllowedTypes: []string{"image/png"},
|
|
}
|
|
ct, body := buildPNGMultipart(t, "foto.png", "data extra")
|
|
|
|
req := httptest.NewRequest("POST", "/upload", body)
|
|
req.Header.Set("Content-Type", ct)
|
|
rec := httptest.NewRecorder()
|
|
|
|
UploadHandler(cfg).ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("got %d, body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp struct {
|
|
Files []UploadedFile `json:"files"`
|
|
}
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if len(resp.Files) != 1 {
|
|
t.Fatalf("got %d files, want 1", len(resp.Files))
|
|
}
|
|
if resp.Files[0].ContentType != "image/png" {
|
|
t.Errorf("got ContentType %q", resp.Files[0].ContentType)
|
|
}
|
|
})
|
|
|
|
t.Run("rechaza tipo no permitido con 415", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cfg := StorageConfig{
|
|
BaseDir: dir,
|
|
MaxFileSize: 1 << 20,
|
|
AllowedTypes: []string{"application/pdf"}, // PNG no en lista
|
|
}
|
|
ct, body := buildPNGMultipart(t, "foto.png", "x")
|
|
|
|
req := httptest.NewRequest("POST", "/upload", body)
|
|
req.Header.Set("Content-Type", ct)
|
|
rec := httptest.NewRecorder()
|
|
|
|
UploadHandler(cfg).ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusUnsupportedMediaType {
|
|
t.Errorf("got %d, want 415", rec.Code)
|
|
}
|
|
})
|
|
|
|
t.Run("rechaza body que excede MaxFileSize con 400", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cfg := StorageConfig{
|
|
BaseDir: dir,
|
|
MaxFileSize: 10, // muy pequeno
|
|
AllowedTypes: []string{"image/png"},
|
|
}
|
|
ct, body := buildPNGMultipart(t, "foto.png", "muchos bytes extra para superar 10")
|
|
|
|
req := httptest.NewRequest("POST", "/upload", body)
|
|
req.Header.Set("Content-Type", ct)
|
|
rec := httptest.NewRecorder()
|
|
|
|
UploadHandler(cfg).ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Errorf("got %d, want 400", rec.Code)
|
|
}
|
|
})
|
|
}
|