-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHandlersDefaultExceptionTest.java
More file actions
151 lines (124 loc) · 4.92 KB
/
Copy pathHandlersDefaultExceptionTest.java
File metadata and controls
151 lines (124 loc) · 4.92 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.retailsvc.http;
import static org.assertj.core.api.Assertions.assertThat;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import com.retailsvc.http.spec.HttpMethod;
import com.retailsvc.http.validate.ValidationError;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
class HandlersDefaultExceptionTest {
private static final TypeMapper JSON = new GsonTypeMapper();
private Logger handlersLogger;
private Level originalLevel;
private ListAppender<ILoggingEvent> appender;
@BeforeEach
void attachAppender() {
handlersLogger = (Logger) LoggerFactory.getLogger(Handlers.class);
originalLevel = handlersLogger.getLevel();
handlersLogger.setLevel(Level.DEBUG);
appender = new ListAppender<>();
appender.start();
handlersLogger.addAppender(appender);
}
@AfterEach
void detachAppender() {
handlersLogger.detachAppender(appender);
handlersLogger.setLevel(originalLevel);
}
@Test
void validationExceptionRendersProblemJson() {
Response resp =
Handlers.defaultExceptionHandler()
.handle(
new ValidationException(
new ValidationError("/x", "type", "expected string", null)));
assertThat(resp.status()).isEqualTo(400);
assertThat(resp.contentType()).isEqualTo("application/problem+json");
byte[] bytes = (byte[]) resp.body();
String json = new String(bytes, StandardCharsets.UTF_8);
@SuppressWarnings("unchecked")
Map<String, Object> parsed = (Map<String, Object>) JSON.readFrom(bytes, "application/json");
assertThat(parsed).containsEntry("keyword", "type");
assertThat(((Number) parsed.get("status")).intValue()).isEqualTo(400);
assertThat(json).contains("expected string");
}
@Test
void badRequestExceptionRendersProblemJsonWithCustomStatus() {
Response resp =
Handlers.defaultExceptionHandler()
.handle(new BadRequestException(422, "email taken", "/email", "unique"));
assertThat(resp.status()).isEqualTo(422);
assertThat(resp.contentType()).isEqualTo("application/problem+json");
@SuppressWarnings("unchecked")
Map<String, Object> parsed =
(Map<String, Object>) JSON.readFrom((byte[]) resp.body(), "application/json");
assertThat(((Number) parsed.get("status")).intValue()).isEqualTo(422);
assertThat(parsed)
.containsEntry("title", "Unprocessable Content")
.containsEntry("detail", "email taken")
.containsEntry("pointer", "/email")
.containsEntry("keyword", "unique");
}
@Test
void notFoundReturns404() {
Response resp = Handlers.defaultExceptionHandler().handle(new NotFoundException("GET /x"));
assertThat(resp.status()).isEqualTo(404);
assertThat(resp.body()).isNull();
}
@Test
void methodNotAllowedReturns405WithAllowHeader() {
Response resp =
Handlers.defaultExceptionHandler()
.handle(new MethodNotAllowedException(Set.of(HttpMethod.GET, HttpMethod.POST)));
assertThat(resp.status()).isEqualTo(405);
assertThat(resp.headers()).containsKey("Allow");
assertThat(resp.headers().get("Allow")).contains("GET").contains("POST");
}
@Test
void badRequestCauseLoggedAtDebug() {
Throwable cause = new IllegalStateException("root");
Handlers.defaultExceptionHandler().handle(new BadRequestException("bad", cause));
assertThat(appender.list)
.anySatisfy(
event -> {
assertThat(event.getLevel()).isEqualTo(Level.DEBUG);
assertThat(event.getThrowableProxy().getClassName())
.isEqualTo(IllegalStateException.class.getName());
});
}
@Test
void badRequestWithoutCauseDoesNotLog() {
Handlers.defaultExceptionHandler().handle(new BadRequestException("bad"));
assertThat(appender.list).isEmpty();
}
@Test
void notFoundCauseLoggedAtDebug() {
Throwable cause = new IllegalStateException("root");
Handlers.defaultExceptionHandler().handle(new NotFoundException("missing", cause));
assertThat(appender.list)
.anySatisfy(
event -> {
assertThat(event.getLevel()).isEqualTo(Level.DEBUG);
assertThat(event.getThrowableProxy().getClassName())
.isEqualTo(IllegalStateException.class.getName());
});
}
@Test
void notFoundWithoutCauseDoesNotLog() {
Handlers.defaultExceptionHandler().handle(new NotFoundException("missing"));
assertThat(appender.list).isEmpty();
}
@Test
void unknownExceptionReturns500() {
Response resp = Handlers.defaultExceptionHandler().handle(new RuntimeException("kaboom"));
assertThat(resp.status()).isEqualTo(500);
assertThat(resp.body()).isNull();
}
}