From 4f367056ab0e73d044e920d44b1d7dd0c8b65d80 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期二, 12 五月 2026 14:25:28 +0800
Subject: [PATCH] fix:注册流程优化、屏蔽账号密码登录、已登录后token永不过期
---
tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/auth/service/AppAuthServiceTest.java | 160 +++++++++++++++++++----------------------------------
1 files changed, 58 insertions(+), 102 deletions(-)
diff --git a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/auth/service/AppAuthServiceTest.java b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/auth/service/AppAuthServiceTest.java
index 41dd1a6..00e455e 100644
--- a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/auth/service/AppAuthServiceTest.java
+++ b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/auth/service/AppAuthServiceTest.java
@@ -10,8 +10,6 @@
import com.tcm.training.admin.app.auth.dto.AppWechatLoginRequest;
import com.tcm.training.admin.app.auth.vo.AppLoginResponse;
import com.tcm.training.admin.app.auth.vo.AppPasswordResetVerifyResponse;
-import com.tcm.training.admin.app.auth.vo.AppSmsCodeSendResponse;
-import com.tcm.training.admin.app.auth.exception.InviteCodeRequiredException;
import com.tcm.training.admin.app.share.service.AppShareService;
import com.tcm.training.admin.member.entity.AppUser;
import com.tcm.training.admin.member.mapper.UserMapper;
@@ -26,13 +24,9 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import java.util.concurrent.TimeUnit;
-
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
@@ -79,9 +73,6 @@
@Mock
private StringRedisTemplate stringRedisTemplate;
- @Mock
- private ValueOperations<String, String> valueOperations;
-
private AppAuthService appAuthService;
@Captor
@@ -105,128 +96,69 @@
}
/**
- * 密码登录成功时应返回统一登录响应并建立 APP 登录态。
+ * 密码登录能力下线后旧客户端调用应返回统一提示。
*/
@Test
- void passwordLoginShouldReturnTokenWhenPasswordMatches() {
+ void passwordLoginShouldReturnDisabledMessage() {
AppPasswordLoginRequest request = new AppPasswordLoginRequest();
request.setPhone("13800138000");
request.setPassword("abc123!!");
- AppUser user = buildEnabledUser("13800138000", "ENCODED");
- SaTokenInfo tokenInfo = new SaTokenInfo();
- tokenInfo.setTokenValue("token-value");
- tokenInfo.setTokenTimeout(7200L);
-
- when(userMapper.selectOne(any())).thenReturn(user);
- when(passwordEncoder.matches("abc123!!", "ENCODED")).thenReturn(true);
- when(appAuthSessionService.getTokenInfo()).thenReturn(tokenInfo);
-
- AppLoginResponse response = appAuthService.passwordLogin(request);
-
- verify(appAuthSessionService).login(1L);
- assertEquals("token-value", response.getToken());
- assertEquals("Bearer", response.getTokenType());
- assertEquals(7200L, response.getExpiresIn());
- assertEquals(Long.valueOf(1L), response.getUser().getId());
- assertEquals("13800138000", response.getUser().getPhone());
- }
-
- /**
- * 密码错误时应返回统一错误文案。
- */
- @Test
- void passwordLoginShouldFailWhenPasswordMismatch() {
- AppPasswordLoginRequest request = new AppPasswordLoginRequest();
- request.setPhone("13800138000");
- request.setPassword("bad-password");
-
- AppUser user = buildEnabledUser("13800138000", "ENCODED");
- when(userMapper.selectOne(any())).thenReturn(user);
- when(passwordEncoder.matches("bad-password", "ENCODED")).thenReturn(false);
-
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> appAuthService.passwordLogin(request));
- assertEquals("账号或密码错误", exception.getMessage());
+ assertEquals("当前版本仅支持验证码登录", exception.getMessage());
+ verify(passwordEncoder, never()).matches(anyString(), anyString());
+ verify(appAuthSessionService, never()).login(anyLong());
}
/**
- * 忘记密码发码仅允许已启用用户发送。
+ * 忘记密码发码能力下线后旧客户端调用应返回统一提示。
*/
@Test
- void sendPasswordResetCodeShouldReturnExpireSeconds() {
+ void sendPasswordResetCodeShouldReturnDisabledMessage() {
AppSmsCodeSendRequest request = new AppSmsCodeSendRequest();
request.setPhone("13800138001");
- when(userMapper.selectOne(any())).thenReturn(buildEnabledUser("13800138001", "ENCODED"));
- when(appSmsCodeService.createPasswordResetCode("13800138001")).thenReturn(new AppSmsCodeSendResponse(300));
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
+ () -> appAuthService.sendPasswordResetCode(request));
- AppSmsCodeSendResponse response = appAuthService.sendPasswordResetCode(request);
-
- assertEquals(300, response.getExpireInSeconds());
+ assertEquals("当前版本仅支持验证码登录", exception.getMessage());
+ verify(appSmsCodeService, never()).createPasswordResetCode(anyString());
}
/**
- * 忘记密码验证码校验成功后应签发一次性重置凭证并写入缓存。
+ * 忘记密码验证码校验能力下线后旧客户端调用应返回统一提示。
*/
@Test
- void verifyPasswordResetCodeShouldCacheTicket() {
+ void verifyPasswordResetCodeShouldReturnDisabledMessage() {
AppPasswordResetVerifyRequest request = new AppPasswordResetVerifyRequest();
request.setPhone("13800138002");
request.setCode("666666");
- when(userMapper.selectOne(any())).thenReturn(buildEnabledUser("13800138002", "ENCODED"));
- when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
- doNothing().when(appSmsCodeService).validatePasswordResetCode("13800138002", "666666");
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
+ () -> appAuthService.verifyPasswordResetCode(request));
- AppPasswordResetVerifyResponse response = appAuthService.verifyPasswordResetCode(request);
-
- assertNotNull(response.getResetTicket());
- verify(valueOperations).set(anyString(), anyString(), anyLong(), any(TimeUnit.class));
+ assertEquals("当前版本仅支持验证码登录", exception.getMessage());
+ verify(appSmsCodeService, never()).validatePasswordResetCode(anyString(), anyString());
}
/**
- * 使用有效重置凭证时应更新数据库中的密码并销毁凭证。
+ * 重置密码能力下线后旧客户端调用应返回统一提示。
*/
@Test
- void resetPasswordShouldUpdatePasswordAndDeleteTicket() {
+ void resetPasswordShouldReturnDisabledMessage() {
AppPasswordResetRequest request = new AppPasswordResetRequest();
request.setResetTicket("ticket-1");
request.setPassword("abc123!!");
request.setConfirmPassword("abc123!!");
- AppUser user = buildEnabledUser("13800138003", "OLD");
-
- when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
- when(valueOperations.get(anyString())).thenReturn("13800138003");
- when(userMapper.selectOne(any())).thenReturn(user);
- when(passwordEncoder.encode("abc123!!")).thenReturn("NEW-ENCODED");
-
- appAuthService.resetPassword(request);
-
- verify(userMapper).updateById(appUserCaptor.capture());
- verify(stringRedisTemplate).delete(anyString());
- assertEquals("NEW-ENCODED", appUserCaptor.getValue().getPassword());
- }
-
- /**
- * 重置凭证失效时应拒绝更新密码。
- */
- @Test
- void resetPasswordShouldFailWhenTicketExpired() {
- AppPasswordResetRequest request = new AppPasswordResetRequest();
- request.setResetTicket("expired-ticket");
- request.setPassword("abc123!!");
- request.setConfirmPassword("abc123!!");
-
- when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
- when(valueOperations.get(anyString())).thenReturn(null);
-
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> appAuthService.resetPassword(request));
- assertEquals("重置凭证已失效,请重新验证", exception.getMessage());
+ assertEquals("当前版本仅支持验证码登录", exception.getMessage());
+ verify(passwordEncoder, never()).encode(anyString());
+ verify(userMapper, never()).updateById(any(AppUser.class));
}
/**
@@ -310,10 +242,10 @@
}
/**
- * 微信首次登录未携带邀请码时应提示联系管理员获取。
+ * 微信首次登录未携带邀请码时应创建待绑定手机号的临时用户。
*/
@Test
- void wechatLoginShouldRequireInviteCodeWhenOpenidNotExists() {
+ void wechatLoginShouldCreatePendingUserWhenInviteCodeMissing() {
AppWechatLoginRequest request = new AppWechatLoginRequest();
request.setAccessToken("access-token");
request.setOpenid("openid-new");
@@ -323,12 +255,19 @@
when(appWechatAuthClient.resolveUserProfile(request)).thenReturn(profile);
when(userMapper.selectOne(any())).thenReturn(null);
+ when(userMapper.insert(any(AppUser.class))).thenAnswer(invocation -> {
+ AppUser inserted = invocation.getArgument(0);
+ inserted.setId(2001L);
+ return 1;
+ });
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildTokenInfo("wechat-pending-token", 7200L));
- InviteCodeRequiredException exception = assertThrows(InviteCodeRequiredException.class,
- () -> appAuthService.wechatLogin(request));
+ AppLoginResponse response = appAuthService.wechatLogin(request);
- assertEquals("暂无邀请码,请联系管理员获取", exception.getMessage());
- verify(userMapper, never()).insert(any());
+ verify(userMapper).insert(appUserCaptor.capture());
+ assertNull(appUserCaptor.getValue().getPhone());
+ assertEquals("openid-new", appUserCaptor.getValue().getWechatOpenid());
+ assertEquals("wechat-pending-token", response.getToken());
}
/**
@@ -405,10 +344,10 @@
}
/**
- * 苹果首次登录未携带邀请码时应提示联系管理员获取。
+ * 苹果首次登录未携带邀请码时应创建待绑定手机号的临时用户。
*/
@Test
- void appleLoginShouldRequireInviteCodeWhenSubjectNotExists() {
+ void appleLoginShouldCreatePendingUserWhenInviteCodeMissing() {
AppAppleLoginRequest request = new AppAppleLoginRequest();
request.setIdentityToken("identity-token");
request.setUserIdentifier("apple-user-new");
@@ -419,12 +358,19 @@
when(appAppleAuthClient.resolveUserProfile(request)).thenReturn(profile);
when(userMapper.selectOne(any())).thenReturn(null);
+ when(userMapper.insert(any(AppUser.class))).thenAnswer(invocation -> {
+ AppUser inserted = invocation.getArgument(0);
+ inserted.setId(3001L);
+ return 1;
+ });
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildTokenInfo("apple-pending-token", 7200L));
- InviteCodeRequiredException exception = assertThrows(InviteCodeRequiredException.class,
- () -> appAuthService.appleLogin(request));
+ AppLoginResponse response = appAuthService.appleLogin(request);
- assertEquals("暂无邀请码,请联系管理员获取", exception.getMessage());
- verify(userMapper, never()).insert(any());
+ verify(userMapper).insert(appUserCaptor.capture());
+ assertNull(appUserCaptor.getValue().getPhone());
+ assertEquals("apple-subject-new", appUserCaptor.getValue().getAppleIdentitySubject());
+ assertEquals("apple-pending-token", response.getToken());
}
/**
@@ -456,6 +402,16 @@
}
/**
+ * 构造测试用 token 信息。
+ */
+ private SaTokenInfo buildTokenInfo(String tokenValue, long timeout) {
+ SaTokenInfo tokenInfo = new SaTokenInfo();
+ tokenInfo.setTokenValue(tokenValue);
+ tokenInfo.setTokenTimeout(timeout);
+ return tokenInfo;
+ }
+
+ /**
* 统一构造启用中的 APP 用户测试桩。
*/
private AppUser buildEnabledUser(String phone, String password) {
--
Gitblit v1.7.1