package com.baiyue.lastleg.merchant; import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; import static org.assertj.core.api.Assertions.assertThat; class MerchantOverseasOpenApiContractTest { @Test void documentsFrozenMerchantPathsPermissionsResponsesAndConflictSemantics() throws Exception { String yaml; try (var input = getClass().getResourceAsStream("/openapi/overseas-business-v1.yaml")) { assertThat(input).isNotNull(); yaml = new String(input.readAllBytes(), StandardCharsets.UTF_8); } for (String path : new String[] { "/api/merchant/v1/last-leg/orders:", "/api/merchant/v1/last-leg/orders/{id}:", "/api/merchant/v1/last-leg/warehouse-transfers:", "/api/merchant/v1/last-leg/warehouse-transfers/{transferNo}:", "/api/merchant/v1/last-leg/warehouse-transfers/{transferNo}/confirm-measurement:", "/api/merchant/v1/last-leg/cargo-discards:", "/api/merchant/v1/last-leg/cargo-discards/inventory-candidates:", "/api/merchant/v1/last-leg/cargo-discards/{discardNo}:", "/api/merchant/v1/last-leg/cargo-discards/{discardNo}/cancel:", "/api/merchant/v1/last-leg/overseas-procurements:", "/api/merchant/v1/last-leg/overseas-procurements/{orderNo}:", "/api/merchant/v1/last-leg/us-truck-orders:", "/api/merchant/v1/last-leg/us-truck-orders/{orderNo}:", "/api/merchant/v1/last-leg/local-looseboard-orders:", "/api/merchant/v1/last-leg/local-looseboard-orders/{orderNo}:", "/api/merchant/v1/last-leg/inbound-plans:", "/api/merchant/v1/last-leg/inbound-plans/{planNo}:", "/api/merchant/v1/last-leg/return-orders/{returnNo}/photos/files/{fileId}/download:"}) { assertThat(yaml).contains(path); assertThat(pathBlock(yaml, path)).doesNotContain("name: customerId"); } assertThat(yaml).contains("merchant:cross-border:procurement:list") .contains("merchant:cross-border:procurement:create") .contains("merchant:cross-border:domestic-trucking:list") .contains("merchant:cross-border:domestic-trucking:create") .contains("merchant:cross-border:domestic-trucking:edit") .contains("merchant:cross-border:pallet-shipping:list") .contains("merchant:cross-border:pallet-shipping:create") .contains("merchant:cross-border:pallet-shipping:edit") .contains("merchant:overseas-warehouse:last-mile-order:list") .contains("merchant:overseas-warehouse:transfer:list") .contains("merchant:overseas-warehouse:transfer:create") .contains("merchant:overseas-warehouse:transfer:confirm") .contains("merchant:overseas-warehouse:discard:list") .contains("merchant:overseas-warehouse:discard:create") .contains("merchant:overseas-warehouse:discard:cancel") .contains("merchant:overseas-warehouse:relabel:list") .contains("merchant:overseas-warehouse:relabel:create") .contains("merchant:overseas-warehouse:relabel:files") .contains("merchant:overseas-warehouse:relabel:confirm") .contains("merchant:overseas-warehouse:return-order:list") .contains("merchant:overseas-warehouse:return-order:create") .contains("merchant:overseas-warehouse:return-order:relabel") .contains("merchant:warehouse:inbound:list") .contains("#/components/schemas/ProcurementDetailResponse") .contains("#/components/schemas/TruckDetailResponse") .contains("#/components/schemas/LooseboardDetailResponse") .contains("#/components/schemas/InboundPlanDetailResponse") .contains("overseasWarehouseCode: { type: string, description: 接柜仓编码,取自尾程订单预分配接收仓事实 }") .contains("overseasWarehouseName: { type: string, description: 接柜仓名称,取自尾程订单预分配接收仓事实 }") .contains("PENDING_REVIEW").contains("PENDING_ACCEPTANCE") .contains("version 必填").contains("幂等冲突"); assertThat(yaml).contains("/api/platform/v1/last-leg/inbound-plans:") .contains("/api/platform/v1/last-leg/inbound-plans/{planNo}:") .contains("overseasWarehouseCode/overseasWarehouseName 只取该客户尾程订单预分配接柜仓事实") .contains("客户范围只取认证 Token,不接收 customerId"); } private static String pathBlock(String yaml, String path) { int start = yaml.indexOf(" " + path); int end = yaml.indexOf("\n /api/", start + path.length()); return yaml.substring(start, end < 0 ? yaml.length() : end); } }