package routers import ( "net/http" "testing" "github.com/gin-gonic/gin" ) func TestPlatformGasRouteUsesGasBasic(t *testing.T) { engine := gin.New() RegisterPlatform("heqi", engine) for _, route := range engine.Routes() { if route.Path == "/heqi/platform/v1/gas/gas_station" { t.Fatal("gas station route must use gas_basic as its resource name") } if route.Method == "GET" && route.Path == "/heqi/platform/v1/gas/gas_basic" { return } } t.Fatal("gas_basic list route is not registered") } func TestPlatformOrganizationAndAccountRoutesExposeResourceCRUD(t *testing.T) { engine := gin.New() RegisterPlatform("heqi", engine) routes := make(map[string]map[string]bool) for _, route := range engine.Routes() { if routes[route.Path] == nil { routes[route.Path] = make(map[string]bool) } routes[route.Path][route.Method] = true } for _, resource := range []string{ "/gas/gas_basic", "/gas/gas_account", "/delivery/delivery_basic", "/delivery/delivery_account", "/staff/account", "/staff/credential", "/user/account", "/user/address", "/user/service_relation", "/platform/platfrom_account", "/platform/platform_role", "/platform/platform_menu", } { assertRouteMethods(t, routes, "/heqi/platform/v1"+resource, http.MethodGet, http.MethodPost) assertRouteMethods(t, routes, "/heqi/platform/v1"+resource+"/:identity", http.MethodGet, http.MethodPut, http.MethodDelete) assertRouteMethods(t, routes, "/heqi/platform/v1"+resource+"/:identity/status", http.MethodPatch) } assertRouteMethods(t, routes, "/heqi/platform/v1/platform/platform_role/:identity/menus", http.MethodPut) } func TestPlatformDeviceSafetyCommerceAndDeliveryRoutesFollowTheirContracts(t *testing.T) { engine := gin.New() RegisterPlatform("heqi", engine) routes := make(map[string]map[string]bool) for _, route := range engine.Routes() { if routes[route.Path] == nil { routes[route.Path] = make(map[string]bool) } routes[route.Path][route.Method] = true } for _, resource := range []string{ "/device/dev_smart_cylinder_valve", "/device/dev_device_binding", "/safety/saf_rule", "/safety/saf_event", "/safety/saf_inspection", "/ec/ec_category", "/ec/ec_product", "/ec/ec_product_attribute", "/ec/ec_product_image", "/ec/ec_cart", "/ec/ec_order", "/ec/ec_order_item", "/ec/ec_review", "/delivery/delivery_task", "/delivery/delivery_track", "/delivery/delivery_track_point", } { assertRouteMethods(t, routes, "/heqi/platform/v1"+resource, http.MethodGet, http.MethodPost) assertRouteMethods(t, routes, "/heqi/platform/v1"+resource+"/:identity", http.MethodGet, http.MethodPut, http.MethodDelete) assertRouteMethods(t, routes, "/heqi/platform/v1"+resource+"/:identity/status", http.MethodPatch) } telemetry := "/heqi/platform/v1/device/dev_telemetry" assertRouteMethods(t, routes, telemetry, http.MethodGet) assertRouteMethods(t, routes, telemetry+"/:identity", http.MethodGet) for _, method := range []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete} { if routes[telemetry][method] || routes[telemetry+"/:identity"][method] { t.Errorf("telemetry unexpectedly permits %s", method) } } disposal := "/heqi/platform/v1/safety/saf_event/:identity/disposals" assertRouteMethods(t, routes, disposal, http.MethodPost) if routes[disposal][http.MethodDelete] { t.Fatal("safety event disposals must be append-only") } } func TestPlatformFinanceContentAndAuditRoutesFollowTheirContracts(t *testing.T) { engine := gin.New() RegisterPlatform("heqi", engine) routes := make(map[string]map[string]bool) for _, route := range engine.Routes() { if routes[route.Path] == nil { routes[route.Path] = make(map[string]bool) } routes[route.Path][route.Method] = true } for _, resource := range []string{ "/finance/fin_payment", "/finance/fin_settlement", "/finance/fin_reconciliation", "/content/cnt_content", "/notification/ntf_template", "/customer_service/cs_ticket", } { assertRouteMethods(t, routes, "/heqi/platform/v1"+resource, http.MethodGet, http.MethodPost) assertRouteMethods(t, routes, "/heqi/platform/v1"+resource+"/:identity", http.MethodGet, http.MethodPut, http.MethodDelete) assertRouteMethods(t, routes, "/heqi/platform/v1"+resource+"/:identity/status", http.MethodPatch) } for _, resource := range []string{ "/wallet/wallet", "/wallet/wallet_ledger", "/wallet/wallet_recharge", "/wallet/wallet_withdrawal", "/report/report", "/report/report_item", "/report/report_metric_snapshot", "/audit/aud_operation_log", "/audit/aud_export_log", "/audit/aud_approval", } { path := "/heqi/platform/v1" + resource assertRouteMethods(t, routes, path, http.MethodGet) assertRouteMethods(t, routes, path+"/:identity", http.MethodGet) for _, method := range []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete} { if routes[path][method] || routes[path+"/:identity"][method] { t.Errorf("read-only resource %s unexpectedly permits %s", resource, method) } } } assertRouteMethods(t, routes, "/heqi/platform/v1/audit/aud_approval/:identity/approve", http.MethodPost) } func assertRouteMethods(t *testing.T, routes map[string]map[string]bool, path string, methods ...string) { t.Helper() for _, method := range methods { if !routes[path][method] { t.Errorf("route %s %s is not registered", method, path) } } }