Files
music-metadata-system/src/test/java/com/music/metadata/controller/WebAppControllerTest.java

105 lines
4.0 KiB
Java

package com.music.metadata.controller;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
class WebAppControllerTest {
private final MockMvc mockMvc = MockMvcBuilders
.standaloneSetup(new WebAppController(new DefaultResourceLoader(), "classpath:/test-empty/app/"))
.build();
private final MockMvc packagedFrontendMockMvc = MockMvcBuilders
.standaloneSetup(new WebAppController(new DefaultResourceLoader(), "classpath:/test-static/app/"))
.build();
@Test
void shouldForwardAppEntryToIndex() throws Exception {
mockMvc.perform(get("/app/"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("/app/index.html"));
}
@Test
void shouldForwardNestedSpaRoutesToIndex() throws Exception {
mockMvc.perform(get("/app/tasks"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("/app/index.html"));
}
@Test
void shouldForwardDeepNestedSpaRoutesToIndex() throws Exception {
mockMvc.perform(get("/app/system/config/editor/advanced/theme"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("/app/index.html"));
}
@Test
void shouldReturnNotFoundForAppIndexWhenFrontendIsNotPackaged() throws Exception {
mockMvc.perform(get("/app/index.html"))
.andExpect(status().isNotFound());
}
@Test
void shouldServePackagedAppIndexWhenFrontendExistsOnClasspath() throws Exception {
packagedFrontendMockMvc.perform(get("/app/index.html"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML))
.andExpect(header().string("Content-Type", org.hamcrest.Matchers.containsString("text/html")));
}
@Test
void shouldServePackagedAssetWhenFrontendExistsOnClasspath() throws Exception {
packagedFrontendMockMvc.perform(get("/app/assets/main.js"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.valueOf("application/javascript")));
}
@Test
void shouldServePackagedTopLevelStaticFileWhenFrontendExistsOnClasspath() throws Exception {
packagedFrontendMockMvc.perform(get("/app/favicon.ico"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.valueOf("image/x-icon")));
}
@Test
void shouldNotForwardMissingStaticAssetRequests() throws Exception {
mockMvc.perform(get("/app/assets/missing.js"))
.andExpect(status().isNotFound());
}
@Test
void shouldAllowDottedClientSegmentsToUseSpaFallback() throws Exception {
mockMvc.perform(get("/app/releases/v1.0.0"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("/app/index.html"));
}
@Test
void shouldTreatTerminalFileNamesAsStaticAssetRequests() throws Exception {
mockMvc.perform(get("/app/assets/main.js"))
.andExpect(status().isNotFound());
}
@Test
void shouldRejectTraversalLikeStaticAssetPaths() throws Exception {
mockMvc.perform(get("/app/assets/../index.html"))
.andExpect(status().isNotFound());
}
@Test
void shouldForwardClientRoutesBeyondFiveSegmentsToIndex() throws Exception {
mockMvc.perform(get("/app/a/b/c/d/e/f/g"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("/app/index.html"));
}
}