Merge remote-tracking branch 'kawa/main'
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
using System.Reflection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using SharepointToolbox.Core.Models;
|
||||
using SharepointToolbox.Services;
|
||||
using SharepointToolbox.ViewModels;
|
||||
using SharepointToolbox.ViewModels.Tabs;
|
||||
using Xunit;
|
||||
|
||||
namespace SharepointToolbox.Tests.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the report filter flags (Show*) project the raw scan output
|
||||
/// (<c>_allNodes</c>) into <c>Results</c> correctly: hiding a kind drops the
|
||||
/// matching root nodes plus their entire subtree, preserving DFS ordering.
|
||||
/// </summary>
|
||||
public class StorageViewModelFilterTests
|
||||
{
|
||||
public StorageViewModelFilterTests() => WeakReferenceMessenger.Default.Reset();
|
||||
|
||||
private static StorageViewModel CreateVm()
|
||||
{
|
||||
var vm = new StorageViewModel(
|
||||
new Mock<IStorageService>().Object,
|
||||
new Mock<ISessionManager>().Object,
|
||||
NullLogger<FeatureViewModelBase>.Instance);
|
||||
vm.SetCurrentProfile(new TenantProfile { Name = "T", TenantUrl = "https://t", ClientId = "c" });
|
||||
return vm;
|
||||
}
|
||||
|
||||
/// <summary>Inject a flat node list straight into the private _allNodes field
|
||||
/// and trigger a rebuild via toggling a Show flag.</summary>
|
||||
private static void Seed(StorageViewModel vm, List<StorageNode> flat)
|
||||
{
|
||||
var field = typeof(StorageViewModel).GetField("_allNodes",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||
field.SetValue(vm, flat);
|
||||
// Toggle off+on to force RebuildFilteredResults().
|
||||
vm.ShowLibraries = false;
|
||||
vm.ShowLibraries = true;
|
||||
}
|
||||
|
||||
private static List<StorageNode> MakeMixedTree() => new()
|
||||
{
|
||||
new() { Name = "Documents", Kind = StorageNodeKind.Library, IndentLevel = 0, TotalSizeBytes = 100 },
|
||||
new() { Name = "Sub", Kind = StorageNodeKind.Library, IndentLevel = 1, TotalSizeBytes = 50 },
|
||||
new() { Name = "Preserve", Kind = StorageNodeKind.PreservationHold, IndentLevel = 0, TotalSizeBytes = 200 },
|
||||
new() { Name = "[Recycle]", Kind = StorageNodeKind.RecycleBin, IndentLevel = 0, TotalSizeBytes = 300 },
|
||||
new() { Name = "[Attach] L",Kind = StorageNodeKind.ListAttachments, IndentLevel = 0, TotalSizeBytes = 75 },
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void AllShowFlagsTrue_AllNodesAppear()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
Seed(vm, MakeMixedTree());
|
||||
Assert.Equal(5, vm.Results.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HideRecycleBin_RemovesOnlyRecycleNode()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
Seed(vm, MakeMixedTree());
|
||||
vm.ShowRecycleBin = false;
|
||||
Assert.DoesNotContain(vm.Results, n => n.Kind == StorageNodeKind.RecycleBin);
|
||||
Assert.Equal(4, vm.Results.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HidePreservationHold_RemovesPreservationNode()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
Seed(vm, MakeMixedTree());
|
||||
vm.ShowPreservationHold = false;
|
||||
Assert.DoesNotContain(vm.Results, n => n.Kind == StorageNodeKind.PreservationHold);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HideLibraries_DropsLibraryRootAndItsChildren()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
Seed(vm, MakeMixedTree());
|
||||
vm.ShowLibraries = false;
|
||||
// "Documents" + "Sub" both gone — Sub's subtree dropped with its parent root.
|
||||
Assert.DoesNotContain(vm.Results, n => n.Name == "Documents");
|
||||
Assert.DoesNotContain(vm.Results, n => n.Name == "Sub");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CombineRecycleBinStages_True_MergesStagesIntoSingleRow()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
var nodes = new List<StorageNode>
|
||||
{
|
||||
new() { Name = "[Recycle Bin] First-stage", Kind = StorageNodeKind.RecycleBin, IndentLevel = 0,
|
||||
SiteTitle = "S1", TotalSizeBytes = 100, FileStreamSizeBytes = 100, TotalFileCount = 3 },
|
||||
new() { Name = "[Recycle Bin] Second-stage", Kind = StorageNodeKind.RecycleBin, IndentLevel = 0,
|
||||
SiteTitle = "S1", TotalSizeBytes = 250, FileStreamSizeBytes = 250, TotalFileCount = 7 },
|
||||
};
|
||||
Seed(vm, nodes);
|
||||
vm.CombineRecycleBinStages = true;
|
||||
|
||||
var bins = vm.Results.Where(n => n.Kind == StorageNodeKind.RecycleBin).ToList();
|
||||
Assert.Single(bins);
|
||||
Assert.Equal(350, bins[0].TotalSizeBytes);
|
||||
Assert.Equal(10, bins[0].TotalFileCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CombineRecycleBinStages_False_KeepsSeparateRows()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
var nodes = new List<StorageNode>
|
||||
{
|
||||
new() { Name = "[Recycle Bin] First-stage", Kind = StorageNodeKind.RecycleBin, IndentLevel = 0,
|
||||
SiteTitle = "S1", TotalSizeBytes = 100 },
|
||||
new() { Name = "[Recycle Bin] Second-stage", Kind = StorageNodeKind.RecycleBin, IndentLevel = 0,
|
||||
SiteTitle = "S1", TotalSizeBytes = 250 },
|
||||
};
|
||||
Seed(vm, nodes);
|
||||
vm.CombineRecycleBinStages = false;
|
||||
|
||||
Assert.Equal(2, vm.Results.Count(n => n.Kind == StorageNodeKind.RecycleBin));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HideAll_LeavesEmptyResults()
|
||||
{
|
||||
var vm = CreateVm();
|
||||
Seed(vm, MakeMixedTree());
|
||||
vm.ShowLibraries = false;
|
||||
vm.ShowHiddenLibraries = false;
|
||||
vm.ShowPreservationHold = false;
|
||||
vm.ShowListAttachments = false;
|
||||
vm.ShowRecycleBin = false;
|
||||
vm.ShowSubsites = false;
|
||||
Assert.Empty(vm.Results);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user