feat(platform): add device safety commerce APIs

This commit is contained in:
2026-07-27 02:47:39 +08:00
parent a3d349f734
commit 57f44e0719
5 changed files with 338 additions and 12 deletions

View File

@@ -7,9 +7,12 @@ import (
"net/http"
"net/http/httptest"
"regexp"
"strings"
"testing"
"time"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/types"
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
"github.com/DATA-DOG/go-sqlmock"
@@ -21,7 +24,7 @@ import (
func TestExpectedResources(t *testing.T) {
assertContract(t, ExpectedResources(), "gas", "gas_basic", Writable, "list")
assertContract(t, ExpectedResources(), "device", "saf_event", Writable, "list")
assertContract(t, ExpectedResources(), "safety", "saf_event", Writable, "list")
assertContract(t, ExpectedResources(), "wallet", "wallet_ledger", ReadOnly, "list")
}
@@ -159,6 +162,76 @@ func TestPlatformRoleStatusAndArchiveReturnNotFoundWhenUpdateAffectsZeroRows(t *
}
}
func TestGetEcOrderReturnsOrderItems(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "ec_order" WHERE identity = $1 ORDER BY "ec_order"."id" LIMIT $2`)).
WithArgs("order-a", 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "order_no", "user_account_id", "gas_station_id", "delivery_point_id", "total_amount"}).
AddRow(uint64(1), "order-a", nil, nil, "enabled", 1, "O-1", uint64(2), uint64(3), uint64(4), int64(500)))
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "ec_order_item" WHERE ec_order_id = $1 ORDER BY id asc`)).
WithArgs(uint64(1)).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "ec_order_id", "ec_product_id", "product_snapshot", "quantity", "sale_amount"}).
AddRow(uint64(2), "item-a", nil, nil, "enabled", 1, uint64(1), uint64(5), `{}`, 2, int64(500)))
ctx, recorder := updateContext(http.MethodGet, "/ec/ec_order/order-a", "order-a", nil)
GetEcOrder(ctx)
assertResponseCode(t, recorder, 0)
if !strings.Contains(recorder.Body.String(), `"items"`) || !strings.Contains(recorder.Body.String(), `"item-a"`) {
t.Fatalf("order detail omitted its items: %s", recorder.Body.String())
}
assertMockExpectations(t, mock)
}
func TestGetDeliveryTrackOrdersAndMasksPointsWithoutPreciseLocationScope(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
now := time.Now().UTC()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "delivery_track" WHERE identity = $1 ORDER BY "delivery_track"."id" LIMIT $2`)).
WithArgs("track-a", 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "delivery_task_id", "started_at", "completed_at"}).
AddRow(uint64(7), "track-a", nil, nil, "enabled", 1, uint64(8), now, nil))
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "delivery_track_point" WHERE delivery_track_id = $1 ORDER BY occurred_at asc`)).
WithArgs(uint64(7)).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "delivery_track_id", "point_type", "occurred_at", "longitude", "latitude"}).
AddRow(uint64(9), "point-a", nil, nil, "enabled", 1, uint64(7), "arrival", now, "120.123", "30.456"))
ctx, recorder := updateContext(http.MethodGet, "/delivery/delivery_track/track-a", "track-a", nil)
GetDeliveryTrack(ctx)
assertResponseCode(t, recorder, 0)
if strings.Contains(recorder.Body.String(), "120.123") || strings.Contains(recorder.Body.String(), "30.456") {
t.Fatalf("unauthorized response exposed precise coordinates: %s", recorder.Body.String())
}
assertMockExpectations(t, mock)
}
func TestDisposeSafetyEventUpdatesEventAndAppendsOperatorActionTransactionally(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
now := time.Now().UTC()
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "saf_event" WHERE identity = $1 ORDER BY "saf_event"."id" LIMIT $2`)).
WithArgs("event-a", 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "event_code", "level", "title", "smart_cylinder_valve_identity", "sla_at"}).
AddRow(uint64(3), "event-a", now, now, "open", 1, "E-1", 2, "alarm", "valve-a", nil))
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "saf_event" SET "status"=$1,"updated_at"=$2 WHERE identity = $3`)).
WithArgs("disposed", sqlmock.AnyArg(), "event-a").
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "saf_event_disposal" ("identity","created_at","updated_at","status","version","saf_event_identity","action","reason","operator_identity") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING "id"`)).
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), "enabled", 1, "event-a", "close", "resolved", "operator-a").
WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uint64(1)))
mock.ExpectCommit()
ctx, recorder := updateContext(http.MethodPost, "/safety/saf_event/event-a/disposals", "event-a", []byte(`{"action":"close","reason":"resolved"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
DisposeSafetyEvent(ctx)
assertResponseCode(t, recorder, 0)
if !strings.Contains(recorder.Body.String(), `"operator_identity":"operator-a"`) {
t.Fatalf("disposal omitted its operator: %s", recorder.Body.String())
}
assertMockExpectations(t, mock)
}
func TestReplacePlatformRoleMenusAllowsAnEmptySetToClearAssignmentsTransactionally(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectBegin()