Tests/sessions/Get-RdpSessionLock.Tests.ps1
|
#Requires -Version 5.1 BeforeAll { # Import module $script:modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\PSWinOps.psd1' Import-Module -Name $script:modulePath -Force -ErrorAction Stop # Mock event XML for locked session $script:mockLockEventXml = @' <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <EventID>4800</EventID> </System> <EventData> <Data Name="TargetUserSid">S-1-5-21-123456789-1234567890-123456789-1001</Data> <Data Name="TargetUserName">testuser</Data> <Data Name="TargetDomainName">TESTDOMAIN</Data> <Data Name="SessionName">RDP-Tcp#2</Data> </EventData> </Event> '@ # Helper function to create properly mocked event objects with ToXml() method function script:New-MockEventObject { param( [Parameter(Mandatory = $true)] [int]$EventId, [Parameter(Mandatory = $true)] [string]$XmlContent ) $mockEvent = [PSCustomObject]@{ Id = $EventId TimeCreated = Get-Date } # Add ToXml() as a proper ScriptMethod $mockEvent | Add-Member -MemberType ScriptMethod -Name 'ToXml' -Value { return $XmlContent }.GetNewClosure() -Force return $mockEvent } # Create the mock lock event using the helper $script:mockLockEvent = New-MockEventObject -EventId 4800 -XmlContent $script:mockLockEventXml } Describe -Name 'Get-RdpSessionLock' -Fixture { Context -Name 'When querying lock events successfully' -Fixture { BeforeEach { Mock -CommandName 'Get-WinEvent' -ModuleName PSWinOps -MockWith { return $script:mockLockEvent } } It -Name 'Should return PSCustomObject with correct type name' -Test { $result = Get-RdpSessionLock $result.PSObject.TypeNames | Should -Contain 'PSWinOps.RdpSessionLock' } It -Name 'Should include all required properties' -Test { $result = Get-RdpSessionLock $result.PSObject.Properties.Name | Should -Contain 'TimeCreated' $result.PSObject.Properties.Name | Should -Contain 'ComputerName' $result.PSObject.Properties.Name | Should -Contain 'UserName' $result.PSObject.Properties.Name | Should -Contain 'Action' $result.PSObject.Properties.Name | Should -Contain 'EventID' } It -Name 'Should map event ID 4800 to Locked action' -Test { $result = Get-RdpSessionLock $result.Action | Should -Be 'Locked' } It -Name 'Should format username as DOMAIN\User' -Test { $result = Get-RdpSessionLock $result.UserName | Should -Be 'TESTDOMAIN\testuser' } It -Name 'Should invoke Get-WinEvent exactly once' -Test { Get-RdpSessionLock Should -Invoke -CommandName 'Get-WinEvent' -ModuleName PSWinOps -Times 1 -Exactly } } Context -Name 'When no events are found' -Fixture { BeforeEach { Mock -CommandName 'Get-WinEvent' -ModuleName PSWinOps -MockWith { return $null } } It -Name 'Should return no output' -Test { $result = Get-RdpSessionLock $result | Should -BeNullOrEmpty } } Context -Name 'When access is denied to Security log' -Fixture { BeforeEach { Mock -CommandName 'Get-WinEvent' -ModuleName PSWinOps -MockWith { throw [System.UnauthorizedAccessException]::new('Access denied') } } It -Name 'Should write error and not throw' -Test { { Get-RdpSessionLock -ErrorAction SilentlyContinue } | Should -Not -Throw } It -Name 'Should return no output' -Test { $result = Get-RdpSessionLock -ErrorAction SilentlyContinue $result | Should -BeNullOrEmpty } } Context -Name 'When querying multiple computers via pipeline' -Fixture { BeforeEach { Mock -CommandName 'Get-WinEvent' -ModuleName PSWinOps -MockWith { return $script:mockLockEvent } } It -Name 'Should process all computers' -Test { $result = @('SRV01', 'SRV02') | Get-RdpSessionLock $result.Count | Should -Be 2 } It -Name 'Should invoke Get-WinEvent once per computer' -Test { @('SRV01', 'SRV02', 'SRV03') | Get-RdpSessionLock Should -Invoke -CommandName 'Get-WinEvent' -ModuleName PSWinOps -Times 3 -Exactly } } Context -Name 'When custom StartTime is provided' -Fixture { BeforeEach { Mock -CommandName 'Get-WinEvent' -ModuleName PSWinOps -MockWith { return $script:mockLockEvent } } It -Name 'Should accept custom StartTime parameter' -Test { $customStart = (Get-Date).AddDays(-30) { Get-RdpSessionLock -StartTime $customStart } | Should -Not -Throw } } } |