111 lines
4.0 KiB
Go
111 lines
4.0 KiB
Go
package sybinnercode
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func importRequest(t *testing.T, field, filename string, content []byte) (*http.Request, string) {
|
|
t.Helper()
|
|
var body bytes.Buffer
|
|
writer := multipart.NewWriter(&body)
|
|
part, err := writer.CreateFormFile(field, filename)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := part.Write(content); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := writer.WriteField("requestId", uuid.NewString()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := writer.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
request := httptest.NewRequest(http.MethodPost, "/import", &body)
|
|
request.Header.Set("Content-Type", writer.FormDataContentType())
|
|
return request, writer.FormDataContentType()
|
|
}
|
|
|
|
func performImport(t *testing.T, request *http.Request) *httptest.ResponseRecorder {
|
|
t.Helper()
|
|
gin.SetMode(gin.TestMode)
|
|
recorder := httptest.NewRecorder()
|
|
router := gin.New()
|
|
router.POST("/import", func(c *gin.Context) {
|
|
c.Set(jwt.JwtPayloadKey, jwt.MapClaims{"identity": float64(1)})
|
|
Handler{DB: testDB(t)}.Import(c)
|
|
})
|
|
router.ServeHTTP(recorder, request)
|
|
return recorder
|
|
}
|
|
|
|
func responsePayload(t *testing.T, recorder *httptest.ResponseRecorder) map[string]any {
|
|
t.Helper()
|
|
var payload map[string]any
|
|
if err := json.Unmarshal(recorder.Body.Bytes(), &payload); err != nil {
|
|
t.Fatalf("decode response %q: %v", recorder.Body.String(), err)
|
|
}
|
|
return payload
|
|
}
|
|
|
|
func TestImportHandlerAcceptsBrowserMultipartBoundary(t *testing.T) {
|
|
content := workbook(t, [][]any{{"2026-08-28", "ORDER-1", "店铺", "A#1", "SKU-1", "黑色,L", "IC-01", 1}})
|
|
request, contentType := importRequest(t, "file", "mapping_20260828.xlsx", content)
|
|
if contentType == "multipart/form-data" || !bytes.Contains([]byte(contentType), []byte("boundary=")) {
|
|
t.Fatalf("browser multipart boundary missing: %s", contentType)
|
|
}
|
|
recorder := performImport(t, request)
|
|
if recorder.Code != http.StatusOK || responsePayload(t, recorder)["code"] != float64(200) {
|
|
t.Fatalf("unexpected response: status=%d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestImportHandlerDistinguishesMalformedAndOversizedBodies(t *testing.T) {
|
|
t.Run("wrong content type", func(t *testing.T) {
|
|
request := httptest.NewRequest(http.MethodPost, "/import", bytes.NewBufferString(`{"file":"not-multipart"}`))
|
|
request.Header.Set("Content-Type", "application/json")
|
|
recorder := performImport(t, request)
|
|
payload := responsePayload(t, recorder)
|
|
if recorder.Code != http.StatusUnprocessableEntity || payload["message"] != "上传格式无效,请重新选择 Excel 后重试" {
|
|
t.Fatalf("unexpected response: status=%d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
})
|
|
|
|
t.Run("wrong field", func(t *testing.T) {
|
|
request, _ := importRequest(t, "wrong", "mapping_20260828.xlsx", []byte("content"))
|
|
recorder := performImport(t, request)
|
|
payload := responsePayload(t, recorder)
|
|
if recorder.Code != http.StatusUnprocessableEntity || payload["message"] != "上传格式无效,请重新选择 Excel 后重试" {
|
|
t.Fatalf("unexpected response: status=%d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
})
|
|
|
|
t.Run("request body over hard limit", func(t *testing.T) {
|
|
request, _ := importRequest(t, "file", "mapping_20260828.xlsx", make([]byte, MaxUploadBytes+(2<<20)))
|
|
recorder := performImport(t, request)
|
|
payload := responsePayload(t, recorder)
|
|
if recorder.Code != http.StatusUnprocessableEntity || payload["message"] != "Excel 超过 10MB 上限" {
|
|
t.Fatalf("unexpected response: status=%d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestValidateUploadKeepsTenMegabyteLimit(t *testing.T) {
|
|
if MaxUploadBytes != 10<<20 {
|
|
t.Fatalf("unexpected upload limit: %d", MaxUploadBytes)
|
|
}
|
|
err := ValidateUpload("mapping.xlsx", MaxUploadBytes+1, []byte{'P', 'K', 0x03, 0x04})
|
|
if err == nil || err.Error() != "Excel 超过 10MB 上限" {
|
|
t.Fatalf("unexpected validation result: %v", err)
|
|
}
|
|
}
|