diff --git a/JiraPS/Public/Get-JiraIssue.ps1 b/JiraPS/Public/Get-JiraIssue.ps1 index 517b83fb..ae208d0c 100644 --- a/JiraPS/Public/Get-JiraIssue.ps1 +++ b/JiraPS/Public/Get-JiraIssue.ps1 @@ -65,6 +65,11 @@ function Get-JiraIssue { [Object] $Filter, + [Parameter()] + [ValidateNotNullOrEmpty()] + [String[]] + $Fields = "*all", + [Parameter( ParameterSetName = 'ByJQL' )] [Parameter( ParameterSetName = 'ByFilter' )] [UInt32] @@ -91,8 +96,10 @@ function Get-JiraIssue { $server = Get-JiraConfigServer -ErrorAction Stop - $resourceURi = "$server/rest/api/latest/issue/{0}?expand=transitions" $searchURi = "$server/rest/api/latest/search" + $resourceURi = "$server/rest/api/latest/issue/{0}" + + [String]$Fields = $Fields -join "," } process { @@ -105,11 +112,18 @@ function Get-JiraIssue { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$_key]" Write-Debug "[$($MyInvocation.MyCommand.Name)] Processing `$_key [$_key]" + $getParameter = @{ expand = "transitions" } + if ($Fields) { + $getParameter["fields"] = $Fields + } + $parameter = @{ - URI = $resourceURi -f $_key - Method = "GET" - Credential = $Credential + URI = $resourceURi -f $_key + Method = "GET" + GetParameter = $getParameter + Credential = $Credential } + Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter" $result = Invoke-JiraMethod @parameter @@ -122,7 +136,7 @@ function Get-JiraIssue { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$_issue]" Write-Debug "[$($MyInvocation.MyCommand.Name)] Processing `$_issue [$_issue]" - Write-Output (Get-JiraIssue -Key $_issue.Key -Credential $Credential) + Write-Output (Get-JiraIssue -Key $_issue.Key -Fields $Fields -Credential $Credential) } } 'ByJQL' { @@ -134,11 +148,15 @@ function Get-JiraIssue { validateQuery = $true expand = "transitions" maxResults = $PageSize + } OutputType = "JiraIssue" Paging = $true Credential = $Credential } + if ($Fields) { + $parameter["GetParameter"]["fields"] = $Fields + } # Paging ($PSCmdlet.PagingParameters | Get-Member -MemberType Property).Name | ForEach-Object { $parameter[$_] = $PSCmdlet.PagingParameters.$_ @@ -158,14 +176,14 @@ function Get-JiraIssue { Invoke-JiraMethod @parameter } 'ByFilter' { - $filterObj = Get-JiraFilter -InputObject $Filter -Credential $Credential -ErrorAction Stop + $filterObj = (Get-JiraFilter -InputObject $Filter -Credential $Credential -ErrorAction Stop).searchurl <# #ToDo:CustomClass Once we have custom classes, this will no longer be necessary #> $parameter = @{ - URI = $filterObj.SearchUrl + URI = $filterObj Method = "GET" GetParameter = @{ validateQuery = $true @@ -175,6 +193,10 @@ function Get-JiraIssue { OutputType = "JiraIssue" Paging = $true Credential = $Credential + + } + if ($Fields) { + $parameter["GetParameter"]["fields"] = $Fields } # Paging ($PSCmdlet.PagingParameters | Get-Member -MemberType Property).Name | ForEach-Object { diff --git a/Tests/Get-JiraIssue.Tests.ps1 b/Tests/Get-JiraIssue.Tests.ps1 index 8ecd54fc..dfbb9aee 100644 --- a/Tests/Get-JiraIssue.Tests.ps1 +++ b/Tests/Get-JiraIssue.Tests.ps1 @@ -1,6 +1,8 @@ Describe "Get-JiraIssue" { - - Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + BeforeAll { + Remove-Module JiraPS -ErrorAction SilentlyContinue + Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + } InModuleScope JiraPS { @@ -28,31 +30,54 @@ '@ #region Mocks - Mock Get-JiraConfigServer { + Mock Get-JiraConfigServer -ModuleName JiraPS { $jiraServer } - Mock Invoke-JiraMethod -ParameterFilter { $Method -eq 'Get' -and $URI -like "$jiraServer/rest/api/latest/issue/TEST-001*" } { + Mock Get-JiraUser -ModuleName JiraPS { + $object = [PSCustomObject] @{ + 'Name' = 'username' + } + $object.PSObject.TypeNames.Insert(0, 'JiraPS.User') + return $object + } + + Mock Get-JiraFilter -ModuleName JiraPS { + [PSCustomObject]@{ + PSTypeName = "JiraPS.Filter" + Id = 12345 + SearchUrl = "https://jira.example.com/rest/api/latest/filter/12345" + } + } + + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter { + $Method -eq 'Get' -and + $URI -like "$jiraServer/rest/api/*/issue/TEST-001*" + } { ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' ConvertFrom-Json $response } - Mock Invoke-JiraMethod -ParameterFilter { $Method -eq 'Get' -and $URI -like "$jiraServer/rest/api/latest/search" -and $GetParameter["jql"] -eq $jqlEscaped } { + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter { + $Method -eq 'Get' -and + $URI -like "$jiraServer/rest/api/*/search" -and + $GetParameter["jql"] -eq $jqlEscaped + } { ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' ConvertFrom-Json $response } - Mock Invoke-JiraMethod { + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter { + $Method -eq 'Get' -and + $URI -like "$jiraServer/rest/api/*/filter/*" + } { ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' - throw "Unidentified call to Invoke-JiraMethod" + ConvertFrom-Json $response } - Mock Get-JiraUser { - $object = [PSCustomObject] @{ - 'Name' = 'username' - } - $object.PSObject.TypeNames.Insert(0, 'JiraPS.User') - return $object + Mock Invoke-JiraMethod -ModuleName JiraPS { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + throw "Unidentified call to Invoke-JiraMethod" } #endregion Mocks @@ -63,6 +88,7 @@ defParam $command 'InputObject' defParam $command 'Query' defParam $command 'Filter' + defParam $command 'Fields' defParam $command 'StartIndex' defParam $command 'MaxResults' defParam $command 'PageSize' @@ -72,7 +98,7 @@ Context "Behavior testing" { It "Obtains information about a provided issue in JIRA" { - { Get-JiraIssue -Key TEST-001 } | Should Not Throw + { Get-JiraIssue -Key TEST-001 } | Should -Not -Throw $assertMockCalledSplat = @{ CommandName = 'Invoke-JiraMethod' @@ -89,7 +115,7 @@ } It "Uses JQL to search for issues if the -Query parameter is used" { - { Get-JiraIssue -Query $jql } | Should Not Throw + { Get-JiraIssue -Query $jql } | Should -Not -Throw $assertMockCalledSplat = @{ CommandName = 'Invoke-JiraMethod' @@ -107,7 +133,7 @@ } It "Supports the -StartIndex and -MaxResults parameters to page through search results" { - { Get-JiraIssue -Query $jql -StartIndex 10 -MaxResults 50 } | Should Not Throw + { Get-JiraIssue -Query $jql -StartIndex 10 -MaxResults 50 } | Should -Not -Throw $assertMockCalledSplat = @{ CommandName = 'Invoke-JiraMethod' @@ -127,7 +153,7 @@ } It "Returns all issues via looping if -MaxResults is not specified" { - { Get-JiraIssue -Query $jql -PageSize 25 } | Should Not Throw + { Get-JiraIssue -Query $jql -PageSize 25 } | Should -Not -Throw $assertMockCalledSplat = @{ CommandName = 'Invoke-JiraMethod' @@ -144,11 +170,78 @@ } Assert-MockCalled @assertMockCalledSplat } + + It "Returns only the fields required with -Fields" { + $issue = [PSCustomObject]@{ + PSTypeName = "JiraPS.Issue" + Key = "TEST-001" + } + + { Get-JiraIssue -Key TEST-001 } | Should -Not -Throw + { Get-JiraIssue -Key TEST-001 -Fields "key" } | Should -Not -Throw + { Get-JiraIssue -Key TEST-001 -Fields "-summary" } | Should -Not -Throw + { Get-JiraIssue -Key TEST-001 -Fields "key", "summary", "status" } | Should -Not -Throw + { Get-JiraIssue -InputObject $issue -Fields "key", "summary", "status" } | Should -Not -Throw + { Get-JiraIssue -Query $jql -Fields "key", "summary", "status" } | Should -Not -Throw + { Get-JiraIssue -Filter "12345" -Fields "key", "summary", "status" } | Should -Not -Throw + + $assertMockCalledSplat = @{ + CommandName = 'Invoke-JiraMethod' + ModuleName = 'JiraPS' + ParameterFilter = { + $Method -eq 'Get' -and + $GetParameter["fields"] -eq "*all" + } + Scope = 'It' + Exactly = $true + Times = 1 + } + Assert-MockCalled @assertMockCalledSplat + + $assertMockCalledSplat = @{ + CommandName = 'Invoke-JiraMethod' + ModuleName = 'JiraPS' + ParameterFilter = { + $Method -eq 'Get' -and + $GetParameter["fields"] -eq "key" + } + Scope = 'It' + Exactly = $true + Times = 1 + } + Assert-MockCalled @assertMockCalledSplat + + $assertMockCalledSplat = @{ + CommandName = 'Invoke-JiraMethod' + ModuleName = 'JiraPS' + ParameterFilter = { + $Method -eq 'Get' -and + $GetParameter["fields"] -eq "-summary" + } + Scope = 'It' + Exactly = $true + Times = 1 + } + Assert-MockCalled @assertMockCalledSplat + + $assertMockCalledSplat = @{ + CommandName = 'Invoke-JiraMethod' + ModuleName = 'JiraPS' + ParameterFilter = { + $Method -eq 'Get' -and + $GetParameter["fields"] -eq "key,summary,status" + } + Scope = 'It' + Exactly = $true + Times = 4 + } + Assert-MockCalled @assertMockCalledSplat + } } Context "Input testing" { It "Accepts an issue key for the -Key parameter" { - { Get-JiraIssue -Key TEST-001 } | Should Not Throw + { Get-JiraIssue -Key TEST-001 } | Should -Not -Throw $assertMockCalledSplat = @{ CommandName = 'Invoke-JiraMethod' @@ -172,7 +265,7 @@ $issue.PSObject.TypeNames.Insert(0, 'JiraPS.Issue') # Should call Get-JiraIssue using the -Key parameter, so our URL should reflect the key we provided - { Get-JiraIssue -InputObject $Issue } | Should Not Throw + { Get-JiraIssue -InputObject $Issue } | Should -Not -Throw $assertMockCalledSplat = @{ CommandName = 'Invoke-JiraMethod' diff --git a/docs/en-US/commands/Get-JiraIssue.md b/docs/en-US/commands/Get-JiraIssue.md index 5a01c7c9..f4b0f964 100644 --- a/docs/en-US/commands/Get-JiraIssue.md +++ b/docs/en-US/commands/Get-JiraIssue.md @@ -18,29 +18,31 @@ Returns information about an issue in JIRA. ### ByIssueKey (Default) ```powershell -Get-JiraIssue [-Key] [-IncludeTotalCount] [-Skip ] [-First ] - [-Credential ] [] +Get-JiraIssue [-Key] [-Fields ] [-IncludeTotalCount] + [-Skip ] [-First ] [-Credential ] [] ``` ### ByInputObject ```powershell -Get-JiraIssue [-InputObject] [-IncludeTotalCount] [-Skip ] [-First ] - [-Credential ] [] +Get-JiraIssue [-InputObject] [-Fields ] [-IncludeTotalCount] + [-Skip ] [-First ] [-Credential ] [] ``` ### ByJQL ```powershell -Get-JiraIssue -Query [-StartIndex ] [-MaxResults ] [[PageSize] ] - [-IncludeTotalCount] [-Skip ] [-First ] [-Credential ] [] +Get-JiraIssue -Query [-Fields ] [-StartIndex ] +[-MaxResults ] [[PageSize] ] [-IncludeTotalCount] [-Skip ] + [-First ] [-Credential ] [] ``` ### ByFilter ```powershell -Get-JiraIssue -Filter [-StartIndex ] [-MaxResults ] [[PageSize] ] - [-IncludeTotalCount] [-Skip ] [-First ] [-Credential ] [] +Get-JiraIssue -Filter [-Fields ][-StartIndex ] + [-MaxResults ] [[PageSize] ] [-IncludeTotalCount] [-Skip ] + [-First ] [-Credential ] [] ``` ## DESCRIPTION @@ -102,11 +104,23 @@ This example retrieves all issues that match the criteria in the saved filter wi ### EXAMPLE 6 ```powershell -Get-JiraFilter 12345 | Select-Object * +Get-JiraFilter 12345 | Get-JiraIssue | Select-Object * ``` This prints all fields of the issue to the console. +### Example 7 + +```powershell +Get-JiraIssue -Query "project = TEST" -Fields "key", "summary", "assignee" +``` + +This example retrieves all issues in project "TEST" - but only the 3 properties +listed above: key, summary and assignee + +By retrieving only the data really needed, the payload the server sends is +reduced, which speeds up the query. + ## PARAMETERS ### -Key @@ -173,6 +187,31 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Fields + +Field you would like to select from your issue. By default, all fields are +returned. + +Allowed values: + +- `"*all"` - return all fields. +- `"*navigable"` - return navigable fields only. +- `"summary", "comment"` - return the summary and comments fields only. +- `"-comment"` - return all fields except comments. +- `"*all", "-comment"` - same as above + +```yaml +Type: String[] +Parameter Sets: ByFilter +Aliases: + +Required: False +Position: Named +Default value: "*all" +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -StartIndex > NOTE: This parameter has been marked as deprecated and will be removed with the next major release.