Files
Sharepoint-Toolbox/.planning/codebase/TESTING.md
Kawa 63cf69f114 docs: map existing codebase
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 09:28:40 +02:00

257 lines
7.8 KiB
Markdown

# Testing Patterns
**Analysis Date:** 2026-04-02
## Test Framework
**Status:** No automated testing framework detected
**Infrastructure:** Not applicable
- No test runner (Jest, Vitest, Pester)
- No test configuration files
- No test suite in codebase
- No CI/CD pipeline test stage configured
## Testing Approach
**Current Testing Model:** Manual testing via GUI
**Test Methods:**
- **GUI Testing:** All functionality tested through WinForms UI
- Manual interaction with controls and dialogs
- Visual verification of results in generated reports
- Log output observation in RichTextBox
- **Report Validation:** HTML and CSV exports manually reviewed for correctness
- **API Integration:** Manual testing of PnP.PowerShell operations against live SharePoint tenant
- **Regression Testing:** Ad-hoc manual verification of features after changes
## Code Organization for Testing
**Testability Patterns:** Limited
The monolithic single-file architecture (`Sharepoint_ToolBox.ps1` at 6408 lines) makes isolated unit testing challenging. Key observations:
**Tight Coupling to UI:**
- Core business logic embedded in event handlers
- Heavy reliance on global `$script:` scope for state
- Example: `Load-Profiles` reads from `Get-ProfilesFilePath`, which is file-system dependent
- Site picker functionality (`Show-SitePicker`) spawns background runspace but depends on form being instantiated
**Hard Dependencies:**
- PnP.PowerShell module imported dynamically in background runspace blocks
- File system access (profiles, templates, settings) not abstracted
- SharePoint connection state implicit in PnP connection context
**Areas with Better Isolation:**
- Pure utility functions like `Format-Bytes`, `EscHtml` could be unit tested
- Data transformation functions like `Merge-PermissionRows` accept input arrays and return structured output
- HTML generation in `Export-PermissionsToHTML` and `Export-StorageToHTML` could be tested against expected markup
## Background Runspace Pattern
**Async Execution Model:**
Most long-running operations execute in separate PowerShell runspace to prevent UI blocking:
```powershell
# 1. Create synchronized hashtable for communication
$sync = [hashtable]::Synchronized(@{
Done = $false
Error = $null
Result = $null
Queue = [System.Collections.Generic.Queue[object]]::new()
})
# 2. Define background script block (has access to passed parameters only)
$bgScript = {
param($Url, $ClientId, $Sync)
try {
Import-Module PnP.PowerShell -ErrorAction Stop
Connect-PnPOnline -Url $Url -Interactive -ClientId $ClientId
# Perform work
$Sync.Result = $data
} catch {
$Sync.Error = $_.Exception.Message
} finally {
$Sync.Done = $true
}
}
# 3. Launch in runspace
$rs = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$rs.ApartmentState = "STA"; $rs.ThreadOptions = "ReuseThread"; $rs.Open()
$ps = [System.Management.Automation.PowerShell]::Create()
$ps.Runspace = $rs
[void]$ps.AddScript($bgScript)
[void]$ps.AddArgument($url)
$hnd = $ps.BeginInvoke()
# 4. Poll completion with timer
$tmr = New-Object System.Windows.Forms.Timer
$tmr.Interval = 300
$tmr.Add_Tick({
if ($sync.Done) {
[void]$ps.EndInvoke($hnd)
$rs.Close(); $rs.Dispose()
# Update UI with $sync.Result
}
})
$tmr.Start()
```
**Used for:**
- Site picker loading: `Show-SitePicker` (lines 212-471)
- Template capture: Background job in template manager (lines 900+)
- Site creation: Background job in bulk creation (lines 1134+)
- Permission/storage export: Operations triggered from event handlers
- File search: Background search execution
## Message Queue Pattern
**For logging from background runspaces:**
```powershell
# Background function enqueues messages
function BgLog([string]$m, [string]$c="LightGreen") {
$Sync.Queue.Enqueue([PSCustomObject]@{ Text=$m; Color=$c })
}
# Main thread timer dequeues and displays
$tmr.Add_Tick({
while ($sync.Queue.Count -gt 0) {
$msg = $sync.Queue.Dequeue()
_Tpl-Log -Box $textBox -Msg $msg.Text -Color $msg.Color
}
})
```
**Rationale:** Avoids cross-thread UI access violations by queueing messages from worker thread.
## Common Testing Patterns in Code
**Null/Existence Checks:**
```powershell
# Before using objects
if ($script:LogBox -and !$script:LogBox.IsDisposed) { ... }
if ($data -and $data.Count -gt 0) { ... }
if ([string]::IsNullOrWhiteSpace($value)) { return $false }
```
**Error Logging in Loops:**
```powershell
# Catch errors in data processing, log, continue
foreach ($item in $items) {
try {
# Process item
} catch {
BgLog " Skipped: $($_.Exception.Message)" "DarkGray"
}
}
```
**Validation Before Operations:**
```powershell
function Validate-Inputs {
if ([string]::IsNullOrWhiteSpace($script:txtClientId.Text)) {
[System.Windows.Forms.MessageBox]::Show(...)
return $false
}
return $true
}
# Called before starting long operations
if (-not (Validate-Inputs)) { return }
```
## Data Flow Testing Approach
**For Feature Development:**
1. **Manual Test Cases** (observed pattern, not formalized):
- Permissions Export:
- Select site with multiple libraries
- Choose CSV format
- Verify CSV contains all libraries and permissions
- Test HTML format in browser for interactivity
- Storage Metrics:
- Run with `PerLibrary` flag
- Verify folder hierarchy is captured
- Test recursive subsite inclusion
- Validate byte calculations
- Template Capture/Apply:
- Capture from source site
- Verify JSON structure
- Create new site from template
- Verify structure, permissions, settings applied
- File Search:
- Test regex patterns
- Verify date filtering
- Test large result sets (pagination)
- Check CSV/HTML output
2. **Visual Verification:**
- Log output reviewed in RichTextBox for progress
- Generated HTML reports tested in multiple browsers
- CSV files opened in Excel for format verification
## Fragility Points & Testing Considerations
**PnP Connection Management:**
- No connection pooling; each operation may create new connection
- Interactive auth prompt appears per runspace
- **Risk:** Auth failures not consistently handled
- **Testing Need:** Mock PnP module or use test tenant
**HTML Generation:**
- String concatenation for large HTML documents (lines 1475+)
- Inline CSS for styling
- JavaScript for interactivity
- **Risk:** Complex HTML fragments prone to markup errors
- **Testing Need:** Validate HTML structure and JavaScript functionality
**JSON Persistence:**
- Profiles, templates, settings stored in JSON
- ConvertTo-Json/-From-Json without depth specification can truncate
- **Risk:** Nested objects may not round-trip correctly
- **Testing Need:** Validate all object types persist/restore
**Background Runspace Cleanup:**
- Runspace and PowerShell objects must be disposed
- Timer must be stopped and disposed
- **Risk:** Resource leaks if exception occurs before cleanup
- **Testing Need:** Verify cleanup in error paths
## Suggested Testing Improvements
**Unit Testing:**
1. Extract pure functions (no UI/file system dependencies)
- `Format-Bytes`, `EscHtml`, `Merge-PermissionRows`
- HTML generation functions
2. Use Pester framework for PowerShell unit tests:
```powershell
Describe "Format-Bytes" {
It "Formats bytes to GB" {
Format-Bytes (1GB * 2) | Should -Be "2 GB"
}
}
```
3. Mock file system and PnP operations for integration tests
**Integration Testing:**
1. Use test SharePoint tenant for functional testing
2. Automate report generation and validation
3. Script common user workflows
**Regression Testing:**
1. Maintain test suite of sites with known structures
2. Generate reports, compare outputs
3. Run before major releases
---
*Testing analysis: 2026-04-02*