package validators import ( "strings" "testing" "gitea.maximumdirect.net/eric/notarius/internal/core/artifacts" "gitea.maximumdirect.net/eric/notarius/internal/framework/contracts" ) func TestApproved(t *testing.T) { decision := Approved(7) if decision.CandidateIndex != 7 { t.Fatalf("CandidateIndex = %d, want 7", decision.CandidateIndex) } if !decision.Approved { t.Fatal("Approved = false, want true") } if decision.ReasonCode != ReasonApproved { t.Fatalf("ReasonCode = %q, want %q", decision.ReasonCode, ReasonApproved) } if decision.Message != "approved" { t.Fatalf("Message = %q, want approved", decision.Message) } } func TestRejectedTrimsReasonAndMessage(t *testing.T) { decision := Rejected(3, " invalid ", "\tmessage\n") if decision.CandidateIndex != 3 { t.Fatalf("CandidateIndex = %d, want 3", decision.CandidateIndex) } if decision.Approved { t.Fatal("Approved = true, want false") } if decision.ReasonCode != "invalid" { t.Fatalf("ReasonCode = %q, want invalid", decision.ReasonCode) } if decision.Message != "message" { t.Fatalf("Message = %q, want message", decision.Message) } } func TestEnforceDecisionCardinalityAllowsNonZeroCandidateIndices(t *testing.T) { candidates := []artifacts.Candidate{{Index: 4}, {Index: 8}} decisions := []contracts.ValidationDecision{Approved(8), Approved(4)} if err := EnforceDecisionCardinality(candidates, decisions); err != nil { t.Fatalf("EnforceDecisionCardinality() error = %v, want nil", err) } } func TestEnforceDecisionCardinalityAllowsEmptyInputs(t *testing.T) { if err := EnforceDecisionCardinality(nil, nil); err != nil { t.Fatalf("EnforceDecisionCardinality() error = %v, want nil", err) } } func TestEnforceDecisionCardinalityRejectsUnknownDecisionIndex(t *testing.T) { err := EnforceDecisionCardinality( []artifacts.Candidate{{Index: 1}}, []contracts.ValidationDecision{Approved(2)}, ) assertCardinalityError(t, err, "unknown candidate index 2") } func TestEnforceDecisionCardinalityRejectsDuplicateDecisionIndex(t *testing.T) { err := EnforceDecisionCardinality( []artifacts.Candidate{{Index: 1}, {Index: 2}}, []contracts.ValidationDecision{Approved(1), Approved(1)}, ) assertCardinalityError(t, err, "duplicate decision") } func TestEnforceDecisionCardinalityRejectsMissingDecisionIndex(t *testing.T) { err := EnforceDecisionCardinality( []artifacts.Candidate{{Index: 1}, {Index: 2}}, []contracts.ValidationDecision{Approved(1)}, ) assertCardinalityError(t, err, "1 decisions for 2 candidates") } func TestEnforceDecisionCardinalityRejectsDuplicateCandidateIndex(t *testing.T) { err := EnforceDecisionCardinality( []artifacts.Candidate{{Index: 1}, {Index: 1}}, []contracts.ValidationDecision{Approved(1), Approved(1)}, ) assertCardinalityError(t, err, "candidate index 1 is duplicated") } func assertCardinalityError(t *testing.T, err error, want string) { t.Helper() if err == nil { t.Fatal("EnforceDecisionCardinality() error = nil, want error") } if !strings.Contains(err.Error(), want) { t.Fatalf("EnforceDecisionCardinality() error = %q, want substring %q", err.Error(), want) } }