Skip to content

Commit e4805b4

Browse files
committed
improved compatibility check in ChangedSchema class for oneOf property changes, added new yamls for tests, added new tests
1 parent a674aa1 commit e4805b4

File tree

6 files changed

+186
-3
lines changed

6 files changed

+186
-3
lines changed

core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,20 @@ private DiffResult calculateCoreChanged() {
177177
&& !discriminatorPropertyChanged) {
178178
return DiffResult.NO_CHANGES;
179179
}
180-
if (changedType) {
181-
if (SCHEMA_TYPE_CHANGED.enabled(context)) {
182-
return DiffResult.INCOMPATIBLE;
180+
if (changedType && SCHEMA_TYPE_CHANGED.enabled(context)) {
181+
if (oldSchema != null && newSchema != null) {
182+
if (context.isResponse() && hasMatchingType(oldSchema.getOneOf(), newSchema.getType())) {
183+
return DiffResult.COMPATIBLE;
184+
}
185+
186+
if (context.isRequest() && hasMatchingType(newSchema.getOneOf(), oldSchema.getType())) {
187+
return DiffResult.COMPATIBLE;
188+
}
183189
}
190+
191+
return DiffResult.INCOMPATIBLE;
184192
}
193+
185194
if (discriminatorPropertyChanged) {
186195
if (SCHEMA_DISCRIMINATOR_CHANGED.enabled(context)) {
187196
return DiffResult.INCOMPATIBLE;
@@ -194,6 +203,14 @@ private DiffResult calculateCoreChanged() {
194203
return DiffResult.COMPATIBLE;
195204
}
196205

206+
@SuppressWarnings("rawtypes")
207+
private boolean hasMatchingType(List<Schema> schemas, String targetType) {
208+
if (schemas == null || targetType == null) {
209+
return false;
210+
}
211+
return schemas.stream().map(Schema::getType).anyMatch(targetType::equals);
212+
}
213+
197214
private boolean compatibleForRequest() {
198215
if (context.isRequest()) {
199216
if (oldSchema == null && newSchema != null) {

core/src/test/java/org/openapitools/openapidiff/core/SchemaDiffTest.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,4 +438,46 @@ public void testAllOfDiff() {
438438
assertThat(changedSchema.getRequired().getMissing()).containsExactly("fieldA");
439439
assertThat(changedSchema.getRequired().getIncreased()).isEmpty();
440440
}
441+
442+
@Test
443+
void testOneOfResponseDiffCompatibleChange() {
444+
ChangedOpenApi changedOpenApi =
445+
OpenApiCompare.fromLocations(
446+
"schemaDiff/issue-798-one-of-response-diff-1.yaml",
447+
"schemaDiff/issue-798-one-of-response-diff-2.yaml");
448+
449+
assertThat(changedOpenApi).isNotNull();
450+
assertThat(changedOpenApi.isChanged()).isEqualTo(DiffResult.COMPATIBLE);
451+
}
452+
453+
@Test
454+
void testOneOfRequestDiffCompatibleChange() {
455+
ChangedOpenApi changedOpenApi =
456+
OpenApiCompare.fromLocations(
457+
"schemaDiff/issue-798-one-of-request-diff-3.yaml",
458+
"schemaDiff/issue-798-one-of-request-diff-4.yaml");
459+
460+
assertThat(changedOpenApi.isChanged()).isEqualTo(DiffResult.COMPATIBLE);
461+
}
462+
463+
@Test
464+
void testOneOfResponseDiffIncompatibleChange() {
465+
ChangedOpenApi changedOpenApi =
466+
OpenApiCompare.fromLocations(
467+
"schemaDiff/issue-798-one-of-response-diff-2.yaml",
468+
"schemaDiff/issue-798-one-of-response-diff-1.yaml");
469+
470+
assertThat(changedOpenApi).isNotNull();
471+
assertThat(changedOpenApi.isChanged()).isEqualTo(DiffResult.INCOMPATIBLE);
472+
}
473+
474+
@Test
475+
void testOneOfRequestDiffIncompatibleChange() {
476+
ChangedOpenApi changedOpenApi =
477+
OpenApiCompare.fromLocations(
478+
"schemaDiff/issue-798-one-of-request-diff-4.yaml",
479+
"schemaDiff/issue-798-one-of-request-diff-3.yaml");
480+
481+
assertThat(changedOpenApi.isChanged()).isEqualTo(DiffResult.INCOMPATIBLE);
482+
}
441483
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
openapi: 3.0.1
2+
info:
3+
title: User Service
4+
version: 1.0.0
5+
paths:
6+
/users:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
type: object
13+
properties:
14+
name:
15+
type: integer
16+
required:
17+
- name
18+
required: true
19+
responses:
20+
201:
21+
description: Created
22+
content:
23+
application/json:
24+
schema:
25+
properties:
26+
id:
27+
type: integer
28+
required:
29+
- id
30+
type: object
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
openapi: 3.0.1
2+
info:
3+
title: User Service
4+
version: 1.0.0
5+
paths:
6+
/users:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
type: object
13+
properties:
14+
name:
15+
oneOf:
16+
- type: integer
17+
- type: string
18+
required:
19+
- name
20+
required: true
21+
responses:
22+
201:
23+
description: Created
24+
content:
25+
application/json:
26+
schema:
27+
properties:
28+
id:
29+
type: integer
30+
required:
31+
- id
32+
type: object
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
openapi: 3.0.1
2+
info:
3+
title: User Service
4+
version: 1.0.0
5+
paths:
6+
/users:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
type: object
13+
properties:
14+
name:
15+
type: integer
16+
required:
17+
- name
18+
required: true
19+
responses:
20+
201:
21+
description: Created
22+
content:
23+
application/json:
24+
schema:
25+
properties:
26+
id:
27+
oneOf:
28+
- type: integer
29+
- type: string
30+
required:
31+
- id
32+
type: object
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
openapi: 3.0.1
2+
info:
3+
title: User Service
4+
version: 1.0.0
5+
paths:
6+
/users:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
type: object
13+
properties:
14+
name:
15+
type: integer
16+
required:
17+
- name
18+
required: true
19+
responses:
20+
201:
21+
description: Created
22+
content:
23+
application/json:
24+
schema:
25+
properties:
26+
id:
27+
type: integer
28+
required:
29+
- id
30+
type: object

0 commit comments

Comments
 (0)