This commit is contained in:
2026-08-08 13:32:20 +08:00
parent 96788e10de
commit 3203adb5a7
73 changed files with 44331 additions and 26 deletions
@@ -0,0 +1,67 @@
package com.baiyue.iam.repository;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
class LocationPermissionSqlContractTest {
@Test
void acceptsKnownPollutionAndRestoresCanonicalPermissionIds() throws Exception {
assertRepairContract(moduleSql());
assertRepairContract(unifiedSql());
}
private static void assertRepairContract(String sql) {
assertThat(sql)
.contains("permission_code = 'platform:download:list' AND parent_id = 5103000")
.contains("permission_code = 'platform:location:list' AND parent_id = 5103000")
.contains("permission_code = 'platform:download:all' AND parent_id = 5103040")
.contains("permission_code = 'platform:location:create' AND parent_id = 5103040")
.contains("库位权限迁移失败:下载中心稳定 ID 被未知权限占用")
.contains("(5103040, 0, 'PLATFORM', 'MENU', 5103000, 'platform:download:list'")
.contains("(5103041, 0, 'PLATFORM', 'BUTTON', 5103040, 'platform:download:all'")
.contains("(5103060, 0, 'PLATFORM', 'MENU', 5103000, 'platform:location:list'")
.contains("(5103061, 0, 'PLATFORM', 'BUTTON', 5103060, 'platform:location:create'");
int snapshot = sql.indexOf("INSERT IGNORE INTO tmp_location_role_grant");
int delete = firstPositive(
sql.indexOf("DELETE role_permission", snapshot),
sql.indexOf("DELETE rp", snapshot));
int canonicalLocation = sql.indexOf("(5103060, 0, 'PLATFORM'", delete);
int restore = sql.indexOf("FROM tmp_location_role_grant", canonicalLocation);
int cleanup = sql.indexOf("DROP TEMPORARY TABLE IF EXISTS tmp_location_role_grant", restore);
assertThat(snapshot).isGreaterThan(0);
assertThat(delete).isGreaterThan(snapshot);
assertThat(canonicalLocation).isGreaterThan(delete);
assertThat(restore).isGreaterThan(canonicalLocation);
assertThat(cleanup).isGreaterThan(restore);
}
private static String moduleSql() throws Exception {
return new ClassPathResource("db/phase2-location-permissions.sql")
.getContentAsString(StandardCharsets.UTF_8);
}
private static int firstPositive(int left, int right) {
if (left < 0) {
return right;
}
if (right < 0) {
return left;
}
return Math.min(left, right);
}
private static String unifiedSql() throws Exception {
Path path = Path.of("deploy/sql/头程数据库统一增量-MySQL8.sql");
if (!Files.exists(path)) {
path = Path.of("../deploy/sql/头程数据库统一增量-MySQL8.sql").normalize();
}
return Files.readString(path, StandardCharsets.UTF_8);
}
}
@@ -40,6 +40,7 @@ class MerchantOnboardingServiceTest {
@MockBean private IamTenantQualificationMapper qualifications;
@MockBean private IamTenantReviewMapper reviews;
@MockBean private CustomerDimensionRuleInitializationService dimensionRuleInitialization;
@MockBean private OverseasStorageFeeInitializationService overseasStorageFeeInitialization;
@Resource private MerchantOnboardingService service;
@Test
void clientRegistrationCreatesOwnerAndAssignsGlobalMerchantOwnerRole() {
@@ -65,6 +66,7 @@ class MerchantOnboardingServiceTest {
verify(memberships).insert(membership.capture());
verify(membershipRoles).insert(roleGrant.capture());
verify(dimensionRuleInitialization).initialize(result.tenantId(), 9001L);
verify(overseasStorageFeeInitialization).initialize(result.tenantId(), 9001L);
assertEquals("PROFILE_REQUIRED", result.tenantStatus());
assertEquals(result.tenantId(), tenant.getValue().getId());
@@ -0,0 +1,42 @@
package com.baiyue.iam.service;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.iam.client.OverseasStorageFeeClient;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SpringJUnitConfig(OverseasStorageFeeInitializationService.class)
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
class OverseasStorageFeeInitializationServiceTest {
@MockBean private OverseasStorageFeeClient client;
@Resource private OverseasStorageFeeInitializationService service;
@AfterEach void clearTransaction() {
if (TransactionSynchronizationManager.isSynchronizationActive()) TransactionSynchronizationManager.clearSynchronization();
}
@Test void retriesThreeTimesWithDeterministicKey() {
when(client.initialize(anyString(), any())).thenThrow(new RuntimeException("timeout"));
when(client.compensate(anyString(), anyLong(), anyString())).thenReturn(ApiResponse.success(null));
BizException error = assertThrows(BizException.class, () -> service.initialize(208L, 9L));
assertEquals(ResultCode.SERVICE_UNAVAILABLE, error.getResultCode());
verify(client, times(3)).initialize(anyString(), any(OverseasStorageFeeClient.InitializationRequest.class));
verify(client).compensate("internal-token", 208L, "iam-customer-create-overseas-fee:208");
}
}
@@ -26,6 +26,7 @@ class TenantCustomerExportTest {
@MockBean private AuthAccountClient authAccountClient;
@MockBean private TenantApprovalInitializationCoordinator approvalInitialization;
@MockBean private CustomerDimensionRuleInitializationService dimensionRuleInitialization;
@MockBean private OverseasStorageFeeInitializationService overseasStorageFeeInitialization;
@MockBean private TenantAdministratorProvisioningService administratorProvisioning;
@Resource private TenantService service;
@Test
@@ -54,6 +54,7 @@ class TenantServiceTest {
@MockBean private IamRoleMapper roles;
@MockBean private AuthAccountClient authClient;
@MockBean private CustomerDimensionRuleInitializationService dimensionRuleInitialization;
@MockBean private OverseasStorageFeeInitializationService overseasStorageFeeInitialization;
@SpyBean private TenantAdministratorProvisioningService provisioning;
@Resource private TenantService service;