Tests/Save-GitWorktree.Tests.ps1
|
BeforeAll { Import-Module "$PSScriptRoot\..\GittHelpers.psd1" -Force } Describe 'Save-GitWorktree' { BeforeEach { $script:WtPath = $TestDrive $script:FakeWt = [PSCustomObject]@{ Path = $script:WtPath Branch = 'feature/my-feature' IsBare = $false IsDetached = $false Head = 'abc1234' } Mock Get-GitRoot { return $TestDrive } -ModuleName GittHelpers Mock Get-WorktreeList { return @($script:FakeWt) } -ModuleName GittHelpers Mock Resolve-Path { [PSCustomObject]@{ Path = $script:WtPath } } -ModuleName GittHelpers Mock git { $global:LASTEXITCODE = 0 } -ModuleName GittHelpers Mock Set-Location { } -ModuleName GittHelpers } It 'Requires -Message' { { Save-GitWorktree -Message '' } | Should -Throw } It 'Throws when path is not a worktree' { Mock Get-WorktreeList { return @() } -ModuleName GittHelpers { Save-GitWorktree -Message 'test' -Path $script:WtPath } | Should -Throw } It 'Throws when worktree is detached HEAD' { $script:FakeWt.Branch = $null Mock Get-WorktreeList { return @($script:FakeWt) } -ModuleName GittHelpers { Save-GitWorktree -Message 'test' -Path $script:WtPath } | Should -Throw } It 'Does not push when -NoPush is specified' { $script:PushCalled = $false Mock git { $global:LASTEXITCODE = 0 if ($args -contains 'push') { $script:PushCalled = $true } if ($args -contains 'diff') { return 'file.txt' } } -ModuleName GittHelpers Save-GitWorktree -Message 'test' -NoPush -NoPrune -Path $script:WtPath -Confirm:$false $script:PushCalled | Should -BeFalse } It 'Opens browser to PR URL when -PullRequest is set' { Mock git { $global:LASTEXITCODE = 0 if ($args -contains 'diff') { return 'file.txt' } if (($args -join ' ') -match 'get-url') { return 'https://github.com/user/repo' } } -ModuleName GittHelpers Mock Start-Process { } -ModuleName GittHelpers Save-GitWorktree -Message 'test' -PullRequest -NoPrune -Path $script:WtPath -Confirm:$false Should -Invoke Start-Process -ModuleName GittHelpers -Times 1 ` -ParameterFilter { $FilePath -match 'github\.com' } } It 'Warns and skips PR creation when -PullRequest is combined with -NoPush' { { Save-GitWorktree -Message 'test' -PullRequest -NoPush -NoPrune -Path $script:WtPath -Confirm:$false ` -WarningAction SilentlyContinue } | Should -Not -Throw } It 'Warns when no remote origin is configured and -PullRequest is set' { Mock git { $global:LASTEXITCODE = 0 if ($args -contains 'diff') { return 'file.txt' } # get-url returns nothing — no origin } -ModuleName GittHelpers Mock Start-Process { } -ModuleName GittHelpers { Save-GitWorktree -Message 'test' -PullRequest -NoPrune -Path $script:WtPath -Confirm:$false ` -WarningAction SilentlyContinue } | Should -Not -Throw Should -Invoke Start-Process -ModuleName GittHelpers -Times 0 } } Describe 'Get-PullRequestUrl' { It 'Builds a GitHub PR URL from an HTTPS remote' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'https://github.com/owner/repo.git' -Branch 'feature/login' } $result | Should -Be 'https://github.com/owner/repo/compare/feature/login?expand=1' } It 'Builds a GitHub PR URL from an SSH remote' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'git@github.com:owner/repo.git' -Branch 'feature/login' } $result | Should -Be 'https://github.com/owner/repo/compare/feature/login?expand=1' } It 'Builds an Azure DevOps PR URL from an HTTPS remote' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'https://dev.azure.com/org/project/_git/repo' -Branch 'feature/login' } $result | Should -Be 'https://dev.azure.com/org/project/_git/repo/pullrequestcreate?sourceRef=feature%2Flogin' } It 'Builds an Azure DevOps PR URL from an SSH remote' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'git@ssh.dev.azure.com:v3/org/project/repo' -Branch 'feature/login' } $result | Should -Be 'https://dev.azure.com/org/project/_git/repo/pullrequestcreate?sourceRef=feature%2Flogin' } It 'Appends targetRef to Azure DevOps URL when -BaseBranch is provided' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'https://dev.azure.com/org/project/_git/repo' -Branch 'feature/login' -BaseBranch 'master' } $result | Should -Match 'targetRef=master' } It 'Builds a Bitbucket PR URL' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'https://bitbucket.org/workspace/repo.git' -Branch 'feature/login' } $result | Should -Be 'https://bitbucket.org/workspace/repo/pull-requests/new?source=feature%2Flogin' } It 'Builds a GitLab MR URL' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'https://gitlab.com/namespace/repo.git' -Branch 'feature/login' } $result | Should -Match 'merge_requests/new' $result | Should -Match 'feature%2Flogin' } It 'Returns the base remote URL for unknown providers' { $result = & (Get-Module GittHelpers) { Get-PullRequestUrl -RemoteUrl 'https://mygitserver.internal/owner/repo.git' -Branch 'feature/login' } $result | Should -Be 'https://mygitserver.internal/owner/repo' } } |