Private/Runtime/Tests/Get-OpenApiOAuthToken.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.openapi.psd1') -Force # Windows PowerShell 5.1 does not load System.Net.Http by default Add-Type -AssemblyName 'System.Net.Http' $RepoRoot = Split-Path -Path (Split-Path -Path $ModuleRoot -Parent) -Parent . (Join-Path -Path $RepoRoot -ChildPath 'tests/Helpers/TestHttpServer.ps1') } AfterAll { Remove-Module -Name tcs.openapi -Force -ErrorAction SilentlyContinue } Describe 'Get-OpenApiOAuthToken' { BeforeAll { $script:server = Start-TestHttpServer -Routes @{ 'POST /token' = { param($Request) @{ Body = @{ access_token = "tok-$([guid]::NewGuid().ToString('N'))"; expires_in = 3600 } } } 'POST /short' = { param($Request) @{ Body = @{ access_token = "tok-$([guid]::NewGuid().ToString('N'))"; expires_in = 30 } } } 'POST /denied' = @{ StatusCode = 401; Body = @{ error = 'invalid_client' } } 'POST /empty' = @{ Body = @{ token_type = 'Bearer' } } } InModuleScope -ModuleName tcs.openapi -Parameters @{ BaseUri = $script:server.BaseUri } { $script:testClient = New-Object System.Net.Http.HttpClient $script:testContext = New-OpenApiContext -Service 'Tok' -BaseUri $BaseUri -ClientId 'id' -ClientSecret ((New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', 'sec').SecurePassword) } } AfterAll { InModuleScope -ModuleName tcs.openapi { $script:testClient.Dispose() } $script:server.Stop() } It 'posts client credentials and caches the token' { InModuleScope -ModuleName tcs.openapi -Parameters @{ BaseUri = $script:server.BaseUri } { Clear-OpenApiTokenCache $first = Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/token" -Scope 'a', 'b' $second = Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/token" -Scope 'a', 'b' $first | Should -BeOfType ([System.Security.SecureString]) (ConvertFrom-OpenApiSecureString -SecureString $second) | Should -Be (ConvertFrom-OpenApiSecureString -SecureString $first) $forced = Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/token" -Scope 'a', 'b' -Force (ConvertFrom-OpenApiSecureString -SecureString $forced) | Should -Not -Be (ConvertFrom-OpenApiSecureString -SecureString $first) } @($script:server.Requests | Where-Object -FilterScript { $_.Path -eq '/token' }).Count | Should -Be 2 $script:server.Requests[0].Body | Should -Be 'grant_type=client_credentials&client_id=id&client_secret=sec&scope=a%20b' } It 'does not reuse a token within 60 seconds of expiry' { InModuleScope -ModuleName tcs.openapi -Parameters @{ BaseUri = $script:server.BaseUri } { $first = Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/short" $second = Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/short" (ConvertFrom-OpenApiSecureString -SecureString $second) | Should -Not -Be (ConvertFrom-OpenApiSecureString -SecureString $first) } } It 'throws AuthenticationException for a failed or empty token response' { InModuleScope -ModuleName tcs.openapi -Parameters @{ BaseUri = $script:server.BaseUri } { { Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/denied" } | Should -Throw -ExceptionType ([System.Security.Authentication.AuthenticationException]) -ExpectedMessage '*401*invalid_client*' { Get-OpenApiOAuthToken -Context $script:testContext -Client $script:testClient -TokenUri "$BaseUri/empty" } | Should -Throw -ExpectedMessage '*no access_token*' } } } |