package contracts_test import ( "crypto/sha256" "encoding/hex" "encoding/json" "os" "path/filepath" "testing" "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer" "github.com/santhosh-tekuri/jsonschema/v6" ) func TestV1BundleHashesAndOfflineFixtures(t *testing.T) { const dir = "../docs/archive/upstream/v1" var manifest struct { Files map[string]string `json:"files"` } if err := json.Unmarshal(readV1(t, dir+"/manifest.json"), &manifest); err != nil { t.Fatal(err) } compiler := jsonschema.NewCompiler() compiler.AssertFormat() compiler.UseLoader(offlineLoader{}) for name, want := range manifest.Files { raw := readV1(t, filepath.Join(dir, name)) sum := sha256.Sum256(raw) if hex.EncodeToString(sum[:]) != want { t.Fatalf("hash mismatch: %s", name) } if filepath.Ext(name) == ".json" && len(name) >= 12 && name[len(name)-12:] == ".schema.json" { var value map[string]any if err := json.Unmarshal(raw, &value); err != nil { t.Fatal(err) } if err := compiler.AddResource(value["$id"].(string), value); err != nil { t.Fatal(err) } } } if err := filepath.WalkDir(dir, func(path string, entry os.DirEntry, err error) error { if err != nil { return err } if entry.IsDir() { return nil } name, err := filepath.Rel(dir, path) if err != nil { return err } if name != "manifest.json" { if _, ok := manifest.Files[name]; !ok { t.Errorf("unhashed file %s", name) } } return nil }); err != nil { t.Fatal(err) } var fixtures []struct { File, Schema string Valid bool } if err := json.Unmarshal(readV1(t, dir+"/fixtures.json"), &fixtures); err != nil { t.Fatal(err) } for _, fixture := range fixtures { schema, err := compiler.Compile("https://go-sip.local/contracts/v1/" + fixture.Schema) if err != nil { t.Fatal(err) } var value any if err := json.Unmarshal(readV1(t, dir+"/"+fixture.File), &value); err != nil { t.Fatal(err) } if err := schema.Validate(value); (err == nil) != fixture.Valid { t.Fatalf("%s: %v", fixture.File, err) } } } func TestV1PythonGoJCSGolden(t *testing.T) { var vectors []struct{ Name, Input, Canonical, SHA256 string } if err := json.Unmarshal(readV1(t, "../docs/archive/upstream/v1/jcs-golden.json"), &vectors); err != nil { t.Fatal(err) } for _, vector := range vectors { t.Run(vector.Name, func(t *testing.T) { canonical, err := jsoncanonicalizer.Transform([]byte(vector.Input)) if err != nil { t.Fatal(err) } if string(canonical) != vector.Canonical { t.Fatalf("cross-language canonical bytes differ: %s", canonical) } sum := sha256.Sum256(canonical) if hex.EncodeToString(sum[:]) != vector.SHA256 { t.Fatal("cross-language digest mismatch") } }) } }