param([string]$BuildFolder = 'ApMode') if ($PSVersionTable.PSEdition -ne 'Desktop') { & "$env:SystemRoot/System32/WindowsPowerShell/v1.0/powershell.exe" -NoProfile -STA -ExecutionPolicy Bypass -File $PSCommandPath -BuildFolder $BuildFolder exit $LASTEXITCODE } $ErrorActionPreference = 'Stop' function Assert-Ap($condition, $message) { if (-not $condition) { throw $message } } Add-Type -AssemblyName PresentationFramework $apAssemblyPath = Join-Path $PSScriptRoot "DCT_test/bin/$BuildFolder/DCT_test.exe" [void][Reflection.Assembly]::LoadFrom($apAssemblyPath) $apWindow = New-Object DCT_test.MainWindow try { $mode = $apWindow.FindName('ComboNetworkMode') $port = $apWindow.FindName('TextPort') $controls = $apWindow.FindName('ApControls') $externalGuide = $apWindow.FindName('ExternalApGuide') Assert-Ap ($mode.SelectedIndex -eq 0 -and $port.Text -eq '6000' -and $port.IsEnabled) 'Direct default must remain editable 6000' $mode.SelectedIndex = 1 $ips = $apWindow.FindName('ComboIp') Assert-Ap ($port.Text -eq '6000' -and $port.IsEnabled -and $ips.IsEnabled -and $controls.Visibility -eq 'Collapsed' -and $externalGuide.Visibility -eq 'Visible') 'External AP current IP and editable port, no hotspot controls' $freePortListener = [Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, 0) $freePortListener.Start() $freePort = $freePortListener.LocalEndpoint.Port $freePortListener.Stop() $ips.Items.Add('127.0.0.1') | Out-Null $ips.SelectedItem = '127.0.0.1' $port.Text = $freePort.ToString() $toggle = $apWindow.GetType().GetMethod('BtnToggleServer_Click', [Reflection.BindingFlags]'Instance,NonPublic') $toggle.Invoke($apWindow, @($null, [Windows.RoutedEventArgs]::new())) | Out-Null Assert-Ap ($apWindow.FindName('TextServerStatus').Text -eq "AP 대기 (127.0.0.1:$freePort)") 'AP must use the selected current IP and entered port' Assert-Ap (-not $mode.IsEnabled -and -not $ips.IsEnabled -and -not $port.IsEnabled) 'Running server must lock mode/address/port' $toggle.Invoke($apWindow, @($null, [Windows.RoutedEventArgs]::new())) | Out-Null Assert-Ap ($mode.IsEnabled -and $ips.IsEnabled -and $port.IsEnabled) 'Stopped external AP must restore endpoint editing' $mode.SelectedIndex = 2 Assert-Ap ($externalGuide.Visibility -eq 'Collapsed') 'Hotspot must hide external router guide' Assert-Ap ($port.Text -eq '5000' -and -not $port.IsEnabled -and $controls.Visibility -eq 'Visible') 'AP controls/fixed port' Assert-Ap ($apWindow.FindName('ComboIp').SelectedItem -eq '192.168.4.1') 'AP fixed IP' $mode.SelectedIndex = 0 Assert-Ap ($port.Text -eq '6000' -and $port.IsEnabled -and $controls.Visibility -eq 'Collapsed' -and $externalGuide.Visibility -eq 'Collapsed') 'Direct restore' } finally { $apWindow.Close() } Write-Output 'PASS: WPF external AP current IP/custom port/start/stop locks, fixed hotspot and Direct restore' # Validate the actual helper with mocked network inventory: no UAC, NIC or # firewall mutations are made by these checks. $global:apVerificationAdapters = @([pscustomobject]@{Status='Up'; InterfaceDescription='Microsoft Wi-Fi Direct Virtual Adapter'; ifIndex=10}) $global:apVerificationAddresses = @([pscustomobject]@{IPAddress='192.168.137.1'; InterfaceIndex=10; PrefixLength=24}) $global:apVerificationDhcp = 'Disabled' function Get-NetAdapter { param([switch]$IncludeHidden) $global:apVerificationAdapters } function Get-NetIPAddress { param($InterfaceIndex, $AddressFamily) $global:apVerificationAddresses | Where-Object { -not $InterfaceIndex -or $_.InterfaceIndex -eq $InterfaceIndex } } function Get-NetIPInterface { param($InterfaceIndex, $AddressFamily) [pscustomobject]@{Dhcp=$global:apVerificationDhcp} } $apHelper = Join-Path $PSScriptRoot 'DCT_test/Configure-HotspotAp.ps1' & $apHelper -ValidateOnly function Assert-Rejected($message) { $rejected = $false try { & $apHelper -ValidateOnly } catch { $rejected = $true } Assert-Ap $rejected $message } $global:apVerificationAdapters[0].InterfaceDescription = 'Intel Wi-Fi physical adapter' Assert-Rejected 'Physical adapter must be rejected' $global:apVerificationAdapters[0].InterfaceDescription = 'Microsoft Wi-Fi Direct Virtual Adapter' $global:apVerificationAdapters += [pscustomobject]@{Status='Up'; InterfaceDescription='Microsoft Wi-Fi Direct Virtual Adapter #2'; ifIndex=11} $global:apVerificationAddresses += [pscustomobject]@{IPAddress='192.168.137.1'; InterfaceIndex=11; PrefixLength=24} Assert-Rejected 'Ambiguous hotspot adapters must be rejected' $global:apVerificationAdapters = @($global:apVerificationAdapters[0]) $global:apVerificationAddresses = @($global:apVerificationAddresses[0], [pscustomobject]@{IPAddress='192.168.4.1'; InterfaceIndex=12; PrefixLength=24}) Assert-Rejected 'Address owned by another adapter must be rejected' $global:apVerificationAddresses = @($global:apVerificationAddresses[0]) $global:apVerificationDhcp = 'Enabled' Assert-Rejected 'DHCP client adapter must be rejected' $global:apVerificationDhcp = 'Disabled' $global:apVerificationAddresses += [pscustomobject]@{IPAddress='192.168.4.1'; InterfaceIndex=10; PrefixLength=16} Assert-Rejected 'Wrong existing subnet prefix must be rejected' $global:apVerificationAddresses[1].PrefixLength = 24 & $apHelper -ValidateOnly Write-Output 'PASS: hotspot helper valid/repeated configuration, physical/ambiguous adapters, conflicting address, DHCP and subnet rejection (no system changes)'