tests/Test-GrantRBACRole.Tests.ps1
Describe "Grant-AzRBACRole" { BeforeAll { Import-Module "$PSScriptRoot/../az-bootstrap.psd1" -Force } InModuleScope 'az-bootstrap' { It "Calls az role assignment create with correct parameters" { # Important: Mock in the right order - mock the more specific commands first # So they take precedence over general mocks # Mock the full az command since we're not using ampersand Mock az { if ($args -contains 'group' -and $args -contains 'show') { return '{"id":"/subscriptions/0000/resourceGroups/rg-test"}' } elseif ($args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'list') { return '[]' } elseif ($args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'create') { return '{"id":"assignment-id"}' } } # Set exit code for successful command execution $global:LASTEXITCODE = 0 # Execute the function { Grant-AzRBACRole -ResourceGroupName "rg-test" -PrincipalId "principal-id" -PrincipalName "test-mi" -RoleDefinition "role-id" } | Should -Not -Throw # Check that az was called with the right parameters Assert-MockCalled az -Times 1 -Exactly -Scope It -ParameterFilter { $args -contains 'group' -and $args -contains 'show' } Assert-MockCalled az -Times 1 -Exactly -Scope It -ParameterFilter { $args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'list' } Assert-MockCalled az -Times 1 -Exactly -Scope It -ParameterFilter { $args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'create' } } It "Skips creation if role assignment already exists" { # Mock the full az command since we're not using ampersand Mock az { if ($args -contains 'group' -and $args -contains 'show') { return '{"id":"/subscriptions/0000/resourceGroups/rg-test"}' } elseif ($args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'list') { return '[{"id":"existing-assignment-id"}]' # Return existing assignment } } # Set exit code for successful command execution $global:LASTEXITCODE = 0 # Execute the function { Grant-AzRBACRole -ResourceGroupName "rg-test" -PrincipalId "principal-id" -PrincipalName "test-mi" -RoleDefinition "role-id" } | Should -Not -Throw # Verify role assignment create was NOT called Assert-MockCalled az -Times 1 -Exactly -Scope It -ParameterFilter { $args -contains 'group' -and $args -contains 'show' } Assert-MockCalled az -Times 1 -Exactly -Scope It -ParameterFilter { $args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'list' } Assert-MockCalled az -Times 0 -Exactly -Scope It -ParameterFilter { $args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'create' } } It "Throws if az group show fails" { # Mock the az command to fail for group show Mock az { if ($args -contains 'group' -and $args -contains 'show') { $global:LASTEXITCODE = 1 return $null } } # Execute and expect exception { Grant-AzRBACRole -ResourceGroupName "fail-rg" -PrincipalId "principal-id" -PrincipalName "test-mi" -RoleDefinition "role-id" } | Should -Throw } It "Throws if az role assignment create fails" { # Mock the full az command with role assignment create failing Mock az { if ($args -contains 'group' -and $args -contains 'show') { $global:LASTEXITCODE = 0 return '{"id":"/subscriptions/0000/resourceGroups/rg-test"}' } elseif ($args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'list') { $global:LASTEXITCODE = 0 return '[]' # Return empty array = assignment doesn't exist } elseif ($args -contains 'role' -and $args -contains 'assignment' -and $args -contains 'create') { $global:LASTEXITCODE = 1 return $null } } # Execute and expect exception { Grant-AzRBACRole -ResourceGroupName "rg-test" -PrincipalId "principal-id" -PrincipalName "test-mi" -RoleDefinition "role-id" } | Should -Throw } AfterEach { # Reset LASTEXITCODE after each test $global:LASTEXITCODE = 0 } } } |