格式修改

This commit is contained in:
2026-08-05 10:35:07 +08:00
parent 81c9c92f5d
commit 496fc58a90
241 changed files with 5600 additions and 2088 deletions
@@ -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");