145 lines
3.8 KiB
Go
145 lines
3.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
imageModels "ginimageApi/app/images/models"
|
|
"ginimageApi/configs"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func setupImageHandlersTestDB(t *testing.T) {
|
|
t.Helper()
|
|
prev := configs.DB
|
|
dsn := "file:" + t.Name() + "?mode=memory&cache=shared"
|
|
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("sqlite open failed: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(&imageModels.Image{}); err != nil {
|
|
t.Fatalf("migrate failed: %v", err)
|
|
}
|
|
configs.DB = db
|
|
t.Cleanup(func() {
|
|
if sqlDB, err := db.DB(); err == nil {
|
|
_ = sqlDB.Close()
|
|
}
|
|
configs.DB = prev
|
|
})
|
|
}
|
|
|
|
func withUser(userID uint) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
c.Set("user_id", userID)
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func TestProcessRequiresFile(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
r.POST("/images/process", Process)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/images/process", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestProcessRejectsInvalidWidth(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
r.POST("/images/process", Process)
|
|
|
|
var body bytes.Buffer
|
|
writer := multipart.NewWriter(&body)
|
|
filePart, err := writer.CreateFormFile("file", "dummy.jpg")
|
|
if err != nil {
|
|
t.Fatalf("failed to create form file: %v", err)
|
|
}
|
|
_, _ = filePart.Write([]byte("not-a-real-image"))
|
|
_ = writer.WriteField("width", "abc")
|
|
if err := writer.Close(); err != nil {
|
|
t.Fatalf("failed to close writer: %v", err)
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/images/process", &body)
|
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestListImagesReturnsOnlyCurrentUser(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
setupImageHandlersTestDB(t)
|
|
|
|
seed := []imageModels.Image{
|
|
{UserID: 1, Filename: "a.avif", PublicPath: "/uploads/processed/a.avif", MimeType: "image/avif", Size: 10, Format: "avif", Quality: 90},
|
|
{UserID: 1, Filename: "b.avif", PublicPath: "/uploads/processed/b.avif", MimeType: "image/avif", Size: 11, Format: "avif", Quality: 90},
|
|
{UserID: 2, Filename: "c.avif", PublicPath: "/uploads/processed/c.avif", MimeType: "image/avif", Size: 12, Format: "avif", Quality: 90},
|
|
}
|
|
if err := configs.DB.Create(&seed).Error; err != nil {
|
|
t.Fatalf("seed failed: %v", err)
|
|
}
|
|
|
|
r := gin.New()
|
|
r.GET("/images", withUser(1), ListImages)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/images", nil)
|
|
req.Host = "localhost:8080"
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("expected 200, got %d body=%s", w.Code, w.Body.String())
|
|
}
|
|
|
|
var resp struct {
|
|
Count int `json:"count"`
|
|
Items []struct {
|
|
ID uint `json:"id"`
|
|
} `json:"items"`
|
|
}
|
|
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
|
t.Fatalf("json parse failed: %v", err)
|
|
}
|
|
if resp.Count != 2 || len(resp.Items) != 2 {
|
|
t.Fatalf("expected 2 images for current user, got count=%d len=%d", resp.Count, len(resp.Items))
|
|
}
|
|
}
|
|
|
|
func TestGetImageRejectsOtherUsersImage(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
setupImageHandlersTestDB(t)
|
|
|
|
img := imageModels.Image{UserID: 2, Filename: "x.avif", PublicPath: "/uploads/processed/x.avif", MimeType: "image/avif", Size: 5, Format: "avif", Quality: 90}
|
|
if err := configs.DB.Create(&img).Error; err != nil {
|
|
t.Fatalf("seed failed: %v", err)
|
|
}
|
|
|
|
r := gin.New()
|
|
r.GET("/images/:id", withUser(1), GetImage)
|
|
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/images/1", nil))
|
|
|
|
if w.Code != http.StatusNotFound {
|
|
t.Fatalf("expected 404, got %d", w.Code)
|
|
}
|
|
}
|