Files
baiyue-firstleg/iam/src/test/java/com/baiyue/iam/controller/IamOpenApiContractTest.java
T
2026-10-19 17:56:36 +08:00

118 lines
7.4 KiB
Java

package com.baiyue.iam.controller;
import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
class IamOpenApiContractTest {
/** 核对当前授权接口公开说明,整车写权限独立且客户派送只读。 */
@Test
void shouldHandleCase01() throws IOException {
String document;
try (var stream = getClass().getResourceAsStream("/openapi/iam-v1.yaml")) {
assertThat(stream).isNotNull();
document = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
}
assertThat(document).contains("/api/platform/v1/iam/authorization/permissions:")
.contains("/api/merchant/v1/iam/authorization/permissions:")
.contains("platform:overseas-warehouse:dispatch:list")
.contains("platform:overseas-warehouse:dispatch:create")
.contains("platform:overseas-warehouse:dispatch:loading-complete")
.contains("platform:overseas-warehouse:dispatch:depart")
.contains("platform:overseas-warehouse:dispatch:edit")
.contains("platform:overseas-warehouse:dispatch:cancel")
.contains("platform:overseas-warehouse:dispatch:transfer-delivery")
.contains("platform:overseas-warehouse:outbound:list")
.contains("platform:overseas-warehouse:outbound:create")
.contains("platform:overseas-warehouse:delivery:list")
.contains("platform:overseas-warehouse:delivery:return")
.contains("platform:overseas-warehouse:delivery:status")
.contains("platform:overseas-warehouse:delivery:documents")
.contains("读取和下载仍使用 `platform:overseas-warehouse:delivery:list`")
.contains("platform:overseas-warehouse:exception-order:list")
.contains("platform:overseas-warehouse:exception-order:create")
.contains("platform:overseas-warehouse:exception-order:process")
.contains("platform:overseas-warehouse:customer-visit:list")
.contains("platform:overseas-warehouse:customer-visit:edit")
.contains("platform:overseas-warehouse:outbound:cancel")
.contains("platform:firstleg:container:list/create/edit")
.contains("platform:firstleg:terminal-drayage:list")
.contains("platform:firstleg:terminal-drayage:document:edit")
.contains("platform:firstleg:terminal-drayage:fleet:edit")
.contains("platform:firstleg:terminal-drayage:pickup-appointment:edit")
.contains("platform:firstleg:terminal-drayage:empty-return:confirm")
.contains("不以 `container:list/edit` 兼容放行国外操作")
.contains("merchant:warehouse:delivery:list")
.doesNotContain("merchant:warehouse:delivery:create")
.contains("merchant:cross-border:procurement:list")
.contains("merchant:cross-border:domestic-trucking:list")
.contains("merchant:cross-border:pallet-shipping:list")
.contains("merchant:warehouse:inbound:list")
.contains("lastleg:pda:operate")
.contains("OVERSEAS_WAREHOUSE_PDA_OPERATOR")
.contains("merchant:finance:account:view")
.contains("merchant:finance:recharge:create")
.contains("platform:finance:recharge:review")
.contains("platform:finance:customer-account:adjust")
.contains("platform:firstleg:inbound:hold")
.contains("不会由 `platform:firstleg:inbound:list` 查看权限自动获得")
.contains("两者独立授权")
.contains("列表权限包含详情只读")
.contains("PermissionCodesApiResponse:")
.contains("TenantPageApiResponse:")
.contains("TenantApiResponse:")
.contains("PendingEnterpriseReviewListApiResponse:")
.contains("PendingEnterpriseReviewResponse:")
.contains("required: [id, tenantId, reviewType, status, tenantName, tenantCode, contactName, submittedAt]")
.contains("submittedAt: {type: string, format: date-time, description: 提交审核时间}")
.contains("TenantSuccess:")
.contains("salesOwnerName:")
.contains("paymentTermDays:")
.contains("registeredCapitalCurrency:")
.contains("createdAt: {type: string, format: date-time, description: 入驻时间}")
.contains("id: {type: string, pattern: '^\\d+$'")
.contains("/api/platform/v1/iam/tenants/{tenantId}/addresses:")
.contains("/api/platform/v1/iam/tenants/{tenantId}/qualifications:")
.contains("/api/platform/v1/iam/tenants/{tenantId}/qualifications/{qualificationId}:")
.contains("/api/merchant/v1/iam/tenant/qualifications/{qualificationId}:")
.contains("originalFileName: {type: string, description: 上传时原始文件名;前端不得从 URL 或内部 ID 推断}")
.contains("updatedAt: {type: string, format: date-time}")
.contains("仅客户状态为 `PROFILE_REQUIRED` 或 `REJECTED` 时允许")
.contains("merchant:qualification:upload")
.contains("platform:customer:list")
.doesNotContain("platform:customer:view")
.contains("TenantAddressListApiResponse:")
.contains("TenantQualificationListApiResponse:")
.contains("InternalUserListApiResponse:")
.contains("MerchantMemberResponse:")
.contains("username: {type: string, description: 统一认证登录账号}")
.contains("lastLoginAt: {type: string, format: date-time, nullable: true")
.contains("RoleResponse:")
.contains("memberCount: {type: integer, format: int64, minimum: 0")
.contains("/api/platform/v1/iam/internal-users/{membershipId}/roles:")
.contains("AssignInternalUserRolesRequest:")
.contains("/api/merchant/v1/iam/members/{membershipId}:")
.contains("仅当 roleIds 与当前角色集合实际不同时额外要求 merchant:member:grant-role")
.contains("传空数组清空角色也属于角色变更")
.contains("roleIds 为服务端实时查询的当前角色集合")
.contains("UpdateMemberRequest:")
.contains("membershipId: {type: integer, format: int64}")
.contains("roleIds: {type: array, items: {type: integer, format: int64}}")
.contains("/api/platform/v1/iam/tenants/administrator-phone-availability:")
.doesNotContain("/api/platform/v1/iam/tenants/contact-phone-availability:")
.contains("公司联系电话,不作为登录标识且不要求跨企业唯一")
.contains("法人身份证、货代资质证书和银行开户许可证选填")
.contains("'422': {$ref: '#/components/responses/UnprocessableEntity'}");
Map<String, Object> openApi = new Yaml().load(document);
assertThat(openApi).containsEntry("openapi", "3.0.3");
assertThat(openApi.get("paths")).isInstanceOf(Map.class);
}
}