Skip to content

Commit c3fb887

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 e336a36 commit c3fb887

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
@@ -598,4 +598,51 @@ void postBlockedForbiddenTokenReturns400() {
598598
}
599599
}
600600
}
601+
602+
@Nested
603+
class Gates {
604+
605+
String path = "/gates";
606+
607+
@Test
608+
void postGateBodyWithOnlyOpenReturns200() {
609+
try (var server = newServer(Map.of("post-gate", new EchoHandler()));
610+
var client = httpClient()) {
611+
var body = "{\"open\":\"anything\"}";
612+
var request = newRequest(server, path, "POST", ofString(body));
613+
614+
var response = client.send(request, BodyHandlers.ofString());
615+
616+
assertThat(response.statusCode()).isEqualTo(200);
617+
} catch (IOException e) {
618+
fail(e);
619+
} catch (InterruptedException e) {
620+
Thread.currentThread().interrupt();
621+
fail(e);
622+
}
623+
}
624+
625+
@Test
626+
void postGateBodyWithBlockedReturns400() {
627+
try (var server = newServer(Map.of("post-gate", new EchoHandler()));
628+
var client = httpClient()) {
629+
// Any value in 'blocked' triggers the false-schema rejection,
630+
// because NeverSchema rejects every value.
631+
var body = "{\"open\":\"x\",\"blocked\":\"anything\"}";
632+
var request = newRequest(server, path, "POST", ofString(body));
633+
634+
var response = client.send(request, BodyHandlers.ofString());
635+
636+
assertThat(response.statusCode()).isEqualTo(400);
637+
assertThat(response.headers().firstValue("Content-Type").orElse(""))
638+
.contains("application/problem+json");
639+
assertThat(response.body()).contains("\"keyword\":\"false\"");
640+
} catch (IOException e) {
641+
fail(e);
642+
} catch (InterruptedException e) {
643+
Thread.currentThread().interrupt();
644+
fail(e);
645+
}
646+
}
647+
}
601648
}

src/test/resources/openapi.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,27 @@
250250
},
251251
"responses": { "200": { "description": "OK" } }
252252
}
253+
},
254+
"/gates": {
255+
"post": {
256+
"operationId": "post-gate",
257+
"requestBody": {
258+
"required": true,
259+
"content": {
260+
"application/json": {
261+
"schema": {
262+
"type": "object",
263+
"required": ["open"],
264+
"properties": {
265+
"open": true,
266+
"blocked": false
267+
}
268+
}
269+
}
270+
}
271+
},
272+
"responses": { "200": { "description": "OK" } }
273+
}
253274
}
254275
},
255276
"components": {

src/test/resources/openapi.yaml

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

180+
/gates:
181+
post:
182+
operationId: post-gate
183+
requestBody:
184+
required: true
185+
content:
186+
application/json:
187+
schema:
188+
type: object
189+
required: [open]
190+
properties:
191+
open: true
192+
blocked: false
193+
responses:
194+
"200":
195+
description: OK
196+
180197
components:
181198
parameters:
182199
Name-Header:

0 commit comments

Comments
 (0)