ZDDC/zddc/internal/zddc/schema_test.go
ZDDC 9b9d823a67 feat(zddc): .zddc JSON Schema (machine grammar) with structure/option tiers
Authoritative machine form of the GRAMMAR.md grammar: zddc.schema.json
(draft 2020-12) describes every .zddc key with type, enum, description, and
x-zddc-tier — "structure" (the project shape an end user shouldn't change:
paths, worm, *_tool, views, available_tools, auto_own*, party_source, history*,
records, acl, created_by) vs "option" (the blanks an operator fills: roles
members, field_codes, convert, display, admins, title, planned dates). This is
the contract a future .zddc form view uses to render option fields editable and
structure fields read-only.

Embedded (ZddcSchemaBytes) and served at GET /.api/zddc-schema for the client.
Test locks the tier classification.

Scope note: the schema uses $ref (recursive paths:) + patternProperties, which
the in-tree internal/jsonschema validator doesn't support — so it drives the
form/client now; wiring it as the SERVER validator (replacing validate.go's
hand-rolled checks) needs a $ref-capable validator and is a separate decision.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 14:54:07 -05:00

59 lines
1.7 KiB
Go

package zddc
import (
"encoding/json"
"testing"
)
// The embedded .zddc schema must be valid JSON, cover the grammar's keys, and
// tag every property structure|option — the contract the form view relies on.
func TestZddcSchemaTiers(t *testing.T) {
var doc struct {
Properties map[string]struct {
Tier string `json:"x-zddc-tier"`
} `json:"properties"`
}
if err := json.Unmarshal(ZddcSchemaBytes(), &doc); err != nil {
t.Fatalf("schema is not valid JSON: %v", err)
}
if len(doc.Properties) == 0 {
t.Fatal("schema has no properties")
}
// Every property carries a valid tier.
for name, p := range doc.Properties {
if p.Tier != "structure" && p.Tier != "option" {
t.Errorf("property %q has x-zddc-tier=%q, want structure|option", name, p.Tier)
}
}
// Spot-check the classification the form depends on.
wantTier := map[string]string{
"roles": "option", // who's in a group — the headline customisation
"field_codes": "option",
"convert": "option",
"display": "option",
"admins": "option",
"title": "option",
"paths": "structure", // the project shape
"worm": "structure",
"party_source": "structure",
"default_tool": "structure",
"available_tools": "structure",
"auto_own": "structure",
"acl": "structure",
"records": "structure",
"views": "structure",
"created_by": "structure",
}
for name, want := range wantTier {
p, ok := doc.Properties[name]
if !ok {
t.Errorf("schema missing expected key %q", name)
continue
}
if p.Tier != want {
t.Errorf("key %q tier=%q, want %q", name, p.Tier, want)
}
}
}