格式修改
This commit is contained in:
@@ -11,25 +11,29 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@DisplayName("账号管理服务")
|
||||
@SpringJUnitConfig(classes = {AccountManagementService.class, AccountManagementServiceTest.TestConfig.class})
|
||||
class AccountManagementServiceTest {
|
||||
private final AuthAccountRepository repository = mock(AuthAccountRepository.class);
|
||||
private final TokenSessionStore sessions = mock(TokenSessionStore.class);
|
||||
private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(4);
|
||||
private final AccountManagementService service = new AccountManagementService();
|
||||
@MockBean private AuthAccountRepository repository;
|
||||
@MockBean private TokenSessionStore sessions;
|
||||
@Resource private PasswordEncoder encoder;
|
||||
@Resource private AccountManagementService service;
|
||||
private AuthAccount account;
|
||||
|
||||
@BeforeEach void setUp() {
|
||||
ReflectionTestUtils.setField(service, "repository", repository);
|
||||
ReflectionTestUtils.setField(service, "passwordEncoder", encoder);
|
||||
ReflectionTestUtils.setField(service, "tokenSessionStore", sessions);
|
||||
account = new AuthAccount(); account.setId(10L); account.setPasswordHash(encoder.encode("OldPass1"));
|
||||
account.setTokenVersion(2); account.setAccountStatus("ACTIVE");
|
||||
when(repository.findById(10L)).thenReturn(account);
|
||||
@@ -123,4 +127,11 @@ class AccountManagementServiceTest {
|
||||
verify(repository).save(account);
|
||||
verify(sessions).revokeAll(10L);
|
||||
}
|
||||
@Configuration
|
||||
static class TestConfig {
|
||||
@Bean
|
||||
PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,31 +7,32 @@ import com.baiyue.auth.repository.AuthAccountRepository;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SpringJUnitConfig(MerchantRegistrationService.class)
|
||||
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
|
||||
class MerchantRegistrationServiceTest {
|
||||
@MockBean private AuthAccountRepository accounts;
|
||||
@MockBean private PasswordEncoder encoder;
|
||||
@MockBean private IamOnboardingClient onboarding;
|
||||
@Resource private MerchantRegistrationService service;
|
||||
@Test
|
||||
void registeredAuthAccountUsesTheOwnerIdentityReturnedByIamOnboarding() {
|
||||
AuthAccountRepository accounts = mock(AuthAccountRepository.class);
|
||||
PasswordEncoder encoder = mock(PasswordEncoder.class);
|
||||
IamOnboardingClient onboarding = mock(IamOnboardingClient.class);
|
||||
MerchantRegistrationService service = new MerchantRegistrationService();
|
||||
ReflectionTestUtils.setField(service, "accountRepository", accounts);
|
||||
ReflectionTestUtils.setField(service, "passwordEncoder", encoder);
|
||||
ReflectionTestUtils.setField(service, "onboardingClient", onboarding);
|
||||
ReflectionTestUtils.setField(service, "internalToken", "internal-token");
|
||||
when(encoder.encode("Password123")).thenReturn("encoded-password");
|
||||
when(onboarding.register(eq("internal-token"), any())).thenReturn(ApiResponse.success(
|
||||
new IamOnboardingClient.OnboardingResponse(10001L, 30001L, "PROFILE_REQUIRED")));
|
||||
@@ -59,14 +60,6 @@ class MerchantRegistrationServiceTest {
|
||||
|
||||
@Test
|
||||
void failedAuthInsertCompensatesTheIamRegistration() {
|
||||
AuthAccountRepository accounts = mock(AuthAccountRepository.class);
|
||||
PasswordEncoder encoder = mock(PasswordEncoder.class);
|
||||
IamOnboardingClient onboarding = mock(IamOnboardingClient.class);
|
||||
MerchantRegistrationService service = new MerchantRegistrationService();
|
||||
ReflectionTestUtils.setField(service, "accountRepository", accounts);
|
||||
ReflectionTestUtils.setField(service, "passwordEncoder", encoder);
|
||||
ReflectionTestUtils.setField(service, "onboardingClient", onboarding);
|
||||
ReflectionTestUtils.setField(service, "internalToken", "internal-token");
|
||||
when(encoder.encode("Password123")).thenReturn("encoded-password");
|
||||
when(onboarding.register(eq("internal-token"), any())).thenReturn(ApiResponse.success(
|
||||
new IamOnboardingClient.OnboardingResponse(10001L, 30001L, "PROFILE_REQUIRED")));
|
||||
@@ -87,14 +80,6 @@ class MerchantRegistrationServiceTest {
|
||||
|
||||
@Test
|
||||
void rolledBackAuthTransactionCompensatesAfterTheLocalTransactionCompletes() {
|
||||
AuthAccountRepository accounts = mock(AuthAccountRepository.class);
|
||||
PasswordEncoder encoder = mock(PasswordEncoder.class);
|
||||
IamOnboardingClient onboarding = mock(IamOnboardingClient.class);
|
||||
MerchantRegistrationService service = new MerchantRegistrationService();
|
||||
ReflectionTestUtils.setField(service, "accountRepository", accounts);
|
||||
ReflectionTestUtils.setField(service, "passwordEncoder", encoder);
|
||||
ReflectionTestUtils.setField(service, "onboardingClient", onboarding);
|
||||
ReflectionTestUtils.setField(service, "internalToken", "internal-token");
|
||||
when(encoder.encode("Password123")).thenReturn("encoded-password");
|
||||
when(onboarding.register(eq("internal-token"), any())).thenReturn(ApiResponse.success(
|
||||
new IamOnboardingClient.OnboardingResponse(10001L, 30001L, "PROFILE_REQUIRED")));
|
||||
|
||||
@@ -3,9 +3,15 @@ package com.baiyue.auth.service;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.data.redis.core.SetOperations;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Set;
|
||||
@@ -18,14 +24,27 @@ import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.eq;
|
||||
|
||||
@DisplayName("令牌会话存储")
|
||||
@SpringJUnitConfig(classes = {TokenSessionStore.class, TokenSessionStoreTest.TestConfig.class})
|
||||
@TestPropertySource(properties = "baiyue.security.token-key-prefix=baiyue:auth")
|
||||
class TokenSessionStoreTest {
|
||||
@MockBean
|
||||
private StringRedisTemplate redis;
|
||||
|
||||
@Resource
|
||||
private TokenSessionStore store;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestConfig {
|
||||
@Bean
|
||||
ObjectMapper objectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void storesAccessAndHashedRefreshWithIndependentTtls() {
|
||||
StringRedisTemplate redis = mock(StringRedisTemplate.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
ValueOperations<String, String> values = mock(ValueOperations.class);
|
||||
when(redis.opsForValue()).thenReturn(values);
|
||||
TokenSessionStore store = new TokenSessionStore(redis, new ObjectMapper(), "baiyue:auth:");
|
||||
|
||||
store.store("jti-1", 42L, "raw-refresh", Duration.ofMinutes(30), Duration.ofDays(7));
|
||||
|
||||
@@ -36,14 +55,12 @@ class TokenSessionStoreTest {
|
||||
|
||||
@Test
|
||||
void atomicallyConsumesRefreshAndRevokesItsAccessSession() throws Exception {
|
||||
StringRedisTemplate redis = mock(StringRedisTemplate.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
ValueOperations<String, String> values = mock(ValueOperations.class);
|
||||
when(redis.opsForValue()).thenReturn(values);
|
||||
String json = new ObjectMapper().writeValueAsString(
|
||||
new TokenSessionStore.RefreshSession(42L, "jti-1"));
|
||||
when(values.getAndDelete(anyString())).thenReturn(json);
|
||||
TokenSessionStore store = new TokenSessionStore(redis, new ObjectMapper(), "baiyue:auth");
|
||||
|
||||
TokenSessionStore.RefreshSession session = store.consume("raw-refresh");
|
||||
|
||||
@@ -55,26 +72,23 @@ class TokenSessionStoreTest {
|
||||
|
||||
@Test
|
||||
void treatsAlreadyConsumedRefreshAsInvalid() {
|
||||
StringRedisTemplate redis = mock(StringRedisTemplate.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
ValueOperations<String, String> values = mock(ValueOperations.class);
|
||||
when(redis.opsForValue()).thenReturn(values);
|
||||
when(values.getAndDelete(anyString())).thenReturn(null);
|
||||
|
||||
assertThat(new TokenSessionStore(redis, new ObjectMapper(), "baiyue:auth")
|
||||
.consume("raw-refresh")).isNull();
|
||||
assertThat(store.consume("raw-refresh")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void revokesAllIndexedSessionsForUser() {
|
||||
StringRedisTemplate redis = mock(StringRedisTemplate.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
SetOperations<String, String> sets = mock(SetOperations.class);
|
||||
when(redis.opsForSet()).thenReturn(sets);
|
||||
when(sets.members("baiyue:auth:user-sessions:42"))
|
||||
.thenReturn(Set.of("baiyue:auth:access:a", "baiyue:auth:refresh:b"));
|
||||
|
||||
new TokenSessionStore(redis, new ObjectMapper(), "baiyue:auth").revokeAll(42L);
|
||||
store.revokeAll(42L);
|
||||
|
||||
verify(redis).delete(eq(Set.of("baiyue:auth:access:a", "baiyue:auth:refresh:b")));
|
||||
verify(redis).delete("baiyue:auth:user-sessions:42");
|
||||
|
||||
Reference in New Issue
Block a user