mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-06-19 06:39:50 +08:00
公共登陆注册方法V2
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
package com.jsowell.service;
|
||||
|
||||
import com.alipay.api.AlipayClient;
|
||||
import com.jsowell.alipay.factory.AlipayClientFactory;
|
||||
import com.jsowell.common.constant.CacheConstants;
|
||||
import com.jsowell.common.core.redis.RedisCache;
|
||||
import com.jsowell.common.enums.adapay.AdapayPayChannelEnum;
|
||||
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
|
||||
import com.jsowell.common.exception.BusinessException;
|
||||
import com.jsowell.common.util.JWTUtils;
|
||||
import com.jsowell.pile.domain.MemberBasicInfo;
|
||||
import com.jsowell.pile.dto.MemberRegisterAndLoginDTO;
|
||||
import com.jsowell.pile.service.MemberBasicInfoService;
|
||||
import com.jsowell.pile.transaction.dto.MemberTransactionDTO;
|
||||
import com.jsowell.pile.transaction.service.TransactionService;
|
||||
import com.jsowell.pile.util.MerchantUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class MemberServiceRegisterAndLoginTest {
|
||||
|
||||
private static final LoginInvoker OLD_LOGIN = MemberService::memberRegisterAndLogin;
|
||||
private static final LoginInvoker V2_LOGIN = MemberService::memberRegisterAndLoginV2;
|
||||
|
||||
@BeforeAll
|
||||
static void initJwtConfig() {
|
||||
setStaticField(JWTUtils.class, "secret", "dGVzdC1zZWNyZXQ=");
|
||||
setStaticField(JWTUtils.class, "serviceExpireTime", 60);
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberRegisterAndLoginV2_shouldCreateMemberAndWallet_whenXiXiaoMerchantFirstLogin() {
|
||||
RedisCache redisCache = mock(RedisCache.class);
|
||||
TransactionService transactionService = mock(TransactionService.class);
|
||||
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||
|
||||
when(redisCache.lock(anyString(), anyString(), eq(60))).thenReturn(true);
|
||||
when(memberBasicInfoService.selectInfoByMobileNumber("13800138000", MerchantUtils.XIXIAO_MERCHANT_ID)).thenReturn(null);
|
||||
when(memberBasicInfoService.queryMemberInfoByMemberId(anyString())).thenReturn(null);
|
||||
when(memberBasicInfoService.generateWalletCode()).thenReturn("WALLET-001");
|
||||
|
||||
MemberService service = newMemberService(redisCache, transactionService, memberBasicInfoService);
|
||||
MemberRegisterAndLoginDTO dto = MemberRegisterAndLoginDTO.builder()
|
||||
.mobileNumber("13800138000")
|
||||
.firstLevelMerchantId(MerchantUtils.XIXIAO_MERCHANT_ID)
|
||||
.openId("wx-open-id")
|
||||
.requestSource(AdapayPayChannelEnum.WX_LITE.getValue())
|
||||
.build();
|
||||
|
||||
String memberToken = service.memberRegisterAndLoginV2(dto);
|
||||
|
||||
assertNotNull(memberToken);
|
||||
|
||||
ArgumentCaptor<MemberTransactionDTO> captor = ArgumentCaptor.forClass(MemberTransactionDTO.class);
|
||||
verify(transactionService).createMember(captor.capture());
|
||||
|
||||
MemberTransactionDTO memberTransactionDTO = captor.getValue();
|
||||
assertNotNull(memberTransactionDTO.getMemberBasicInfo());
|
||||
assertEquals("13800138000", memberTransactionDTO.getMemberBasicInfo().getMobileNumber());
|
||||
assertEquals("wx-open-id", memberTransactionDTO.getMemberBasicInfo().getOpenId());
|
||||
assertNotNull(memberTransactionDTO.getMemberWalletInfo());
|
||||
assertEquals(MerchantUtils.XIXIAO_MERCHANT_ID, memberTransactionDTO.getMemberWalletInfo().getMerchantId());
|
||||
assertEquals("WALLET-001", memberTransactionDTO.getMemberWalletInfo().getWalletCode());
|
||||
verify(memberBasicInfoService, never()).updateMemberBasicInfo(any(MemberBasicInfo.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberRegisterAndLoginV2_shouldUpdateOpenId_whenExistingWechatMemberOpenIdChanged() {
|
||||
RedisCache redisCache = mock(RedisCache.class);
|
||||
TransactionService transactionService = mock(TransactionService.class);
|
||||
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||
|
||||
when(redisCache.lock(anyString(), anyString(), eq(60))).thenReturn(true);
|
||||
|
||||
MemberBasicInfo memberBasicInfo = MemberBasicInfo.builder()
|
||||
.memberId("M001")
|
||||
.nickName("会员M001")
|
||||
.mobileNumber("13800138001")
|
||||
.merchantId(99L)
|
||||
.openId("old-open-id")
|
||||
.build();
|
||||
when(memberBasicInfoService.selectInfoByMobileNumber("13800138001", "99")).thenReturn(memberBasicInfo);
|
||||
|
||||
MemberService service = newMemberService(redisCache, transactionService, memberBasicInfoService);
|
||||
MemberRegisterAndLoginDTO dto = MemberRegisterAndLoginDTO.builder()
|
||||
.mobileNumber("13800138001")
|
||||
.firstLevelMerchantId("99")
|
||||
.openId("new-open-id")
|
||||
.requestSource(AdapayPayChannelEnum.WX_LITE.getValue())
|
||||
.build();
|
||||
|
||||
String memberToken = service.memberRegisterAndLoginV2(dto);
|
||||
|
||||
assertNotNull(memberToken);
|
||||
assertEquals("new-open-id", memberBasicInfo.getOpenId());
|
||||
verify(memberBasicInfoService).updateMemberBasicInfo(memberBasicInfo);
|
||||
verify(transactionService, never()).createMember(any(MemberTransactionDTO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberRegisterAndLoginV2_shouldThrow_whenRegisterLockNotAcquired() {
|
||||
RedisCache redisCache = mock(RedisCache.class);
|
||||
TransactionService transactionService = mock(TransactionService.class);
|
||||
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||
|
||||
when(redisCache.lock(anyString(), anyString(), eq(60))).thenReturn(false);
|
||||
|
||||
MemberService service = newMemberService(redisCache, transactionService, memberBasicInfoService);
|
||||
MemberRegisterAndLoginDTO dto = MemberRegisterAndLoginDTO.builder()
|
||||
.mobileNumber("13800138002")
|
||||
.firstLevelMerchantId("88")
|
||||
.openId("wx-open-id")
|
||||
.requestSource(AdapayPayChannelEnum.WX_LITE.getValue())
|
||||
.build();
|
||||
|
||||
BusinessException exception = assertThrows(BusinessException.class, () -> service.memberRegisterAndLoginV2(dto));
|
||||
|
||||
assertEquals(ReturnCodeEnum.CODE_MEMBER_REGISTER_AND_LOGIN_PROCESSING.getCode(), exception.getCode());
|
||||
verify(memberBasicInfoService, never()).selectInfoByMobileNumber(anyString(), anyString());
|
||||
verify(redisCache, never()).unLock(CacheConstants.USER_APP_REGISTER + "13800138002:88");
|
||||
verify(transactionService, never()).createMember(any(MemberTransactionDTO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberRegisterAndLoginV2_shouldMatchOriginal_whenExistingAlipayMemberBuyerIdChanged() {
|
||||
exerciseExistingAlipayBuyerIdUpdate(OLD_LOGIN);
|
||||
exerciseExistingAlipayBuyerIdUpdate(V2_LOGIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberRegisterAndLoginV2_shouldMatchOriginal_whenDuplicateKeyHappensDuringRegister() {
|
||||
exerciseDuplicateKeyFallback(OLD_LOGIN);
|
||||
exerciseDuplicateKeyFallback(V2_LOGIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberRegisterAndLoginV2_shouldMatchOriginal_whenLockNotAcquired() {
|
||||
exerciseLockFailure(OLD_LOGIN);
|
||||
exerciseLockFailure(V2_LOGIN);
|
||||
}
|
||||
|
||||
private static void exerciseExistingAlipayBuyerIdUpdate(LoginInvoker invoker) {
|
||||
RedisCache redisCache = mock(RedisCache.class);
|
||||
TransactionService transactionService = mock(TransactionService.class);
|
||||
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||
|
||||
when(redisCache.lock(anyString(), anyString(), eq(60))).thenReturn(true);
|
||||
|
||||
MemberBasicInfo memberBasicInfo = MemberBasicInfo.builder()
|
||||
.memberId("A001")
|
||||
.nickName("会员A001")
|
||||
.mobileNumber("13900139000")
|
||||
.merchantId(66L)
|
||||
.buyerId("old-buyer-id")
|
||||
.build();
|
||||
when(memberBasicInfoService.selectInfoByMobileNumber("13900139000", "66")).thenReturn(memberBasicInfo);
|
||||
|
||||
MemberService service = newMemberService(redisCache, transactionService, memberBasicInfoService);
|
||||
MemberRegisterAndLoginDTO dto = MemberRegisterAndLoginDTO.builder()
|
||||
.mobileNumber("13900139000")
|
||||
.firstLevelMerchantId("66")
|
||||
.buyerId("new-buyer-id")
|
||||
.requestSource(AdapayPayChannelEnum.ALIPAY_LITE.getValue())
|
||||
.build();
|
||||
|
||||
String memberToken = invoker.invoke(service, dto);
|
||||
|
||||
assertNotNull(memberToken);
|
||||
assertEquals("new-buyer-id", memberBasicInfo.getBuyerId());
|
||||
verify(memberBasicInfoService).updateMemberBasicInfo(memberBasicInfo);
|
||||
verify(transactionService, never()).createMember(any(MemberTransactionDTO.class));
|
||||
}
|
||||
|
||||
private static void exerciseDuplicateKeyFallback(LoginInvoker invoker) {
|
||||
RedisCache redisCache = mock(RedisCache.class);
|
||||
TransactionService transactionService = mock(TransactionService.class);
|
||||
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||
|
||||
when(redisCache.lock(anyString(), anyString(), eq(60))).thenReturn(true);
|
||||
|
||||
MemberBasicInfo existingMember = MemberBasicInfo.builder()
|
||||
.memberId("D001")
|
||||
.nickName("会员D001")
|
||||
.mobileNumber("13700137000")
|
||||
.merchantId(77L)
|
||||
.openId("wx-dup-open-id")
|
||||
.build();
|
||||
when(memberBasicInfoService.selectInfoByMobileNumber("13700137000", "77")).thenReturn(null, existingMember);
|
||||
when(memberBasicInfoService.queryMemberInfoByMemberId(anyString())).thenReturn(null);
|
||||
doThrow(new DuplicateKeyException("duplicate key")).when(transactionService).createMember(any(MemberTransactionDTO.class));
|
||||
|
||||
MemberService service = newMemberService(redisCache, transactionService, memberBasicInfoService);
|
||||
MemberRegisterAndLoginDTO dto = MemberRegisterAndLoginDTO.builder()
|
||||
.mobileNumber("13700137000")
|
||||
.firstLevelMerchantId("77")
|
||||
.openId("wx-dup-open-id")
|
||||
.requestSource(AdapayPayChannelEnum.WX_LITE.getValue())
|
||||
.build();
|
||||
|
||||
String memberToken = invoker.invoke(service, dto);
|
||||
|
||||
assertNotNull(memberToken);
|
||||
verify(transactionService).createMember(any(MemberTransactionDTO.class));
|
||||
verify(memberBasicInfoService, times(2)).selectInfoByMobileNumber("13700137000", "77");
|
||||
verify(memberBasicInfoService, never()).updateMemberBasicInfo(any(MemberBasicInfo.class));
|
||||
}
|
||||
|
||||
private static void exerciseLockFailure(LoginInvoker invoker) {
|
||||
RedisCache redisCache = mock(RedisCache.class);
|
||||
TransactionService transactionService = mock(TransactionService.class);
|
||||
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||
|
||||
when(redisCache.lock(anyString(), anyString(), eq(60))).thenReturn(false);
|
||||
|
||||
MemberService service = newMemberService(redisCache, transactionService, memberBasicInfoService);
|
||||
MemberRegisterAndLoginDTO dto = MemberRegisterAndLoginDTO.builder()
|
||||
.mobileNumber("13600136000")
|
||||
.firstLevelMerchantId("55")
|
||||
.openId("wx-lock-open-id")
|
||||
.requestSource(AdapayPayChannelEnum.WX_LITE.getValue())
|
||||
.build();
|
||||
|
||||
BusinessException exception = assertThrows(BusinessException.class, () -> invoker.invoke(service, dto));
|
||||
|
||||
assertEquals(ReturnCodeEnum.CODE_MEMBER_REGISTER_AND_LOGIN_PROCESSING.getCode(), exception.getCode());
|
||||
verify(memberBasicInfoService, never()).selectInfoByMobileNumber(anyString(), anyString());
|
||||
verify(transactionService, never()).createMember(any(MemberTransactionDTO.class));
|
||||
}
|
||||
|
||||
private static MemberService newMemberService(RedisCache redisCache,
|
||||
TransactionService transactionService,
|
||||
MemberBasicInfoService memberBasicInfoService) {
|
||||
AlipayClientFactory alipayClientFactory = mock(AlipayClientFactory.class);
|
||||
when(alipayClientFactory.getAlipayClient()).thenReturn(mock(AlipayClient.class));
|
||||
|
||||
MemberService service = new MemberService(alipayClientFactory);
|
||||
setField(service, "redisCache", redisCache);
|
||||
setField(service, "transactionService", transactionService);
|
||||
setField(service, "memberBasicInfoService", memberBasicInfoService);
|
||||
return service;
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = target.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setStaticField(Class<?> targetClass, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = targetClass.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(null, value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface LoginInvoker {
|
||||
String invoke(MemberService service, MemberRegisterAndLoginDTO dto);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user