Skip to content

Commit caf5dbf

Browse files
committed
test: Verify string format validation end-to-end via OpenApiServer
Add /format/email and /format/byte operations to openapi.json and openapi.yaml fixtures. Register inline handlers in OpenApiServerIT and add four IT methods covering valid/invalid email and base64 inputs.
1 parent 242c3f4 commit caf5dbf

3 files changed

Lines changed: 174 additions & 0 deletions

File tree

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

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,110 @@ void postBlockedForbiddenTokenReturns400() {
599599
}
600600
}
601601

602+
@Nested
603+
class FormatEmail {
604+
605+
String path = "/format/email";
606+
607+
@Test
608+
void formatEmailShouldReturnBadRequestOnInvalidEmail() {
609+
try (var server =
610+
newServer(Map.of("format-email", exchange -> exchange.sendResponseHeaders(200, -1)));
611+
var client = httpClient()) {
612+
613+
var request = newRequest(server, path + "?addr=not-an-email", "GET", noBody());
614+
615+
var response = client.send(request, BodyHandlers.ofString());
616+
var statusCode = response.statusCode();
617+
var contentType = response.headers().firstValue("Content-Type").orElse("");
618+
var responseBody = response.body();
619+
620+
assertThat(statusCode).isEqualTo(400);
621+
assertThat(contentType).contains("application/problem+json");
622+
assertThat(responseBody).contains("\"format\"");
623+
624+
} catch (IOException e) {
625+
fail(e);
626+
} catch (InterruptedException e) {
627+
Thread.currentThread().interrupt();
628+
fail(e);
629+
}
630+
}
631+
632+
@Test
633+
void formatEmailShouldReturnOkOnValidEmail() {
634+
try (var server =
635+
newServer(Map.of("format-email", exchange -> exchange.sendResponseHeaders(200, -1)));
636+
var client = httpClient()) {
637+
638+
var request = newRequest(server, path + "?addr=user%40example.com", "GET", noBody());
639+
640+
var response = client.send(request, BodyHandlers.ofString());
641+
var statusCode = response.statusCode();
642+
643+
assertThat(statusCode).isEqualTo(200);
644+
645+
} catch (IOException e) {
646+
fail(e);
647+
} catch (InterruptedException e) {
648+
Thread.currentThread().interrupt();
649+
fail(e);
650+
}
651+
}
652+
}
653+
654+
@Nested
655+
class FormatByte {
656+
657+
String path = "/format/byte";
658+
659+
@Test
660+
void formatByteShouldReturnBadRequestOnInvalidBase64() {
661+
try (var server =
662+
newServer(Map.of("format-byte", exchange -> exchange.sendResponseHeaders(200, -1)));
663+
var client = httpClient()) {
664+
665+
var request = newRequest(server, path + "?data=not%20base64!!", "GET", noBody());
666+
667+
var response = client.send(request, BodyHandlers.ofString());
668+
var statusCode = response.statusCode();
669+
var contentType = response.headers().firstValue("Content-Type").orElse("");
670+
var responseBody = response.body();
671+
672+
assertThat(statusCode).isEqualTo(400);
673+
assertThat(contentType).contains("application/problem+json");
674+
assertThat(responseBody).contains("\"format\"");
675+
676+
} catch (IOException e) {
677+
fail(e);
678+
} catch (InterruptedException e) {
679+
Thread.currentThread().interrupt();
680+
fail(e);
681+
}
682+
}
683+
684+
@Test
685+
void formatByteShouldReturnOkOnValidBase64() {
686+
try (var server =
687+
newServer(Map.of("format-byte", exchange -> exchange.sendResponseHeaders(200, -1)));
688+
var client = httpClient()) {
689+
690+
var request = newRequest(server, path + "?data=aGVsbG8%3D", "GET", noBody());
691+
692+
var response = client.send(request, BodyHandlers.ofString());
693+
var statusCode = response.statusCode();
694+
695+
assertThat(statusCode).isEqualTo(200);
696+
697+
} catch (IOException e) {
698+
fail(e);
699+
} catch (InterruptedException e) {
700+
Thread.currentThread().interrupt();
701+
fail(e);
702+
}
703+
}
704+
}
705+
602706
@Nested
603707
class Gates {
604708

src/test/resources/openapi.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,48 @@
251251
"responses": { "200": { "description": "OK" } }
252252
}
253253
},
254+
"/format/email": {
255+
"get": {
256+
"operationId": "format-email",
257+
"parameters": [
258+
{
259+
"in": "query",
260+
"name": "addr",
261+
"required": true,
262+
"schema": {
263+
"type": "string",
264+
"format": "email"
265+
}
266+
}
267+
],
268+
"responses": {
269+
"200": {
270+
"description": "OK"
271+
}
272+
}
273+
}
274+
},
275+
"/format/byte": {
276+
"get": {
277+
"operationId": "format-byte",
278+
"parameters": [
279+
{
280+
"in": "query",
281+
"name": "data",
282+
"required": true,
283+
"schema": {
284+
"type": "string",
285+
"format": "byte"
286+
}
287+
}
288+
],
289+
"responses": {
290+
"200": {
291+
"description": "OK"
292+
}
293+
}
294+
}
295+
},
254296
"/gates": {
255297
"post": {
256298
"operationId": "post-gate",

src/test/resources/openapi.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,34 @@ paths:
177177
"200":
178178
description: OK
179179

180+
/format/email:
181+
get:
182+
operationId: format-email
183+
parameters:
184+
- in: query
185+
name: addr
186+
required: true
187+
schema:
188+
type: string
189+
format: email
190+
responses:
191+
"200":
192+
description: OK
193+
194+
/format/byte:
195+
get:
196+
operationId: format-byte
197+
parameters:
198+
- in: query
199+
name: data
200+
required: true
201+
schema:
202+
type: string
203+
format: byte
204+
responses:
205+
"200":
206+
description: OK
207+
180208
/gates:
181209
post:
182210
operationId: post-gate

0 commit comments

Comments
 (0)