Tests/Test-O365MailboxUsage-Validation.ps1

<#
.SYNOPSIS
    Basic syntax and structure validation for Get-O365MailboxUsage function
 
.DESCRIPTION
    This script performs basic validation tests that don't require Exchange Online connection:
    - PowerShell syntax validation
    - Parameter validation
    - Function structure validation
    - Help documentation validation
 
.NOTES
    This can be run without Exchange Online connection or the ExchangeOnlineManagement module.
#>


# Test script path
$functionPath = Join-Path $PSScriptRoot "..\Public\Get-O365MailboxUsage.ps1"

Write-Host "=== Get-O365MailboxUsage Basic Validation Tests ===" -ForegroundColor Green
Write-Host "Testing file: $functionPath" -ForegroundColor Gray
Write-Host ""

# Test 1: File exists
Write-Host "Test 1: File Existence" -ForegroundColor Yellow
if (Test-Path $functionPath) {
    Write-Host " [PASS] Function file exists" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Function file not found at: $functionPath" -ForegroundColor Red
    exit 1
}

# Test 2: PowerShell syntax validation
Write-Host "`nTest 2: PowerShell Syntax Validation" -ForegroundColor Yellow
try {
    $scriptContent = Get-Content $functionPath -Raw
    $scriptBlock = [ScriptBlock]::Create($scriptContent)
    Write-Host " [PASS] PowerShell syntax is valid" -ForegroundColor Green
}
catch {
    Write-Host " [FAIL] PowerShell syntax error: $($_.Exception.Message)" -ForegroundColor Red
    exit 1
}

# Test 3: Load function without execution
Write-Host "`nTest 3: Function Loading" -ForegroundColor Yellow
try {
    # Create a new PowerShell session to test loading
    $testSession = [PowerShell]::Create()
    $testSession.AddScript($scriptContent) | Out-Null
    $testSession.Invoke() | Out-Null
    
    if ($testSession.HadErrors) {
        Write-Host " [FAIL] Function loading errors: $($testSession.Streams.Error -join '; ')" -ForegroundColor Red
    } else {
        Write-Host " [PASS] Function loads without errors" -ForegroundColor Green
    }
    $testSession.Dispose()
}
catch {
    Write-Host " [FAIL] Function loading failed: $($_.Exception.Message)" -ForegroundColor Red
}

# Test 4: Function structure validation
Write-Host "`nTest 4: Function Structure Validation" -ForegroundColor Yellow

# Check for function definition
if ($scriptContent -match "function\s+Get-O365MailboxUsage") {
    Write-Host " [PASS] Function definition found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Function definition not found" -ForegroundColor Red
}

# Check for CmdletBinding
if ($scriptContent -match "\[CmdletBinding\(\)\]") {
    Write-Host " [PASS] CmdletBinding attribute found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] CmdletBinding attribute not found" -ForegroundColor Red
}

# Check for parameter block
if ($scriptContent -match "param\s*\(") {
    Write-Host " [PASS] Parameter block found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Parameter block not found" -ForegroundColor Red
}

# Check for begin/process/end blocks
$hasBegin = $scriptContent -match "\s+begin\s*\{"
$hasProcess = $scriptContent -match "\s+process\s*\{"
$hasEnd = $scriptContent -match "\s+end\s*\{"

if ($hasBegin -and $hasProcess -and $hasEnd) {
    Write-Host " [PASS] All pipeline blocks (begin/process/end) found" -ForegroundColor Green
} else {
    Write-Host " [WARN] Missing pipeline blocks - Begin: $hasBegin, Process: $hasProcess, End: $hasEnd" -ForegroundColor Yellow
}

# Test 5: Parameter validation
Write-Host "`nTest 5: Parameter Validation" -ForegroundColor Yellow

# Check for expected parameters
$expectedParams = @(
    "UserPrincipalName",
    "SortBy", 
    "IncludeArchive"
)

$allParamsFound = $true
foreach ($param in $expectedParams) {
    if ($scriptContent -match "\`$$param\b") {
        Write-Host " [PASS] Parameter '$param' found" -ForegroundColor Green
    } else {
        Write-Host " [FAIL] Parameter '$param' not found" -ForegroundColor Red
        $allParamsFound = $false
    }
}

# Check for pipeline input support
if ($scriptContent -match "ValueFromPipeline\s*=\s*\`$true") {
    Write-Host " [PASS] Pipeline input support configured" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Pipeline input support not configured" -ForegroundColor Red
}

# Check for ValidateSet on SortBy
if ($scriptContent -match "ValidateSet.*PercentFull.*UsedSpaceGB.*TotalQuotaGB.*DisplayName") {
    Write-Host " [PASS] SortBy parameter validation found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] SortBy parameter validation not found or incomplete" -ForegroundColor Red
}

# Test 6: Help documentation validation
Write-Host "`nTest 6: Help Documentation Validation" -ForegroundColor Yellow

$helpSections = @{
    "SYNOPSIS" = "\.SYNOPSIS"
    "DESCRIPTION" = "\.DESCRIPTION" 
    "PARAMETER" = "\.PARAMETER"
    "EXAMPLE" = "\.EXAMPLE"
    "NOTES" = "\.NOTES"
}

foreach ($section in $helpSections.GetEnumerator()) {
    if ($scriptContent -match $section.Value) {
        Write-Host " [PASS] Help section '$($section.Key)' found" -ForegroundColor Green
    } else {
        Write-Host " [WARN] Help section '$($section.Key)' not found" -ForegroundColor Yellow
    }
}

# Count examples
$exampleMatches = [regex]::Matches($scriptContent, "\.EXAMPLE")
Write-Host " [INFO] Found $($exampleMatches.Count) usage examples" -ForegroundColor Cyan

# Test 7: Key functionality checks
Write-Host "`nTest 7: Key Functionality Checks" -ForegroundColor Yellow

# Check for Exchange Online connection test
if ($scriptContent -match "Get-ConnectionInformation") {
    Write-Host " [PASS] Exchange Online connection check found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Exchange Online connection check not found" -ForegroundColor Red
}

# Check for error handling
if ($scriptContent -match "try\s*\{.*catch") {
    Write-Host " [PASS] Error handling (try-catch) found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Error handling not found" -ForegroundColor Red
}

# Check for percentage calculation
if ($scriptContent -match "PercentFull.*100") {
    Write-Host " [PASS] Percentage calculation logic found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Percentage calculation logic not found" -ForegroundColor Red
}

# Check for sorting functionality
if ($scriptContent -match "Sort-Object.*PercentFull") {
    Write-Host " [PASS] Sorting functionality found" -ForegroundColor Green
} else {
    Write-Host " [FAIL] Sorting functionality not found" -ForegroundColor Red
}

# Check for GB conversion
if ($scriptContent -match "ConvertTo-GB" -or $scriptContent -match "1GB" -or $scriptContent -match "/.*1024") {
    Write-Host " [PASS] Size conversion logic found" -ForegroundColor Green
} else {
    Write-Host " [WARN] Size conversion logic not clearly identified" -ForegroundColor Yellow
}

# Test 8: Load function and test basic cmdlet info
Write-Host "`nTest 8: Function Cmdlet Information" -ForegroundColor Yellow
try {
    # Load the function
    . $functionPath
    
    # Check if function is available
    $command = Get-Command Get-O365MailboxUsage -ErrorAction Stop
    Write-Host " [PASS] Function loaded and available" -ForegroundColor Green
    
    # Check parameter information
    $params = $command.Parameters
    Write-Host " [INFO] Function has $($params.Count) parameters" -ForegroundColor Cyan
    
    foreach ($expectedParam in $expectedParams) {
        if ($params.ContainsKey($expectedParam)) {
            Write-Host " [PASS] Parameter '$expectedParam' available in loaded function" -ForegroundColor Green
        } else {
            Write-Host " [FAIL] Parameter '$expectedParam' not available in loaded function" -ForegroundColor Red
        }
    }
    
    # Test help
    $help = Get-Help Get-O365MailboxUsage -ErrorAction SilentlyContinue
    if ($help -and $help.Synopsis) {
        Write-Host " [PASS] Help documentation accessible" -ForegroundColor Green
        Write-Host " [INFO] Synopsis: $($help.Synopsis)" -ForegroundColor Cyan
    } else {
        Write-Host " [WARN] Help documentation not accessible" -ForegroundColor Yellow
    }
}
catch {
    Write-Host " [FAIL] Could not load function: $($_.Exception.Message)" -ForegroundColor Red
}

# Summary
Write-Host "`n" + "="*60 -ForegroundColor Green
Write-Host "VALIDATION SUMMARY" -ForegroundColor Green
Write-Host "="*60 -ForegroundColor Green

Write-Host "Basic syntax and structure validation completed." -ForegroundColor Cyan
Write-Host "If all critical tests passed, the function should work correctly" -ForegroundColor Cyan
Write-Host "when connected to Exchange Online." -ForegroundColor Cyan
Write-Host ""
Write-Host "Next steps:" -ForegroundColor Yellow
Write-Host "1. Install ExchangeOnlineManagement module if not already installed" -ForegroundColor White
Write-Host "2. Run Connect-ExchangeOnline to establish connection" -ForegroundColor White  
Write-Host "3. Run the manual integration tests: .\Test-O365MailboxUsage-Manual.ps1" -ForegroundColor White
Write-Host "4. Run Pester unit tests: Invoke-Pester .\Get-O365MailboxUsage.Tests.ps1" -ForegroundColor White

Write-Host "`nValidation completed at $(Get-Date)" -ForegroundColor Gray