From 4c2dd7fdd86ddfad69611a5e825ff4a0cfab3c06 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期四, 30 四月 2026 22:03:06 +0800
Subject: [PATCH] fix:登录注册修改
---
tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 151 insertions(+), 5 deletions(-)
diff --git a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java
index 8300e88..2408f06 100644
--- a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java
+++ b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/settings/service/AppSettingsServiceTest.java
@@ -2,12 +2,13 @@
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import cn.dev33.satoken.stp.SaTokenInfo;
import com.tcm.training.admin.app.auth.service.AppAuthSessionService;
+import com.tcm.training.admin.app.auth.vo.AppLoginResponse;
import com.tcm.training.admin.app.auth.service.AppSmsCodeService;
import com.tcm.training.admin.app.auth.service.AppWechatAuthClient;
import com.tcm.training.admin.app.settings.dto.AppSettingsPhoneBindRequest;
import com.tcm.training.admin.app.settings.mapper.AppUserNotificationSettingMapper;
-import com.tcm.training.admin.app.settings.vo.AppSettingsProfileVO;
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;
@@ -28,6 +29,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -103,12 +105,15 @@
when(userMapper.selectById(1L)).thenReturn(currentUser);
when(userMapper.selectOne(any())).thenReturn(null);
doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("bind-token"));
- AppSettingsProfileVO response = appSettingsService.bindPhone(request);
+ AppLoginResponse response = appSettingsService.bindPhone(request);
verify(userMapper).updateById(appUserCaptor.capture());
+ verify(appAuthSessionService).login(1L);
assertEquals("13800138000", appUserCaptor.getValue().getPhone());
- assertEquals("13800138000", response.getPhone());
+ assertEquals("13800138000", response.getUser().getPhone());
+ assertEquals("bind-token", response.getToken());
}
/**
@@ -132,10 +137,141 @@
}
/**
- * 目标手机号被其他有效用户占用时不允许绑定。
+ * 微信临时账号绑定已注册但未绑定微信的手机号时,应合并到手机号账号。
*/
@Test
- void bindPhoneShouldRejectOccupiedPhone() {
+ void bindPhoneShouldMergeWechatUserIntoExistingPhoneUser() {
+ AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+ request.setNewPhone("13800138000");
+ request.setCode("123456");
+ AppUser currentUser = buildEnabledUser(null);
+ currentUser.setWechatOpenid("wx-openid");
+ currentUser.setNickname(null);
+ currentUser.setWechatNickname("微信昵称");
+ AppUser occupiedUser = buildEnabledUser("13800138000");
+ occupiedUser.setId(2L);
+ occupiedUser.setNickname(null);
+
+ when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+ when(userMapper.selectById(1L)).thenReturn(currentUser);
+ when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+ doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("merged-token"));
+
+ AppLoginResponse response = appSettingsService.bindPhone(request);
+
+ verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+ AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+ AppUser deletedTemporaryUser = appUserCaptor.getAllValues().get(1);
+ verify(appAuthSessionService).login(2L);
+ assertEquals("wx-openid", mergedUser.getWechatOpenid());
+ assertEquals("微信昵称", mergedUser.getNickname());
+ assertEquals(Integer.valueOf(1), deletedTemporaryUser.getDeleted());
+ assertEquals(Long.valueOf(2L), response.getUser().getId());
+ assertEquals("merged-token", response.getToken());
+ }
+
+ /**
+ * 微信临时账号绑定已绑定微信的手机号时,应直接覆盖目标账号微信票据。
+ */
+ @Test
+ void bindPhoneShouldOverwriteWechatBindingWhenPhoneUserAlreadyBoundWechat() {
+ AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+ request.setNewPhone("13800138000");
+ request.setCode("123456");
+ AppUser currentUser = buildEnabledUser(null);
+ currentUser.setWechatOpenid("wx-openid");
+ currentUser.setWechatNickname("新微信昵称");
+ AppUser occupiedUser = buildEnabledUser("13800138000");
+ occupiedUser.setId(2L);
+ occupiedUser.setWechatOpenid("other-wx-openid");
+
+ when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+ when(userMapper.selectById(1L)).thenReturn(currentUser);
+ when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+ doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("wechat-overwrite-token"));
+
+ AppLoginResponse response = appSettingsService.bindPhone(request);
+
+ verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+ AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+ AppUser deletedTemporaryUser = appUserCaptor.getAllValues().get(1);
+ verify(appAuthSessionService).login(2L);
+ assertEquals("wx-openid", mergedUser.getWechatOpenid());
+ assertEquals("新微信昵称", mergedUser.getWechatNickname());
+ assertEquals(Integer.valueOf(1), deletedTemporaryUser.getDeleted());
+ assertEquals(Long.valueOf(2L), response.getUser().getId());
+ }
+
+ /**
+ * 苹果临时账号绑定已注册但未绑定苹果的手机号时,应合并到手机号账号。
+ */
+ @Test
+ void bindPhoneShouldMergeAppleUserIntoExistingPhoneUser() {
+ AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+ request.setNewPhone("13800138000");
+ request.setCode("123456");
+ AppUser currentUser = buildEnabledUser(null);
+ currentUser.setAppleIdentitySubject("apple-subject");
+ currentUser.setAppleUserIdentifier("apple-user");
+ AppUser occupiedUser = buildEnabledUser("13800138000");
+ occupiedUser.setId(2L);
+
+ when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+ when(userMapper.selectById(1L)).thenReturn(currentUser);
+ when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+ doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("apple-merged-token"));
+
+ AppLoginResponse response = appSettingsService.bindPhone(request);
+
+ verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+ AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+ verify(appAuthSessionService).login(2L);
+ assertEquals("apple-subject", mergedUser.getAppleIdentitySubject());
+ assertEquals("apple-user", mergedUser.getAppleUserIdentifier());
+ assertEquals(Long.valueOf(2L), response.getUser().getId());
+ }
+
+ /**
+ * 苹果临时账号绑定已绑定苹果的手机号时,应直接覆盖目标账号苹果票据。
+ */
+ @Test
+ void bindPhoneShouldOverwriteAppleBindingWhenPhoneUserAlreadyBoundApple() {
+ AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
+ request.setNewPhone("13800138000");
+ request.setCode("123456");
+ AppUser currentUser = buildEnabledUser(null);
+ currentUser.setAppleIdentitySubject("apple-subject");
+ currentUser.setAppleUserIdentifier("apple-user");
+ AppUser occupiedUser = buildEnabledUser("13800138000");
+ occupiedUser.setId(2L);
+ occupiedUser.setAppleIdentitySubject("other-apple-subject");
+
+ when(appAuthSessionService.requireLoginUserId()).thenReturn(1L);
+ when(userMapper.selectById(1L)).thenReturn(currentUser);
+ when(userMapper.selectOne(any())).thenReturn(occupiedUser);
+ doNothing().when(appSmsCodeService).validatePhoneChangeCode("13800138000", "123456");
+ when(appAuthSessionService.getTokenInfo()).thenReturn(buildToken("apple-overwrite-token"));
+
+ AppLoginResponse response = appSettingsService.bindPhone(request);
+
+ verify(userMapper, times(2)).updateById(appUserCaptor.capture());
+ AppUser mergedUser = appUserCaptor.getAllValues().get(0);
+ AppUser deletedTemporaryUser = appUserCaptor.getAllValues().get(1);
+ verify(appAuthSessionService).login(2L);
+ assertEquals("apple-subject", mergedUser.getAppleIdentitySubject());
+ assertEquals("apple-user", mergedUser.getAppleUserIdentifier());
+ assertEquals(Integer.valueOf(1), deletedTemporaryUser.getDeleted());
+ assertEquals(Long.valueOf(2L), response.getUser().getId());
+ }
+
+ /**
+ * 非第三方临时账号绑定已注册手机号时仍按占用处理。
+ */
+ @Test
+ void bindPhoneShouldRejectOccupiedPhoneWithoutThirdPartyBinding() {
AppSettingsPhoneBindRequest request = new AppSettingsPhoneBindRequest();
request.setNewPhone("13800138000");
request.setCode("123456");
@@ -177,6 +313,16 @@
}
/**
+ * 构造测试登录态。
+ */
+ private SaTokenInfo buildToken(String tokenValue) {
+ SaTokenInfo tokenInfo = new SaTokenInfo();
+ tokenInfo.setTokenValue(tokenValue);
+ tokenInfo.setTokenTimeout(7200L);
+ return tokenInfo;
+ }
+
+ /**
* 构造启用状态 APP 用户。
*/
private AppUser buildEnabledUser(String phone) {
--
Gitblit v1.7.1