2026-08-11 10:00:07 +08:00
|
|
|
|
package integration
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2026-08-11 10:06:10 +08:00
|
|
|
|
"bytes"
|
2026-08-11 10:00:07 +08:00
|
|
|
|
"net/http"
|
|
|
|
|
|
"net/http/httptest"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
|
|
|
|
|
|
"cmautobuy/admin/config"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func TestRequireCatalogToken(t *testing.T) {
|
|
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
|
|
const token = "0123456789abcdef0123456789abcdef"
|
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
|
|
name, header string
|
|
|
|
|
|
cfg config.CatalogIntegrationConfig
|
|
|
|
|
|
want int
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"未启用", "", config.CatalogIntegrationConfig{}, http.StatusServiceUnavailable},
|
|
|
|
|
|
{"缺少", "", config.CatalogIntegrationConfig{Source: "script", Token: token}, http.StatusUnauthorized},
|
|
|
|
|
|
{"错误", "Bearer wrong", config.CatalogIntegrationConfig{Source: "script", Token: token}, http.StatusUnauthorized},
|
|
|
|
|
|
{"正确", "Bearer " + token, config.CatalogIntegrationConfig{Source: "script", Token: token}, http.StatusNoContent},
|
|
|
|
|
|
} {
|
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
|
r := gin.New()
|
|
|
|
|
|
r.GET("/protected", RequireCatalogToken(tc.cfg), func(c *gin.Context) {
|
|
|
|
|
|
if integrationSource(c) != tc.cfg.Source {
|
|
|
|
|
|
t.Fatalf("source=%q", integrationSource(c))
|
|
|
|
|
|
}
|
|
|
|
|
|
c.Status(http.StatusNoContent)
|
|
|
|
|
|
})
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/protected", nil)
|
|
|
|
|
|
req.Header.Set("Authorization", tc.header)
|
|
|
|
|
|
resp := httptest.NewRecorder()
|
|
|
|
|
|
r.ServeHTTP(resp, req)
|
|
|
|
|
|
if resp.Code != tc.want {
|
|
|
|
|
|
t.Fatalf("status=%d body=%s", resp.Code, resp.Body.String())
|
|
|
|
|
|
}
|
|
|
|
|
|
if strings.Contains(resp.Body.String(), token) || strings.Contains(resp.Body.String(), "wrong") {
|
|
|
|
|
|
t.Fatal("响应泄露接口凭据")
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-08-11 10:06:10 +08:00
|
|
|
|
|
|
|
|
|
|
func TestCatalogBatchAPI_鉴权JSON与体积限制(t *testing.T) {
|
|
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
|
|
const token = "0123456789abcdef0123456789abcdef"
|
|
|
|
|
|
r := gin.New()
|
|
|
|
|
|
Register(r, nil, config.CatalogIntegrationConfig{Source: "script", Token: token})
|
|
|
|
|
|
|
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
|
|
name, auth string
|
|
|
|
|
|
body []byte
|
|
|
|
|
|
want int
|
|
|
|
|
|
}{
|
|
|
|
|
|
{"无鉴权", "", []byte(`{}`), http.StatusUnauthorized},
|
|
|
|
|
|
{"坏JSON", "Bearer " + token, []byte(`{"schema_version":`), http.StatusBadRequest},
|
|
|
|
|
|
{"超限", "Bearer " + token, bytes.Repeat([]byte("x"), catalogMaxBody+1), http.StatusRequestEntityTooLarge},
|
|
|
|
|
|
} {
|
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/integrations/catalog/batches", bytes.NewReader(tc.body))
|
|
|
|
|
|
req.Header.Set("Authorization", tc.auth)
|
|
|
|
|
|
resp := httptest.NewRecorder()
|
|
|
|
|
|
r.ServeHTTP(resp, req)
|
|
|
|
|
|
if resp.Code != tc.want {
|
|
|
|
|
|
t.Fatalf("status=%d body=%s", resp.Code, resp.Body.String())
|
|
|
|
|
|
}
|
|
|
|
|
|
if !strings.Contains(resp.Header().Get("Content-Type"), "application/json") {
|
|
|
|
|
|
t.Fatalf("错误响应必须是 JSON:%s", resp.Header())
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|