diff --git a/build.gradle b/build.gradle index 83e8aad..330191c 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ dependencies { testImplementation 'run.halo.app:api' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } test { diff --git a/src/main/java/run/halo/live2d/ThemeFetcher.java b/src/main/java/run/halo/live2d/ThemeFetcher.java index 32ae780..9271104 100644 --- a/src/main/java/run/halo/live2d/ThemeFetcher.java +++ b/src/main/java/run/halo/live2d/ThemeFetcher.java @@ -30,10 +30,12 @@ public Mono getActiveThemeName() { return this.extensionClient.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG ) - .map(ConfigMap::getData) - .map(data -> JsonUtils.jsonToObject( - data.get("theme"), JsonNode.class).get("active").asText() - ); + .flatMap(configMap -> Mono.justOrEmpty(configMap.getData())) + .flatMap(data -> Mono.justOrEmpty(data.get("theme"))) + .filter(themeConfig -> !themeConfig.isBlank()) + .map(themeConfig -> JsonUtils.jsonToObject(themeConfig, JsonNode.class)) + .map(themeConfig -> themeConfig.path("active").asText(null)) + .filter(themeName -> themeName != null && !themeName.isBlank()); } public Mono getActiveThemeLive2dTipsPath(String pathTemplate) { diff --git a/src/test/java/run/halo/live2d/ThemeFetcherTest.java b/src/test/java/run/halo/live2d/ThemeFetcherTest.java new file mode 100644 index 0000000..64ae4e2 --- /dev/null +++ b/src/test/java/run/halo/live2d/ThemeFetcherTest.java @@ -0,0 +1,52 @@ +package run.halo.live2d; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Map; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import run.halo.app.extension.ConfigMap; +import run.halo.app.extension.ReactiveExtensionClient; +import run.halo.app.infra.SystemSetting; + +class ThemeFetcherTest { + + private final ReactiveExtensionClient extensionClient = mock(ReactiveExtensionClient.class); + + @Test + void shouldReturnEmptyWhenThemeConfigIsMissing() { + var configMap = new ConfigMap(); + configMap.setData(Map.of()); + when(extensionClient.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)) + .thenReturn(Mono.just(configMap)); + + var themeFetcher = new ThemeFetcher(extensionClient); + + assertThat(themeFetcher.getActiveThemeName().blockOptional()).isEmpty(); + } + + @Test + void shouldReturnEmptyWhenThemeConfigDataIsNull() { + var configMap = new ConfigMap(); + when(extensionClient.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)) + .thenReturn(Mono.just(configMap)); + + var themeFetcher = new ThemeFetcher(extensionClient); + + assertThat(themeFetcher.getActiveThemeName().blockOptional()).isEmpty(); + } + + @Test + void shouldReturnActiveThemeName() { + var configMap = new ConfigMap(); + configMap.setData(Map.of("theme", "{\"active\":\"default\"}")); + when(extensionClient.fetch(ConfigMap.class, SystemSetting.SYSTEM_CONFIG)) + .thenReturn(Mono.just(configMap)); + + var themeFetcher = new ThemeFetcher(extensionClient); + + assertThat(themeFetcher.getActiveThemeName().blockOptional()).contains("default"); + } +}