mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-07 02:57:51 +00:00
test(auth): verify organization creation rollback
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
parent
52e4e052a1
commit
1e2de2798b
2 changed files with 52 additions and 2 deletions
|
|
@ -6,6 +6,6 @@
|
|||
|
||||
## Verification
|
||||
|
||||
- [x] 集成测试覆盖成功、仅 owner 可进入组织详情、非管理员、禁用/不存在 owner 和重复 slug。
|
||||
- [x] 集成测试覆盖成功、仅 owner 可进入组织详情、非管理员、禁用/不存在 owner、重复 slug,以及审计失败时四类写入的事务回滚。
|
||||
- [x] 完整后端测试、Web typecheck/lint 和 OpenSpec strict validation 通过。
|
||||
- [ ] 检查最终 diff、敏感信息、精确 SHA 与预览环境;经人工评审后再提 PR/合并。
|
||||
- [ ] 核对 PR 最终 diff、敏感信息、精确 SHA 与预览环境;完成评审和合并前验收。
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
package com.iflytek.skillhub.controller.admin;
|
||||
|
||||
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.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
|
@ -10,6 +15,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||
|
||||
import com.iflytek.skillhub.auth.device.DeviceAuthService;
|
||||
import com.iflytek.skillhub.auth.rbac.PlatformPrincipal;
|
||||
import com.iflytek.skillhub.domain.audit.AuditLogService;
|
||||
import com.iflytek.skillhub.domain.audit.AuditLog;
|
||||
import com.iflytek.skillhub.domain.organization.Organization;
|
||||
import com.iflytek.skillhub.domain.organization.OrganizationMembership;
|
||||
|
|
@ -17,6 +23,8 @@ import com.iflytek.skillhub.domain.organization.OrganizationRole;
|
|||
import com.iflytek.skillhub.domain.organization.OrganizationRoleBinding;
|
||||
import com.iflytek.skillhub.domain.user.UserAccount;
|
||||
import com.iflytek.skillhub.domain.user.UserStatus;
|
||||
import com.iflytek.skillhub.dto.OrganizationCreateRequest;
|
||||
import com.iflytek.skillhub.service.PlatformOrganizationCreateAppService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
|
@ -27,12 +35,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
|
|
@ -46,6 +57,15 @@ class PlatformOrganizationControllerTest {
|
|||
@Autowired
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
@Autowired
|
||||
private PlatformOrganizationCreateAppService appService;
|
||||
|
||||
@SpyBean
|
||||
private AuditLogService auditLogService;
|
||||
|
||||
@MockBean
|
||||
private DeviceAuthService deviceAuthService;
|
||||
|
||||
|
|
@ -185,6 +205,31 @@ class PlatformOrganizationControllerTest {
|
|||
assertThat(organizationCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void create_rollsBackAllWritesWhenAuditFails() {
|
||||
transactionTemplate.executeWithoutResult(status -> persistUser("rollback-owner"));
|
||||
long organizationsBefore = count("Organization");
|
||||
long membershipsBefore = count("OrganizationMembership");
|
||||
long rolesBefore = count("OrganizationRoleBinding");
|
||||
long auditsBefore = count("AuditLog");
|
||||
|
||||
doThrow(new IllegalStateException("forced audit failure"))
|
||||
.when(auditLogService).recordOrganizationCreated(
|
||||
eq("platform-admin"), anyString(), any());
|
||||
|
||||
assertThatThrownBy(() -> appService.create(
|
||||
new OrganizationCreateRequest("rollback-team", "Rollback Team", "rollback-owner"),
|
||||
"platform-admin"))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("forced audit failure");
|
||||
|
||||
assertThat(count("Organization")).isEqualTo(organizationsBefore);
|
||||
assertThat(count("OrganizationMembership")).isEqualTo(membershipsBefore);
|
||||
assertThat(count("OrganizationRoleBinding")).isEqualTo(rolesBefore);
|
||||
assertThat(count("AuditLog")).isEqualTo(auditsBefore);
|
||||
}
|
||||
|
||||
private UserAccount persistUser(String userId) {
|
||||
UserAccount user = new UserAccount(userId, userId, userId + "@example.com", "");
|
||||
entityManager.persist(user);
|
||||
|
|
@ -198,6 +243,11 @@ class PlatformOrganizationControllerTest {
|
|||
.getSingleResult();
|
||||
}
|
||||
|
||||
private long count(String entityName) {
|
||||
return entityManager.createQuery("select count(e) from " + entityName + " e", Long.class)
|
||||
.getSingleResult();
|
||||
}
|
||||
|
||||
private String request(String slug, String displayName, String owner) {
|
||||
return "{\"slug\":\"" + slug + "\",\"displayName\":\"" + displayName
|
||||
+ "\",\"initialOwnerUserId\":\"" + owner + "\"}";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue