--- phase: 06-global-site-selection plan: 05 type: execute wave: 3 depends_on: [06-01, 06-02, 06-04] files_modified: - SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs autonomous: true requirements: - SITE-01 - SITE-02 must_haves: truths: - "Unit tests verify GlobalSitesChangedMessage broadcasts when MainWindowViewModel global sites change" - "Unit tests verify FeatureViewModelBase receives global sites and updates GlobalSites property" - "Unit tests verify single-site tab VMs pre-fill SiteUrl from first global site" - "Unit tests verify PermissionsViewModel pre-populates SelectedSites from global sites" - "Unit tests verify local override prevents global sites from overwriting tab state" - "Unit tests verify tenant switch clears global site selection" - "All tests pass with dotnet test" artifacts: - path: "SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs" provides: "Comprehensive unit tests for global site selection flow" contains: "GlobalSiteSelectionTests" key_links: - from: "SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs" to: "SharepointToolbox/ViewModels/MainWindowViewModel.cs" via: "Tests broadcast and clear behavior" pattern: "GlobalSelectedSites" - from: "SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs" to: "SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs" via: "Tests single-site consumption and local override" pattern: "OnGlobalSitesChanged" --- Create unit tests covering the full global site selection flow: message broadcast, base class reception, tab VM consumption, local override behavior, and tenant switch clearing. Purpose: Verify the contracts established in plans 06-01 through 06-04 work correctly end-to-end without requiring a live SharePoint tenant. Output: GlobalSiteSelectionTests.cs with passing tests covering all critical paths. @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/06-global-site-selection/06-CONTEXT.md @.planning/phases/06-global-site-selection/06-01-SUMMARY.md @.planning/phases/06-global-site-selection/06-02-SUMMARY.md @.planning/phases/06-global-site-selection/06-04-SUMMARY.md ```csharp // FeatureViewModelBase protected IReadOnlyList GlobalSites { get; private set; } protected virtual void OnGlobalSitesChanged(IReadOnlyList sites) { } // Registers for GlobalSitesChangedMessage in OnActivated() ``` ```csharp public ObservableCollection GlobalSelectedSites { get; } public RelayCommand OpenGlobalSitePickerCommand { get; } public string GlobalSitesSelectedLabel { get; } // CollectionChanged on GlobalSelectedSites sends GlobalSitesChangedMessage // OnSelectedProfileChanged clears GlobalSelectedSites // ClearSessionAsync clears GlobalSelectedSites ``` ```csharp // StorageViewModel (and Search, Duplicates, FolderStructure) protected override void OnGlobalSitesChanged(IReadOnlyList sites) { if (_hasLocalSiteOverride) return; SiteUrl = sites.Count > 0 ? sites[0].Url : string.Empty; } // PermissionsViewModel protected override void OnGlobalSitesChanged(IReadOnlyList sites) { if (_hasLocalSiteOverride) return; SelectedSites.Clear(); foreach (var site in sites) SelectedSites.Add(site); } ``` ```csharp // Tests use Moq for service interfaces, internal constructors for VMs // InternalsVisibleTo is already configured // WeakReferenceMessenger.Default for message sending in tests ``` Task 1: Create GlobalSiteSelectionTests with comprehensive test coverage SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs - Test 1: GlobalSitesChangedMessage carries site list — send message, verify receiver gets the sites - Test 2: FeatureViewModelBase updates GlobalSites on message receive — send message to a derived VM, check GlobalSites property - Test 3: StorageViewModel pre-fills SiteUrl from first global site — send global sites message, verify SiteUrl equals first site URL - Test 4: StorageViewModel local override prevents global update — set SiteUrl manually, then send global sites, verify SiteUrl unchanged - Test 5: StorageViewModel clearing SiteUrl reverts to global — set local override, clear SiteUrl, verify it reverts to global site - Test 6: PermissionsViewModel pre-populates SelectedSites from global sites — send global sites, verify SelectedSites matches - Test 7: PermissionsViewModel local picker override prevents global update — mark local override, send global sites, verify SelectedSites unchanged - Test 8: Tenant switch clears global sites on StorageViewModel — send global sites, then send TenantSwitchedMessage, verify SiteUrl cleared and override reset - Test 9: TransferViewModel pre-fills SourceSiteUrl from first global site - Test 10: MainWindowViewModel GlobalSitesSelectedLabel updates with count — add sites to GlobalSelectedSites, verify label text Create `SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs` with the tests described above. Use the existing test patterns from the project: - Moq for `IStorageService`, `ISessionManager`, `IPermissionsService`, `ISiteListService`, `ILogger` - Internal test constructors for ViewModels (already available via InternalsVisibleTo) - `WeakReferenceMessenger.Default.Send(new GlobalSitesChangedMessage(...))` to simulate the toolbar broadcasting Key implementation notes: 1. For tests that need to verify GlobalSites property on FeatureViewModelBase: Create a minimal concrete subclass in the test file: ```csharp private class TestFeatureViewModel : FeatureViewModelBase { public TestFeatureViewModel(ILogger logger) : base(logger) { } protected override Task RunOperationAsync(CancellationToken ct, IProgress progress) => Task.CompletedTask; // Expose protected property for test assertions public IReadOnlyList TestGlobalSites => GlobalSites; } ``` 2. For StorageViewModel tests: use the internal test constructor `StorageViewModel(IStorageService, ISessionManager, ILogger)`. 3. For PermissionsViewModel tests: use the internal test constructor `PermissionsViewModel(IPermissionsService, ISiteListService, ISessionManager, ILogger)`. 4. For TransferViewModel tests: use the production constructor with mocked dependencies. Check if TransferViewModel has an internal test constructor — if not, mock all constructor parameters. 5. For MainWindowViewModel label test: use the production constructor with mocked ProfileService, SessionManager, ILogger. Add SiteInfo items to GlobalSelectedSites and assert the label property. 6. Reset WeakReferenceMessenger.Default between tests to avoid cross-test contamination: ```csharp public GlobalSiteSelectionTests() { WeakReferenceMessenger.Default.Reset(); } ``` 7. Each test should be a `[Fact]` with a descriptive name following the pattern: `MethodOrScenario_Condition_ExpectedResult`. Example test structure: ```csharp [Fact] public void OnGlobalSitesChanged_WithSites_PreFillsSiteUrlOnStorageTab() { var logger = Mock.Of>(); var vm = new StorageViewModel( Mock.Of(), Mock.Of(), logger); var sites = new List { new("https://contoso.sharepoint.com/sites/hr", "HR"), new("https://contoso.sharepoint.com/sites/finance", "Finance") }; WeakReferenceMessenger.Default.Send(new GlobalSitesChangedMessage(sites.AsReadOnly())); Assert.Equal("https://contoso.sharepoint.com/sites/hr", vm.SiteUrl); } ``` Write all 10 tests. Ensure every test has clear Arrange/Act/Assert sections. cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet test SharepointToolbox.Tests/SharepointToolbox.Tests.csproj --filter "FullyQualifiedName~GlobalSiteSelection" --verbosity normal 2>&1 | tail -20 All 10 tests in GlobalSiteSelectionTests pass. Tests cover message broadcast, base class reception, single-site pre-fill, multi-site pre-populate, local override, override reset, tenant switch clear, and label update. - `dotnet test SharepointToolbox.Tests --filter "GlobalSiteSelection"` shows 10 passed, 0 failed - `dotnet test SharepointToolbox.Tests` shows no regressions in existing tests - Test file exists at SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs - Tests cover both SITE-01 (global consumption) and SITE-02 (local override) requirements All 10 unit tests pass, validating the full global site selection contract: message creation, base class plumbing, tab VM consumption (multi-site and single-site), local override behavior, and tenant switch clearing. No regressions in existing test suite. After completion, create `.planning/phases/06-global-site-selection/06-05-SUMMARY.md`