lib/rules/releases/duplicate_release/duplicate_release.Tests.ps1
|
############################################################################# # Tests for Rule: duplicate_release ############################################################################# BeforeAll { . "$PSScriptRoot/../../../StateModel.ps1" . "$PSScriptRoot/../../../ValidationRules.ps1" . "$PSScriptRoot/../../../RemediationActions.ps1" . "$PSScriptRoot/duplicate_release.ps1" } Describe "duplicate_release" { Context "Condition - Configuration checks" { It "should return results when check-releases is 'error'" { $state = [RepositoryState]::new() $release1 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 123 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $true } $release2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 456 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0-draft" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($release1), [ReleaseInfo]::new($release2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 1 $result[0].Id | Should -Be 456 } It "should return results when check-releases is 'warning'" { $state = [RepositoryState]::new() $release1 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 123 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $release2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 456 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0-draft" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($release1), [ReleaseInfo]::new($release2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'warning' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 1 } It "should return empty when check-releases is 'none'" { $state = [RepositoryState]::new() $release1 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 123 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $release2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 456 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0-draft" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($release1), [ReleaseInfo]::new($release2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'none' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 0 } } Context "Condition - Finding duplicate releases" { It "should return draft duplicate when published release exists" { $state = [RepositoryState]::new() $published = [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 = $true } $draft = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($published), [ReleaseInfo]::new($draft) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 1 $result[0].Id | Should -Be 200 $result[0].IsDraft | Should -Be $true } It "should delete newer draft when two drafts exist for same tag" { $state = [RepositoryState]::new() $draft1 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 100 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $draft2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($draft1), [ReleaseInfo]::new($draft2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config # Should delete the newer draft (id 200), keep the older one (id 100) $result.Count | Should -Be 1 $result[0].Id | Should -Be 200 } It "should delete multiple draft duplicates" { $state = [RepositoryState]::new() $published = [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 = $true } $draft1 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $draft2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 300 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($published), [ReleaseInfo]::new($draft1), [ReleaseInfo]::new($draft2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 2 $result.Id | Should -Contain 200 $result.Id | Should -Contain 300 } It "should not return anything when no duplicates exist" { $state = [RepositoryState]::new() $release1 = [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 = $true } $release2 = [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 = $true } $state.Releases = @( [ReleaseInfo]::new($release1), [ReleaseInfo]::new($release2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 0 } It "should not return published duplicate (cannot be deleted)" { $state = [RepositoryState]::new() $published1 = [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 = $true } $published2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $true } $state.Releases = @( [ReleaseInfo]::new($published1), [ReleaseInfo]::new($published2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config # Cannot delete published releases, so no results $result.Count | Should -Be 0 } It "should skip ignored versions" { $state = [RepositoryState]::new() $release1 = [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 = $true } $release2 = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $r1 = [ReleaseInfo]::new($release1) $r1.IsIgnored = $true $r2 = [ReleaseInfo]::new($release2) $r2.IsIgnored = $true $state.Releases = @($r1, $r2) $state.IgnoreVersions = @("v1.0.0") $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config $result.Count | Should -Be 0 } It "should only match patch versions (not floating versions)" { $state = [RepositoryState]::new() # Duplicate releases for a major version tag (should be ignored) $major1 = [PSCustomObject]@{ tag_name = "v1" id = 100 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1" target_commitish = "abc123" immutable = $false } $major2 = [PSCustomObject]@{ tag_name = "v1" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1" target_commitish = "abc123" immutable = $false } # Duplicate releases for a minor version tag (should be ignored) $minor1 = [PSCustomObject]@{ tag_name = "v1.0" id = 300 draft = $false prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0" target_commitish = "abc123" immutable = $false } $minor2 = [PSCustomObject]@{ tag_name = "v1.0" id = 400 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0" target_commitish = "abc123" immutable = $false } $state.Releases = @( [ReleaseInfo]::new($major1), [ReleaseInfo]::new($major2), [ReleaseInfo]::new($minor1), [ReleaseInfo]::new($minor2) ) $state.IgnoreVersions = @() $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Condition $state $config # Floating versions should not be checked $result.Count | Should -Be 0 } } Context "Check" { It "should return false for duplicate releases (they are invalid)" { $state = [RepositoryState]::new() $releaseData = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $release = [ReleaseInfo]::new($releaseData) $config = @{ 'check-releases' = 'error' } $result = & $Rule_DuplicateRelease.Check $release $state $config $result | Should -Be $false } } Context "CreateIssue" { It "should create issue with error severity when check-releases is 'error'" { $state = [RepositoryState]::new() $releaseData = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $release = [ReleaseInfo]::new($releaseData) $config = @{ 'check-releases' = 'error' } $issue = & $Rule_DuplicateRelease.CreateIssue $release $state $config $issue.Severity | Should -Be "error" $issue.Type | Should -Be "duplicate_release" $issue.Version | Should -Be "v1.0.0" $issue.Message | Should -Match "Duplicate draft release" $issue.Message | Should -Match "200" } It "should create issue with warning severity when check-releases is 'warning'" { $state = [RepositoryState]::new() $releaseData = [PSCustomObject]@{ tag_name = "v1.0.0" id = 200 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $release = [ReleaseInfo]::new($releaseData) $config = @{ 'check-releases' = 'warning' } $issue = & $Rule_DuplicateRelease.CreateIssue $release $state $config $issue.Severity | Should -Be "warning" } It "should create DeleteReleaseAction with correct release ID" { $state = [RepositoryState]::new() $releaseData = [PSCustomObject]@{ tag_name = "v1.0.0" id = 12345 draft = $true prerelease = $false html_url = "https://github.com/repo/releases/tag/v1.0.0" target_commitish = "abc123" immutable = $false } $release = [ReleaseInfo]::new($releaseData) $config = @{ 'check-releases' = 'error' } $issue = & $Rule_DuplicateRelease.CreateIssue $release $state $config $issue.RemediationAction | Should -Not -BeNullOrEmpty $issue.RemediationAction.GetType().Name | Should -Be "DeleteReleaseAction" $issue.RemediationAction.ReleaseId | Should -Be 12345 $issue.RemediationAction.TagName | Should -Be "v1.0.0" } } Context "Priority ordering with other release rules" { It "should have priority lower than release_should_be_published" { . "$PSScriptRoot/../release_should_be_published/release_should_be_published.ps1" $Rule_DuplicateRelease.Priority | Should -BeLessThan $Rule_ReleaseShouldBePublished.Priority } It "should have priority lower than patch_release_required" { . "$PSScriptRoot/../patch_release_required/patch_release_required.ps1" $Rule_DuplicateRelease.Priority | Should -BeLessThan $Rule_PatchReleaseRequired.Priority } } } |