Skip to content

Commit baf0175

Browse files
committed
Added more test cases for generating server sent event endpoints. The ones failing or crashing the generator are ignored for the moment.
1 parent 7f25af0 commit baf0175

File tree

5 files changed

+342
-50
lines changed

5 files changed

+342
-50
lines changed

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java

Lines changed: 122 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
import static java.util.stream.Collectors.groupingBy;
6060
import static org.assertj.core.api.Assertions.assertThat;
61+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
6162
import static org.openapitools.codegen.TestUtils.*;
6263
import static org.openapitools.codegen.languages.AbstractJavaCodegen.GENERATE_BUILDERS;
6364
import static org.openapitools.codegen.languages.AbstractJavaCodegen.GENERATE_CONSTRUCTOR_WITH_ALL_ARGS;
@@ -4476,46 +4477,140 @@ public void multiLineTagDescription() throws IOException {
44764477

44774478
@Test
44784479
public void testSSEOperationSupport() throws Exception {
4479-
Map<String, Object> additionalProperties = Map.of(SSE, true, REACTIVE, "true", INTERFACE_ONLY, "false",
4480-
DELEGATE_PATTERN, "true");
4480+
Map<String, Object> additionalProperties = Map.of(
4481+
SSE, true,
4482+
REACTIVE, "true",
4483+
INTERFACE_ONLY, "false",
4484+
DELEGATE_PATTERN, "true"
4485+
);
44814486
Map<String, File> files = generateFromContract("src/test/resources/3_0/sse.yaml", "spring-boot", additionalProperties);
44824487

44834488
MapAssert.assertThatMap(files).isNotEmpty();
44844489
File api = files.get("PathApi.java");
44854490
File delegate = files.get("PathApiDelegate.java");
44864491

44874492
JavaFileAssert.assertThat(api)
4488-
.assertMethod("sseVariant1", "ServerWebExchange")
4489-
.isNotNull()
4490-
.hasReturnType("Flux<String>")
4491-
.toFileAssert()
4492-
.assertMethod("sseVariant2", "ServerWebExchange")
4493-
.isNotNull()
4494-
.hasReturnType("Flux<EventType>")
4495-
.toFileAssert()
4496-
.assertMethod("nonSSE", "ServerWebExchange")
4497-
.isNotNull()
4498-
.hasReturnType("Mono<ResponseEntity<String>>");
4493+
.assertMethod("sse1", "ServerWebExchange")
4494+
.hasReturnType("Flux<String>")
4495+
.toFileAssert()
4496+
.assertMethod("sse2", "ServerWebExchange")
4497+
.hasReturnType("Flux<EventType>")
4498+
.toFileAssert()
4499+
// FIXME: Generator Crash
4500+
// .assertMethod("sse3", "ServerWebExchange")
4501+
// .hasReturnType("Flux<String>")
4502+
// .toFileAssert()
4503+
.assertMethod("sse4", "ServerWebExchange")
4504+
.hasReturnType("Flux<String>")
4505+
.toFileAssert()
4506+
// FIXME: Generator Crash, see #17271
4507+
// .assertMethod("sse5", "ServerWebExchange")
4508+
// .hasReturnType("Flux<EventType>")
4509+
// .toFileAssert()
4510+
4511+
// FIXME: Generator Crash
4512+
// .assertMethod("notSse1", "ServerWebExchange")
4513+
// .hasReturnType("Mono<ResponseEntity<Void>>")
4514+
// .toFileAssert()
4515+
// FIXME: Generator Crash
4516+
// .assertMethod("notSse2", "ServerWebExchange")
4517+
// .hasReturnType("Mono<ResponseEntity<Flux<String>>>")
4518+
// .toFileAssert()
4519+
.assertMethod("notSse3", "ServerWebExchange")
4520+
.hasReturnType("Mono<ResponseEntity<String>>")
4521+
.toFileAssert()
4522+
.assertMethod("notSse5", "ServerWebExchange")
4523+
.hasReturnType("Mono<ResponseEntity<Void>>")
4524+
.toFileAssert()
4525+
.assertMethod("notSse7", "ServerWebExchange")
4526+
.hasReturnType("Mono<ResponseEntity<String>>")
4527+
.toFileAssert()
4528+
// FIXME: Generator Crash
4529+
// .assertMethod("notSse8", "ServerWebExchange")
4530+
// .hasReturnType("Mono<ResponseEntity<String>>")
4531+
;
44994532

45004533
JavaFileAssert.assertThat(delegate)
4501-
.assertMethod("sseVariant1", "ServerWebExchange")
4502-
.isNotNull()
4503-
.hasReturnType("Flux<String>")
4504-
.bodyContainsLines("return Flux.empty();")
4505-
.toFileAssert()
4506-
.assertMethod("sseVariant2", "ServerWebExchange")
4507-
.isNotNull()
4508-
.hasReturnType("Flux<EventType>")
4509-
.bodyContainsLines("return Flux.empty();")
4510-
.toFileAssert()
4511-
.assertMethod("nonSSE", "ServerWebExchange")
4512-
.isNotNull()
4513-
.hasReturnType("Mono<ResponseEntity<String>>")
4514-
.bodyContainsLines("return result.then(Mono.empty());")
4534+
.assertMethod("sse1", "ServerWebExchange")
4535+
.hasReturnType("Flux<String>")
4536+
.bodyContainsLines("return Flux.empty();")
4537+
.toFileAssert()
4538+
.assertMethod("sse2", "ServerWebExchange")
4539+
.hasReturnType("Flux<EventType>")
4540+
.bodyContainsLines("return Flux.empty();")
4541+
.toFileAssert()
4542+
// FIXME: Generator Crash
4543+
// .assertMethod("sse3", "ServerWebExchange")
4544+
// .hasReturnType("Flux<String>")
4545+
// .bodyContainsLines("return Flux.empty();")
4546+
// .toFileAssert()
4547+
.assertMethod("sse4", "ServerWebExchange")
4548+
.hasReturnType("Flux<String>")
4549+
.bodyContainsLines("return Flux.empty();")
4550+
.toFileAssert()
4551+
// FIXME: Generator Crash
4552+
// .assertMethod("sse5", "ServerWebExchange")
4553+
// .hasReturnType("Flux<String>")
4554+
// .bodyContainsLines("return Flux.empty();")
4555+
// .toFileAssert()
4556+
4557+
// FIXME: Generator Crash
4558+
// .assertMethod("notSse1", "ServerWebExchange")
4559+
// .hasReturnType("Mono<ResponseEntity<Void>>")
4560+
// .bodyContainsLines("return result.then(Mono.empty());")
4561+
// .toFileAssert()
4562+
// FIXME: Generator Crash
4563+
// .assertMethod("notSse2", "ServerWebExchange")
4564+
// .hasReturnType("Mono<ResponseEntity<Flux<String>>>")
4565+
// .bodyContainsLines("return result.then(Mono.empty());")
4566+
// .toFileAssert()
4567+
.assertMethod("notSse3", "ServerWebExchange")
4568+
.hasReturnType("Mono<ResponseEntity<String>>")
4569+
.bodyContainsLines("return result.then(Mono.empty());")
4570+
.toFileAssert()
4571+
.assertMethod("notSse5", "ServerWebExchange")
4572+
.hasReturnType("Mono<ResponseEntity<Void>>")
4573+
.bodyContainsLines("return result.then(Mono.empty());")
4574+
.toFileAssert()
4575+
.assertMethod("notSse7", "ServerWebExchange")
4576+
.hasReturnType("Mono<ResponseEntity<String>>")
4577+
.bodyContainsLines("return result.then(Mono.empty());")
4578+
.toFileAssert()
4579+
// FIXME: Generator Crash
4580+
// .assertMethod("notSse8", "ServerWebExchange")
4581+
// .hasReturnType("Mono<ResponseEntity<String>>")
4582+
// .bodyContainsLines("return result.then(Mono.empty());")
45154583
;
45164584

45174585
}
45184586

4587+
@DataProvider(name = "invalid sse endpoints")
4588+
public static Object[][] specsWithInvalidSSEEndpoints() {
4589+
return new Object[][] {
4590+
{"sse_but_missing_format.yaml", "schema format 'event-stream' is required, when SSE is detected"},
4591+
// FIXME: spec does not generate correct code, but not detected
4592+
// {"sse_but_multiple_media_types.yaml", "only 1 response media type supported, when SSE is detected"},
4593+
{"sse_but_incompatible_item_types.yaml", "only single item type is supported, when SSE is detected"}
4594+
};
4595+
}
4596+
4597+
@Test(dataProvider = "invalid sse endpoints")
4598+
public void testSSEOperationSupport_forInvalidSSEEndpointSpecs(String inputSpec, String expectedError) {
4599+
// checks the design decision, that if the specs looks like it should be an SSE endpoint but it is not
4600+
// matching the required format, an exception is thrown containing a descriptive error message
4601+
Map<String, Object> additionalProperties = Map.of(
4602+
SSE, true,
4603+
REACTIVE, "true",
4604+
INTERFACE_ONLY, "false",
4605+
DELEGATE_PATTERN, "true"
4606+
);
4607+
String input = "src/test/resources/3_0/" + inputSpec;
4608+
assertThatThrownBy(() -> generateFromContract(input, "spring-boot", additionalProperties))
4609+
.rootCause()
4610+
.isInstanceOf(RuntimeException.class)
4611+
.hasMessage(expectedError);
4612+
}
4613+
45194614
@Test
45204615
public void givenMultipartForm_whenGenerateReactiveServer_thenParameterAreCreatedAsRequestPart() throws IOException {
45214616
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();

modules/openapi-generator/src/test/resources/3_0/sse.yaml

Lines changed: 129 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,165 @@ info:
44
description: SSE test cases
55
version: 1.0.0
66
servers:
7-
- url: 'https'
7+
- url: 'https://'
88
tags:
99
- name: sse
1010
paths:
11-
/path/variant1:
12-
post:
13-
operationId: sseVariant1
14-
tags:
15-
- sse
11+
/path/sse/1:
12+
get:
13+
operationId: sse_1
1614
responses:
17-
'200':
18-
description: acknowledged
15+
"200":
16+
description: easiest case
1917
content:
2018
text/event-stream:
2119
schema:
2220
type: array
2321
format: event-stream
2422
items:
2523
type: string
26-
/path/variant2:
27-
post:
28-
operationId: sseVariant2
29-
tags:
30-
- sse
24+
/path/sse/2:
25+
get:
26+
operationId: sse_2
3127
responses:
32-
'200':
33-
description: acknowledged
28+
"200":
29+
description: using reference for array items
3430
content:
3531
text/event-stream:
3632
schema:
3733
type: array
3834
format: event-stream
3935
items:
40-
$ref: '#/components/schemas/EventType'
41-
/path/variant3:
42-
post:
43-
operationId: nonSSE
44-
tags:
45-
- sse
36+
$ref: "#/components/schemas/EventType"
37+
# FIXME: Generator Crash
38+
# /path/sse/3:
39+
# get:
40+
# operationId: sse_3
41+
# responses:
42+
# "200":
43+
# description: using reference for schema
44+
# content:
45+
# text/event-stream:
46+
# schema:
47+
# $ref: "#/components/schemas/EventTypeStream"
48+
/path/sse/4:
49+
get:
50+
operationId: sse_4
51+
responses:
52+
"200":
53+
$ref: "#/components/responses/EventTypeResponse"
54+
# FIXME: generator crash
55+
# /path/sse/5:
56+
# post:
57+
# operationId: sse_5
58+
# description: indirect references, see Issue 17271
59+
# responses:
60+
# '200':
61+
# $ref: '#/components/responses/EventTypeResponseWithReference'
62+
63+
# FIXME: generator crash
64+
# /path/notsse/1:
65+
# get:
66+
# operationId: not_sse_1
67+
# responses:
68+
# '200':
69+
# description: no schema defined, but this is a valid OpenAPI Specification
70+
# FIXME: generator crash
71+
# /path/notsse/2:
72+
# get:
73+
# operationId: not_sse_2
74+
# responses:
75+
# '200':
76+
# description: wrong media type
77+
# content:
78+
# application/json:
79+
# schema:
80+
# type: array
81+
# format: event-stream
82+
# items:
83+
# type: string
84+
/path/notsse/3:
85+
get:
86+
operationId: not_sse_3
4687
responses:
4788
'200':
48-
description: acknowledged
89+
description: schema not of type array
4990
content:
5091
text/event-stream:
5192
schema:
5293
type: string
5394
format: event-stream
95+
/path/notsse/5:
96+
get:
97+
operationId: not_sse_5
98+
responses:
99+
'400':
100+
description: sse only intended for success status codes not for errors
101+
content:
102+
text/event-stream:
103+
schema:
104+
type: array
105+
format: event-stream
106+
items:
107+
type: string
108+
/path/notsse/7:
109+
get:
110+
operationId: not_sse_7
111+
description: referenced response object does not match
112+
responses:
113+
'200':
114+
$ref: "#/components/responses/NotAStreamResponse"
115+
# FIXME: Generator Crashed
116+
# /path/notsse/8:
117+
# get:
118+
# operationId: not_sse_8
119+
# responses:
120+
# "200":
121+
# description: referenced schema does not match
122+
# content:
123+
# text/event-stream:
124+
# schema:
125+
# $ref: "#/components/schemas/NotAStreamType"
126+
54127
components:
55128
schemas:
56129
EventType:
57130
type: object
58131
properties:
59132
attribute1:
60133
type: string
134+
EventTypeStream:
135+
type: array
136+
format: event-stream
137+
items:
138+
type: string
139+
NotAStreamType:
140+
type: string
141+
format: event-stream
142+
143+
144+
responses:
145+
EventTypeResponse:
146+
description: response
147+
content:
148+
text/event-stream:
149+
schema:
150+
type: array
151+
format: event-stream
152+
items:
153+
type: string
154+
155+
EventTypeResponseWithReference:
156+
description: acknowledged
157+
content:
158+
text/event-stream:
159+
schema:
160+
$ref: '#/components/schemas/EventTypeStream'
61161

62-
162+
NotAStreamResponse:
163+
description: response
164+
content:
165+
text/event-stream:
166+
schema:
167+
type: string
168+
format: event-stream

0 commit comments

Comments
 (0)