feat(tools): add duplicate audit report
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
|
||||
)
|
||||
|
||||
func TestBuildDuplicateAuditGroupsProjectsAndThoughtsSafely(t *testing.T) {
|
||||
now := time.Date(2026, 4, 12, 20, 5, 0, 0, time.UTC)
|
||||
projects := []thoughttypes.ProjectSummary{
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("11111111-1111-1111-1111-111111111111"), NumericID: 1, Name: "AMCS", CreatedAt: now}, ThoughtCount: 3},
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("22222222-2222-2222-2222-222222222222"), NumericID: 2, Name: "amcs ", CreatedAt: now.Add(time.Hour)}, ThoughtCount: 1},
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("33333333-3333-3333-3333-333333333333"), NumericID: 3, Name: "other", CreatedAt: now}, ThoughtCount: 1},
|
||||
}
|
||||
thoughts := []thoughttypes.Thought{
|
||||
{ID: 10, GUID: uuid.MustParse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"), Content: "Same text", Metadata: thoughttypes.ThoughtMetadata{Type: "Note", Topics: []string{"Go", "go"}, People: []string{"Alice"}}, CreatedAt: now},
|
||||
{ID: 11, GUID: uuid.MustParse("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"), Content: " same text ", Metadata: thoughttypes.ThoughtMetadata{Type: "note", Topics: []string{"go"}, People: []string{"alice"}}, CreatedAt: now.Add(time.Hour)},
|
||||
{ID: 12, GUID: uuid.MustParse("cccccccc-cccc-cccc-cccc-cccccccccccc"), Content: "unique", Metadata: thoughttypes.ThoughtMetadata{Type: "Task", Topics: []string{"Tasks"}}, CreatedAt: now},
|
||||
}
|
||||
|
||||
report := buildDuplicateAuditReport(projects, thoughts, DuplicateAuditInput{})
|
||||
|
||||
if len(report.ProjectCandidates) != 1 {
|
||||
t.Fatalf("project candidates = %d, want 1: %#v", len(report.ProjectCandidates), report.ProjectCandidates)
|
||||
}
|
||||
projectCandidate := report.ProjectCandidates[0]
|
||||
if projectCandidate.MatchType != "normalized_name" || projectCandidate.NormalizedValue != "amcs" || len(projectCandidate.Projects) != 2 {
|
||||
t.Fatalf("project candidate mismatch: %#v", projectCandidate)
|
||||
}
|
||||
if projectCandidate.RecommendedCanonicalID != projects[0].ID {
|
||||
t.Fatalf("recommended project = %s, want %s", projectCandidate.RecommendedCanonicalID, projects[0].ID)
|
||||
}
|
||||
|
||||
if len(report.ThoughtCandidates) != 1 {
|
||||
t.Fatalf("thought candidates = %d, want 1: %#v", len(report.ThoughtCandidates), report.ThoughtCandidates)
|
||||
}
|
||||
thoughtCandidate := report.ThoughtCandidates[0]
|
||||
if thoughtCandidate.MatchType != "normalized_content" || thoughtCandidate.NormalizedValue != "same text" || len(thoughtCandidate.Thoughts) != 2 {
|
||||
t.Fatalf("thought candidate mismatch: %#v", thoughtCandidate)
|
||||
}
|
||||
if thoughtCandidate.RecommendedCanonicalID != thoughts[0].GUID {
|
||||
t.Fatalf("recommended thought = %s, want %s", thoughtCandidate.RecommendedCanonicalID, thoughts[0].GUID)
|
||||
}
|
||||
|
||||
if len(report.MetadataCandidates) != 3 {
|
||||
t.Fatalf("metadata candidates = %d, want 3: %#v", len(report.MetadataCandidates), report.MetadataCandidates)
|
||||
}
|
||||
if report.Summary.ProjectCandidateGroups != 1 || report.Summary.ThoughtCandidateGroups != 1 || report.Summary.MetadataCandidateGroups != 3 {
|
||||
t.Fatalf("summary mismatch: %#v", report.Summary)
|
||||
}
|
||||
if report.Summary.DryRun != true {
|
||||
t.Fatalf("dry run = false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDuplicateAuditRespectsLimit(t *testing.T) {
|
||||
projects := []thoughttypes.ProjectSummary{
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("11111111-1111-1111-1111-111111111111"), Name: "Alpha"}},
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("22222222-2222-2222-2222-222222222222"), Name: "alpha"}},
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("33333333-3333-3333-3333-333333333333"), Name: "Beta"}},
|
||||
{Project: thoughttypes.Project{ID: uuid.MustParse("44444444-4444-4444-4444-444444444444"), Name: "beta"}},
|
||||
}
|
||||
|
||||
report := buildDuplicateAuditReport(projects, nil, DuplicateAuditInput{Limit: 1})
|
||||
|
||||
if len(report.ProjectCandidates) != 1 {
|
||||
t.Fatalf("project candidates = %d, want 1", len(report.ProjectCandidates))
|
||||
}
|
||||
if report.Summary.Truncated != true {
|
||||
t.Fatalf("truncated = false, want true")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user