package com.tcm.training.admin.app.register.service;
|
|
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.tcm.training.admin.app.auth.service.AppSmsCodeService;
|
import com.tcm.training.admin.app.integration.haizhentong.entity.HztAppUser;
|
import com.tcm.training.admin.app.integration.haizhentong.entity.HztClinic;
|
import com.tcm.training.admin.app.integration.haizhentong.mapper.HztAppUserMapper;
|
import com.tcm.training.admin.app.integration.haizhentong.mapper.HztClinicMapper;
|
import com.tcm.training.admin.app.register.dto.AppRegisterOperatorPrepareRequest;
|
import com.tcm.training.admin.app.register.dto.AppRegisterUserRequest;
|
import com.tcm.training.admin.app.register.vo.AppRegisterOperatorPrepareResponse;
|
import com.tcm.training.admin.app.register.vo.AppRegisterResultVO;
|
import com.tcm.training.admin.app.share.service.AppShareService;
|
import com.tcm.training.admin.live.entity.Clinic;
|
import com.tcm.training.admin.live.mapper.ClinicMapper;
|
import com.tcm.training.admin.member.entity.AppUser;
|
import com.tcm.training.admin.member.mapper.UserMapper;
|
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.ArgumentCaptor;
|
import org.mockito.Captor;
|
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.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
/**
|
* APP 注册服务测试。
|
*/
|
@ExtendWith(MockitoExtension.class)
|
class AppRegisterServiceTest {
|
|
@BeforeAll
|
static void initLambdaCache() {
|
MapperBuilderAssistant assistant = new MapperBuilderAssistant(new MybatisConfiguration(), "");
|
TableInfoHelper.initTableInfo(assistant, AppUser.class);
|
TableInfoHelper.initTableInfo(assistant, Clinic.class);
|
TableInfoHelper.initTableInfo(assistant, HztAppUser.class);
|
TableInfoHelper.initTableInfo(assistant, HztClinic.class);
|
}
|
|
@Mock
|
private UserMapper userMapper;
|
|
@Mock
|
private ClinicMapper clinicMapper;
|
|
@Mock
|
private BCryptPasswordEncoder passwordEncoder;
|
|
@Mock
|
private AppSmsCodeService appSmsCodeService;
|
|
@Mock
|
private AppRegisterRegionService appRegisterRegionService;
|
|
@Mock
|
private HztAppUserMapper hztAppUserMapper;
|
|
@Mock
|
private HztClinicMapper hztClinicMapper;
|
|
@Mock
|
private StringRedisTemplate stringRedisTemplate;
|
|
@Mock
|
private ValueOperations<String, String> valueOperations;
|
|
private AppRegisterService appRegisterService;
|
|
@Captor
|
private ArgumentCaptor<AppUser> appUserCaptor;
|
@Mock
|
private AppShareService appShareService;
|
/**
|
* 使用 Mockito mock 重新组装被测服务。
|
*/
|
@BeforeEach
|
void setUp() {
|
appRegisterService = new AppRegisterService(
|
userMapper,
|
clinicMapper,
|
passwordEncoder,
|
appSmsCodeService,
|
appRegisterRegionService,
|
hztAppUserMapper,
|
hztClinicMapper,
|
stringRedisTemplate,
|
new ObjectMapper(),
|
appShareService
|
);
|
}
|
|
/**
|
* 普通用户注册时应同步海诊通资料并绑定邀请码对应的上级诊所用户。
|
*/
|
@Test
|
void registerUserShouldSyncHaizhentongProfileAndBindSuperiorClinicUser() {
|
AppRegisterUserRequest request = new AppRegisterUserRequest();
|
request.setPhone("13800138000");
|
request.setCode("666666");
|
request.setPassword("abc123!!");
|
request.setInviteCode("abc123");
|
|
HztAppUser hztAppUser = new HztAppUser();
|
hztAppUser.setNickName("海诊通昵称");
|
hztAppUser.setAvatar("https://cdn.test/avatar.png");
|
hztAppUser.setSex(2);
|
|
Clinic clinic = new Clinic();
|
clinic.setId(19L);
|
|
AppUser clinicUser = new AppUser();
|
clinicUser.setId(88L);
|
clinicUser.setClinicId(19L);
|
|
when(passwordEncoder.encode("abc123!!")).thenReturn("ENCODED");
|
when(hztAppUserMapper.selectOne(any())).thenReturn(hztAppUser);
|
when(clinicMapper.selectOne(any())).thenReturn(clinic);
|
when(userMapper.selectOne(any())).thenReturn(null, clinicUser);
|
doNothing().when(appSmsCodeService).validateRegisterCode("13800138000", "666666");
|
when(userMapper.insert(any(AppUser.class))).thenAnswer(invocation -> {
|
AppUser inserted = invocation.getArgument(0);
|
inserted.setId(1001L);
|
return 1;
|
});
|
|
AppRegisterResultVO result = appRegisterService.registerUser(request);
|
|
verify(userMapper).insert(appUserCaptor.capture());
|
AppUser inserted = appUserCaptor.getValue();
|
assertEquals("海诊通昵称", inserted.getNickname());
|
assertEquals("https://cdn.test/avatar.png", inserted.getAvatar());
|
assertEquals(Integer.valueOf(0), inserted.getGender());
|
assertEquals(Long.valueOf(19L), inserted.getClinicId());
|
assertEquals(Long.valueOf(88L), inserted.getSuperiorClinicUserId());
|
assertEquals("ENCODED", inserted.getPassword());
|
assertEquals(Long.valueOf(1001L), result.getUserId());
|
assertEquals(Integer.valueOf(0), result.getUserType());
|
}
|
|
/**
|
* 普通用户注册在海诊通未命中时应回退为手机号兜底昵称。
|
*/
|
@Test
|
void registerUserShouldFallbackToPhoneNicknameWhenHaizhentongUserMissing() {
|
AppRegisterUserRequest request = new AppRegisterUserRequest();
|
request.setPhone("13800138123");
|
request.setCode("666666");
|
request.setPassword("abc123!!");
|
|
when(passwordEncoder.encode("abc123!!")).thenReturn("ENCODED");
|
when(userMapper.selectOne(any())).thenReturn(null);
|
when(hztAppUserMapper.selectOne(any())).thenReturn(null);
|
doNothing().when(appSmsCodeService).validateRegisterCode("13800138123", "666666");
|
when(userMapper.insert(any(AppUser.class))).thenAnswer(invocation -> {
|
AppUser inserted = invocation.getArgument(0);
|
inserted.setId(1002L);
|
return 1;
|
});
|
|
AppRegisterResultVO result = appRegisterService.registerUser(request);
|
|
verify(userMapper).insert(appUserCaptor.capture());
|
AppUser inserted = appUserCaptor.getValue();
|
assertEquals("138****8123", inserted.getNickname());
|
assertNull(inserted.getAvatar());
|
assertNull(inserted.getGender());
|
assertEquals(Long.valueOf(1002L), result.getUserId());
|
assertEquals(Integer.valueOf(0), result.getUserType());
|
}
|
|
/**
|
* 经营者第一步在海诊通未命中诊所时仍应允许继续进入第二步手填。
|
*/
|
@Test
|
void prepareOperatorShouldAllowManualWhenClinicNotMatched() {
|
AppRegisterOperatorPrepareRequest request = new AppRegisterOperatorPrepareRequest();
|
request.setPhone("13800138001");
|
request.setCode("666666");
|
request.setPassword("abc123!!");
|
|
when(passwordEncoder.encode("abc123!!")).thenReturn("ENCODED");
|
when(userMapper.selectOne(any())).thenReturn(null);
|
when(hztClinicMapper.selectOne(any())).thenReturn(null);
|
when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
|
doNothing().when(appSmsCodeService).validateRegisterCode("13800138001", "666666");
|
|
AppRegisterOperatorPrepareResponse response = appRegisterService.prepareOperatorRegister(request);
|
|
assertTrue(response.getRegisterTicket() != null && !response.getRegisterTicket().trim().isEmpty());
|
assertFalse(response.isClinicMatched());
|
assertNotNull(response.getClinicInfo());
|
assertNull(response.getClinicInfo().getInstitutionName());
|
verify(valueOperations).set(any(String.class), any(String.class), anyLong(), any(TimeUnit.class));
|
}
|
|
/**
|
* 经营者第一步应使用 sys_region 解析后的地区编码回填诊所信息。
|
*/
|
@Test
|
void prepareOperatorShouldFillResolvedRegionSelection() {
|
AppRegisterOperatorPrepareRequest request = new AppRegisterOperatorPrepareRequest();
|
request.setPhone("13800138002");
|
request.setCode("666666");
|
request.setPassword("abc123!!");
|
|
HztClinic hztClinic = new HztClinic();
|
hztClinic.setClinicName("海诊通诊所");
|
hztClinic.setProvinceName("浙江省");
|
hztClinic.setCityName("杭州市");
|
hztClinic.setDistrictName("西湖区");
|
hztClinic.setClinicAddress("文三路 1 号");
|
|
AppRegisterRegionService.RegionSelection regionSelection = new AppRegisterRegionService.RegionSelection();
|
regionSelection.setProvinceCode("330000");
|
regionSelection.setProvinceName("浙江省");
|
regionSelection.setCityCode("330100");
|
regionSelection.setCityName("杭州市");
|
regionSelection.setDistrictCode("330106");
|
regionSelection.setDistrictName("西湖区");
|
|
when(passwordEncoder.encode("abc123!!")).thenReturn("ENCODED");
|
when(userMapper.selectOne(any())).thenReturn(null);
|
when(hztClinicMapper.selectOne(any())).thenReturn(hztClinic);
|
when(appRegisterRegionService.resolveRegionSelection(null, "浙江省", null, "杭州市", null, "西湖区")).thenReturn(regionSelection);
|
when(stringRedisTemplate.opsForValue()).thenReturn(valueOperations);
|
doNothing().when(appSmsCodeService).validateRegisterCode("13800138002", "666666");
|
|
AppRegisterOperatorPrepareResponse response = appRegisterService.prepareOperatorRegister(request);
|
|
assertTrue(response.isClinicMatched());
|
assertEquals("海诊通诊所", response.getClinicInfo().getInstitutionName());
|
assertEquals("330000", response.getClinicInfo().getProvinceCode());
|
assertEquals("330100", response.getClinicInfo().getCityCode());
|
assertEquals("330106", response.getClinicInfo().getDistrictCode());
|
assertEquals("文三路 1 号", response.getClinicInfo().getDetailAddress());
|
}
|
}
|