mirror of https://github.com/halo-dev/halo
refactor: plugin js bundle file loading and routing rules (#2556)
#### What type of PR is this? /kind improvement /area core /milestone 2.0 /kind api-change #### What this PR does / why we need it: 重构插件 JsBundle 文件加载方式及路由规则 - 将插件静态资源的访问路由规则从 /assets/{plugin-name}/** 改为 /plugins/{plugin-name}/assets/** 与主题静态资源规则结构一致 - 默认在 Halo 中提供 /plugins/{plugin-name}/assets/console/** 路由以确保插件都能加载到最基础的 JsBundle 文件 #### Which issue(s) this PR fixes: Fixes #2555 #### Special notes for your reviewer: how to test it? 1. 安装并启用一个插件能访问到 `/plugins/{plugin-name}/assets/console/main.js` 和 `/plugins/{plugin-name}/assets/console/style.css` 即为功能正确 2. 在插件的 extensions 目录创建一个 reverse proxy 的自定义模型 yaml 资源,并使用此插件,插件反向代理规则能正确访问到文件即为功能正确 /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? ```release-note 重构插件 JsBundle 文件加载方式及路由规则 ```pull/2582/head
parent
08fe1858cf
commit
6cce2202a1
|
@ -57,7 +57,6 @@ import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
|||
import run.halo.app.infra.properties.HaloProperties;
|
||||
import run.halo.app.plugin.ExtensionComponentsFinder;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.resources.JsBundleRuleProvider;
|
||||
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionRegistry;
|
||||
import run.halo.app.theme.router.TemplateRouteManager;
|
||||
|
||||
|
@ -116,10 +115,9 @@ public class ExtensionConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
Controller pluginController(ExtensionClient client, HaloPluginManager haloPluginManager,
|
||||
JsBundleRuleProvider jsBundleRule) {
|
||||
Controller pluginController(ExtensionClient client, HaloPluginManager haloPluginManager) {
|
||||
return new ControllerBuilder("plugin-controller", client)
|
||||
.reconciler(new PluginReconciler(client, haloPluginManager, jsBundleRule))
|
||||
.reconciler(new PluginReconciler(client, haloPluginManager))
|
||||
.extension(new Plugin())
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -17,8 +17,7 @@ import run.halo.app.extension.controller.Reconciler.Request;
|
|||
import run.halo.app.infra.utils.JsonUtils;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginStartingError;
|
||||
import run.halo.app.plugin.resources.JsBundleRuleProvider;
|
||||
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionFactory;
|
||||
import run.halo.app.plugin.resources.BundleResourceUtils;
|
||||
|
||||
/**
|
||||
* Plugin reconciler.
|
||||
|
@ -32,14 +31,10 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
private final ExtensionClient client;
|
||||
private final HaloPluginManager haloPluginManager;
|
||||
|
||||
private final JsBundleRuleProvider jsBundleRule;
|
||||
|
||||
public PluginReconciler(ExtensionClient client,
|
||||
HaloPluginManager haloPluginManager,
|
||||
JsBundleRuleProvider jsBundleRule) {
|
||||
HaloPluginManager haloPluginManager) {
|
||||
this.client = client;
|
||||
this.haloPluginManager = haloPluginManager;
|
||||
this.jsBundleRule = jsBundleRule;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,15 +124,12 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
PluginState currentState = haloPluginManager.startPlugin(pluginName);
|
||||
handleStatus(plugin, currentState, PluginState.STARTED);
|
||||
Plugin.PluginStatus status = plugin.statusNonNull();
|
||||
// TODO Check whether the JS bundle rule exists. If it does not exist, do not populate
|
||||
// populate stylesheet path
|
||||
jsBundleRule.jsRule(pluginName)
|
||||
.map(jsRule -> ReverseProxyRouterFunctionFactory.buildRoutePath(pluginName, jsRule))
|
||||
.ifPresent(status::setEntry);
|
||||
|
||||
jsBundleRule.cssRule(pluginName)
|
||||
.map(cssRule -> ReverseProxyRouterFunctionFactory.buildRoutePath(pluginName, cssRule))
|
||||
.ifPresent(status::setStylesheet);
|
||||
String jsBundlePath = BundleResourceUtils.getJsBundlePath(haloPluginManager, pluginName);
|
||||
status.setEntry(jsBundlePath);
|
||||
|
||||
String cssBundlePath = BundleResourceUtils.getCssBundlePath(haloPluginManager, pluginName);
|
||||
status.setStylesheet(cssBundlePath);
|
||||
|
||||
status.setLastStartTime(Instant.now());
|
||||
}
|
||||
|
|
|
@ -22,8 +22,13 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import run.halo.app.plugin.resources.BundleResourceUtils;
|
||||
|
||||
/**
|
||||
* Plugin autoconfiguration for Spring Boot.
|
||||
|
@ -150,4 +155,22 @@ public class PluginAutoConfiguration {
|
|||
pluginManager.setSystemVersion(pluginProperties.getSystemVersion());
|
||||
return pluginManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> pluginJsBundleRoute(HaloPluginManager haloPluginManager) {
|
||||
return RouterFunctions.route()
|
||||
.GET("/plugins/{name}/assets/console/{*resource}", request -> {
|
||||
String pluginName = request.pathVariable("name");
|
||||
String fileName = request.pathVariable("resource");
|
||||
|
||||
Resource jsBundleResource =
|
||||
BundleResourceUtils.getJsBundleResource(haloPluginManager, pluginName,
|
||||
fileName);
|
||||
if (jsBundleResource == null) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
return ServerResponse.ok().bodyValue(jsBundleResource);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,8 @@ public interface PluginConst {
|
|||
String PLUGIN_NAME_LABEL_NAME = "plugin.halo.run/plugin-name";
|
||||
|
||||
String SYSTEM_PLUGIN_NAME = "system";
|
||||
|
||||
static String assertsRoutePrefix(String pluginName) {
|
||||
return "/plugins/" + pluginName + "/assets/";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package run.halo.app.plugin.resources;
|
||||
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginConst;
|
||||
|
||||
/**
|
||||
* Plugin bundle resources utils.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public abstract class BundleResourceUtils {
|
||||
private static final String CONSOLE_BUNDLE_LOCATION = "console";
|
||||
private static final String JS_BUNDLE = "main.js";
|
||||
private static final String CSS_BUNDLE = "style.css";
|
||||
|
||||
/**
|
||||
* Gets plugin css bundle resource path relative to the plugin classpath if exists.
|
||||
*
|
||||
* @return css bundle resource path if exists, otherwise return null.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getCssBundlePath(HaloPluginManager haloPluginManager,
|
||||
String pluginName) {
|
||||
Resource jsBundleResource = getJsBundleResource(haloPluginManager, pluginName, CSS_BUNDLE);
|
||||
if (jsBundleResource != null) {
|
||||
return consoleResourcePath(pluginName, CSS_BUNDLE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String consoleResourcePath(String pluginName, String name) {
|
||||
return PathUtils.combinePath(PluginConst.assertsRoutePrefix(pluginName),
|
||||
CONSOLE_BUNDLE_LOCATION, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plugin js bundle resource path relative to the plugin classpath if exists.
|
||||
*
|
||||
* @return js bundle resource path if exists, otherwise return null.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getJsBundlePath(HaloPluginManager haloPluginManager,
|
||||
String pluginName) {
|
||||
Resource jsBundleResource = getJsBundleResource(haloPluginManager, pluginName, JS_BUNDLE);
|
||||
if (jsBundleResource != null) {
|
||||
return consoleResourcePath(pluginName, JS_BUNDLE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets js bundle resource by plugin name in console location.
|
||||
*
|
||||
* @return js bundle resource if exists, otherwise null
|
||||
*/
|
||||
@Nullable
|
||||
public static Resource getJsBundleResource(HaloPluginManager pluginManager, String pluginName,
|
||||
String bundleName) {
|
||||
Assert.hasText(pluginName, "The pluginName must not be blank");
|
||||
Assert.hasText(bundleName, "Bundle name must not be blank");
|
||||
|
||||
DefaultResourceLoader resourceLoader = getResourceLoader(pluginManager, pluginName);
|
||||
if (resourceLoader == null) {
|
||||
return null;
|
||||
}
|
||||
String path = PathUtils.combinePath(CONSOLE_BUNDLE_LOCATION, bundleName);
|
||||
Resource resource = resourceLoader.getResource(path);
|
||||
return resource.exists() ? resource : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static DefaultResourceLoader getResourceLoader(HaloPluginManager pluginManager,
|
||||
String pluginName) {
|
||||
Assert.notNull(pluginManager, "Plugin manager must not be null");
|
||||
PluginWrapper plugin = pluginManager.getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
return null;
|
||||
}
|
||||
return new DefaultResourceLoader(plugin.getPluginClassLoader());
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package run.halo.app.plugin.resources;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.core.extension.ReverseProxy.FileReverseProxyProvider;
|
||||
import run.halo.app.core.extension.ReverseProxy.ReverseProxyRule;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
|
||||
/**
|
||||
* TODO Optimize code to support user customize js bundle rules.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class JsBundleRuleProvider {
|
||||
private static final String JS_LOCATION = "/console/main.js";
|
||||
private static final String CSS_LOCATION = "/console/style.css";
|
||||
|
||||
private static final FileReverseProxyProvider JS_FILE_PROXY =
|
||||
new FileReverseProxyProvider("console", "main.js");
|
||||
|
||||
private static final FileReverseProxyProvider CSS_FILE_PROXY =
|
||||
new FileReverseProxyProvider("console", "style.css");
|
||||
|
||||
private final HaloPluginManager haloPluginManager;
|
||||
|
||||
public JsBundleRuleProvider(HaloPluginManager haloPluginManager) {
|
||||
this.haloPluginManager = haloPluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plugin js bundle rule.
|
||||
*
|
||||
* @param pluginName plugin name
|
||||
* @return a js bundle rule
|
||||
*/
|
||||
public Optional<ReverseProxyRule> jsRule(String pluginName) {
|
||||
return Optional.of(JS_LOCATION)
|
||||
.filter(path -> createResourceLoader(pluginName)
|
||||
.getResource(path).exists())
|
||||
.map(path -> new ReverseProxyRule(path, JS_FILE_PROXY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plugin stylesheet rule.
|
||||
*
|
||||
* @param pluginName plugin name
|
||||
* @return a stylesheet bundle rule
|
||||
*/
|
||||
public Optional<ReverseProxyRule> cssRule(String pluginName) {
|
||||
return Optional.of(CSS_LOCATION)
|
||||
.filter(path -> createResourceLoader(pluginName)
|
||||
.getResource(path)
|
||||
.exists())
|
||||
.map(path -> new ReverseProxyRule(path, CSS_FILE_PROXY));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private DefaultResourceLoader createResourceLoader(String pluginName) {
|
||||
PluginWrapper plugin = haloPluginManager.getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
return new DefaultResourceLoader();
|
||||
}
|
||||
return new DefaultResourceLoader(plugin.getPluginClassLoader());
|
||||
}
|
||||
|
||||
}
|
|
@ -4,20 +4,19 @@ import static org.springframework.http.MediaType.ALL;
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.server.PathContainer;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.core.extension.ReverseProxy;
|
||||
|
@ -38,13 +37,6 @@ import run.halo.app.plugin.PluginConst;
|
|||
@Slf4j
|
||||
@Component
|
||||
public class ReverseProxyRouterFunctionFactory {
|
||||
private static final String REVERSE_PROXY_API_PREFIX = "/assets";
|
||||
|
||||
private final JsBundleRuleProvider jsBundleRuleProvider;
|
||||
|
||||
public ReverseProxyRouterFunctionFactory(JsBundleRuleProvider jsBundleRuleProvider) {
|
||||
this.jsBundleRuleProvider = jsBundleRuleProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Create {@link RouterFunction} according to the {@link ReverseProxy} custom resource
|
||||
|
@ -67,7 +59,7 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
Assert.notNull(reverseProxy, "The reverseProxy must not be null.");
|
||||
Assert.notNull(applicationContext, "The applicationContext must not be null.");
|
||||
final var pluginId = getPluginId(applicationContext);
|
||||
var rules = getReverseProxyRules(pluginId, reverseProxy);
|
||||
var rules = getReverseProxyRules(reverseProxy);
|
||||
|
||||
return rules.map(rule -> {
|
||||
String routePath = buildRoutePath(pluginId, rule);
|
||||
|
@ -93,21 +85,13 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
return PluginConst.SYSTEM_PLUGIN_NAME;
|
||||
}
|
||||
|
||||
private Flux<ReverseProxyRule> getReverseProxyRules(String pluginId,
|
||||
ReverseProxy reverseProxy) {
|
||||
return Flux.fromIterable(reverseProxy.getRules())
|
||||
.concatWith(Flux.fromIterable(getJsBundleRules(pluginId)));
|
||||
}
|
||||
|
||||
private List<ReverseProxyRule> getJsBundleRules(String pluginId) {
|
||||
List<ReverseProxyRule> rules = new ArrayList<>(2);
|
||||
jsBundleRuleProvider.jsRule(pluginId).ifPresent(rules::add);
|
||||
jsBundleRuleProvider.cssRule(pluginId).ifPresent(rules::add);
|
||||
return rules;
|
||||
private Flux<ReverseProxyRule> getReverseProxyRules(ReverseProxy reverseProxy) {
|
||||
return Flux.fromIterable(reverseProxy.getRules());
|
||||
}
|
||||
|
||||
public static String buildRoutePath(String pluginId, ReverseProxyRule reverseProxyRule) {
|
||||
return PathUtils.combinePath(REVERSE_PROXY_API_PREFIX, pluginId, reverseProxyRule.path());
|
||||
return PathUtils.combinePath(PluginConst.assertsRoutePrefix(pluginId),
|
||||
reverseProxyRule.path());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,13 +124,13 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
if (StringUtils.isNotBlank(configuredFilename)) {
|
||||
filename = configuredFilename;
|
||||
} else {
|
||||
AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||
String routePath = buildRoutePath(pluginId, rule);
|
||||
filename =
|
||||
antPathMatcher.extractPathWithinPattern(routePath, request.path());
|
||||
PathContainer pathContainer = PathPatternParser.defaultInstance.parse(routePath)
|
||||
.extractPathWithinPattern(PathContainer.parsePath(request.path()));
|
||||
filename = pathContainer.value();
|
||||
}
|
||||
|
||||
String filePath = PathUtils.appendPathSeparatorIfMissing(directory) + filename;
|
||||
String filePath = PathUtils.combinePath(directory, filename);
|
||||
return pluginApplicationContext.getResource(filePath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import run.halo.app.extension.controller.Reconciler;
|
|||
import run.halo.app.infra.utils.JsonUtils;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginStartingError;
|
||||
import run.halo.app.plugin.resources.JsBundleRuleProvider;
|
||||
|
||||
/**
|
||||
* Tests for {@link PluginReconciler}.
|
||||
|
@ -49,8 +48,7 @@ class PluginReconcilerTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
JsBundleRuleProvider jsBundleRule = new JsBundleRuleProvider(haloPluginManager);
|
||||
pluginReconciler = new PluginReconciler(extensionClient, haloPluginManager, jsBundleRule);
|
||||
pluginReconciler = new PluginReconciler(extensionClient, haloPluginManager);
|
||||
|
||||
when(haloPluginManager.getPlugin(any())).thenReturn(pluginWrapper);
|
||||
when(haloPluginManager.getUnresolvedPlugins()).thenReturn(List.of());
|
||||
|
|
|
@ -21,6 +21,9 @@ class PathUtilsTest {
|
|||
String s = PathUtils.combinePath(segments.split(","));
|
||||
assertThat(s).isEqualTo(expected);
|
||||
});
|
||||
|
||||
String s = PathUtils.combinePath("a", "", "c");
|
||||
assertThat(s).isEqualTo("/a/c");
|
||||
}
|
||||
|
||||
private Map<String, String> getCombinePathCases() {
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package run.halo.app.plugin.resources;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
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.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.pf4j.PluginClassLoader;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.core.io.Resource;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
|
||||
/**
|
||||
* Tests for {@link BundleResourceUtils}.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BundleResourceUtilsTest {
|
||||
|
||||
@Mock
|
||||
private HaloPluginManager pluginManager;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws MalformedURLException {
|
||||
PluginWrapper pluginWrapper = Mockito.mock(PluginWrapper.class);
|
||||
PluginClassLoader pluginClassLoader = Mockito.mock(PluginClassLoader.class);
|
||||
when(pluginWrapper.getPluginClassLoader()).thenReturn(pluginClassLoader);
|
||||
lenient().when(pluginManager.getPlugin(eq("fake-plugin"))).thenReturn(pluginWrapper);
|
||||
|
||||
lenient().when(pluginClassLoader.getResource(eq("console/main.js"))).thenReturn(
|
||||
new URL("file://console/main.js"));
|
||||
lenient().when(pluginClassLoader.getResource(eq("console/style.css"))).thenReturn(
|
||||
new URL("file://console/style.css"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCssBundlePath() {
|
||||
String cssBundlePath =
|
||||
BundleResourceUtils.getCssBundlePath(pluginManager, "nothing-plugin");
|
||||
assertThat(cssBundlePath).isNull();
|
||||
|
||||
cssBundlePath = BundleResourceUtils.getCssBundlePath(pluginManager, "fake-plugin");
|
||||
assertThat(cssBundlePath).isEqualTo("/plugins/fake-plugin/assets/console/style.css");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getJsBundlePath() {
|
||||
String jsBundlePath =
|
||||
BundleResourceUtils.getJsBundlePath(pluginManager, "nothing-plugin");
|
||||
assertThat(jsBundlePath).isNull();
|
||||
|
||||
jsBundlePath = BundleResourceUtils.getJsBundlePath(pluginManager, "fake-plugin");
|
||||
assertThat(jsBundlePath).isEqualTo("/plugins/fake-plugin/assets/console/main.js");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getJsBundleResource() {
|
||||
Resource jsBundleResource =
|
||||
BundleResourceUtils.getJsBundleResource(pluginManager, "fake-plugin", "main.js");
|
||||
assertThat(jsBundleResource).isNotNull();
|
||||
assertThat(jsBundleResource.exists()).isTrue();
|
||||
|
||||
jsBundleResource =
|
||||
BundleResourceUtils.getJsBundleResource(pluginManager, "fake-plugin", "test.js");
|
||||
assertThat(jsBundleResource).isNull();
|
||||
|
||||
jsBundleResource =
|
||||
BundleResourceUtils.getJsBundleResource(pluginManager, "nothing-plugin", "main.js");
|
||||
assertThat(jsBundleResource).isNull();
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||
import reactor.test.StepVerifier;
|
||||
import run.halo.app.core.extension.ReverseProxy;
|
||||
import run.halo.app.extension.Metadata;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginApplicationContext;
|
||||
import run.halo.app.plugin.PluginConst;
|
||||
|
||||
|
@ -27,16 +26,13 @@ class ReverseProxyRouterFunctionFactoryTest {
|
|||
|
||||
@Mock
|
||||
private PluginApplicationContext pluginApplicationContext;
|
||||
@Mock
|
||||
private HaloPluginManager haloPluginManager;
|
||||
|
||||
private ReverseProxyRouterFunctionFactory reverseProxyRouterFunctionFactory;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
JsBundleRuleProvider jsBundleRuleProvider = new JsBundleRuleProvider(haloPluginManager);
|
||||
reverseProxyRouterFunctionFactory =
|
||||
new ReverseProxyRouterFunctionFactory(jsBundleRuleProvider);
|
||||
new ReverseProxyRouterFunctionFactory();
|
||||
|
||||
when(pluginApplicationContext.getPluginId()).thenReturn("fakeA");
|
||||
}
|
||||
|
@ -50,7 +46,6 @@ class ReverseProxyRouterFunctionFactoryTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
|
||||
private ReverseProxy mockReverseProxy() {
|
||||
ReverseProxy.ReverseProxyRule reverseProxyRule =
|
||||
new ReverseProxy.ReverseProxyRule("/static/**",
|
||||
|
|
Loading…
Reference in New Issue