using SharepointToolbox.Core.Models; using SharepointToolbox.Services; using Xunit; namespace SharepointToolbox.Tests.Services; /// /// Pure-logic tests for the MakeKey composite key function (no CSOM needed). /// Inline helper matches the implementation DuplicatesService will produce in Plan 03-04. /// public class DuplicatesServiceTests { // Inline copy of MakeKey to test logic before Plan 03-04 creates the real class private static string MakeKey(DuplicateItem item, DuplicateScanOptions opts) { var parts = new System.Collections.Generic.List { item.Name.ToLowerInvariant() }; if (opts.MatchSize && item.SizeBytes.HasValue) parts.Add(item.SizeBytes.Value.ToString()); if (opts.MatchCreated && item.Created.HasValue) parts.Add(item.Created.Value.Date.ToString("yyyy-MM-dd")); if (opts.MatchModified && item.Modified.HasValue) parts.Add(item.Modified.Value.Date.ToString("yyyy-MM-dd")); if (opts.MatchSubfolderCount && item.FolderCount.HasValue) parts.Add(item.FolderCount.Value.ToString()); if (opts.MatchFileCount && item.FileCount.HasValue) parts.Add(item.FileCount.Value.ToString()); return string.Join("|", parts); } [Fact] public void MakeKey_NameOnly_ReturnsLowercaseName() { var item = new DuplicateItem { Name = "Report.docx", SizeBytes = 1000 }; var opts = new DuplicateScanOptions(MatchSize: false); Assert.Equal("report.docx", MakeKey(item, opts)); } [Fact] public void MakeKey_WithSizeMatch_AppendsSizeToKey() { var item = new DuplicateItem { Name = "Report.docx", SizeBytes = 1024 }; var opts = new DuplicateScanOptions(MatchSize: true); Assert.Equal("report.docx|1024", MakeKey(item, opts)); } [Fact] public void MakeKey_WithCreatedAndModified_AppendsDateStrings() { var item = new DuplicateItem { Name = "file.pdf", SizeBytes = 500, Created = new DateTime(2024, 3, 15), Modified = new DateTime(2024, 6, 1) }; var opts = new DuplicateScanOptions(MatchSize: false, MatchCreated: true, MatchModified: true); Assert.Equal("file.pdf|2024-03-15|2024-06-01", MakeKey(item, opts)); } [Fact] public void MakeKey_SameKeyForSameItems_GroupsCorrectly() { var opts = new DuplicateScanOptions(MatchSize: true); var item1 = new DuplicateItem { Name = "Budget.xlsx", SizeBytes = 2048 }; var item2 = new DuplicateItem { Name = "BUDGET.xlsx", SizeBytes = 2048 }; Assert.Equal(MakeKey(item1, opts), MakeKey(item2, opts)); } [Fact] public void MakeKey_DifferentSize_ProducesDifferentKeys() { var opts = new DuplicateScanOptions(MatchSize: true); var item1 = new DuplicateItem { Name = "file.docx", SizeBytes = 100 }; var item2 = new DuplicateItem { Name = "file.docx", SizeBytes = 200 }; Assert.NotEqual(MakeKey(item1, opts), MakeKey(item2, opts)); } [Fact(Skip = "Requires live CSOM context — covered by Plan 03-04 implementation")] public Task ScanDuplicatesAsync_Files_GroupsByCompositeKey() => Task.CompletedTask; [Fact(Skip = "Requires live CSOM context — covered by Plan 03-04 implementation")] public Task ScanDuplicatesAsync_Folders_UsesCamlFSObjType1() => Task.CompletedTask; }