Repository navigation
Expand file tree
/
Copy pathWebHandlerTest.java
More file actions
110 lines (99 loc) · 5 KB
/
Copy pathWebHandlerTest.java
File metadata and controls
110 lines (99 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package demo;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
class WebHandlerTest {
@ParameterizedTest
@ValueSource(strings = {"/", "/create", "/multiple", "/delete", "/audit"})
void dispatchesOnlyTheMatchingRouteAndPreservesTheResponse(String path) {
var input = request(path, "GET").withQueryStringParameters(Map.of("example", "value"));
var expected = new APIGatewayProxyResponseEvent()
.withStatusCode(path.equals("/") ? 200 : 307)
.withHeaders(Map.of("Location", "/", "Cache-Control", "no-cache"))
.withBody("response");
var calls = new AtomicInteger();
Map<String, RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent>> routes = new HashMap<>();
for (String route : new String[]{"/", "/create", "/multiple", "/delete", "/audit"}) {
routes.put(route, (event, context) -> {
assertEquals(path, route, "Must not invoke a different action");
assertSame(input, event, "Forward the complete request without rebuilding it");
calls.incrementAndGet();
return expected;
});
}
assertSame(expected, new WebHandler(routes).handleRequest(input, null));
assertEquals(1, calls.get());
}
@ParameterizedTest
@ValueSource(strings = {"/missing", "/create/extra", "/CREATE", "/create/"})
void unknownPathsNeverReachAnAction(String path) {
// Construct the actual production router offline: no DB connection or AWS call is needed.
assertEquals(404, new WebHandler().handleRequest(request(path, "GET"), null).getStatusCode());
}
@ParameterizedTest
@ValueSource(strings = {"POST", "PUT", "DELETE", "HEAD", "OPTIONS"})
void rejectsOtherMethodsBeforeAnActionCanWrite(String method) {
var response = new WebHandler().handleRequest(request("/create", method), null);
assertEquals(405, response.getStatusCode());
assertEquals("GET", response.getHeaders().get("Allow"));
}
@Test
void rejectsIncompleteRequests() {
var handler = new WebHandler();
assertEquals(400, handler.handleRequest(null, null).getStatusCode());
assertEquals(400, handler.handleRequest(request(null, "GET"), null).getStatusCode());
assertEquals(400, handler.handleRequest(request("/create", null), null).getStatusCode());
}
@Test
void warmRequestsDoNotReuseThePreviousRouteOrResponse() {
var handler = new WebHandler(Map.of(
"/", (event, context) -> new APIGatewayProxyResponseEvent().withStatusCode(200).withBody("home"),
"/create", (event, context) -> new APIGatewayProxyResponseEvent().withStatusCode(307).withHeaders(Map.of("Location", "/"))));
assertEquals("home", handler.handleRequest(request("/", "GET"), null).getBody());
var redirect = handler.handleRequest(request("/create", "GET"), null);
assertEquals(307, redirect.getStatusCode());
assertNull(redirect.getBody());
var homeAgain = handler.handleRequest(request("/", "GET"), null);
assertEquals(200, homeAgain.getStatusCode());
assertNull(homeAgain.getHeaders());
}
@Test
void existingActionStillRedirectsAfterExactlyOneWrite() {
var calls = new AtomicInteger();
var action = new AbstractActionFrontEnd() {
@Override
protected void performAction() {
calls.incrementAndGet();
}
};
var handler = new WebHandler(Map.of("/create", action));
var response = handler.handleRequest(request("/create", "GET"), null);
assertEquals(1, calls.get());
assertEquals(307, response.getStatusCode());
assertEquals("/", response.getHeaders().get("Location"));
assertEquals("no-cache", response.getHeaders().get("Cache-Control"));
}
@Test
void existingActionFailureRemainsAnErrorResponse() {
var action = new AbstractActionFrontEnd() {
@Override
protected void performAction() {
throw new IllegalStateException("test database failure");
}
};
var response = new WebHandler(Map.of("/create", action))
.handleRequest(request("/create", "GET"), null);
assertEquals(500, response.getStatusCode());
assertTrue(response.getBody().contains("test database failure"));
}
private static APIGatewayProxyRequestEvent request(String path, String method) {
return new APIGatewayProxyRequestEvent().withPath(path).withHttpMethod(method);
}
}