80 lines
2.9 KiB
Go
80 lines
2.9 KiB
Go
package shape
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
|
)
|
|
|
|
func TestValidatorApprovesWellFormedSpellPayload(t *testing.T) {
|
|
result, err := New(Options{}).Validate(context.Background(), requestWithValue(validSpellList()))
|
|
if err != nil {
|
|
t.Fatalf("Validate() error = %v, want nil", err)
|
|
}
|
|
if !result.Approved {
|
|
t.Fatalf("Validate() = %#v, want approved", result)
|
|
}
|
|
}
|
|
|
|
func TestValidatorRejectsMissingSpellList(t *testing.T) {
|
|
result, err := New(Options{}).Validate(context.Background(), requestWithValue(dnd.SpellList{}))
|
|
if err != nil {
|
|
t.Fatalf("Validate() error = %v, want nil", err)
|
|
}
|
|
if result.Approved {
|
|
t.Fatalf("Approved = true, want false")
|
|
}
|
|
if result.ReasonCode != ReasonCode {
|
|
t.Fatalf("ReasonCode = %q, want %q", result.ReasonCode, ReasonCode)
|
|
}
|
|
}
|
|
|
|
func TestValidatorRejectsMissingRequiredSpellFields(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mutate func(*dnd.SpellCast)
|
|
}{
|
|
{name: "blank caster", mutate: func(cast *dnd.SpellCast) { cast.Caster = " " }},
|
|
{name: "blank spell", mutate: func(cast *dnd.SpellCast) { cast.Spell = "" }},
|
|
{name: "empty evidence", mutate: func(cast *dnd.SpellCast) { cast.SourceRefs = nil }},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
value := validSpellList()
|
|
test.mutate(&value.SpellCasts[0])
|
|
result, err := New(Options{}).Validate(context.Background(), requestWithValue(value))
|
|
if err != nil || result.Approved || result.ReasonCode != ReasonCode {
|
|
t.Fatalf("Validate() = %#v, %v; want shape rejection", result, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidatorSpecCheckpointAndRegistration(t *testing.T) {
|
|
if got := New(Options{}).CheckpointFingerprints(); len(got) != 1 || got[0].Name != "policy" || got[0].Value != policy {
|
|
t.Fatalf("CheckpointFingerprints() = %#v, want local policy", got)
|
|
}
|
|
if spec := Spec(); spec.Key != Key || spec.ExecutionClass != contracts.ExecutionClassDeterministic {
|
|
t.Fatalf("Spec() = %#v, want deterministic shape validator", spec)
|
|
}
|
|
registry := pipeline.NewValidatorRegistry()
|
|
if err := Register(registry); err != nil {
|
|
t.Fatalf("Register() error = %v, want nil", err)
|
|
}
|
|
if _, err := DecodeOptions(map[string]any{"unexpected": true}); err == nil {
|
|
t.Fatal("DecodeOptions() error = nil, want unknown option error")
|
|
}
|
|
}
|
|
|
|
func requestWithValue(value dnd.SpellList) contracts.TypedValidationRequest[dnd.SpellList] {
|
|
return contracts.TypedValidationRequest[dnd.SpellList]{Value: value}
|
|
}
|
|
|
|
func validSpellList() dnd.SpellList {
|
|
return dnd.SpellList{SpellCasts: []dnd.SpellCast{{Caster: "Aria", Spell: "Cure Wounds", SourceRefs: []source.SourceRef{{SourceID: "session", StartUnitID: 1, EndUnitID: 1}}}}}
|
|
}
|