package jobs import ( "bytes" "image" "image/color" "image/png" "io" "log/slog" "mime/multipart" "net/http/httptest" "net/textproto" "testing" "warpbox.dev/backend/libs/services" ) func TestGenerateMissingThumbnailsForBox(t *testing.T) { service := newThumbnailTestUploadService(t) result := createThumbnailTestBox(t, service) box, err := service.GetBox(result.BoxID) if err != nil { t.Fatalf("GetBox returned error: %v", err) } if box.Files[0].Thumbnail != "" { t.Fatalf("thumbnail should start empty") } jobResult, err := generateMissingThumbnailsForBox(service, slog.New(slog.NewTextHandler(io.Discard, nil)), box) if err != nil { t.Fatalf("generateMissingThumbnailsForBox returned error: %v", err) } if jobResult.Generated != 1 || jobResult.Failed != 0 { t.Fatalf("job result = %+v, want 1 generated and 0 failed", jobResult) } updated, err := service.GetBox(result.BoxID) if err != nil { t.Fatalf("GetBox after thumbnail returned error: %v", err) } if updated.Files[0].Thumbnail == "" { t.Fatalf("thumbnail was not saved to box metadata") } if service.ThumbnailPath(updated, updated.Files[0]) == "" { t.Fatalf("thumbnail path was empty") } } func newThumbnailTestUploadService(t *testing.T) *services.UploadService { t.Helper() service, err := services.NewUploadService(1024*1024, t.TempDir(), "http://example.test", slog.New(slog.NewTextHandler(io.Discard, nil))) if err != nil { t.Fatalf("NewUploadService returned error: %v", err) } t.Cleanup(func() { if err := service.Close(); err != nil { t.Fatalf("Close returned error: %v", err) } }) return service } func createThumbnailTestBox(t *testing.T, service *services.UploadService) services.UploadResult { t.Helper() result, err := service.CreateBox(thumbnailTestFileHeaders(t), services.UploadOptions{MaxDays: 1}) if err != nil { t.Fatalf("CreateBox returned error: %v", err) } return result } func thumbnailTestFileHeaders(t *testing.T) []*multipart.FileHeader { t.Helper() var imageData bytes.Buffer img := image.NewRGBA(image.Rect(0, 0, 2, 2)) img.Set(0, 0, color.RGBA{R: 255, A: 255}) if err := png.Encode(&imageData, img); err != nil { t.Fatalf("png.Encode returned error: %v", err) } var payload bytes.Buffer writer := multipart.NewWriter(&payload) header := make(textproto.MIMEHeader) header.Set("Content-Disposition", `form-data; name="file"; filename="thumb.png"`) header.Set("Content-Type", "image/png") part, err := writer.CreatePart(header) if err != nil { t.Fatalf("CreateFormFile returned error: %v", err) } if _, err := part.Write(imageData.Bytes()); err != nil { t.Fatalf("part.Write returned error: %v", err) } if err := writer.Close(); err != nil { t.Fatalf("writer.Close returned error: %v", err) } request := httptest.NewRequest("POST", "/upload", &payload) request.Header.Set("Content-Type", writer.FormDataContentType()) if err := request.ParseMultipartForm(1024 * 1024); err != nil { t.Fatalf("ParseMultipartForm returned error: %v", err) } return request.MultipartForm.File["file"] }