docs(06-05): complete GlobalSiteSelectionTests plan — phase 6 done

- SUMMARY.md created with test coverage details and decision rationale
- STATE.md updated: progress 100%, decisions recorded, session logged
- ROADMAP.md phase 6 marked Complete (5/5 plans with summaries)
This commit is contained in:
Dev
2026-04-07 10:14:48 +02:00
parent 80ef092a2e
commit 9add2592b3
3 changed files with 132 additions and 9 deletions

View File

@@ -20,7 +20,7 @@
**v1.1 Enhanced Reports** **v1.1 Enhanced Reports**
- [ ] **Phase 6: Global Site Selection** — Toolbar-level multi-site picker that all feature tabs consume as their default target - [x] **Phase 6: Global Site Selection** — Toolbar-level multi-site picker that all feature tabs consume as their default target (completed 2026-04-07)
- [ ] **Phase 7: User Access Audit** — New feature tab: export every SharePoint/Teams access a specific user holds across selected sites - [ ] **Phase 7: User Access Audit** — New feature tab: export every SharePoint/Teams access a specific user holds across selected sites
- [ ] **Phase 8: Simplified Permissions** — Plain-language labels, summary counts, color coding, and detail-level toggle on the permissions report - [ ] **Phase 8: Simplified Permissions** — Plain-language labels, summary counts, color coding, and detail-level toggle on the permissions report
- [ ] **Phase 9: Storage Visualization** — Charting dependency + pie/donut and bar chart views of storage by file type in the Storage Metrics tab - [ ] **Phase 9: Storage Visualization** — Charting dependency + pie/donut and bar chart views of storage by file type in the Storage Metrics tab
@@ -36,7 +36,7 @@
2. Selecting sites in the toolbar causes all feature tabs to default to those sites when an operation is run 2. Selecting sites in the toolbar causes all feature tabs to default to those sites when an operation is run
3. A user can override the global selection on any individual tab without clearing the global state 3. A user can override the global selection on any individual tab without clearing the global state
4. The global site selection persists across tab switches within the same session 4. The global site selection persists across tab switches within the same session
**Plans:** 4/5 plans executed **Plans:** 5/5 plans complete
Plans: Plans:
- [ ] 06-01-PLAN.md — GlobalSitesChangedMessage + FeatureViewModelBase extension - [ ] 06-01-PLAN.md — GlobalSitesChangedMessage + FeatureViewModelBase extension
- [ ] 06-02-PLAN.md — MainWindowViewModel global selection state + command - [ ] 06-02-PLAN.md — MainWindowViewModel global selection state + command
@@ -86,7 +86,7 @@ Plans:
| 3. Storage and File Operations | v1.0 | 8/8 | Complete | 2026-04-02 | | 3. Storage and File Operations | v1.0 | 8/8 | Complete | 2026-04-02 |
| 4. Bulk Operations and Provisioning | v1.0 | 10/10 | Complete | 2026-04-03 | | 4. Bulk Operations and Provisioning | v1.0 | 10/10 | Complete | 2026-04-03 |
| 5. Distribution and Hardening | v1.0 | 3/3 | Complete | 2026-04-03 | | 5. Distribution and Hardening | v1.0 | 3/3 | Complete | 2026-04-03 |
| 6. Global Site Selection | 4/5 | In Progress| | - | | 6. Global Site Selection | 5/5 | Complete | 2026-04-07 | - |
| 7. User Access Audit | v1.1 | 0/? | Not started | - | | 7. User Access Audit | v1.1 | 0/? | Not started | - |
| 8. Simplified Permissions | v1.1 | 0/? | Not started | - | | 8. Simplified Permissions | v1.1 | 0/? | Not started | - |
| 9. Storage Visualization | v1.1 | 0/? | Not started | - | | 9. Storage Visualization | v1.1 | 0/? | Not started | - |

View File

@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.0 milestone: v1.0
milestone_name: milestone milestone_name: milestone
status: completed status: completed
stopped_at: Completed 06-04-PLAN.md — all 6 tab VMs wired to OnGlobalSitesChanged with local override protection stopped_at: Completed 06-05-PLAN.md — 10 GlobalSiteSelectionTests covering full global site selection contract
last_updated: "2026-04-07T08:10:03.678Z" last_updated: "2026-04-07T08:14:30.489Z"
last_activity: 2026-04-07 — Roadmap created (Phases 6-9), 10/10 requirements mapped last_activity: 2026-04-07 — Roadmap created (Phases 6-9), 10/10 requirements mapped
progress: progress:
total_phases: 4 total_phases: 4
completed_phases: 0 completed_phases: 1
total_plans: 5 total_plans: 5
completed_plans: 4 completed_plans: 5
--- ---
# Project State # Project State
@@ -46,6 +46,7 @@ Phase 6 [ ] → Phase 7 [ ] → Phase 8 [ ] → Phase 9 [ ]
| Phase 06-global-site-selection P01 | 2 | 2 tasks | 3 files | | Phase 06-global-site-selection P01 | 2 | 2 tasks | 3 files |
| Phase 06-global-site-selection P03 | 2 | 3 tasks | 5 files | | Phase 06-global-site-selection P03 | 2 | 3 tasks | 5 files |
| Phase 06-global-site-selection P04 | 2 | 3 tasks | 6 files | | Phase 06-global-site-selection P04 | 2 | 3 tasks | 6 files |
| Phase 06-global-site-selection P05 | 2 | 1 tasks | 1 files |
## Accumulated Context ## Accumulated Context
@@ -66,6 +67,8 @@ Decisions are logged in PROJECT.md Key Decisions table.
- [Phase 06-global-site-selection]: PermissionsViewModel uses _hasLocalSiteOverride guard for SelectedSites; site picker sets flag, tenant switch resets it - [Phase 06-global-site-selection]: PermissionsViewModel uses _hasLocalSiteOverride guard for SelectedSites; site picker sets flag, tenant switch resets it
- [Phase 06-global-site-selection]: Single-site VMs use partial void OnSiteUrlChanged to detect local typing; clearing field reverts to global - [Phase 06-global-site-selection]: Single-site VMs use partial void OnSiteUrlChanged to detect local typing; clearing field reverts to global
- [Phase 06-global-site-selection]: BulkMembersViewModel confirmed excluded: no SiteUrl field, CSV-driven per-row site URLs - [Phase 06-global-site-selection]: BulkMembersViewModel confirmed excluded: no SiteUrl field, CSV-driven per-row site URLs
- [Phase 06-global-site-selection]: Test 8 asserts override-reset via next global sites message (not SiteUrl='' — OnSiteUrlChanged re-applies global immediately when cleared)
- [Phase 06-global-site-selection]: Used reflection to set _hasLocalSiteOverride in PermissionsViewModel test — avoids needing a real SitePickerDialog
### Pending Todos ### Pending Todos
@@ -77,6 +80,6 @@ None.
## Session Continuity ## Session Continuity
Last session: 2026-04-07T08:10:03.675Z Last session: 2026-04-07T08:14:30.486Z
Stopped at: Completed 06-04-PLAN.md — all 6 tab VMs wired to OnGlobalSitesChanged with local override protection Stopped at: Completed 06-05-PLAN.md — 10 GlobalSiteSelectionTests covering full global site selection contract
Resume file: None Resume file: None

View File

@@ -0,0 +1,120 @@
---
phase: 06-global-site-selection
plan: 05
subsystem: testing
tags: [xunit, moq, wpf, mvvm, weak-reference-messenger, global-sites]
# Dependency graph
requires:
- phase: 06-global-site-selection/06-01
provides: GlobalSitesChangedMessage, FeatureViewModelBase.GlobalSites, OnGlobalSitesChanged virtual hook
- phase: 06-global-site-selection/06-02
provides: MainWindowViewModel.GlobalSelectedSites, GlobalSitesSelectedLabel
- phase: 06-global-site-selection/06-04
provides: Tab VM OnGlobalSitesChanged overrides with local override protection
provides:
- GlobalSiteSelectionTests (10 unit tests covering full global site selection contract)
- Test coverage for message broadcast, base class reception, single/multi-site pre-fill
- Test coverage for local override, override reset, tenant switch clearing, label update
affects: []
# Tech tracking
tech-stack:
added: []
patterns:
- "TestFeatureViewModel inner class pattern — expose protected property for assertion via public accessor"
- "WeakReferenceMessenger.Default.Reset() in test constructor — prevents cross-test message contamination"
- "Reflection to set private bool flag (_hasLocalSiteOverride) for testing guard conditions without requiring a dialog to open"
key-files:
created:
- SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs
modified: []
key-decisions:
- "Test 8 (tenant switch) verifies override reset by sending new global sites after TenantSwitchedMessage — cleaner than asserting SiteUrl='' since OnSiteUrlChanged immediately re-applies global when SiteUrl is cleared and GlobalSites is non-empty"
- "Used reflection to set _hasLocalSiteOverride in PermissionsViewModel override test — avoids needing a real SitePickerDialog; acceptable for unit test scenario coverage"
- "MainWindowViewModel instantiated with real ProfileRepository (temp file path) and MsalClientFactory() — avoids needing to refactor VM for testability while still keeping test hermetic"
patterns-established:
- "Messenger reset pattern: WeakReferenceMessenger.Default.Reset() in constructor prevents leakage between WeakReferenceMessenger-heavy tests"
requirements-completed:
- SITE-01
- SITE-02
# Metrics
duration: 3min
completed: 2026-04-07
---
# Phase 06 Plan 05: GlobalSiteSelectionTests Summary
**10 unit tests validating the full global site selection contract — message broadcast, base class GlobalSites property, single-site pre-fill, multi-site pre-populate, local override protection, override reset on clear, tenant switch clearing, and toolbar label count**
## Performance
- **Duration:** ~3 min
- **Started:** 2026-04-07T08:11:40Z
- **Completed:** 2026-04-07T08:14:30Z
- **Tasks:** 1
- **Files modified:** 1 created
## Accomplishments
- All 10 tests pass covering both SITE-01 (global consumption) and SITE-02 (local override) requirements
- Total test suite grows from 134 to 144 passing tests (22 skipped unchanged)
- Tests exercise the full flow: MainWindowViewModel broadcasts, FeatureViewModelBase receives, tab VMs react, local override blocks global, tenant switch resets state
- No regressions in any pre-existing test
## Task Commits
Each task was committed atomically:
1. **Task 1: Create GlobalSiteSelectionTests with comprehensive test coverage** - `80ef092` (test)
## Files Created/Modified
- `SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs` — 10 xUnit Fact tests covering all critical paths in the global site selection flow
## Decisions Made
- Test 8 revised to verify override-reset behavior indirectly: after `TenantSwitchedMessage`, sending new global sites verifies override was cleared (the simpler `Assert.Equal("", SiteUrl)` was wrong — `OnSiteUrlChanged` immediately re-applies GlobalSites when SiteUrl is cleared and GlobalSites is non-empty, which is correct designed behavior)
- Used `System.Reflection` to set `_hasLocalSiteOverride` on `PermissionsViewModel` for Test 7 — allows testing the guard without requiring a live dialog factory
- `MainWindowViewModel` instantiated via concrete `ProfileRepository(tempFile)` and `new MsalClientFactory()` — no refactoring needed, test remains hermetic
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] Corrected Test 8 assertion to match actual StorageViewModel behavior**
- **Found during:** Task 1 (first test run)
- **Issue:** Initial Test 8 asserted `vm.SiteUrl == string.Empty` after tenant switch, but `OnSiteUrlChanged` immediately re-applies `GlobalSites[0].Url` when SiteUrl is cleared and GlobalSites is non-empty — this is correct, designed behavior (clearing = revert to global)
- **Fix:** Rewrote test to assert the real contract: after tenant switch, override flag is reset, so the next global sites message is applied to SiteUrl
- **Files modified:** SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs
- **Verification:** All 10 tests pass
- **Committed in:** 80ef092 (Task 1 commit)
---
**Total deviations:** 1 auto-fixed (1 bug — incorrect test assertion)
**Impact on plan:** Fix was necessary for test correctness; the assertion was wrong about the expected behavior, not the VM code.
## Issues Encountered
- First test run had 9/10 passing; Test 8 failed because the assertion tested an intermediate state that the VM immediately transitions through (SiteUrl clears then immediately re-fills from GlobalSites). Fixed by testing the stable end state instead.
## User Setup Required
None — no external service configuration required.
## Self-Check: PASSED
File exists: SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs
Commit 80ef092 exists in git log.
All 10 tests pass: `dotnet test --filter "GlobalSiteSelection"` → 10 Passed, 0 Failed.
No regressions: full suite → 144 Passed, 22 Skipped.
## Next Phase Readiness
- Phase 6 is complete — all 5 plans executed, all requirements SITE-01 and SITE-02 covered
- The global site selection feature is fully implemented and tested end-to-end
- No blockers for Phase 7
---
*Phase: 06-global-site-selection*
*Completed: 2026-04-07*