This commit is contained in:
2026-08-05 16:26:10 +08:00
parent 06f7f9d2f2
commit 5ba9716e12
155 changed files with 2883 additions and 551 deletions
@@ -23,7 +23,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SpringJUnitConfig(CustomerListExportProviderController.class)
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
@TestPropertySource(properties = "baiyue.security.internal-service-token=test-internal-service-token-at-least-32-bytes")
class CustomerListExportProviderControllerTest {
@MockBean private CustomerListExportProviderService service;
@Resource private CustomerListExportProviderController controller;
@@ -48,7 +48,7 @@ class CustomerListExportProviderControllerTest {
ExportBatchResponse batch = new ExportBatchResponse(1, "sha256:test", "snapshot",
List.of(), List.of(), null, false, 0L);
when(service.exportBatch(request)).thenReturn(batch);
var response = controller.batch("internal-token", request);
var response = controller.batch("test-internal-service-token-at-least-32-bytes", request);
assertEquals(ResultCode.SUCCESS.code(), response.code());
assertEquals(batch, response.data());
@@ -21,7 +21,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SpringJUnitConfig(InternalTenantController.class)
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
@TestPropertySource(properties = "baiyue.security.internal-service-token=test-internal-service-token-at-least-32-bytes")
class InternalCustomerExportContractTest {
@MockBean private MerchantOnboardingService onboardingService;
@MockBean private ProfileResourceService profileResourceService;
@@ -36,7 +36,7 @@ class InternalCustomerExportContractTest {
when(service.exportMerchants(null, 100, "柏悦", "ACTIVE"))
.thenReturn(new CustomerExportBatch(List.of(), null, false));
var response = controller.exportCustomers("internal-token", null, 100, "柏悦", "ACTIVE");
var response = controller.exportCustomers("test-internal-service-token-at-least-32-bytes", null, 100, "柏悦", "ACTIVE");
assertEquals(ResultCode.SUCCESS.code(), response.code());
verify(service).exportMerchants(null, 100, "柏悦", "ACTIVE");
}
@@ -0,0 +1,34 @@
package com.baiyue.iam.controller;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.jupiter.api.Assertions.assertThrows;
class InternalServiceTokenConfigurationTest {
@Test
void internalTenantControllerRejectsEmptyAndShortTokens() {
assertInternalTenantTokenRejected(null);
assertInternalTenantTokenRejected("");
assertInternalTenantTokenRejected("short-token");
}
@Test
void customerExportControllerRejectsEmptyAndShortTokens() {
assertCustomerExportTokenRejected(null);
assertCustomerExportTokenRejected("");
assertCustomerExportTokenRejected("short-token");
}
private void assertInternalTenantTokenRejected(String token) {
InternalTenantController controller = new InternalTenantController();
ReflectionTestUtils.setField(controller, "internalTokenValue", token);
assertThrows(IllegalStateException.class, controller::initializeToken);
}
private void assertCustomerExportTokenRejected(String token) {
CustomerListExportProviderController controller = new CustomerListExportProviderController();
ReflectionTestUtils.setField(controller, "internalTokenValue", token);
assertThrows(IllegalStateException.class, controller::initializeToken);
}
}
@@ -51,7 +51,7 @@ class CustomerProfileMigrationContractTest {
@Test
void shouldHandleCase03() throws IOException {
Path repositoryRoot = Path.of(System.getProperty("maven.multiModuleProjectDirectory", ".."));
Path migration = repositoryRoot.resolve("deploy/sql/2026-07-31一期回归测试环境增量迁移.sql");
Path migration = repositoryRoot.resolve("deploy/sql/头程数据库统一增量-MySQL8.sql");
Path readme = repositoryRoot.resolve("deploy/sql/README.md");
assertThat(migration).exists();
@@ -60,27 +60,18 @@ class CustomerProfileMigrationContractTest {
String instructions = Files.readString(readme, StandardCharsets.UTF_8);
assertThat(sql)
.contains("CALL regression_assert_table('iam_tenant')")
.contains("CALL regression_assert_table('iam_tenant_review')")
.contains("CALL regression_assert_table('iam_tenant_qualification')")
.contains("ALTER TABLE iam_tenant MODIFY COLUMN status")
.contains("DEFAULT 'PROFILE_REQUIRED'")
.contains("CREATE PROCEDURE regression_add_iam_column")
.contains("regression_add_iam_column('approved_at'")
.contains("regression_add_iam_column('approved_by'")
.contains("regression_add_iam_column('reject_reason'")
.contains("regression_add_iam_related_column('iam_tenant_qualification', 'review_comment'")
.contains("'IAM注册审核字段'")
.contains("'IAM资质与成员审计字段'")
.contains("CALL phase1_iam_add_column('iam_tenant', 'approved_at'")
.contains("CALL phase1_iam_add_column('iam_tenant', 'approved_by'")
.contains("CALL phase1_iam_add_column('iam_tenant', 'reject_reason'")
.contains("CALL phase1_iam_add_column('iam_tenant_qualification', 'review_comment'")
.contains("platform:customer:view")
.contains("platform:customer:export")
.contains("platform:download:list")
.contains("'MERCHANT_OWNER'")
.contains("IAM全局企业管理员模板")
.contains("owner_role.id, permission.id, 0")
.contains("'IAM客户档案字段' AS check_item")
.contains("10 AS expected_count")
.contains("47 AS expected_count")
.contains("MIGRATION_COMPLETED");
.contains("统一增量全部执行完成");
assertThat(instructions)
.contains("phase1-platform-master-data-and-permission-management.sql")
.contains("phase1-customer-profile.sql")
@@ -0,0 +1,38 @@
package com.baiyue.iam.service;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.security.AuthenticatedUser;
import org.junit.jupiter.api.Test;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class TenantGuardTest {
@Test
void acceptsPlatformOnlyAtZeroTenant() {
assertEquals(0L, TenantGuard.tenant(user(0L, "PLATFORM"), "PLATFORM"));
BizException exception = assertThrows(BizException.class,
() -> TenantGuard.tenant(user(10001L, "PLATFORM"), "PLATFORM"));
assertEquals(ResultCode.FORBIDDEN, exception.getResultCode());
}
@Test
void acceptsMerchantOnlyAtPositiveCustomerTenant() {
assertEquals(10001L, TenantGuard.tenant(user(10001L, "MERCHANT"), "MERCHANT"));
BizException exception = assertThrows(BizException.class,
() -> TenantGuard.tenant(user(0L, "MERCHANT"), "MERCHANT"));
assertEquals(ResultCode.FORBIDDEN, exception.getResultCode());
}
private AuthenticatedUser user(long tenantId, String appCode) {
return new AuthenticatedUser(42L, tenantId, tenantId, 9L,
"operator", appCode, appCode, Set.of());
}
}
@@ -4,6 +4,7 @@ import com.baiyue.common.core.api.PageResult;
import com.baiyue.iam.entity.IamTenant;
import com.baiyue.iam.dto.TenantDtos.ChangeTenantStatusRequest;
import com.baiyue.iam.dto.TenantDtos.UpdateTenantRequest;
import com.baiyue.iam.dto.TenantDtos.UpdateProfileRequest;
import com.baiyue.iam.dto.TenantDtos.RegisterRequest;
import com.baiyue.iam.entity.IamTenantQualification;
import com.baiyue.iam.entity.IamTenantReview;
@@ -122,6 +123,23 @@ class TenantServiceTest {
assertEquals(ResultCode.CONFLICT, exception.getResultCode());
}
@Test
void merchantProfileCannotReadOrUpdatePlatformTenant() {
IamTenant platform = new IamTenant();
platform.setId(0L);
platform.setTenantType("PLATFORM");
when(repository.findTenant(0L)).thenReturn(platform);
BizException readFailure = assertThrows(BizException.class, () -> service.profile(0L));
BizException updateFailure = assertThrows(BizException.class, () -> service.update(0L,
new UpdateProfileRequest("Platform", "Platform", "Owner", "Contact",
"13800138000", "platform@example.com")));
assertEquals(ResultCode.NOT_FOUND, readFailure.getResultCode());
assertEquals(ResultCode.NOT_FOUND, updateFailure.getResultCode());
verify(repository, never()).saveTenant(platform);
}
@Test
void platformRegistrationCreatesDraftWithoutCreatingReviewTicket() {