Public/Tests/New-JiraTicket.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.jira.psd1') -Force Set-JiraContext -JiraUrl 'https://contoso.atlassian.net' -Username 'user@contoso.com' -PersonalAccessToken 'tok-SECRET-123' $Base = 'https://contoso.atlassian.net' } AfterAll { Remove-Module -Name tcs.jira -Force -ErrorAction SilentlyContinue } Describe 'New-JiraTicket' { BeforeEach { Mock -ModuleName tcs.jira Invoke-RestMethod { [pscustomobject]@{ id = '1'; key = 'PROJ-1' } } } It 'Posts the fields to /rest/api/3/issue and returns the result' { $result = New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'Rotate certificates' -Description 'Expires soon' $result.key | Should -Be 'PROJ-1' Should -Invoke Invoke-RestMethod -ModuleName tcs.jira -Times 1 -Exactly -ParameterFilter { $sent = if ($Body) { $Body | ConvertFrom-Json } else { [pscustomobject]@{} } $Uri -eq "$Base/rest/api/3/issue" -and $Method -eq 'Post' -and $sent.fields.project.key -eq 'PROJ' -and $sent.fields.issuetype.name -eq 'Task' -and $sent.fields.summary -eq 'Rotate certificates' -and $sent.fields.description.type -eq 'doc' -and $sent.fields.description.content[0].content[0].text -eq 'Expires soon' -and $null -eq $sent.fields.customfield_14982 } } It 'Merges -Fields into the create payload' { $null = New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'S' -Fields @{ labels = @('ops'); customfield_10010 = @{ value = 'BAU' } } Should -Invoke Invoke-RestMethod -ModuleName tcs.jira -Times 1 -Exactly -ParameterFilter { $sent = if ($Body) { $Body | ConvertFrom-Json } else { [pscustomobject]@{} } $sent.fields.customfield_10010.value -eq 'BAU' -and (@($sent.fields.labels) -join ',') -eq 'ops' -and $sent.fields.summary -eq 'S' -and $sent.fields.project.key -eq 'PROJ' -and $null -eq $sent.fields.description } } It 'No longer has the site-specific -WorkloadType parameter' { (Get-Command -Name New-JiraTicket).Parameters.Keys | Should -Not -Contain 'WorkloadType' } It 'Does not retry the create request on HTTP 503' { Mock -ModuleName tcs.jira Start-Sleep { } Mock -ModuleName tcs.jira Invoke-RestMethod { $exception = New-Object -TypeName System.Exception -ArgumentList 'Service Unavailable' $exception | Add-Member -NotePropertyName Response -NotePropertyValue ([pscustomobject]@{ StatusCode = 503 }) throw (New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList $exception, 'HttpError', ([System.Management.Automation.ErrorCategory]::InvalidOperation), $null) } { New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'S' -WarningAction SilentlyContinue } | Should -Throw '*503*' Should -Invoke Invoke-RestMethod -ModuleName tcs.jira -Times 1 -Exactly } It 'Does not call Jira with -WhatIf' { New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'S' -WhatIf Should -Invoke Invoke-RestMethod -ModuleName tcs.jira -Times 0 -Exactly } It 'Writes nothing to the information stream or host' { $output = New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'S' 6>&1 @($output).Count | Should -Be 1 $output.key | Should -Be 'PROJ-1' } It 'Requires a summary' { { New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary '' } | Should -Throw } } Describe 'New-JiraTicket telemetry' { BeforeEach { Mock -ModuleName tcs.jira Invoke-RestMethod { [pscustomobject]@{ id = '1'; key = 'PROJ-1' } } Mock -ModuleName tcs.jira Invoke-TelemetryCollection { } } It 'Sends Start and End events and returns only the ticket' { $output = New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'S' @($output).Count | Should -Be 1 $output.key | Should -Be 'PROJ-1' Should -Invoke Invoke-TelemetryCollection -ModuleName tcs.jira -Times 1 -Exactly -ParameterFilter { $CommandName -eq 'New-JiraTicket' -and $Stage -eq 'Start' } Should -Invoke Invoke-TelemetryCollection -ModuleName tcs.jira -Times 1 -Exactly -ParameterFilter { $CommandName -eq 'New-JiraTicket' -and $Stage -eq 'End' -and -not $Failed } } It 'Sends Start and End events with -WhatIf without calling Jira' { New-JiraTicket -ProjectKey 'PROJ' -IssueType 'Task' -Summary 'S' -WhatIf Should -Invoke Invoke-RestMethod -ModuleName tcs.jira -Times 0 -Exactly Should -Invoke Invoke-TelemetryCollection -ModuleName tcs.jira -Times 1 -Exactly -ParameterFilter { $CommandName -eq 'New-JiraTicket' -and $Stage -eq 'Start' } Should -Invoke Invoke-TelemetryCollection -ModuleName tcs.jira -Times 1 -Exactly -ParameterFilter { $CommandName -eq 'New-JiraTicket' -and $Stage -eq 'End' -and -not $Failed } } } |