test(token): harden duplicate name regression coverage

This commit is contained in:
yun-zhi-ztl 2026-03-15 19:08:29 +08:00
parent 74ac44ed65
commit 7c2bd553e5
2 changed files with 59 additions and 0 deletions

View file

@ -93,6 +93,28 @@ class TokenControllerTest {
.andExpect(jsonPath("$.msg").value("Token 名称最多 64 个字符"));
}
@Test
void create_rejectsDuplicateActiveNames() throws Exception {
PlatformPrincipal principal = new PlatformPrincipal(
"user-42", "tester", "tester@example.com", "", "github", Set.of("USER")
);
var auth = new UsernamePasswordAuthenticationToken(
principal, null, List.of(new SimpleGrantedAuthority("ROLE_USER"))
);
given(apiTokenService.createToken(anyString(), anyString(), anyString(), org.mockito.ArgumentMatchers.nullable(String.class)))
.willThrow(new DomainBadRequestException("error.token.name.duplicate"));
mockMvc.perform(post("/api/v1/tokens")
.with(authentication(auth))
.with(csrf())
.contentType("application/json")
.content("""
{"name":"cli"}
"""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.msg").value("你已经有同名 Token"));
}
@Test
void create_passesExpirationToService() throws Exception {
PlatformPrincipal principal = new PlatformPrincipal(

View file

@ -1,12 +1,16 @@
package com.iflytek.skillhub.auth.token;
import com.iflytek.skillhub.auth.repository.ApiTokenRepository;
import com.iflytek.skillhub.auth.entity.ApiToken;
import com.iflytek.skillhub.domain.shared.exception.DomainBadRequestException;
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 org.springframework.dao.DataIntegrityViolationException;
import java.time.LocalDateTime;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThat;
@ -83,4 +87,37 @@ class ApiTokenServiceTest {
verify(tokenRepo, never()).save(any());
}
@Test
void createToken_rejectsBlankNamesAfterTrimming() {
assertThatThrownBy(() -> service.createToken("user-1", " ", "[]"))
.isInstanceOf(DomainBadRequestException.class)
.hasMessageContaining("validation.token.name.notBlank");
verify(tokenRepo, never()).save(any());
}
@Test
void createToken_allowsReusingNameWhenPreviousTokenIsRevoked() {
when(tokenRepo.existsByUserIdAndRevokedAtIsNullAndNameIgnoreCase("user-1", "CLI"))
.thenReturn(false);
when(tokenRepo.save(any())).thenAnswer(invocation -> invocation.getArgument(0));
var result = service.createToken("user-1", " CLI ", "[]");
assertThat(result.entity().getName()).isEqualTo("CLI");
verify(tokenRepo).existsByUserIdAndRevokedAtIsNullAndNameIgnoreCase("user-1", "CLI");
verify(tokenRepo).save(any(ApiToken.class));
}
@Test
void createToken_translatesDatabaseConstraintViolationToDuplicateError() {
when(tokenRepo.existsByUserIdAndRevokedAtIsNullAndNameIgnoreCase("user-1", "CLI"))
.thenReturn(false);
when(tokenRepo.save(any())).thenThrow(new DataIntegrityViolationException("duplicate key"));
assertThatThrownBy(() -> service.createToken("user-1", "CLI", "[]"))
.isInstanceOf(DomainBadRequestException.class)
.hasMessageContaining("error.token.name.duplicate");
}
}