Skip to content

Commit

Permalink
fixing json schema validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mfenner committed Apr 5, 2024
1 parent 4689264 commit 428c674
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 42 deletions.
24 changes: 15 additions & 9 deletions schemautils/schemautils.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
package schemautils

import (
"commonmeta/metadata"
"encoding/json"
"fmt"
"log"
"slices"

"github.com/xeipuuv/gojsonschema"
)

func JSONSchemaErrors(document metadata.Metadata) *gojsonschema.Result {
documentJSON, err := json.Marshal(document)
if err != nil {
log.Fatal(err)
func JSONSchemaErrors(document []byte, schema ...string) *gojsonschema.Result {
// If no schema is provided, default to commonmeta_v0.12
if len(schema) == 0 {
schema = append(schema, "commonmeta_v0.12")
}
s := schema[len(schema)-1]
// JSON Schema files stored locally to validate against
schemata := []string{"commonmeta_v0.12", "datacite-v4.5", "crossref-v0.2", "csl-data", "cff_v1.2.0"}
if !slices.Contains(schemata, s) {
log.Fatalf("Schema %s not found", s)
}
schemaLoader := gojsonschema.NewReferenceLoader("file://../resources/commonmeta_v0.12.json")
documentLoader := gojsonschema.NewBytesLoader(documentJSON)
schemaPath := "file://../resources/" + s + ".json"
schemaLoader := gojsonschema.NewReferenceLoader(schemaPath)
documentLoader := gojsonschema.NewBytesLoader(document)
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
panic(err.Error())
Expand All @@ -24,7 +30,7 @@ func JSONSchemaErrors(document metadata.Metadata) *gojsonschema.Result {
if result.Valid() {
fmt.Printf("The document is valid\n")
} else {
fmt.Printf("Input: %v\n", string(documentJSON))
fmt.Printf("Input: %v\n", string(document))
fmt.Printf("The document is not valid. see errors :\n")
for _, desc := range result.Errors() {
fmt.Printf("- %s\n", desc)
Expand Down
65 changes: 60 additions & 5 deletions schemautils/schemautils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,75 @@ package schemautils_test
import (
"commonmeta/metadata"
"commonmeta/schemautils"
"encoding/json"
"fmt"
"log"
"os"
"testing"
)

func TestJSONSchemaErrors(t *testing.T) {
t.Parallel()
type testCase struct {
meta metadata.Metadata
want int
}
m := metadata.Metadata{
ID: "https://doi.org/10.7554/elife.01567",
Type: "JournalArticle",
Url: "https://elifesciences.org/articles/01567",
}
want := 0
result := schemautils.JSONSchemaErrors(m)
got := len(result.Errors())
if want != got {
t.Errorf("want %d, got %d", want, got)

// missing required ID, defaults to empty string
n := metadata.Metadata{
Type: "JournalArticle",
}

// Type is not supported
o := metadata.Metadata{
ID: "https://doi.org/10.7554/elife.01567",
Type: "Umbrella",
}

testCases := []testCase{
{meta: m, want: 0},
{meta: n, want: 2},
{meta: o, want: 1},
}
for _, tc := range testCases {
documentJSON, err := json.Marshal(tc.meta)
if err != nil {
log.Fatal(err)
}
result := schemautils.JSONSchemaErrors(documentJSON)
got := len(result.Errors())
if tc.want != got {
t.Errorf("want %d, got %d", tc.want, got)
}
}
}

func TestJSONSchemaErrorsTestdata(t *testing.T) {
t.Parallel()
type testCase struct {
meta string
schema string
want int
}

testCases := []testCase{
{meta: "citeproc.json", schema: "csl-data", want: 0},
{meta: "datacite.json", schema: "datacite-v4.5", want: 3},
}
for _, tc := range testCases {
data, err := os.ReadFile("../testdata/" + tc.meta)
if err != nil {
fmt.Print(err)
}
result := schemautils.JSONSchemaErrors(data, tc.schema)
got := len(result.Errors())
if tc.want != got {
t.Errorf("want %d, got %d", tc.want, got)
}
}
}
58 changes: 30 additions & 28 deletions testdata/citeproc.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
{
"type": "post-weblog",
"id": "https://doi.org/10.5438/4k3m-nyvg",
"DOI": "10.5438/4k3m-nyvg",
"URL": "https://blog.datacite.org/eating-your-own-dog-food",
"title": "Eating your own Dog Food",
"container-title": "DataCite Blog",
"publisher": { "name": "DataCite" },
"abstract": "Eating your own dog food is a slang term to describe that an organization should itself use the products and services it provides. For DataCite this means that we should use DOIs with appropriate metadata and strategies for long-term preservation for...",
"categories": [
"Phylogeny",
"Malaria",
"Parasites",
"Taxonomy",
"Mitochondrial genome",
"Africa",
"Plasmodium"
],
"issued": {
"date-parts": [[2016, 12, 20]]
},
"author": [
{
"family": "Fenner",
"given": "Martin"
}
]
}
[
{
"type": "post-weblog",
"id": "https://doi.org/10.5438/4k3m-nyvg",
"DOI": "10.5438/4k3m-nyvg",
"URL": "https://blog.datacite.org/eating-your-own-dog-food",
"title": "Eating your own Dog Food",
"container-title": "DataCite Blog",
"publisher": "DataCite",
"abstract": "Eating your own dog food is a slang term to describe that an organization should itself use the products and services it provides. For DataCite this means that we should use DOIs with appropriate metadata and strategies for long-term preservation for...",
"categories": [
"Phylogeny",
"Malaria",
"Parasites",
"Taxonomy",
"Mitochondrial genome",
"Africa",
"Plasmodium"
],
"issued": {
"date-parts": [[2016, 12, 20]]
},
"author": [
{
"family": "Fenner",
"given": "Martin"
}
]
}
]

0 comments on commit 428c674

Please sign in to comment.