✅ 增加 social 模块的单测覆盖率
This commit is contained in:
parent
af41069b50
commit
49aee82b6a
@ -23,7 +23,7 @@ public class SocialUserPageReqVO extends PageParam {
|
||||
@Schema(description = "用户昵称", example = "李四")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "社交 openid", example = "oz-Jdt0kd_jdhUxJHQdBJMlOFN7w\n")
|
||||
@Schema(description = "社交 openid", example = "oz-Jdt0kd_jdhUxJHQdBJMlOFN7w")
|
||||
private String openid;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
|
@ -142,7 +142,8 @@ public class SocialClientServiceImpl implements SocialClientService {
|
||||
* @param userType 用户类型
|
||||
* @return AuthRequest 对象
|
||||
*/
|
||||
private AuthRequest buildAuthRequest(Integer socialType, Integer userType) {
|
||||
@VisibleForTesting
|
||||
AuthRequest buildAuthRequest(Integer socialType, Integer userType) {
|
||||
// 1. 先查找默认的配置项,从 application-*.yaml 中读取
|
||||
AuthRequest request = authRequestFactory.get(SocialTypeEnum.valueOfType(socialType).getSource());
|
||||
Assert.notNull(request, String.format("社交平台(%d) 不存在", socialType));
|
||||
@ -180,7 +181,8 @@ public class SocialClientServiceImpl implements SocialClientService {
|
||||
* @param userType 用户类型
|
||||
* @return WxMpService 对象
|
||||
*/
|
||||
private WxMpService getWxMpService(Integer userType) {
|
||||
@VisibleForTesting
|
||||
WxMpService getWxMpService(Integer userType) {
|
||||
// 第一步,查询 DB 的配置项,获得对应的 WxMpService 对象
|
||||
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
|
||||
SocialTypeEnum.WECHAT_MP.getType(), userType);
|
||||
@ -198,7 +200,7 @@ public class SocialClientServiceImpl implements SocialClientService {
|
||||
* @param clientSecret 微信公众号 secret
|
||||
* @return WxMpService 对象
|
||||
*/
|
||||
private WxMpService buildWxMpService(String clientId, String clientSecret) {
|
||||
public WxMpService buildWxMpService(String clientId, String clientSecret) {
|
||||
// 第一步,创建 WxMpRedisConfigImpl 对象
|
||||
WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl(
|
||||
new RedisTemplateWxRedisOps(stringRedisTemplate),
|
||||
@ -231,7 +233,8 @@ public class SocialClientServiceImpl implements SocialClientService {
|
||||
* @param userType 用户类型
|
||||
* @return WxMpService 对象
|
||||
*/
|
||||
private WxMaService getWxMaService(Integer userType) {
|
||||
@VisibleForTesting
|
||||
WxMaService getWxMaService(Integer userType) {
|
||||
// 第一步,查询 DB 的配置项,获得对应的 WxMaService 对象
|
||||
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
|
||||
SocialTypeEnum.WECHAT_MINI_APP.getType(), userType);
|
||||
@ -311,7 +314,6 @@ public class SocialClientServiceImpl implements SocialClientService {
|
||||
* @param userType 用户类型
|
||||
* @param socialType 社交类型
|
||||
*/
|
||||
@VisibleForTesting
|
||||
private void validateSocialClientUnique(Long id, Integer userType, Integer socialType) {
|
||||
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
|
||||
socialType, userType);
|
||||
|
@ -59,7 +59,7 @@ public class SocialUserServiceImpl implements SocialUserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String bindSocialUser(SocialUserBindReqDTO reqDTO) {
|
||||
// 获得社交用户
|
||||
SocialUserDO socialUser = authSocialUser(reqDTO.getSocialType(), reqDTO.getUserType(),
|
||||
@ -108,7 +108,6 @@ public class SocialUserServiceImpl implements SocialUserService {
|
||||
return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId());
|
||||
}
|
||||
|
||||
// TODO 芋艿:调整下单测
|
||||
/**
|
||||
* 授权获得对应的社交用户
|
||||
* 如果授权失败,则会抛出 {@link ServiceException} 异常
|
||||
|
@ -1,33 +1,53 @@
|
||||
package cn.iocoder.yudao.module.system.service.social;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||
import cn.binarywang.wx.miniapp.api.WxMaUserService;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
|
||||
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
|
||||
import com.xingyuv.jushauth.config.AuthConfig;
|
||||
import com.xingyuv.jushauth.model.AuthResponse;
|
||||
import com.xingyuv.jushauth.model.AuthUser;
|
||||
import com.xingyuv.jushauth.request.AuthDefaultRequest;
|
||||
import com.xingyuv.jushauth.request.AuthRequest;
|
||||
import com.xingyuv.jushauth.utils.AuthStateUtils;
|
||||
import com.xingyuv.justauth.AuthRequestFactory;
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_CLIENT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
// TODO 芋艿:单测后续补充下;
|
||||
/**
|
||||
* {@link SocialClientServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(SocialClientServiceImpl.class)
|
||||
@Disabled
|
||||
public class SocialClientServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
@ -36,10 +56,305 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
|
||||
@Resource
|
||||
private SocialClientMapper socialClientMapper;
|
||||
|
||||
@MockBean
|
||||
private AuthRequestFactory authRequestFactory;
|
||||
|
||||
@MockBean
|
||||
private WxMpService wxMpService;
|
||||
@MockBean
|
||||
private WxMpProperties wxMpProperties;
|
||||
@MockBean
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@MockBean
|
||||
private WxMaService wxMaService;
|
||||
@MockBean
|
||||
private WxMaProperties wxMaProperties;
|
||||
|
||||
@Test
|
||||
public void testGetAuthorizeUrl() {
|
||||
try (MockedStatic<AuthStateUtils> authStateUtilsMock = mockStatic(AuthStateUtils.class)) {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.WECHAT_MP.getType();
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
String redirectUri = "sss";
|
||||
// mock 获得对应的 AuthRequest 实现
|
||||
AuthRequest authRequest = mock(AuthRequest.class);
|
||||
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
// mock 方法
|
||||
authStateUtilsMock.when(AuthStateUtils::createState).thenReturn("aoteman");
|
||||
when(authRequest.authorize(eq("aoteman"))).thenReturn("https://www.iocoder.cn?redirect_uri=yyy");
|
||||
|
||||
// 调用
|
||||
String url = socialClientService.getAuthorizeUrl(socialType, userType, redirectUri);
|
||||
// 断言
|
||||
assertEquals("https://www.iocoder.cn?redirect_uri=sss", url);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_success() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.WECHAT_MP.getType();
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
String code = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法(AuthRequest)
|
||||
AuthRequest authRequest = mock(AuthRequest.class);
|
||||
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
// mock 方法(AuthResponse)
|
||||
AuthUser authUser = randomPojo(AuthUser.class);
|
||||
AuthResponse<?> authResponse = new AuthResponse<>(2000, null, authUser);
|
||||
when(authRequest.login(argThat(authCallback -> {
|
||||
assertEquals(code, authCallback.getCode());
|
||||
assertEquals(state, authCallback.getState());
|
||||
return true;
|
||||
}))).thenReturn(authResponse);
|
||||
|
||||
// 调用
|
||||
AuthUser result = socialClientService.getAuthUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertSame(authUser, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_fail() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.WECHAT_MP.getType();
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
String code = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法(AuthRequest)
|
||||
AuthRequest authRequest = mock(AuthRequest.class);
|
||||
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
// mock 方法(AuthResponse)
|
||||
AuthResponse<?> authResponse = new AuthResponse<>(0, "模拟失败", null);
|
||||
when(authRequest.login(argThat(authCallback -> {
|
||||
assertEquals(code, authCallback.getCode());
|
||||
assertEquals(state, authCallback.getState());
|
||||
return true;
|
||||
}))).thenReturn(authResponse);
|
||||
|
||||
// 调用并断言
|
||||
assertServiceException(
|
||||
() -> socialClientService.getAuthUser(socialType, userType, code, state),
|
||||
SOCIAL_USER_AUTH_FAILURE, "模拟失败");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildAuthRequest_clientNull() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.WECHAT_MP.getType();
|
||||
Integer userType = randomPojo(SocialTypeEnum.class).getType();
|
||||
// mock 获得对应的 AuthRequest 实现
|
||||
AuthRequest authRequest = mock(AuthDefaultRequest.class);
|
||||
AuthConfig authConfig = (AuthConfig) ReflectUtil.getFieldValue(authRequest, "config");
|
||||
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
|
||||
// 调用
|
||||
AuthRequest result = socialClientService.buildAuthRequest(socialType, userType);
|
||||
// 断言
|
||||
assertSame(authRequest, result);
|
||||
assertSame(authConfig, ReflectUtil.getFieldValue(authConfig, "config"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildAuthRequest_clientDisable() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.WECHAT_MP.getType();
|
||||
Integer userType = randomPojo(SocialTypeEnum.class).getType();
|
||||
// mock 获得对应的 AuthRequest 实现
|
||||
AuthRequest authRequest = mock(AuthDefaultRequest.class);
|
||||
AuthConfig authConfig = (AuthConfig) ReflectUtil.getFieldValue(authRequest, "config");
|
||||
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
// mock 数据
|
||||
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())
|
||||
.setUserType(userType).setSocialType(socialType));
|
||||
socialClientMapper.insert(client);
|
||||
|
||||
// 调用
|
||||
AuthRequest result = socialClientService.buildAuthRequest(socialType, userType);
|
||||
// 断言
|
||||
assertSame(authRequest, result);
|
||||
assertSame(authConfig, ReflectUtil.getFieldValue(authConfig, "config"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildAuthRequest_clientEnable() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.WECHAT_MP.getType();
|
||||
Integer userType = randomPojo(SocialTypeEnum.class).getType();
|
||||
// mock 获得对应的 AuthRequest 实现
|
||||
AuthConfig authConfig = mock(AuthConfig.class);
|
||||
AuthRequest authRequest = mock(AuthDefaultRequest.class);
|
||||
ReflectUtil.setFieldValue(authRequest, "config", authConfig);
|
||||
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
// mock 数据
|
||||
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setUserType(userType).setSocialType(socialType));
|
||||
socialClientMapper.insert(client);
|
||||
|
||||
// 调用
|
||||
AuthRequest result = socialClientService.buildAuthRequest(socialType, userType);
|
||||
// 断言
|
||||
assertSame(authRequest, result);
|
||||
assertNotSame(authConfig, ReflectUtil.getFieldValue(authRequest, "config"));
|
||||
}
|
||||
|
||||
// =================== 微信公众号独有 ===================
|
||||
|
||||
@Test
|
||||
public void testCreateWxMpJsapiSignature() throws WxErrorException {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
String url = randomString();
|
||||
// mock 方法
|
||||
WxJsapiSignature signature = randomPojo(WxJsapiSignature.class);
|
||||
when(wxMpService.createJsapiSignature(eq(url))).thenReturn(signature);
|
||||
|
||||
// 调用
|
||||
WxJsapiSignature result = socialClientService.createWxMpJsapiSignature(userType, url);
|
||||
// 断言
|
||||
assertSame(signature, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMpService_clientNull() {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
WxMpService result = socialClientService.getWxMpService(userType);
|
||||
// 断言
|
||||
assertSame(wxMpService, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMpService_clientDisable() {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
// mock 数据
|
||||
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())
|
||||
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MP.getType()));
|
||||
socialClientMapper.insert(client);
|
||||
|
||||
// 调用
|
||||
WxMpService result = socialClientService.getWxMpService(userType);
|
||||
// 断言
|
||||
assertSame(wxMpService, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMpService_clientEnable() {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
// mock 数据
|
||||
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MP.getType()));
|
||||
socialClientMapper.insert(client);
|
||||
// mock 方法
|
||||
WxMpProperties.ConfigStorage configStorage = mock(WxMpProperties.ConfigStorage.class);
|
||||
when(wxMpProperties.getConfigStorage()).thenReturn(configStorage);
|
||||
|
||||
// 调用
|
||||
WxMpService result = socialClientService.getWxMpService(userType);
|
||||
// 断言
|
||||
assertNotSame(wxMpService, result);
|
||||
assertEquals(client.getClientId(), result.getWxMpConfigStorage().getAppId());
|
||||
assertEquals(client.getClientSecret(), result.getWxMpConfigStorage().getSecret());
|
||||
}
|
||||
|
||||
// =================== 微信小程序独有 ===================
|
||||
|
||||
@Test
|
||||
public void testGetWxMaPhoneNumberInfo_success() throws WxErrorException {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
String phoneCode = randomString();
|
||||
// mock 方法
|
||||
WxMaUserService userService = mock(WxMaUserService.class);
|
||||
when(wxMaService.getUserService()).thenReturn(userService);
|
||||
WxMaPhoneNumberInfo phoneNumber = randomPojo(WxMaPhoneNumberInfo.class);
|
||||
when(userService.getPhoneNoInfo(eq(phoneCode))).thenReturn(phoneNumber);
|
||||
|
||||
// 调用
|
||||
WxMaPhoneNumberInfo result = socialClientService.getWxMaPhoneNumberInfo(userType, phoneCode);
|
||||
// 断言
|
||||
assertSame(phoneNumber, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMaPhoneNumberInfo_exception() throws WxErrorException {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
String phoneCode = randomString();
|
||||
// mock 方法
|
||||
WxMaUserService userService = mock(WxMaUserService.class);
|
||||
when(wxMaService.getUserService()).thenReturn(userService);
|
||||
WxErrorException wxErrorException = randomPojo(WxErrorException.class);
|
||||
when(userService.getPhoneNoInfo(eq(phoneCode))).thenThrow(wxErrorException);
|
||||
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> socialClientService.getWxMaPhoneNumberInfo(userType, phoneCode),
|
||||
SOCIAL_CLIENT_WEIXIN_MINI_APP_PHONE_CODE_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMaService_clientNull() {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
WxMaService result = socialClientService.getWxMaService(userType);
|
||||
// 断言
|
||||
assertSame(wxMaService, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMaService_clientDisable() {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
// mock 数据
|
||||
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())
|
||||
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MINI_APP.getType()));
|
||||
socialClientMapper.insert(client);
|
||||
|
||||
// 调用
|
||||
WxMaService result = socialClientService.getWxMaService(userType);
|
||||
// 断言
|
||||
assertSame(wxMaService, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMaService_clientEnable() {
|
||||
// 准备参数
|
||||
Integer userType = randomPojo(UserTypeEnum.class).getValue();
|
||||
// mock 数据
|
||||
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MINI_APP.getType()));
|
||||
socialClientMapper.insert(client);
|
||||
// mock 方法
|
||||
WxMaProperties.ConfigStorage configStorage = mock(WxMaProperties.ConfigStorage.class);
|
||||
when(wxMaProperties.getConfigStorage()).thenReturn(configStorage);
|
||||
|
||||
// 调用
|
||||
WxMaService result = socialClientService.getWxMaService(userType);
|
||||
// 断言
|
||||
assertNotSame(wxMaService, result);
|
||||
assertEquals(client.getClientId(), result.getWxMaConfig().getAppid());
|
||||
assertEquals(client.getClientSecret(), result.getWxMaConfig().getSecret());
|
||||
}
|
||||
|
||||
// =================== 客户端管理 ===================
|
||||
|
||||
@Test
|
||||
public void testCreateSocialClient_success() {
|
||||
// 准备参数
|
||||
SocialClientSaveReqVO reqVO = randomPojo(SocialClientSaveReqVO.class)
|
||||
SocialClientSaveReqVO reqVO = randomPojo(SocialClientSaveReqVO.class,
|
||||
o -> o.setSocialType(randomEle(SocialTypeEnum.values()).getType())
|
||||
.setUserType(randomEle(UserTypeEnum.values()).getValue())
|
||||
.setStatus(randomCommonStatus()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
@ -59,6 +374,9 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
|
||||
// 准备参数
|
||||
SocialClientSaveReqVO reqVO = randomPojo(SocialClientSaveReqVO.class, o -> {
|
||||
o.setId(dbSocialClient.getId()); // 设置更新的 ID
|
||||
o.setSocialType(randomEle(SocialTypeEnum.values()).getType())
|
||||
.setUserType(randomEle(UserTypeEnum.values()).getValue())
|
||||
.setStatus(randomCommonStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
@ -101,40 +419,47 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetSocialClient() {
|
||||
// mock 数据
|
||||
SocialClientDO dbSocialClient = randomPojo(SocialClientDO.class);
|
||||
socialClientMapper.insert(dbSocialClient);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSocialClient.getId();
|
||||
|
||||
// 调用
|
||||
SocialClientDO socialClient = socialClientService.getSocialClient(id);
|
||||
// 校验数据正确
|
||||
assertPojoEquals(dbSocialClient, socialClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSocialClientPage() {
|
||||
// mock 数据
|
||||
SocialClientDO dbSocialClient = randomPojo(SocialClientDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setSocialType(null);
|
||||
o.setUserType(null);
|
||||
o.setClientId(null);
|
||||
o.setClientSecret(null);
|
||||
o.setStatus(null);
|
||||
o.setCreateTime(null);
|
||||
o.setName("芋头");
|
||||
o.setSocialType(SocialTypeEnum.GITEE.getType());
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setClientId("yudao");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
socialClientMapper.insert(dbSocialClient);
|
||||
// 测试 name 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setName(null)));
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setName(randomString())));
|
||||
// 测试 socialType 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setSocialType(null)));
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setSocialType(SocialTypeEnum.DINGTALK.getType())));
|
||||
// 测试 userType 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setUserType(null)));
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 clientId 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setClientId(null)));
|
||||
// 测试 clientSecret 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setClientSecret(null)));
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setClientId("dao")));
|
||||
// 测试 status 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setStatus(null)));
|
||||
// 测试 createTime 不匹配
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setCreateTime(null)));
|
||||
socialClientMapper.insert(cloneIgnoreId(dbSocialClient, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
SocialClientPageReqVO reqVO = new SocialClientPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setSocialType(null);
|
||||
reqVO.setUserType(null);
|
||||
reqVO.setClientId(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setName("芋");
|
||||
reqVO.setSocialType(SocialTypeEnum.GITEE.getType());
|
||||
reqVO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
reqVO.setClientId("yu");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<SocialClientDO> pageResult = socialClientService.getSocialClientPage(reqVO);
|
||||
|
@ -1,21 +1,17 @@
|
||||
package cn.iocoder.yudao.module.system.service.social;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.socail.vo.user.SocialUserPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||
import com.xingyuv.jushauth.enums.AuthResponseStatus;
|
||||
import com.xingyuv.jushauth.model.AuthCallback;
|
||||
import com.xingyuv.jushauth.model.AuthResponse;
|
||||
import com.xingyuv.jushauth.model.AuthUser;
|
||||
import com.xingyuv.jushauth.request.AuthRequest;
|
||||
import com.xingyuv.justauth.AuthRequestFactory;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@ -23,18 +19,27 @@ import org.springframework.context.annotation.Import;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.hutool.core.util.RandomUtil.randomLong;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_AUTH_FAILURE;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link SocialUserServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(SocialUserServiceImpl.class)
|
||||
@Disabled // TODO 芋艿:后续统一修复
|
||||
public class SocialUserServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
@ -46,119 +51,7 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest {
|
||||
private SocialUserBindMapper socialUserBindMapper;
|
||||
|
||||
@MockBean
|
||||
private AuthRequestFactory authRequestFactory;
|
||||
|
||||
// TODO 芋艿:后续统一修复
|
||||
// @Test
|
||||
// public void testGetAuthorizeUrl() {
|
||||
// try (MockedStatic<AuthStateUtils> authStateUtilsMock = mockStatic(AuthStateUtils.class)) {
|
||||
// // 准备参数
|
||||
// Integer type = SocialTypeEnum.WECHAT_MP.getType();
|
||||
// String redirectUri = "sss";
|
||||
// // mock 获得对应的 AuthRequest 实现
|
||||
// AuthRequest authRequest = mock(AuthRequest.class);
|
||||
// when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
|
||||
// // mock 方法
|
||||
// authStateUtilsMock.when(AuthStateUtils::createState).thenReturn("aoteman");
|
||||
// when(authRequest.authorize(eq("aoteman"))).thenReturn("https://www.iocoder.cn?redirect_uri=yyy");
|
||||
//
|
||||
// // 调用
|
||||
// String url = socialUserService.getAuthorizeUrl(type, redirectUri);
|
||||
// // 断言
|
||||
// assertEquals("https://www.iocoder.cn?redirect_uri=sss", url);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_exists() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
// mock 方法
|
||||
SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(socialType).setCode(code).setState(state);
|
||||
socialUserMapper.insert(socialUser);
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertPojoEquals(socialUser, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_authFailure() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
// mock 方法
|
||||
AuthRequest authRequest = mock(AuthRequest.class);
|
||||
when(authRequestFactory.get(anyString())).thenReturn(authRequest);
|
||||
AuthResponse<?> authResponse = new AuthResponse<>(0, "模拟失败", null);
|
||||
when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse);
|
||||
|
||||
// 调用并断言
|
||||
assertServiceException(
|
||||
() -> socialUserService.authSocialUser(socialType, userType, randomString(10), randomString(10)),
|
||||
SOCIAL_USER_AUTH_FAILURE, "模拟失败");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_insert() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
// mock 方法
|
||||
AuthRequest authRequest = mock(AuthRequest.class);
|
||||
when(authRequestFactory.get(eq(SocialTypeEnum.GITEE.getSource()))).thenReturn(authRequest);
|
||||
AuthUser authUser = randomPojo(AuthUser.class);
|
||||
AuthResponse<AuthUser> authResponse = new AuthResponse<>(AuthResponseStatus.SUCCESS.getCode(), null, authUser);
|
||||
when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse);
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertBindSocialUser(socialType, result, authResponse.getData());
|
||||
assertEquals(code, result.getCode());
|
||||
assertEquals(state, result.getState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_update() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
// mock 数据
|
||||
socialUserMapper.insert(randomPojo(SocialUserDO.class).setType(socialType).setOpenid("test_openid"));
|
||||
// mock 方法
|
||||
AuthRequest authRequest = mock(AuthRequest.class);
|
||||
when(authRequestFactory.get(eq(SocialTypeEnum.GITEE.getSource()))).thenReturn(authRequest);
|
||||
AuthUser authUser = randomPojo(AuthUser.class);
|
||||
authUser.getToken().setOpenId("test_openid");
|
||||
AuthResponse<AuthUser> authResponse = new AuthResponse<>(AuthResponseStatus.SUCCESS.getCode(), null, authUser);
|
||||
when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse);
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertBindSocialUser(socialType, result, authResponse.getData());
|
||||
assertEquals(code, result.getCode());
|
||||
assertEquals(state, result.getState());
|
||||
}
|
||||
|
||||
private void assertBindSocialUser(Integer type, SocialUserDO socialUser, AuthUser authUser) {
|
||||
assertEquals(authUser.getToken().getAccessToken(), socialUser.getToken());
|
||||
assertEquals(toJsonString(authUser.getToken()), socialUser.getRawTokenInfo());
|
||||
assertEquals(authUser.getNickname(), socialUser.getNickname());
|
||||
assertEquals(authUser.getAvatar(), socialUser.getAvatar());
|
||||
assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo());
|
||||
assertEquals(type, socialUser.getType());
|
||||
assertEquals(authUser.getUuid(), socialUser.getOpenid());
|
||||
}
|
||||
private SocialClientService socialClientService;
|
||||
|
||||
@Test
|
||||
public void testGetSocialUserList() {
|
||||
@ -260,4 +153,136 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest {
|
||||
assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_exists() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
// mock 方法
|
||||
SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(socialType).setCode(code).setState(state);
|
||||
socialUserMapper.insert(socialUser);
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertPojoEquals(socialUser, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_notNull() {
|
||||
// mock 数据
|
||||
SocialUserDO socialUser = randomPojo(SocialUserDO.class,
|
||||
o -> o.setType(SocialTypeEnum.GITEE.getType()).setCode("tudou").setState("yuanma"));
|
||||
socialUserMapper.insert(socialUser);
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertPojoEquals(socialUser, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_insert() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
// mock 方法
|
||||
AuthUser authUser = randomPojo(AuthUser.class);
|
||||
when(socialClientService.getAuthUser(eq(socialType), eq(userType), eq(code), eq(state))).thenReturn(authUser);
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertBindSocialUser(socialType, result, authUser);
|
||||
assertEquals(code, result.getCode());
|
||||
assertEquals(state, result.getState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSocialUser_update() {
|
||||
// 准备参数
|
||||
Integer socialType = SocialTypeEnum.GITEE.getType();
|
||||
Integer userType = randomEle(SocialTypeEnum.values()).getType();
|
||||
String code = "tudou";
|
||||
String state = "yuanma";
|
||||
// mock 数据
|
||||
socialUserMapper.insert(randomPojo(SocialUserDO.class).setType(socialType).setOpenid("test_openid"));
|
||||
// mock 方法
|
||||
AuthUser authUser = randomPojo(AuthUser.class);
|
||||
when(socialClientService.getAuthUser(eq(socialType), eq(userType), eq(code), eq(state))).thenReturn(authUser);
|
||||
|
||||
// 调用
|
||||
SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state);
|
||||
// 断言
|
||||
assertBindSocialUser(socialType, result, authUser);
|
||||
assertEquals(code, result.getCode());
|
||||
assertEquals(state, result.getState());
|
||||
}
|
||||
|
||||
private void assertBindSocialUser(Integer type, SocialUserDO socialUser, AuthUser authUser) {
|
||||
assertEquals(authUser.getToken().getAccessToken(), socialUser.getToken());
|
||||
assertEquals(toJsonString(authUser.getToken()), socialUser.getRawTokenInfo());
|
||||
assertEquals(authUser.getNickname(), socialUser.getNickname());
|
||||
assertEquals(authUser.getAvatar(), socialUser.getAvatar());
|
||||
assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo());
|
||||
assertEquals(type, socialUser.getType());
|
||||
assertEquals(authUser.getUuid(), socialUser.getOpenid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSocialUser_id() {
|
||||
// mock 数据
|
||||
SocialUserDO socialUserDO = randomPojo(SocialUserDO.class);
|
||||
socialUserMapper.insert(socialUserDO);
|
||||
// 参数准备
|
||||
Long id = socialUserDO.getId();
|
||||
|
||||
// 调用
|
||||
SocialUserDO dbSocialUserDO = socialUserService.getSocialUser(id);
|
||||
// 断言
|
||||
assertPojoEquals(socialUserDO, dbSocialUserDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSocialUserPage() {
|
||||
// mock 数据
|
||||
SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, o -> { // 等会查询到
|
||||
o.setType(SocialTypeEnum.GITEE.getType());
|
||||
o.setNickname("芋艿");
|
||||
o.setOpenid("yudaoyuanma");
|
||||
o.setCreateTime(buildTime(2020, 1, 15));
|
||||
});
|
||||
socialUserMapper.insert(dbSocialUser);
|
||||
// 测试 type 不匹配
|
||||
socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setType(SocialTypeEnum.DINGTALK.getType())));
|
||||
// 测试 nickname 不匹配
|
||||
socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setNickname(randomString())));
|
||||
// 测试 openid 不匹配
|
||||
socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setOpenid("java")));
|
||||
// 测试 createTime 不匹配
|
||||
socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setCreateTime(buildTime(2020, 1, 21))));
|
||||
// 准备参数
|
||||
SocialUserPageReqVO reqVO = new SocialUserPageReqVO();
|
||||
reqVO.setType(SocialTypeEnum.GITEE.getType());
|
||||
reqVO.setNickname("芋");
|
||||
reqVO.setOpenid("yudao");
|
||||
reqVO.setCreateTime(buildBetweenTime(2020, 1, 10, 2020, 1, 20));
|
||||
|
||||
// 调用
|
||||
PageResult<SocialUserDO> pageResult = socialUserService.getSocialUserPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSocialUser, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -361,13 +361,14 @@ CREATE TABLE IF NOT EXISTS "system_social_client" (
|
||||
"user_type" int NOT NULL,
|
||||
"client_id" varchar(255) NOT NULL,
|
||||
"client_secret" varchar(255) NOT NULL,
|
||||
"agent_id" varchar(255) NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint NOT NULL,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '社交客户端表';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user