diff --git a/CHANGELOG.md b/CHANGELOG.md index b51ccb21..6a53cd0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## [NEXT VERSION] - YYYY-MM-DD + +### Added + +- Parameter for retrieving information about a specific user with `Get-JiraUser` (#328, [@michalporeba]) + - this implementations will be changed with the next major update in favor of #306 + ## [2.9] - 2018-12-12 ### Added @@ -21,7 +28,6 @@ - Fixed missing properties on `Get-JiraUser` (#321, [@lipkau]) - Fixed `-DateStarted` on `Add-JiraIssueWorklog` (#324, [@lipkau]) - ## [2.8] - 2018-06-28 More detailed description about the changes can be found on [Our Website](https://atlassianps.org/article/announcement/JiraPS-v2.8.html). @@ -311,6 +317,7 @@ which is in turn inspired by the [Vagrant](https://github.com/mitchellh/vagrant/ [@LiamLeane]: https://github.com/LiamLeane [@lipkau]: https://github.com/lipkau [@lukhase]: https://github.com/lukhase + [@michalporeba]: https://github.com/michalporeba [@padgers]: https://github.com/padgers [@ThePSAdmin]: https://github.com/ThePSAdmin [@tuxgoose]: https://github.com/tuxgoose diff --git a/JiraPS/Private/ConvertTo-JiraProject.ps1 b/JiraPS/Private/ConvertTo-JiraProject.ps1 index 24f49e32..5b84ab01 100644 --- a/JiraPS/Private/ConvertTo-JiraProject.ps1 +++ b/JiraPS/Private/ConvertTo-JiraProject.ps1 @@ -20,6 +20,7 @@ function ConvertTo-JiraProject { 'Roles' = $i.roles 'RestUrl' = $i.self 'Components' = $i.components + 'Style' = $i.style } if ($i.projectCategory) { diff --git a/JiraPS/Public/Get-JiraComponent.ps1 b/JiraPS/Public/Get-JiraComponent.ps1 index 4374669b..57a9735d 100644 --- a/JiraPS/Public/Get-JiraComponent.ps1 +++ b/JiraPS/Public/Get-JiraComponent.ps1 @@ -56,26 +56,22 @@ function Get-JiraComponent { switch ($PSCmdlet.ParameterSetName) { "ByProject" { - if ($Project.PSObject.TypeNames -contains 'JiraPS.Project') { - Write-Output (Get-JiraComponent -ComponentId ($Project.Components).id) - } - else { - foreach ($_project in $Project) { - Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$_project]" - Write-Debug "[$($MyInvocation.MyCommand.Name)] Processing `$_project [$_project]" - - if ($_project -is [string]) { - $parameter = @{ - URI = $resourceURi -f "/project/$_project/components" - Method = "GET" - Credential = $Credential - } - Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter" - $result = Invoke-JiraMethod @parameter + foreach ($_project in $Project) { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$_project]" + Write-Debug "[$($MyInvocation.MyCommand.Name)] Processing `$_project [$_project]" - Write-Output (ConvertTo-JiraComponent -InputObject $result) - } + if ($_project -isnot [string]) { + $_project = $_project.Key } + $parameter = @{ + URI = $resourceURi -f "/project/$_project/components" + Method = "GET" + Credential = $Credential + } + Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter" + $result = Invoke-JiraMethod @parameter + + Write-Output (ConvertTo-JiraComponent -InputObject $result) } } "ByID" { diff --git a/JiraPS/Public/Get-JiraIssueCreateMetadata.ps1 b/JiraPS/Public/Get-JiraIssueCreateMetadata.ps1 index f1a03ab0..8e1b05c8 100644 --- a/JiraPS/Public/Get-JiraIssueCreateMetadata.ps1 +++ b/JiraPS/Public/Get-JiraIssueCreateMetadata.ps1 @@ -29,7 +29,17 @@ function Get-JiraIssueCreateMetadata { Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)" $projectObj = Get-JiraProject -Project $Project -Credential $Credential -ErrorAction Stop - $issueTypeObj = Get-JiraIssueType -IssueType $IssueType -Credential $Credential -ErrorAction Stop + $issueTypeObj = $projectObj.IssueTypes | Where-Object -FilterScript {$_.Id -eq $IssueType -or $_.Name -eq $IssueType} + + if ($null -eq $issueTypeObj.Id) + { + $errorMessage = @{ + Category = "InvalidResult" + CategoryActivity = "Validating parameters" + Message = "No issue types were found in the project [$Project] for the given issue type [$IssueType]. Use Get-JiraIssueType for more details." + } + Write-Error @errorMessage + } $parameter = @{ URI = $resourceURi -f $projectObj.Id, $issueTypeObj.Id diff --git a/JiraPS/Public/Get-JiraUser.ps1 b/JiraPS/Public/Get-JiraUser.ps1 index 640517ce..aa18cc30 100644 --- a/JiraPS/Public/Get-JiraUser.ps1 +++ b/JiraPS/Public/Get-JiraUser.ps1 @@ -11,6 +11,10 @@ function Get-JiraUser { [Parameter( Position = 0, Mandatory, ParameterSetName = 'ByInputObject' )] [Object[]] $InputObject, + [Parameter( ParameterSetName = 'ByInputObject' )] + [Parameter( ParameterSetName = 'ByUserName' )] + [Switch]$Exact, + [Switch] $IncludeInactive, @@ -37,6 +41,7 @@ function Get-JiraUser { $selfResourceUri = "$server/rest/api/latest/myself" $searchResourceUri = "$server/rest/api/latest/user/search?username={0}" + $exactResourceUri = "$server/rest/api/latest/user?username={0}" if ($IncludeInactive) { $searchResourceUri += "&includeInactive=true" @@ -80,7 +85,7 @@ function Get-JiraUser { $PsCmdlet.ParameterSetName = "ByUserName" } "ByUserName" { - $resourceURi = $searchResourceUri + $resourceURi = if ($Exact) { $exactResourceUri } else { $searchResourceUri } foreach ($user in $UserName) { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$user]" diff --git a/JiraPS/Public/New-JiraIssue.ps1 b/JiraPS/Public/New-JiraIssue.ps1 index 53751b6d..ee2beced 100644 --- a/JiraPS/Public/New-JiraIssue.ps1 +++ b/JiraPS/Public/New-JiraIssue.ps1 @@ -66,7 +66,17 @@ function New-JiraIssue { Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)" $ProjectObj = Get-JiraProject -Project $Project -Credential $Credential -ErrorAction Stop -Debug:$false - $IssueTypeObj = Get-JiraIssueType -IssueType $IssueType -Credential $Credential -ErrorAction Stop -Debug:$false + $issueTypeObj = $projectObj.IssueTypes | Where-Object -FilterScript {$_.Id -eq $IssueType -or $_.Name -eq $IssueType} + + if ($null -eq $issueTypeObj.Id) + { + $errorMessage = @{ + Category = "InvalidResult" + CategoryActivity = "Validating parameters" + Message = "No issue types were found in the project [$Project] for the given issue type [$IssueType]. Use Get-JiraIssueType for more details." + } + Write-Error @errorMessage + } $requestBody = @{ "project" = @{"id" = $ProjectObj.Id} @@ -85,6 +95,10 @@ function New-JiraIssue { if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey("Reporter")) { $requestBody["reporter"] = @{"name" = "$Reporter"} } + elseif ($ProjectObj.Style -eq "next-gen"){ + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] Adding reporter as next-gen projects must have reporter set." + $requestBody["reporter"] = @{"name" = "$((Get-JiraUser -Credential $Credential).Name)"} + } if ($Parent) { $requestBody["parent"] = @{"key" = $Parent} diff --git a/JiraPS/Public/Set-JiraIssue.ps1 b/JiraPS/Public/Set-JiraIssue.ps1 index 2dfb465e..01bce57c 100644 --- a/JiraPS/Public/Set-JiraIssue.ps1 +++ b/JiraPS/Public/Set-JiraIssue.ps1 @@ -96,7 +96,7 @@ function Set-JiraIssue { $validAssignee = $true } else { - if ($assigneeObj = Get-JiraUser -UserName $Assignee -Credential $Credential) { + if ($assigneeObj = Get-JiraUser -UserName $Assignee -Credential $Credential -Exact) { Write-Debug "[$($MyInvocation.MyCommand.Name)] User found (name=[$($assigneeObj.Name)],RestUrl=[$($assigneeObj.RestUrl)])" $assigneeString = $assigneeObj.Name $validAssignee = $true diff --git a/Tests/Functions/Get-JiraIssueAttachmentFile.Unit.Tests.ps1 b/Tests/Functions/Get-JiraIssueAttachmentFile.Unit.Tests.ps1 index eeb9863f..a3d0b2e3 100644 --- a/Tests/Functions/Get-JiraIssueAttachmentFile.Unit.Tests.ps1 +++ b/Tests/Functions/Get-JiraIssueAttachmentFile.Unit.Tests.ps1 @@ -122,7 +122,6 @@ Describe "Get-JiraIssueAttachmentFile" -Tag 'Unit' { } It 'uses Invoke-JiraMethod for saving to disk' { - $script:ShowMockData = $true Get-JiraIssueAttachment -Issue "Foo" | Get-JiraIssueAttachmentFile Get-JiraIssueAttachment -Issue "Foo" | Get-JiraIssueAttachmentFile -Path "../" diff --git a/Tests/Functions/Get-JiraIssueCreateMetadata.Unit.Tests.ps1 b/Tests/Functions/Get-JiraIssueCreateMetadata.Unit.Tests.ps1 index 8562c198..c8cbdc75 100644 --- a/Tests/Functions/Get-JiraIssueCreateMetadata.Unit.Tests.ps1 +++ b/Tests/Functions/Get-JiraIssueCreateMetadata.Unit.Tests.ps1 @@ -218,23 +218,20 @@ Describe "Get-JiraIssueCreateMetadata" -Tag 'Unit' { } Mock Get-JiraProject -ModuleName JiraPS { + $issueObject = [PSCustomObject] @{ + ID = 2 + Name = 'Test Issue Type' + } + $issueObject.PSObject.TypeNames.Insert(0, 'JiraPS.IssueType') $object = [PSCustomObject] @{ ID = 10003 Name = 'Test Project' } + Add-Member -InputObject $object -MemberType NoteProperty -Name "IssueTypes" -Value $issueObject $object.PSObject.TypeNames.Insert(0, 'JiraPS.Project') return $object } - Mock Get-JiraIssueType -ModuleName JiraPS { - $object = [PSCustomObject] @{ - ID = 2 - Name = 'Test Issue Type' - } - $object.PSObject.TypeNames.Insert(0, 'JiraPS.IssueType') - return $object - } - Mock ConvertTo-JiraCreateMetaField -ModuleName JiraPS { $InputObject } diff --git a/Tests/Functions/Get-JiraUser.Unit.Tests.ps1 b/Tests/Functions/Get-JiraUser.Unit.Tests.ps1 index cd09868c..d8a13a43 100644 --- a/Tests/Functions/Get-JiraUser.Unit.Tests.ps1 +++ b/Tests/Functions/Get-JiraUser.Unit.Tests.ps1 @@ -108,6 +108,12 @@ Describe "Get-JiraUser" -Tag 'Unit' { ConvertFrom-Json -InputObject $restResult } + # Get exact user + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter {$Method -eq 'Get' -and $URI -like "$jiraServer/rest/api/*/user?username=$testUsername"} { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + ConvertFrom-Json -InputObject $restResult + } + # Viewing a specific user. The main difference here is that this includes groups, and the first does not. Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter {$Method -eq 'Get' -and $URI -like "$jiraServer/rest/api/*/user?username=$testUsername&expand=groups"} { ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' @@ -138,6 +144,16 @@ Describe "Get-JiraUser" -Tag 'Unit' { $getResult | Should Not BeNullOrEmpty + Assert-MockCalled -CommandName Invoke-JiraMethod -Exactly 1 -Scope It -ParameterFilter {$URI -like "$jiraServer/rest/api/*/user/search?*username=$testUsername*"} + Assert-MockCalled -CommandName Invoke-JiraMethod -Exactly 1 -Scope It -ParameterFilter {$URI -like "$jiraServer/rest/api/*/user?username=$testUsername&expand=groups"} + } + + It "Gets information about a provided Jira exact user" { + $getResult = Get-JiraUser -UserName $testUsername -Exact + + $getResult | Should Not BeNullOrEmpty + + Assert-MockCalled -CommandName Invoke-JiraMethod -Exactly 1 -Scope It -ParameterFilter {$Method -eq 'Get' -and $URI -like "$jiraServer/rest/api/*/user?username=$testUsername"} Assert-MockCalled -CommandName Invoke-JiraMethod -Exactly 1 -Scope It -ParameterFilter {$URI -like "$jiraServer/rest/api/*/user?username=$testUsername&expand=groups"} } diff --git a/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 b/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 index 8ccb039f..6b76ae53 100644 --- a/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 +++ b/Tests/Functions/New-JiraIssue.Unit.Tests.ps1 @@ -39,6 +39,7 @@ Describe "New-JiraIssue" -Tag 'Unit' { $jiraServer = 'https://jira.example.com' + $issueTypeTest = 1 Mock Get-JiraConfigServer { $jiraServer @@ -56,22 +57,20 @@ Describe "New-JiraIssue" -Tag 'Unit' { } Mock Get-JiraProject { + $issueObject = [PSCustomObject] @{ + ID = $issueTypeTest + Name = 'Test Issue Type' + } + $issueObject.PSObject.TypeNames.Insert(0, 'JiraPS.IssueType') $object = [PSCustomObject] @{ 'ID' = $Project 'Key' = "TEST" } + Add-Member -InputObject $object -MemberType NoteProperty -Name "IssueTypes" -Value $issueObject $object.PSObject.TypeNames.Insert(0, 'JiraPS.Project') return $object } - Mock Get-JiraIssueType { - $object = [PSCustomObject] @{ - 'ID' = $IssueType; - } - $object.PSObject.TypeNames.Insert(0, 'JiraPS.IssueType') - return $object - } - Mock Get-JiraUser { $object = [PSCustomObject] @{ 'Name' = $UserName; diff --git a/docs/en-US/commands/Get-JiraUser.md b/docs/en-US/commands/Get-JiraUser.md index 76d9d06c..fa55f7eb 100644 --- a/docs/en-US/commands/Get-JiraUser.md +++ b/docs/en-US/commands/Get-JiraUser.md @@ -24,13 +24,13 @@ Get-JiraUser [-Credential ] [] ### ByUserName ```powershell -Get-JiraUser [-UserName] [-IncludeInactive] [[-MaxResults] ] [[-Skip] ] [-Credential ] [] +Get-JiraUser [-UserName] [-IncludeInactive] [[-MaxResults] ] [[-Skip] ] [-Credential ] [-Exact] [] ``` ### ByInputObject ```powershell -Get-JiraUser [-InputObject] [-IncludeInactive] [-Credential ] [] +Get-JiraUser [-InputObject] [-IncludeInactive] [-Credential ] [-Exact] [] ``` ## DESCRIPTION @@ -45,7 +45,7 @@ This function returns information regarding a specified user from Jira. Get-JiraUser -UserName user1 ``` -Returns information about the user user1 +Returns information about all users with username like user1 ### EXAMPLE 2 @@ -63,6 +63,14 @@ Get-JiraUser -Credential $cred This example returns the JIRA user that is executing the command. +### EXAMPLE 4 + +```powershell +Get-JiraUser -UserName user1 -Exact +``` + +Returns information about user user1 + ## PARAMETERS ### -UserName @@ -97,6 +105,22 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Exact + +Limits the search to users where the username is exactly the term searched for. + +```yaml +Type: Switch +Parameter Sets: ByUserName, ByInputObject +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -IncludeInactive Include inactive users in the search