Commit 878445a238cd2f47c6cdfbe6735a16bbdd9c653f
1 parent
89df5b3c
重构社交登录,完善单元测试
Showing
8 changed files
with
109 additions
and
186 deletions
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
| ... | ... | @@ -23,33 +23,33 @@ public enum SocialTypeEnum implements IntArrayValuable { |
| 23 | 23 | * Gitee |
| 24 | 24 | * 文档链接:https://gitee.com/api/v5/oauth_doc#/ |
| 25 | 25 | */ |
| 26 | - GITEE(10, 1, "GITEE"), | |
| 26 | + GITEE(10, "GITEE"), | |
| 27 | 27 | /** |
| 28 | 28 | * 钉钉 |
| 29 | 29 | * 文档链接:https://developers.dingtalk.com/document/app/obtain-identity-credentials |
| 30 | 30 | */ |
| 31 | - DINGTALK(20, 2, "DINGTALK"), | |
| 31 | + DINGTALK(20, "DINGTALK"), | |
| 32 | 32 | |
| 33 | 33 | /** |
| 34 | 34 | * 企业微信 |
| 35 | 35 | * 文档链接:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html |
| 36 | 36 | */ |
| 37 | - WECHAT_ENTERPRISE(30, 3, "WECHAT_ENTERPRISE"), | |
| 37 | + WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"), | |
| 38 | 38 | /** |
| 39 | 39 | * 微信公众平台 - 移动端 H5 |
| 40 | 40 | * 文档链接:https://www.cnblogs.com/juewuzhe/p/11905461.html |
| 41 | 41 | */ |
| 42 | - WECHAT_MP(31, 3, "WECHAT_MP"), | |
| 42 | + WECHAT_MP(31, "WECHAT_MP"), | |
| 43 | 43 | /** |
| 44 | 44 | * 微信开放平台 - 网站应用 PC 端扫码授权登录 |
| 45 | 45 | * 文档链接:https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证 |
| 46 | 46 | */ |
| 47 | - WECHAT_OPEN(32, 3, "WECHAT_OPEN"), | |
| 47 | + WECHAT_OPEN(32, "WECHAT_OPEN"), | |
| 48 | 48 | /** |
| 49 | 49 | * 微信小程序 |
| 50 | 50 | * 文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html |
| 51 | 51 | */ |
| 52 | - WECHAT_MINI_PROGRAM(33, 3, "WECHAT_MINI_PROGRAM"), | |
| 52 | + WECHAT_MINI_PROGRAM(33, "WECHAT_MINI_PROGRAM"), | |
| 53 | 53 | ; |
| 54 | 54 | |
| 55 | 55 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SocialTypeEnum::getType).toArray(); |
| ... | ... | @@ -59,12 +59,6 @@ public enum SocialTypeEnum implements IntArrayValuable { |
| 59 | 59 | */ |
| 60 | 60 | private final Integer type; |
| 61 | 61 | /** |
| 62 | - * 平台 | |
| 63 | - * | |
| 64 | - * 例如说,微信平台下,有企业微信、公众平台、开放平台、小程序等 | |
| 65 | - */ | |
| 66 | - private final Integer platform; | |
| 67 | - /** | |
| 68 | 62 | * 类型的标识 |
| 69 | 63 | */ |
| 70 | 64 | private final String source; |
| ... | ... | @@ -78,11 +72,4 @@ public enum SocialTypeEnum implements IntArrayValuable { |
| 78 | 72 | return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); |
| 79 | 73 | } |
| 80 | 74 | |
| 81 | - public static Set<Integer> getTypes(Collection<Integer> platforms) { | |
| 82 | - return Arrays.stream(values()) | |
| 83 | - .filter(socialTypeEnum -> platforms.contains(socialTypeEnum.getPlatform())) | |
| 84 | - .map(SocialTypeEnum::getType) | |
| 85 | - .collect(Collectors.toSet()); | |
| 86 | - } | |
| 87 | - | |
| 88 | 75 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserBindDO.java
| ... | ... | @@ -22,6 +22,8 @@ public class SocialUserBindDO extends BaseDO { |
| 22 | 22 | |
| 23 | 23 | /** |
| 24 | 24 | * 关联的用户编号 |
| 25 | + * | |
| 26 | + * 关联 UserDO 的编号 | |
| 25 | 27 | */ |
| 26 | 28 | private Long userId; |
| 27 | 29 | /** |
| ... | ... | @@ -32,14 +34,16 @@ public class SocialUserBindDO extends BaseDO { |
| 32 | 34 | private Integer userType; |
| 33 | 35 | |
| 34 | 36 | /** |
| 35 | - * 社交平台 | |
| 37 | + * 社交平台的用户编号 | |
| 36 | 38 | * |
| 37 | - * 枚举 {@link SocialTypeEnum#getPlatform()} | |
| 39 | + * 关联 {@link SocialUserDO#getId()} | |
| 38 | 40 | */ |
| 39 | - private Integer platform; | |
| 41 | + private Long socialUserId; | |
| 40 | 42 | /** |
| 41 | - * 社交的全局编号 | |
| 43 | + * 社交平台的类型 | |
| 44 | + * | |
| 45 | + * 冗余 {@link SocialUserDO#getType()} | |
| 42 | 46 | */ |
| 43 | - private String unionId; | |
| 47 | + private Integer socialType; | |
| 44 | 48 | |
| 45 | 49 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java
| 1 | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.social; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | |
| 4 | -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 5 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | 4 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 7 | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| ... | ... | @@ -10,7 +8,6 @@ import lombok.*; |
| 10 | 8 | |
| 11 | 9 | /** |
| 12 | 10 | * 社交用户 |
| 13 | - * 通过 {@link SocialUserDO#getUserId()} 关联到对应的 {@link AdminUserDO} | |
| 14 | 11 | * |
| 15 | 12 | * @author weir |
| 16 | 13 | */ | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java
| ... | ... | @@ -10,26 +10,23 @@ import java.util.List; |
| 10 | 10 | @Mapper |
| 11 | 11 | public interface SocialUserBindMapper extends BaseMapperX<SocialUserBindDO> { |
| 12 | 12 | |
| 13 | - default void deleteByUserTypeAndUserIdAndUnionId(Integer userType, Long userId, Integer platform) { | |
| 13 | + default void deleteByUserTypeAndUserIdAndSocialType(Integer userType, Long userId, Integer socialType) { | |
| 14 | 14 | delete(new LambdaQueryWrapperX<SocialUserBindDO>() |
| 15 | 15 | .eq(SocialUserBindDO::getUserType, userType) |
| 16 | 16 | .eq(SocialUserBindDO::getUserId, userId) |
| 17 | - .eq(SocialUserBindDO::getPlatform, platform)); | |
| 17 | + .eq(SocialUserBindDO::getSocialType, socialType)); | |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | - default void deleteByUserTypeAndPlatformAndUnionId(Integer userType, Integer platform, String unionId) { | |
| 20 | + default void deleteByUserTypeAndSocialUserId(Integer userType, Long socialUserId) { | |
| 21 | 21 | delete(new LambdaQueryWrapperX<SocialUserBindDO>() |
| 22 | 22 | .eq(SocialUserBindDO::getUserType, userType) |
| 23 | - .eq(SocialUserBindDO::getPlatform, platform) | |
| 24 | - .eq(SocialUserBindDO::getUnionId, unionId)); | |
| 23 | + .eq(SocialUserBindDO::getSocialUserId, socialUserId)); | |
| 25 | 24 | } |
| 26 | 25 | |
| 27 | - default SocialUserBindDO selectByUserTypeAndPlatformAndUnionId(Integer userType, | |
| 28 | - Integer platform, String unionId) { | |
| 26 | + default SocialUserBindDO selectByUserTypeAndSocialUserId(Integer userType, Long socialUserId) { | |
| 29 | 27 | return selectOne(new LambdaQueryWrapperX<SocialUserBindDO>() |
| 30 | 28 | .eq(SocialUserBindDO::getUserType, userType) |
| 31 | - .eq(SocialUserBindDO::getPlatform, platform) | |
| 32 | - .eq(SocialUserBindDO::getUnionId, unionId)); | |
| 29 | + .eq(SocialUserBindDO::getSocialUserId, socialUserId)); | |
| 33 | 30 | } |
| 34 | 31 | |
| 35 | 32 | default List<SocialUserBindDO> selectListByUserIdAndUserType(Long userId, Integer userType) { | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java
| ... | ... | @@ -22,13 +22,7 @@ public interface SocialUserMapper extends BaseMapperX<SocialUserDO> { |
| 22 | 22 | default SocialUserDO selectByTypeAndOpenid(Integer type, String openid) { |
| 23 | 23 | return selectOne(new LambdaQueryWrapper<SocialUserDO>() |
| 24 | 24 | .eq(SocialUserDO::getType, type) |
| 25 | - .eq(SocialUserDO::getCode, openid)); | |
| 26 | - } | |
| 27 | - | |
| 28 | - default List<SocialUserDO> selectListByUnionIdAndType(Collection<String> unionIds, Collection<Integer> types) { | |
| 29 | - return selectList(new LambdaQueryWrapper<SocialUserDO>() | |
| 30 | - .in(SocialUserDO::getUnionId, unionIds) | |
| 31 | - .in(SocialUserDO::getType, types)); | |
| 25 | + .eq(SocialUserDO::getOpenid, openid)); | |
| 32 | 26 | } |
| 33 | 27 | |
| 34 | 28 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
| ... | ... | @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.system.service.social; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.lang.Assert; |
| 5 | -import cn.hutool.core.util.StrUtil; | |
| 6 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 7 | 5 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 8 | 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 9 | 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| ... | ... | @@ -25,9 +23,9 @@ import org.springframework.validation.annotation.Validated; |
| 25 | 23 | import javax.annotation.Resource; |
| 26 | 24 | import java.util.Collections; |
| 27 | 25 | import java.util.List; |
| 28 | -import java.util.Set; | |
| 29 | 26 | |
| 30 | 27 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 28 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 31 | 29 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 32 | 30 | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; |
| 33 | 31 | |
| ... | ... | @@ -78,7 +76,6 @@ public class SocialUserServiceImpl implements SocialUserService { |
| 78 | 76 | } |
| 79 | 77 | socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询 |
| 80 | 78 | .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) |
| 81 | - .setUnionId(StrUtil.blankToDefault(authUser.getToken().getUnionId(), authUser.getUuid())) // unionId 识别多个用户 | |
| 82 | 79 | .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())); |
| 83 | 80 | if (socialUser.getId() == null) { |
| 84 | 81 | socialUserMapper.insert(socialUser); |
| ... | ... | @@ -96,9 +93,7 @@ public class SocialUserServiceImpl implements SocialUserService { |
| 96 | 93 | return Collections.emptyList(); |
| 97 | 94 | } |
| 98 | 95 | // 获得社交用户 |
| 99 | - Set<Integer> platforms = CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getPlatform); | |
| 100 | - return socialUserMapper.selectListByUnionIdAndType(CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getUnionId), | |
| 101 | - SocialTypeEnum.getTypes(platforms)); | |
| 96 | + return socialUserMapper.selectBatchIds(convertSet(socialUserBinds, SocialUserBindDO::getSocialUserId)); | |
| 102 | 97 | } |
| 103 | 98 | |
| 104 | 99 | @Override |
| ... | ... | @@ -108,19 +103,17 @@ public class SocialUserServiceImpl implements SocialUserService { |
| 108 | 103 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); |
| 109 | 104 | Assert.notNull(socialUser, "社交用户不能为空"); |
| 110 | 105 | |
| 111 | - // 如果 unionId 之前被绑定过,需要进行解绑 | |
| 112 | - Integer platform = SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(); | |
| 113 | - socialUserBindMapper.deleteByUserTypeAndPlatformAndUnionId(reqDTO.getUserType(), platform, | |
| 114 | - socialUser.getUnionId()); | |
| 106 | + // 社交用户可能之前绑定过别的用户,需要进行解绑 | |
| 107 | + socialUserBindMapper.deleteByUserTypeAndSocialUserId(reqDTO.getUserType(), socialUser.getId()); | |
| 115 | 108 | |
| 116 | - // 如果 userId 之前绑定过该 type 的其它账号,需要进行解绑 | |
| 117 | - socialUserBindMapper.deleteByUserTypeAndUserIdAndUnionId(reqDTO.getUserType(), reqDTO.getUserId(), | |
| 118 | - socialUser.getUnionId()); | |
| 109 | + // 用户可能之前已经绑定过该社交类型,需要进行解绑 | |
| 110 | + socialUserBindMapper.deleteByUserTypeAndUserIdAndSocialType(reqDTO.getUserType(), reqDTO.getUserId(), | |
| 111 | + socialUser.getType()); | |
| 119 | 112 | |
| 120 | 113 | // 绑定当前登录的社交用户 |
| 121 | 114 | SocialUserBindDO socialUserBind = SocialUserBindDO.builder() |
| 122 | 115 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) |
| 123 | - .platform(platform).unionId(socialUser.getUnionId()).build(); | |
| 116 | + .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); | |
| 124 | 117 | socialUserBindMapper.insert(socialUserBind); |
| 125 | 118 | } |
| 126 | 119 | |
| ... | ... | @@ -133,8 +126,7 @@ public class SocialUserServiceImpl implements SocialUserService { |
| 133 | 126 | } |
| 134 | 127 | |
| 135 | 128 | // 获得对应的社交绑定关系 |
| 136 | - socialUserBindMapper.deleteByUserTypeAndUserIdAndPlatformAndUnionId(userType, userId, | |
| 137 | - SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(), socialUser.getUnionId()); | |
| 129 | + socialUserBindMapper.deleteByUserTypeAndUserIdAndSocialType(userType, userId, socialUser.getType()); | |
| 138 | 130 | } |
| 139 | 131 | |
| 140 | 132 | @Override |
| ... | ... | @@ -144,8 +136,8 @@ public class SocialUserServiceImpl implements SocialUserService { |
| 144 | 136 | Assert.notNull(socialUser, "社交用户不能为空"); |
| 145 | 137 | |
| 146 | 138 | // 如果未绑定的社交用户,则无法自动登录,进行报错 |
| 147 | - SocialUserBindDO socialUserBind = socialUserBindMapper.selectByUserTypeAndPlatformAndUnionId(userType, | |
| 148 | - SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(), socialUser.getUnionId()); | |
| 139 | + SocialUserBindDO socialUserBind = socialUserBindMapper.selectByUserTypeAndSocialUserId(userType, | |
| 140 | + socialUser.getId()); | |
| 149 | 141 | if (socialUserBind == null) { |
| 150 | 142 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 151 | 143 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java
| 1 | 1 | package cn.iocoder.yudao.module.system.service.social; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | -import cn.iocoder.yudao.framework.test.core.util.AssertUtils; | |
| 5 | -import cn.iocoder.yudao.framework.test.core.util.RandomUtils; | |
| 4 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; | |
| 6 | 5 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 7 | 6 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| 8 | 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 9 | 8 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; |
| 10 | 9 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; |
| 11 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; | |
| 12 | 10 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 13 | -import com.baomidou.mybatisplus.core.toolkit.PluginUtils; | |
| 14 | 11 | import com.xkcoding.justauth.AuthRequestFactory; |
| 15 | 12 | import me.zhyd.oauth.enums.AuthResponseStatus; |
| 16 | 13 | import me.zhyd.oauth.model.AuthCallback; |
| ... | ... | @@ -19,16 +16,15 @@ import me.zhyd.oauth.model.AuthUser; |
| 19 | 16 | import me.zhyd.oauth.request.AuthRequest; |
| 20 | 17 | import me.zhyd.oauth.utils.AuthStateUtils; |
| 21 | 18 | import org.junit.jupiter.api.Test; |
| 22 | -import org.junit.jupiter.api.function.Executable; | |
| 23 | 19 | import org.mockito.MockedStatic; |
| 24 | 20 | import org.springframework.boot.test.mock.mockito.MockBean; |
| 25 | 21 | import org.springframework.context.annotation.Import; |
| 26 | 22 | |
| 27 | 23 | import javax.annotation.Resource; |
| 28 | - | |
| 29 | 24 | import java.util.List; |
| 30 | 25 | |
| 31 | -import static cn.hutool.core.util.RandomUtil.*; | |
| 26 | +import static cn.hutool.core.util.RandomUtil.randomLong; | |
| 27 | +import static cn.hutool.core.util.RandomUtil.randomString; | |
| 32 | 28 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 33 | 29 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 34 | 30 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| ... | ... | @@ -157,24 +153,22 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { |
| 157 | 153 | assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo()); |
| 158 | 154 | assertEquals(type, socialUser.getType()); |
| 159 | 155 | assertEquals(authUser.getUuid(), socialUser.getOpenid()); |
| 160 | - assertEquals(authUser.getToken().getUnionId(), socialUser.getUnionId()); | |
| 161 | 156 | } |
| 162 | 157 | |
| 163 | 158 | @Test |
| 164 | 159 | public void testGetSocialUserList() { |
| 165 | 160 | Long userId = 1L; |
| 166 | 161 | Integer userType = UserTypeEnum.ADMIN.getValue(); |
| 167 | - // mock 获得绑定 | |
| 168 | - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 | |
| 169 | - .setUserId(userId).setUserType(userType).setPlatform(SocialTypeEnum.GITEE.getPlatform()) | |
| 170 | - .setUnionId("test_unionId")); | |
| 171 | - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 | |
| 172 | - .setUserId(2L).setUserType(userType).setPlatform(SocialTypeEnum.DINGTALK.getPlatform())); | |
| 173 | 162 | // mock 获得社交用户 |
| 174 | - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()) | |
| 175 | - .setUnionId("test_unionId"); | |
| 163 | + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()); | |
| 176 | 164 | socialUserMapper.insert(socialUser); // 可被查到 |
| 177 | 165 | socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到 |
| 166 | + // mock 获得绑定 | |
| 167 | + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 | |
| 168 | + .setUserId(userId).setUserType(userType).setSocialType(SocialTypeEnum.GITEE.getType()) | |
| 169 | + .setSocialUserId(socialUser.getId())); | |
| 170 | + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 | |
| 171 | + .setUserId(2L).setUserType(userType).setSocialType(SocialTypeEnum.DINGTALK.getType())); | |
| 178 | 172 | |
| 179 | 173 | // 调用 |
| 180 | 174 | List<SocialUserDO> result = socialUserService.getSocialUserList(userId, userType); |
| ... | ... | @@ -184,120 +178,79 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { |
| 184 | 178 | } |
| 185 | 179 | |
| 186 | 180 | @Test |
| 187 | - public void testBindSocialUser_create() { | |
| 181 | + public void testBindSocialUser() { | |
| 188 | 182 | // 准备参数 |
| 189 | 183 | SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO() |
| 190 | 184 | .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) |
| 191 | 185 | .setType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state"); |
| 192 | 186 | // mock 数据:获得社交用户 |
| 193 | 187 | SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getType()) |
| 194 | - .setCode(reqDTO.getCode()).setState(reqDTO.getState()).setUnionId("test_unionId"); | |
| 188 | + .setCode(reqDTO.getCode()).setState(reqDTO.getState()); | |
| 195 | 189 | socialUserMapper.insert(socialUser); |
| 196 | - // mock 数据:解绑其它账号 | |
| 190 | + // mock 数据:用户可能之前已经绑定过该社交类型 | |
| 197 | 191 | socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) |
| 198 | - .setPlatform(SocialTypeEnum.GITEE.getPlatform()).setUnionId("test_delete_unionId")); | |
| 192 | + .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(-1L)); | |
| 193 | + // mock 数据:社交用户可能之前绑定过别的用户 | |
| 194 | + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserType(UserTypeEnum.ADMIN.getValue()) | |
| 195 | + .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); | |
| 199 | 196 | |
| 200 | 197 | // 调用 |
| 201 | 198 | socialUserService.bindSocialUser(reqDTO); |
| 202 | 199 | // 断言 |
| 203 | 200 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); |
| 204 | 201 | assertEquals(1, socialUserBinds.size()); |
| 202 | + } | |
| 205 | 203 | |
| 204 | + @Test | |
| 205 | + public void testUnbindSocialUser_success() { | |
| 206 | + // 准备参数 | |
| 207 | + Long userId = 1L; | |
| 208 | + Integer userType = UserTypeEnum.ADMIN.getValue(); | |
| 209 | + Integer type = SocialTypeEnum.GITEE.getType(); | |
| 210 | + String openid = "test_openid"; | |
| 211 | + // mock 数据:社交用户 | |
| 212 | + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setOpenid(openid); | |
| 213 | + socialUserMapper.insert(socialUser); | |
| 214 | + // mock 数据:社交绑定关系 | |
| 215 | + SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType) | |
| 216 | + .setUserId(userId).setSocialType(type); | |
| 217 | + socialUserBindMapper.insert(socialUserBind); | |
| 218 | + | |
| 219 | + // 调用 | |
| 220 | + socialUserService.unbindSocialUser(userId, userType, type, openid); | |
| 221 | + // 断言 | |
| 222 | + assertEquals(0, socialUserBindMapper.selectCount(null).intValue()); | |
| 223 | + } | |
| 224 | + | |
| 225 | + @Test | |
| 226 | + public void testUnbindSocialUser_notFound() { | |
| 227 | + // 调用,并断言 | |
| 228 | + assertServiceException( | |
| 229 | + () -> socialUserService.unbindSocialUser(randomLong(), UserTypeEnum.ADMIN.getValue(), | |
| 230 | + SocialTypeEnum.GITEE.getType(), "test_openid"), | |
| 231 | + SOCIAL_USER_NOT_FOUND); | |
| 206 | 232 | } |
| 207 | -// | |
| 208 | -// /** | |
| 209 | -// * 情况二,更新 SocialUserDO 的情况 | |
| 210 | -// */ | |
| 211 | -// @Test | |
| 212 | -// public void testBindSocialUser_update() { | |
| 213 | -// // mock 数据 | |
| 214 | -// SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | |
| 215 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 216 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | |
| 217 | -// }); | |
| 218 | -// socialUserMapper.insert(dbSocialUser); | |
| 219 | -// // 准备参数 | |
| 220 | -// Long userId = dbSocialUser.getUserId(); | |
| 221 | -// Integer type = dbSocialUser.getType(); | |
| 222 | -// AuthUser authUser = randomPojo(AuthUser.class); | |
| 223 | -// // mock 方法 | |
| 224 | -// | |
| 225 | -// // 调用 | |
| 226 | -// socialService.bindSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, authUser); | |
| 227 | -// // 断言 | |
| 228 | -// List<SocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId); | |
| 229 | -// assertEquals(1, socialUsers.size()); | |
| 230 | -// assertBindSocialUser(socialUsers.get(0), authUser, userId, type); | |
| 231 | -// } | |
| 232 | -// | |
| 233 | -// /** | |
| 234 | -// * 情况一和二都存在的,逻辑二的场景 | |
| 235 | -// */ | |
| 236 | -// @Test | |
| 237 | -// public void testBindSocialUser_userId() { | |
| 238 | -// // mock 数据 | |
| 239 | -// SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | |
| 240 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 241 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | |
| 242 | -// }); | |
| 243 | -// socialUserMapper.insert(dbSocialUser); | |
| 244 | -// // 准备参数 | |
| 245 | -// Long userId = randomLongId(); | |
| 246 | -// Integer type = dbSocialUser.getType(); | |
| 247 | -// AuthUser authUser = randomPojo(AuthUser.class); | |
| 248 | -// // mock 方法 | |
| 249 | -// | |
| 250 | -// // 调用 | |
| 251 | -// socialService.bindSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, authUser); | |
| 252 | -// // 断言 | |
| 253 | -// List<SocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId); | |
| 254 | -// assertEquals(1, socialUsers.size()); | |
| 255 | -// } | |
| 256 | 233 | |
| 257 | -// | |
| 258 | -// /** | |
| 259 | -// * 情况一,如果新老的 unionId 是一致的,无需解绑 | |
| 260 | -// */ | |
| 261 | -// @Test | |
| 262 | -// public void testUnbindOldSocialUser_no() { | |
| 263 | -// // mock 数据 | |
| 264 | -// SocialUserDO oldSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | |
| 265 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 266 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | |
| 267 | -// }); | |
| 268 | -// socialUserMapper.insert(oldSocialUser); | |
| 269 | -// // 准备参数 | |
| 270 | -// Long userId = oldSocialUser.getUserId(); | |
| 271 | -// Integer type = oldSocialUser.getType(); | |
| 272 | -// String newUnionId = oldSocialUser.getUnionId(); | |
| 273 | -// | |
| 274 | -// // 调用 | |
| 275 | -// socialService.unbindOldSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, newUnionId); | |
| 276 | -// // 断言 | |
| 277 | -// assertEquals(1L, socialUserMapper.selectCount(null).longValue()); | |
| 278 | -// } | |
| 279 | -// | |
| 280 | -// | |
| 281 | -// /** | |
| 282 | -// * 情况二,如果新老的 unionId 不一致的,需解绑 | |
| 283 | -// */ | |
| 284 | -// @Test | |
| 285 | -// public void testUnbindOldSocialUser_yes() { | |
| 286 | -// // mock 数据 | |
| 287 | -// SocialUserDO oldSocialUser = randomPojo(SocialUserDO.class, socialUserDO -> { | |
| 288 | -// socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue()); | |
| 289 | -// socialUserDO.setType(randomEle(SocialTypeEnum.values()).getType()); | |
| 290 | -// }); | |
| 291 | -// socialUserMapper.insert(oldSocialUser); | |
| 292 | -// // 准备参数 | |
| 293 | -// Long userId = oldSocialUser.getUserId(); | |
| 294 | -// Integer type = oldSocialUser.getType(); | |
| 295 | -// String newUnionId = randomString(10); | |
| 296 | -// | |
| 297 | -// // 调用 | |
| 298 | -// socialService.unbindOldSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, newUnionId); | |
| 299 | -// // 断言 | |
| 300 | -// assertEquals(0L, socialUserMapper.selectCount(null).longValue()); | |
| 301 | -// } | |
| 234 | + @Test | |
| 235 | + public void testGetBindUserId() { | |
| 236 | + // 准备参数 | |
| 237 | + Integer userType = UserTypeEnum.ADMIN.getValue(); | |
| 238 | + Integer type = SocialTypeEnum.GITEE.getType(); | |
| 239 | + String code = "tudou"; | |
| 240 | + String state = "yuanma"; | |
| 241 | + // mock 社交用户 | |
| 242 | + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); | |
| 243 | + socialUserMapper.insert(socialUser); | |
| 244 | + // mock 社交用户的绑定 | |
| 245 | + Long userId = randomLong(); | |
| 246 | + SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) | |
| 247 | + .setSocialType(type).setSocialUserId(socialUser.getId()); | |
| 248 | + socialUserBindMapper.insert(socialUserBind); | |
| 249 | + | |
| 250 | + // 调用 | |
| 251 | + Long result = socialUserService.getBindUserId(userType, type, code, state); | |
| 252 | + // 断言 | |
| 253 | + assertEquals(userId, result); | |
| 254 | + } | |
| 302 | 255 | |
| 303 | 256 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -381,7 +381,6 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( |
| 381 | 381 | "type" tinyint NOT NULL, |
| 382 | 382 | "openid" varchar(64) NOT NULL, |
| 383 | 383 | "token" varchar(256) DEFAULT NULL, |
| 384 | - "union_id" varchar(64) NOT NULL, | |
| 385 | 384 | "raw_token_info" varchar(1024) NOT NULL, |
| 386 | 385 | "nickname" varchar(32) NOT NULL, |
| 387 | 386 | "avatar" varchar(255) DEFAULT NULL, |
| ... | ... | @@ -399,15 +398,15 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( |
| 399 | 398 | CREATE TABLE IF NOT EXISTS "system_social_user_bind" ( |
| 400 | 399 | "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, |
| 401 | 400 | "user_id" bigint NOT NULL, |
| 402 | - "user_type" tinyint NOT NULL DEFAULT '0', | |
| 403 | - "platform" tinyint NOT NULL, | |
| 404 | - "union_id" varchar(64) NOT NULL, | |
| 405 | - "creator" varchar(64) DEFAULT '', | |
| 406 | - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 407 | - "updater" varchar(64) DEFAULT '', | |
| 408 | - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 409 | - "deleted" bit NOT NULL DEFAULT FALSE, | |
| 410 | - PRIMARY KEY ("id") | |
| 401 | + "user_type" tinyint NOT NULL, | |
| 402 | + "social_type" tinyint NOT NULL, | |
| 403 | + "social_user_id" number NOT NULL, | |
| 404 | + "creator" varchar(64) DEFAULT '', | |
| 405 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 406 | + "updater" varchar(64) DEFAULT '', | |
| 407 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 408 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 409 | + PRIMARY KEY ("id") | |
| 411 | 410 | ) COMMENT '社交用户的绑定'; |
| 412 | 411 | |
| 413 | 412 | CREATE TABLE IF NOT EXISTS "system_tenant" ( | ... | ... |