Skip to content

Commit 58ac1de

Browse files
committed
test: Cover CORS preflight rejection paths
1 parent af63f22 commit 58ac1de

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

src/test/java/com/retailsvc/http/CorsPreflightHandlerTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
import static com.retailsvc.http.spec.HttpMethod.OPTIONS;
66
import static com.retailsvc.http.spec.HttpMethod.POST;
77
import static com.retailsvc.http.spec.HttpMethod.PUT;
8+
import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
9+
import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
810
import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
911
import static org.assertj.core.api.Assertions.assertThat;
12+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1013

1114
import com.retailsvc.http.spec.HttpMethod;
1215
import java.time.Duration;
@@ -96,4 +99,72 @@ void corsPreflightHandlerOmitsAllowHeadersWhenListEmpty() {
9699
assertThat(resp.headers()).doesNotContainKey("Access-Control-Allow-Headers");
97100
assertThat(resp.status()).isEqualTo(HTTP_NO_CONTENT);
98101
}
102+
103+
@Test
104+
void corsPreflightHandlerRejectsNonOptionsWith405AndAllowOptions() {
105+
RequestHandler handler = Handlers.corsPreflightHandler(ORIGINS, METHODS, HEADERS, false, null);
106+
107+
Response resp = handler.handle(bare(GET));
108+
109+
assertThat(resp.status()).isEqualTo(HTTP_BAD_METHOD);
110+
assertThat(resp.headers()).containsEntry("Allow", "OPTIONS");
111+
}
112+
113+
@Test
114+
void corsPreflightHandlerRejectsMissingOriginWith400() {
115+
RequestHandler handler = Handlers.corsPreflightHandler(ORIGINS, METHODS, HEADERS, false, null);
116+
117+
assertThatThrownBy(() -> handler.handle(preflight(null, "POST", "content-type")))
118+
.isInstanceOf(BadRequestException.class)
119+
.hasMessageContaining("Origin");
120+
}
121+
122+
@Test
123+
void corsPreflightHandlerRejectsMissingRequestMethodWith400() {
124+
RequestHandler handler = Handlers.corsPreflightHandler(ORIGINS, METHODS, HEADERS, false, null);
125+
126+
assertThatThrownBy(
127+
() -> handler.handle(preflight("https://app.example.com", null, "content-type")))
128+
.isInstanceOf(BadRequestException.class)
129+
.hasMessageContaining("Access-Control-Request-Method");
130+
}
131+
132+
@Test
133+
void corsPreflightHandlerRejectsDisallowedOriginWith403() {
134+
RequestHandler handler = Handlers.corsPreflightHandler(ORIGINS, METHODS, HEADERS, false, null);
135+
136+
Response resp = handler.handle(preflight("https://evil.example.com", "POST", "content-type"));
137+
138+
assertThat(resp.status()).isEqualTo(HTTP_FORBIDDEN);
139+
assertThat(resp.headers()).doesNotContainKey("Access-Control-Allow-Origin");
140+
}
141+
142+
@Test
143+
void corsPreflightHandlerRejectsDisallowedMethodWith403() {
144+
RequestHandler handler =
145+
Handlers.corsPreflightHandler(ORIGINS, List.of(GET), HEADERS, false, null);
146+
147+
Response resp = handler.handle(preflight("https://app.example.com", "DELETE", "content-type"));
148+
149+
assertThat(resp.status()).isEqualTo(HTTP_FORBIDDEN);
150+
}
151+
152+
@Test
153+
void corsPreflightHandlerRejectsDisallowedHeaderWith403() {
154+
RequestHandler handler =
155+
Handlers.corsPreflightHandler(ORIGINS, METHODS, List.of("content-type"), false, null);
156+
157+
Response resp = handler.handle(preflight("https://app.example.com", "POST", "x-secret"));
158+
159+
assertThat(resp.status()).isEqualTo(HTTP_FORBIDDEN);
160+
}
161+
162+
@Test
163+
void corsPreflightHandlerRejectsUnknownMethodTokenWith403() {
164+
RequestHandler handler = Handlers.corsPreflightHandler(ORIGINS, METHODS, HEADERS, false, null);
165+
166+
Response resp = handler.handle(preflight("https://app.example.com", "BOGUS", "content-type"));
167+
168+
assertThat(resp.status()).isEqualTo(HTTP_FORBIDDEN);
169+
}
99170
}

0 commit comments

Comments
 (0)