Functions/Get-PartnerCenterAccessToken.Tests.ps1
describe "BitTitan.Runbooks.PartnerCenter/Get-PartnerCenterAccessToken" -Tags "module", "unit" { # Import the function to test . "$($PSScriptRoot)\Get-PartnerCenterAccessToken.ps1" # Declare our own external functions function Get-CredentialFromMSPCompleteEndpoint { param ($endpoint) return [PSCredential]::new("username@domain.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } function Invoke-RestMethod { param ($Uri, $ContentType, $Body, $Method) } context "when there are no issues" { # Mock Get-CredentialFromMSPCompleteEndpoint mock Get-CredentialFromMSPCompleteEndpoint { return [PSCredential]::new("username@domain.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } # Mock Invoke-RestMethod mock Invoke-RestMethod { return [PSCustomObject]@{ expires_in = 1000 access_token = "valid-token" } } it "retrieves the access token given the username and the password" { # Call the function $output = Get-PartnerCenterAccessToken -Username "username@domain.com" -Password ("password" | ConvertTo-SecureString -AsPlainText -Force) ` -ApplicationId ([Guid]::empty).Guid # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 0 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 1 -Exactly -ParameterFilter { # Verify the URI $uriRegexMatch = [Regex]::new("https://login\.windows\.net/([\S]+)/oauth2/token").Match($Uri) $uriMatches = $uriRegexMatch.Groups[1].Value -eq "domain.com" # Verify the body Add-Type -AssemblyName System.Web $bodyRegexMatches = [Regex]::new("client_id=([\S]+)&username=([\S]+)&password=([\S]+)&scope=openid").Match($Body) $bodyMatches = $bodyRegexMatches.Groups[1].Value -eq ([Guid]::Empty).Guid -and ` $bodyRegexMatches.Groups[2].Value -eq "username%40domain.com" -and ` $bodyRegexMatches.Groups[3].Value -eq "password" $uriMatches -and $bodyMatches -and $ContentType -eq "application/x-www-form-urlencoded" -and $Method -eq "POST" } -Scope it # Verify the output $output | Should Be "valid-token" } it "retrieves the access token given the endpoint" { # Mock the endpoint $endpoint = [PSCustomObject]@{ Name = "Stub endpoint" ExtendedProperties = @{ ApplicationId = ([Guid]::empty).Guid } } # Call the function $output = Get-PartnerCenterAccessToken -Endpoint $endpoint # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 1 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 1 -Exactly -ParameterFilter { # Verify the URI $uriRegexMatch = [Regex]::new("https://login\.windows\.net/([\S]+)/oauth2/token").Match($Uri) $uriMatches = $uriRegexMatch.Groups[1].Value -eq "domain.com" # Verify the body Add-Type -AssemblyName System.Web $bodyRegexMatches = [Regex]::new("client_id=([\S]+)&username=([\S]+)&password=([\S]+)&scope=openid").Match($Body) $bodyMatches = $bodyRegexMatches.Groups[1].Value -eq ([Guid]::Empty).Guid -and ` $bodyRegexMatches.Groups[2].Value -eq "username%40domain.com" -and ` $bodyRegexMatches.Groups[3].Value -eq "password" $uriMatches -and $bodyMatches -and $ContentType -eq "application/x-www-form-urlencoded" -and $Method -eq "POST" } -Scope it # Verify the output $output | Should Be "valid-token" } } context "when there is an exception while invoking the REST call" { # Mock Get-CredentialFromMSPCompleteEndpoint mock Get-CredentialFromMSPCompleteEndpoint { return [PSCredential]::new("username@domain.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } # Mock Invoke-RestMethod mock Invoke-RestMethod { throw "throws exception" } it "fails to retrieve the access token and outputs an error" { # Mock the endpoint $endpoint = [PSCustomObject]@{ Name = "Stub endpoint" ExtendedProperties = @{ ApplicationId = ([Guid]::empty).Guid } } # Call the function $output = Get-PartnerCenterAccessToken -Endpoint $endpoint -ErrorAction SilentlyContinue ` -ErrorVariable errorVariable # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 1 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 1 -Exactly -ParameterFilter { # Verify the URI $uriRegexMatch = [Regex]::new("https://login\.windows\.net/([\S]+)/oauth2/token").Match($Uri) $uriMatches = $uriRegexMatch.Groups[1].Value -eq "domain.com" # Verify the body Add-Type -AssemblyName System.Web $bodyRegexMatches = [Regex]::new("client_id=([\S]+)&username=([\S]+)&password=([\S]+)&scope=openid").Match($Body) $bodyMatches = $bodyRegexMatches.Groups[1].Value -eq ([Guid]::Empty).Guid -and ` $bodyRegexMatches.Groups[2].Value -eq "username%40domain.com" -and ` $bodyRegexMatches.Groups[3].Value -eq "password" $uriMatches -and $bodyMatches -and $ContentType -eq "application/x-www-form-urlencoded" -and $Method -eq "POST" } -Scope it # Verify the output $errorVariable | Should Not BeNullOrEmpty $output | Should Be $null } } context "when a valid access token is not returned" { # Mock Get-CredentialFromMSPCompleteEndpoint mock Get-CredentialFromMSPCompleteEndpoint { return [PSCredential]::new("username@domain.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } # Mock Invoke-RestMethod mock Invoke-RestMethod { return $null } it "fails to retrieve the access token and outputs an error" { # Mock the endpoint $endpoint = [PSCustomObject]@{ Name = "Stub endpoint" ExtendedProperties = @{ ApplicationId = ([Guid]::empty).Guid } } # Call the function $output = Get-PartnerCenterAccessToken -Endpoint $endpoint -ErrorAction SilentlyContinue ` -ErrorVariable errorVariable # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 1 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 1 -Exactly -ParameterFilter { # Verify the URI $uriRegexMatch = [Regex]::new("https://login\.windows\.net/([\S]+)/oauth2/token").Match($Uri) $uriMatches = $uriRegexMatch.Groups[1].Value -eq "domain.com" # Verify the body Add-Type -AssemblyName System.Web $bodyRegexMatches = [Regex]::new("client_id=([\S]+)&username=([\S]+)&password=([\S]+)&scope=openid").Match($Body) $bodyMatches = $bodyRegexMatches.Groups[1].Value -eq ([Guid]::Empty).Guid -and ` $bodyRegexMatches.Groups[2].Value -eq "username%40domain.com" -and ` $bodyRegexMatches.Groups[3].Value -eq "password" $uriMatches -and $bodyMatches -and $ContentType -eq "application/x-www-form-urlencoded" -and $Method -eq "POST" } -Scope it # Verify the output $errorVariable | Should Not BeNullOrEmpty $output | Should Be $null } } context "when the endpoint does not contain an 'ExtendedProperties' property" { # Mock Get-CredentialFromMSPCompleteEndpoint mock Get-CredentialFromMSPCompleteEndpoint { return [PSCredential]::new("username@domain.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } # Mock Invoke-RestMethod mock Invoke-RestMethod { return [PSCustomObject]@{ expires_in = 1000 access_token = "valid-token" } } it "fails to retrieve the access token and outputs an error" { # Mock the endpoint $endpoint = [PSCustomObject]@{ Name = "Stub endpoint" } # Call the function $output = Get-PartnerCenterAccessToken -Endpoint $endpoint -ErrorAction SilentlyContinue ` -ErrorVariable errorVariable # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 1 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 0 -Exactly -Scope it # Verify the output $errorVariable | Should Not BeNullOrEmpty $output | Should Be $null } } context "when the endpoint does not contain an 'ApplicationId' extended property" { # Mock Get-CredentialFromMSPCompleteEndpoint mock Get-CredentialFromMSPCompleteEndpoint { return [PSCredential]::new("username@domain.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } # Mock Invoke-RestMethod mock Invoke-RestMethod { return [PSCustomObject]@{ expires_in = 1000 access_token = "valid-token" } } it "fails to retrieve the access token and outputs an error" { # Mock the endpoint $endpoint = [PSCustomObject]@{ Name = "Stub endpoint" ExtendedProperties = @{} } # Call the function $output = Get-PartnerCenterAccessToken -Endpoint $endpoint -ErrorAction SilentlyContinue ` -ErrorVariable errorVariable # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 1 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 0 -Exactly -Scope it # Verify the output $errorVariable | Should Not BeNullOrEmpty $output | Should Be $null } } context "when the username is not in the form of <user>@<domain>" { # Mock Get-CredentialFromMSPCompleteEndpoint mock Get-CredentialFromMSPCompleteEndpoint { return [PSCredential]::new("username.com", ("password" | ConvertTo-SecureString -AsPlainText -Force)) } # Mock Invoke-RestMethod mock Invoke-RestMethod { return [PSCustomObject]@{ expires_in = 1000 access_token = "valid-token" } } it "fails to retrieve the access token and outputs an error" { # Mock the endpoint $endpoint = [PSCustomObject]@{ Name = "Stub endpoint" ExtendedProperties = @{ ApplicationId = ([Guid]::empty).Guid } } # Call the function $output = Get-PartnerCenterAccessToken -Endpoint $endpoint -ErrorAction SilentlyContinue ` -ErrorVariable errorVariable # Verify the mocks Assert-MockCalled Get-CredentialFromMSPCompleteEndpoint -Times 1 -Exactly -Scope it Assert-MockCalled Invoke-RestMethod -Times 0 -Exactly -Scope it # Verify the output $errorVariable | Should Not BeNullOrEmpty $output | Should Be $null } } } |