tests/Private/Set-GCPTag.Tests.ps1
|
Describe 'Set-GCPTag' { BeforeAll { $ModulePath = $PSScriptRoot | Split-Path -Parent | Split-Path -Parent | Join-Path -ChildPath 'PSCumulus.psd1' Import-Module $ModulePath -Force } Context 'Parameter validation' { It 'Should have -Project as mandatory parameter' { InModuleScope PSCumulus { $params = (Get-Command Set-GCPTag).Parameters $params.ContainsKey('Project') | Should -BeTrue $params.Project.Attributes.Mandatory | Should -BeTrue } } It 'Should have -Resource as mandatory parameter' { InModuleScope PSCumulus { $params = (Get-Command Set-GCPTag).Parameters $params.ContainsKey('Resource') | Should -BeTrue $params.Resource.Attributes.Mandatory | Should -BeTrue } } It 'Should have -Tags as mandatory parameter' { InModuleScope PSCumulus { $params = (Get-Command Set-GCPTag).Parameters $params.ContainsKey('Tags') | Should -BeTrue $params.Tags.Attributes.Mandatory | Should -BeTrue } } It 'Should have -Merge switch' { InModuleScope PSCumulus { $params = (Get-Command Set-GCPTag).Parameters $params.ContainsKey('Merge') | Should -BeTrue $params.Merge.ParameterType.Name | Should -Be 'SwitchParameter' } } } Context 'Command availability check' { It 'Should fail if gcloud is not available' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable -MockWith { throw 'gcloud not found' } { Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key = 'Value'} -ErrorAction Stop } | Should -Throw } } It 'Should not throw when gcloud is available' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { @() } { Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key = 'Value'} } | Should -Not -Throw } } } Context 'Tag format conversion' { It 'Should convert hashtable to key=value format' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { param($Arguments) $tagIndex = $Arguments.IndexOf('--tag') $tagIndex | Should -BeGreaterThan -1 $tagValue = $Arguments[$tagIndex + 1] $tagValue | Should -BeLike '*Key1=Value1*' $tagValue | Should -BeLike '*Key2=Value2*' @() } Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key1 = 'Value1'; Key2 = 'Value2'} } } } Context 'Tag merge behavior' { It 'Should merge with existing tags when -Merge is specified' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { param($Arguments, $ErrorAction) if ($Arguments -contains 'list') { @( @{ names = @('ExistingTag'); shortValue = 'ExistingValue' } ) } else { @() } } $tags = @{NewTag = 'NewValue'} Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags $tags -Merge # The merge should add ExistingTag to $tags } } It 'Should not merge when -Merge is not specified' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { param($Arguments, $ErrorAction) if ($Arguments -contains 'list') { @( @{ names = @('ExistingTag'); shortValue = 'ExistingValue' } ) } else { @() } } Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{NewTag = 'NewValue'} -ErrorAction SilentlyContinue } } } Context 'gcloud command invocation' { It 'Should invoke gcloud resource-manager tags list when merging' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { param($Arguments) if ($Arguments -contains 'list') { $Arguments -contains 'resource-manager' | Should -BeTrue $Arguments -contains 'tags' | Should -BeTrue $Arguments -contains 'list' | Should -BeTrue @() } else { @() } } Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key = 'Value'} -Merge } } It 'Should invoke gcloud resource-manager tags create' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { param($Arguments) if ($Arguments -contains 'create') { $Arguments -contains 'resource-manager' | Should -BeTrue $Arguments -contains 'tags' | Should -BeTrue $Arguments -contains 'create' | Should -BeTrue } @() } Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key = 'Value'} } } } Context 'Error handling' { It 'Should handle empty existing tags gracefully' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { @() } { Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key = 'Value'} -Merge } | Should -Not -Throw } } It 'Should stop on gcloud errors' { InModuleScope PSCumulus { Mock -CommandName Assert-CommandAvailable Mock -CommandName Invoke-GCloudJson -MockWith { throw 'gcloud command failed' } { Set-GCPTag -Project 'test-project' -Resource 'test-resource' -Tags @{Key = 'Value'} -ErrorAction Stop } | Should -Throw } } } } |