Improve D&D validation reliability

This commit is contained in:
2026-08-29 01:24:45 +00:00
parent 4da9360d74
commit 917d150279
55 changed files with 1300 additions and 565 deletions

View File

@@ -7,6 +7,8 @@ import (
"testing"
"github.com/santhosh-tekuri/jsonschema/v6"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
)
func TestResponseSchemaOwnsOnlyPrivateStructuralContract(t *testing.T) {
@@ -29,7 +31,6 @@ func TestResponseSchemaOwnsOnlyPrivateStructuralContract(t *testing.T) {
semanticCandidate := validOccurrenceResponse()
occurrence := semanticCandidate["occurrences"].([]any)[0].(map[string]any)
occurrence["name"] = ""
occurrence["kind"] = "unsupported"
ref := occurrence["source_refs"].([]any)[0].(map[string]any)
ref["start_unit_id"] = 0
ref["end_unit_id"] = -1
@@ -38,12 +39,13 @@ func TestResponseSchemaOwnsOnlyPrivateStructuralContract(t *testing.T) {
t.Fatal(err)
}
if err := validateJSONSchema(content, schema.JSONSchema); err != nil {
t.Fatalf("schema rejected validator-owned semantics: %v", err)
t.Fatalf("schema rejected non-categorical validator-owned semantics: %v", err)
}
for _, mutate := range []func(map[string]any){
func(record map[string]any) { delete(record, "name") },
func(record map[string]any) { record["kind"] = 1 },
func(record map[string]any) { record["kind"] = "unsupported" },
func(record map[string]any) { record["npc_id"] = "npc:sha256:opaque" },
func(record map[string]any) { record["unexpected"] = true },
func(record map[string]any) {
@@ -79,6 +81,24 @@ func TestResponseSchemaIsDefensiveAndContentSafe(t *testing.T) {
}
}
func TestResponseSchemaAcceptsEverySupportedKind(t *testing.T) {
schema, err := loadResponseSchema()
if err != nil {
t.Fatal(err)
}
for _, kind := range []string{string(dnd.NPCOccurrenceKindMentioned), string(dnd.NPCOccurrenceKindNoncombatPresence), string(dnd.NPCOccurrenceKindDialogue), string(dnd.NPCOccurrenceKindCombatAlly), string(dnd.NPCOccurrenceKindCombatOpponent), string(dnd.NPCOccurrenceKindOther)} {
candidate := validOccurrenceResponse()
candidate["occurrences"].([]any)[0].(map[string]any)["kind"] = kind
content, err := json.Marshal(candidate)
if err != nil {
t.Fatal(err)
}
if err := validateJSONSchema(content, schema.JSONSchema); err != nil {
t.Fatalf("supported NPC-occurrence kind %q was rejected: %v", kind, err)
}
}
}
func validOccurrenceResponse() map[string]any {
return map[string]any{"occurrences": []any{map[string]any{
"name": "Mira Thorn", "kind": "dialogue",