docs(07-08): complete unit tests plan summary
- 07-08-SUMMARY.md: 32 tests across 4 files, all passing - STATE.md: advance plan, record metrics and decisions - ROADMAP.md: phase 7 complete (8/8 plans)
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
**v1.1 Enhanced Reports**
|
||||
|
||||
- [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
|
||||
- [x] **Phase 7: User Access Audit** — New feature tab: export every SharePoint/Teams access a specific user holds across selected sites (completed 2026-04-07)
|
||||
- [ ] **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
|
||||
|
||||
@@ -53,7 +53,7 @@ Plans:
|
||||
2. Running the audit returns a list of all access entries the user holds across the selected sites
|
||||
3. Results distinguish between direct role assignments, SharePoint group memberships, and inherited access
|
||||
4. Results can be exported to CSV or HTML in the same format established by v1.0 export patterns
|
||||
**Plans:** 7/8 plans executed
|
||||
**Plans:** 8/8 plans complete
|
||||
Plans:
|
||||
- [ ] 07-01-PLAN.md — UserAccessEntry model + service interfaces (Wave 1)
|
||||
- [ ] 07-02-PLAN.md — UserAccessAuditService implementation (Wave 2)
|
||||
@@ -96,6 +96,6 @@ Plans:
|
||||
| 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 |
|
||||
| 6. Global Site Selection | 5/5 | Complete | 2026-04-07 | - |
|
||||
| 7. User Access Audit | 7/8 | In Progress| | - |
|
||||
| 7. User Access Audit | 8/8 | Complete | 2026-04-07 | - |
|
||||
| 8. Simplified Permissions | v1.1 | 0/? | Not started | - |
|
||||
| 9. Storage Visualization | v1.1 | 0/? | Not started | - |
|
||||
|
||||
@@ -3,14 +3,14 @@ gsd_state_version: 1.0
|
||||
milestone: v1.0
|
||||
milestone_name: milestone
|
||||
status: completed
|
||||
stopped_at: Completed 07-07-PLAN.md
|
||||
last_updated: "2026-04-07T10:54:46.890Z"
|
||||
stopped_at: Completed 07-08-PLAN.md
|
||||
last_updated: "2026-04-07T11:00:01.832Z"
|
||||
last_activity: 2026-04-07 — Roadmap created (Phases 6-9), 10/10 requirements mapped
|
||||
progress:
|
||||
total_phases: 4
|
||||
completed_phases: 1
|
||||
completed_phases: 2
|
||||
total_plans: 13
|
||||
completed_plans: 12
|
||||
completed_plans: 13
|
||||
---
|
||||
|
||||
# Project State
|
||||
@@ -54,6 +54,7 @@ Phase 6 [ ] → Phase 7 [ ] → Phase 8 [ ] → Phase 9 [ ]
|
||||
| Phase 07-user-access-audit P04 | 2 | 1 tasks | 1 files |
|
||||
| Phase 07-user-access-audit P05 | 4 | 2 tasks | 2 files |
|
||||
| Phase 07-user-access-audit P07 | 8 | 3 tasks | 7 files |
|
||||
| Phase 07-user-access-audit P08 | 2 | 2 tasks | 4 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@@ -91,6 +92,8 @@ Decisions are logged in PROJECT.md Key Decisions table.
|
||||
- [Phase 07-05]: Simple ListBox autocomplete (not Popup) following plan's recommended simpler alternative — avoids Popup placement issues
|
||||
- [Phase 07-user-access-audit]: Dialog factory wiring in MainWindow.xaml.cs by casting auditView.DataContext to UserAccessAuditViewModel — matches PermissionsView pattern
|
||||
- [Phase 07-user-access-audit]: UserAccessAuditView created inline (Rule 3) when 07-05 found missing — follows 07-05 spec with two-panel layout
|
||||
- [Phase 07-user-access-audit]: Used internal TestRunOperationAsync for ViewModel tests; Application.Current null in tests lets else branch run synchronously
|
||||
- [Phase 07-user-access-audit]: WeakReferenceMessenger.Default.Reset() in test constructor prevents cross-test contamination from message registrations
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@@ -102,6 +105,6 @@ None.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-04-07T10:54:46.888Z
|
||||
Stopped at: Completed 07-07-PLAN.md
|
||||
Last session: 2026-04-07T11:00:01.830Z
|
||||
Stopped at: Completed 07-08-PLAN.md
|
||||
Resume file: None
|
||||
|
||||
126
.planning/phases/07-user-access-audit/07-08-SUMMARY.md
Normal file
126
.planning/phases/07-user-access-audit/07-08-SUMMARY.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
phase: 07-user-access-audit
|
||||
plan: 08
|
||||
subsystem: testing
|
||||
tags: [unit-tests, xunit, moq, user-access-audit, csv-export, html-export, viewmodel]
|
||||
|
||||
requires:
|
||||
- phase: 07-02
|
||||
provides: [UserAccessAuditService]
|
||||
- phase: 07-03
|
||||
provides: [GraphUserSearchService, IGraphUserSearchService]
|
||||
- phase: 07-04
|
||||
provides: [UserAccessAuditViewModel]
|
||||
- phase: 07-06
|
||||
provides: [UserAccessCsvExportService, UserAccessHtmlExportService]
|
||||
|
||||
provides:
|
||||
- Unit tests for UserAccessAuditService (12 tests)
|
||||
- Unit tests for UserAccessCsvExportService (5 tests)
|
||||
- Unit tests for UserAccessHtmlExportService (7 tests)
|
||||
- Unit tests for UserAccessAuditViewModel (8 tests)
|
||||
|
||||
affects: []
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: [Moq mock setup with ReturnsAsync, reflection for private field access in override guard tests, WeakReferenceMessenger.Reset in test constructor]
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- SharepointToolbox.Tests/Services/UserAccessAuditServiceTests.cs
|
||||
- SharepointToolbox.Tests/Services/Export/UserAccessCsvExportServiceTests.cs
|
||||
- SharepointToolbox.Tests/Services/Export/UserAccessHtmlExportServiceTests.cs
|
||||
- SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelTests.cs
|
||||
modified: []
|
||||
|
||||
key-decisions:
|
||||
- "Used internal TestRunOperationAsync to exercise ViewModel business logic directly, consistent with PermissionsViewModelTests pattern"
|
||||
- "Application.Current is null in tests — RunOperationAsync else branch executes synchronously, no Dispatcher mocking required"
|
||||
- "WeakReferenceMessenger.Default.Reset() in test constructor prevents cross-test contamination from GlobalSitesChangedMessage and TenantSwitchedMessage registrations"
|
||||
- "Reflection used to set _hasLocalSiteOverride for override guard tests, consistent with existing GlobalSiteSelectionTests pattern"
|
||||
|
||||
patterns-established:
|
||||
- "UserAccess test helpers: MakeEntry() factory for UserAccessEntry, CreateViewModel() factory returns (vm, mockAudit) tuple"
|
||||
- "Service test pattern: CreateService() returns (svc, permMock, sessionMock) and sets up ScanSiteAsync/GetOrCreateContextAsync on all mocks"
|
||||
|
||||
requirements-completed: [UACC-01, UACC-02]
|
||||
|
||||
duration: 2min
|
||||
completed: 2026-04-07
|
||||
---
|
||||
|
||||
# Phase 7 Plan 08: Unit Tests Summary
|
||||
|
||||
**32 unit tests covering UserAccessAuditService (user filtering, claim matching, access classification), CSV/HTML export services (format correctness, encoding), and UserAccessAuditViewModel (audit invocation, result population, summary properties, tenant reset, site selection) — all passing with no regressions.**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** ~2 min
|
||||
- **Started:** 2026-04-07T11:16:30Z
|
||||
- **Completed:** 2026-04-07T11:18:50Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 4
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- UserAccessAuditServiceTests (12 tests): full coverage of user login filtering, claim format bidirectional matching, Direct/Group/Inherited classification, Full Control + Site Collection Administrator high-privilege detection, external user #EXT# flagging, semicolon-delimited user and permission level splitting, multi-site scan loop verification
|
||||
- UserAccessCsvExportServiceTests (5 tests): summary section content, data header presence, RFC 4180 double-quote escaping, 7-column count enforcement, WriteSingleFileAsync multi-user combined output
|
||||
- UserAccessHtmlExportServiceTests (7 tests): DOCTYPE prefix, stat-card presence, dual-view section identifiers (view-user/view-site), access-direct/group/inherited CSS badge classes, filterTable/toggleView JS functions, HTML entity encoding for XSS-risk content
|
||||
- UserAccessAuditViewModelTests (8 tests): AuditUsersAsync mock invocation, Results population count, TotalAccessCount/SitesCount/HighPrivilegeCount computed properties, OnTenantSwitched full reset, GlobalSitesChangedMessage updates SelectedSites, override guard prevents global update, CanExport false/true states
|
||||
|
||||
## Task Commits
|
||||
|
||||
1. **Task 1: Write UserAccessAuditService unit tests** - `5df9503` (test)
|
||||
2. **Task 2: Write export service and ViewModel tests** - `35b2c2a` (test)
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `SharepointToolbox.Tests/Services/UserAccessAuditServiceTests.cs` — 12 tests for audit service business logic
|
||||
- `SharepointToolbox.Tests/Services/Export/UserAccessCsvExportServiceTests.cs` — 5 tests for CSV export formatting
|
||||
- `SharepointToolbox.Tests/Services/Export/UserAccessHtmlExportServiceTests.cs` — 7 tests for HTML export content
|
||||
- `SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelTests.cs` — 8 tests for ViewModel orchestration
|
||||
|
||||
## Decisions Made
|
||||
|
||||
1. **TestRunOperationAsync for ViewModel tests** — Used the internal `TestRunOperationAsync` method to exercise `RunOperationAsync` business logic directly. This avoids requiring a full WPF application pump (no Application.Current in tests). Since `Application.Current?.Dispatcher` returns null in the test runner, the else branch executes synchronously — Results and summary properties are set immediately.
|
||||
|
||||
2. **WeakReferenceMessenger.Reset in constructor** — Test class constructor calls `WeakReferenceMessenger.Default.Reset()` to clear all registered receivers between tests. This prevents cross-test contamination where a GlobalSitesChangedMessage from one test bleeds into another.
|
||||
|
||||
3. **Reflection for override guard test** — The `_hasLocalSiteOverride` field is private with no public setter. Using reflection to set it directly is the standard pattern established by GlobalSiteSelectionTests for PermissionsViewModel — consistent approach maintained.
|
||||
|
||||
4. **No special WPF threading setup** — The `CollectionViewSource` and `ICollectionView` used in the ViewModel constructor work in a WPF-enabled test environment (the test project targets `net10.0-windows` with `UseWPF=true`). No mock dispatcher or `[STAThread]` annotation needed.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None — plan executed exactly as written.
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
None.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
- All Phase 7 unit tests complete. 32 new tests, 176 total passing, 22 skipped (pre-existing).
|
||||
- Phase 7 is fully implemented: models (07-01), audit service (07-02), Graph search (07-03), ViewModel (07-04), view (07-05), exports (07-06), integration wiring (07-07), unit tests (07-08).
|
||||
- Ready to proceed to Phase 8 or Phase 9.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
Files confirmed present:
|
||||
- FOUND: SharepointToolbox.Tests/Services/UserAccessAuditServiceTests.cs
|
||||
- FOUND: SharepointToolbox.Tests/Services/Export/UserAccessCsvExportServiceTests.cs
|
||||
- FOUND: SharepointToolbox.Tests/Services/Export/UserAccessHtmlExportServiceTests.cs
|
||||
- FOUND: SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelTests.cs
|
||||
|
||||
Commits confirmed:
|
||||
- FOUND: 5df9503
|
||||
- FOUND: 35b2c2a
|
||||
|
||||
---
|
||||
*Phase: 07-user-access-audit*
|
||||
*Completed: 2026-04-07*
|
||||
Reference in New Issue
Block a user