| | |
| | | import org.springframework.test.util.ReflectionTestUtils; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | |
| | | |
| | | /** 编辑公司用例共享的远程账号客户端 mock,供 verify 使用 */ |
| | | private SysUserClient editUserClient; |
| | | |
| | | /** 新增公司用例共享的远程账号客户端 mock,供 verify 使用 */ |
| | | private SysUserClient addUserClient; |
| | | |
| | | @BeforeAll |
| | | static void initTableInfo() { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 添加/编辑企业弹窗不再配置账户模式:未传账户模式时按共享模式(1)建档 |
| | | * 添加/编辑企业弹窗不再配置账户模式:未传账户模式时按共享模式(1)建档; |
| | | * 登录账号由系统自动生成(忽略前端传入值),并随返回体回显 |
| | | */ |
| | | @Test |
| | | void addCompanyDefaultsAccountModeToSharedWhenAbsent() { |
| | |
| | | company.setName("测试公司"); |
| | | |
| | | TGroupCompanyServiceImpl service = buildAddCompanyService(); |
| | | assertEquals(200, code(service.addCompany(company))); |
| | | AjaxResult result = service.addCompany(company); |
| | | assertEquals(200, code(result)); |
| | | |
| | | ArgumentCaptor<TGroupCompany> captor = ArgumentCaptor.forClass(TGroupCompany.class); |
| | | Mockito.verify(service).save(captor.capture()); |
| | | assertEquals(1, captor.getValue().getAccountMode()); |
| | | // 账号不可由前端指定:传入值被系统生成值覆盖 |
| | | assertTrue(captor.getValue().getAccount().matches("admin\\d{4}")); |
| | | assertTrue(!captor.getValue().getAccount().equals("company01")); |
| | | assertEquals(captor.getValue().getAccount(), String.valueOf(result.get("data"))); |
| | | } |
| | | |
| | | /** |
| | |
| | | ArgumentCaptor<TGroupCompany> captor = ArgumentCaptor.forClass(TGroupCompany.class); |
| | | Mockito.verify(service).save(captor.capture()); |
| | | assertEquals(2, captor.getValue().getAccountMode()); |
| | | // 账号仍为系统生成值,而非前端传入值 |
| | | assertTrue(captor.getValue().getAccount().matches("admin\\d{4}")); |
| | | assertTrue(!captor.getValue().getAccount().equals("company02")); |
| | | } |
| | | |
| | | /** |
| | | * 新增公司:登录账号自动生成 admin+4位随机数字,初始密码按登录口径 HMAC-MD5 传输, |
| | | * 生成账号随返回体回显 |
| | | */ |
| | | @Test |
| | | void addCompanyGeneratesAccountAndDefaultPassword() { |
| | | TGroupCompany company = new TGroupCompany(); |
| | | company.setName("测试公司"); |
| | | |
| | | TGroupCompanyServiceImpl service = buildAddCompanyService(); |
| | | AjaxResult result = service.addCompany(company); |
| | | assertEquals(200, code(result)); |
| | | |
| | | assertTrue(company.getAccount().matches("admin\\d{4}")); |
| | | assertEquals(company.getAccount(), String.valueOf(result.get("data"))); |
| | | |
| | | ArgumentCaptor<SysUser> userCaptor = ArgumentCaptor.forClass(SysUser.class); |
| | | Mockito.verify(addUserClient).addSysUser(userCaptor.capture()); |
| | | SysUser created = userCaptor.getValue(); |
| | | assertEquals(company.getAccount(), created.getUserName()); |
| | | // 初始密码 123456:HMAC-MD5(明文, password),与登录/重置链路口径一致 |
| | | assertEquals(hmacMd5Expected("123456", "password"), created.getPassword()); |
| | | } |
| | | |
| | | /** |
| | | * 生成候选账号被 sys_user 占用时换号重试,最终以未占用账号建户 |
| | | */ |
| | | @Test |
| | | void addCompanyRetriesWhenCandidateAccountOccupied() { |
| | | TGroupCompany company = new TGroupCompany(); |
| | | company.setName("测试公司"); |
| | | |
| | | SysUserClient sysUserClient = Mockito.mock(SysUserClient.class); |
| | | SysUser occupied = new SysUser(); |
| | | occupied.setUserId(9L); |
| | | // 首个候选账号被占用,第二个候选通过 |
| | | Mockito.when(sysUserClient.queryUserByUserName(Mockito.any())) |
| | | .thenReturn(R.ok(occupied), R.ok()); |
| | | Mockito.when(sysUserClient.addSysUser(Mockito.any())).thenReturn(R.ok(100L)); |
| | | Mockito.when(sysUserClient.getSysUser(Mockito.anyLong())).thenReturn(R.ok()); |
| | | |
| | | SysRoleClient sysRoleClient = Mockito.mock(SysRoleClient.class); |
| | | Mockito.when(sysRoleClient.getRoleIdByRoleKey(Mockito.any())).thenReturn(R.ok(74L)); |
| | | |
| | | TGroupCompanyServiceImpl service = Mockito.spy(new TGroupCompanyServiceImpl()); |
| | | Mockito.doReturn(0L).when(service).count(Mockito.any()); |
| | | Mockito.doReturn(true).when(service).save(Mockito.any()); |
| | | ReflectionTestUtils.setField(service, "sysUserClient", sysUserClient); |
| | | ReflectionTestUtils.setField(service, "sysRoleClient", sysRoleClient); |
| | | |
| | | AjaxResult result = service.addCompany(company); |
| | | assertEquals(200, code(result)); |
| | | assertEquals(company.getAccount(), String.valueOf(result.get("data"))); |
| | | |
| | | // 最终以通过查重的候选账号建户 |
| | | ArgumentCaptor<SysUser> userCaptor = ArgumentCaptor.forClass(SysUser.class); |
| | | Mockito.verify(sysUserClient).addSysUser(userCaptor.capture()); |
| | | assertEquals(company.getAccount(), userCaptor.getValue().getUserName()); |
| | | assertTrue(userCaptor.getValue().getUserName().matches("admin\\d{4}")); |
| | | } |
| | | |
| | | @Test |
| | |
| | | Mockito.doReturn(true).when(service).save(Mockito.any()); |
| | | ReflectionTestUtils.setField(service, "sysUserClient", sysUserClient); |
| | | ReflectionTestUtils.setField(service, "sysRoleClient", sysRoleClient); |
| | | this.addUserClient = sysUserClient; |
| | | return service; |
| | | } |
| | | |
| | | /** |
| | | * 按登录口径计算 HMAC-MD5(明文, key) 的期望值(小写 Hex),用于断言初始密码传输值 |
| | | */ |
| | | private String hmacMd5Expected(String text, String key) { |
| | | try { |
| | | javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacMD5"); |
| | | mac.init(new javax.crypto.spec.SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacMD5")); |
| | | byte[] bytes = mac.doFinal(text.getBytes(StandardCharsets.UTF_8)); |
| | | StringBuilder hex = new StringBuilder(bytes.length * 2); |
| | | for (byte b : bytes) { |
| | | hex.append(Character.forDigit((b >> 4) & 0xF, 16)); |
| | | hex.append(Character.forDigit(b & 0xF, 16)); |
| | | } |
| | | return hex.toString(); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 编辑公司修改登录账号:按旧账号定位用户后把 userName 更新为新账号, |
| | | * 不误走补建分支(避免双账号残留) |
| | | */ |