package images import ( "bytes" "encoding/json" "mime/multipart" "net/http" "net/http/httptest" "strings" "testing" ) // a 1x1 transparent PNG. var pngBytes = []byte{ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, 0x89, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, } func uploadReq(t *testing.T, field string, data []byte) *http.Request { t.Helper() var buf bytes.Buffer mw := multipart.NewWriter(&buf) fw, err := mw.CreateFormFile(field, "x.png") if err != nil { t.Fatal(err) } fw.Write(data) mw.Close() req := httptest.NewRequest(http.MethodPost, "/", &buf) req.Header.Set("Content-Type", mw.FormDataContentType()) return req } func TestUploadAndServe(t *testing.T) { h, err := New(t.TempDir()) if err != nil { t.Fatal(err) } r := h.Routes() // Upload a PNG → expect a JSON url under /api/images/. rec := httptest.NewRecorder() r.ServeHTTP(rec, uploadReq(t, "image", pngBytes)) if rec.Code != http.StatusOK { t.Fatalf("upload code=%d body=%s", rec.Code, rec.Body) } var resp struct{ URL string } if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatal(err) } if !strings.HasPrefix(resp.URL, "/api/images/") || !strings.HasSuffix(resp.URL, ".png") { t.Fatalf("unexpected url %q", resp.URL) } // The same content uploaded again dedupes to the same URL. rec2 := httptest.NewRecorder() r.ServeHTTP(rec2, uploadReq(t, "image", pngBytes)) var resp2 struct{ URL string } json.Unmarshal(rec2.Body.Bytes(), &resp2) if resp2.URL != resp.URL { t.Fatalf("expected dedup to same url, got %q vs %q", resp2.URL, resp.URL) } // Fetch it back. name := strings.TrimPrefix(resp.URL, "/api/images/") rec3 := httptest.NewRecorder() r.ServeHTTP(rec3, httptest.NewRequest(http.MethodGet, "/"+name, nil)) if rec3.Code != http.StatusOK { t.Fatalf("serve code=%d", rec3.Code) } if !bytes.Equal(rec3.Body.Bytes(), pngBytes) { t.Fatal("served bytes differ from uploaded") } } func TestUploadRejectsNonImage(t *testing.T) { h, _ := New(t.TempDir()) r := h.Routes() rec := httptest.NewRecorder() r.ServeHTTP(rec, uploadReq(t, "image", []byte("this is plainly not an image at all"))) if rec.Code != http.StatusUnsupportedMediaType { t.Fatalf("expected 415, got %d", rec.Code) } } func TestServeMissing(t *testing.T) { h, _ := New(t.TempDir()) r := h.Routes() rec := httptest.NewRecorder() r.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/deadbeef.png", nil)) if rec.Code != http.StatusNotFound { t.Fatalf("expected 404, got %d", rec.Code) } }