Skip to content

Commit

Permalink
enable more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
reuvenharrison committed Feb 3, 2025
1 parent 081dd38 commit e035db0
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 120 deletions.
3 changes: 2 additions & 1 deletion checker/check_api_deprecation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestBreaking_DeprecationWithoutSunsetWithPolicy(t *testing.T) {
errs := checker.CheckBackwardCompatibility(c, d, osm)
require.Len(t, errs, 1)
require.Equal(t, checker.APIDeprecatedSunsetMissingId, errs[0].GetId())
require.Equal(t, "sunset date is missing for deprecated API", errs[0].GetText(checker.NewDefaultLocalizer()))
require.Equal(t, "sunset date is missing for deprecated API", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
}

// BC: deprecating an operation with a default deprecation policy but without specifying sunset date is not breaking
Expand Down Expand Up @@ -195,6 +195,7 @@ func TestBreaking_DeprecationWithProperSunset(t *testing.T) {
errs := checker.CheckBackwardCompatibilityUntilLevel(c, d, osm, checker.INFO)
require.Len(t, errs, 1)
// only a non-breaking change detected
require.Equal(t, checker.EndpointDeprecatedId, errs[0].GetId())
require.Equal(t, checker.INFO, errs[0].GetLevel())
require.Equal(t, "endpoint deprecated", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
}
Expand Down
21 changes: 18 additions & 3 deletions checker/check_request_parameter_deprecation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"cloud.google.com/go/civil"
"github.com/getkin/kin-openapi/openapi3"
"github.com/tufin/oasdiff/diff"
)

Expand All @@ -30,6 +31,7 @@ func RequestParameterDeprecationCheck(diffReport *diff.Diff, operationsSources *
}

op := pathItem.Revision.GetOperation(operation)
opInfo := newOpInfo(config, op, operationsSources, operation, path)

for paramLocation, paramItems := range operationDiff.ParametersDiff.Modified {
for paramName, paramItem := range paramItems {
Expand All @@ -55,7 +57,7 @@ func RequestParameterDeprecationCheck(diffReport *diff.Diff, operationsSources *
continue
}

stability, err := getStabilityLevel(op.Extensions) // TODO: how to handle stability?
stability, err := getStabilityLevel(op.Extensions)
if err != nil {
// handled in CheckBackwardCompatibility
continue

Check warning on line 63 in checker/check_request_parameter_deprecation.go

View check run for this annotation

Codecov / codecov/patch

checker/check_request_parameter_deprecation.go#L62-L63

Added lines #L62 - L63 were not covered by tests
Expand All @@ -67,7 +69,7 @@ func RequestParameterDeprecationCheck(diffReport *diff.Diff, operationsSources *
if !ok {
// if deprecation policy is defined and sunset is missing, it's a breaking change
if deprecationDays > 0 {
result = append(result, getAPIDeprecatedSunsetMissing(newOpInfo(config, op, operationsSources, operation, path)))
result = append(result, getParameterDeprecatedSunsetMissing(opInfo, param))
}
continue
}
Expand All @@ -93,7 +95,7 @@ func RequestParameterDeprecationCheck(diffReport *diff.Diff, operationsSources *
result = append(result, NewApiChange(
RequestParameterSunsetDateTooSmallId,
config,
[]any{date, deprecationDays},
[]any{param.In, param.Name, date, deprecationDays},
"",
operationsSources,
op,
Expand Down Expand Up @@ -121,3 +123,16 @@ func RequestParameterDeprecationCheck(diffReport *diff.Diff, operationsSources *

return result
}

func getParameterDeprecatedSunsetMissing(opInfo opInfo, param *openapi3.Parameter) Change {
return NewApiChange(
RequestParameterDeprecatedSunsetMissingId,
opInfo.config,
[]any{param.In, param.Name},
"",
opInfo.operationsSources,
opInfo.operation,
opInfo.method,
opInfo.path,
)
}
190 changes: 85 additions & 105 deletions checker/check_request_parameter_deprecation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package checker_test
import (
"fmt"
"testing"
"time"

"cloud.google.com/go/civil"
"github.com/stretchr/testify/require"
"github.com/tufin/oasdiff/checker"
"github.com/tufin/oasdiff/diff"
Expand Down Expand Up @@ -32,135 +34,113 @@ func TestBreaking_ParameterDeprecationWithInvalidSunset(t *testing.T) {
require.Equal(t, "failed to parse sunset date for the 'query' request parameter 'id': 'sunset date doesn't conform with RFC3339: invalid-date'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
}

// // BC: deprecating an operation without a deprecation policy but without specifying sunset date is not breaking
// func TestBreaking_DeprecationWithoutSunsetNoPolicy(t *testing.T) {
// BC: deprecating a parameter without a deprecation policy but without specifying sunset date is not breaking
func TestBreaking_ParameterDeprecationWithoutSunsetNoPolicy(t *testing.T) {

// s1, err := open(getParameterDeprecationFile("base.yaml"))
// require.NoError(t, err)

// s2, err := open(getParameterDeprecationFile("deprecated-no-sunset.yaml"))
// require.NoError(t, err)

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// require.NoError(t, err)
// c := singleCheckConfig(checker.ParameterDeprecationCheck).WithDeprecation(0, 0)
// errs := checker.CheckBackwardCompatibility(c, d, osm)
// require.Empty(t, errs)
// }

// // BC: deprecating an operation with a deprecation policy but without specifying sunset date is breaking
// func TestBreaking_DeprecationWithoutSunsetWithPolicy(t *testing.T) {
s1, err := open(getParameterDeprecationFile("base.yaml"))
require.NoError(t, err)

// s1, err := open(getParameterDeprecationFile("base.yaml"))
// require.NoError(t, err)
s2, err := open(getParameterDeprecationFile("deprecated-no-sunset.yaml"))
require.NoError(t, err)

// s2, err := open(getParameterDeprecationFile("deprecated-no-sunset.yaml"))
// require.NoError(t, err)
d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
require.NoError(t, err)
c := singleCheckConfig(checker.RequestParameterDeprecationCheck).WithDeprecation(0, 0)
errs := checker.CheckBackwardCompatibility(c, d, osm)
require.Empty(t, errs)
}

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// require.NoError(t, err)
// c := singleCheckConfig(checker.ParameterDeprecationCheck).WithDeprecation(30, 100)
// errs := checker.CheckBackwardCompatibility(c, d, osm)
// require.Len(t, errs, 1)
// require.Equal(t, checker.APIDeprecatedSunsetMissingId, errs[0].GetId())
// require.Equal(t, "sunset date is missing for deprecated API", errs[0].GetText(checker.NewDefaultLocalizer()))
// }
// BC: deprecating a parameter with a deprecation policy but without specifying sunset date is breaking
func TestBreaking_ParameterDeprecationWithoutSunsetWithPolicy(t *testing.T) {

// // BC: deprecating an operation with a default deprecation policy but without specifying sunset date is not breaking
// func TestBreaking_DeprecationWithoutSunset(t *testing.T) {
s1, err := open(getParameterDeprecationFile("base.yaml"))
require.NoError(t, err)

// s1, err := open(getParameterDeprecationFile("base.yaml"))
// require.NoError(t, err)
s2, err := open(getParameterDeprecationFile("deprecated-no-sunset.yaml"))
require.NoError(t, err)

// s2, err := open(getParameterDeprecationFile("deprecated-no-sunset.yaml"))
// require.NoError(t, err)
d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
require.NoError(t, err)
c := singleCheckConfig(checker.RequestParameterDeprecationCheck).WithDeprecation(30, 100)
errs := checker.CheckBackwardCompatibility(c, d, osm)
require.Len(t, errs, 1)
require.Equal(t, checker.RequestParameterDeprecatedSunsetMissingId, errs[0].GetId())
require.Equal(t, "'query' request parameter 'id' was deprecated without sunset date", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
}

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// require.NoError(t, err)
// c := singleCheckConfig(checker.ParameterDeprecationCheck)
// errs := checker.CheckBackwardCompatibility(c, d, osm)
// require.Empty(t, errs)
// }
// BC: deprecating a parameter with a default deprecation policy but without specifying sunset date is not breaking
func TestBreaking_ParameterDeprecationWithoutSunset(t *testing.T) {

// // BC: deprecating an operation without a deprecation policy and without specifying sunset date is not breaking for alpha level
// func TestBreaking_DeprecationForAlpha(t *testing.T) {
s1, err := open(getParameterDeprecationFile("base.yaml"))
require.NoError(t, err)

// s1, err := open(getParameterDeprecationFile("base-alpha-stability.yaml"))
// require.NoError(t, err)
s2, err := open(getParameterDeprecationFile("deprecated-no-sunset.yaml"))
require.NoError(t, err)

// s2, err := open(getParameterDeprecationFile("deprecated-no-sunset-alpha-stability.yaml"))
// require.NoError(t, err)
d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
require.NoError(t, err)
c := singleCheckConfig(checker.RequestParameterDeprecationCheck)
errs := checker.CheckBackwardCompatibility(c, d, osm)
require.Empty(t, errs)
}

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// require.NoError(t, err)
// errs := checker.CheckBackwardCompatibility(singleCheckConfig(checker.ParameterDeprecationCheck), d, osm)
// require.Empty(t, errs)
// }
// BC: deprecating an operation without a deprecation policy and without specifying sunset date is not breaking for alpha level
func TestBreaking_ParameterDeprecationForAlpha(t *testing.T) {

// // BC: deprecating an operation without a deprecation policy and without specifying sunset date is not breaking for draft level
// func TestBreaking_DeprecationForDraft(t *testing.T) {
// s1, err := open(getParameterDeprecationFile("base-alpha-stability.yaml"))
// require.NoError(t, err)
// draft := toJson(t, checker.STABILITY_DRAFT)
// s1.Spec.Paths.Value("/api/test").Get.Extensions["x-stability-level"] = draft
s1, err := open(getParameterDeprecationFile("base-alpha-stability.yaml"))
require.NoError(t, err)

// s2, err := open(getParameterDeprecationFile("deprecated-no-sunset-alpha-stability.yaml"))
// require.NoError(t, err)
// s2.Spec.Paths.Value("/api/test").Get.Extensions["x-stability-level"] = draft
s2, err := open(getParameterDeprecationFile("deprecated-no-sunset-alpha-stability.yaml"))
require.NoError(t, err)

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// require.NoError(t, err)
// errs := checker.CheckBackwardCompatibility(singleCheckConfig(checker.ParameterDeprecationCheck), d, osm)
// require.Empty(t, errs)
// }
d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
require.NoError(t, err)
errs := checker.CheckBackwardCompatibility(singleCheckConfig(checker.RequestParameterDeprecationCheck), d, osm)
require.Empty(t, errs)
}

// func toJson(t *testing.T, value string) json.RawMessage {
// t.Helper()
// data, err := json.Marshal(value)
// require.NoError(t, err)
// return data
// }
// BC: deprecating a parameter with a deprecation policy and sunset date before required deprecation period is breaking
func TestBreaking_ParameterDeprecationWithEarlySunset(t *testing.T) {
s1, err := open(getParameterDeprecationFile("base.yaml"))
require.NoError(t, err)

// // BC: deprecating an operation with a deprecation policy and sunset date before required deprecation period is breaking
// func TestBreaking_DeprecationWithEarlySunset(t *testing.T) {
// s1, err := open(getParameterDeprecationFile("base.yaml"))
// require.NoError(t, err)
s2, err := open(getParameterDeprecationFile("deprecated-future.yaml"))
require.NoError(t, err)
sunsetDate := civil.DateOf(time.Now()).AddDays(9).String()

// s2, err := open(getParameterDeprecationFile("deprecated-future.yaml"))
// require.NoError(t, err)
// sunsetDate := civil.DateOf(time.Now()).AddDays(9).String()
// s2.Spec.Paths.Value("/api/test").Get.Extensions[diff.SunsetExtension] = toJson(t, sunsetDate)
s2.Spec.Paths.Value("/api/test").GetOperation("GET").Parameters.GetByInAndName("query", "id").Extensions[diff.SunsetExtension] = toJson(t, sunsetDate)

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// require.NoError(t, err)
// c := singleCheckConfig(checker.ParameterDeprecationCheck).WithDeprecation(0, 10)
// errs := checker.CheckBackwardCompatibility(c, d, osm)
// require.NotEmpty(t, errs)
// require.Len(t, errs, 1)
// require.Equal(t, checker.APISunsetDateTooSmallId, errs[0].GetId())
// require.Equal(t, fmt.Sprintf("sunset date '%s' is too small, must be at least '10' days from now", sunsetDate), errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
// }
d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
require.NoError(t, err)
c := singleCheckConfig(checker.RequestParameterDeprecationCheck).WithDeprecation(0, 10)
errs := checker.CheckBackwardCompatibility(c, d, osm)
require.NotEmpty(t, errs)
require.Len(t, errs, 1)
require.Equal(t, checker.RequestParameterSunsetDateTooSmallId, errs[0].GetId())
require.Equal(t, fmt.Sprintf("'query' request parameter 'id' sunset date '%s' is too small, must be at least '10' days from now", sunsetDate), errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
}

// // BC: deprecating an operation with a deprecation policy and sunset date after required deprecation period is not breaking
// func TestBreaking_DeprecationWithProperSunset(t *testing.T) {
// BC: deprecating a parameter with a deprecation policy and sunset date after required deprecation period is not breaking
func TestBreaking_ParameterDeprecationWithProperSunset(t *testing.T) {

// s1, err := open(getParameterDeprecationFile("base.yaml"))
// require.NoError(t, err)
s1, err := open(getParameterDeprecationFile("base.yaml"))
require.NoError(t, err)

// s2, err := open(getParameterDeprecationFile("deprecated-future.yaml"))
// require.NoError(t, err)
s2, err := open(getParameterDeprecationFile("deprecated-future.yaml"))
require.NoError(t, err)

// s2.Spec.Paths.Value("/api/test").Get.Extensions[diff.SunsetExtension] = toJson(t, civil.DateOf(time.Now()).AddDays(10).String())
s2.Spec.Paths.Value("/api/test").GetOperation("GET").Parameters.GetByInAndName("query", "id").Extensions[diff.SunsetExtension] = toJson(t, civil.DateOf(time.Now()).AddDays(10).String())

// d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
// c := singleCheckConfig(checker.ParameterDeprecationCheck).WithDeprecation(0, 10)
// require.NoError(t, err)
// errs := checker.CheckBackwardCompatibilityUntilLevel(c, d, osm, checker.INFO)
// require.Len(t, errs, 1)
// // only a non-breaking change detected
// require.Equal(t, checker.INFO, errs[0].GetLevel())
// require.Equal(t, "endpoint deprecated", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
// }
d, osm, err := diff.GetWithOperationsSourcesMap(diff.NewConfig(), s1, s2)
c := singleCheckConfig(checker.RequestParameterDeprecationCheck).WithDeprecation(0, 10)
require.NoError(t, err)
errs := checker.CheckBackwardCompatibilityUntilLevel(c, d, osm, checker.INFO)
require.Len(t, errs, 1)
// only a non-breaking change detected
require.Equal(t, checker.RequestParameterDeprecatedId, errs[0].GetId())
require.Equal(t, checker.INFO, errs[0].GetLevel())
require.Equal(t, "'query' request parameter 'id' was deprecated", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer()))
}

// CL: parameters that became deprecated
func TestParameterDeprecated_DetectsDeprecated(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion checker/localizations/localizations.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions checker/localizations_src/en/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ endpoint-added: endpoint added
endpoint-deprecated: endpoint deprecated
endpoint-reactivated: endpoint reactivated
request-parameter-reactivated: "%s request parameter %s was reactivated"
request-parameter-deprecated-sunset-missing: "%s request parameter %s was deprecated without sunset date"
request-parameter-sunset-date-too-small: "%s request parameter %s sunset date %s is too small, must be at least %s days from now"
request-parameter-deprecated: "%s request parameter %s was deprecated"
api-path-removed-without-deprecation: api path removed without deprecation
api-path-removed-with-deprecation: api path removed with deprecation
Expand Down
23 changes: 23 additions & 0 deletions data/param-deprecation/deprecated-no-sunset-alpha-stability.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
info:
title: Tufin
version: 1.0.0
openapi: 3.0.3
paths:
/api/test:
get:
x-stability-level: alpha
parameters:
- $ref: '#/components/parameters/id'
responses:
200:
description: OK
components:
parameters:
id:
name: id
in: query
required: true
schema:
type: string
description: 'The ID'
deprecated: true
Loading

0 comments on commit e035db0

Please sign in to comment.