diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a38e9..abbd958 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/spaceapi_validator.go b/spaceapi_validator.go index a0ec6e0..06ca755 100644 --- a/spaceapi_validator.go +++ b/spaceapi_validator.go @@ -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 @@ -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 != "" { - 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 != "" { + 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 } diff --git a/spaceapi_validator_test.go b/spaceapi_validator_test.go index edb9953..66dd68d 100644 --- a/spaceapi_validator_test.go +++ b/spaceapi_validator_test.go @@ -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) @@ -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("") @@ -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") + } + } } diff --git a/versioning.go b/versioning.go new file mode 100644 index 0000000..04ac3c4 --- /dev/null +++ b/versioning.go @@ -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, +}