This commit is contained in:
wujinliang
2026-09-18 09:16:02 +08:00
parent 522afd0185
commit 6be4e764a9
11 changed files with 211 additions and 27 deletions
@@ -2,6 +2,7 @@ package com.baiyue.iam.notification;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.iam.entity.IamMembership;
import com.baiyue.iam.entity.IamMembershipRole;
import com.baiyue.iam.entity.IamRole;
import com.baiyue.iam.entity.IamUser;
import com.baiyue.iam.mapper.IamMembershipMapper;
@@ -22,7 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
class NotificationRecipientResolverTest {
private final IamMembershipMapper memberships = mock(IamMembershipMapper.class);
@@ -70,7 +71,7 @@ class NotificationRecipientResolverTest {
@Test
void explainsWhenRoleCodeDoesNotExist() {
when(roles.selectOne(any())).thenReturn(null);
when(roles.selectList(any())).thenReturn(List.of());
assertThatThrownBy(() -> resolver.resolve(roleRequest(RecipientType.PLATFORM_ROLE, "MISSING_ROLE")))
.isInstanceOf(BizException.class)
@@ -81,7 +82,7 @@ class NotificationRecipientResolverTest {
void explainsWhenRoleHasNoActiveMembers() {
IamRole role = new IamRole();
role.setId(501L);
when(roles.selectOne(any())).thenReturn(role);
when(roles.selectList(any())).thenReturn(List.of(role));
when(membershipRoles.selectList(any())).thenReturn(List.of());
assertThatThrownBy(() -> resolver.resolve(roleRequest(RecipientType.PLATFORM_ROLE, "CUSTOMER_REVIEWER")))
@@ -89,6 +90,39 @@ class NotificationRecipientResolverTest {
.hasMessage("该角色下暂无可接收消息的有效用户,请先为角色分配启用中的成员");
}
@Test
void resolvesEnterpriseMemberAssignedToPlatformProvidedMerchantRole() {
IamRole role = new IamRole();
role.setId(501L);
role.setTenantId(0L);
role.setAppCode("MERCHANT");
role.setRoleCode("MERCHANT_OWNER");
IamMembershipRole assignment = new IamMembershipRole();
assignment.setTenantId(9L);
assignment.setRoleId(role.getId());
assignment.setMembershipId(301L);
IamMembership membership = new IamMembership();
membership.setId(301L);
membership.setTenantId(9L);
membership.setUserId(401L);
membership.setStatus("ACTIVE");
IamUser user = new IamUser();
user.setId(401L);
user.setDisplayName("企业管理员");
user.setStatus("ACTIVE");
when(roles.selectList(any())).thenReturn(List.of(role));
when(membershipRoles.selectList(any())).thenReturn(List.of(assignment));
when(memberships.selectBatchIds(List.of(301L))).thenReturn(List.of(membership));
when(users.selectById(401L)).thenReturn(user);
var recipients = resolver.resolve(new CreateNotificationRequest(9L, "ORDER_STATUS_CHANGED",
RecipientType.TENANT_ROLE, null, "MERCHANT_OWNER", Map.of(), null,
"notification-tenant-role-key", null, null));
assertThat(recipients).containsExactly(new NotificationRecipientResolver.ResolvedRecipient(
9L, 301L, 401L, "企业管理员", "MERCHANT"));
}
private CreateNotificationRequest request(RecipientType recipientType, List<Long> recipientIds) {
return new CreateNotificationRequest(9L, "ORDER_STATUS_CHANGED", recipientType, recipientIds,
null, Map.of(), null, "notification-test-key", null, null);
@@ -7,6 +7,6 @@ import java.util.Set;
import static org.assertj.core.api.Assertions.*;
class NotificationTemplateRendererTest {
private final NotificationTemplateRenderer renderer=new NotificationTemplateRenderer();
@Test void rendersOnlyWhitelistedVariables(){assertThat(renderer.render("Order {{order_no}} is {{status}}",Set.of("order_no","status"),Map.of("order_no","A1","status","ready"))).isEqualTo("Order A1 is ready");}
@Test void rejectsMissingAndUnknownVariables(){assertThatThrownBy(()->renderer.render("{{order_no}}",Set.of("order_no"),Map.of())).isInstanceOf(BizException.class).hasMessageContaining("NOTIFICATION_VARIABLE_MISSING");assertThatThrownBy(()->renderer.render("ok",Set.of(),Map.of("secret","x"))).isInstanceOf(BizException.class).hasMessageContaining("NOTIFICATION_VARIABLE_NOT_ALLOWED");}
@Test void rendersOnlyWhitelistedVariables(){assertThat(renderer.render("Order ${order_no} is {{status}}",Set.of("order_no","status"),Map.of("order_no","A1","status","ready"))).isEqualTo("Order A1 is ready");}
@Test void rejectsMissingAndUnknownVariables(){assertThatThrownBy(()->renderer.render("${order_no}",Set.of("order_no"),Map.of())).isInstanceOf(BizException.class).hasMessageContaining("NOTIFICATION_VARIABLE_MISSING");assertThatThrownBy(()->renderer.render("ok",Set.of(),Map.of("secret","x"))).isInstanceOf(BizException.class).hasMessageContaining("NOTIFICATION_VARIABLE_NOT_ALLOWED");}
}
@@ -1,6 +1,7 @@
package com.baiyue.iam.service;
import com.baiyue.iam.dto.OnboardingDtos.PlatformQualificationRegistrationRequest;
import com.baiyue.iam.dto.OnboardingDtos.RequiredQualificationPackageRequest;
import com.baiyue.iam.entity.IamTenant;
import com.baiyue.iam.entity.IamTenantQualification;
import com.baiyue.iam.repository.ProfileResourceRepository;
@@ -69,4 +70,51 @@ class PlatformQualificationRegistrationTest {
assertEquals(existing.getDocumentUrl(), response.replacedDocumentUrl());
assertEquals("PENDING", captor.getAllValues().get(1).getStatus());
}
@Test
void platformCanReplaceAnApprovedOptionalQualificationForAnActiveTenant() {
IamTenant tenant = new IamTenant();
tenant.setId(10001L); tenant.setTenantType("MERCHANT"); tenant.setStatus("ACTIVE");
IamTenantQualification existing = new IamTenantQualification();
existing.setId(88L); existing.setTenantId(10001L); existing.setQualificationType("BANK_ACCOUNT_LICENSE");
existing.setStatus("APPROVED");
existing.setDocumentUrl("/api/merchant/v1/files/qualifications/old-file.pdf");
when(tenantRepository.findTenantForUpdate(10001L)).thenReturn(tenant);
when(repository.findQualificationsForUpdate(10001L)).thenReturn(List.of(existing));
var response = service.registerPlatformQualification(new PlatformQualificationRegistrationRequest(
10001L, "BANK_ACCOUNT_LICENSE", null, "/api/merchant/v1/files/qualifications/new-file.pdf",
"new-file.pdf", LocalDate.of(2031, 12, 31), true));
ArgumentCaptor<IamTenantQualification> captor = ArgumentCaptor.forClass(IamTenantQualification.class);
verify(repository, times(2)).saveQualification(captor.capture());
assertEquals("SUPERSEDED", existing.getStatus());
assertEquals("APPROVED", captor.getAllValues().get(1).getStatus());
assertEquals("ACTIVE", response.tenantStatus());
assertEquals(existing.getDocumentUrl(), response.replacedDocumentUrl());
}
@Test
void platformCanReplaceAnApprovedBusinessLicenseForAnActiveTenant() {
IamTenant tenant = new IamTenant();
tenant.setId(10001L); tenant.setTenantType("MERCHANT"); tenant.setStatus("ACTIVE");
tenant.setUnifiedSocialCreditCode("91310101ABCDE12345");
IamTenantQualification existing = new IamTenantQualification();
existing.setId(88L); existing.setTenantId(10001L); existing.setQualificationType("BUSINESS_LICENSE");
existing.setStatus("APPROVED");
existing.setDocumentUrl("/api/merchant/v1/files/qualifications/old-license.pdf");
when(tenantRepository.findTenantForUpdate(10001L)).thenReturn(tenant);
when(repository.findQualificationsForUpdate(10001L)).thenReturn(List.of(existing));
var response = service.registerPlatformRequiredQualificationPackage(new RequiredQualificationPackageRequest(
10001L, "91310101ABCDE12345", "/api/merchant/v1/files/qualifications/new-license.pdf",
"new-license.pdf", LocalDate.of(2031, 12, 31), true, null, null, null, null));
ArgumentCaptor<IamTenantQualification> captor = ArgumentCaptor.forClass(IamTenantQualification.class);
verify(repository, times(2)).saveQualification(captor.capture());
assertEquals("SUPERSEDED", existing.getStatus());
assertEquals("APPROVED", captor.getAllValues().get(1).getStatus());
assertEquals("ACTIVE", response.tenantStatus());
assertEquals(existing.getDocumentUrl(), response.replacedBusinessLicenseDocumentUrl());
}
}