Skip to content

Commit cf49734

Browse files
thcedclaude
andcommitted
test: Add integration coverage for boolean schemas via /gates
Extend the OpenAPI fixture with a /gates endpoint whose request body uses properties.open: true (any value accepted) and properties.blocked: false (any presence rejected). Two IT cases verify a body with only 'open' returns 200 and a body containing 'blocked' returns 400 with keyword "false" in the problem detail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 46b4df4 commit cf49734

3 files changed

Lines changed: 85 additions & 0 deletions

File tree

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,51 @@ void getPathParams_shouldReturnInternalErrorOnMissingHandler() {
402402
}
403403
}
404404
}
405+
406+
@Nested
407+
class Gates {
408+
409+
String path = "/gates";
410+
411+
@Test
412+
void postGateBodyWithOnlyOpenReturns200() {
413+
try (var server = newServer(Map.of("post-gate", new EchoHandler()));
414+
var client = httpClient()) {
415+
var body = "{\"open\":\"anything\"}";
416+
var request = newRequest(server, path, "POST", ofString(body));
417+
418+
var response = client.send(request, BodyHandlers.ofString());
419+
420+
assertThat(response.statusCode()).isEqualTo(200);
421+
} catch (IOException e) {
422+
fail(e);
423+
} catch (InterruptedException e) {
424+
Thread.currentThread().interrupt();
425+
fail(e);
426+
}
427+
}
428+
429+
@Test
430+
void postGateBodyWithBlockedReturns400() {
431+
try (var server = newServer(Map.of("post-gate", new EchoHandler()));
432+
var client = httpClient()) {
433+
// Even null in 'blocked' triggers the false-schema rejection,
434+
// because NeverSchema rejects every value.
435+
var body = "{\"open\":\"x\",\"blocked\":\"anything\"}";
436+
var request = newRequest(server, path, "POST", ofString(body));
437+
438+
var response = client.send(request, BodyHandlers.ofString());
439+
440+
assertThat(response.statusCode()).isEqualTo(400);
441+
assertThat(response.headers().firstValue("Content-Type").orElse(""))
442+
.contains("application/problem+json");
443+
assertThat(response.body()).contains("false");
444+
} catch (IOException e) {
445+
fail(e);
446+
} catch (InterruptedException e) {
447+
Thread.currentThread().interrupt();
448+
fail(e);
449+
}
450+
}
451+
}
405452
}

src/test/resources/openapi.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,27 @@
179179
"post": {
180180

181181
}
182+
},
183+
"/gates": {
184+
"post": {
185+
"operationId": "post-gate",
186+
"requestBody": {
187+
"required": true,
188+
"content": {
189+
"application/json": {
190+
"schema": {
191+
"type": "object",
192+
"required": ["open"],
193+
"properties": {
194+
"open": true,
195+
"blocked": false
196+
}
197+
}
198+
}
199+
}
200+
},
201+
"responses": { "200": { "description": "OK" } }
202+
}
182203
}
183204
},
184205
"components": {

src/test/resources/openapi.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,23 @@ paths:
115115
/allOf:
116116
post: {}
117117

118+
/gates:
119+
post:
120+
operationId: post-gate
121+
requestBody:
122+
required: true
123+
content:
124+
application/json:
125+
schema:
126+
type: object
127+
required: [open]
128+
properties:
129+
open: true
130+
blocked: false
131+
responses:
132+
"200":
133+
description: OK
134+
118135
components:
119136
parameters:
120137
Name-Header:

0 commit comments

Comments
 (0)