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,101 @@
|
||||
package infra
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// buildMultipart construye un multipart body con los archivos dados (field, filename, contenido).
|
||||
func buildMultipart(t *testing.T, files []struct{ field, filename, content string }) (string, *bytes.Buffer) {
|
||||
t.Helper()
|
||||
var body bytes.Buffer
|
||||
w := multipart.NewWriter(&body)
|
||||
for _, f := range files {
|
||||
part, err := w.CreateFormFile(f.field, f.filename)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateFormFile: %v", err)
|
||||
}
|
||||
if _, err := part.Write([]byte(f.content)); err != nil {
|
||||
t.Fatalf("Write part: %v", err)
|
||||
}
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
t.Fatalf("Close writer: %v", err)
|
||||
}
|
||||
return w.FormDataContentType(), &body
|
||||
}
|
||||
|
||||
func newMultipartReq(t *testing.T, contentType string, body *bytes.Buffer) *http.Request {
|
||||
t.Helper()
|
||||
req := httptest.NewRequest("POST", "/upload", body)
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
return req
|
||||
}
|
||||
|
||||
func TestUploadParse(t *testing.T) {
|
||||
t.Run("extrae un archivo del multipart", func(t *testing.T) {
|
||||
ct, body := buildMultipart(t, []struct{ field, filename, content string }{
|
||||
{"file", "a.txt", "hello"},
|
||||
})
|
||||
req := newMultipartReq(t, ct, body)
|
||||
|
||||
got, err := UploadParse(req, 1<<20)
|
||||
if err != nil {
|
||||
t.Fatalf("UploadParse: %v", err)
|
||||
}
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("got %d files, want 1", len(got))
|
||||
}
|
||||
if got[0].Filename != "a.txt" {
|
||||
t.Errorf("got Filename %q", got[0].Filename)
|
||||
}
|
||||
if got[0].Size != 5 {
|
||||
t.Errorf("got Size %d, want 5", got[0].Size)
|
||||
}
|
||||
buf, _ := io.ReadAll(got[0].Content)
|
||||
if string(buf) != "hello" {
|
||||
t.Errorf("got content %q, want hello", buf)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("extrae multiples archivos", func(t *testing.T) {
|
||||
ct, body := buildMultipart(t, []struct{ field, filename, content string }{
|
||||
{"a", "1.txt", "uno"},
|
||||
{"b", "2.txt", "dos"},
|
||||
})
|
||||
req := newMultipartReq(t, ct, body)
|
||||
|
||||
got, err := UploadParse(req, 1<<20)
|
||||
if err != nil {
|
||||
t.Fatalf("UploadParse: %v", err)
|
||||
}
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("got %d files, want 2", len(got))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("rechaza content-type no multipart", func(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", "/upload", strings.NewReader("x"))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
_, err := UploadParse(req, 1<<20)
|
||||
if err == nil || !strings.Contains(err.Error(), "no es multipart") {
|
||||
t.Errorf("got %v, want error de content-type", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("respeta maxSize", func(t *testing.T) {
|
||||
ct, body := buildMultipart(t, []struct{ field, filename, content string }{
|
||||
{"file", "big.bin", strings.Repeat("x", 1024)},
|
||||
})
|
||||
req := newMultipartReq(t, ct, body)
|
||||
_, err := UploadParse(req, 100) // demasiado pequeno
|
||||
if err == nil {
|
||||
t.Errorf("got nil err, want max bytes error")
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user