lib/actions/releases/CreateReleaseAction/CreateReleaseAction.Tests.ps1
|
BeforeAll { . "$PSScriptRoot/../../../StateModel.ps1" . "$PSScriptRoot/../../../Logging.ps1" . "$PSScriptRoot/../../../GitHubApi.ps1" . "$PSScriptRoot/../../base/RemediationAction.ps1" . "$PSScriptRoot/../../base/ReleaseRemediationAction.ps1" . "$PSScriptRoot/CreateReleaseAction.ps1" } Describe "CreateReleaseAction" { BeforeEach { $script:state = [RepositoryState]::new() $script:state.RepoOwner = "test-owner" $script:state.RepoName = "test-repo" $script:state.ApiUrl = "https://api.github.com" $script:state.ServerUrl = "https://github.com" $script:state.Token = "test-token" } Context "Constructor" { It "Should create action for draft release (isDraft=true)" { $action = [CreateReleaseAction]::new("v1.0.0", $true) $action.TagName | Should -Be "v1.0.0" $action.AutoPublish | Should -Be $false $action.Priority | Should -Be 30 } It "Should create action for published release (isDraft=false)" { $action = [CreateReleaseAction]::new("v1.0.0", $false) $action.AutoPublish | Should -Be $true } It "Should create action with explicit auto-publish" { $action = [CreateReleaseAction]::new("v1.0.0", $true, $true) $action.TagName | Should -Be "v1.0.0" $action.AutoPublish | Should -Be $true $action.Priority | Should -Be 30 } } Context "GetManualCommands" { It "Should generate correct manual commands for draft" { $action = [CreateReleaseAction]::new("v1.0.0", $true, $false) $commands = $action.GetManualCommands($script:state) $commands.Count | Should -Be 1 $commands[0] | Should -Match "gh release create v1.0.0" $commands[0] | Should -Match "--repo test-owner/test-repo" $commands[0] | Should -Match "--draft" $commands[0] | Should -Not -Match "^#" } It "Should generate correct manual commands for auto-publish" { $action = [CreateReleaseAction]::new("v1.0.0", $true, $true) $commands = $action.GetManualCommands($script:state) $commands.Count | Should -Be 1 $commands[0] | Should -Match "gh release create v1.0.0" $commands[0] | Should -Match "--repo test-owner/test-repo" $commands[0] | Should -Not -Match "--draft" $commands[0] | Should -Not -Match "^#" } It "Should return empty array when issue is unfixable" { # Create unfixable issue $action = [CreateReleaseAction]::new("v1.0.0", $false) $issue = [ValidationIssue]::new("missing_release", "error", "Release missing") $issue.Version = "v1.0.0" $issue.Status = "unfixable" $script:state.Issues = @($issue) $commands = $action.GetManualCommands($script:state) $commands.Count | Should -Be 0 } } Context "Execute" { BeforeEach { Mock New-GitHubRelease { return @{ Success = $true } } } It "Should call New-GitHubRelease with draft=true when AutoPublish is false" { $action = [CreateReleaseAction]::new("v1.0.0", $true, $false) $action.Execute($script:state) Should -Invoke New-GitHubRelease -Times 1 -ParameterFilter { $TagName -eq "v1.0.0" -and $Draft -eq $true } } It "Should call New-GitHubRelease with draft=false when AutoPublish is true" { $action = [CreateReleaseAction]::new("v1.0.0", $false, $true) $action.Execute($script:state) Should -Invoke New-GitHubRelease -Times 1 -ParameterFilter { $TagName -eq "v1.0.0" -and $Draft -eq $false } } It "Should mark issue as unfixable on 422 error" { Mock New-GitHubRelease { return @{ Success = $false; Unfixable = $true } } $action = [CreateReleaseAction]::new("v1.0.0", $false) $issue = [ValidationIssue]::new("missing_release", "error", "Release missing") $issue.Version = "v1.0.0" $issue.Status = "pending" $script:state.Issues = @($issue) $result = $action.Execute($script:state) $result | Should -Be $false $issue.Status | Should -Be "unfixable" $issue.Message | Should -Match "immutable release" } } Context "MakeLatest - prevents overwriting correct latest release" { BeforeEach { Mock New-GitHubRelease { return @{ Success = $true } } } It "Should default MakeLatest to null (let GitHub decide)" { $action = [CreateReleaseAction]::new("v1.0.0", $false) $action.MakeLatest | Should -BeNullOrEmpty } It "Should allow explicit MakeLatest=false to prevent becoming latest" { $action = [CreateReleaseAction]::new("v1.0.0", $false) $action.MakeLatest = $false $action.MakeLatest | Should -Be $false } It "Should pass MakeLatest=false to New-GitHubRelease when explicitly set" { $action = [CreateReleaseAction]::new("v1.0.0", $false) $action.MakeLatest = $false $action.Execute($script:state) Should -Invoke New-GitHubRelease -Times 1 -ParameterFilter { $MakeLatest -eq $false } } It "Should not pass MakeLatest parameter when null (let GitHub use default)" { $action = [CreateReleaseAction]::new("v1.0.0", $false) # MakeLatest is null by default $action.Execute($script:state) # When MakeLatest is null, New-GitHubRelease should not receive a specific MakeLatest value Should -Invoke New-GitHubRelease -Times 1 -ParameterFilter { $null -eq $MakeLatest -or $MakeLatest -eq $true } } It "Should use MakeLatest=false when creating release for older version" { # Scenario: v2.0.0 exists as latest, we're creating v1.1.0 # Creating v1.1.0 should NOT become latest $release = [PSCustomObject]@{ tag_name = "v2.0.0" id = 200 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v2.0.0" target_commitish = "def456" immutable = $false } $releaseInfo = [ReleaseInfo]::new($release) $releaseInfo.IsLatest = $true $script:state.Releases = @($releaseInfo) $script:state.Tags = @([VersionRef]::new("v2.0.0", "refs/tags/v2.0.0", "def456", "tag")) $action = [CreateReleaseAction]::new("v1.1.0", $false) $action.MakeLatest = $false # Explicitly prevent becoming latest $action.Execute($script:state) Should -Invoke New-GitHubRelease -Times 1 -ParameterFilter { $MakeLatest -eq $false } } It "Should use MakeLatest=false when creating release for prerelease version" { # Scenario: v1.0.0 exists as latest (stable), we're creating v2.0.0 marked as prerelease # The prerelease should NOT become latest $release = [PSCustomObject]@{ tag_name = "v1.0.0" id = 100 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $releaseInfo = [ReleaseInfo]::new($release) $releaseInfo.IsLatest = $true $script:state.Releases = @($releaseInfo) $script:state.Tags = @([VersionRef]::new("v1.0.0", "refs/tags/v1.0.0", "abc123", "tag")) # Creating v2.0.0 as a prerelease - should NOT become latest $action = [CreateReleaseAction]::new("v2.0.0", $false) $action.MakeLatest = $false # Explicitly prevent becoming latest for prerelease $action.Execute($script:state) Should -Invoke New-GitHubRelease -Times 1 -ParameterFilter { $MakeLatest -eq $false } } } Context "MakeLatest - GetManualCommands output" { It "Should include --latest=false in manual command when MakeLatest is false" { $action = [CreateReleaseAction]::new("v1.0.0", $false) $action.MakeLatest = $false $commands = $action.GetManualCommands($script:state) $commands[0] | Should -Match "--latest=false" } It "Should include --latest in manual command when MakeLatest is true" { $action = [CreateReleaseAction]::new("v1.0.0", $false) $action.MakeLatest = $true $commands = $action.GetManualCommands($script:state) $commands[0] | Should -Match "--latest" $commands[0] | Should -Not -Match "--latest=false" } It "Should not include --latest in manual command when MakeLatest is null" { $action = [CreateReleaseAction]::new("v1.0.0", $false) # MakeLatest is null by default $commands = $action.GetManualCommands($script:state) $commands[0] | Should -Not -Match "--latest" } } } |