Files
mcp-microsoft/eng/common/scripts/tests/Get-PackageApprovalStatus.Tests.ps1
T
6865d70a8d Sync eng/common directory with azure-sdk-tools for PR 16660 (#3428)
* Add Get-PackageApprovalStatus script.

* Sync eng/common directory with azure-sdk-tools repository for Tools PR 16660

* Sync eng/common directory with azure-sdk-tools repository for Tools PR 16660

* Sync eng/common directory with azure-sdk-tools repository for Tools PR 16660

* Sync eng/common directory with azure-sdk-tools repository for Tools PR 16660

* Sync eng/common directory with azure-sdk-tools repository for Tools PR 16660

---------

Co-authored-by: Travis Prescott <trpresco@microsoft.com>
Co-authored-by: azure-sdk <azuresdk@microsoft.com>
2026-08-31 09:06:53 -07:00

214 lines
8.6 KiB
PowerShell

Describe "Get-PackageApprovalStatus.ps1" {
BeforeAll {
$scriptPath = Join-Path (Join-Path $PSScriptRoot "..") "Get-PackageApprovalStatus.ps1"
function global:azsdk {
param (
[Parameter(ValueFromRemainingArguments = $true)]
[object[]] $Arguments
)
if ($Arguments.Count -eq 1 -and $Arguments[0] -eq "--version") {
$global:LASTEXITCODE = 0
return $global:AzSdkVersion
}
$global:CapturedAzSdkArguments = @($Arguments)
$global:CapturedAzSdkInvocations += ,@($Arguments)
$global:LASTEXITCODE = $global:AzSdkExitCode
return $global:AzSdkOutput
}
}
AfterAll {
Remove-Item Function:\azsdk -ErrorAction SilentlyContinue
Remove-Variable AzSdkExitCode, AzSdkOutput, AzSdkVersion, CapturedAzSdkArguments, CapturedAzSdkInvocations, LanguageShort -Scope Global -ErrorAction SilentlyContinue
}
BeforeEach {
$global:LanguageShort = "python"
$global:AzSdkExitCode = 0
$global:AzSdkVersion = "0.6.38"
$global:AzSdkOutput = '{"operation_status":"Succeeded","result":{"isApproved":true,"finalSource":"reviewHub","reason":"approved"}}'
$global:CapturedAzSdkArguments = @()
$global:CapturedAzSdkInvocations = @()
$packageInfoPath = Join-Path $TestDrive "azure-test.json"
@{
Name = "azure-test"
Version = "1.0.0"
} | ConvertTo-Json | Set-Content $packageInfoPath
}
It "passes package coordinates, API hash, and repository owner to azsdk" {
$packageInfo = Get-Content $packageInfoPath -Raw | ConvertFrom-Json
$packageInfo | Add-Member -NotePropertyName ApiHash -NotePropertyValue abc123
$packageInfo | ConvertTo-Json | Set-Content $packageInfoPath
& $scriptPath -PackageInfoFiles $packageInfoPath -RepoOwner Contoso
($global:CapturedAzSdkArguments -join "|") | Should Be (@(
"package", "get-approval-status",
"--language", "python",
"--package-name", "azure-test",
"--package-version", "1.0.0",
"--output", "json",
"--api-hash", "abc123",
"--repo-owner", "Contoso"
) -join "|")
}
It "omits the API hash when it is unavailable" {
& $scriptPath -PackageInfoFiles $packageInfoPath
($global:CapturedAzSdkArguments -join "|") | Should Not Match "--api-hash"
($global:CapturedAzSdkArguments -join "|") | Should Not Match "--repo-owner"
}
It "fails without prompting when the azsdk executable is unavailable" {
$missingExecutable = Join-Path $TestDrive "missing-azsdk.exe"
$caughtError = $null
try {
& $scriptPath -PackageInfoFiles $packageInfoPath -AzSdkExePath $missingExecutable
}
catch {
$caughtError = $_
}
$caughtError | Should Not BeNullOrEmpty
$caughtError.Exception.Message | Should Match "azsdk CLI executable was not found"
}
It "fails when the azsdk version is unsupported" {
$global:AzSdkVersion = "0.6.37"
$caughtError = $null
try {
& $scriptPath -PackageInfoFiles $packageInfoPath
}
catch {
$caughtError = $_
}
$caughtError.Exception.Message | Should Match "version 0.6.38 or later is required"
$global:CapturedAzSdkInvocations.Count | Should Be 0
}
It "fails when azsdk returns a nonzero exit code" {
$global:AzSdkExitCode = 1
$global:AzSdkOutput = '{"operation_status":"Failed","response_error":"distinct raw command output"}'
$caughtError = $null
try {
& $scriptPath -PackageInfoFiles $packageInfoPath
}
catch {
$caughtError = $_
}
$caughtError | Should Not BeNullOrEmpty
$caughtError.Exception.Message | Should Match "distinct raw command output"
}
It "logs a reproducible command invocation" {
$packageInfo = Get-Content $packageInfoPath -Raw | ConvertFrom-Json
$packageInfo.Name = "azure test"
$packageInfo | ConvertTo-Json | Set-Content $packageInfoPath
$messages = @(& $scriptPath -PackageInfoFiles $packageInfoPath 6>&1)
($messages -join [Environment]::NewLine) | Should Match 'Command: azsdk package get-approval-status --language python --package-name "azure test" --package-version 1.0.0 --output json'
}
It "shows Review Hub and APIView results before the overall result" {
$global:AzSdkOutput = '{"operation_status":"Succeeded","result":{"isApproved":true,"finalSource":"APIView","reason":"approved","reviewHub":{"isApproved":false,"reason":"repositoryNotSupported","statusCode":200},"apiView":{"isApproved":true,"reason":"approved","statusCode":200,"details":["API review is approved."]}}}'
$messages = @(& $scriptPath -PackageInfoFiles $packageInfoPath 6>&1) |
ForEach-Object { "$_" }
[Array]::IndexOf($messages, "API Review Hub") | Should BeLessThan ([Array]::IndexOf($messages, "APIView"))
[Array]::IndexOf($messages, "APIView") | Should BeLessThan ([Array]::IndexOf($messages, "Overall"))
($messages -join [Environment]::NewLine) | Should Match "Overall\r?\n Status: APPROVED\r?\n Source: APIView\r?\n Reason: approved"
}
It "includes raw output when azsdk returns malformed output" {
$global:AzSdkExitCode = 1
$global:AzSdkOutput = "distinct raw command output"
$caughtError = $null
try {
& $scriptPath -PackageInfoFiles $packageInfoPath
}
catch {
$caughtError = $_
}
$caughtError | Should Not BeNullOrEmpty
$caughtError.Exception.Message | Should Match "distinct raw command output"
}
It "fails when the response is malformed" {
$global:AzSdkOutput = "not json"
{ & $scriptPath -PackageInfoFiles $packageInfoPath } |
Should Throw
}
It "fails when a successful CLI invocation reports an unapproved result" {
$global:AzSdkOutput = '{"operation_status":"Succeeded","result":{"isApproved":false,"finalSource":"none","reason":"pending"}}'
{ & $scriptPath -PackageInfoFiles $packageInfoPath } |
Should Throw
}
It "ignores a failed approval check for an unreleased package" {
$packageInfo = Get-Content $packageInfoPath -Raw | ConvertFrom-Json
$packageInfo | Add-Member -NotePropertyName ReleaseStatus -NotePropertyValue Unreleased
$packageInfo | ConvertTo-Json | Set-Content $packageInfoPath
$global:AzSdkExitCode = 1
$global:AzSdkOutput = '{"operation_status":"Failed","response_error":"Package is not approved."}'
$messages = @(& $scriptPath -PackageInfoFiles $packageInfoPath 6>&1)
($messages -join [Environment]::NewLine) | Should Match "azure-test 1.0.0 is not marked for release. Ignoring approval check failure"
$global:CapturedAzSdkInvocations.Count | Should Be 1
}
It "fails when the response contract is missing the result" {
$global:AzSdkOutput = '{"operation_status":"Succeeded"}'
{ & $scriptPath -PackageInfoFiles $packageInfoPath } |
Should Throw
}
It "fails when the approval decision is not Boolean" {
$global:AzSdkOutput = '{"operation_status":"Succeeded","result":{"isApproved":"false"}}'
{ & $scriptPath -PackageInfoFiles $packageInfoPath } |
Should Throw
}
It "checks every explicitly supplied package-info file" {
$secondPackageInfoPath = Join-Path $TestDrive "azure-test-two.json"
@{
Name = "azure-test-two"
Version = "2.0.0"
ApiHash = "def456"
} | ConvertTo-Json | Set-Content $secondPackageInfoPath
& $scriptPath -PackageInfoFiles @($packageInfoPath, $secondPackageInfoPath)
$global:CapturedAzSdkInvocations.Count | Should Be 2
($global:CapturedAzSdkInvocations[0] -join "|") | Should Match "--package-name\|azure-test\|--package-version\|1.0.0"
($global:CapturedAzSdkInvocations[1] -join "|") | Should Match "--package-name\|azure-test-two\|--package-version\|2.0.0.*--api-hash\|def456"
}
It "continues checking valid packages after invalid package info" {
$invalidPackageInfoPath = Join-Path $TestDrive "invalid.json"
Set-Content $invalidPackageInfoPath "not json"
{ & $scriptPath -PackageInfoFiles @($invalidPackageInfoPath, $packageInfoPath) } |
Should Throw
$global:CapturedAzSdkInvocations.Count | Should Be 1
}
}