Skip to content

Commit

Permalink
refactor fallback away from GlobalExceptionHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulKreft committed Feb 28, 2024
1 parent 3472616 commit 1ff950a
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,14 @@
package de.neuefische.paulkreft.backend.exception;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.NoResourceFoundException;

@ControllerAdvice
public class GlobalExceptionHandler {
private final String environment;

public GlobalExceptionHandler(@Value("${app.environment}") String environment) {
this.environment = environment;
}

@ExceptionHandler({NoResourceFoundException.class})
public ModelAndView noResourceFoundHandler(NoResourceFoundException e) {
String basePath = environment.equals("production") ? "/" : "http://localhost:5173/";
String route = environment.equals("production") ? "" : e.getResourcePath();
return new ModelAndView("redirect:" + basePath + route);
}

@ExceptionHandler({EmailAlreadyRegisteredException.class})
@ResponseStatus(HttpStatus.CONFLICT)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package de.neuefische.paulkreft.backend.fallback;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;

import java.io.IOException;

@Configuration
public class Fallback implements WebMvcConfigurer {

public static final String DEFAULT_STARTING_PAGE = "static/index.html";

static class ReactRoutingPathResourceResolver extends PathResourceResolver {
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
var requestedResource = location.createRelative(resourcePath);

// Is this a request to a real file?
if (requestedResource.exists() && requestedResource.isReadable()) {
return requestedResource;
}

// It seems to be only a frontend-routing request (Single-Page-Application).
return new ClassPathResource(DEFAULT_STARTING_PAGE);
}
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new ReactRoutingPathResourceResolver());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package de.neuefische.paulkreft.backend.fallback;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class FallbackTest {

@Test
void expectRelativeResource_ifItExists() throws IOException {

// GIVEN
var resolver = new Fallback.ReactRoutingPathResourceResolver();
var location = mock(Resource.class);
var relativeLocation = mock(Resource.class);
var resourcePath = "index.html";
when(location.createRelative(resourcePath)).thenReturn(relativeLocation);
when(relativeLocation.exists()).thenReturn(true);
when(relativeLocation.isReadable()).thenReturn(true);

// WHEN
var actual = resolver.getResource(resourcePath, location);

// THEN
Assertions.assertEquals(relativeLocation, actual);
}

@Test
void expectIndexHtml_ifRequestedResourceDoesNotExist() throws IOException {

// GIVEN
var resolver = new Fallback.ReactRoutingPathResourceResolver();
var location = mock(Resource.class);
var relativeLocation = mock(Resource.class);
var resourcePath = "index.html";
when(location.createRelative(resourcePath)).thenReturn(relativeLocation);
when(relativeLocation.exists()).thenReturn(false);

// WHEN
var actual = resolver.getResource(resourcePath, location);

// THEN
ClassPathResource expected = new ClassPathResource("static/index.html");
Assertions.assertEquals(expected, actual);
}

}

0 comments on commit 1ff950a

Please sign in to comment.