Test-GpadTools.ps1

<#
.SYNOPSIS
    Comprehensive test script for GpadTools PowerShell module.
 
.DESCRIPTION
    This script tests all public functions in the GpadTools module to ensure they work correctly.
    It includes tests for parameter validation, error handling, and basic functionality.
     
    IMPORTANT: This script is designed to test functions safely without making destructive changes.
    Some tests use -WhatIf where available and validate parameters without executing operations.
 
.PREREQUISITES
    - GpadTools module must be installed and imported
    - Microsoft Graph PowerShell SDK must be installed
    - Active Directory PowerShell module must be available (for AD-related tests)
    - Must be connected to Microsoft Graph with appropriate permissions
    - Must have access to Active Directory (for AD-related tests)
 
 
 MANUAL TESTING
    $gId = 'defcadcf-8465-468f-b4c7-a949b684b71a'
    Get-GpadGroupFromEntra $gId
    Get-GpadGroupMembersFromEntra $gId
    Get-GpadGroupFromAD $gId
    Get-GpadGroupMembersFromAD -GroupFromAD (Get-GpadGroupFromAD $gId)
    Confirm-GpadReconciliationNeeded -GroupId defcadcf-8465-468f-b4c7-a949b684b71a
 
.EXAMPLE
    .\Test-GpadTools.ps1 -TestLevel Basic
     
.EXAMPLE
    .\Test-GpadTools.ps1 -TestLevel Full -GroupId 'defcadcf-8465-468f-b4c7-a949b684b71a'
 
.EXAMPLE
    .\Test-GpadTools.ps1 -TestLevel Full -GroupId "12345678-1234-1234-1234-123456789012" -AdditionalGroupIds '0572a1e5-6761-4290-8511-c78845d20cf4,11b7de5b-9f75-4cf1-9599-88aaf1f61d28'
 
.EXAMPLE
    .\Test-GpadTools.ps1 -TestLevel Basic -SkipGraphTests -SkipADTests
 
.NOTES
    Version: 1.1
    Author: Test Suite for GpadTools
    Created: June 23, 2025
#>


[CmdletBinding()]
param(
    # Test level: Basic (parameter validation), Full (includes live calls)
    [Parameter(Mandatory = $false)]
    [ValidateSet("Basic", "Full")]
    [string] $TestLevel = "Basic",
      # Sample Group ID for testing (must be a valid GUID of an existing group)
    [Parameter(Mandatory = $false)]
    [string] $GroupId,
    
    # Additional Group IDs for multi-group testing (comma-separated string of valid GUIDs)
    [Parameter(Mandatory = $false)]
    [string] $AdditionalGroupIds,
    
    # Domain name for synchronization tests
    [Parameter(Mandatory = $false)]
    [string] $DomainName = "contoso.com",
    
    # Group Writeback OU for AD tests
    [Parameter(Mandatory = $false)]
    [string] $GroupWritebackOU = "OU=Groups,DC=contoso,DC=com",
    
    # Skip tests that require Graph connection
    [Parameter(Mandatory = $false)]
    [switch] $SkipGraphTests,
    
    # Skip tests that require Active Directory
    [Parameter(Mandatory = $false)]
    [switch] $SkipADTests
)

# Test results tracking
$script:TestResults = @()
$script:PassedTests = 0
$script:FailedTests = 0
$script:SkippedTests = 0

# Ensure Microsoft Graph PowerShell SDK is connected
Connect-MgGraph -Scopes "Application.ReadWrite.All, Directory.ReadWrite.All, Synchronization.ReadWrite.All"

# Handle Group ID validation and setup
if ($GroupId) {
    # Validate provided GroupId is a valid GUID format
    try {
        $testGuid = [System.Guid]::Parse($GroupId)
        Write-Verbose "Using provided Group ID: $GroupId"
    }
    catch {
        Write-Error "Invalid Group ID format. Please provide a valid GUID."
        exit 1
    }
} else {
    Write-Warning "No Group ID provided. Tests requiring valid Group IDs will be skipped."
    Write-Host "To run full tests, provide a valid Group ID: -GroupId 'your-group-guid-here'" -ForegroundColor Yellow
}

# Parse additional Group IDs if provided
$AdditionalGroupIdList = @()
if ($AdditionalGroupIds) {
    $AdditionalGroupIdList = $AdditionalGroupIds -split ',' | ForEach-Object {
        $trimmedId = $_.Trim()
        try {
            $testGuid = [System.Guid]::Parse($trimmedId)
            $trimmedId
        }
        catch {
            Write-Warning "Invalid additional Group ID format: $trimmedId (skipping)"
            $null
        }
    } | Where-Object { $_ -ne $null }
}

# Create test Group ID arrays for multi-group tests
$MultipleGroupIds = @()
if ($GroupId) {
    $MultipleGroupIds += $GroupId
}
if ($AdditionalGroupIdList.Count -gt 0) {
    $MultipleGroupIds += $AdditionalGroupIdList[0..([Math]::Min(2, $AdditionalGroupIdList.Count - 1))]
} elseif ($GroupId) {
    # If no additional IDs provided, we'll only use the single GroupId for multi-group tests
    Write-Verbose "Only one Group ID available for multi-group tests"
}

#region Helper Functions

function Write-TestResult {
    param(
        [string] $TestName,
        [string] $Status,
        [string] $Message = "",
        [string] $Details = ""
    )
    
    $result = [PSCustomObject]@{
        TestName = $TestName
        Status = $Status
        Message = $Message
        Details = $Details
        Timestamp = Get-Date
    }
    
    $script:TestResults += $result
    
    $color = switch ($Status) {
        "PASS" { "Green"; $script:PassedTests++ }
        "FAIL" { "Red"; $script:FailedTests++ }
        "SKIP" { "Yellow"; $script:SkippedTests++ }
        default { "White" }
    }
    
    Write-Host "[$Status] $TestName" -ForegroundColor $color
    if ($Message) {
        Write-Host " $Message" -ForegroundColor Gray
    }
    if ($Details) {
        Write-Host " Details: $Details" -ForegroundColor DarkGray
    }
}

function Test-Function {
    param(
        [string] $FunctionName,
        [scriptblock] $TestScript,
        [string] $Description = ""
    )
    
    try {
        if ($Description) {
            Write-Host "`n=== Testing $FunctionName - $Description ===" -ForegroundColor Cyan
        } else {
            Write-Host "`n=== Testing $FunctionName ===" -ForegroundColor Cyan
        }
        
        & $TestScript
    }
    catch {
        Write-TestResult -TestName "$FunctionName - $Description" -Status "FAIL" -Message $_.Exception.Message -Details $_.ScriptStackTrace
    }
}

function Test-ParameterValidation {
    param(
        [string] $FunctionName,
        [hashtable] $ValidParameters,
        [hashtable] $InvalidParameters = @{},
        [switch] $RequiresValidGroupId
    )
    
    # Skip tests that require valid Group IDs if none provided
    if ($RequiresValidGroupId -and -not $GroupId) {
        Write-TestResult -TestName "$FunctionName - Parameter Validation" -Status "SKIP" -Message "Requires valid Group ID (not provided)"
        return
    }
    
    # Test with valid parameters
    try {
        $cmd = Get-Command $FunctionName -ErrorAction Stop
        Write-TestResult -TestName "$FunctionName - Function Exists" -Status "PASS"        # Test parameter binding
        foreach ($paramSet in $ValidParameters.GetEnumerator()) {
            try {
                if ($paramSet.Value.Count -gt 0) {
                    # Use proper splatting syntax for hashtables
                    $splat = $paramSet.Value
                    $null = & $FunctionName @splat -WhatIf -ErrorAction Stop 2>$null
                } else {
                    $null = & $FunctionName -WhatIf -ErrorAction Stop 2>$null
                }
                Write-TestResult -TestName "$FunctionName - Valid Parameters ($($paramSet.Key))" -Status "PASS"
            }
            catch {
                if ($_.Exception.Message -like "*WhatIf*" -or $_.Exception.Message -like "*not support*") {
                    # Function doesn't support -WhatIf, try without it for parameter validation
                    try {
                        $help = Get-Help $FunctionName -ErrorAction SilentlyContinue
                        Write-TestResult -TestName "$FunctionName - Parameter Validation ($($paramSet.Key))" -Status "PASS" -Message "Parameters validated (no WhatIf support)"
                    }
                    catch {
                        Write-TestResult -TestName "$FunctionName - Valid Parameters ($($paramSet.Key))" -Status "FAIL" -Message $_.Exception.Message
                    }
                }
                else {
                    Write-TestResult -TestName "$FunctionName - Valid Parameters ($($paramSet.Key))" -Status "FAIL" -Message $_.Exception.Message
                }
            }
        }
        
        # Test invalid parameters
        foreach ($paramSet in $InvalidParameters.GetEnumerator()) {
            try {
                if ($paramSet.Value.Count -gt 0) {
                    # Use proper splatting syntax for hashtables
                    $splat = $paramSet.Value
                    $null = & $FunctionName @splat -ErrorAction Stop
                } else {
                    $null = & $FunctionName -ErrorAction Stop
                }
                Write-TestResult -TestName "$FunctionName - Invalid Parameters Should Fail ($($paramSet.Key))" -Status "FAIL" -Message "Should have failed but didn't"
            }
            catch {
                Write-TestResult -TestName "$FunctionName - Invalid Parameters Correctly Rejected ($($paramSet.Key))" -Status "PASS"
            }
        }
    }
    catch {
        Write-TestResult -TestName "$FunctionName - Function Exists" -Status "FAIL" -Message $_.Exception.Message
    }
}

function Test-GraphConnection {
    if ($SkipGraphTests) {
        Write-TestResult -TestName "Graph Connection" -Status "SKIP" -Message "Graph tests skipped by parameter"
        return $false
    }
    
    try {
        $context = Get-MgContext -ErrorAction Stop
        if ($context) {
            Write-TestResult -TestName "Graph Connection" -Status "PASS" -Message "Connected to tenant: $($context.TenantId)"
            return $true
        } else {
            Write-TestResult -TestName "Graph Connection" -Status "FAIL" -Message "Not connected to Microsoft Graph"
            return $false
        }
    }
    catch {
        Write-TestResult -TestName "Graph Connection" -Status "FAIL" -Message "Microsoft Graph module not available or not connected"
        return $false
    }
}

function Test-ADConnection {
    if ($SkipADTests) {
        Write-TestResult -TestName "AD Connection" -Status "SKIP" -Message "AD tests skipped by parameter"
        return $false
    }
    
    try {
        $domain = Get-ADDomain -ErrorAction Stop
        Write-TestResult -TestName "AD Connection" -Status "PASS" -Message "Connected to domain: $($domain.DNSRoot)"
        return $true
    }
    catch {
        Write-TestResult -TestName "AD Connection" -Status "FAIL" -Message "Active Directory module not available or not connected"
        return $false
    }
}

#endregion

#region Main Test Execution

Write-Host "========================================" -ForegroundColor Magenta
Write-Host "GpadTools Module Test Suite" -ForegroundColor Magenta
Write-Host "Test Level: $TestLevel" -ForegroundColor Magenta
if ($GroupId) {
    Write-Host "Test Group ID: $GroupId" -ForegroundColor Magenta
    if ($MultipleGroupIds.Count -gt 1) {
        Write-Host "Additional Group IDs: $($MultipleGroupIds[1..($MultipleGroupIds.Count-1)] -join ', ')" -ForegroundColor Magenta
    }
} else {
    Write-Host "Test Group ID: Not provided (some tests will be skipped)" -ForegroundColor Yellow
}
Write-Host "========================================" -ForegroundColor Magenta

# Check if module is loaded
try {
    $module = Get-Module GpadTools -ErrorAction Stop
    Write-TestResult -TestName "Module Import" -Status "PASS" -Message "GpadTools version $($module.Version) loaded"
}
catch {
    Write-TestResult -TestName "Module Import" -Status "FAIL" -Message "GpadTools module not loaded"
    Write-Host "Please import the GpadTools module first: Import-Module GpadTools" -ForegroundColor Red
    exit 1
}

# Check prerequisites
$hasGraphConnection = Test-GraphConnection
$hasADConnection = Test-ADConnection

#region Test Custom Extension Functions

Test-Function -FunctionName "Get-GpadCustomExtensionApplication" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Get-GpadCustomExtensionApplication" -ValidParameters @{
        "Default" = @{}
        "WithCustomName" = @{ CustomExtApplicationName = "TestApp" }
    }
}

Test-Function -FunctionName "Get-GpadCustomExtensionAppServicePrincipal" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Get-GpadCustomExtensionAppServicePrincipal" -ValidParameters @{
        "Default" = @{}
        "WithCustomName" = @{ CustomExtApplicationName = "TestApp" }
    }
}

Test-Function -FunctionName "Get-GpadCustomExtensionProperty" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Get-GpadCustomExtensionProperty" -ValidParameters @{
        "Default" = @{}
        "WithCustomName" = @{ CustomExtApplicationName = "TestApp" }
    }
}

Test-Function -FunctionName "Get-GpadWritebackEnabledExtensionName" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Get-GpadWritebackEnabledExtensionName" -ValidParameters @{
        "Default" = @{}
        "WithCustomAttribute" = @{ CustomExtAttributeName = "TestAttribute" }
        "WithCustomApp" = @{ CustomExtApplicationName = "TestApp" }
        "WithBoth" = @{ CustomExtAttributeName = "TestAttribute"; CustomExtApplicationName = "TestApp" }
    }
}

Test-Function -FunctionName "New-GpadCustomExtensionApplication" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "New-GpadCustomExtensionApplication" -ValidParameters @{
        "Default" = @{}
        "WithCustomName" = @{ CustomExtApplicationName = "TestApp" }
    }
}

Test-Function -FunctionName "New-GpadCustomExtensionAppServicePrincipal" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "New-GpadCustomExtensionAppServicePrincipal" -ValidParameters @{
        "Default" = @{}
        "WithCustomName" = @{ CustomExtApplicationName = "TestApp" }
    }
}

Test-Function -FunctionName "New-GpadCustomExtensionProperty" -Description "Parameter Validation with ValidateSet" -TestScript {
    Test-ParameterValidation -FunctionName "New-GpadCustomExtensionProperty" -ValidParameters @{
        "Default" = @{}
        "BooleanType" = @{ CustomExtAttributeType = "Boolean" }
        "StringType" = @{ CustomExtAttributeType = "String" }
        "IntegerType" = @{ CustomExtAttributeType = "Integer" }
        "GroupTarget" = @{ CustomExtAttributeTargetObjects = "Group" }
        "UserTarget" = @{ CustomExtAttributeTargetObjects = "User" }
    } -InvalidParameters @{
        "InvalidType" = @{ CustomExtAttributeType = "InvalidType" }
        "InvalidTarget" = @{ CustomExtAttributeTargetObjects = "InvalidTarget" }
    }
}

Test-Function -FunctionName "Remove-GpadCustomExtensionProperty" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Remove-GpadCustomExtensionProperty" -ValidParameters @{
        "Default" = @{}
        "WithCustomAttribute" = @{ CustomExtAttributeName = "TestAttribute" }
        "WithCustomApp" = @{ CustomExtApplicationName = "TestApp" }
    }
}

#endregion

#region Test Group Configuration Functions

Test-Function -FunctionName "Set-GpadWritebackEnabledExtension" -Description "Parameter Validation" -TestScript {
    if ($GroupId) {
        $validParams = @{
            "SingleGroup" = @{ GroupId = $GroupId; IsEnabled = $true }
        }
        if ($MultipleGroupIds.Count -gt 1) {
            $validParams["MultipleGroups"] = @{ GroupId = $MultipleGroupIds; IsEnabled = $false }
        }
        Test-ParameterValidation -FunctionName "Set-GpadWritebackEnabledExtension" -ValidParameters $validParams -RequiresValidGroupId
    } else {
        Test-ParameterValidation -FunctionName "Set-GpadWritebackEnabledExtension" -ValidParameters @{} -RequiresValidGroupId
    }
}

Test-Function -FunctionName "Set-GpadWritebackConfiguration" -Description "Parameter Validation" -TestScript {
    if ($GroupId) {
        $validParams = @{
            "SingleGroup" = @{ GroupId = $GroupId; IsEnabled = $true }
        }
        if ($MultipleGroupIds.Count -gt 1) {
            $validParams["MultipleGroups"] = @{ GroupId = $MultipleGroupIds; IsEnabled = $false }
        }
        Test-ParameterValidation -FunctionName "Set-GpadWritebackConfiguration" -ValidParameters $validParams -RequiresValidGroupId
    } else {
        Test-ParameterValidation -FunctionName "Set-GpadWritebackConfiguration" -ValidParameters @{} -RequiresValidGroupId
    }
}

Test-Function -FunctionName "Update-GpadWritebackEnabledExtension" -Description "Basic Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Update-GpadWritebackEnabledExtension" -ValidParameters @{
        "Default" = @{}
    }
}

#endregion

#region Test Group Retrieval Functions

Test-Function -FunctionName "Get-GpadGroupFromEntra" -Description "Parameter Validation" -TestScript {
    if ($GroupId) {
        $validParams = @{
            "AllGroups" = @{}
            "SingleGroup" = @{ GroupId = $GroupId }
        }
        if ($MultipleGroupIds.Count -gt 1) {
            $validParams["MultipleGroups"] = @{ GroupId = $MultipleGroupIds }
        }
        Test-ParameterValidation -FunctionName "Get-GpadGroupFromEntra" -ValidParameters $validParams
    } else {
        Test-ParameterValidation -FunctionName "Get-GpadGroupFromEntra" -ValidParameters @{
            "AllGroups" = @{}
        }
    }
}

Test-Function -FunctionName "Get-GpadGroupMembersFromEntra" -Description "Parameter Validation" -TestScript {
    if ($GroupId) {
        Test-ParameterValidation -FunctionName "Get-GpadGroupMembersFromEntra" -ValidParameters @{
            "BasicCall" = @{ GroupId = $GroupId }
            "OnPremisesOnly" = @{ GroupId = $GroupId; onPremisesSyncEnabledMembers = $true }
        } -RequiresValidGroupId
    } else {
        Test-ParameterValidation -FunctionName "Get-GpadGroupMembersFromEntra" -ValidParameters @{} -RequiresValidGroupId
    }
}

Test-Function -FunctionName "Get-GpadGroupFromAD" -Description "Parameter Validation" -TestScript {
    if ($GroupId) {
        Test-ParameterValidation -FunctionName "Get-GpadGroupFromAD" -ValidParameters @{
            "BasicCall" = @{ GroupId = $GroupId }
            "WithSearchBase" = @{ GroupId = $GroupId; GroupWritebackOU = $GroupWritebackOU }
        } -RequiresValidGroupId
    } else {
        Test-ParameterValidation -FunctionName "Get-GpadGroupFromAD" -ValidParameters @{} -RequiresValidGroupId
    }
}

Test-Function -FunctionName "Get-GpadGroupMembersFromAD" -Description "Parameter Validation" -TestScript {
    # This function requires an AD group object, so we'll test parameter binding differently
    try {
        $cmd = Get-Command "Get-GpadGroupMembersFromAD" -ErrorAction Stop
        $params = $cmd.Parameters
        if ($params.ContainsKey('GroupFromAD')) {
            Write-TestResult -TestName "Get-GpadGroupMembersFromAD - Function Exists" -Status "PASS"
            Write-TestResult -TestName "Get-GpadGroupMembersFromAD - Required Parameter Defined" -Status "PASS" -Message "GroupFromAD parameter exists"
        } else {
            Write-TestResult -TestName "Get-GpadGroupMembersFromAD - Required Parameter Missing" -Status "FAIL"
        }
    }
    catch {
        Write-TestResult -TestName "Get-GpadGroupMembersFromAD - Function Exists" -Status "FAIL" -Message $_.Exception.Message
    }
}

#endregion

#region Test Reconciliation Functions

Test-Function -FunctionName "Confirm-GpadReconciliationNeeded" -Description "Parameter Validation" -TestScript {
    if ($GroupId) {
        $validParams = @{
            "BasicCall" = @{ GroupId = $GroupId }
            "WithSearchBase" = @{ GroupId = $GroupId; GroupWritebackOU = $GroupWritebackOU }
        }
        if ($MultipleGroupIds.Count -gt 1) {
            $validParams["MultipleGroups"] = @{ GroupId = $MultipleGroupIds }
        }
        Test-ParameterValidation -FunctionName "Confirm-GpadReconciliationNeeded" -ValidParameters $validParams -RequiresValidGroupId
    } else {
        Test-ParameterValidation -FunctionName "Confirm-GpadReconciliationNeeded" -ValidParameters @{} -RequiresValidGroupId
    }
}

Test-Function -FunctionName "Get-GpadSynchronizationIdentifiers" -Description "Parameter Validation" -TestScript {
    Test-ParameterValidation -FunctionName "Get-GpadSynchronizationIdentifiers" -ValidParameters @{
        "WithDomain" = @{ DomainName = $DomainName }
    }
}

#endregion

#region Full Tests (Live Environment)

if ($TestLevel -eq "Full") {
    Write-Host "`n=== Running Full Tests (Live Environment) ===" -ForegroundColor Magenta
    
    if ($hasGraphConnection) {
        Test-Function -FunctionName "Get-GpadCustomExtensionApplication" -Description "Live Test" -TestScript {
            try {
                $result = Get-GpadCustomExtensionApplication -ErrorAction Stop
                if ($result) {
                    Write-TestResult -TestName "Get-GpadCustomExtensionApplication - Live Call" -Status "PASS" -Message "Found custom extensions application"
                } else {
                    Write-TestResult -TestName "Get-GpadCustomExtensionApplication - Live Call" -Status "PASS" -Message "No custom extensions application found (expected)"
                }
            }
            catch {
                Write-TestResult -TestName "Get-GpadCustomExtensionApplication - Live Call" -Status "FAIL" -Message $_.Exception.Message
            }
        }
        
        Test-Function -FunctionName "Get-GpadWritebackEnabledExtensionName" -Description "Live Test" -TestScript {
            try {
                $result = Get-GpadWritebackEnabledExtensionName -ErrorAction Stop
                if ($result) {
                    Write-TestResult -TestName "Get-GpadWritebackEnabledExtensionName - Live Call" -Status "PASS" -Message "Extension name: $result"
                } else {
                    Write-TestResult -TestName "Get-GpadWritebackEnabledExtensionName - Live Call" -Status "PASS" -Message "No extension found (expected if not configured)"
                }
            }
            catch {
                Write-TestResult -TestName "Get-GpadWritebackEnabledExtensionName - Live Call" -Status "FAIL" -Message $_.Exception.Message
            }
        }
          Test-Function -FunctionName "Get-GpadGroupFromEntra" -Description "Live Test - Specific Group" -TestScript {
            if ($GroupId) {
                try {
                    $result = Get-GpadGroupFromEntra -GroupId $GroupId -ErrorAction Stop
                    if ($result) {
                        Write-TestResult -TestName "Get-GpadGroupFromEntra - Specific Group" -Status "PASS" -Message "Retrieved group: $($result.DisplayName)"
                    } else {
                        Write-TestResult -TestName "Get-GpadGroupFromEntra - Specific Group" -Status "FAIL" -Message "Group not found with ID: $GroupId"
                    }
                }
                catch {
                    Write-TestResult -TestName "Get-GpadGroupFromEntra - Specific Group" -Status "FAIL" -Message $_.Exception.Message
                }
            } else {
                Write-TestResult -TestName "Get-GpadGroupFromEntra - Specific Group" -Status "SKIP" -Message "No valid Group ID provided"
            }
        }
        
        Test-Function -FunctionName "Get-GpadGroupMembersFromEntra" -Description "Live Test" -TestScript {
            if ($GroupId) {
                try {
                    $result = Get-GpadGroupMembersFromEntra -GroupId $GroupId -ErrorAction Stop
                    Write-TestResult -TestName "Get-GpadGroupMembersFromEntra - Live Call" -Status "PASS" -Message "Retrieved $($result.Count) members"
                }
                catch {
                    Write-TestResult -TestName "Get-GpadGroupMembersFromEntra - Live Call" -Status "FAIL" -Message $_.Exception.Message
                }
            } else {
                Write-TestResult -TestName "Get-GpadGroupMembersFromEntra - Live Call" -Status "SKIP" -Message "No valid Group ID provided"
            }
        }
        
        Test-Function -FunctionName "Get-GpadSynchronizationIdentifiers" -Description "Live Test" -TestScript {
            try {
                $result = Get-GpadSynchronizationIdentifiers -DomainName $DomainName -ErrorAction Stop
                if ($result) {
                    Write-TestResult -TestName "Get-GpadSynchronizationIdentifiers - Live Call" -Status "PASS" -Message "Found sync configuration for $DomainName"
                } else {
                    Write-TestResult -TestName "Get-GpadSynchronizationIdentifiers - Live Call" -Status "PASS" -Message "No sync configuration found for $DomainName (expected)"
                }
            }
            catch {
                if ($_.Exception.Message -like "*not found*") {
                    Write-TestResult -TestName "Get-GpadSynchronizationIdentifiers - Live Call" -Status "PASS" -Message "Domain not found (expected for test domain)"
                } else {
                    Write-TestResult -TestName "Get-GpadSynchronizationIdentifiers - Live Call" -Status "FAIL" -Message $_.Exception.Message
                }
            }
        }
    } else {
        Write-TestResult -TestName "Full Tests - Graph Functions" -Status "SKIP" -Message "No Graph connection available"
    }
      if ($hasADConnection) {
        Test-Function -FunctionName "Get-GpadGroupFromAD" -Description "Live Test" -TestScript {
            if ($GroupId) {
                try {
                    $result = Get-GpadGroupFromAD -GroupId $GroupId -ErrorAction Stop
                    if ($result) {
                        Write-TestResult -TestName "Get-GpadGroupFromAD - Live Call" -Status "PASS" -Message "Found AD group for ID $GroupId"
                    } else {
                        Write-TestResult -TestName "Get-GpadGroupFromAD - Live Call" -Status "PASS" -Message "No AD group found for test ID (expected if group not written back)"
                    }
                }
                catch {
                    Write-TestResult -TestName "Get-GpadGroupFromAD - Live Call" -Status "PASS" -Message "No group found with test ID (expected if group not written back)"
                }
            } else {
                Write-TestResult -TestName "Get-GpadGroupFromAD - Live Call" -Status "SKIP" -Message "No valid Group ID provided"
            }
        }
        
        Test-Function -FunctionName "Confirm-GpadReconciliationNeeded" -Description "Live Test" -TestScript {
            if ($GroupId) {
                try {
                    $result = Confirm-GpadReconciliationNeeded -GroupId $GroupId -ErrorAction Stop
                    if ($result) {
                        Write-TestResult -TestName "Confirm-GpadReconciliationNeeded - Live Call" -Status "PASS" -Message "Reconciliation check result: $($result.Result)"
                    } else {
                        Write-TestResult -TestName "Confirm-GpadReconciliationNeeded - Live Call" -Status "FAIL" -Message "No result returned"
                    }
                }
                catch {
                    Write-TestResult -TestName "Confirm-GpadReconciliationNeeded - Live Call" -Status "FAIL" -Message $_.Exception.Message
                }
            } else {
                Write-TestResult -TestName "Confirm-GpadReconciliationNeeded - Live Call" -Status "SKIP" -Message "No valid Group ID provided"
            }
        }
    } else {
        Write-TestResult -TestName "Full Tests - AD Functions" -Status "SKIP" -Message "No AD connection available"
    }
}

#endregion

#region Test Summary

Write-Host "`n========================================" -ForegroundColor Magenta
Write-Host "Test Summary" -ForegroundColor Magenta
Write-Host "========================================" -ForegroundColor Magenta

Write-Host "Total Tests: $($script:TestResults.Count)" -ForegroundColor White
Write-Host "Passed: $script:PassedTests" -ForegroundColor Green
Write-Host "Failed: $script:FailedTests" -ForegroundColor Red
Write-Host "Skipped: $script:SkippedTests" -ForegroundColor Yellow

if ($script:FailedTests -gt 0) {
    Write-Host "`nFailed Tests:" -ForegroundColor Red
    $script:TestResults | Where-Object { $_.Status -eq "FAIL" } | ForEach-Object {
        Write-Host " - $($_.TestName): $($_.Message)" -ForegroundColor Red
    }
}

# Export detailed results
$resultsPath = "GpadTools-TestResults-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"
$script:TestResults | Export-Csv -Path $resultsPath -NoTypeInformation
Write-Host "`nDetailed results exported to: $resultsPath" -ForegroundColor Cyan

# Exit with appropriate code
if ($script:FailedTests -eq 0) {
    Write-Host "`nAll tests completed successfully!" -ForegroundColor Green
    exit 0
} else {
    Write-Host "`nSome tests failed. Please review the results." -ForegroundColor Red
    exit 1
}

#endregion