From 2ac7ddf67c973eff0822185ca6ac14896bd290f2 Mon Sep 17 00:00:00 2001 From: Kuanju Chen Date: Mon, 26 Aug 2024 16:57:09 -0700 Subject: [PATCH] Duplicated fields with same name conflict New-JiraIssues Get-JiraField could return multiple fields upon a name search. When there is only 1 field returns, the field is used as is. When there are many fields, the field with its name matched to its ID is used. Otherwise, an exception is thrown. add tests --- JiraPS/Public/New-JiraIssue.ps1 | 22 +++++++- Tests/Functions/New-JiraIssue.Unit.Tests.ps1 | 58 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/JiraPS/Public/New-JiraIssue.ps1 b/JiraPS/Public/New-JiraIssue.ps1 index d2d83784..68b02daf 100644 --- a/JiraPS/Public/New-JiraIssue.ps1 +++ b/JiraPS/Public/New-JiraIssue.ps1 @@ -119,7 +119,27 @@ function New-JiraIssue { $name = $_key $value = $Fields.$_key - if ($field = Get-JiraField -Field $name -Credential $Credential -Debug:$false) { + $fieldsMatchingName = Get-JiraField -Field $name -Credential $Credential -Debug:$false + if ($fieldsMatchingName.Count -gt 0) { + $field = $fieldsMatchingName[0] + if ($fieldsMatchingName.Count -gt 1) { + $fieldsMatchingId = @($fieldsMatchingName | Where-Object { + $each = $_ + $each.ID -eq $name + }) + if ($fieldsMatchingId.Count -eq 1) { + $field = $fieldsMatchingId[0] + } + else { + $exception = ([System.ArgumentException]"Invalid value for Parameter") + $errorId = 'ParameterValue.InvalidFields' + $errorCategory = 'InvalidArgument' + $errorTarget = $Fields + $errorItem = New-Object -TypeName System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $errorTarget + $errorItem.ErrorDetails = "Field name [$name] matches multiple fields by name or by IDs ($($fieldsMatchingName | Out-String)). Please specify field by ID." + $PSCmdlet.ThrowTerminatingError($errorItem) + } + } # For some reason, this was coming through as a hashtable instead of a String, # which was causing ConvertTo-Json to crash later. # Not sure why, but this forces $id to be a String and not a hashtable. diff --git a/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 b/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 index 6b76ae53..f2fb2b24 100644 --- a/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 +++ b/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 @@ -143,6 +143,64 @@ Describe "New-JiraIssue" -Tag 'Unit' { } } + Context "New-JiraIssue handles duplicate fields" { + # Intentionally output multiple objects of different IDs but with the same name + Mock Get-JiraField { + $Field | % { + $name = $_ + if ($name -eq 'Reporter') { + 'Reporter', 'Reporter_mismatched' | % { + $fieldname = $_ + $object = [PSCustomObject] @{ + 'Id' = "$fieldname" + } + $object.PSObject.TypeNames.Insert(0, 'JiraPS.Field') + $object + } + } + else { + $object = [PSCustomObject] @{ + 'Id' = "$name" + } + $object.PSObject.TypeNames.Insert(0, 'JiraPS.Field') + $object + } + } + } + + It "finds the right field which has a matching name and id" { + Mock Get-JiraIssueCreateMetadata { + @( + @{Name = 'Project'; ID = 'Project'; Required = $true} + @{Name = 'IssueType'; ID = 'IssueType'; Required = $true} + @{Name = 'Priority'; ID = 'Priority'; Required = $true} + @{Name = 'Summary'; ID = 'Summary'; Required = $true} + @{Name = 'Description'; ID = 'Description'; Required = $true} + @{Name = 'Reporter'; ID = 'Reporter'; Required = $true} + @{Name = 'Reporter'; ID = 'Reporter_mismatch'; Required = $false} + ) + } + + { New-JiraIssue @newParams } | Should Not Throw + } + + It "throws when a field name return multiple fields without a field has matching name and id" { + Mock Get-JiraIssueCreateMetadata { + @( + @{Name = 'Project'; ID = 'Project'; Required = $true} + @{Name = 'IssueType'; ID = 'IssueType'; Required = $true} + @{Name = 'Priority'; ID = 'Priority'; Required = $true} + @{Name = 'Summary'; ID = 'Summary'; Required = $true} + @{Name = 'Description'; ID = 'Description'; Required = $true} + @{Name = 'Reporter'; ID = 'Reporter_mismatch1'; Required = $true} + @{Name = 'Reporter'; ID = 'Reporter_mismatch2'; Required = $false} + ) + } + + { New-JiraIssue @newParams } | Should Throw + } + } + Context "Input testing" { It "Checks to make sure all required fields are provided" { # We'll create a custom field that's required, then see what happens when we don't provide it