diff --git a/.idea/libraries/junit_jupiter.xml b/.idea/libraries/junit_jupiter.xml
new file mode 100644
index 0000000..7bbe2d4
--- /dev/null
+++ b/.idea/libraries/junit_jupiter.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/mockito_core.xml b/.idea/libraries/mockito_core.xml
new file mode 100644
index 0000000..fa3e0af
--- /dev/null
+++ b/.idea/libraries/mockito_core.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/apiguardian-api-1.1.2.jar b/lib/apiguardian-api-1.1.2.jar
new file mode 100644
index 0000000..2b678e1
Binary files /dev/null and b/lib/apiguardian-api-1.1.2.jar differ
diff --git a/lib/junit-jupiter-5.9.0.jar b/lib/junit-jupiter-5.9.0.jar
new file mode 100644
index 0000000..ba53fad
Binary files /dev/null and b/lib/junit-jupiter-5.9.0.jar differ
diff --git a/lib/junit-jupiter-api-5.9.0.jar b/lib/junit-jupiter-api-5.9.0.jar
new file mode 100644
index 0000000..6f4cc94
Binary files /dev/null and b/lib/junit-jupiter-api-5.9.0.jar differ
diff --git a/lib/junit-jupiter-engine-5.9.0.jar b/lib/junit-jupiter-engine-5.9.0.jar
new file mode 100644
index 0000000..3a116cd
Binary files /dev/null and b/lib/junit-jupiter-engine-5.9.0.jar differ
diff --git a/lib/junit-jupiter-params-5.9.0.jar b/lib/junit-jupiter-params-5.9.0.jar
new file mode 100644
index 0000000..ead9506
Binary files /dev/null and b/lib/junit-jupiter-params-5.9.0.jar differ
diff --git a/lib/junit-platform-commons-1.9.0.jar b/lib/junit-platform-commons-1.9.0.jar
new file mode 100644
index 0000000..5b7a2da
Binary files /dev/null and b/lib/junit-platform-commons-1.9.0.jar differ
diff --git a/lib/junit-platform-engine-1.9.0.jar b/lib/junit-platform-engine-1.9.0.jar
new file mode 100644
index 0000000..5b29d89
Binary files /dev/null and b/lib/junit-platform-engine-1.9.0.jar differ
diff --git a/lib/opentest4j-1.2.0.jar b/lib/opentest4j-1.2.0.jar
new file mode 100644
index 0000000..d500636
Binary files /dev/null and b/lib/opentest4j-1.2.0.jar differ
diff --git a/src/main/java/at/nanopenguin/mtcg/http/Router.java b/src/main/java/at/nanopenguin/mtcg/http/Router.java
index d47cb35..b09daeb 100644
--- a/src/main/java/at/nanopenguin/mtcg/http/Router.java
+++ b/src/main/java/at/nanopenguin/mtcg/http/Router.java
@@ -1,6 +1,7 @@
package at.nanopenguin.mtcg.http;
import at.nanopenguin.mtcg.application.service.Service;
+import lombok.NonNull;
import java.util.*;
import java.util.stream.IntStream;
@@ -8,11 +9,14 @@ import java.util.stream.IntStream;
public class Router {
private final Map> routeMap = new HashMap<>();
- public void addRoute(final HttpMethod method, final String route, final Service service, final int[] pathVars) {
- Map map = this.routeMap.get(method);
- if (method != null && map == null) {
- this.routeMap.put(method, (map = new HashMap<>()));
+ public Router() {
+ for (HttpMethod httpMethod : HttpMethod.values()) {
+ this.routeMap.put(httpMethod, new HashMap<>());
}
+ }
+
+ public void addRoute(@NonNull final HttpMethod method, final String route, final Service service, final int[] pathVars) {
+ Map map = this.routeMap.get(method);
List routeComponents = new ArrayList<>(Arrays.asList(route.split("/")));
for ( Integer pathVarPos : pathVars) {
diff --git a/src/test/java/at/nanopenguin/mtcg/http/RouterTest.java b/src/test/java/at/nanopenguin/mtcg/http/RouterTest.java
new file mode 100644
index 0000000..d7ae726
--- /dev/null
+++ b/src/test/java/at/nanopenguin/mtcg/http/RouterTest.java
@@ -0,0 +1,162 @@
+package at.nanopenguin.mtcg.http;
+
+import at.nanopenguin.mtcg.application.service.Service;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class RouterTest {
+ private static Router router;
+ @BeforeEach
+ void setup() {
+ router = new Router();
+ }
+
+ @Test
+ void simpleRoute() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedService, new int[]{});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ }
+
+ @Test
+ void wrongPath() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedService, new int[]{});
+
+ Assertions.assertNull(router.resolveRoute(HttpMethod.GET, "/different"));
+ }
+
+ @Test
+ void wrongMethod() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedService, new int[]{});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+
+ Assertions.assertNull(router.resolveRoute(HttpMethod.POST, "/get"));
+ Assertions.assertNull(router.resolveRoute(HttpMethod.PUT, "/get"));
+ Assertions.assertNull(router.resolveRoute(HttpMethod.DELETE, "/get"));
+ }
+
+ @Test
+ void differentHttpExists() throws SQLException, JsonProcessingException {
+ Service mockedServiceGet = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedServiceGet, new int[]{});
+
+ Service mockedServicePost = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.POST, "/get", mockedServicePost, new int[]{});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedServiceGet, Mockito.times(1)).handleRequest(null);
+ Mockito.verify(mockedServicePost, Mockito.times(0)).handleRequest(null);
+ }
+
+ @Test
+ void longerPathExists() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedService, new int[]{});
+
+ Service mockedServiceLong = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/long", mockedServiceLong, new int[]{});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ Mockito.verify(mockedServiceLong, Mockito.times(0)).handleRequest(null);
+ }
+
+ @Test
+ void shorterPathExists() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/path", mockedService, new int[]{});
+
+ Service mockedServiceShort = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedServiceShort, new int[]{});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get/path");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ Mockito.verify(mockedServiceShort, Mockito.times(0)).handleRequest(null);
+ }
+
+ @Test
+ void pathWithVar() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/{var}", mockedService, new int[]{2});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get/value");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ }
+
+ @Test
+ void longerPathWithVarExists() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedService, new int[]{});
+
+ Service mockedServiceVar = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/{var}", mockedServiceVar, new int[]{2});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ Mockito.verify(mockedServiceVar, Mockito.times(0)).handleRequest(null);
+ }
+
+ @Test
+ void pathBeforeVarIsValid() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/{var}", mockedService, new int[]{2});
+
+ Service mockedServiceNoVar = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get", mockedServiceNoVar, new int[]{});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get/value");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ Mockito.verify(mockedServiceNoVar, Mockito.times(0)).handleRequest(null);
+ }
+
+ @Test
+ void pathContinuesAfterVar() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/{var}/path", mockedService, new int[]{2});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get/value/path");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ }
+
+ @Test
+ void pathWithTwoVars() throws SQLException, JsonProcessingException {
+ Service mockedService = Mockito.mock(Service.class);
+ router.addRoute(HttpMethod.GET, "/get/{var}/path/{var}", mockedService, new int[]{2, 4});
+
+ Service result = router.resolveRoute(HttpMethod.GET, "/get/value/path/other_value");
+ Assertions.assertNotNull(result);
+ result.handleRequest(null);
+ Mockito.verify(mockedService, Mockito.times(1)).handleRequest(null);
+ }
+}