package validators import ( "testing" "gitea.maximumdirect.net/eric/audita/v3/internal/core/glossary" "gitea.maximumdirect.net/eric/audita/v3/internal/core/schema" "gitea.maximumdirect.net/eric/audita/v3/internal/framework/proposals" ) func TestIndependentProtectionForSelectedGlossary(t *testing.T) { active := []glossary.Entry{{Collection: "spells", ID: "shield", Name: "Shield"}} entries := append(append([]glossary.Entry(nil), active...), glossary.Entry{Collection: "items", ID: "shield", Name: "Shield", Aliases: []string{"Aegis"}}) cases := []struct { name string terms []glossary.Term before, after string approved bool }{ {"shared spelling exempt", glossary.Vocabulary(entries, active), "Shield", "Barrier", true}, {"other alias protected", glossary.Vocabulary(entries, active), "Aegis", "Armor", false}, {"full protection retained", glossary.Vocabulary(entries, nil), "Shield", "Barrier", false}, {"empty protection", nil, "Aegis", "Armor", true}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { result, err := ValidateProtectedTerms(Request{ProtectedTerms: tc.terms, CandidateProposal: []proposals.EnrichedCorrectionProposal{{CorrectionProposal: proposals.CorrectionProposal{OriginalText: tc.before, CorrectedText: tc.after}}}}) if err != nil || len(result.Decisions) != 1 || result.Decisions[0].Approved != tc.approved { t.Fatalf("result=%+v err=%v", result, err) } }) } } func TestSharedAliasRetainsAllIdentities(t *testing.T) { entries := []glossary.Entry{ {Collection: "a", ID: "first", Name: "First", Aliases: []string{"Shared"}}, {Collection: "b", ID: "second", Name: "Second", Aliases: []string{"Shared"}}, } vocabulary := NewProtectedVocabulary(glossary.Vocabulary(entries, nil)) identities := vocabulary.occurrencesByIdentity("Shared") if len(identities) != 2 || len(identities[glossary.Identity{Collection: "a", ID: "first"}]) != 1 || len(identities[glossary.Identity{Collection: "b", ID: "second"}]) != 1 { t.Fatalf("identities=%v", identities) } } func TestApplicationChecksCurrentTextWithSelectedProtection(t *testing.T) { active := []glossary.Entry{{Collection: "spells", ID: "spell", Name: "Shield"}} protected := append(append([]glossary.Entry(nil), active...), glossary.Entry{Collection: "items", ID: "item", Name: "Shield", Aliases: []string{"Aegis"}}) vocabulary := NewProtectedVocabulary(glossary.Vocabulary(protected, active)) transcript := &schema.Transcript{Segments: []schema.Segment{{ID: 1, Text: "Shield and Aegis"}}} candidates := []proposals.EnrichedCorrectionProposal{ {CorrectionProposal: proposals.CorrectionProposal{TargetSegmentID: 1, OriginalText: "Shield", CorrectedText: "Barrier", Confidence: 1}, ProposalMetadata: proposals.ProposalMetadata{ProposalIndex: 0}}, {CorrectionProposal: proposals.CorrectionProposal{TargetSegmentID: 1, OriginalText: "egis", CorrectedText: "rmor", Confidence: 1}, ProposalMetadata: proposals.ProposalMetadata{ProposalIndex: 1}}, } result := proposals.ApplyProposals(transcript, candidates, proposals.ReplacementPolicyRequireUnique, func(before, after string) bool { return vocabulary.AllowsChange(before, after, false) }) if result.Transcript.Segments[0].Text != "Barrier and Aegis" || len(result.Applied) != 1 || len(result.Skipped) != 1 || result.Skipped[0].SkipReason != proposals.SkipReasonProtectedTerm { t.Fatalf("unexpected application: %+v", result) } } func TestValidationContextIncludesEachSharedDefinition(t *testing.T) { entries := []glossary.Entry{ {Collection: "spells", ID: "shield", Name: "Shield", Category: "spell"}, {Collection: "items", ID: "shield", Name: "Shield", Category: "item"}, {Collection: "items", ID: "sword", Name: "Sword", Category: "item"}, } segments := []schema.Segment{{ID: 1, Text: "Shield"}} _, selected := validationContext(segments, 0, entries, NewProtectedVocabulary(glossary.Vocabulary(entries, nil)), "Barrier") if len(selected) != 2 || selected[0].Category != "spell" || selected[1].ID != "shield" || selected[1].Collection != "items" { t.Fatalf("selected=%+v", selected) } }