feat(t222): add freight ingestion admin flow

This commit is contained in:
QiuSW
2026-07-28 23:26:34 +08:00
parent c524e734fb
commit 6d052b0462
37 changed files with 3397 additions and 101 deletions
@@ -922,6 +922,78 @@ func TestRendererUsesMissingKeyErrors(t *testing.T) {
}
}
func TestFreightPagesEscapeSourceDataAndCreateAsyncSync(t *testing.T) {
now := time.Date(2026, 7, 28, 3, 4, 5, 0, time.UTC)
service := &fakeFreightService{
fakeService: &fakeService{},
orders: []FreightOrder{{
ID: testTaskID,
ExternalStockID: "12",
SourceCode: `<script>private</script>`,
ShopName: "测试店铺",
ItemCount: 2,
Revision: 1,
UpdatedAt: now,
}},
createResult: FreightSync{
ID: testTaskID,
Status: "PENDING",
CreatedAt: now,
},
}
router := newTestRouter(t, service)
list := performRequest(t, router, http.MethodGet, "/freight", nil, "")
if list.Code != http.StatusOK ||
strings.Contains(list.Body.String(), `<script>private</script>`) ||
!strings.Contains(list.Body.String(), "&lt;script&gt;private") ||
!strings.Contains(list.Body.String(), "2 项") {
t.Fatalf("freight list status/body = %d / %s", list.Code, list.Body)
}
assertSecurityHeaders(t, list)
form := performRequest(
t,
router,
http.MethodGet,
"/freight/import",
nil,
"",
)
cookie := csrfCookie(t, form)
idempotencyKey := hiddenValue(
t,
form.Body.String(),
"idempotency_key",
)
values := url.Values{
"csrf_token": {cookie.Value},
"idempotency_key": {idempotencyKey},
"order_number": {"SOURCE-12"},
}
request := httptest.NewRequest(
http.MethodPost,
"/freight/import",
strings.NewReader(values.Encode()),
)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.AddCookie(cookie)
response := httptest.NewRecorder()
router.ServeHTTP(response, request)
if response.Code != http.StatusSeeOther ||
response.Header().Get("Location") !=
"/freight/import?sync="+testTaskID {
t.Fatalf(
"create sync status/location = %d / %q",
response.Code,
response.Header().Get("Location"),
)
}
if service.createInput.OrderNumber != "SOURCE-12" ||
service.createInput.IdempotencyKey != idempotencyKey {
t.Fatalf("create input = %+v", service.createInput)
}
}
type fakeService struct {
listInput ListTasksInput
listResult TaskList
@@ -945,6 +1017,45 @@ type fakeService struct {
authorizeInput AuthorizeOrderInput
}
type fakeFreightService struct {
*fakeService
orders []FreightOrder
orderDetail FreightOrderDetail
sync FreightSync
createInput CreateFreightSyncInput
createResult FreightSync
err error
}
func (service *fakeFreightService) ListFreightOrders(
context.Context,
int,
) ([]FreightOrder, error) {
return service.orders, service.err
}
func (service *fakeFreightService) GetFreightOrder(
context.Context,
string,
) (FreightOrderDetail, error) {
return service.orderDetail, service.err
}
func (service *fakeFreightService) GetFreightSync(
context.Context,
string,
) (FreightSync, error) {
return service.sync, service.err
}
func (service *fakeFreightService) CreateFreightSync(
_ context.Context,
input CreateFreightSyncInput,
) (FreightSync, error) {
service.createInput = input
return service.createResult, service.err
}
func (service *fakeService) ListTasks(
_ context.Context,
input ListTasksInput,