Skip to content

Commit

Permalink
feat: better handling of enum changes based on direction
Browse files Browse the repository at this point in the history
| Enum Change   | In Request (path/query/body) | In Response (body) | In Both  |
|---------------|------------------------------|--------------------|----------|
| Value Added   | OK                           | Breaking           | Breaking |
| Value Removed | Breaking                     | OK                 | Breaking |
  • Loading branch information
NextFire committed Jul 10, 2024
1 parent 962f5b0 commit 5a0f306
Show file tree
Hide file tree
Showing 21 changed files with 926 additions and 51 deletions.
92 changes: 92 additions & 0 deletions src/Criteo.OpenApi.Comparator.UTest/OpenApiEnumDirectionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) Criteo Technology. All rights reserved.
// Licensed under the Apache 2.0 License. See LICENSE in the project root for license information.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Criteo.OpenApi.Comparator.Logging;
using NUnit.Framework;

namespace Criteo.OpenApi.Comparator.UTest;

[TestFixture]
public class OpenApiEnumDirectionTests
{
[TestCase("old_without_refs", "path_add", "#/paths/~1order~1{path}/post/parameters/0/schema/enum")]
[TestCase("old_without_refs", "query_add", "#/paths/~1order~1{path}/post/parameters/1/schema/enum")]
[TestCase("old_without_refs", "body_add", "#/paths/~1order~1{path}/post/requestBody/content/application~1json/schema/properties/foo/enum")]
[TestCase("old_with_refs", "request_ref_add", "#/paths/~1order~1{path}/post/parameters/0/schema/enum")]
public void CompareOAS_ShouldReturn_NonBreaking_AddedEnumValueChange(string oldName, string newName, string jsonRef, int expectedDifferencesCount = 1)
{
var differences = CompareSpecifications(oldName, newName);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.AddedEnumValue,
Severity = Severity.Warning,
NewJsonRef = jsonRef
}, expectedDifferencesCount);
}


[TestCase("old_without_refs", "response_add", "#/paths/~1order~1{path}/post/responses/200/content/application~1json/schema/properties/bar/enum")]
[TestCase("old_with_refs", "response_ref_add", "#/paths/~1order~1{path}/post/responses/200/content/application~1json/schema/properties/bar/enum")]
[TestCase("old_with_refs", "both_ref_add", "#/paths/~1order~1{path}/post/responses/200/content/application~1json/schema/properties/foo/enum", 2)]
public void CompareOAS_ShouldReturn_Breaking_AddedEnumValueChange(string oldName, string newName, string jsonRef, int expectedDifferencesCount = 1)
{
var differences = CompareSpecifications(oldName, newName);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.AddedEnumValue,
Severity = Severity.Error,
NewJsonRef = jsonRef
}, expectedDifferencesCount);
}

[TestCase("old_without_refs", "response_remove", "#/paths/~1order~1{path}/post/responses/200/content/application~1json/schema/properties/bar/enum")]
[TestCase("old_with_refs", "response_ref_remove", "#/paths/~1order~1{path}/post/responses/200/content/application~1json/schema/properties/bar/enum")]
public void CompareOAS_ShouldReturn_NonBreaking_RemovedEnumValueChange(string oldName, string newName, string jsonRef, int expectedDifferencesCount = 1)
{
var differences = CompareSpecifications(oldName, newName);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.RemovedEnumValue,
Severity = Severity.Warning,
NewJsonRef = jsonRef
}, expectedDifferencesCount);
}

[TestCase("old_without_refs", "path_remove", "#/paths/~1order~1{path}/post/parameters/0/schema/enum")]
[TestCase("old_without_refs", "query_remove", "#/paths/~1order~1{path}/post/parameters/1/schema/enum")]
[TestCase("old_without_refs", "body_remove", "#/paths/~1order~1{path}/post/requestBody/content/application~1json/schema/properties/foo/enum")]
[TestCase("old_with_refs", "request_ref_remove", "#/paths/~1order~1{path}/post/parameters/0/schema/enum")]
[TestCase("old_with_refs", "both_ref_remove", "#/paths/~1order~1{path}/post/requestBody/content/application~1json/schema/properties/foo/enum")]
public void CompareOAS_ShouldReturn_Breaking_RemovedEnumValueChange(string oldName, string newName, string jsonRef, int expectedDifferencesCount = 1)
{
var differences = CompareSpecifications(oldName, newName);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.RemovedEnumValue,
Severity = Severity.Error,
NewJsonRef = jsonRef,
}, expectedDifferencesCount);
}

private static IList<ComparisonMessage> CompareSpecifications(string oldName, string newName)
{
var baseDirectory = Directory
.GetParent(typeof(OpenApiSpecificationsCompareTests).GetTypeInfo().Assembly.Location)
.ToString();

var oldFileName = Path.Combine(baseDirectory, "Resource", "enum_direction", oldName + ".json");
var newFileName = Path.Combine(baseDirectory, "Resource", "enum_direction", newName + ".yaml");

var differences = OpenApiComparator
.Compare(File.ReadAllText(oldFileName), File.ReadAllText(newFileName), strict: true)
.ToList();

OpenApiSpecificationsCompareTests.ValidateDifferences(differences);

return differences;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,12 @@ public void CompareOAS_ShouldReturn_RemovedEnumValueDifferences()
Rule = ComparisonRules.RemovedEnumValue,
Severity = Severity.Warning,
OldJsonRef = "#/paths/~1api~1Parameters/put/parameters/0/schema/enum"
}, 2);
}, 3);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.ConstraintIsStronger,
Severity = Severity.Info,
}, 2);
}, 3);
}

[Test]
Expand All @@ -333,12 +333,12 @@ public void CompareOAS_ShouldReturn_AddedEnumValueDifferences()
Rule = ComparisonRules.AddedEnumValue,
Severity = Severity.Warning,
NewJsonRef = "#/paths/~1api~1Parameters/put/responses/200/content/application~1json/schema/properties/petType/enum"
}, 1);
}, 2);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.ConstraintIsWeaker,
Severity = Severity.Info,
}, 2);
}, 4);
}

[Test]
Expand Down Expand Up @@ -627,12 +627,12 @@ public void CompareOAS_ShouldReturn_OneMessagePerRule_When_RecursiveModel()
Rule = ComparisonRules.RemovedProperty,
Severity = Severity.Warning,
OldJsonRef = "#/paths/~1api~1Operations/post/parameters/0/schema/properties/error/properties/target"
}, 1);
}, 2);
differences.AssertContains(new ExpectedDifference
{
Rule = ComparisonRules.ReadonlyPropertyChanged,
Severity = Severity.Warning,
}, 1);
}, 2);
}

[Test]
Expand Down Expand Up @@ -859,7 +859,7 @@ private static void ValidateMessage(ComparisonMessage message)
}
}

private static void ValidateDifferences(IEnumerable<ComparisonMessage> differences)
internal static void ValidateDifferences(IEnumerable<ComparisonMessage> differences)
{
foreach (var message in differences)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
openapi: 3.0.0
info:
title: My API
version: 0.2.0
paths:
/order/{path}:
post:
parameters:
- name: path
in: path
required: true
schema:
type: string
enum:
- abc
- def
- name: query
in: query
schema:
type: string
enum:
- ghi
- jkl
requestBody:
content:
application/json:
schema:
properties:
foo:
type: string
enum:
- zzzzzz
- mno
- pqr
responses:
"200":
description: Successful Response
content:
application/json:
schema:
properties:
bar:
type: string
enum:
- stu
- vwx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
openapi: 3.0.0
info:
title: My API
version: 0.2.0
paths:
/order/{path}:
post:
parameters:
- name: path
in: path
required: true
schema:
type: string
enum:
- abc
- def
- name: query
in: query
schema:
type: string
enum:
- ghi
- jkl
requestBody:
content:
application/json:
schema:
properties:
foo:
type: string
enum:
- pqr
responses:
"200":
description: Successful Response
content:
application/json:
schema:
properties:
bar:
type: string
enum:
- stu
- vwx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
openapi: 3.0.0
info:
title: My API
version: 0.2.0
paths:
/order/{path}:
post:
parameters:
- name: path
in: path
required: true
schema:
$ref: "#/components/schemas/RequestOnlyEnum"
requestBody:
content:
application/json:
schema:
properties:
foo:
$ref: "#/components/schemas/RequestResponseEnum"
responses:
"200":
description: Successful Response
content:
application/json:
schema:
properties:
foo:
$ref: "#/components/schemas/RequestResponseEnum"
bar:
$ref: "#/components/schemas/ResponseOnlyEnum"
components:
schemas:
RequestOnlyEnum:
type: string
enum:
- abc
- def
ResponseOnlyEnum:
type: string
enum:
- ghi
- jkl
RequestResponseEnum:
type: string
enum:
- zzzzzz
- mno
- pqr
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
openapi: 3.0.0
info:
title: My API
version: 0.2.0
paths:
/order/{path}:
post:
parameters:
- name: path
in: path
required: true
schema:
$ref: "#/components/schemas/RequestOnlyEnum"
requestBody:
content:
application/json:
schema:
properties:
foo:
$ref: "#/components/schemas/RequestResponseEnum"
responses:
"200":
description: Successful Response
content:
application/json:
schema:
properties:
foo:
$ref: "#/components/schemas/RequestResponseEnum"
bar:
$ref: "#/components/schemas/ResponseOnlyEnum"
components:
schemas:
RequestOnlyEnum:
type: string
enum:
- abc
- def
ResponseOnlyEnum:
type: string
enum:
- ghi
- jkl
RequestResponseEnum:
type: string
enum:
- pqr
Loading

0 comments on commit 5a0f306

Please sign in to comment.