package isphere import "testing" func TestReconcileMessageSourcesStrongAndMediumMatches(t *testing.T) { left := []MessageReconciliationCandidate{ {Source: "packetlog", MessageID: "same-1", ConversationID: "conv-a", SenderID: "alice", TimestampUnixMilli: 1000, BodyPresent: true}, {Source: "packetlog", MessageID: "left-2", ConversationID: "conv-b", SenderID: "bob", TimestampUnixMilli: 100000, BodyPresent: true}, {Source: "packetlog", MessageID: "left-3", ConversationID: "conv-c", SenderID: "carol", TimestampUnixMilli: 200000, AttachmentPresent: true}, } right := []MessageReconciliationCandidate{ {Source: "msglib", MessageID: "same-1", ConversationID: "conv-a", SenderID: "alice", TimestampUnixMilli: 900, BodyPresent: true}, {Source: "msglib", MessageID: "right-2", ConversationID: "conv-b", SenderID: "bob", TimestampUnixMilli: 102500, BodyPresent: true}, {Source: "msglib", MessageID: "right-4", ConversationID: "conv-d", SenderID: "dave", TimestampUnixMilli: 300000, AttachmentPresent: true}, } summary := ReconcileMessageSources(left, right) if summary.LeftCount != 3 || summary.RightCount != 3 { t.Fatalf("counts = %d/%d", summary.LeftCount, summary.RightCount) } if summary.StrongMatches != 1 { t.Fatalf("strong matches = %d, want 1", summary.StrongMatches) } if summary.MediumMatches != 1 { t.Fatalf("medium matches = %d, want 1", summary.MediumMatches) } if summary.UnmatchedLeft != 1 || summary.UnmatchedRight != 1 { t.Fatalf("unmatched = %d/%d, want 1/1", summary.UnmatchedLeft, summary.UnmatchedRight) } if summary.AutoMergeRecommended { t.Fatalf("auto merge should remain false with weak coverage: %+v", summary) } } func TestReconcileMessageSourcesAutoMergeRecommendedAtHighStrongRatio(t *testing.T) { left := []MessageReconciliationCandidate{ {Source: "packetlog", MessageID: "m1", ConversationID: "c1", SenderID: "s1", TimestampUnixMilli: 1}, {Source: "packetlog", MessageID: "m2", ConversationID: "c2", SenderID: "s2", TimestampUnixMilli: 2}, {Source: "packetlog", MessageID: "m3", ConversationID: "c3", SenderID: "s3", TimestampUnixMilli: 3}, {Source: "packetlog", MessageID: "m4", ConversationID: "c4", SenderID: "s4", TimestampUnixMilli: 4}, } right := []MessageReconciliationCandidate{ {Source: "msglib", MessageID: "m1", ConversationID: "c1", SenderID: "s1", TimestampUnixMilli: 1}, {Source: "msglib", MessageID: "m2", ConversationID: "c2", SenderID: "s2", TimestampUnixMilli: 2}, {Source: "msglib", MessageID: "m3", ConversationID: "c3", SenderID: "s3", TimestampUnixMilli: 3}, {Source: "msglib", MessageID: "m4", ConversationID: "c4", SenderID: "s4", TimestampUnixMilli: 4}, } summary := ReconcileMessageSources(left, right) if summary.StrongMatches != 4 || summary.MediumMatches != 0 || summary.UnmatchedLeft != 0 || summary.UnmatchedRight != 0 { t.Fatalf("unexpected exact summary: %+v", summary) } if !summary.AutoMergeRecommended { t.Fatalf("auto merge should be recommended for complete strong match: %+v", summary) } }