Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions tools/cli/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ E2E_TIMEOUT?=60m
E2E_PARALLEL?=1
E2E_EXTRA_ARGS?=



LINKER_GH_SHA_FLAG=-s -w -X github.com/mongodb/openapi/tools/cli/internal/version.GitCommit=${GIT_SHA}
LINKER_FLAGS=${LINKER_GH_SHA_FLAG} -X github.com/mongodb/openapi/tools/cli/internal/version.Version=${VERSION}

Expand Down
13 changes: 7 additions & 6 deletions tools/cli/internal/apiversion/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package apiversion

import (
Expand Down Expand Up @@ -128,7 +129,7 @@ func Parse(contentType string) (string, error) {
}

// FindLatestContentVersionMatched finds the latest content version that matches the requested version.
func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *APIVersion) (*APIVersion, error) {
func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *APIVersion) *APIVersion {
/*
given:
version: 2024-01-01
Expand All @@ -142,7 +143,7 @@ func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *A
*/
var latestVersionMatch *APIVersion
if op.Responses == nil {
return requestedVersion, nil
return requestedVersion
}

for _, response := range op.Responses.Map() {
Expand All @@ -153,15 +154,15 @@ func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *A
for contentType := range response.Value.Content {
contentVersion, err := New(WithContent(contentType))
if err != nil {
log.Printf("Ignoring invalid content type: %s", contentType)
log.Printf("Ignoring invalid content type: %q", contentType)
continue
}
if contentVersion.GreaterThan(requestedVersion) {
continue
}

if contentVersion.Equal(requestedVersion) {
return contentVersion, nil
return contentVersion
}

if latestVersionMatch == nil || contentVersion.GreaterThan(latestVersionMatch) {
Expand All @@ -171,10 +172,10 @@ func FindLatestContentVersionMatched(op *openapi3.Operation, requestedVersion *A
}

if latestVersionMatch == nil {
return requestedVersion, nil
return requestedVersion
}

return latestVersionMatch, nil
return latestVersionMatch
}

// Sort versions
Expand Down
135 changes: 96 additions & 39 deletions tools/cli/internal/apiversion/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (
"testing"
"time"

"github.com/getkin/kin-openapi/openapi3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestParseVersion(t *testing.T) {
Expand Down Expand Up @@ -126,6 +128,7 @@ func TestNewAPIVersionFromContentType(t *testing.T) {
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
version, err := New(WithContent(tt.contentType))
t.Parallel()
if tt.wantErr {
assert.Error(t, err)
} else {
Expand Down Expand Up @@ -158,6 +161,7 @@ func TestApiVersion_GreaterThan(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v1, _ := New(WithVersion(tt.version1))
v2, _ := New(WithVersion(tt.version2))
assert.Equal(t, tt.expected, v1.GreaterThan(v2))
Expand Down Expand Up @@ -188,6 +192,7 @@ func TestApiVersion_LessThan(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v1, _ := New(WithVersion(tt.version1))
v2, _ := New(WithVersion(tt.version2))
assert.Equal(t, tt.expected, v1.LessThan(v2))
Expand Down Expand Up @@ -215,6 +220,7 @@ func TestApiVersion_IsZero(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v, _ := New(WithVersion(tt.version))
assert.Equal(t, tt.expected, v.IsZero())
})
Expand Down Expand Up @@ -275,6 +281,7 @@ func TestApiVersion_Equal(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v1, _ := New(WithVersion(tt.version1))
v2, _ := New(WithVersion(tt.version2))
assert.Equal(t, tt.expected, v1.Equal(v2))
Expand Down Expand Up @@ -311,6 +318,7 @@ func TestNewAPIVersionFromTime(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
timeValue, _ := time.Parse("2006-01-02", tt.time)
match, err := New(WithDate(timeValue))
if tt.wantErr {
Expand All @@ -327,114 +335,163 @@ func TestNewVersionDate(t *testing.T) {
name string
version string
expectedMatch string
wantErr bool
wantErr require.ErrorAssertionFunc
}{
{
name: "2023-01-01",
version: "2023-01-01",
expectedMatch: "2023-01-01",
wantErr: false,
wantErr: require.NoError,
},
{
name: "2023-01-02",
version: "2023-01-02",
expectedMatch: "2023-01-02",
wantErr: false,
wantErr: require.NoError,
},
{
name: "2030-02-20",
version: "2030-02-20",
expectedMatch: "2030-02-20",
wantErr: false,
wantErr: require.NoError,
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
match, err := DateFromVersion(tt.version)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.Equal(t, tt.expectedMatch, match.Format(dateFormat))
}
tt.wantErr(t, err)
assert.Equal(t, tt.expectedMatch, match.Format(dateFormat))
})
}
}

func TestNewAPIVersionFromDateString(t *testing.T) {
func TestNew_WithVersion(t *testing.T) {
testCases := []struct {
name string
version string
expectedMatch string
wantErr bool
wantErr require.ErrorAssertionFunc
}{
{
name: "2023-01-01",
version: "2023-01-01",
expectedMatch: "2023-01-01",
wantErr: false,
wantErr: require.NoError,
},
{
name: "2023-01-02",
version: "2023-01-02",
expectedMatch: "2023-01-02",
wantErr: false,
wantErr: require.NoError,
},
{
name: "2030-02-20",
version: "2030-02-20",
expectedMatch: "2030-02-20",
wantErr: false,
wantErr: require.NoError,
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
match, err := New(WithVersion(tt.version))
if tt.wantErr {
assert.Error(t, err)
} else {
assert.Equal(t, tt.expectedMatch, match.String())
}
tt.wantErr(t, err)
assert.Equal(t, tt.expectedMatch, match.String())
})
}
}

func TestNewAPIVersion(t *testing.T) {
func TestFindLatestContentVersionMatched(t *testing.T) {
testCases := []struct {
name string
version string
targetVersion string
expectedMatch string
wantErr bool
}{
{
name: "2023-01-01",
version: "2023-01-01",
name: "exact match 2023-01-01",
targetVersion: "2023-01-01",
expectedMatch: "2023-01-01",
wantErr: false,
},
{
name: "2023-01-02",
version: "2023-01-02",
expectedMatch: "2023-01-02",
wantErr: false,
name: "exact match 2023-11-15",
targetVersion: "2023-11-15",
expectedMatch: "2023-11-15",
},
{
name: "2030-02-20",
version: "2030-02-20",
expectedMatch: "2030-02-20",
wantErr: false,
name: "exact match 2024-05-30",
targetVersion: "2024-05-30",
expectedMatch: "2024-05-30",
},
{
name: "approx match 2023-01-01",
targetVersion: "2023-01-02",
expectedMatch: "2023-01-01",
},
{
name: "approx match 2023-01-01",
targetVersion: "2023-01-31",
expectedMatch: "2023-01-01",
},
{
name: "approx match 2023-02-01",
targetVersion: "2023-02-20",
expectedMatch: "2023-02-01",
},
{
name: "future date",
targetVersion: "2030-02-20",
expectedMatch: "2024-05-30",
},
{
name: "past date",
targetVersion: "1999-02-20",
expectedMatch: "1999-02-20",
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
match, err := New(WithVersion(tt.version))
if tt.wantErr {
assert.Error(t, err)
} else {
assert.Equal(t, tt.expectedMatch, match.String())
}
t.Parallel()
targetVersion, err := New(WithVersion(tt.targetVersion))
require.NoError(t, err)
r := FindLatestContentVersionMatched(oasOperationAllVersions(), targetVersion)
// transform time to str with format "2006-01-02"
assert.Equal(t, tt.expectedMatch, r.String())
})
}
}

func oasOperationAllVersions() *openapi3.Operation {
responses := &openapi3.Responses{}
responses.Set("200", &openapi3.ResponseRef{
Value: &openapi3.Response{
Content: map[string]*openapi3.MediaType{
"application/vnd.atlas.2023-01-01+json": {},
"application/vnd.atlas.2023-01-01+csv": {},
"application/vnd.atlas.2023-02-01+json": {},
"application/vnd.atlas.2023-10-01+json": {},
"application/vnd.atlas.2023-11-15+json": {},
"application/vnd.atlas.2024-05-30+json": {},
},
},
})

return &openapi3.Operation{
OperationID: "operationId",
Responses: responses,
RequestBody: &openapi3.RequestBodyRef{
Value: &openapi3.RequestBody{
Content: map[string]*openapi3.MediaType{
"application/vnd.atlas.2023-01-01+json": {},
"application/vnd.atlas.2023-02-01+json": {},
"application/vnd.atlas.2023-10-01+json": {},
"application/vnd.atlas.2023-11-15+json": {},
"application/vnd.atlas.2024-05-30+json": {},
},
},
},
}
}
23 changes: 11 additions & 12 deletions tools/cli/internal/openapi/filter/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package filter

import (
Expand All @@ -29,9 +30,11 @@ type ExtensionFilter struct {
metadata *Metadata
}

const sunsetExtension = "x-sunset"
const xGenExtension = "x-xgen-version"
const format = "2006-01-02T15:04:05Z07:00"
const (
sunsetExtension = "x-sunset"
xGenExtension = "x-xgen-version"
format = "2006-01-02T15:04:05Z07:00"
)

func (f *ExtensionFilter) Apply() error {
for _, pathItem := range f.oas.Paths.Map() {
Expand All @@ -47,11 +50,7 @@ func (f *ExtensionFilter) Apply() error {

updateExtensionToDateString(operation.Extensions)

latestVersionMatch, err := apiversion.FindLatestContentVersionMatched(operation, f.metadata.targetVersion)
if err != nil {
return err
}

latestVersionMatch := apiversion.FindLatestContentVersionMatched(operation, f.metadata.targetVersion)
for _, response := range operation.Responses.Map() {
if response == nil {
continue
Expand Down Expand Up @@ -89,15 +88,15 @@ func updateExtensionToDateString(extensions map[string]any) {
return
}

for key, value := range extensions {
if key != sunsetExtension && key != xGenExtension {
for k, v := range extensions {
if k != sunsetExtension && k != xGenExtension {
continue
}
date, err := time.Parse(format, value.(string))
date, err := time.Parse(format, v.(string))
if err != nil {
continue
}
extensions[key] = date.Format("2006-01-02")
extensions[k] = date.Format("2006-01-02")
}
}

Expand Down
Loading
Loading