Skip to content
Open
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Possible log types:

### Unreleased

- [added] Support for schema 16-draft
- [changed] Fail validation on usage of wrong versioning scheme (i.e. `.api` vs `.api_compatibility`)

### v0.2.0 (2024-12-29)

- [added] Support for schema v15
Expand Down
72 changes: 42 additions & 30 deletions spaceapi_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,30 @@ func Validate(document string) (ValidationResult, error) {
return myResult, err
}

versionList := getVersionList(suppliedVersion)
versionList, invalidVersions := getVersionList(suppliedVersion)

for _, version := range invalidVersions {
// Version not found. Thus, we cannot validate. Show an
// error for the declared "api_compatibilty" and continue.
myResult.Valid = false
invalidVersionErrors := []ResultError{
{
"api_compatibility",
"(root).api_compatibility",
fmt.Sprintf("Endpoint declares compatibility with schema version %s, which isn't supported", version),
},
}
myResult.Schemas = append(myResult.Schemas, VersionValidationResult{
version,
false,
invalidVersionErrors,
})
myResult.Errors = append(myResult.Errors, invalidVersionErrors...)
}

for _, version := range versionList {
schemaString, found := SpaceAPISchemas[version]
if !found {
// Version not found. Thus, we cannot validate. Show an
// error for the declared "api_compatibilty" and continue.
myResult.Valid = false
invalidVersionErrors := []ResultError{
{
"api_compatibility",
"(root).api_compatibility",
fmt.Sprintf("Endpoint declares compatibility with schema version %s, which isn't supported", version),
},
}
myResult.Schemas = append(myResult.Schemas, VersionValidationResult{
version,
false,
invalidVersionErrors,
})
myResult.Errors = append(myResult.Errors, invalidVersionErrors...)
continue
}
var schema = gojsonschema.NewStringLoader(schemaString)
schemaVersion := SpaceAPISchemas[version]
var schema = gojsonschema.NewStringLoader(schemaVersion)
result, err := gojsonschema.Validate(schema, documentLoader)
if err != nil {
myResult.Valid = false
Expand Down Expand Up @@ -108,15 +108,27 @@ func Validate(document string) (ValidationResult, error) {
return myResult, err
}

func getVersionList(suppliedVersion spaceAPIVersion) []string {
versionList := suppliedVersion.APICompatibility
oldVersion := strings.Replace(fmt.Sprintf("%v", suppliedVersion.API), "0.", "", 1)
if oldVersion != "<nil>" {
versionList = append(versionList, oldVersion)
func getVersionList(suppliedVersion spaceAPIVersion) ([]string, []string) {
var versionList = []string{}
var invalidVersions = []string{}
for _, v14version := range suppliedVersion.APICompatibility {
if schema, found := SpaceApiVersioning[v14version]; found && schema == V14 {
versionList = append(versionList, v14version)
} else {
invalidVersions = append(invalidVersions, v14version)
}
}
v12version := strings.Replace(fmt.Sprintf("%v", suppliedVersion.API), "0.", "", 1)
if v12version != "<nil>" {
if schema, found := SpaceApiVersioning[v12version]; found && schema == V12 {
versionList = append(versionList, v12version)
} else {
invalidVersions = append(invalidVersions, v12version)
}
}

if len(versionList) == 0 {
versionList = []string{"14"}
if len(versionList) == 0 && len(invalidVersions) == 0 {
versionList = []string{"15"}
}
return versionList
return versionList, invalidVersions
}
39 changes: 37 additions & 2 deletions spaceapi_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ var missingIssueReportChannel13 = `{
}
}`
var noVersion = `{ "data": "asd" }`
var wrongVersionUsage = `{ "api": "14", "api_compatibility": [ "13", "0.13" ], "space": "example", "url": "https://example.com", "logo": "https://example.com/logo.png", "location": { "lon": 42, "lat": 23 }, "state": { "open": true }, "contact": {} }`

func TestValidate(t *testing.T) {
invalidResult, _ := Validate(invalid13)
Expand Down Expand Up @@ -150,9 +151,9 @@ func TestValidate(t *testing.T) {
t.Error("Expected validation to be false, got", invalidResult.Valid)
}
invalidErrors = invalidResult.Errors
if len(invalidErrors) != 6 {
if len(invalidErrors) != 5 {
t.Logf("%v", invalidResult)
t.Error("Schema should have got 6 errors, got", len(invalidErrors))
t.Error("Schema should have got 5 errors, got", len(invalidErrors))
}

validResult, err := Validate("")
Expand Down Expand Up @@ -187,4 +188,38 @@ func TestValidate(t *testing.T) {
if !strings.Contains(invalidErrors[0].Description, "Endpoint declares compatibility with schema version 142, which isn't supported") {
t.Error("Did not find expected 'unknown schema version' error:", invalidErrors[0].Description)
}

invalidResult, err = Validate(wrongVersionUsage)
if err != nil {
t.Error("validation error shouldn't show up on valid json")
} else if invalidResult.Valid == true {
t.Error("Expected validation to be false, got true")
}
invalidErrors = invalidResult.Errors
if len(invalidErrors) != 3 {
t.Logf("%v", invalidResult)
t.Error("Schema should have got 3 errors, got", len(invalidErrors))
}
if !strings.Contains(invalidErrors[0].Description, "Endpoint declares compatibility with schema version 13, which isn't supported") {
t.Error("Did not find expected 'unknown schema version' error:", invalidErrors[0].Description)
}
if !strings.Contains(invalidErrors[1].Description, "Endpoint declares compatibility with schema version 0.13, which isn't supported") {
t.Error("Did not find expected 'unknown schema version' error:", invalidErrors[1].Description)
}
if !strings.Contains(invalidErrors[2].Description, "Endpoint declares compatibility with schema version 14, which isn't supported") {
t.Error("Did not find expected 'unknown schema version' error:", invalidErrors[2].Description)
}
}

func TestSchemaVersioningMatch(t *testing.T) {
for v, _ := range SpaceAPISchemas {
if _, found := SpaceApiVersioning[v]; !found {
t.Error("Version", v, "from schemas.SpaceAPISchemas missing in versioning.SpaceApiVersioning")
}
}
for v, _ := range SpaceApiVersioning {
if _, found := SpaceAPISchemas[v]; !found {
t.Error("Version", v, "from versioning.SpaceApiVersioning missing in schemas.SpaceAPISchemas")
}
}
}
18 changes: 18 additions & 0 deletions versioning.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package spaceapivalidator

type VersionSchema int

const (
// versioning scheme introduced in v0.12: ".api" key
V12 VersionSchema = iota
// versioning scheme introduced in v14: ".api_compatibility" list
V14
)

var SpaceApiVersioning = map[string]VersionSchema{
"12": V12,
"13": V12,
"14": V14,
"15": V14,
"16": V14,
}