mirror of https://github.com/halo-dev/halo
Merge branch 'main' into refactor/setting-config-update
commit
e2e1d1da4e
|
@ -6,6 +6,7 @@ import static run.halo.app.infra.utils.FileUtils.checkDirectoryTraversal;
|
|||
import static run.halo.app.infra.utils.FileUtils.deleteFileSilently;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
|
@ -25,6 +26,7 @@ import org.springframework.core.io.buffer.DataBuffer;
|
|||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
@ -156,19 +158,14 @@ class LocalAttachmentUploadHandler implements AttachmentHandler {
|
|||
var typeValidator = file.content()
|
||||
.next()
|
||||
.handle((dataBuffer, sink) -> {
|
||||
var mimeType = "Unknown";
|
||||
try {
|
||||
mimeType = FileTypeDetectUtils.detectMimeType(dataBuffer.asInputStream());
|
||||
var isAllow = setting.getAllowedFileTypes()
|
||||
.stream()
|
||||
.map(FileCategoryMatcher::of)
|
||||
.anyMatch(matcher -> matcher.match(file.filename()));
|
||||
if (isAllow) {
|
||||
sink.next(dataBuffer);
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Failed to detect file type", e);
|
||||
var mimeType = detectMimeType(dataBuffer.asInputStream());
|
||||
var isAllow = setting.getAllowedFileTypes()
|
||||
.stream()
|
||||
.map(FileCategoryMatcher::of)
|
||||
.anyMatch(matcher -> matcher.match(mimeType));
|
||||
if (isAllow) {
|
||||
sink.next(dataBuffer);
|
||||
return;
|
||||
}
|
||||
sink.error(new FileTypeNotAllowedException("File type is not allowed",
|
||||
"problemDetail.attachment.upload.fileTypeNotSupported",
|
||||
|
@ -180,6 +177,16 @@ class LocalAttachmentUploadHandler implements AttachmentHandler {
|
|||
return Mono.when(validations);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String detectMimeType(InputStream inputStream) {
|
||||
try {
|
||||
return FileTypeDetectUtils.detectMimeType(inputStream);
|
||||
} catch (IOException e) {
|
||||
log.warn("Failed to detect file type", e);
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Attachment> delete(DeleteContext deleteContext) {
|
||||
return Mono.just(deleteContext)
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.springframework.expression.MethodExecutor;
|
|||
import org.springframework.expression.MethodResolver;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.CompilablePropertyAccessor;
|
||||
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
|
||||
import org.springframework.integration.json.JsonPropertyAccessor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
@ -122,7 +123,7 @@ public class EvaluationContextEnhancer extends AbstractTemplateBoundariesProcess
|
|||
public PropertyAccessor createOptimalAccessor(EvaluationContext context, Object target,
|
||||
String name) {
|
||||
var optimalAccessor = delegate.createOptimalAccessor(context, target, name);
|
||||
if (optimalAccessor instanceof OptimalPropertyAccessor optimalPropertyAccessor) {
|
||||
if (optimalAccessor instanceof CompilablePropertyAccessor optimalPropertyAccessor) {
|
||||
if (ReactiveUtils.isReactiveType(optimalPropertyAccessor.getPropertyType())) {
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import reactor.core.publisher.Flux;
|
||||
import run.halo.app.core.extension.Role;
|
||||
|
@ -47,7 +47,7 @@ class ExtensionConfigurationTest {
|
|||
@Autowired
|
||||
SchemeManager schemeManager;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
RoleService roleService;
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -13,10 +13,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.socket.WebSocketHandler;
|
||||
import org.springframework.web.reactive.socket.WebSocketMessage;
|
||||
|
@ -38,7 +38,7 @@ class WebFluxConfigTest {
|
|||
@Autowired
|
||||
WebTestClient webClient;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
RoleService roleService;
|
||||
|
||||
@LocalServerPort
|
||||
|
|
|
@ -12,8 +12,8 @@ import org.junit.jupiter.api.Test;
|
|||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
@ -46,7 +46,7 @@ class CategoryPostCountUpdaterTest {
|
|||
@Autowired
|
||||
private SchemeManager schemeManager;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private ExtensionClient client;
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -12,9 +12,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import reactor.core.publisher.Flux;
|
||||
import run.halo.app.core.extension.Role;
|
||||
|
@ -39,7 +39,7 @@ public class PostIntegrationTests {
|
|||
@Autowired
|
||||
private WebTestClient webTestClient;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
RoleService roleService;
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -14,8 +14,8 @@ import org.junit.jupiter.api.Nested;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
@ -48,7 +48,7 @@ class CommentServiceImplIntegrationTest {
|
|||
@Autowired
|
||||
private SchemeManager schemeManager;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private ReactiveExtensionClient reactiveClient;
|
||||
|
||||
@Autowired
|
||||
|
@ -57,7 +57,7 @@ class CommentServiceImplIntegrationTest {
|
|||
@Autowired
|
||||
private IndexerFactory indexerFactory;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private CommentServiceImpl commentService;
|
||||
|
||||
Mono<Extension> deleteImmediately(Extension extension) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package run.halo.app.content.comment;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
@ -12,7 +11,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.json.JSONException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
@ -61,53 +59,25 @@ import run.halo.app.security.authorization.AuthorityUtils;
|
|||
class CommentServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private SystemConfigurableEnvironmentFetcher environmentFetcher;
|
||||
SystemConfigurableEnvironmentFetcher environmentFetcher;
|
||||
|
||||
@Mock
|
||||
private ReactiveExtensionClient client;
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@Mock
|
||||
private UserService userService;
|
||||
UserService userService;
|
||||
|
||||
@Mock
|
||||
private RoleService roleService;
|
||||
RoleService roleService;
|
||||
|
||||
@Mock
|
||||
private ExtensionGetter extensionGetter;
|
||||
ExtensionGetter extensionGetter;
|
||||
|
||||
@InjectMocks
|
||||
private CommentServiceImpl commentService;
|
||||
CommentServiceImpl commentService;
|
||||
|
||||
@Mock
|
||||
private CounterService counterService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
SystemSetting.Comment commentSetting = getCommentSetting();
|
||||
lenient().when(environmentFetcher.fetchComment()).thenReturn(Mono.just(commentSetting));
|
||||
|
||||
ListResult<Comment> comments = new ListResult<>(1, 10, 3, comments());
|
||||
when(client.listBy(eq(Comment.class), any(ListOptions.class), any(PageRequest.class)))
|
||||
.thenReturn(Mono.just(comments));
|
||||
|
||||
when(userService.getUserOrGhost(eq("A-owner")))
|
||||
.thenReturn(Mono.just(createUser("A-owner")));
|
||||
when(userService.getUserOrGhost(eq("B-owner")))
|
||||
.thenReturn(Mono.just(createUser("B-owner")));
|
||||
when(client.fetch(eq(User.class), eq("C-owner")))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
when(roleService.contains(Set.of("USER"),
|
||||
Set.of(AuthorityUtils.COMMENT_MANAGEMENT_ROLE_NAME)))
|
||||
.thenReturn(Mono.just(false));
|
||||
|
||||
PostCommentSubject postCommentSubject = Mockito.mock(PostCommentSubject.class);
|
||||
when(extensionGetter.getExtensions(CommentSubject.class))
|
||||
.thenReturn(Flux.just(postCommentSubject));
|
||||
|
||||
when(postCommentSubject.supports(any())).thenReturn(true);
|
||||
when(postCommentSubject.get(eq("fake-post"))).thenReturn(Mono.just(post()));
|
||||
}
|
||||
CounterService counterService;
|
||||
|
||||
private static User createUser(String name) {
|
||||
User user = new User();
|
||||
|
@ -122,10 +92,21 @@ class CommentServiceImplTest {
|
|||
|
||||
@Test
|
||||
void listComment() {
|
||||
var comments = new ListResult<Comment>(1, 10, 3, comments());
|
||||
when(client.listBy(eq(Comment.class), any(ListOptions.class), any(PageRequest.class)))
|
||||
.thenReturn(Mono.just(comments));
|
||||
|
||||
PostCommentSubject postCommentSubject = Mockito.mock(PostCommentSubject.class);
|
||||
when(extensionGetter.getExtensions(CommentSubject.class))
|
||||
.thenReturn(Flux.just(postCommentSubject));
|
||||
|
||||
when(postCommentSubject.supports(any())).thenReturn(true);
|
||||
when(postCommentSubject.get(eq("fake-post"))).thenReturn(Mono.just(post()));
|
||||
|
||||
when(userService.getUserOrGhost(any()))
|
||||
.thenReturn(Mono.just(ghostUser()));
|
||||
when(userService.getUserOrGhost("A-owner"))
|
||||
.thenReturn(Mono.just(createUser("A-owner")));
|
||||
// when(userService.getUserOrGhost("A-owner"))
|
||||
// .thenReturn(Mono.just(createUser("A-owner")));
|
||||
when(userService.getUserOrGhost("B-owner"))
|
||||
.thenReturn(Mono.just(createUser("B-owner")));
|
||||
|
||||
|
@ -170,6 +151,12 @@ class CommentServiceImplTest {
|
|||
@Test
|
||||
@WithMockUser(username = "B-owner")
|
||||
void create() throws JSONException {
|
||||
var commentSetting = getCommentSetting();
|
||||
when(environmentFetcher.fetchComment()).thenReturn(Mono.just(commentSetting));
|
||||
when(roleService.contains(Set.of("USER"),
|
||||
Set.of(AuthorityUtils.COMMENT_MANAGEMENT_ROLE_NAME)))
|
||||
.thenReturn(Mono.just(false));
|
||||
|
||||
CommentRequest commentRequest = new CommentRequest();
|
||||
commentRequest.setRaw("fake-raw");
|
||||
commentRequest.setContent("fake-content");
|
||||
|
|
|
@ -14,8 +14,8 @@ import org.junit.jupiter.api.Nested;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
@ -56,7 +56,7 @@ class ReplyServiceImplIntegrationTest {
|
|||
@Autowired
|
||||
private SchemeManager schemeManager;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private ReactiveExtensionClient reactiveClient;
|
||||
|
||||
@Autowired
|
||||
|
@ -65,7 +65,7 @@ class ReplyServiceImplIntegrationTest {
|
|||
@Autowired
|
||||
private IndexerFactory indexerFactory;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private ReplyServiceImpl replyService;
|
||||
|
||||
Mono<Extension> deleteImmediately(Extension extension) {
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
package run.halo.app.core.endpoint.console;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.csrf;
|
||||
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
|
||||
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
|
||||
import io.github.resilience4j.reactor.ratelimiter.operator.RateLimiterOperator;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -39,47 +35,49 @@ import run.halo.app.extension.ReactiveExtensionClient;
|
|||
@ExtendWith(SpringExtension.class)
|
||||
@WithMockUser(username = "fake-user", password = "fake-password")
|
||||
class EmailVerificationCodeTest {
|
||||
|
||||
WebTestClient webClient;
|
||||
|
||||
@Mock
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@Mock
|
||||
EmailVerificationService emailVerificationService;
|
||||
|
||||
@Mock
|
||||
UserService userService;
|
||||
|
||||
@Mock
|
||||
RateLimiterRegistry rateLimiterRegistry;
|
||||
|
||||
@InjectMocks
|
||||
UserEndpoint endpoint;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
var spyUserEndpoint = spy(endpoint);
|
||||
webClient = WebTestClient.bindToRouterFunction(endpoint.endpoint())
|
||||
.apply(springSecurity())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendEmailVerificationCode() {
|
||||
var config = RateLimiterConfig.custom()
|
||||
.limitRefreshPeriod(Duration.ofSeconds(10))
|
||||
.limitForPeriod(1)
|
||||
.build();
|
||||
var sendCodeRateLimiter = RateLimiterRegistry.of(config)
|
||||
.rateLimiter("send-email-verification-code-fake-user:hi@halo.run");
|
||||
doReturn(RateLimiterOperator.of(sendCodeRateLimiter)).when(spyUserEndpoint)
|
||||
.sendEmailVerificationCodeRateLimiter(eq("fake-user"), eq("hi@halo.run"));
|
||||
when(rateLimiterRegistry.rateLimiter(
|
||||
"send-email-verification-code-fake-user:hi@halo.run",
|
||||
"send-email-verification-code")
|
||||
).thenReturn(sendCodeRateLimiter);
|
||||
|
||||
var verifyEmailRateLimiter = RateLimiterRegistry.of(config)
|
||||
.rateLimiter("verify-email-fake-user");
|
||||
doReturn(RateLimiterOperator.of(verifyEmailRateLimiter)).when(spyUserEndpoint)
|
||||
.verificationEmailRateLimiter(eq("fake-user"));
|
||||
|
||||
webClient = WebTestClient.bindToRouterFunction(spyUserEndpoint.endpoint()).build()
|
||||
.mutateWith(csrf());
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendEmailVerificationCode() {
|
||||
var user = new User();
|
||||
user.setMetadata(new Metadata());
|
||||
user.getMetadata().setName("fake-user");
|
||||
user.setSpec(new User.UserSpec());
|
||||
user.getSpec().setEmail("hi@halo.run");
|
||||
when(client.get(eq(User.class), eq("fake-user"))).thenReturn(Mono.just(user));
|
||||
when(emailVerificationService.sendVerificationCode(anyString(), anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
webClient.post()
|
||||
|
@ -100,6 +98,16 @@ class EmailVerificationCodeTest {
|
|||
|
||||
@Test
|
||||
void verifyEmail() {
|
||||
var config = RateLimiterConfig.custom()
|
||||
.limitRefreshPeriod(Duration.ofSeconds(10))
|
||||
.limitForPeriod(1)
|
||||
.build();
|
||||
|
||||
var verifyEmailRateLimiter = RateLimiterRegistry.of(config)
|
||||
.rateLimiter("verify-email-fake-user");
|
||||
when(rateLimiterRegistry.rateLimiter("verify-email-fake-user", "verify-email"))
|
||||
.thenReturn(verifyEmailRateLimiter);
|
||||
|
||||
when(emailVerificationService.verify(anyString(), anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
when(userService.confirmPassword(anyString(), anyString()))
|
||||
|
|
|
@ -14,9 +14,9 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -37,7 +37,7 @@ public class UserEndpointIntegrationTest {
|
|||
@Autowired
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
RoleService roleService;
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -9,13 +9,13 @@ import org.junit.jupiter.api.BeforeEach;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import run.halo.app.search.SearchService;
|
||||
|
||||
@SpringBootTest
|
||||
class DefaultPluginApplicationContextFactoryTest {
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
SpringPluginManager pluginManager;
|
||||
|
||||
DefaultPluginApplicationContextFactory factory;
|
||||
|
|
|
@ -23,11 +23,11 @@ import org.mockito.Mock;
|
|||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.skyscreamer.jsonassert.JSONAssert;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCache;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.ConfigMap;
|
||||
|
@ -55,7 +55,7 @@ class DefaultSettingFetcherTest {
|
|||
@Mock
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
private final PluginContext pluginContext = PluginContext.builder()
|
||||
.name("fake")
|
||||
.configMapName("fake-config")
|
||||
|
|
|
@ -37,11 +37,12 @@ import run.halo.app.infra.utils.JsonUtils;
|
|||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
class AuthProviderServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ReactiveExtensionClient client;
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@InjectMocks
|
||||
private AuthProviderServiceImpl authProviderService;
|
||||
AuthProviderServiceImpl authProviderService;
|
||||
|
||||
@Test
|
||||
void testEnable() {
|
||||
|
@ -57,14 +58,12 @@ class AuthProviderServiceImplTest {
|
|||
when(client.fetch(eq(ConfigMap.class), eq(SystemSetting.SYSTEM_CONFIG)))
|
||||
.thenReturn(Mono.just(configMap));
|
||||
|
||||
AuthProvider local = createAuthProvider("local");
|
||||
local.getMetadata().getLabels().put(AuthProvider.PRIVILEGED_LABEL, "true");
|
||||
when(client.list(eq(AuthProvider.class), any(), any())).thenReturn(Flux.just(local));
|
||||
|
||||
// Call the method being tested
|
||||
Mono<AuthProvider> result = authProviderService.enable("github");
|
||||
authProviderService.enable("github")
|
||||
.as(StepVerifier::create)
|
||||
.expectNext(authProvider)
|
||||
.verifyComplete();
|
||||
|
||||
assertEquals(authProvider, result.block());
|
||||
ConfigMap value = captor.getValue();
|
||||
String providerSettingStr = value.getData().get(SystemSetting.AuthProvider.GROUP);
|
||||
Set<String> enabled =
|
||||
|
@ -84,7 +83,7 @@ class AuthProviderServiceImplTest {
|
|||
|
||||
AuthProvider local = createAuthProvider("local");
|
||||
local.getMetadata().getLabels().put(AuthProvider.PRIVILEGED_LABEL, "true");
|
||||
when(client.list(eq(AuthProvider.class), any(), any())).thenReturn(Flux.just(local));
|
||||
// when(client.list(eq(AuthProvider.class), any(), any())).thenReturn(Flux.just(local));
|
||||
|
||||
ArgumentCaptor<ConfigMap> captor = ArgumentCaptor.forClass(ConfigMap.class);
|
||||
when(client.update(captor.capture())).thenReturn(Mono.empty());
|
||||
|
@ -155,7 +154,7 @@ class AuthProviderServiceImplTest {
|
|||
"supportsBinding": false,
|
||||
"privileged": false
|
||||
},{
|
||||
|
||||
|
||||
"name": "gitee",
|
||||
"displayName": "gitee",
|
||||
"enabled": false,
|
||||
|
|
|
@ -10,8 +10,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import run.halo.app.core.extension.Role;
|
||||
import run.halo.app.core.extension.RoleBinding;
|
||||
|
@ -28,7 +28,7 @@ import run.halo.app.extension.ReactiveExtensionClient;
|
|||
@AutoConfigureTestDatabase
|
||||
class SuperAdminInitializerTest {
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -17,7 +17,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -26,6 +25,7 @@ import org.springframework.security.core.userdetails.ReactiveUserDetailsPassword
|
|||
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
|
@ -49,13 +49,13 @@ class AuthorizationTest {
|
|||
@Autowired
|
||||
WebTestClient webClient;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
ReactiveUserDetailsService userDetailsService;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
ReactiveUserDetailsPasswordService userDetailsPasswordService;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
RoleService roleService;
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -11,11 +11,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
|
@ -36,7 +36,7 @@ public class ThemeIntegrationTest {
|
|||
@Autowired
|
||||
WebTestClient webClient;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
InitializationStateGetter initializationStateGetter;
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -2,14 +2,13 @@ package run.halo.app.theme;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
@ -35,40 +34,41 @@ import reactor.test.StepVerifier;
|
|||
class ViewNameResolverTest {
|
||||
|
||||
@Mock
|
||||
private ThemeResolver themeResolver;
|
||||
ThemeResolver themeResolver;
|
||||
|
||||
@Mock
|
||||
private ThymeleafProperties thymeleafProperties;
|
||||
ThymeleafProperties thymeleafProperties;
|
||||
|
||||
@InjectMocks
|
||||
private DefaultViewNameResolver viewNameResolver;
|
||||
DefaultViewNameResolver viewNameResolver;
|
||||
|
||||
@TempDir
|
||||
private File themePath;
|
||||
Path themePath;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws IOException {
|
||||
when(thymeleafProperties.getSuffix()).thenReturn(ThymeleafProperties.DEFAULT_SUFFIX);
|
||||
}
|
||||
|
||||
var templatesPath = themePath.toPath().resolve("templates");
|
||||
@Test
|
||||
void resolveViewNameOrDefault() throws URISyntaxException, IOException {
|
||||
var templatesPath = themePath.resolve("templates");
|
||||
if (!Files.exists(templatesPath)) {
|
||||
Files.createDirectory(templatesPath);
|
||||
}
|
||||
Files.createFile(templatesPath.resolve("post_news.html"));
|
||||
Files.createFile(templatesPath.resolve("post_docs.html"));
|
||||
|
||||
when(themeResolver.getTheme(any()))
|
||||
|
||||
var exchange = Mockito.mock(ServerWebExchange.class);
|
||||
when(themeResolver.getTheme(exchange))
|
||||
.thenReturn(Mono.fromSupplier(() -> ThemeContext.builder()
|
||||
.name("fake-theme")
|
||||
.path(themePath.toPath())
|
||||
.path(themePath)
|
||||
.active(true)
|
||||
.build())
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveViewNameOrDefault() throws URISyntaxException {
|
||||
ServerWebExchange exchange = Mockito.mock(ServerWebExchange.class);
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.uri(new URI("/")).method(HttpMethod.GET)
|
||||
.exchange(exchange)
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
@ -27,10 +27,10 @@ class GeneratorMetaProcessorTest {
|
|||
@Autowired
|
||||
WebTestClient webClient;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
InitializationStateGetter initializationStateGetter;
|
||||
|
||||
@MockBean
|
||||
@MockitoBean
|
||||
ThemeResolver themeResolver;
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -44,21 +44,19 @@ import run.halo.app.metrics.CounterService;
|
|||
class CommentPublicQueryServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ReactiveExtensionClient client;
|
||||
@Mock
|
||||
private UserService userService;
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@Mock
|
||||
private CounterService counterService;
|
||||
UserService userService;
|
||||
|
||||
@Mock
|
||||
CounterService counterService;
|
||||
|
||||
@InjectMocks
|
||||
private CommentPublicQueryServiceImpl commentPublicQueryService;
|
||||
CommentPublicQueryServiceImpl commentPublicQueryService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
User ghost = createUser();
|
||||
ghost.getMetadata().setName("ghost");
|
||||
when(userService.getUserOrGhost(eq("ghost"))).thenReturn(Mono.just(ghost));
|
||||
when(userService.getUserOrGhost(eq("fake-user"))).thenReturn(Mono.just(createUser()));
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
|
@ -38,14 +38,14 @@ import run.halo.app.theme.ThemeResolver;
|
|||
@AutoConfigureWebTestClient
|
||||
public class ThemeMessageResolverIntegrationTest {
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private ThemeResolver themeResolver;
|
||||
|
||||
private URL defaultThemeUrl;
|
||||
|
||||
private URL otherThemeUrl;
|
||||
|
||||
@SpyBean
|
||||
@MockitoSpyBean
|
||||
private InitializationStateGetter initializationStateGetter;
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -43,36 +43,40 @@ import run.halo.app.theme.finders.vo.SinglePageVo;
|
|||
@ExtendWith(SpringExtension.class)
|
||||
class PreviewRouterFunctionTest {
|
||||
@Mock
|
||||
private ReactiveExtensionClient client;
|
||||
ReactiveExtensionClient client;
|
||||
|
||||
@Mock
|
||||
private PostPublicQueryService postPublicQueryService;
|
||||
PostPublicQueryService postPublicQueryService;
|
||||
|
||||
@Mock
|
||||
private ViewNameResolver viewNameResolver;
|
||||
ViewNameResolver viewNameResolver;
|
||||
|
||||
@Mock
|
||||
private ViewResolver viewResolver;
|
||||
ViewResolver viewResolver;
|
||||
|
||||
@Mock
|
||||
private PostService postService;
|
||||
PostService postService;
|
||||
|
||||
@Mock
|
||||
private SinglePageConversionService singlePageConversionService;
|
||||
SinglePageConversionService singlePageConversionService;
|
||||
|
||||
@InjectMocks
|
||||
private PreviewRouterFunction previewRouterFunction;
|
||||
PreviewRouterFunction previewRouterFunction;
|
||||
|
||||
private WebTestClient webTestClient;
|
||||
WebTestClient webTestClient;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
void setUp() {
|
||||
webTestClient = WebTestClient.bindToRouterFunction(previewRouterFunction.previewRouter())
|
||||
.handlerStrategies(HandlerStrategies.builder()
|
||||
.viewResolver(viewResolver)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "testuser")
|
||||
void previewPost() {
|
||||
when(viewResolver.resolveViewName(any(), any()))
|
||||
.thenReturn(Mono.just(new EmptyView() {
|
||||
@Override
|
||||
|
@ -81,11 +85,7 @@ class PreviewRouterFunctionTest {
|
|||
return super.render(model, contentType, exchange);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "testuser")
|
||||
public void previewPost() {
|
||||
Post post = new Post();
|
||||
post.setMetadata(new Metadata());
|
||||
post.getMetadata().setName("post1");
|
||||
|
@ -123,6 +123,15 @@ class PreviewRouterFunctionTest {
|
|||
@Test
|
||||
@WithMockUser(username = "testuser")
|
||||
public void previewSinglePage() {
|
||||
when(viewResolver.resolveViewName(any(), any()))
|
||||
.thenReturn(Mono.just(new EmptyView() {
|
||||
@Override
|
||||
public Mono<Void> render(Map<String, ?> model, MediaType contentType,
|
||||
ServerWebExchange exchange) {
|
||||
return super.render(model, contentType, exchange);
|
||||
}
|
||||
}));
|
||||
|
||||
SinglePage singlePage = new SinglePage();
|
||||
singlePage.setMetadata(new Metadata());
|
||||
singlePage.getMetadata().setName("page1");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
plugins {
|
||||
id 'org.springframework.boot' version '3.3.3' apply false
|
||||
id 'org.springframework.boot' version '3.4.0-M3' apply false
|
||||
id 'io.spring.dependency-management' version '1.1.6' apply false
|
||||
id "com.gorylenko.gradle-git-properties" version "2.4.1" apply false
|
||||
id "de.undercouch.download" version "5.6.0" apply false
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
setupCoreModules,
|
||||
setupPluginModules,
|
||||
} from "@console/setup/setupModules";
|
||||
import { useSystemConfigMapStore } from "@console/stores/system-configmap";
|
||||
import { useThemeStore } from "@console/stores/theme";
|
||||
|
||||
const app = createApp(App);
|
||||
|
@ -97,10 +96,6 @@ async function initApp() {
|
|||
console.error("Failed to load plugins", e);
|
||||
}
|
||||
|
||||
// load system configMap
|
||||
const systemConfigMapStore = useSystemConfigMapStore();
|
||||
await systemConfigMapStore.fetchSystemConfigMap();
|
||||
|
||||
if (globalInfoStore.globalInfo?.userInitialized) {
|
||||
await loadActivatedTheme();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import { Toast, VButton } from "@halo-dev/components";
|
|||
// hooks
|
||||
import { useGlobalInfoStore } from "@/stores/global-info";
|
||||
import { useSettingFormConvert } from "@console/composables/use-setting-form";
|
||||
import { useSystemConfigMapStore } from "@console/stores/system-configmap";
|
||||
import type { ConfigMap, Setting } from "@halo-dev/api-client";
|
||||
import { coreApiClient } from "@halo-dev/api-client";
|
||||
import { useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||
|
@ -18,7 +17,6 @@ import { useI18n } from "vue-i18n";
|
|||
const SYSTEM_CONFIGMAP_NAME = "system";
|
||||
|
||||
const { t } = useI18n();
|
||||
const systemConfigMapStore = useSystemConfigMapStore();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const group = inject<Ref<string>>("activeTab", ref("basic"));
|
||||
|
@ -52,7 +50,7 @@ const handleSaveConfigMap = async () => {
|
|||
return;
|
||||
}
|
||||
|
||||
const { data } = await coreApiClient.configMap.updateConfigMap({
|
||||
await coreApiClient.configMap.updateConfigMap({
|
||||
name: SYSTEM_CONFIGMAP_NAME,
|
||||
configMap: configMapToUpdate,
|
||||
});
|
||||
|
@ -61,7 +59,6 @@ const handleSaveConfigMap = async () => {
|
|||
|
||||
queryClient.invalidateQueries({ queryKey: ["system-configMap"] });
|
||||
await useGlobalInfoStore().fetchGlobalInfo();
|
||||
systemConfigMapStore.configMap = data;
|
||||
|
||||
saving.value = false;
|
||||
};
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import type { ConfigMap } from "@halo-dev/api-client";
|
||||
import { coreApiClient } from "@halo-dev/api-client";
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
interface SystemConfigMapState {
|
||||
configMap?: ConfigMap;
|
||||
}
|
||||
|
||||
export const useSystemConfigMapStore = defineStore({
|
||||
id: "system-configmap",
|
||||
state: (): SystemConfigMapState => ({
|
||||
configMap: undefined,
|
||||
}),
|
||||
actions: {
|
||||
async fetchSystemConfigMap() {
|
||||
try {
|
||||
const { data } = await coreApiClient.configMap.getConfigMap(
|
||||
{
|
||||
name: "system",
|
||||
},
|
||||
{ mute: true }
|
||||
);
|
||||
this.configMap = data;
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch system configMap", error);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
Loading…
Reference in New Issue