test(cli): align auth tests with bearer hardening

Refs: 25f57a32-5f1d-4d56-b6b7-9b6b7b868799
Signed-off-by: dongmucat <1127093059@qq.com>
This commit is contained in:
dongmucat 2026-06-17 11:27:09 +08:00
parent cb4bf94711
commit cf22f568f7
2 changed files with 30 additions and 31 deletions

View file

@ -1,7 +1,11 @@
package com.iflytek.skillhub.controller.cli;
import com.iflytek.skillhub.auth.rbac.PlatformPrincipal;
import com.iflytek.skillhub.auth.entity.ApiToken;
import com.iflytek.skillhub.auth.repository.UserRoleBindingRepository;
import com.iflytek.skillhub.auth.token.ApiTokenService;
import com.iflytek.skillhub.domain.skill.SkillVisibility;
import com.iflytek.skillhub.domain.user.UserAccount;
import com.iflytek.skillhub.domain.user.UserAccountRepository;
import com.iflytek.skillhub.dto.cli.CliDryRunResponse;
import com.iflytek.skillhub.service.cli.CliSkillAppService;
import org.junit.jupiter.api.Test;
@ -10,18 +14,16 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -32,18 +34,22 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class CliDryRunValidateTest {
@Autowired MockMvc mockMvc;
@MockBean CliSkillAppService cliSkillAppService;
@MockBean ApiTokenService apiTokenService;
@MockBean UserAccountRepository userAccountRepository;
@MockBean UserRoleBindingRepository userRoleBindingRepository;
private UsernamePasswordAuthenticationToken auth() {
PlatformPrincipal principal = new PlatformPrincipal(
"user-1", "tester", "t@example.com", "", "api_token", Set.of("USER"));
return new UsernamePasswordAuthenticationToken(
principal, null, List.of(
new SimpleGrantedAuthority("ROLE_USER"),
new SimpleGrantedAuthority("SCOPE_skill:publish")));
private void givenValidPublishToken() {
ApiToken token = new ApiToken("user-1", "cli", "sk_test", "hash", "[\"skill:publish\"]");
UserAccount user = new UserAccount("user-1", "tester", "t@example.com", "");
given(apiTokenService.validateToken("test-token")).willReturn(Optional.of(token));
given(userAccountRepository.findById("user-1")).willReturn(Optional.of(user));
given(userRoleBindingRepository.findByUserId("user-1")).willReturn(List.of());
}
@Test
void validatePublish_returnsValidResult() throws Exception {
givenValidPublishToken();
given(cliSkillAppService.validatePublish(
eq("global"), any(), eq("user-1"), eq(SkillVisibility.PUBLIC), eq(Set.of("USER"))))
.willReturn(new CliDryRunResponse(
@ -55,8 +61,7 @@ class CliDryRunValidateTest {
mockMvc.perform(multipart("/api/cli/v1/skills/global/publish/validate")
.file(file)
.header("Authorization", "Bearer test-token")
.with(authentication(auth())))
.header("Authorization", "Bearer test-token"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.valid").value(true))
.andExpect(jsonPath("$.data.resolvedSlug").value("my-skill"))
@ -65,6 +70,7 @@ class CliDryRunValidateTest {
@Test
void validatePublish_returnsInvalidResult() throws Exception {
givenValidPublishToken();
given(cliSkillAppService.validatePublish(
eq("global"), any(), eq("user-1"), eq(SkillVisibility.PUBLIC), eq(Set.of("USER"))))
.willReturn(new CliDryRunResponse(
@ -76,8 +82,7 @@ class CliDryRunValidateTest {
mockMvc.perform(multipart("/api/cli/v1/skills/global/publish/validate")
.file(file)
.header("Authorization", "Bearer test-token")
.with(authentication(auth())))
.header("Authorization", "Bearer test-token"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.valid").value(false))
.andExpect(jsonPath("$.data.errors[0]").value("Missing required file: SKILL.md at root"))
@ -86,6 +91,7 @@ class CliDryRunValidateTest {
@Test
void validatePublish_acceptsCustomVisibility() throws Exception {
givenValidPublishToken();
given(cliSkillAppService.validatePublish(
eq("global"), any(), eq("user-1"), eq(SkillVisibility.PRIVATE), eq(Set.of("USER"))))
.willReturn(new CliDryRunResponse(
@ -97,22 +103,21 @@ class CliDryRunValidateTest {
mockMvc.perform(multipart("/api/cli/v1/skills/global/publish/validate")
.file(file)
.file(new MockMultipartFile("visibility", "", "text/plain", "PRIVATE".getBytes()))
.header("Authorization", "Bearer test-token")
.with(authentication(auth())))
.header("Authorization", "Bearer test-token"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.valid").value(true));
}
@Test
void validatePublish_rejectsInvalidVisibility() throws Exception {
givenValidPublishToken();
MockMultipartFile file = new MockMultipartFile("file", "skill.zip",
"application/zip", new byte[]{0x50, 0x4B, 0x03, 0x04});
mockMvc.perform(multipart("/api/cli/v1/skills/global/publish/validate")
.file(file)
.file(new MockMultipartFile("visibility", "", "text/plain", "BOGUS".getBytes()))
.header("Authorization", "Bearer test-token")
.with(authentication(auth())))
.header("Authorization", "Bearer test-token"))
.andExpect(status().isBadRequest());
}

View file

@ -22,8 +22,6 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.bind.annotation.PostMapping;
@ -33,7 +31,6 @@ import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -43,7 +40,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.BDDMockito.given;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -204,13 +200,12 @@ class CliSkillControllerTest {
@Test
void deleteReturnsCliDeleteResponse() throws Exception {
PlatformPrincipal principal = new PlatformPrincipal(
"user-1", "tester", "t@example.com", "", "api_token", Set.of("USER"));
var auth = new UsernamePasswordAuthenticationToken(
principal, null, List.of(
new SimpleGrantedAuthority("ROLE_USER"),
new SimpleGrantedAuthority("SCOPE_skill:delete")));
ApiToken token = new ApiToken("user-1", "cli", "sk_test", "hash", "[\"skill:delete\"]");
UserAccount user = new UserAccount("user-1", "tester", "t@example.com", "");
given(apiTokenService.validateToken("test-token")).willReturn(Optional.of(token));
given(userAccountRepository.findById("user-1")).willReturn(Optional.of(user));
given(userRoleBindingRepository.findByUserId("user-1")).willReturn(List.of());
given(cliSkillAppService.deleteRemote(
org.mockito.ArgumentMatchers.eq("global"),
org.mockito.ArgumentMatchers.eq("demo"),
@ -222,8 +217,7 @@ class CliSkillControllerTest {
mockMvc.perform(org.springframework.test.web.servlet.request.MockMvcRequestBuilders
.delete("/api/cli/v1/skills/global/demo")
.header("Authorization", "Bearer test-token")
.with(authentication(auth)))
.header("Authorization", "Bearer test-token"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.ok").value(true))
.andExpect(jsonPath("$.data.namespace").value("global"))