feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
+231
@@ -0,0 +1,231 @@
|
||||
package io.destiny.client.client;
|
||||
|
||||
import io.destiny.client.config.DouyinMiniProgramConfig;
|
||||
import io.destiny.client.core.exception.ClientUserAuthExceptionCode;
|
||||
import io.destiny.client.dto.WechatAuthResponse;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
class DouyinMiniProgramClientTest {
|
||||
|
||||
@Mock
|
||||
private WebClient webClient;
|
||||
|
||||
@Mock
|
||||
private WebClient.RequestHeadersUriSpec requestHeadersUriSpec;
|
||||
|
||||
@Mock
|
||||
private WebClient.RequestHeadersSpec requestHeadersSpec;
|
||||
|
||||
@Mock
|
||||
private WebClient.ResponseSpec responseSpec;
|
||||
|
||||
@Mock
|
||||
private DouyinMiniProgramConfig config;
|
||||
|
||||
private DouyinMiniProgramClient douyinMiniProgramClient;
|
||||
|
||||
private static final String TEST_CODE = "test_code_123";
|
||||
private static final String TEST_APP_ID = "test_app_id";
|
||||
private static final String TEST_APP_SECRET = "test_app_secret";
|
||||
private static final String TEST_OPEN_ID = "test_open_id";
|
||||
private static final String TEST_SESSION_KEY = "test_session_key";
|
||||
private static final String TEST_UNION_ID = "test_union_id";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
when(config.getAppId()).thenReturn(TEST_APP_ID);
|
||||
when(config.getAppSecret()).thenReturn(TEST_APP_SECRET);
|
||||
douyinMiniProgramClient = new DouyinMiniProgramClient(config, webClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_Success() {
|
||||
String successResponse = String.format("{\"err_no\":0,\"err_tips\":\"success\",\"data\":{\"openid\":\"%s\",\"session_key\":\"%s\",\"unionid\":\"%s\"}}",
|
||||
TEST_OPEN_ID, TEST_SESSION_KEY, TEST_UNION_ID);
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(successResponse));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response ->
|
||||
TEST_OPEN_ID.equals(response.getOpenId()) &&
|
||||
TEST_SESSION_KEY.equals(response.getSessionKey()) &&
|
||||
TEST_UNION_ID.equals(response.getUnionId()))
|
||||
.verifyComplete();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_WebClientResponseException() {
|
||||
WebClientResponseException exception = WebClientResponseException.create(
|
||||
400, "Bad Request", null, "{\"errcode\":40029,\"errmsg\":\"invalid code\"}".getBytes(), null);
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.error(exception));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_GeneralException() {
|
||||
RuntimeException exception = new RuntimeException("Network error");
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.error(exception));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_InvalidResponseFormat() {
|
||||
String invalidResponse = "invalid json";
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(invalidResponse));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_ResponseWithoutUnionId() {
|
||||
String responseWithoutUnionId = String.format("{\"err_no\":0,\"err_tips\":\"success\",\"data\":{\"openid\":\"%s\",\"session_key\":\"%s\"}}",
|
||||
TEST_OPEN_ID, TEST_SESSION_KEY);
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(responseWithoutUnionId));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response ->
|
||||
TEST_OPEN_ID.equals(response.getOpenId()) &&
|
||||
TEST_SESSION_KEY.equals(response.getSessionKey()) &&
|
||||
response.getUnionId() == null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_ApiError() {
|
||||
String errorResponse = "{\"err_no\":40029,\"err_tips\":\"invalid code\"}";
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(errorResponse));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_ResponseWithoutData() {
|
||||
String responseWithoutData = "{\"err_no\":0,\"err_tips\":\"success\"}";
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(responseWithoutData));
|
||||
|
||||
Mono<WechatAuthResponse> result = douyinMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
package io.destiny.client.client;
|
||||
|
||||
import io.destiny.client.config.WechatMiniProgramConfig;
|
||||
import io.destiny.client.core.exception.ClientUserAuthExceptionCode;
|
||||
import io.destiny.client.dto.WechatAuthResponse;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
class WechatMiniProgramClientTest {
|
||||
|
||||
@Mock
|
||||
private WebClient webClient;
|
||||
|
||||
@Mock
|
||||
private WebClient.RequestHeadersUriSpec requestHeadersUriSpec;
|
||||
|
||||
@Mock
|
||||
private WebClient.RequestHeadersSpec requestHeadersSpec;
|
||||
|
||||
@Mock
|
||||
private WebClient.ResponseSpec responseSpec;
|
||||
|
||||
@Mock
|
||||
private WechatMiniProgramConfig config;
|
||||
|
||||
private WechatMiniProgramClient wechatMiniProgramClient;
|
||||
|
||||
private static final String TEST_CODE = "test_code_123";
|
||||
private static final String TEST_APP_ID = "test_app_id";
|
||||
private static final String TEST_APP_SECRET = "test_app_secret";
|
||||
private static final String TEST_OPEN_ID = "test_open_id";
|
||||
private static final String TEST_SESSION_KEY = "test_session_key";
|
||||
private static final String TEST_UNION_ID = "test_union_id";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
when(config.getAppId()).thenReturn(TEST_APP_ID);
|
||||
when(config.getAppSecret()).thenReturn(TEST_APP_SECRET);
|
||||
wechatMiniProgramClient = new WechatMiniProgramClient(config, webClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_Success() {
|
||||
String successResponse = String.format("{\"openid\":\"%s\",\"session_key\":\"%s\",\"unionid\":\"%s\"}",
|
||||
TEST_OPEN_ID, TEST_SESSION_KEY, TEST_UNION_ID);
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(successResponse));
|
||||
|
||||
Mono<WechatAuthResponse> result = wechatMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response ->
|
||||
TEST_OPEN_ID.equals(response.getOpenId()) &&
|
||||
TEST_SESSION_KEY.equals(response.getSessionKey()) &&
|
||||
TEST_UNION_ID.equals(response.getUnionId()))
|
||||
.verifyComplete();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_WebClientResponseException() {
|
||||
WebClientResponseException exception = WebClientResponseException.create(
|
||||
400, "Bad Request", null, "{\"errcode\":40029,\"errmsg\":\"invalid code\"}".getBytes(), null);
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.error(exception));
|
||||
|
||||
Mono<WechatAuthResponse> result = wechatMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_GeneralException() {
|
||||
RuntimeException exception = new RuntimeException("Network error");
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.error(exception));
|
||||
|
||||
Mono<WechatAuthResponse> result = wechatMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_InvalidResponseFormat() {
|
||||
String invalidResponse = "invalid json";
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(invalidResponse));
|
||||
|
||||
Mono<WechatAuthResponse> result = wechatMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED))
|
||||
.verify();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuth_ResponseWithoutUnionId() {
|
||||
String responseWithoutUnionId = String.format("{\"openid\":\"%s\",\"session_key\":\"%s\"}",
|
||||
TEST_OPEN_ID, TEST_SESSION_KEY);
|
||||
|
||||
when(webClient.get()).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.uri(anyString(), any(Function.class))).thenReturn(requestHeadersUriSpec);
|
||||
when(requestHeadersUriSpec.accept(MediaType.APPLICATION_JSON)).thenReturn(requestHeadersSpec);
|
||||
when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
|
||||
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(responseWithoutUnionId));
|
||||
|
||||
Mono<WechatAuthResponse> result = wechatMiniProgramClient.auth(TEST_CODE);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response ->
|
||||
TEST_OPEN_ID.equals(response.getOpenId()) &&
|
||||
TEST_SESSION_KEY.equals(response.getSessionKey()) &&
|
||||
response.getUnionId() == null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webClient, times(1)).get();
|
||||
verify(requestHeadersUriSpec, times(1)).uri(anyString(), any(Function.class));
|
||||
verify(requestHeadersUriSpec, times(1)).accept(MediaType.APPLICATION_JSON);
|
||||
verify(requestHeadersSpec, times(1)).retrieve();
|
||||
verify(responseSpec, times(1)).bodyToMono(String.class);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package io.destiny.client.config;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AliyunSmsConfigTest {
|
||||
|
||||
private AliyunSmsConfig aliyunSmsConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
aliyunSmsConfig = new AliyunSmsConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters_Success() {
|
||||
aliyunSmsConfig.setAccessKeyId("testAccessKeyId");
|
||||
aliyunSmsConfig.setAccessKeySecret("testAccessKeySecret");
|
||||
aliyunSmsConfig.setEndpoint("testEndpoint");
|
||||
aliyunSmsConfig.setSignName("testSignName");
|
||||
aliyunSmsConfig.setTemplateCode("testTemplateCode");
|
||||
|
||||
assertEquals("testAccessKeyId", aliyunSmsConfig.getAccessKeyId());
|
||||
assertEquals("testAccessKeySecret", aliyunSmsConfig.getAccessKeySecret());
|
||||
assertEquals("testEndpoint", aliyunSmsConfig.getEndpoint());
|
||||
assertEquals("testSignName", aliyunSmsConfig.getSignName());
|
||||
assertEquals("testTemplateCode", aliyunSmsConfig.getTemplateCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues_Success() {
|
||||
assertEquals(10, aliyunSmsConfig.getExpireMinutes());
|
||||
assertEquals(60, aliyunSmsConfig.getSendIntervalSeconds());
|
||||
assertEquals(10, aliyunSmsConfig.getMaxSendCountPerDay());
|
||||
assertEquals(5, aliyunSmsConfig.getMaxVerifyAttempts());
|
||||
assertEquals(10, aliyunSmsConfig.getLockMinutes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCustomValues_Success() {
|
||||
aliyunSmsConfig.setExpireMinutes(5);
|
||||
aliyunSmsConfig.setSendIntervalSeconds(30);
|
||||
aliyunSmsConfig.setMaxSendCountPerDay(20);
|
||||
aliyunSmsConfig.setMaxVerifyAttempts(3);
|
||||
aliyunSmsConfig.setLockMinutes(15);
|
||||
|
||||
assertEquals(5, aliyunSmsConfig.getExpireMinutes());
|
||||
assertEquals(30, aliyunSmsConfig.getSendIntervalSeconds());
|
||||
assertEquals(20, aliyunSmsConfig.getMaxSendCountPerDay());
|
||||
assertEquals(3, aliyunSmsConfig.getMaxVerifyAttempts());
|
||||
assertEquals(15, aliyunSmsConfig.getLockMinutes());
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package io.destiny.client.config;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class DouyinMiniProgramConfigTest {
|
||||
|
||||
private DouyinMiniProgramConfig douyinMiniProgramConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
douyinMiniProgramConfig = new DouyinMiniProgramConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters_Success() {
|
||||
douyinMiniProgramConfig.setAppId("testAppId");
|
||||
douyinMiniProgramConfig.setAppSecret("testAppSecret");
|
||||
|
||||
assertEquals("testAppId", douyinMiniProgramConfig.getAppId());
|
||||
assertEquals("testAppSecret", douyinMiniProgramConfig.getAppSecret());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullValues_Success() {
|
||||
assertNull(douyinMiniProgramConfig.getAppId());
|
||||
assertNull(douyinMiniProgramConfig.getAppSecret());
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package io.destiny.client.config;
|
||||
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SmsClientConfigTest {
|
||||
|
||||
private SmsClientConfig smsClientConfig;
|
||||
|
||||
@Mock
|
||||
private AliyunSmsConfig smsConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
smsClientConfig = new SmsClientConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSmsClientBean_Success() throws Exception {
|
||||
Client client = smsClientConfig.smsClient(smsConfig);
|
||||
|
||||
assertNotNull(client);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package io.destiny.client.config;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class WechatMiniProgramConfigTest {
|
||||
|
||||
private WechatMiniProgramConfig wechatMiniProgramConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
wechatMiniProgramConfig = new WechatMiniProgramConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters_Success() {
|
||||
wechatMiniProgramConfig.setAppId("testAppId");
|
||||
wechatMiniProgramConfig.setAppSecret("testAppSecret");
|
||||
|
||||
assertEquals("testAppId", wechatMiniProgramConfig.getAppId());
|
||||
assertEquals("testAppSecret", wechatMiniProgramConfig.getAppSecret());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullValues_Success() {
|
||||
assertNull(wechatMiniProgramConfig.getAppId());
|
||||
assertNull(wechatMiniProgramConfig.getAppSecret());
|
||||
}
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
package io.destiny.client.core.domain;
|
||||
|
||||
import io.destiny.common.primitive.IpAddress;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientLoginLogTest {
|
||||
|
||||
private static final Long TEST_ID = 12345L;
|
||||
private static final Long TEST_CLIENT_USER_ID = 67890L;
|
||||
private static final IpAddress TEST_IP_ADDRESS = IpAddress.of("192.168.1.1");
|
||||
|
||||
@Test
|
||||
void testConstructor_DefaultValues() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
|
||||
assertNull(log.getId());
|
||||
assertNull(log.getClientUserId());
|
||||
assertNull(log.getIpAddress());
|
||||
assertNull(log.getLoginTime());
|
||||
assertNull(log.getLogoutTime());
|
||||
assertNull(log.getCreatedAt());
|
||||
assertNull(log.getUpdatedAt());
|
||||
assertNull(log.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructor_WithParameters() {
|
||||
ClientLoginLog log = new ClientLoginLog(TEST_CLIENT_USER_ID, TEST_IP_ADDRESS);
|
||||
|
||||
assertNotNull(log.getId());
|
||||
assertTrue(log.getId() > 0);
|
||||
assertEquals(TEST_CLIENT_USER_ID, log.getClientUserId());
|
||||
assertEquals(TEST_IP_ADDRESS, log.getIpAddress());
|
||||
assertNotNull(log.getLoginTime());
|
||||
assertTrue(log.getLoginTime().isBefore(LocalDateTime.now().plusSeconds(1)));
|
||||
assertTrue(log.getLoginTime().isAfter(LocalDateTime.now().minusSeconds(1)));
|
||||
assertNull(log.getLogoutTime());
|
||||
assertNull(log.getCreatedAt());
|
||||
assertNull(log.getUpdatedAt());
|
||||
assertNull(log.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
|
||||
log.setId(TEST_ID);
|
||||
log.setClientUserId(TEST_CLIENT_USER_ID);
|
||||
log.setIpAddress(TEST_IP_ADDRESS);
|
||||
LocalDateTime testLoginTime = LocalDateTime.now().minusHours(1);
|
||||
LocalDateTime testLogoutTime = LocalDateTime.now().minusMinutes(30);
|
||||
LocalDateTime testCreatedAt = LocalDateTime.now().minusDays(1);
|
||||
LocalDateTime testUpdatedAt = LocalDateTime.now().minusHours(1);
|
||||
LocalDateTime testDeletedAt = LocalDateTime.now();
|
||||
log.setLoginTime(testLoginTime);
|
||||
log.setLogoutTime(testLogoutTime);
|
||||
log.setCreatedAt(testCreatedAt);
|
||||
log.setUpdatedAt(testUpdatedAt);
|
||||
log.setDeletedAt(testDeletedAt);
|
||||
|
||||
assertEquals(TEST_ID, log.getId());
|
||||
assertEquals(TEST_CLIENT_USER_ID, log.getClientUserId());
|
||||
assertEquals(TEST_IP_ADDRESS, log.getIpAddress());
|
||||
assertEquals(testLoginTime, log.getLoginTime());
|
||||
assertEquals(testLogoutTime, log.getLogoutTime());
|
||||
assertEquals(testCreatedAt, log.getCreatedAt());
|
||||
assertEquals(testUpdatedAt, log.getUpdatedAt());
|
||||
assertEquals(testDeletedAt, log.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_SetsUniqueId() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
log.generateId();
|
||||
|
||||
assertNotNull(log.getId());
|
||||
assertTrue(log.getId() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_GeneratesDifferentIds() {
|
||||
ClientLoginLog log1 = new ClientLoginLog();
|
||||
ClientLoginLog log2 = new ClientLoginLog();
|
||||
|
||||
log1.generateId();
|
||||
log2.generateId();
|
||||
|
||||
assertNotNull(log1.getId());
|
||||
assertNotNull(log2.getId());
|
||||
assertNotEquals(log1.getId(), log2.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_OverwritesExistingId() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
log.setId(TEST_ID);
|
||||
|
||||
log.generateId();
|
||||
|
||||
assertNotEquals(TEST_ID, log.getId());
|
||||
assertNotNull(log.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_SetsDeletedAt() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
assertNull(log.getDeletedAt());
|
||||
|
||||
log.delete();
|
||||
|
||||
assertNotNull(log.getDeletedAt());
|
||||
assertTrue(log.getDeletedAt().isBefore(LocalDateTime.now().plusSeconds(1)));
|
||||
assertTrue(log.getDeletedAt().isAfter(LocalDateTime.now().minusSeconds(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_CanBeCalledMultipleTimes() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
log.delete();
|
||||
LocalDateTime firstDeletedAt = log.getDeletedAt();
|
||||
|
||||
log.delete();
|
||||
LocalDateTime secondDeletedAt = log.getDeletedAt();
|
||||
|
||||
assertNotNull(secondDeletedAt);
|
||||
assertNotEquals(firstDeletedAt, secondDeletedAt);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsLogoutTimeNull_WhenNull() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
log.setLogoutTime(null);
|
||||
|
||||
assertTrue(log.isLogoutTimeNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsLogoutTimeNull_WhenNotNull() {
|
||||
ClientLoginLog log = new ClientLoginLog();
|
||||
LocalDateTime logoutTime = LocalDateTime.now();
|
||||
log.setLogoutTime(logoutTime);
|
||||
|
||||
assertFalse(log.isLogoutTimeNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructor_GeneratesId() {
|
||||
ClientLoginLog log1 = new ClientLoginLog(TEST_CLIENT_USER_ID, TEST_IP_ADDRESS);
|
||||
ClientLoginLog log2 = new ClientLoginLog(TEST_CLIENT_USER_ID, TEST_IP_ADDRESS);
|
||||
|
||||
assertNotNull(log1.getId());
|
||||
assertNotNull(log2.getId());
|
||||
assertNotEquals(log1.getId(), log2.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructor_SetsLoginTimeToNow() {
|
||||
LocalDateTime before = LocalDateTime.now();
|
||||
ClientLoginLog log = new ClientLoginLog(TEST_CLIENT_USER_ID, TEST_IP_ADDRESS);
|
||||
LocalDateTime after = LocalDateTime.now();
|
||||
|
||||
assertNotNull(log.getLoginTime());
|
||||
assertTrue(log.getLoginTime().isAfter(before.minusSeconds(1)));
|
||||
assertTrue(log.getLoginTime().isBefore(after.plusSeconds(1)));
|
||||
}
|
||||
}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
package io.destiny.client.core.domain;
|
||||
|
||||
import io.destiny.common.primitive.PhoneNumber;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientUserTest {
|
||||
|
||||
private static final Long TEST_ID = 12345L;
|
||||
private static final String TEST_USERNAME = "testuser";
|
||||
private static final String TEST_PASSWORD = "password123";
|
||||
private static final String TEST_WECHAT_OPEN_ID = "wx_open_id_123";
|
||||
private static final String TEST_WECHAT_UNION_ID = "wx_union_id_456";
|
||||
private static final String TEST_DOUYIN_OPEN_ID = "dy_open_id_789";
|
||||
private static final String TEST_DOUYIN_UNION_ID = "dy_union_id_012";
|
||||
private static final String TEST_GENDER = "male";
|
||||
private static final String TEST_NICKNAME = "测试用户";
|
||||
private static final String TEST_AVATAR_URL = "https://example.com/avatar.jpg";
|
||||
|
||||
@Test
|
||||
void testConstructor_DefaultValues() {
|
||||
ClientUser user = new ClientUser();
|
||||
|
||||
assertNull(user.getId());
|
||||
assertNull(user.getUsername());
|
||||
assertNull(user.getPassword());
|
||||
assertNull(user.getEmail());
|
||||
assertNull(user.getPhone());
|
||||
assertNull(user.getGender());
|
||||
assertNull(user.getBirthTime());
|
||||
assertNull(user.getWechatOpenId());
|
||||
assertNull(user.getWechatUnionId());
|
||||
assertNull(user.getDouyinOpenId());
|
||||
assertNull(user.getDouyinUnionId());
|
||||
assertNull(user.getPhoneVerified());
|
||||
assertNull(user.getNickname());
|
||||
assertNull(user.getAvatarUrl());
|
||||
assertNull(user.getCreatedAt());
|
||||
assertNull(user.getUpdatedAt());
|
||||
assertNull(user.getDeletedAt());
|
||||
assertNull(user.getLoginLogs());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
ClientUser user = new ClientUser();
|
||||
|
||||
user.setId(TEST_ID);
|
||||
user.setUsername(TEST_USERNAME);
|
||||
user.setPassword(TEST_PASSWORD);
|
||||
user.setGender(TEST_GENDER);
|
||||
user.setWechatOpenId(TEST_WECHAT_OPEN_ID);
|
||||
user.setWechatUnionId(TEST_WECHAT_UNION_ID);
|
||||
user.setDouyinOpenId(TEST_DOUYIN_OPEN_ID);
|
||||
user.setDouyinUnionId(TEST_DOUYIN_UNION_ID);
|
||||
user.setPhoneVerified(true);
|
||||
user.setNickname(TEST_NICKNAME);
|
||||
user.setAvatarUrl(TEST_AVATAR_URL);
|
||||
LocalDateTime testBirthTime = LocalDateTime.of(1990, 1, 1, 0, 0);
|
||||
user.setBirthTime(testBirthTime);
|
||||
LocalDateTime testCreatedAt = LocalDateTime.now().minusDays(1);
|
||||
LocalDateTime testUpdatedAt = LocalDateTime.now().minusHours(1);
|
||||
LocalDateTime testDeletedAt = LocalDateTime.now();
|
||||
user.setCreatedAt(testCreatedAt);
|
||||
user.setUpdatedAt(testUpdatedAt);
|
||||
user.setDeletedAt(testDeletedAt);
|
||||
|
||||
assertEquals(TEST_ID, user.getId());
|
||||
assertEquals(TEST_USERNAME, user.getUsername());
|
||||
assertEquals(TEST_PASSWORD, user.getPassword());
|
||||
assertEquals(TEST_GENDER, user.getGender());
|
||||
assertEquals(TEST_WECHAT_OPEN_ID, user.getWechatOpenId());
|
||||
assertEquals(TEST_WECHAT_UNION_ID, user.getWechatUnionId());
|
||||
assertEquals(TEST_DOUYIN_OPEN_ID, user.getDouyinOpenId());
|
||||
assertEquals(TEST_DOUYIN_UNION_ID, user.getDouyinUnionId());
|
||||
assertTrue(user.getPhoneVerified());
|
||||
assertEquals(TEST_NICKNAME, user.getNickname());
|
||||
assertEquals(TEST_AVATAR_URL, user.getAvatarUrl());
|
||||
assertEquals(testBirthTime, user.getBirthTime());
|
||||
assertEquals(testCreatedAt, user.getCreatedAt());
|
||||
assertEquals(testUpdatedAt, user.getUpdatedAt());
|
||||
assertEquals(testDeletedAt, user.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetPhone_WithPhoneNumber() {
|
||||
ClientUser user = new ClientUser();
|
||||
PhoneNumber phoneNumber = PhoneNumber.of("13800138000");
|
||||
|
||||
user.setPhone(phoneNumber);
|
||||
|
||||
assertEquals(phoneNumber, user.getPhone());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetPhone_WithNull() {
|
||||
ClientUser user = new ClientUser();
|
||||
|
||||
user.setPhone(null);
|
||||
|
||||
assertNull(user.getPhone());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_SetsUniqueId() {
|
||||
ClientUser user = new ClientUser();
|
||||
user.generateId();
|
||||
|
||||
assertNotNull(user.getId());
|
||||
assertTrue(user.getId() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_GeneratesDifferentIds() {
|
||||
ClientUser user1 = new ClientUser();
|
||||
ClientUser user2 = new ClientUser();
|
||||
|
||||
user1.generateId();
|
||||
user2.generateId();
|
||||
|
||||
assertNotNull(user1.getId());
|
||||
assertNotNull(user2.getId());
|
||||
assertNotEquals(user1.getId(), user2.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_SetsDeletedAt() {
|
||||
ClientUser user = new ClientUser();
|
||||
assertNull(user.getDeletedAt());
|
||||
|
||||
user.delete();
|
||||
|
||||
assertNotNull(user.getDeletedAt());
|
||||
assertTrue(user.getDeletedAt().isBefore(LocalDateTime.now().plusSeconds(1)));
|
||||
assertTrue(user.getDeletedAt().isAfter(LocalDateTime.now().minusSeconds(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_CanBeCalledMultipleTimes() {
|
||||
ClientUser user = new ClientUser();
|
||||
user.delete();
|
||||
LocalDateTime firstDeletedAt = user.getDeletedAt();
|
||||
|
||||
user.delete();
|
||||
LocalDateTime secondDeletedAt = user.getDeletedAt();
|
||||
|
||||
assertNotNull(secondDeletedAt);
|
||||
assertNotEquals(firstDeletedAt, secondDeletedAt);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhoneVerified_DefaultValue() {
|
||||
ClientUser user = new ClientUser();
|
||||
|
||||
assertNull(user.getPhoneVerified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhoneVerified_SetToTrue() {
|
||||
ClientUser user = new ClientUser();
|
||||
user.setPhoneVerified(true);
|
||||
|
||||
assertTrue(user.getPhoneVerified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhoneVerified_SetToFalse() {
|
||||
ClientUser user = new ClientUser();
|
||||
user.setPhoneVerified(false);
|
||||
|
||||
assertFalse(user.getPhoneVerified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedAt_DefaultValue() {
|
||||
ClientUser user = new ClientUser();
|
||||
|
||||
assertNull(user.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleted_AfterDelete() {
|
||||
ClientUser user = new ClientUser();
|
||||
user.delete();
|
||||
|
||||
assertNotNull(user.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginLogs_DefaultValue() {
|
||||
ClientUser user = new ClientUser();
|
||||
|
||||
assertNull(user.getLoginLogs());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLoginLogs_WithEmptyList() {
|
||||
ClientUser user = new ClientUser();
|
||||
user.setLoginLogs(List.of());
|
||||
|
||||
assertNotNull(user.getLoginLogs());
|
||||
assertTrue(user.getLoginLogs().isEmpty());
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
package io.destiny.client.core.domain;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SmsVerificationCodeTest {
|
||||
|
||||
private static final String TEST_PHONE = "13800138000";
|
||||
private static final String TEST_CODE = "123456";
|
||||
private static final String TEST_TYPE = "login";
|
||||
|
||||
@Test
|
||||
void testConstructor_ValidInput_Success() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertNotNull(code.getId());
|
||||
assertEquals(TEST_PHONE, code.getPhone());
|
||||
assertEquals(TEST_CODE, code.getCode());
|
||||
assertEquals(TEST_TYPE, code.getType());
|
||||
assertEquals(expireTime, code.getExpireTime());
|
||||
assertNotNull(code.getCreatedAt());
|
||||
assertNotNull(code.getUpdatedAt());
|
||||
assertFalse(code.isVerified());
|
||||
assertEquals(0, code.getVerifyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructor_GeneratesUniqueId() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code1 = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
SmsVerificationCode code2 = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertNotNull(code1.getId());
|
||||
assertNotNull(code2.getId());
|
||||
assertNotEquals(code1.getId(), code2.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMarkAsVerified_UpdatesStatusAndTimestamp() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
LocalDateTime originalUpdatedAt = code.getUpdatedAt();
|
||||
|
||||
code.markAsVerified();
|
||||
|
||||
assertTrue(code.isVerified());
|
||||
assertTrue(code.getUpdatedAt().isAfter(originalUpdatedAt) || code.getUpdatedAt().isEqual(originalUpdatedAt));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIncrementVerifyCount_FromZero() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
code.incrementVerifyCount();
|
||||
|
||||
assertEquals(1, code.getVerifyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIncrementVerifyCount_MultipleTimes() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
code.incrementVerifyCount();
|
||||
code.incrementVerifyCount();
|
||||
code.incrementVerifyCount();
|
||||
|
||||
assertEquals(3, code.getVerifyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIncrementVerifyCount_UpdatesTimestamp() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
LocalDateTime originalUpdatedAt = code.getUpdatedAt();
|
||||
|
||||
code.incrementVerifyCount();
|
||||
|
||||
assertTrue(code.getUpdatedAt().isAfter(originalUpdatedAt) || code.getUpdatedAt().isEqual(originalUpdatedAt));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsExpired_WithFutureExpireTime() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertFalse(code.isExpired());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsExpired_WithPastExpireTime() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().minusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertTrue(code.isExpired());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsExpired_WithCurrentTime() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(1);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertFalse(code.isExpired());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsVerified_DefaultValue() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertFalse(code.isVerified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsVerified_AfterMarkAsVerified() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
code.markAsVerified();
|
||||
|
||||
assertTrue(code.isVerified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetVerifyCount_DefaultValue() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
assertEquals(0, code.getVerifyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetVerifyCount_AfterIncrements() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
code.incrementVerifyCount();
|
||||
code.incrementVerifyCount();
|
||||
|
||||
assertEquals(2, code.getVerifyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(5);
|
||||
SmsVerificationCode code = new SmsVerificationCode(TEST_PHONE, TEST_CODE, TEST_TYPE, expireTime);
|
||||
|
||||
Long testId = 12345L;
|
||||
LocalDateTime testCreatedAt = LocalDateTime.now().minusHours(1);
|
||||
LocalDateTime testUpdatedAt = LocalDateTime.now().minusMinutes(30);
|
||||
|
||||
code.setId(testId);
|
||||
code.setCreatedAt(testCreatedAt);
|
||||
code.setUpdatedAt(testUpdatedAt);
|
||||
|
||||
assertEquals(testId, code.getId());
|
||||
assertEquals(testCreatedAt, code.getCreatedAt());
|
||||
assertEquals(testUpdatedAt, code.getUpdatedAt());
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
package io.destiny.client.core.domain;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class UserBindingTest {
|
||||
|
||||
private static final Long TEST_ID = 12345L;
|
||||
private static final Long TEST_USER_ID = 67890L;
|
||||
private static final String TEST_PLATFORM = "wechat";
|
||||
private static final String TEST_PLATFORM_OPEN_ID = "wx_open_id_123";
|
||||
private static final String TEST_PLATFORM_UNION_ID = "wx_union_id_456";
|
||||
|
||||
@Test
|
||||
void testConstructor_DefaultValues() {
|
||||
UserBinding binding = new UserBinding();
|
||||
|
||||
assertNull(binding.getId());
|
||||
assertNull(binding.getUserId());
|
||||
assertNull(binding.getPlatform());
|
||||
assertNull(binding.getPlatformOpenId());
|
||||
assertNull(binding.getPlatformUnionId());
|
||||
assertNull(binding.getCreatedAt());
|
||||
assertNull(binding.getUpdatedAt());
|
||||
assertNull(binding.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
UserBinding binding = new UserBinding();
|
||||
|
||||
binding.setId(TEST_ID);
|
||||
binding.setUserId(TEST_USER_ID);
|
||||
binding.setPlatform(TEST_PLATFORM);
|
||||
binding.setPlatformOpenId(TEST_PLATFORM_OPEN_ID);
|
||||
binding.setPlatformUnionId(TEST_PLATFORM_UNION_ID);
|
||||
LocalDateTime testCreatedAt = LocalDateTime.now().minusDays(1);
|
||||
LocalDateTime testUpdatedAt = LocalDateTime.now().minusHours(1);
|
||||
LocalDateTime testDeletedAt = LocalDateTime.now();
|
||||
binding.setCreatedAt(testCreatedAt);
|
||||
binding.setUpdatedAt(testUpdatedAt);
|
||||
binding.setDeletedAt(testDeletedAt);
|
||||
|
||||
assertEquals(TEST_ID, binding.getId());
|
||||
assertEquals(TEST_USER_ID, binding.getUserId());
|
||||
assertEquals(TEST_PLATFORM, binding.getPlatform());
|
||||
assertEquals(TEST_PLATFORM_OPEN_ID, binding.getPlatformOpenId());
|
||||
assertEquals(TEST_PLATFORM_UNION_ID, binding.getPlatformUnionId());
|
||||
assertEquals(testCreatedAt, binding.getCreatedAt());
|
||||
assertEquals(testUpdatedAt, binding.getUpdatedAt());
|
||||
assertEquals(testDeletedAt, binding.getDeletedAt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_SetsUniqueId() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.generateId();
|
||||
|
||||
assertNotNull(binding.getId());
|
||||
assertTrue(binding.getId() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateId_GeneratesDifferentIds() {
|
||||
UserBinding binding1 = new UserBinding();
|
||||
UserBinding binding2 = new UserBinding();
|
||||
|
||||
binding1.generateId();
|
||||
binding2.generateId();
|
||||
|
||||
assertNotNull(binding1.getId());
|
||||
assertNotNull(binding2.getId());
|
||||
assertNotEquals(binding1.getId(), binding2.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_SetsDeletedAt() {
|
||||
UserBinding binding = new UserBinding();
|
||||
assertNull(binding.getDeletedAt());
|
||||
|
||||
binding.delete();
|
||||
|
||||
assertNotNull(binding.getDeletedAt());
|
||||
assertTrue(binding.getDeletedAt().isBefore(LocalDateTime.now().plusSeconds(1)));
|
||||
assertTrue(binding.getDeletedAt().isAfter(LocalDateTime.now().minusSeconds(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_CanBeCalledMultipleTimes() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.delete();
|
||||
LocalDateTime firstDeletedAt = binding.getDeletedAt();
|
||||
|
||||
binding.delete();
|
||||
LocalDateTime secondDeletedAt = binding.getDeletedAt();
|
||||
|
||||
assertNotNull(secondDeletedAt);
|
||||
assertNotEquals(firstDeletedAt, secondDeletedAt);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsWechatPlatform_WhenWechat() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setPlatform("wechat");
|
||||
|
||||
assertTrue(binding.isWechatPlatform());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsWechatPlatform_WhenDouyin() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setPlatform("douyin");
|
||||
|
||||
assertFalse(binding.isWechatPlatform());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsWechatPlatform_WhenNull() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setPlatform(null);
|
||||
|
||||
assertFalse(binding.isWechatPlatform());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDouyinPlatform_WhenDouyin() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setPlatform("douyin");
|
||||
|
||||
assertTrue(binding.isDouyinPlatform());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDouyinPlatform_WhenWechat() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setPlatform("wechat");
|
||||
|
||||
assertFalse(binding.isDouyinPlatform());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDouyinPlatform_WhenNull() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setPlatform(null);
|
||||
|
||||
assertFalse(binding.isDouyinPlatform());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDeleted_WhenDeletedAtPresent() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setDeletedAt(LocalDateTime.now());
|
||||
|
||||
assertTrue(binding.isDeleted());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsDeleted_WhenDeletedAtNull() {
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setDeletedAt(null);
|
||||
|
||||
assertFalse(binding.isDeleted());
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package io.destiny.client.core.enums;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class PlatformTypeTest {
|
||||
|
||||
@Test
|
||||
void testGetCode() {
|
||||
assertEquals("wechat", PlatformType.WECHAT.getCode());
|
||||
assertEquals("douyin", PlatformType.DOUYIN.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDisplayName() {
|
||||
assertEquals("微信小程序", PlatformType.WECHAT.getDisplayName());
|
||||
assertEquals("抖音小程序", PlatformType.DOUYIN.getDisplayName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFromCode() {
|
||||
assertEquals(PlatformType.WECHAT, PlatformType.fromCode("wechat"));
|
||||
assertEquals(PlatformType.DOUYIN, PlatformType.fromCode("douyin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFromCodeInvalid() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> PlatformType.fromCode("invalid_code")
|
||||
);
|
||||
assertTrue(exception.getMessage().contains("Unknown platform type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValues() {
|
||||
PlatformType[] values = PlatformType.values();
|
||||
assertEquals(2, values.length);
|
||||
assertEquals(PlatformType.WECHAT, values[0]);
|
||||
assertEquals(PlatformType.DOUYIN, values[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValueOf() {
|
||||
assertEquals(PlatformType.WECHAT, PlatformType.valueOf("WECHAT"));
|
||||
assertEquals(PlatformType.DOUYIN, PlatformType.valueOf("DOUYIN"));
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package io.destiny.client.core.enums;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SmsCodeTypeTest {
|
||||
|
||||
@Test
|
||||
void testGetCode() {
|
||||
assertEquals("login", SmsCodeType.LOGIN.getCode());
|
||||
assertEquals("register", SmsCodeType.REGISTER.getCode());
|
||||
assertEquals("bind", SmsCodeType.BIND.getCode());
|
||||
assertEquals("reset_password", SmsCodeType.RESET_PASSWORD.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDisplayName() {
|
||||
assertEquals("登录验证码", SmsCodeType.LOGIN.getDisplayName());
|
||||
assertEquals("注册验证码", SmsCodeType.REGISTER.getDisplayName());
|
||||
assertEquals("绑定验证码", SmsCodeType.BIND.getDisplayName());
|
||||
assertEquals("重置密码验证码", SmsCodeType.RESET_PASSWORD.getDisplayName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetTemplateCode() {
|
||||
assertEquals("SMS_123456789", SmsCodeType.LOGIN.getTemplateCode());
|
||||
assertEquals("SMS_123456790", SmsCodeType.REGISTER.getTemplateCode());
|
||||
assertEquals("SMS_123456791", SmsCodeType.BIND.getTemplateCode());
|
||||
assertEquals("SMS_123456792", SmsCodeType.RESET_PASSWORD.getTemplateCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFromCode() {
|
||||
assertEquals(SmsCodeType.LOGIN, SmsCodeType.fromCode("login"));
|
||||
assertEquals(SmsCodeType.REGISTER, SmsCodeType.fromCode("register"));
|
||||
assertEquals(SmsCodeType.BIND, SmsCodeType.fromCode("bind"));
|
||||
assertEquals(SmsCodeType.RESET_PASSWORD, SmsCodeType.fromCode("reset_password"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFromCodeInvalid() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> SmsCodeType.fromCode("invalid_code")
|
||||
);
|
||||
assertTrue(exception.getMessage().contains("Unknown SMS code type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValues() {
|
||||
SmsCodeType[] values = SmsCodeType.values();
|
||||
assertEquals(4, values.length);
|
||||
assertEquals(SmsCodeType.LOGIN, values[0]);
|
||||
assertEquals(SmsCodeType.REGISTER, values[1]);
|
||||
assertEquals(SmsCodeType.BIND, values[2]);
|
||||
assertEquals(SmsCodeType.RESET_PASSWORD, values[3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValueOf() {
|
||||
assertEquals(SmsCodeType.LOGIN, SmsCodeType.valueOf("LOGIN"));
|
||||
assertEquals(SmsCodeType.REGISTER, SmsCodeType.valueOf("REGISTER"));
|
||||
assertEquals(SmsCodeType.BIND, SmsCodeType.valueOf("BIND"));
|
||||
assertEquals(SmsCodeType.RESET_PASSWORD, SmsCodeType.valueOf("RESET_PASSWORD"));
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package io.destiny.client.core.exception;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientUserAuthExceptionCodeTest {
|
||||
|
||||
@Test
|
||||
void testGetCode() {
|
||||
assertEquals("CLIENT_AUTH_10001", ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD.getCode());
|
||||
assertEquals("CLIENT_AUTH_10002", ClientUserAuthExceptionCode.CLIENT_INVALID_PLATFORM.getCode());
|
||||
assertEquals("CLIENT_AUTH_10003", ClientUserAuthExceptionCode.CLIENT_INVALID_WECHAT_CODE.getCode());
|
||||
assertEquals("CLIENT_AUTH_10004", ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10005", ClientUserAuthExceptionCode.CLIENT_INVALID_DOUYIN_CODE.getCode());
|
||||
assertEquals("CLIENT_AUTH_10006", ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10007", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXPIRED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10008", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID.getCode());
|
||||
assertEquals("CLIENT_AUTH_10009", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_USED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10010", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXCEEDED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10011", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_TOO_FAST.getCode());
|
||||
assertEquals("CLIENT_AUTH_10012", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10013", ClientUserAuthExceptionCode.CLIENT_USER_NOT_FOUND.getCode());
|
||||
assertEquals("CLIENT_AUTH_10014", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_ALREADY_BOUND.getCode());
|
||||
assertEquals("CLIENT_AUTH_10015", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_BIND_FAILED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10016", ClientUserAuthExceptionCode.CLIENT_PHONE_NOT_VERIFIED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10017", ClientUserAuthExceptionCode.CLIENT_AUTO_REGISTER_FAILED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10018", ClientUserAuthExceptionCode.CLIENT_LOGIN_TYPE_INVALID.getCode());
|
||||
assertEquals("CLIENT_AUTH_10019", ClientUserAuthExceptionCode.CLIENT_LOGIN_FAILED.getCode());
|
||||
assertEquals("CLIENT_AUTH_10020", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_LOCKED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDisplayName() {
|
||||
assertEquals("用户名或密码错误", ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD.getDisplayName());
|
||||
assertEquals("平台标识无效", ClientUserAuthExceptionCode.CLIENT_INVALID_PLATFORM.getDisplayName());
|
||||
assertEquals("微信授权码无效", ClientUserAuthExceptionCode.CLIENT_INVALID_WECHAT_CODE.getDisplayName());
|
||||
assertEquals("微信授权失败", ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED.getDisplayName());
|
||||
assertEquals("抖音授权码无效", ClientUserAuthExceptionCode.CLIENT_INVALID_DOUYIN_CODE.getDisplayName());
|
||||
assertEquals("抖音授权失败", ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED.getDisplayName());
|
||||
assertEquals("验证码已过期", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXPIRED.getDisplayName());
|
||||
assertEquals("验证码错误", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID.getDisplayName());
|
||||
assertEquals("验证码已使用", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_USED.getDisplayName());
|
||||
assertEquals("验证码验证次数过多", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXCEEDED.getDisplayName());
|
||||
assertEquals("验证码发送频率过高", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_TOO_FAST.getDisplayName());
|
||||
assertEquals("验证码发送次数超限", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED.getDisplayName());
|
||||
assertEquals("用户不存在", ClientUserAuthExceptionCode.CLIENT_USER_NOT_FOUND.getDisplayName());
|
||||
assertEquals("账号已绑定", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_ALREADY_BOUND.getDisplayName());
|
||||
assertEquals("账号绑定失败", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_BIND_FAILED.getDisplayName());
|
||||
assertEquals("手机号未验证", ClientUserAuthExceptionCode.CLIENT_PHONE_NOT_VERIFIED.getDisplayName());
|
||||
assertEquals("自动注册失败", ClientUserAuthExceptionCode.CLIENT_AUTO_REGISTER_FAILED.getDisplayName());
|
||||
assertEquals("登录类型无效", ClientUserAuthExceptionCode.CLIENT_LOGIN_TYPE_INVALID.getDisplayName());
|
||||
assertEquals("登录失败", ClientUserAuthExceptionCode.CLIENT_LOGIN_FAILED.getDisplayName());
|
||||
assertEquals("账号已锁定", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_LOCKED.getDisplayName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetHttpCode() {
|
||||
assertEquals("401", ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_INVALID_PLATFORM.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_INVALID_WECHAT_CODE.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_INVALID_DOUYIN_CODE.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXPIRED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_USED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXCEEDED.getHttpCode());
|
||||
assertEquals("429", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_TOO_FAST.getHttpCode());
|
||||
assertEquals("429", ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED.getHttpCode());
|
||||
assertEquals("404", ClientUserAuthExceptionCode.CLIENT_USER_NOT_FOUND.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_ALREADY_BOUND.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_BIND_FAILED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_PHONE_NOT_VERIFIED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_AUTO_REGISTER_FAILED.getHttpCode());
|
||||
assertEquals("400", ClientUserAuthExceptionCode.CLIENT_LOGIN_TYPE_INVALID.getHttpCode());
|
||||
assertEquals("401", ClientUserAuthExceptionCode.CLIENT_LOGIN_FAILED.getHttpCode());
|
||||
assertEquals("403", ClientUserAuthExceptionCode.CLIENT_ACCOUNT_LOCKED.getHttpCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValues() {
|
||||
ClientUserAuthExceptionCode[] values = ClientUserAuthExceptionCode.values();
|
||||
assertEquals(20, values.length);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD, values[0]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_PLATFORM, values[1]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_WECHAT_CODE, values[2]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED, values[3]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_DOUYIN_CODE, values[4]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED, values[5]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXPIRED, values[6]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID, values[7]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_USED, values[8]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXCEEDED, values[9]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_TOO_FAST, values[10]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED, values[11]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_USER_NOT_FOUND, values[12]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_ALREADY_BOUND, values[13]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_BIND_FAILED, values[14]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_PHONE_NOT_VERIFIED, values[15]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_AUTO_REGISTER_FAILED, values[16]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_LOGIN_TYPE_INVALID, values[17]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_LOGIN_FAILED, values[18]);
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_LOCKED, values[19]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValueOf() {
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD, ClientUserAuthExceptionCode.valueOf("CLIENT_INVALID_USERNAME_OR_PASSWORD"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_PLATFORM, ClientUserAuthExceptionCode.valueOf("CLIENT_INVALID_PLATFORM"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_WECHAT_CODE, ClientUserAuthExceptionCode.valueOf("CLIENT_INVALID_WECHAT_CODE"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_WECHAT_AUTH_FAILED, ClientUserAuthExceptionCode.valueOf("CLIENT_WECHAT_AUTH_FAILED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_INVALID_DOUYIN_CODE, ClientUserAuthExceptionCode.valueOf("CLIENT_INVALID_DOUYIN_CODE"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_DOUYIN_AUTH_FAILED, ClientUserAuthExceptionCode.valueOf("CLIENT_DOUYIN_AUTH_FAILED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXPIRED, ClientUserAuthExceptionCode.valueOf("CLIENT_SMS_CODE_EXPIRED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID, ClientUserAuthExceptionCode.valueOf("CLIENT_SMS_CODE_INVALID"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_USED, ClientUserAuthExceptionCode.valueOf("CLIENT_SMS_CODE_USED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_EXCEEDED, ClientUserAuthExceptionCode.valueOf("CLIENT_SMS_CODE_EXCEEDED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_TOO_FAST, ClientUserAuthExceptionCode.valueOf("CLIENT_SMS_CODE_SEND_TOO_FAST"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED, ClientUserAuthExceptionCode.valueOf("CLIENT_SMS_CODE_SEND_EXCEEDED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_USER_NOT_FOUND, ClientUserAuthExceptionCode.valueOf("CLIENT_USER_NOT_FOUND"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_ALREADY_BOUND, ClientUserAuthExceptionCode.valueOf("CLIENT_ACCOUNT_ALREADY_BOUND"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_BIND_FAILED, ClientUserAuthExceptionCode.valueOf("CLIENT_ACCOUNT_BIND_FAILED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_PHONE_NOT_VERIFIED, ClientUserAuthExceptionCode.valueOf("CLIENT_PHONE_NOT_VERIFIED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_AUTO_REGISTER_FAILED, ClientUserAuthExceptionCode.valueOf("CLIENT_AUTO_REGISTER_FAILED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_LOGIN_TYPE_INVALID, ClientUserAuthExceptionCode.valueOf("CLIENT_LOGIN_TYPE_INVALID"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_LOGIN_FAILED, ClientUserAuthExceptionCode.valueOf("CLIENT_LOGIN_FAILED"));
|
||||
assertEquals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_LOCKED, ClientUserAuthExceptionCode.valueOf("CLIENT_ACCOUNT_LOCKED"));
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package io.destiny.client.core.exception;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientUserExceptionCodeTest {
|
||||
|
||||
@Test
|
||||
void testGetCode() {
|
||||
assertEquals("CLIENT_USER_20001", ClientUserExceptionCode.CLIENT_USER_NOT_FOUND.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDisplayName() {
|
||||
assertEquals("客户端用户不存在", ClientUserExceptionCode.CLIENT_USER_NOT_FOUND.getDisplayName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetHttpCode() {
|
||||
assertEquals("500", ClientUserExceptionCode.CLIENT_USER_NOT_FOUND.getHttpCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValues() {
|
||||
ClientUserExceptionCode[] values = ClientUserExceptionCode.values();
|
||||
assertEquals(1, values.length);
|
||||
assertEquals(ClientUserExceptionCode.CLIENT_USER_NOT_FOUND, values[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValueOf() {
|
||||
assertEquals(ClientUserExceptionCode.CLIENT_USER_NOT_FOUND, ClientUserExceptionCode.valueOf("CLIENT_USER_NOT_FOUND"));
|
||||
}
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
package io.destiny.client.core.exception;
|
||||
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import io.destiny.common.exception.ExceptionCode;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@DisplayName("GlobalExceptionHandler 测试")
|
||||
class GlobalExceptionHandlerTest {
|
||||
|
||||
private GlobalExceptionHandler globalExceptionHandler;
|
||||
|
||||
private ServerWebExchange exchange;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
globalExceptionHandler = new GlobalExceptionHandler();
|
||||
exchange = MockServerWebExchange.from(org.springframework.mock.http.server.reactive.MockServerHttpRequest
|
||||
.get("/api/test").accept(MediaType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 ApplicationException - 包含 exceptionCode")
|
||||
void testHandleApplicationExceptionWithCode() {
|
||||
ApplicationException exception = new ApplicationException(
|
||||
ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID);
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.BAD_REQUEST, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 ApplicationException - exceptionCode 为 null,exceptionMessage 不为 null")
|
||||
void testHandleApplicationExceptionWithNullCodeAndMessage() {
|
||||
ApplicationException exception = new ApplicationException((ExceptionCode) null,
|
||||
new Object[] { "Custom error message" });
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 ApplicationException - exceptionCode 不为 null,arguments 为 null")
|
||||
void testHandleApplicationExceptionWithCodeAndNullMessage() {
|
||||
ApplicationException exception = new ApplicationException(
|
||||
ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID,
|
||||
(Object[]) null);
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.BAD_REQUEST, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 ApplicationException - exceptionCode 和 arguments 都为 null")
|
||||
void testHandleApplicationExceptionWithNullCodeAndNullMessage() {
|
||||
ApplicationException exception = new ApplicationException((ExceptionCode) null, (Object[]) null);
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 IllegalArgumentException")
|
||||
void testHandleIllegalArgumentException() {
|
||||
IllegalArgumentException exception = new IllegalArgumentException("Invalid argument");
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.BAD_REQUEST, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理通用 Exception")
|
||||
void testHandleGenericException() {
|
||||
Exception exception = new Exception("Unexpected error");
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理未知 Throwable(非 Exception)")
|
||||
void testHandleUnknownException() {
|
||||
Throwable throwable = new Throwable("Unknown error");
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(throwable, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 RuntimeException(继承自 Exception)")
|
||||
void testHandleRuntimeException() {
|
||||
RuntimeException exception = new RuntimeException("Runtime error");
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 NullPointerException(继承自 RuntimeException)")
|
||||
void testHandleNullPointerException() {
|
||||
NullPointerException exception = new NullPointerException("Null pointer");
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(exception, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("处理 Error(非 Exception)")
|
||||
void testHandleError() {
|
||||
Error error = new Error("Fatal error");
|
||||
|
||||
StepVerifier.create(globalExceptionHandler.handleException(error, exchange))
|
||||
.assertNext(response -> {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.statusCode());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
package io.destiny.client.core.service;
|
||||
|
||||
import io.destiny.client.core.domain.ClientLoginLog;
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
import io.destiny.client.core.domain.query.ClientUserLogin;
|
||||
import io.destiny.client.core.repository.IClientLoginLogRepository;
|
||||
import io.destiny.client.core.repository.IClientUserRepository;
|
||||
import io.destiny.client.dto.ClientLoginResponse;
|
||||
import io.destiny.client.security.JwtTokenProvider;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import io.destiny.common.primitive.EmailAddress;
|
||||
import io.destiny.common.primitive.IpAddress;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ClientUserAuthServiceTest {
|
||||
|
||||
@Mock
|
||||
private IClientUserRepository clientUserRepository;
|
||||
|
||||
@Mock
|
||||
private IClientLoginLogRepository clientLoginLogRepository;
|
||||
|
||||
@Mock
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Mock
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@InjectMocks
|
||||
private ClientUserAuthService clientUserAuthService;
|
||||
|
||||
private ClientUser testUser;
|
||||
private ClientUserLogin testLogin;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
testUser = new ClientUser();
|
||||
testUser.setId(1L);
|
||||
testUser.setUsername("testuser");
|
||||
testUser.setPassword("encodedPassword");
|
||||
testUser.setEmail(EmailAddress.of("test@example.com"));
|
||||
|
||||
testLogin = new ClientUserLogin();
|
||||
testLogin.setUsername("testuser");
|
||||
testLogin.setPassword("rawPassword");
|
||||
testLogin.setIpAddress(IpAddress.of("127.0.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegister_Success() {
|
||||
ClientUser newUser = new ClientUser();
|
||||
newUser.setUsername("newuser");
|
||||
newUser.setPassword("rawPassword");
|
||||
newUser.setEmail(EmailAddress.of("new@example.com"));
|
||||
|
||||
when(passwordEncoder.encode(anyString())).thenReturn("encodedPassword");
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
Mono<ClientUser> result = clientUserAuthService.register(newUser);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientUser registeredUser = result.block();
|
||||
assertEquals("testuser", registeredUser.getUsername());
|
||||
assertEquals("encodedPassword", registeredUser.getPassword());
|
||||
|
||||
verify(passwordEncoder, times(1)).encode(anyString());
|
||||
verify(clientUserRepository, times(1)).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_Success() {
|
||||
when(clientUserRepository.findByUsername(anyString())).thenReturn(Mono.just(testUser));
|
||||
when(passwordEncoder.matches(anyString(), anyString())).thenReturn(true);
|
||||
when(clientLoginLogRepository.save(any(ClientLoginLog.class))).thenReturn(Mono.just(new ClientLoginLog()));
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
Mono<ClientLoginResponse> result = clientUserAuthService.login(testLogin);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientLoginResponse response = result.block();
|
||||
assertNotNull(response);
|
||||
assertEquals("test-token", response.getToken());
|
||||
|
||||
verify(clientUserRepository, times(1)).findByUsername(anyString());
|
||||
verify(passwordEncoder, times(1)).matches(anyString(), anyString());
|
||||
verify(clientLoginLogRepository, times(1)).save(any(ClientLoginLog.class));
|
||||
verify(jwtTokenProvider, times(1)).generateToken(anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_InvalidPassword() {
|
||||
when(clientUserRepository.findByUsername(anyString())).thenReturn(Mono.just(testUser));
|
||||
when(passwordEncoder.matches(anyString(), anyString())).thenReturn(false);
|
||||
|
||||
Mono<ClientLoginResponse> result = clientUserAuthService.login(testLogin);
|
||||
|
||||
assertThrows(ApplicationException.class, () -> result.block());
|
||||
|
||||
verify(clientUserRepository, times(1)).findByUsername(anyString());
|
||||
verify(passwordEncoder, times(1)).matches(anyString(), anyString());
|
||||
verify(clientLoginLogRepository, never()).save(any(ClientLoginLog.class));
|
||||
verify(jwtTokenProvider, never()).generateToken(anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_UserNotFound() {
|
||||
when(clientUserRepository.findByUsername(anyString())).thenReturn(Mono.empty());
|
||||
|
||||
Mono<ClientLoginResponse> result = clientUserAuthService.login(testLogin);
|
||||
|
||||
assertThrows(ApplicationException.class, () -> result.block());
|
||||
|
||||
verify(clientUserRepository, times(1)).findByUsername(anyString());
|
||||
verify(passwordEncoder, never()).matches(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRefreshLoginToken_Success() {
|
||||
String oldToken = "old-test-token";
|
||||
when(jwtTokenProvider.getUserIdFromToken(anyString())).thenReturn(1L);
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.just(testUser));
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("new-test-token");
|
||||
|
||||
Mono<ClientLoginResponse> result = clientUserAuthService.refreshLoginToken(oldToken);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientLoginResponse response = result.block();
|
||||
assertNotNull(response);
|
||||
assertEquals("new-test-token", response.getToken());
|
||||
|
||||
verify(jwtTokenProvider, times(1)).getUserIdFromToken(anyString());
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
verify(jwtTokenProvider, times(1)).generateToken(anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRefreshLoginToken_InvalidToken() {
|
||||
String oldToken = "invalid-token";
|
||||
when(jwtTokenProvider.getUserIdFromToken(anyString())).thenReturn(null);
|
||||
|
||||
Mono<ClientLoginResponse> result = clientUserAuthService.refreshLoginToken(oldToken);
|
||||
|
||||
assertThrows(ApplicationException.class, () -> result.block());
|
||||
|
||||
verify(jwtTokenProvider, times(1)).getUserIdFromToken(anyString());
|
||||
verify(clientUserRepository, never()).findById(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRefreshLoginToken_UserNotFound() {
|
||||
String oldToken = "old-test-token";
|
||||
when(jwtTokenProvider.getUserIdFromToken(anyString())).thenReturn(1L);
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
Mono<ClientLoginResponse> result = clientUserAuthService.refreshLoginToken(oldToken);
|
||||
|
||||
assertThrows(ApplicationException.class, () -> result.block());
|
||||
|
||||
verify(jwtTokenProvider, times(1)).getUserIdFromToken(anyString());
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogout_Success() {
|
||||
Long userId = 1L;
|
||||
ClientLoginLog loginLog = new ClientLoginLog();
|
||||
loginLog.setLogoutTime(null);
|
||||
|
||||
when(clientLoginLogRepository.findByClientUserId(anyLong())).thenReturn(Flux.just(loginLog));
|
||||
when(clientLoginLogRepository.save(any(ClientLoginLog.class))).thenReturn(Mono.just(loginLog));
|
||||
|
||||
Mono<Void> result = clientUserAuthService.logout(userId);
|
||||
|
||||
assertNotNull(result);
|
||||
result.block();
|
||||
|
||||
verify(clientLoginLogRepository, times(1)).findByClientUserId(anyLong());
|
||||
verify(clientLoginLogRepository, times(1)).save(any(ClientLoginLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogout_NoActiveSession() {
|
||||
Long userId = 1L;
|
||||
when(clientLoginLogRepository.findByClientUserId(anyLong())).thenReturn(Flux.empty());
|
||||
|
||||
Mono<Void> result = clientUserAuthService.logout(userId);
|
||||
|
||||
assertNotNull(result);
|
||||
result.block();
|
||||
|
||||
verify(clientLoginLogRepository, times(1)).findByClientUserId(anyLong());
|
||||
verify(clientLoginLogRepository, never()).save(any(ClientLoginLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckLoginStatus_Active() {
|
||||
Long userId = 1L;
|
||||
ClientLoginLog loginLog = new ClientLoginLog();
|
||||
loginLog.setLogoutTime(null);
|
||||
|
||||
when(clientLoginLogRepository.findByClientUserId(anyLong())).thenReturn(Flux.just(loginLog));
|
||||
|
||||
Mono<Boolean> result = clientUserAuthService.checkLoginStatus(userId);
|
||||
|
||||
assertNotNull(result);
|
||||
Boolean isActive = result.block();
|
||||
assertTrue(isActive);
|
||||
|
||||
verify(clientLoginLogRepository, times(1)).findByClientUserId(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckLoginStatus_Inactive() {
|
||||
Long userId = 1L;
|
||||
when(clientLoginLogRepository.findByClientUserId(anyLong())).thenReturn(Flux.empty());
|
||||
|
||||
Mono<Boolean> result = clientUserAuthService.checkLoginStatus(userId);
|
||||
|
||||
assertNotNull(result);
|
||||
Boolean isActive = result.block();
|
||||
assertFalse(isActive);
|
||||
|
||||
verify(clientLoginLogRepository, times(1)).findByClientUserId(anyLong());
|
||||
}
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
package io.destiny.client.core.service;
|
||||
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
import io.destiny.client.core.domain.query.ClientUserQuery;
|
||||
import io.destiny.client.core.repository.IClientUserRepository;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import io.destiny.common.primitive.EmailAddress;
|
||||
import io.destiny.common.request.PageQuery;
|
||||
import io.destiny.common.response.PageModel;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ClientUserServiceTest {
|
||||
|
||||
@Mock
|
||||
private IClientUserRepository clientUserRepository;
|
||||
|
||||
@InjectMocks
|
||||
private ClientUserService clientUserService;
|
||||
|
||||
private ClientUser testUser;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
testUser = new ClientUser();
|
||||
testUser.setId(1L);
|
||||
testUser.setUsername("testuser");
|
||||
testUser.setPassword("password");
|
||||
testUser.setEmail(EmailAddress.of("test@example.com"));
|
||||
testUser.setCreatedAt(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSave_Success() {
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
Mono<ClientUser> result = clientUserService.save(testUser);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientUser savedUser = result.block();
|
||||
assertEquals(1L, savedUser.getId());
|
||||
assertEquals("testuser", savedUser.getUsername());
|
||||
|
||||
verify(clientUserRepository, times(1)).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdate_Success() {
|
||||
ClientUser updateUser = new ClientUser();
|
||||
updateUser.setId(1L);
|
||||
updateUser.setUsername("updateduser");
|
||||
updateUser.setPassword("newpassword");
|
||||
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.just(testUser));
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(updateUser));
|
||||
|
||||
Mono<ClientUser> result = clientUserService.update(updateUser);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientUser updatedUser = result.block();
|
||||
assertEquals("updateduser", updatedUser.getUsername());
|
||||
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
verify(clientUserRepository, times(1)).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdate_UserNotFound() {
|
||||
ClientUser updateUser = new ClientUser();
|
||||
updateUser.setId(999L);
|
||||
updateUser.setUsername("updateduser");
|
||||
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
Mono<ClientUser> result = clientUserService.update(updateUser);
|
||||
|
||||
assertThrows(ApplicationException.class, () -> result.block());
|
||||
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteById_Success() {
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.just(testUser));
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
Mono<Void> result = clientUserService.deleteById(1L);
|
||||
|
||||
assertNotNull(result);
|
||||
result.block();
|
||||
|
||||
assertNotNull(testUser.getDeletedAt());
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
verify(clientUserRepository, times(1)).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteById_UserNotFound() {
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Void> result = clientUserService.deleteById(999L);
|
||||
|
||||
assertThrows(ApplicationException.class, () -> result.block());
|
||||
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindById_Success() {
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.just(testUser));
|
||||
|
||||
Mono<ClientUser> result = clientUserService.findById(1L);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientUser foundUser = result.block();
|
||||
assertEquals(1L, foundUser.getId());
|
||||
assertEquals("testuser", foundUser.getUsername());
|
||||
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindById_NotFound() {
|
||||
when(clientUserRepository.findById(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
Mono<ClientUser> result = clientUserService.findById(999L);
|
||||
|
||||
assertNotNull(result);
|
||||
ClientUser foundUser = result.block();
|
||||
assertNull(foundUser);
|
||||
|
||||
verify(clientUserRepository, times(1)).findById(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByPage_Success() {
|
||||
ClientUserQuery query = new ClientUserQuery();
|
||||
PageQuery pageQuery = new PageQuery(0, 10);
|
||||
|
||||
PageModel<ClientUser> pageModel = new PageModel<>(1L, Collections.singletonList(testUser));
|
||||
|
||||
when(clientUserRepository.findByQueryWithPagination(any(ClientUserQuery.class), any(PageQuery.class)))
|
||||
.thenReturn(Mono.just(pageModel));
|
||||
|
||||
Mono<PageModel<ClientUser>> result = clientUserService.findByPage(query, pageQuery);
|
||||
|
||||
assertNotNull(result);
|
||||
PageModel<ClientUser> resultPage = result.block();
|
||||
assertEquals(1, resultPage.getData().size());
|
||||
assertEquals(1L, resultPage.getCount());
|
||||
|
||||
verify(clientUserRepository, times(1)).findByQueryWithPagination(any(ClientUserQuery.class), any(PageQuery.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByPage_EmptyResult() {
|
||||
ClientUserQuery query = new ClientUserQuery();
|
||||
PageQuery pageQuery = new PageQuery(0, 10);
|
||||
|
||||
PageModel<ClientUser> pageModel = new PageModel<>(0L, Collections.emptyList());
|
||||
|
||||
when(clientUserRepository.findByQueryWithPagination(any(ClientUserQuery.class), any(PageQuery.class)))
|
||||
.thenReturn(Mono.just(pageModel));
|
||||
|
||||
Mono<PageModel<ClientUser>> result = clientUserService.findByPage(query, pageQuery);
|
||||
|
||||
assertNotNull(result);
|
||||
PageModel<ClientUser> resultPage = result.block();
|
||||
assertTrue(resultPage.getData().isEmpty());
|
||||
assertEquals(0L, resultPage.getCount());
|
||||
|
||||
verify(clientUserRepository, times(1)).findByQueryWithPagination(any(ClientUserQuery.class), any(PageQuery.class));
|
||||
}
|
||||
}
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
package io.destiny.client.core.service;
|
||||
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import io.destiny.client.config.AliyunSmsConfig;
|
||||
import io.destiny.client.core.domain.SmsVerificationCode;
|
||||
import io.destiny.client.core.enums.SmsCodeType;
|
||||
import io.destiny.client.core.exception.ClientUserAuthExceptionCode;
|
||||
import io.destiny.client.core.repository.ISmsVerificationCodeRepository;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@DisplayName("SmsService 测试")
|
||||
class SmsServiceTest {
|
||||
|
||||
@Mock
|
||||
private AliyunSmsConfig smsConfig;
|
||||
|
||||
@Mock
|
||||
private ISmsVerificationCodeRepository smsVerificationCodeRepository;
|
||||
|
||||
@Mock
|
||||
private Client smsClient;
|
||||
|
||||
private SmsService smsService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
lenient().when(smsConfig.getSignName()).thenReturn("TestSign");
|
||||
smsService = new SmsService(smsConfig, smsVerificationCodeRepository, smsClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 手机号为 null")
|
||||
void testSendVerificationCodeWithNullPhone() {
|
||||
StepVerifier.create(smsService.sendVerificationCode(null, SmsCodeType.LOGIN))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 手机号为空字符串")
|
||||
void testSendVerificationCodeWithEmptyPhone() {
|
||||
StepVerifier.create(smsService.sendVerificationCode("", SmsCodeType.LOGIN))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_INVALID)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - SmsCodeType 为 null")
|
||||
void testSendVerificationCodeWithNullType() {
|
||||
StepVerifier.create(smsService.sendVerificationCode("13800138000", null))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 新手机号成功发送")
|
||||
void testSendVerificationCodeSuccess() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("OK");
|
||||
responseBody.setRequestId("test-request-id");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
|
||||
SmsVerificationCode savedCode = new SmsVerificationCode();
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class)))
|
||||
.thenReturn(Mono.just(savedCode));
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> {
|
||||
assertNotNull(code);
|
||||
assertEquals(6, code.length());
|
||||
assertTrue(code.chars().allMatch(Character::isDigit));
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
ArgumentCaptor<SmsVerificationCode> codeCaptor = ArgumentCaptor.forClass(SmsVerificationCode.class);
|
||||
verify(smsVerificationCodeRepository).save(codeCaptor.capture());
|
||||
|
||||
SmsVerificationCode capturedCode = codeCaptor.getValue();
|
||||
assertEquals(phone, capturedCode.getPhone());
|
||||
assertEquals(type.getCode(), capturedCode.getType());
|
||||
assertNotNull(capturedCode.getExpireTime());
|
||||
assertTrue(capturedCode.getExpireTime().isAfter(LocalDateTime.now()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 分钟速率限制已达到且未过期")
|
||||
void testSendVerificationCodeMinuteRateLimitExceeded() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("OK");
|
||||
responseBody.setRequestId("test-request-id");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class)))
|
||||
.thenReturn(Mono.just(new SmsVerificationCode()));
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_TOO_FAST)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 分钟速率限制已达到但已过期")
|
||||
void testSendVerificationCodeMinuteRateLimitExpired() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("OK");
|
||||
responseBody.setRequestId("test-request-id");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class)))
|
||||
.thenReturn(Mono.just(new SmsVerificationCode()));
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
|
||||
modifySendRecordExpireTime(phone, LocalDateTime.now().minusMinutes(1));
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 日速率限制已达到且未过期")
|
||||
void testSendVerificationCodeDayRateLimitExceeded() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("OK");
|
||||
responseBody.setRequestId("test-request-id");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class)))
|
||||
.thenReturn(Mono.just(new SmsVerificationCode()));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
modifySendRecordExpireTime(phone, LocalDateTime.now().minusMinutes(1));
|
||||
}
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 日速率限制已达到但已过期")
|
||||
void testSendVerificationCodeDayRateLimitExpired() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("OK");
|
||||
responseBody.setRequestId("test-request-id");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class)))
|
||||
.thenReturn(Mono.just(new SmsVerificationCode()));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
modifySendRecordExpireTime(phone, LocalDateTime.now().minusMinutes(1));
|
||||
}
|
||||
|
||||
modifySendRecordDayExpireTime(phone, LocalDateTime.now().minusDays(1));
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 阿里云短信发送失败")
|
||||
void testSendVerificationCodeAliyunSendFailed() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("FAILED");
|
||||
responseBody.setMessage("Invalid phone number");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 短信签名为 null")
|
||||
void testSendVerificationCodeWithNullSignName() throws Exception {
|
||||
String phone = "13800138000";
|
||||
SmsCodeType type = SmsCodeType.LOGIN;
|
||||
|
||||
when(smsConfig.getSignName()).thenReturn(null);
|
||||
|
||||
smsService = new SmsService(smsConfig, smsVerificationCodeRepository, smsClient);
|
||||
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.expectErrorMatches(throwable -> throwable instanceof ApplicationException &&
|
||||
((ApplicationException) throwable)
|
||||
.getExceptionCode() == ClientUserAuthExceptionCode.CLIENT_SMS_CODE_SEND_EXCEEDED)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("发送验证码 - 不同的验证码类型")
|
||||
void testSendVerificationCodeWithDifferentTypes() throws Exception {
|
||||
SendSmsResponseBody responseBody = new SendSmsResponseBody();
|
||||
responseBody.setCode("OK");
|
||||
responseBody.setRequestId("test-request-id");
|
||||
|
||||
SendSmsResponse response = new SendSmsResponse();
|
||||
response.setBody(responseBody);
|
||||
|
||||
when(smsClient.sendSms(any(SendSmsRequest.class))).thenReturn(response);
|
||||
|
||||
SmsVerificationCode savedCode = new SmsVerificationCode();
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class)))
|
||||
.thenReturn(Mono.just(savedCode));
|
||||
|
||||
SmsCodeType[] types = { SmsCodeType.LOGIN, SmsCodeType.REGISTER, SmsCodeType.BIND,
|
||||
SmsCodeType.RESET_PASSWORD };
|
||||
|
||||
for (SmsCodeType type : types) {
|
||||
String phone = "1380013800" + type.getCode();
|
||||
StepVerifier.create(smsService.sendVerificationCode(phone, type))
|
||||
.assertNext(code -> assertNotNull(code))
|
||||
.verifyComplete();
|
||||
|
||||
ArgumentCaptor<SmsVerificationCode> codeCaptor = ArgumentCaptor
|
||||
.forClass(SmsVerificationCode.class);
|
||||
verify(smsVerificationCodeRepository, atLeastOnce()).save(codeCaptor.capture());
|
||||
|
||||
SmsVerificationCode capturedCode = codeCaptor.getValue();
|
||||
assertEquals(type.getCode(), capturedCode.getType());
|
||||
}
|
||||
}
|
||||
|
||||
private void modifySendRecordExpireTime(String phone, LocalDateTime newExpireTime) {
|
||||
try {
|
||||
Field cacheField = SmsService.class.getDeclaredField("sendRecords");
|
||||
cacheField.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
Cache<String, Object> cache = (Cache<String, Object>) cacheField.get(smsService);
|
||||
Object sendRecord = cache.getIfPresent(phone);
|
||||
if (sendRecord != null) {
|
||||
Field minuteExpireTimeField = sendRecord.getClass()
|
||||
.getDeclaredField("minuteExpireTime");
|
||||
minuteExpireTimeField.setAccessible(true);
|
||||
minuteExpireTimeField.set(sendRecord, newExpireTime);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to modify send record expire time", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void modifySendRecordDayExpireTime(String phone, LocalDateTime newExpireTime) {
|
||||
try {
|
||||
Field cacheField = SmsService.class.getDeclaredField("sendRecords");
|
||||
cacheField.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
Cache<String, Object> cache = (Cache<String, Object>) cacheField.get(smsService);
|
||||
Object sendRecord = cache.getIfPresent(phone);
|
||||
if (sendRecord != null) {
|
||||
Field dayExpireTimeField = sendRecord.getClass().getDeclaredField("dayExpireTime");
|
||||
dayExpireTimeField.setAccessible(true);
|
||||
dayExpireTimeField.set(sendRecord, newExpireTime);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to modify send record day expire time", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+324
@@ -0,0 +1,324 @@
|
||||
package io.destiny.client.core.strategy;
|
||||
|
||||
import io.destiny.client.client.DouyinMiniProgramClient;
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
import io.destiny.client.core.domain.UserBinding;
|
||||
import io.destiny.client.core.repository.IClientUserRepository;
|
||||
import io.destiny.client.core.repository.IUserBindingRepository;
|
||||
import io.destiny.client.core.service.ClientUserAuthService;
|
||||
import io.destiny.client.dto.DouyinLoginRequest;
|
||||
import io.destiny.client.dto.LoginRequest;
|
||||
|
||||
import io.destiny.client.dto.WechatAuthResponse;
|
||||
import io.destiny.client.security.JwtTokenProvider;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static io.destiny.client.core.exception.ClientUserAuthExceptionCode.CLIENT_INVALID_DOUYIN_CODE;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DouyinLoginStrategyTest {
|
||||
|
||||
@Mock
|
||||
private ClientUserAuthService clientUserAuthService;
|
||||
|
||||
@Mock
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Mock
|
||||
private DouyinMiniProgramClient douyinClient;
|
||||
|
||||
@Mock
|
||||
private IClientUserRepository clientUserRepository;
|
||||
|
||||
@Mock
|
||||
private IUserBindingRepository userBindingRepository;
|
||||
|
||||
@InjectMocks
|
||||
private DouyinLoginStrategy douyinLoginStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLoginType() {
|
||||
assertEquals("douyin", douyinLoginStrategy.getLoginType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithValidData() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("valid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.validateRequest(request))
|
||||
.expectNext(request)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithNullCode() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode(null);
|
||||
request.setData(douyinRequest);
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.validateRequest(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode().equals(CLIENT_INVALID_DOUYIN_CODE))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithEmptyCode() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.validateRequest(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode().equals(CLIENT_INVALID_DOUYIN_CODE))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithInvalidDataType() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData("invalid_data");
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.validateRequest(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode().equals(CLIENT_INVALID_DOUYIN_CODE))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithExistingUserByOpenId() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("valid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setDouyinOpenId("open_id_123");
|
||||
|
||||
when(douyinClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByDouyinOpenId("open_id_123")).thenReturn(Mono.just(user));
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("douyin") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository, never()).findByDouyinUnionId(anyString());
|
||||
verify(userBindingRepository, never()).findByPlatformAndUnionId(anyString(), anyString());
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithExistingUserByUnionId() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("valid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setDouyinUnionId("union_id_456");
|
||||
|
||||
when(douyinClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByDouyinOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByDouyinUnionId("union_id_456")).thenReturn(Mono.just(user));
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("douyin") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(userBindingRepository, never()).findByPlatformAndUnionId(anyString(), anyString());
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithExistingUserByBinding() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("valid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setUserId(1L);
|
||||
binding.setPlatform("douyin");
|
||||
binding.setPlatformUnionId("union_id_456");
|
||||
|
||||
when(douyinClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByDouyinOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByDouyinUnionId("union_id_456")).thenReturn(Mono.empty());
|
||||
when(userBindingRepository.findByPlatformAndUnionId("douyin", "union_id_456")).thenReturn(Mono.just(binding));
|
||||
when(clientUserRepository.findById(1L)).thenReturn(Mono.just(user));
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("douyin") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithNewUser() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("valid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser newUser = new ClientUser();
|
||||
newUser.setId(1L);
|
||||
newUser.setDouyinOpenId("open_id_123");
|
||||
newUser.setDouyinUnionId("union_id_456");
|
||||
newUser.setPhoneVerified(false);
|
||||
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setId(1L);
|
||||
binding.setUserId(1L);
|
||||
binding.setPlatform("douyin");
|
||||
binding.setPlatformOpenId("open_id_123");
|
||||
binding.setPlatformUnionId("union_id_456");
|
||||
|
||||
when(douyinClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByDouyinOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByDouyinUnionId("union_id_456")).thenReturn(Mono.empty());
|
||||
when(userBindingRepository.findByPlatformAndUnionId("douyin", "union_id_456")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(newUser));
|
||||
when(userBindingRepository.save(any(UserBinding.class))).thenReturn(Mono.just(binding));
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getPlatform().equals("douyin") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository).save(any(ClientUser.class));
|
||||
verify(userBindingRepository).save(any(UserBinding.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNewUserWithoutUnionId() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("valid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser newUser = new ClientUser();
|
||||
newUser.setId(1L);
|
||||
newUser.setDouyinOpenId("open_id_123");
|
||||
newUser.setPhoneVerified(false);
|
||||
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setId(1L);
|
||||
binding.setUserId(1L);
|
||||
binding.setPlatform("douyin");
|
||||
binding.setPlatformOpenId("open_id_123");
|
||||
|
||||
when(douyinClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByDouyinOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(newUser));
|
||||
when(userBindingRepository.save(any(UserBinding.class))).thenReturn(Mono.just(binding));
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getPlatform().equals("douyin") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository, never()).findByDouyinUnionId(anyString());
|
||||
verify(userBindingRepository, never()).findByPlatformAndUnionId(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithAuthFailure() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("invalid_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
when(douyinClient.auth("invalid_code")).thenReturn(Mono.error(new Exception("Auth failed")));
|
||||
|
||||
StepVerifier.create(douyinLoginStrategy.login(request))
|
||||
.expectError(Exception.class)
|
||||
.verify();
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package io.destiny.client.core.strategy;
|
||||
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LoginStrategyFactoryTest {
|
||||
|
||||
@Mock
|
||||
private WechatLoginStrategy wechatLoginStrategy;
|
||||
|
||||
@Mock
|
||||
private DouyinLoginStrategy douyinLoginStrategy;
|
||||
|
||||
@Mock
|
||||
private SmsLoginStrategy smsLoginStrategy;
|
||||
|
||||
private LoginStrategyFactory factory;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(wechatLoginStrategy.getLoginType()).thenReturn("wechat");
|
||||
when(douyinLoginStrategy.getLoginType()).thenReturn("douyin");
|
||||
when(smsLoginStrategy.getLoginType()).thenReturn("sms");
|
||||
|
||||
factory = new LoginStrategyFactory(List.of(wechatLoginStrategy, douyinLoginStrategy, smsLoginStrategy));
|
||||
factory.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStrategy_Wechat() {
|
||||
LoginStrategy strategy = factory.getStrategy("wechat");
|
||||
|
||||
assertNotNull(strategy);
|
||||
assertEquals(wechatLoginStrategy, strategy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStrategy_Douyin() {
|
||||
LoginStrategy strategy = factory.getStrategy("douyin");
|
||||
|
||||
assertNotNull(strategy);
|
||||
assertEquals(douyinLoginStrategy, strategy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStrategy_Sms() {
|
||||
LoginStrategy strategy = factory.getStrategy("sms");
|
||||
|
||||
assertNotNull(strategy);
|
||||
assertEquals(smsLoginStrategy, strategy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStrategy_InvalidType() {
|
||||
assertThrows(ApplicationException.class, () -> {
|
||||
factory.getStrategy("invalid");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStrategy_NullType() {
|
||||
assertThrows(ApplicationException.class, () -> {
|
||||
factory.getStrategy(null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStrategy_EmptyType() {
|
||||
assertThrows(ApplicationException.class, () -> {
|
||||
factory.getStrategy("");
|
||||
});
|
||||
}
|
||||
}
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
package io.destiny.client.core.strategy;
|
||||
|
||||
import io.destiny.client.core.exception.ClientUserAuthExceptionCode;
|
||||
import io.destiny.client.dto.DouyinLoginRequest;
|
||||
import io.destiny.client.dto.LoginRequest;
|
||||
import io.destiny.client.dto.LoginResult;
|
||||
import io.destiny.client.dto.SmsLoginRequest;
|
||||
import io.destiny.client.dto.WechatLoginRequest;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LoginStrategyProxyTest {
|
||||
|
||||
@Mock
|
||||
private LoginStrategyFactory strategyFactory;
|
||||
|
||||
@Mock
|
||||
private LoginStrategy loginStrategy;
|
||||
|
||||
@InjectMocks
|
||||
private LoginStrategyProxy loginStrategyProxy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(strategyFactory.getStrategy(any())).thenReturn(loginStrategy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccess() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("wechat");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(loginStrategy).login(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNullIpAddress() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress(null);
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("wechat");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginFailureWithApplicationException() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
ApplicationException exception = new ApplicationException(ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD);
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.error(exception));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectError(ApplicationException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginFailureWithNonApplicationException() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
RuntimeException exception = new RuntimeException("Unexpected error");
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.error(exception));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_LOGIN_FAILED))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAccountLockAfterMultipleFailedAttempts() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
ApplicationException exception = new ApplicationException(ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD);
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.error(exception));
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectError(ApplicationException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode().equals(ClientUserAuthExceptionCode.CLIENT_ACCOUNT_LOCKED))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithDouyinRequest() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode("douyin_code");
|
||||
request.setData(douyinRequest);
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("douyin");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithDouyinRequestNullCode() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
DouyinLoginRequest douyinRequest = new DouyinLoginRequest();
|
||||
douyinRequest.setCode(null);
|
||||
request.setData(douyinRequest);
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("douyin");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithSmsRequest() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("sms");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone("13800138000");
|
||||
smsRequest.setCode("123456");
|
||||
request.setData(smsRequest);
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("sms");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithSmsRequestNullPhone() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("sms");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(null);
|
||||
smsRequest.setCode("123456");
|
||||
request.setData(smsRequest);
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("sms");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNullLoginType() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType(null);
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("wechat");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNullData() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(null);
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("password");
|
||||
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClearAttemptRecordAfterSuccessfulLogin() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new WechatLoginRequest());
|
||||
|
||||
ApplicationException exception = new ApplicationException(ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD);
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.error(exception));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectError(ApplicationException.class)
|
||||
.verify();
|
||||
|
||||
LoginResult result = new LoginResult();
|
||||
result.setUserId(1L);
|
||||
result.setPlatform("wechat");
|
||||
when(loginStrategy.login(any())).thenReturn(Mono.just(result));
|
||||
|
||||
StepVerifier.create(loginStrategyProxy.login(request))
|
||||
.expectNext(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
+385
@@ -0,0 +1,385 @@
|
||||
package io.destiny.client.core.strategy;
|
||||
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
import io.destiny.client.core.domain.SmsVerificationCode;
|
||||
import io.destiny.client.core.enums.SmsCodeType;
|
||||
import io.destiny.client.core.repository.IClientUserRepository;
|
||||
import io.destiny.client.core.repository.ISmsVerificationCodeRepository;
|
||||
import io.destiny.client.core.service.ClientUserAuthService;
|
||||
import io.destiny.client.dto.LoginRequest;
|
||||
import io.destiny.client.dto.LoginResult;
|
||||
import io.destiny.client.dto.SmsLoginRequest;
|
||||
import io.destiny.client.security.JwtTokenProvider;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import io.destiny.common.primitive.PhoneNumber;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static io.destiny.client.core.exception.ClientUserAuthExceptionCode.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SmsLoginStrategyTest {
|
||||
|
||||
@Mock
|
||||
private ClientUserAuthService clientUserAuthService;
|
||||
|
||||
@Mock
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Mock
|
||||
private IClientUserRepository clientUserRepository;
|
||||
|
||||
@Mock
|
||||
private ISmsVerificationCodeRepository smsVerificationCodeRepository;
|
||||
|
||||
private SmsLoginStrategy strategy;
|
||||
|
||||
private static final String TEST_PHONE = "13800138000";
|
||||
private static final String TEST_CODE = "123456";
|
||||
private static final Long TEST_USER_ID = 12345L;
|
||||
private static final String TEST_TOKEN = "test_jwt_token";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
strategy = new SmsLoginStrategy(clientUserAuthService, jwtTokenProvider, clientUserRepository, smsVerificationCodeRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLoginType() {
|
||||
String result = strategy.getLoginType();
|
||||
|
||||
assert "sms".equals(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequest_Success() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
Mono<LoginRequest> result = strategy.validateRequest(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNext(request)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequest_NullPhone() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(null);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
Mono<LoginRequest> result = strategy.validateRequest(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequest_EmptyPhone() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone("");
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
Mono<LoginRequest> result = strategy.validateRequest(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequest_NullCode() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(null);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
Mono<LoginRequest> result = strategy.validateRequest(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequest_EmptyCode() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode("");
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
Mono<LoginRequest> result = strategy.validateRequest(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequest_InvalidDataType() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(new Object());
|
||||
|
||||
Mono<LoginRequest> result = strategy.validateRequest(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_ExistingUser_Success() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
SmsVerificationCode verificationCode = new SmsVerificationCode();
|
||||
verificationCode.setCode(TEST_CODE);
|
||||
verificationCode.setExpireTime(LocalDateTime.now().plusMinutes(5));
|
||||
verificationCode.setVerified(false);
|
||||
verificationCode.setVerifyCount(0);
|
||||
|
||||
ClientUser existingUser = new ClientUser();
|
||||
existingUser.setId(TEST_USER_ID);
|
||||
existingUser.setPhone(PhoneNumber.of(TEST_PHONE));
|
||||
existingUser.setUsername(TEST_PHONE);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.just(verificationCode));
|
||||
when(smsVerificationCodeRepository.markAsVerified(any())).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByPhone(PhoneNumber.of(TEST_PHONE))).thenReturn(Mono.just(existingUser));
|
||||
when(jwtTokenProvider.generateToken(TEST_USER_ID, "sms")).thenReturn(TEST_TOKEN);
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(loginResult ->
|
||||
TEST_USER_ID.equals(loginResult.getUserId()) &&
|
||||
TEST_PHONE.equals(loginResult.getUsername()) &&
|
||||
TEST_PHONE.equals(loginResult.getPhone()) &&
|
||||
"sms".equals(loginResult.getPlatform()) &&
|
||||
TEST_TOKEN.equals(loginResult.getToken()))
|
||||
.verifyComplete();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(smsVerificationCodeRepository, times(1)).markAsVerified(any());
|
||||
verify(clientUserRepository, times(1)).findByPhone(PhoneNumber.of(TEST_PHONE));
|
||||
verify(jwtTokenProvider, times(1)).generateToken(TEST_USER_ID, "sms");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_NewUser_Success() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
SmsVerificationCode verificationCode = new SmsVerificationCode();
|
||||
verificationCode.setCode(TEST_CODE);
|
||||
verificationCode.setExpireTime(LocalDateTime.now().plusMinutes(5));
|
||||
verificationCode.setVerified(false);
|
||||
verificationCode.setVerifyCount(0);
|
||||
|
||||
ClientUser newUser = new ClientUser();
|
||||
newUser.setId(TEST_USER_ID);
|
||||
newUser.setPhone(PhoneNumber.of(TEST_PHONE));
|
||||
newUser.setPhoneVerified(true);
|
||||
newUser.setUsername(TEST_PHONE);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.just(verificationCode));
|
||||
when(smsVerificationCodeRepository.markAsVerified(any())).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByPhone(PhoneNumber.of(TEST_PHONE))).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(newUser));
|
||||
when(jwtTokenProvider.generateToken(TEST_USER_ID, "sms")).thenReturn(TEST_TOKEN);
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(loginResult ->
|
||||
TEST_USER_ID.equals(loginResult.getUserId()) &&
|
||||
TEST_PHONE.equals(loginResult.getUsername()) &&
|
||||
TEST_PHONE.equals(loginResult.getPhone()) &&
|
||||
"sms".equals(loginResult.getPlatform()) &&
|
||||
TEST_TOKEN.equals(loginResult.getToken()))
|
||||
.verifyComplete();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(smsVerificationCodeRepository, times(1)).markAsVerified(any());
|
||||
verify(clientUserRepository, times(1)).findByPhone(PhoneNumber.of(TEST_PHONE));
|
||||
verify(clientUserRepository, times(1)).save(any(ClientUser.class));
|
||||
verify(jwtTokenProvider, times(1)).generateToken(TEST_USER_ID, "sms");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_CodeNotFound() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(clientUserRepository, never()).findByPhone(any());
|
||||
verify(jwtTokenProvider, never()).generateToken(any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_CodeExpired() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
SmsVerificationCode verificationCode = new SmsVerificationCode();
|
||||
verificationCode.setCode(TEST_CODE);
|
||||
verificationCode.setExpireTime(LocalDateTime.now().minusMinutes(1));
|
||||
verificationCode.setVerified(false);
|
||||
verificationCode.setVerifyCount(0);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.just(verificationCode));
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_EXPIRED))
|
||||
.verify();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(clientUserRepository, never()).findByPhone(any());
|
||||
verify(jwtTokenProvider, never()).generateToken(any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_CodeAlreadyUsed() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
SmsVerificationCode verificationCode = new SmsVerificationCode();
|
||||
verificationCode.setCode(TEST_CODE);
|
||||
verificationCode.setExpireTime(LocalDateTime.now().plusMinutes(5));
|
||||
verificationCode.setVerified(true);
|
||||
verificationCode.setVerifyCount(0);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.just(verificationCode));
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_USED))
|
||||
.verify();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(clientUserRepository, never()).findByPhone(any());
|
||||
verify(jwtTokenProvider, never()).generateToken(any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_VerifyCountExceeded() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode(TEST_CODE);
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
SmsVerificationCode verificationCode = new SmsVerificationCode();
|
||||
verificationCode.setCode(TEST_CODE);
|
||||
verificationCode.setExpireTime(LocalDateTime.now().plusMinutes(5));
|
||||
verificationCode.setVerified(false);
|
||||
verificationCode.setVerifyCount(5);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.just(verificationCode));
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_EXCEEDED))
|
||||
.verify();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(clientUserRepository, never()).findByPhone(any());
|
||||
verify(jwtTokenProvider, never()).generateToken(any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogin_WrongCode() {
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
smsRequest.setPhone(TEST_PHONE);
|
||||
smsRequest.setCode("999999");
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData(smsRequest);
|
||||
|
||||
SmsVerificationCode verificationCode = new SmsVerificationCode();
|
||||
verificationCode.setCode(TEST_CODE);
|
||||
verificationCode.setExpireTime(LocalDateTime.now().plusMinutes(5));
|
||||
verificationCode.setVerified(false);
|
||||
verificationCode.setVerifyCount(0);
|
||||
|
||||
when(smsVerificationCodeRepository.findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode()))
|
||||
.thenReturn(Mono.just(verificationCode));
|
||||
when(smsVerificationCodeRepository.save(any(SmsVerificationCode.class))).thenReturn(Mono.just(verificationCode));
|
||||
|
||||
Mono<LoginResult> result = strategy.login(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectErrorMatches(ex -> ex instanceof ApplicationException &&
|
||||
((ApplicationException) ex).getExceptionCode().equals(CLIENT_SMS_CODE_INVALID))
|
||||
.verify();
|
||||
|
||||
verify(smsVerificationCodeRepository, times(1)).findLatestByPhoneAndType(TEST_PHONE, SmsCodeType.LOGIN.getCode());
|
||||
verify(smsVerificationCodeRepository, times(1)).save(any(SmsVerificationCode.class));
|
||||
verify(clientUserRepository, never()).findByPhone(any());
|
||||
verify(jwtTokenProvider, never()).generateToken(any(), anyString());
|
||||
}
|
||||
}
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
package io.destiny.client.core.strategy;
|
||||
|
||||
import io.destiny.client.core.domain.ClientLoginLog;
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
import io.destiny.client.core.repository.IClientLoginLogRepository;
|
||||
import io.destiny.client.core.repository.IClientUserRepository;
|
||||
import io.destiny.client.core.service.ClientUserAuthService;
|
||||
import io.destiny.client.dto.LoginRequest;
|
||||
import io.destiny.client.security.JwtTokenProvider;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.destiny.client.core.exception.ClientUserAuthExceptionCode.CLIENT_INVALID_USERNAME_OR_PASSWORD;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class UsernamePasswordLoginStrategyTest {
|
||||
|
||||
@Mock
|
||||
private ClientUserAuthService clientUserAuthService;
|
||||
|
||||
@Mock
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Mock
|
||||
private IClientUserRepository clientUserRepository;
|
||||
|
||||
@Mock
|
||||
private IClientLoginLogRepository clientLoginLogRepository;
|
||||
|
||||
@Mock
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@InjectMocks
|
||||
private UsernamePasswordLoginStrategy usernamePasswordLoginStrategy;
|
||||
|
||||
@Test
|
||||
void testGetLoginType() {
|
||||
assertEquals("password", usernamePasswordLoginStrategy.getLoginType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccess() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "testuser");
|
||||
data.put("password", "password123");
|
||||
request.setData(data);
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setPassword("encoded_password");
|
||||
|
||||
when(clientUserRepository.findByUsername("testuser")).thenReturn(Mono.just(user));
|
||||
when(passwordEncoder.matches("password123", "encoded_password")).thenReturn(true);
|
||||
when(clientLoginLogRepository.save(any(ClientLoginLog.class)))
|
||||
.thenReturn(Mono.just(new ClientLoginLog()));
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("password") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository).findByUsername("testuser");
|
||||
verify(passwordEncoder).matches("password123", "encoded_password");
|
||||
verify(clientLoginLogRepository).save(any(ClientLoginLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNullUsername() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", null);
|
||||
data.put("password", "password123");
|
||||
request.setData(data);
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository, never()).findByUsername(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithEmptyUsername() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "");
|
||||
data.put("password", "password123");
|
||||
request.setData(data);
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository, never()).findByUsername(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNullPassword() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "testuser");
|
||||
data.put("password", null);
|
||||
request.setData(data);
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository, never()).findByUsername(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithEmptyPassword() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "testuser");
|
||||
data.put("password", "");
|
||||
request.setData(data);
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository, never()).findByUsername(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithInvalidData() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData("invalid_data");
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository, never()).findByUsername(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithUserNotFound() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "nonexistent");
|
||||
data.put("password", "password123");
|
||||
request.setData(data);
|
||||
|
||||
when(clientUserRepository.findByUsername("nonexistent")).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository).findByUsername("nonexistent");
|
||||
verify(passwordEncoder, never()).matches(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithWrongPassword() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "testuser");
|
||||
data.put("password", "wrong_password");
|
||||
request.setData(data);
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setPassword("encoded_password");
|
||||
|
||||
when(clientUserRepository.findByUsername("testuser")).thenReturn(Mono.just(user));
|
||||
when(passwordEncoder.matches("wrong_password", "encoded_password")).thenReturn(false);
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_USERNAME_OR_PASSWORD))
|
||||
.verify();
|
||||
|
||||
verify(clientUserRepository).findByUsername("testuser");
|
||||
verify(passwordEncoder).matches("wrong_password", "encoded_password");
|
||||
verify(clientLoginLogRepository, never()).save(any(ClientLoginLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNullIpAddress() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("password");
|
||||
request.setIpAddress(null);
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("username", "testuser");
|
||||
data.put("password", "password123");
|
||||
request.setData(data);
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setPassword("encoded_password");
|
||||
|
||||
when(clientUserRepository.findByUsername("testuser")).thenReturn(Mono.just(user));
|
||||
when(passwordEncoder.matches("password123", "encoded_password")).thenReturn(true);
|
||||
when(clientLoginLogRepository.save(any(ClientLoginLog.class)))
|
||||
.thenReturn(Mono.just(new ClientLoginLog()));
|
||||
|
||||
StepVerifier.create(usernamePasswordLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("password"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository).findByUsername("testuser");
|
||||
verify(passwordEncoder).matches("password123", "encoded_password");
|
||||
verify(clientLoginLogRepository).save(any(ClientLoginLog.class));
|
||||
}
|
||||
}
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
package io.destiny.client.core.strategy;
|
||||
|
||||
import io.destiny.client.client.WechatMiniProgramClient;
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
import io.destiny.client.core.domain.UserBinding;
|
||||
import io.destiny.client.core.repository.IClientUserRepository;
|
||||
import io.destiny.client.core.repository.IUserBindingRepository;
|
||||
import io.destiny.client.core.service.ClientUserAuthService;
|
||||
import io.destiny.client.dto.LoginRequest;
|
||||
|
||||
import io.destiny.client.dto.WechatAuthResponse;
|
||||
import io.destiny.client.dto.WechatLoginRequest;
|
||||
import io.destiny.client.security.JwtTokenProvider;
|
||||
import io.destiny.common.exception.ApplicationException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static io.destiny.client.core.exception.ClientUserAuthExceptionCode.CLIENT_INVALID_WECHAT_CODE;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class WechatLoginStrategyTest {
|
||||
|
||||
@Mock
|
||||
private ClientUserAuthService clientUserAuthService;
|
||||
|
||||
@Mock
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Mock
|
||||
private WechatMiniProgramClient wechatClient;
|
||||
|
||||
@Mock
|
||||
private IClientUserRepository clientUserRepository;
|
||||
|
||||
@Mock
|
||||
private IUserBindingRepository userBindingRepository;
|
||||
|
||||
@InjectMocks
|
||||
private WechatLoginStrategy wechatLoginStrategy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLoginType() {
|
||||
assertEquals("wechat", wechatLoginStrategy.getLoginType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithValidData() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("valid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.validateRequest(request))
|
||||
.expectNext(request)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithNullCode() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode(null);
|
||||
request.setData(wechatRequest);
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.validateRequest(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_WECHAT_CODE))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithEmptyCode() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.validateRequest(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_WECHAT_CODE))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateRequestWithInvalidDataType() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setData("invalid_data");
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.validateRequest(request))
|
||||
.expectErrorMatches(error -> error instanceof ApplicationException &&
|
||||
((ApplicationException) error).getExceptionCode()
|
||||
.equals(CLIENT_INVALID_WECHAT_CODE))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithExistingUserByOpenId() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("valid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setWechatOpenId("open_id_123");
|
||||
|
||||
when(wechatClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByWechatOpenId("open_id_123")).thenReturn(Mono.just(user));
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("wechat") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository, never()).findByWechatUnionId(anyString());
|
||||
verify(userBindingRepository, never()).findByPlatformAndUnionId(anyString(), anyString());
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithExistingUserByUnionId() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("valid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
user.setWechatUnionId("union_id_456");
|
||||
|
||||
when(wechatClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByWechatOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByWechatUnionId("union_id_456")).thenReturn(Mono.just(user));
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("wechat") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(userBindingRepository, never()).findByPlatformAndUnionId(anyString(), anyString());
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithExistingUserByBinding() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("valid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser user = new ClientUser();
|
||||
user.setId(1L);
|
||||
user.setUsername("testuser");
|
||||
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setUserId(1L);
|
||||
binding.setPlatform("wechat");
|
||||
binding.setPlatformUnionId("union_id_456");
|
||||
|
||||
when(wechatClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByWechatOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByWechatUnionId("union_id_456")).thenReturn(Mono.empty());
|
||||
when(userBindingRepository.findByPlatformAndUnionId("wechat", "union_id_456"))
|
||||
.thenReturn(Mono.just(binding));
|
||||
when(clientUserRepository.findById(1L)).thenReturn(Mono.just(user));
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getUsername().equals("testuser") &&
|
||||
result.getPlatform().equals("wechat") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository, never()).save(any(ClientUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginSuccessWithNewUser() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("valid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setUnionId("union_id_456");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser newUser = new ClientUser();
|
||||
newUser.setId(1L);
|
||||
newUser.setWechatOpenId("open_id_123");
|
||||
newUser.setWechatUnionId("union_id_456");
|
||||
newUser.setPhoneVerified(false);
|
||||
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setId(1L);
|
||||
binding.setUserId(1L);
|
||||
binding.setPlatform("wechat");
|
||||
binding.setPlatformOpenId("open_id_123");
|
||||
binding.setPlatformUnionId("union_id_456");
|
||||
|
||||
when(wechatClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByWechatOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.findByWechatUnionId("union_id_456")).thenReturn(Mono.empty());
|
||||
when(userBindingRepository.findByPlatformAndUnionId("wechat", "union_id_456")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(newUser));
|
||||
when(userBindingRepository.save(any(UserBinding.class))).thenReturn(Mono.just(binding));
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getPlatform().equals("wechat") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository).save(any(ClientUser.class));
|
||||
verify(userBindingRepository).save(any(UserBinding.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithNewUserWithoutUnionId() {
|
||||
when(jwtTokenProvider.generateToken(anyLong(), anyString())).thenReturn("test-token");
|
||||
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("valid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
WechatAuthResponse authResponse = new WechatAuthResponse();
|
||||
authResponse.setOpenId("open_id_123");
|
||||
authResponse.setSessionKey("session_key");
|
||||
|
||||
ClientUser newUser = new ClientUser();
|
||||
newUser.setId(1L);
|
||||
newUser.setWechatOpenId("open_id_123");
|
||||
newUser.setPhoneVerified(false);
|
||||
|
||||
UserBinding binding = new UserBinding();
|
||||
binding.setId(1L);
|
||||
binding.setUserId(1L);
|
||||
binding.setPlatform("wechat");
|
||||
binding.setPlatformOpenId("open_id_123");
|
||||
|
||||
when(wechatClient.auth("valid_code")).thenReturn(Mono.just(authResponse));
|
||||
when(clientUserRepository.findByWechatOpenId("open_id_123")).thenReturn(Mono.empty());
|
||||
when(clientUserRepository.save(any(ClientUser.class))).thenReturn(Mono.just(newUser));
|
||||
when(userBindingRepository.save(any(UserBinding.class))).thenReturn(Mono.just(binding));
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.login(request))
|
||||
.expectNextMatches(result -> result.getUserId().equals(1L) &&
|
||||
result.getPlatform().equals("wechat") &&
|
||||
result.getToken().equals("test-token"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(clientUserRepository, never()).findByWechatUnionId(anyString());
|
||||
verify(userBindingRepository, never()).findByPlatformAndUnionId(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoginWithAuthFailure() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
request.setLoginType("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
wechatRequest.setCode("invalid_code");
|
||||
request.setData(wechatRequest);
|
||||
|
||||
when(wechatClient.auth("invalid_code")).thenReturn(Mono.error(new Exception("Auth failed")));
|
||||
|
||||
StepVerifier.create(wechatLoginStrategy.login(request))
|
||||
.expectError(Exception.class)
|
||||
.verify();
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AccountBindRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
AccountBindRequest request = new AccountBindRequest();
|
||||
|
||||
request.setPlatform("wechat");
|
||||
request.setCode("test_code_123");
|
||||
|
||||
assertEquals("wechat", request.getPlatform());
|
||||
assertEquals("test_code_123", request.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
AccountBindRequest request = new AccountBindRequest();
|
||||
|
||||
assertNull(request.getPlatform());
|
||||
assertNull(request.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
AccountBindRequest request = new AccountBindRequest();
|
||||
|
||||
request.setPlatform(null);
|
||||
request.setCode(null);
|
||||
|
||||
assertNull(request.getPlatform());
|
||||
assertNull(request.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
AccountBindRequest request = new AccountBindRequest();
|
||||
|
||||
request.setPlatform("");
|
||||
request.setCode("");
|
||||
|
||||
assertEquals("", request.getPlatform());
|
||||
assertEquals("", request.getCode());
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import io.destiny.client.core.domain.query.ClientUserLogin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientUserLoginRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
ClientUserLoginRequest request = new ClientUserLoginRequest();
|
||||
|
||||
request.setUsername("testuser");
|
||||
request.setPassword("password123");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
assertEquals("testuser", request.getUsername());
|
||||
assertEquals("password123", request.getPassword());
|
||||
assertEquals("192.168.1.1", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
ClientUserLoginRequest request = new ClientUserLoginRequest();
|
||||
|
||||
assertNull(request.getUsername());
|
||||
assertNull(request.getPassword());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
ClientUserLoginRequest request = new ClientUserLoginRequest();
|
||||
|
||||
request.setUsername(null);
|
||||
request.setPassword(null);
|
||||
request.setIpAddress(null);
|
||||
|
||||
assertNull(request.getUsername());
|
||||
assertNull(request.getPassword());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
ClientUserLoginRequest request = new ClientUserLoginRequest();
|
||||
|
||||
request.setUsername("");
|
||||
request.setPassword("");
|
||||
request.setIpAddress("");
|
||||
|
||||
assertEquals("", request.getUsername());
|
||||
assertEquals("", request.getPassword());
|
||||
assertEquals("", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToDomain() {
|
||||
ClientUserLoginRequest request = new ClientUserLoginRequest();
|
||||
request.setUsername("testuser");
|
||||
request.setPassword("password123");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
ClientUserLogin domain = request.toDomain();
|
||||
|
||||
assertNotNull(domain);
|
||||
assertEquals("testuser", domain.getUsername());
|
||||
assertEquals("password123", domain.getPassword());
|
||||
assertNotNull(domain.getIpAddress());
|
||||
assertEquals("192.168.1.1", domain.getIpAddress().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToDomainWithNullValues() {
|
||||
ClientUserLoginRequest request = new ClientUserLoginRequest();
|
||||
|
||||
ClientUserLogin domain = request.toDomain();
|
||||
|
||||
assertNotNull(domain);
|
||||
assertNull(domain.getUsername());
|
||||
assertNull(domain.getPassword());
|
||||
assertNull(domain.getIpAddress());
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import io.destiny.client.core.domain.ClientUser;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClientUserRegisterRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
|
||||
request.setUsername("testuser");
|
||||
request.setPassword("password123");
|
||||
request.setEmail("test@example.com");
|
||||
request.setPhone("13800138000");
|
||||
request.setGender("male");
|
||||
|
||||
assertEquals("testuser", request.getUsername());
|
||||
assertEquals("password123", request.getPassword());
|
||||
assertEquals("test@example.com", request.getEmail());
|
||||
assertEquals("13800138000", request.getPhone());
|
||||
assertEquals("male", request.getGender());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
|
||||
assertNull(request.getUsername());
|
||||
assertNull(request.getPassword());
|
||||
assertNull(request.getEmail());
|
||||
assertNull(request.getPhone());
|
||||
assertNull(request.getGender());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
|
||||
request.setUsername(null);
|
||||
request.setPassword(null);
|
||||
request.setEmail(null);
|
||||
request.setPhone(null);
|
||||
request.setGender(null);
|
||||
|
||||
assertNull(request.getUsername());
|
||||
assertNull(request.getPassword());
|
||||
assertNull(request.getEmail());
|
||||
assertNull(request.getPhone());
|
||||
assertNull(request.getGender());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
|
||||
request.setUsername("");
|
||||
request.setPassword("");
|
||||
request.setEmail("");
|
||||
request.setPhone("");
|
||||
request.setGender("");
|
||||
|
||||
assertEquals("", request.getUsername());
|
||||
assertEquals("", request.getPassword());
|
||||
assertEquals("", request.getEmail());
|
||||
assertEquals("", request.getPhone());
|
||||
assertEquals("", request.getGender());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToDomain() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
request.setUsername("testuser");
|
||||
request.setPassword("password123");
|
||||
request.setEmail("test@example.com");
|
||||
request.setPhone("13800138000");
|
||||
request.setGender("male");
|
||||
|
||||
ClientUser domain = request.toDomain();
|
||||
|
||||
assertNotNull(domain);
|
||||
assertEquals("testuser", domain.getUsername());
|
||||
assertEquals("password123", domain.getPassword());
|
||||
assertNotNull(domain.getEmail());
|
||||
assertEquals("test@example.com", domain.getEmail().getValue());
|
||||
assertNotNull(domain.getPhone());
|
||||
assertEquals("13800138000", domain.getPhone().getValue());
|
||||
assertEquals("male", domain.getGender());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToDomainWithNullValues() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
|
||||
ClientUser domain = request.toDomain();
|
||||
|
||||
assertNotNull(domain);
|
||||
assertNull(domain.getUsername());
|
||||
assertNull(domain.getPassword());
|
||||
assertNull(domain.getEmail());
|
||||
assertNull(domain.getPhone());
|
||||
assertNull(domain.getGender());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToDomainWithPartialValues() {
|
||||
ClientUserRegisterRequest request = new ClientUserRegisterRequest();
|
||||
request.setUsername("testuser");
|
||||
request.setPassword("password123");
|
||||
|
||||
ClientUser domain = request.toDomain();
|
||||
|
||||
assertNotNull(domain);
|
||||
assertEquals("testuser", domain.getUsername());
|
||||
assertEquals("password123", domain.getPassword());
|
||||
assertNull(domain.getEmail());
|
||||
assertNull(domain.getPhone());
|
||||
assertNull(domain.getGender());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class DouyinLoginRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
DouyinLoginRequest request = new DouyinLoginRequest();
|
||||
|
||||
request.setCode("test_code_123");
|
||||
request.setPlatform("douyin");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
assertEquals("test_code_123", request.getCode());
|
||||
assertEquals("douyin", request.getPlatform());
|
||||
assertEquals("192.168.1.1", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
DouyinLoginRequest request = new DouyinLoginRequest();
|
||||
|
||||
assertNull(request.getCode());
|
||||
assertNull(request.getPlatform());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
DouyinLoginRequest request = new DouyinLoginRequest();
|
||||
|
||||
request.setCode(null);
|
||||
request.setPlatform(null);
|
||||
request.setIpAddress(null);
|
||||
|
||||
assertNull(request.getCode());
|
||||
assertNull(request.getPlatform());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
DouyinLoginRequest request = new DouyinLoginRequest();
|
||||
|
||||
request.setCode("");
|
||||
request.setPlatform("");
|
||||
request.setIpAddress("");
|
||||
|
||||
assertEquals("", request.getCode());
|
||||
assertEquals("", request.getPlatform());
|
||||
assertEquals("", request.getIpAddress());
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class LoginRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
|
||||
request.setLoginType("sms");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
request.setData(new SmsLoginRequest());
|
||||
|
||||
assertEquals("sms", request.getLoginType());
|
||||
assertEquals("192.168.1.1", request.getIpAddress());
|
||||
assertNotNull(request.getData());
|
||||
assertTrue(request.getData() instanceof SmsLoginRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
|
||||
assertNull(request.getLoginType());
|
||||
assertNull(request.getIpAddress());
|
||||
assertNull(request.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
|
||||
request.setLoginType(null);
|
||||
request.setIpAddress(null);
|
||||
request.setData(null);
|
||||
|
||||
assertNull(request.getLoginType());
|
||||
assertNull(request.getIpAddress());
|
||||
assertNull(request.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
|
||||
request.setLoginType("");
|
||||
request.setIpAddress("");
|
||||
|
||||
assertEquals("", request.getLoginType());
|
||||
assertEquals("", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetDifferentDataTypes() {
|
||||
LoginRequest request = new LoginRequest();
|
||||
|
||||
SmsLoginRequest smsRequest = new SmsLoginRequest();
|
||||
request.setData(smsRequest);
|
||||
assertEquals(smsRequest, request.getData());
|
||||
|
||||
PasswordLoginRequest passwordRequest = new PasswordLoginRequest();
|
||||
request.setData(passwordRequest);
|
||||
assertEquals(passwordRequest, request.getData());
|
||||
|
||||
WechatLoginRequest wechatRequest = new WechatLoginRequest();
|
||||
request.setData(wechatRequest);
|
||||
assertEquals(wechatRequest, request.getData());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class PasswordLoginRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
PasswordLoginRequest request = new PasswordLoginRequest();
|
||||
|
||||
request.setUsername("testuser");
|
||||
request.setPassword("password123");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
assertEquals("testuser", request.getUsername());
|
||||
assertEquals("password123", request.getPassword());
|
||||
assertEquals("192.168.1.1", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
PasswordLoginRequest request = new PasswordLoginRequest();
|
||||
|
||||
assertNull(request.getUsername());
|
||||
assertNull(request.getPassword());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
PasswordLoginRequest request = new PasswordLoginRequest();
|
||||
|
||||
request.setUsername(null);
|
||||
request.setPassword(null);
|
||||
request.setIpAddress(null);
|
||||
|
||||
assertNull(request.getUsername());
|
||||
assertNull(request.getPassword());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
PasswordLoginRequest request = new PasswordLoginRequest();
|
||||
|
||||
request.setUsername("");
|
||||
request.setPassword("");
|
||||
request.setIpAddress("");
|
||||
|
||||
assertEquals("", request.getUsername());
|
||||
assertEquals("", request.getPassword());
|
||||
assertEquals("", request.getIpAddress());
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SmsCodeSendRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
SmsCodeSendRequest request = new SmsCodeSendRequest();
|
||||
|
||||
request.setPhone("13800138000");
|
||||
request.setType("login");
|
||||
|
||||
assertEquals("13800138000", request.getPhone());
|
||||
assertEquals("login", request.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
SmsCodeSendRequest request = new SmsCodeSendRequest();
|
||||
|
||||
assertNull(request.getPhone());
|
||||
assertNull(request.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
SmsCodeSendRequest request = new SmsCodeSendRequest();
|
||||
|
||||
request.setPhone(null);
|
||||
request.setType(null);
|
||||
|
||||
assertNull(request.getPhone());
|
||||
assertNull(request.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
SmsCodeSendRequest request = new SmsCodeSendRequest();
|
||||
|
||||
request.setPhone("");
|
||||
request.setType("");
|
||||
|
||||
assertEquals("", request.getPhone());
|
||||
assertEquals("", request.getType());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SmsLoginRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
SmsLoginRequest request = new SmsLoginRequest();
|
||||
|
||||
request.setPhone("13800138000");
|
||||
request.setCode("123456");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
assertEquals("13800138000", request.getPhone());
|
||||
assertEquals("123456", request.getCode());
|
||||
assertEquals("192.168.1.1", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
SmsLoginRequest request = new SmsLoginRequest();
|
||||
|
||||
assertNull(request.getPhone());
|
||||
assertNull(request.getCode());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
SmsLoginRequest request = new SmsLoginRequest();
|
||||
|
||||
request.setPhone(null);
|
||||
request.setCode(null);
|
||||
request.setIpAddress(null);
|
||||
|
||||
assertNull(request.getPhone());
|
||||
assertNull(request.getCode());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
SmsLoginRequest request = new SmsLoginRequest();
|
||||
|
||||
request.setPhone("");
|
||||
request.setCode("");
|
||||
request.setIpAddress("");
|
||||
|
||||
assertEquals("", request.getPhone());
|
||||
assertEquals("", request.getCode());
|
||||
assertEquals("", request.getIpAddress());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package io.destiny.client.dto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class WechatLoginRequestTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
WechatLoginRequest request = new WechatLoginRequest();
|
||||
|
||||
request.setCode("test_code_123");
|
||||
request.setPlatform("wechat");
|
||||
request.setIpAddress("192.168.1.1");
|
||||
|
||||
assertEquals("test_code_123", request.getCode());
|
||||
assertEquals("wechat", request.getPlatform());
|
||||
assertEquals("192.168.1.1", request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultValues() {
|
||||
WechatLoginRequest request = new WechatLoginRequest();
|
||||
|
||||
assertNull(request.getCode());
|
||||
assertNull(request.getPlatform());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
WechatLoginRequest request = new WechatLoginRequest();
|
||||
|
||||
request.setCode(null);
|
||||
request.setPlatform(null);
|
||||
request.setIpAddress(null);
|
||||
|
||||
assertNull(request.getCode());
|
||||
assertNull(request.getPlatform());
|
||||
assertNull(request.getIpAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyValues() {
|
||||
WechatLoginRequest request = new WechatLoginRequest();
|
||||
|
||||
request.setCode("");
|
||||
request.setPlatform("");
|
||||
request.setIpAddress("");
|
||||
|
||||
assertEquals("", request.getCode());
|
||||
assertEquals("", request.getPlatform());
|
||||
assertEquals("", request.getIpAddress());
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
package io.destiny.client.security;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JwtTokenProviderTest {
|
||||
|
||||
@InjectMocks
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
private static final String SECRET_KEY = "your-secret-key-must-be-at-least-256-bits-long-for-hs256-algorithm";
|
||||
private static final Long EXPIRATION = 86400000L;
|
||||
private static final Long USER_ID = 123L;
|
||||
private static final String USERNAME = "testuser";
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
ReflectionTestUtils.setField(jwtTokenProvider, "secret", SECRET_KEY);
|
||||
ReflectionTestUtils.setField(jwtTokenProvider, "expiration", EXPIRATION);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateToken_Success() {
|
||||
String token = jwtTokenProvider.generateToken(USER_ID, USERNAME);
|
||||
assertNotNull(token);
|
||||
assertFalse(token.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUserIdFromToken_Success() {
|
||||
String token = jwtTokenProvider.generateToken(USER_ID, USERNAME);
|
||||
Long userId = jwtTokenProvider.getUserIdFromToken(token);
|
||||
assertEquals(USER_ID, userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUserIdFromToken_InvalidToken() {
|
||||
Long userId = jwtTokenProvider.getUserIdFromToken("invalid.token.here");
|
||||
assertNull(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUserIdFromToken_NullToken() {
|
||||
Long userId = jwtTokenProvider.getUserIdFromToken(null);
|
||||
assertNull(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUsernameFromToken_Success() {
|
||||
String token = jwtTokenProvider.generateToken(USER_ID, USERNAME);
|
||||
String username = jwtTokenProvider.getUsernameFromToken(token);
|
||||
assertEquals(USERNAME, username);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUsernameFromToken_InvalidToken() {
|
||||
String username = jwtTokenProvider.getUsernameFromToken("invalid.token.here");
|
||||
assertNull(username);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUsernameFromToken_NullToken() {
|
||||
String username = jwtTokenProvider.getUsernameFromToken(null);
|
||||
assertNull(username);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateToken_Success() {
|
||||
String token = jwtTokenProvider.generateToken(USER_ID, USERNAME);
|
||||
Boolean isValid = jwtTokenProvider.validateToken(token);
|
||||
assertTrue(isValid);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateToken_InvalidToken() {
|
||||
Boolean isValid = jwtTokenProvider.validateToken("invalid.token.here");
|
||||
assertFalse(isValid);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateToken_NullToken() {
|
||||
Boolean isValid = jwtTokenProvider.validateToken(null);
|
||||
assertFalse(isValid);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsTokenExpired_False() {
|
||||
String token = jwtTokenProvider.generateToken(USER_ID, USERNAME);
|
||||
Boolean isExpired = jwtTokenProvider.isTokenExpired(token);
|
||||
assertFalse(isExpired);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsTokenExpired_InvalidToken() {
|
||||
Boolean isExpired = jwtTokenProvider.isTokenExpired("invalid.token.here");
|
||||
assertTrue(isExpired);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsTokenExpired_NullToken() {
|
||||
Boolean isExpired = jwtTokenProvider.isTokenExpired(null);
|
||||
assertTrue(isExpired);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGenerateToken_DifferentUsers() {
|
||||
String token1 = jwtTokenProvider.generateToken(1L, "user1");
|
||||
String token2 = jwtTokenProvider.generateToken(2L, "user2");
|
||||
assertNotEquals(token1, token2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUserIdFromToken_CorrectUser() {
|
||||
String token = jwtTokenProvider.generateToken(USER_ID, USERNAME);
|
||||
Long userId = jwtTokenProvider.getUserIdFromToken(token);
|
||||
assertEquals(USER_ID, userId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user