diff --git a/JiraPS/Private/ConvertTo-JiraFilter.ps1 b/JiraPS/Private/ConvertTo-JiraFilter.ps1 index 6eb2be6f..15f1b635 100644 --- a/JiraPS/Private/ConvertTo-JiraFilter.ps1 +++ b/JiraPS/Private/ConvertTo-JiraFilter.ps1 @@ -3,7 +3,10 @@ function ConvertTo-JiraFilter { param( [Parameter( ValueFromPipeline )] [PSObject[]] - $InputObject + $InputObject, + + [PSObject[]] + $FilterPermissions ) process { @@ -11,17 +14,22 @@ function ConvertTo-JiraFilter { Write-Debug "[$($MyInvocation.MyCommand.Name)] Converting `$InputObject to custom object" $props = @{ - 'ID' = $i.id - 'Name' = $i.name - 'JQL' = $i.jql - 'RestUrl' = $i.self - 'ViewUrl' = $i.viewUrl - 'SearchUrl' = $i.searchUrl - 'Favourite' = $i.favourite - - 'SharePermission' = $i.sharePermissions - 'SharedUser' = $i.sharedUsers - 'Subscription' = $i.subscriptions + 'ID' = $i.id + 'Name' = $i.name + 'JQL' = $i.jql + 'RestUrl' = $i.self + 'ViewUrl' = $i.viewUrl + 'SearchUrl' = $i.searchUrl + 'Favourite' = $i.favourite + 'FilterPermissions' = @() + + 'SharePermission' = $i.sharePermissions + 'SharedUser' = $i.sharedUsers + 'Subscription' = $i.subscriptions + } + + if ($FilterPermissions) { + $props.FilterPermissions = @(ConvertTo-JiraFilterPermission ($FilterPermissions)) } if ($i.description) { diff --git a/JiraPS/Private/ConvertTo-JiraFilterPermission.ps1 b/JiraPS/Private/ConvertTo-JiraFilterPermission.ps1 new file mode 100644 index 00000000..95cd1225 --- /dev/null +++ b/JiraPS/Private/ConvertTo-JiraFilterPermission.ps1 @@ -0,0 +1,39 @@ +function ConvertTo-JiraFilterPermission { + [CmdletBinding()] + param( + [Parameter( ValueFromPipeline )] + [PSObject[]] + $InputObject + ) + + process { + foreach ($i in $InputObject) { + Write-Debug "[$($MyInvocation.MyCommand.Name)] Converting `$InputObject to custom object" + + $props = @{ + 'ID' = $i.id + 'Type' = $i.type + 'Group' = $null + 'Project' = $null + 'Role' = $null + } + if ($i.group) { + $props["Group"] = ConvertTo-JiraGroup $i.group + } + if ($i.project) { + $props["Project"] = ConvertTo-JiraProject $i.project + } + if ($i.role) { + $props["Role"] = ConvertTo-JiraProjectRole $i.role + } + + $result = New-Object -TypeName PSObject -Property $props + $result.PSObject.TypeNames.Insert(0, 'JiraPS.FilterPermission') + $result | Add-Member -MemberType ScriptMethod -Name 'ToString' -Force -Value { + Write-Output "$($this.Type)" + } + + Write-Output $result + } + } +} diff --git a/JiraPS/Private/ConvertTo-JiraProjectRole.ps1 b/JiraPS/Private/ConvertTo-JiraProjectRole.ps1 new file mode 100644 index 00000000..aef189f7 --- /dev/null +++ b/JiraPS/Private/ConvertTo-JiraProjectRole.ps1 @@ -0,0 +1,30 @@ +function ConvertTo-JiraProjectRole { + [CmdletBinding()] + param( + [Parameter( ValueFromPipeline )] + [PSObject[]] + $InputObject + ) + + process { + foreach ($i in $InputObject) { + Write-Debug "[$($MyInvocation.MyCommand.Name)] Converting `$InputObject to custom object" + + $props = @{ + 'ID' = $i.id + 'Name' = $i.name + 'Description' = $i.description + 'Actors' = $i.actors + 'RestUrl' = $i.self + } + + $result = New-Object -TypeName PSObject -Property $props + $result.PSObject.TypeNames.Insert(0, 'JiraPS.ProjectRole') + $result | Add-Member -MemberType ScriptMethod -Name "ToString" -Force -Value { + Write-Output "$($this.Name)" + } + + Write-Output $result + } + } +} diff --git a/JiraPS/Private/Resolve-FullPath.ps1 b/JiraPS/Private/Resolve-FullPath.ps1 new file mode 100644 index 00000000..75e4af72 --- /dev/null +++ b/JiraPS/Private/Resolve-FullPath.ps1 @@ -0,0 +1,35 @@ +function Resolve-FullPath { + [CmdletBinding()] + param ( + # Path to be resolved. + # Can be realtive or absolute. + # Resolves PSDrives + [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] + [ValidateNotNullOrEmpty()] + [ValidateScript( + { + if (-not (Test-Path $_ -PathType Leaf)) { + $errorItem = [System.Management.Automation.ErrorRecord]::new( + ([System.ArgumentException]"File not found"), + 'ParameterValue.FileNotFound', + [System.Management.Automation.ErrorCategory]::ObjectNotFound, + $_ + ) + $errorItem.ErrorDetails = "No file could be found with the provided path '$_'." + $PSCmdlet.ThrowTerminatingError($errorItem) + } + else { + return $true + } + } + )] + [Alias( 'FullName', 'PSPath' )] + [String] + $Path + ) + + process { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Resolving path $Path" + $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Path) + } +} diff --git a/JiraPS/Public/Add-JiraFilterPermission.ps1 b/JiraPS/Public/Add-JiraFilterPermission.ps1 new file mode 100644 index 00000000..6e2ca439 --- /dev/null +++ b/JiraPS/Public/Add-JiraFilterPermission.ps1 @@ -0,0 +1,79 @@ +function Add-JiraFilterPermission { + [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName = 'ByInputObject' )] + # [OutputType( [JiraPS.FilterPermission] )] + param( + [Parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = 'ByInputObject' )] + [ValidateNotNullOrEmpty()] + [PSTypeName('JiraPS.Filter')] + $Filter, + + [Parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] + [ValidateNotNullOrEmpty()] + [UInt32[]] + $Id, + + [Parameter( Mandatory )] + [ValidateNotNullOrEmpty()] + [ValidateSet('Group', 'Project', 'ProjectRole', 'Authenticated', 'Global')] + [String]$Type, + + [Parameter()] + [String]$Value, + + [Parameter()] + [System.Management.Automation.PSCredential] + [System.Management.Automation.Credential()] + $Credential = [System.Management.Automation.PSCredential]::Empty + ) + + begin { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started" + + $resourceURi = "{0}/permission" + } + + process { + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] ParameterSetName: $($PsCmdlet.ParameterSetName)" + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)" + + if ($PSCmdlet.ParameterSetName -eq 'ById') { + $Filter = Get-JiraFilter -Id $Id + } + + $body = @{ + type = $Type.ToLower() + } + switch ($Type) { + "Group" { + $body["groupname"] = $Value + } + "Project" { + $body["projectId"] = $Value + } + "ProjectRole" { + $body["projectRoleId"] = $Value + } + "Authenticated" { } + "Global" { } + } + + foreach ($_filter in $Filter) { + $parameter = @{ + URI = $resourceURi -f $_filter.RestURL + Method = "POST" + Body = ConvertTo-Json $body + Credential = $Credential + } + Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter" + if ($PSCmdlet.ShouldProcess($_filter.Name, "Add Permission [$Type - $Value]")) { + $result = Invoke-JiraMethod @parameter + + Write-Output (ConvertTo-JiraFilter -InputObject $_filter -FilterPermissions $result) + } + } + } + + end { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete" + } +} diff --git a/JiraPS/Public/Get-JiraFilterPermission.ps1 b/JiraPS/Public/Get-JiraFilterPermission.ps1 new file mode 100644 index 00000000..bc8fc4f6 --- /dev/null +++ b/JiraPS/Public/Get-JiraFilterPermission.ps1 @@ -0,0 +1,51 @@ +function Get-JiraFilterPermission { + [CmdletBinding( DefaultParameterSetName = 'ById' )] + # [OutputType( [JiraPS.FilterPermission] )] + param( + [Parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = 'ByInputObject' )] + [ValidateNotNullOrEmpty()] + [PSTypeName('JiraPS.Filter')] + $Filter, + + [Parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] + [ValidateNotNullOrEmpty()] + [UInt32[]] + $Id, + + [Parameter()] + [System.Management.Automation.PSCredential] + [System.Management.Automation.Credential()] + $Credential = [System.Management.Automation.PSCredential]::Empty + ) + + begin { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started" + + $resourceURi = "{0}/permission" + } + + process { + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] ParameterSetName: $($PsCmdlet.ParameterSetName)" + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)" + + if ($PSCmdlet.ParameterSetName -eq 'ById') { + $Filter = Get-JiraFilter -Id $Id + } + + foreach ($_filter in $Filter) { + $parameter = @{ + URI = $resourceURi -f $_filter.RestURL + Method = "GET" + Credential = $Credential + } + Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter" + $result = Invoke-JiraMethod @parameter + + Write-Output (ConvertTo-JiraFilter -InputObject $_filter -FilterPermissions $result) + } + } + + end { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete" + } +} diff --git a/JiraPS/Public/Remove-JiraFilter.ps1 b/JiraPS/Public/Remove-JiraFilter.ps1 index 8a892bdf..886a7709 100644 --- a/JiraPS/Public/Remove-JiraFilter.ps1 +++ b/JiraPS/Public/Remove-JiraFilter.ps1 @@ -7,6 +7,7 @@ function Remove-JiraFilter { $InputObject, [Parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] + [ValidateNotNullOrEmpty()] [UInt32[]] $Id, diff --git a/JiraPS/Public/Remove-JiraFilterPermission.ps1 b/JiraPS/Public/Remove-JiraFilterPermission.ps1 new file mode 100644 index 00000000..be5affac --- /dev/null +++ b/JiraPS/Public/Remove-JiraFilterPermission.ps1 @@ -0,0 +1,85 @@ +function Remove-JiraFilterPermission { + [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName = 'ByFilterId' )] + param( + [Parameter( Position = 0, Mandatory, ValueFromPipeline, ParameterSetName = 'ByFilterObject' )] + [ValidateNotNullOrEmpty()] + [ValidateScript( + { + if (@($Filter).Count -gt 1) { + $exception = ([System.ArgumentException]"Invalid Parameter") + $errorId = 'ParameterType.TooManyFilters' + $errorCategory = 'InvalidArgument' + $errorTarget = $_ + $errorItem = New-Object -TypeName System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $errorTarget + $errorItem.ErrorDetails = "Only one Filter can be passed at a time." + $PSCmdlet.ThrowTerminatingError($errorItem) + } + elseif (@($_.FilterPermissions).Count -lt 1) { + $exception = ([System.ArgumentException]"Invalid Type for Parameter") + $errorId = 'ParameterType.FilterWithoutPermission' + $errorCategory = 'InvalidArgument' + $errorTarget = $_ + $errorItem = New-Object -TypeName System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $errorTarget + $errorItem.ErrorDetails = "The Filter provided does not contain any Permission to delete." + $PSCmdlet.ThrowTerminatingError($errorItem) + } + else { + return $true + } + } + )] + [PSTypeName('JiraPS.Filter')] + $Filter, + + [Parameter( Position = 0, Mandatory, ParameterSetName = 'ByFilterId' )] + [ValidateNotNullOrEmpty()] + [Alias('Id')] + [UInt32] + $FilterId, + + # TODO: [Parameter( Position = 1, ParameterSetName = 'ByFilterObject')] + [Parameter( Position = 1, Mandatory, ParameterSetName = 'ByFilterId')] + [ValidateNotNullOrEmpty()] + [UInt32[]] + $PermissionId, + + [Parameter()] + [System.Management.Automation.PSCredential] + [System.Management.Automation.Credential()] + $Credential = [System.Management.Automation.PSCredential]::Empty + ) + + begin { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started" + } + + process { + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] ParameterSetName: $($PsCmdlet.ParameterSetName)" + Write-DebugMessage "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)" + + switch ($PSCmdlet.ParameterSetName) { + "ByFilterObject" { + $PermissionId = $Filter.FilterPermissions.Id + } + "ByFilterId" { + $Filter = Get-JiraFilter -Id $FilterId + } + } + + foreach ($_permissionId in $PermissionId) { + $parameter = @{ + URI = "{0}/permission/{1}" -f $Filter.RestURL, $_permissionId + Method = "DELETE" + Credential = $Credential + } + Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter" + if ($PSCmdlet.ShouldProcess($InputObject.Type, "Remove Permission")) { + Invoke-JiraMethod @parameter + } + } + } + + end { + Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete" + } +} diff --git a/Tests/Add-JiraFilterPermission.Tests.ps1 b/Tests/Add-JiraFilterPermission.Tests.ps1 new file mode 100644 index 00000000..d1f947c5 --- /dev/null +++ b/Tests/Add-JiraFilterPermission.Tests.ps1 @@ -0,0 +1,291 @@ +Describe 'Add-JiraFilterPermission' { + BeforeAll { + Remove-Module JiraPS -ErrorAction SilentlyContinue + Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + } + + InModuleScope JiraPS { + + . "$PSScriptRoot/Shared.ps1" + + #region Definitions + $jiraServer = "https://jira.example.com" + + $permissionJSON = @" +[ + { + "id": 10000, + "type": "global" + }, + { + "id": 10010, + "type": "project", + "project": { + "self": "$jiraServer/jira/rest/api/2/project/EX", + "id": "10000", + "key": "EX", + "name": "Example", + "avatarUrls": { + "48x48": "$jiraServer/jira/secure/projectavatar?size=large&pid=10000", + "24x24": "$jiraServer/jira/secure/projectavatar?size=small&pid=10000", + "16x16": "$jiraServer/jira/secure/projectavatar?size=xsmall&pid=10000", + "32x32": "$jiraServer/jira/secure/projectavatar?size=medium&pid=10000" + }, + "projectCategory": { + "self": "$jiraServer/jira/rest/api/2/projectCategory/10000", + "id": "10000", + "name": "FIRST", + "description": "First Project Category" + }, + "simplified": false + } + }, + { + "id": 10010, + "type": "project", + "project": { + "self": "$jiraServer/jira/rest/api/2/project/MKY", + "id": "10002", + "key": "MKY", + "name": "Example", + "avatarUrls": { + "48x48": "$jiraServer/jira/secure/projectavatar?size=large&pid=10002", + "24x24": "$jiraServer/jira/secure/projectavatar?size=small&pid=10002", + "16x16": "$jiraServer/jira/secure/projectavatar?size=xsmall&pid=10002", + "32x32": "$jiraServer/jira/secure/projectavatar?size=medium&pid=10002" + }, + "projectCategory": { + "self": "$jiraServer/jira/rest/api/2/projectCategory/10000", + "id": "10000", + "name": "FIRST", + "description": "First Project Category" + }, + "simplified": false + }, + "role": { + "self": "$jiraServer/jira/rest/api/2/project/MKY/role/10360", + "name": "Developers", + "id": 10360, + "description": "A project role that represents developers in a project", + "actors": [ + { + "id": 10240, + "displayName": "jira-developers", + "type": "atlassian-group-role-actor", + "name": "jira-developers" + }, + { + "id": 10241, + "displayName": "Fred F. User", + "type": "atlassian-user-role-actor", + "name": "fred" + } + ] + } + }, + { + "id": 10010, + "type": "group", + "group": { + "name": "jira-administrators", + "self": "$jiraServer/jira/rest/api/2/group?groupname=jira-administrators" + } + } +] +"@ + #endregion Definitions + + #region Mocks + Mock Get-JiraConfigServer -ModuleName JiraPS { + $jiraServer + } + + Mock ConvertTo-JiraFilter -ModuleName JiraPS { + $i = New-Object -TypeName PSCustomObject + $i.PSObject.TypeNames.Insert(0, 'JiraPS.Filter') + $i + } + + Mock ConvertTo-JiraFilterPermission -ModuleName JiraPS { + $i = (ConvertFrom-Json $permissionJSON) + $i.PSObject.TypeNames.Insert(0, 'JiraPS.FilterPermission') + $i + } + + Mock Get-JiraFilter -ModuleName JiraPS { + foreach ($_id in $Id) { + $object = New-Object -TypeName PSCustomObject -Property @{ + id = $_id + RestUrl = "$jiraServer/rest/api/latest/filter/$_id" + } + $object.PSObject.TypeNames.Insert(0, 'JiraPS.Filter') + $object + } + } + + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter {$Method -eq 'Post' -and $URI -like "$jiraServer/rest/api/*/filter/*/permission"} { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri', 'Body' + ConvertFrom-Json $permissionJSON + } + + Mock Invoke-JiraMethod -ModuleName JiraPS { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + throw "Unidentified call to Invoke-JiraMethod" + } + #endregion Mocks + + Context "Sanity checking" { + $command = Get-Command -Name Add-JiraFilterPermission + + defParam $command 'Filter' + defParam $command 'Id' + defParam $command 'Type' + defParam $command 'Value' + defParam $command 'Credential' + } + + Context "Behavior testing" { + It "Adds share permission to Filter Object" { + { + Add-JiraFilterPermission -Filter (Get-JiraFilter -Id 12844) -Type "Global" + } | Should Not Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' + } + + Assert-MockCalled -CommandName ConvertTo-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + } + + It "Adds share permission to FilterId" { + { + Add-JiraFilterPermission -Id 12844 -Type "Global" + } | Should Not Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' + } + + Assert-MockCalled -CommandName ConvertTo-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + } + } + + Context "Input testing" { + It "requires -Filter to be a JiraPS.Filter" { + { Add-JiraFilterPermission -Filter 1 -Type "Global" } | Should -Throw + { Add-JiraFilterPermission -Filter "lorem" -Type "Global" } | Should -Throw + { Add-JiraFilterPermission -Filter (Get-Date) -Type "Global" } | Should -Throw + + { Add-JiraFilterPermission -Filter (Get-JiraFilter -Id 1) -Type "Global" } | Should -Not -Throw + } + + It "allows a JiraPS.Filter to be passed over the pipeline" { + { Get-JiraFilter -Id 1 | Add-JiraFilterPermission -Type "Global" } | Should -Not -Throw + } + + It "can process multiple Filters" { + $filters = 1..5 | ForEach-Object { Get-JiraFilter -Id 1 } + $filters.Count | Should -Be 5 + + { Add-JiraFilterPermission -Filter $filters -Type "Global" } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 5 -Scope It + } + + It "can find a filter by it's Id" { + { Add-JiraFilterPermission -Id 1 -Type "Global" } | Should -Not -Throw + + Assert-MockCalled -CommandName Get-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + } + + It "allows for the filter's Id to be passed over the pipeline" { + { 1,2 | Add-JiraFilterPermission -Type "Global" } | Should -Not -Throw + + Assert-MockCalled -CommandName Get-JiraFilter -ModuleName JiraPS -Exactly -Times 2 -Scope It + } + + It "can process mutiple FilterIds" { + { Add-JiraFilterPermission -Id 1,2,3,4,5 -Type "Global" } | Should -Not -Throw + + Assert-MockCalled -CommandName Get-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 5 -Scope It + } + + It "accepts the 5 known permission types" { + { Add-JiraFilterPermission -Id 1 -Type "lorem" } | Should -Throw + { Add-JiraFilterPermission -Id 1 -Type "Invalid" } | Should -Throw + + { Add-JiraFilterPermission -Id 1 -Type "Global" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "Group" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "Project" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "ProjectRole" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "Authenticated" } | Should -Not -Throw + } + + It "does not validate -Value" { + { Add-JiraFilterPermission -Id 1 -Type "Global" -Value "invalid" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "Group" -Value "not a group" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "Project" -Value "not a project" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "ProjectRole" -Value "not a Role" } | Should -Not -Throw + { Add-JiraFilterPermission -Id 1 -Type "Authenticated" -Value "invalid" } | Should -Not -Throw + } + + It "constructs a valid request Body for type 'Global'" { + { Add-JiraFilterPermission -Id 12844 -Type "Global" } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' -and + $Body -match '"type":\s*"global"' -and + $Body -notmatch ',' + } + } + + It "constructs a valid request Body for type 'Authenticated'" { + { Add-JiraFilterPermission -Id 12844 -Type "Authenticated" } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' -and + $Body -match '"type":\s*"authenticated"' -and + $Body -notmatch "," + } + } + + It "constructs a valid request Body for type 'Group'" { + { Add-JiraFilterPermission -Id 12844 -Type "Group" -Value "administrators" } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' -and + $Body -match '"type":\s*"group"' -and + $Body -match '"groupname":\s*"administrators"' + } + } + + It "constructs a valid request Body for type 'Project'" { + { Add-JiraFilterPermission -Id 12844 -Type "Project" -Value "11822" } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' -and + $Body -match '"type":\s*"project"' -and + $Body -match '"projectId":\s*"11822"' + } + } + + It "constructs a valid request Body for type 'ProjectRole'" { + { Add-JiraFilterPermission -Id 12844 -Type "ProjectRole" -Value "11822" } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Post' -and + $URI -like '*/rest/api/*/filter/12844/permission' -and + $Body -match '"type":\s*"projectRole"' -and + $Body -match '"projectRoleId":\s*"11822"' + } + } + } + } +} diff --git a/Tests/ConvertTo-JiraFilter.Tests.ps1 b/Tests/ConvertTo-JiraFilter.Tests.ps1 index c53fc172..0aa7e6a4 100644 --- a/Tests/ConvertTo-JiraFilter.Tests.ps1 +++ b/Tests/ConvertTo-JiraFilter.Tests.ps1 @@ -52,8 +52,97 @@ Describe "ConvertTo-JiraFilter" { } '@ + $samplePermission = @" +[ + { + "id": 10000, + "type": "global" + }, + { + "id": 10010, + "type": "project", + "project": { + "self": "$jiraServer/jira/rest/api/2/project/EX", + "id": "10000", + "key": "EX", + "name": "Example", + "avatarUrls": { + "48x48": "$jiraServer/jira/secure/projectavatar?size=large&pid=10000", + "24x24": "$jiraServer/jira/secure/projectavatar?size=small&pid=10000", + "16x16": "$jiraServer/jira/secure/projectavatar?size=xsmall&pid=10000", + "32x32": "$jiraServer/jira/secure/projectavatar?size=medium&pid=10000" + }, + "projectCategory": { + "self": "$jiraServer/jira/rest/api/2/projectCategory/10000", + "id": "10000", + "name": "FIRST", + "description": "First Project Category" + }, + "simplified": false + } + }, + { + "id": 10010, + "type": "project", + "project": { + "self": "$jiraServer/jira/rest/api/2/project/MKY", + "id": "10002", + "key": "MKY", + "name": "Example", + "avatarUrls": { + "48x48": "$jiraServer/jira/secure/projectavatar?size=large&pid=10002", + "24x24": "$jiraServer/jira/secure/projectavatar?size=small&pid=10002", + "16x16": "$jiraServer/jira/secure/projectavatar?size=xsmall&pid=10002", + "32x32": "$jiraServer/jira/secure/projectavatar?size=medium&pid=10002" + }, + "projectCategory": { + "self": "$jiraServer/jira/rest/api/2/projectCategory/10000", + "id": "10000", + "name": "FIRST", + "description": "First Project Category" + }, + "simplified": false + }, + "role": { + "self": "$jiraServer/jira/rest/api/2/project/MKY/role/10360", + "name": "Developers", + "id": 10360, + "description": "A project role that represents developers in a project", + "actors": [ + { + "id": 10240, + "displayName": "jira-developers", + "type": "atlassian-group-role-actor", + "name": "jira-developers" + }, + { + "id": 10241, + "displayName": "Fred F. User", + "type": "atlassian-user-role-actor", + "name": "fred" + } + ] + } + }, + { + "id": 10010, + "type": "group", + "group": { + "name": "jira-administrators", + "self": "$jiraServer/jira/rest/api/2/group?groupname=jira-administrators" + } + } +] +"@ + + Mock ConvertTo-JiraFilterPermission -ModuleName JiraPS { + $i = New-Object -TypeName PSCustomObject -Property @{ Id = 1111 } + $i.PSObject.TypeNames.Insert(0, 'JiraPS.FilterPermission') + $i + } + $sampleObject = ConvertFrom-Json -InputObject $sampleJson - $r = ConvertTo-JiraFilter -InputObject $sampleObject + $r = ConvertTo-JiraFilter -InputObject $sampleObject -FilterPermission $samplePermission It "Creates a PSObject out of JSON input" { $r | Should Not BeNullOrEmpty @@ -67,7 +156,17 @@ Describe "ConvertTo-JiraFilter" { defProp $r 'RestUrl' 'https://jira.atlassian.com/rest/api/latest/filter/12844' defProp $r 'ViewUrl' 'https://jira.atlassian.com/secure/IssueNavigator.jspa?mode=hide&requestId=12844' defProp $r 'SearchUrl' 'https://jira.atlassian.com/rest/api/latest/search?jql=project+%3D+10240+AND+issuetype+%3D+1+ORDER+BY+key+DESC' - defProp $r 'Favorite' $false + defProp $r 'Favourite' $false + It "Defines the 'Favorite' property as an alias of 'Favourite'" { + ($r | Get-Member -Name Favorite).MemberType | Should -Be "AliasProperty" + } + It "Uses output type of 'JiraPS.FilterPermission' for property 'FilterPermissions'" { + checkType $r.FilterPermissions 'JiraPS.FilterPermission' + } + + It "uses ConvertTo-JiraFilterPermission" { + Assert-MockCalled -CommandName ConvertTo-JiraFilterPermission -Module JiraPS -Exactly -Times 1 -Scope Describe + } } } diff --git a/Tests/ConvertTo-JiraFilterPermission.Tests.ps1 b/Tests/ConvertTo-JiraFilterPermission.Tests.ps1 new file mode 100644 index 00000000..2c4f1475 --- /dev/null +++ b/Tests/ConvertTo-JiraFilterPermission.Tests.ps1 @@ -0,0 +1,117 @@ +Describe "ConvertTo-JiraFilterPermission" { + + Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + + InModuleScope JiraPS { + + . "$PSScriptRoot/Shared.ps1" + + $sampleJson = @" +[ + { + "id": 10000, + "type": "global" + }, + { + "id": 10010, + "type": "project", + "project": { + "self": "$jiraServer/jira/rest/api/2/project/EX", + "id": "10000", + "key": "EX", + "name": "Example", + "avatarUrls": { + "48x48": "$jiraServer/jira/secure/projectavatar?size=large&pid=10000", + "24x24": "$jiraServer/jira/secure/projectavatar?size=small&pid=10000", + "16x16": "$jiraServer/jira/secure/projectavatar?size=xsmall&pid=10000", + "32x32": "$jiraServer/jira/secure/projectavatar?size=medium&pid=10000" + }, + "projectCategory": { + "self": "$jiraServer/jira/rest/api/2/projectCategory/10000", + "id": "10000", + "name": "FIRST", + "description": "First Project Category" + }, + "simplified": false + } + }, + { + "id": 10010, + "type": "project", + "project": { + "self": "$jiraServer/jira/rest/api/2/project/MKY", + "id": "10002", + "key": "MKY", + "name": "Example", + "avatarUrls": { + "48x48": "$jiraServer/jira/secure/projectavatar?size=large&pid=10002", + "24x24": "$jiraServer/jira/secure/projectavatar?size=small&pid=10002", + "16x16": "$jiraServer/jira/secure/projectavatar?size=xsmall&pid=10002", + "32x32": "$jiraServer/jira/secure/projectavatar?size=medium&pid=10002" + }, + "projectCategory": { + "self": "$jiraServer/jira/rest/api/2/projectCategory/10000", + "id": "10000", + "name": "FIRST", + "description": "First Project Category" + }, + "simplified": false + }, + "role": { + "self": "$jiraServer/jira/rest/api/2/project/MKY/role/10360", + "name": "Developers", + "id": 10360, + "description": "A project role that represents developers in a project", + "actors": [ + { + "id": 10240, + "displayName": "jira-developers", + "type": "atlassian-group-role-actor", + "name": "jira-developers" + }, + { + "id": 10241, + "displayName": "Fred F. User", + "type": "atlassian-user-role-actor", + "name": "fred" + } + ] + } + }, + { + "id": 10010, + "type": "group", + "group": { + "name": "jira-administrators", + "self": "$jiraServer/jira/rest/api/2/group?groupname=jira-administrators" + } + } +] +"@ + + $sampleObject = ConvertFrom-Json -InputObject $sampleJson + $r = ConvertTo-JiraFilterPermission -InputObject $sampleObject + + It "Creates a PSObject out of JSON input" { + $r | Should -Not -BeNullOrEmpty + } + + checkPsType $r 'JiraPS.FilterPermission' + + defProp $r 'Id' @(10000, 10010, 10010, 10010) + defProp $r 'Type' @('global', 'project', 'project', 'group') + It "Defines the 'Group' property of type 'JiraPS.Group'" { + checkType $r[3].Group 'JiraPS.Group' + $r.Group.Name | Should -Be 'jira-administrators' + } + It "Defines the 'Project' property of type 'JiraPS.Project'" { + checkType $r[1].Project 'JiraPS.Project' + $r.Project.Name | Should -Be @('Example', 'Example') + } + + It "Defines the 'Role' property of type 'JiraPS.ProjectRole'" { + checkType $r[2].Role 'JiraPS.ProjectRole' + $r.Role.Name | Should -Be 'Developers' + } + } +} diff --git a/Tests/ConvertTo-JiraProjectRole.Tests.ps1 b/Tests/ConvertTo-JiraProjectRole.Tests.ps1 new file mode 100644 index 00000000..acee0c95 --- /dev/null +++ b/Tests/ConvertTo-JiraProjectRole.Tests.ps1 @@ -0,0 +1,49 @@ +Describe "ConvertTo-JiraProjectRole" { + + Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + + InModuleScope JiraPS { + + . "$PSScriptRoot/Shared.ps1" + + $sampleJson = @" +[ + { + "self": "http://www.example.com/jira/rest/api/2/project/MKY/role/10360", + "name": "Developers", + "id": 10360, + "description": "A project role that represents developers in a project", + "actors": [ + { + "id": 10240, + "displayName": "jira-developers", + "type": "atlassian-group-role-actor", + "name": "jira-developers" + }, + { + "id": 10241, + "displayName": "Fred F. User", + "type": "atlassian-user-role-actor", + "name": "fred" + } + ] + } +] +"@ + + $sampleObject = ConvertFrom-Json -InputObject $sampleJson + $r = ConvertTo-JiraProjectRole -InputObject $sampleObject + + It "Creates a PSObject out of JSON input" { + $r | Should -Not -BeNullOrEmpty + } + + checkPsType $r 'JiraPS.ProjectRole' + + defProp $r 'Id' 10360 + defProp $r 'Name' "Developers" + defProp $r 'Description' "A project role that represents developers in a project" + hasProp $r 'Actors' + defProp $r 'RestUrl' "http://www.example.com/jira/rest/api/2/project/MKY/role/10360" + } +} diff --git a/Tests/Get-JiraFilterPermission.Tests.ps1 b/Tests/Get-JiraFilterPermission.Tests.ps1 new file mode 100644 index 00000000..71ff2533 --- /dev/null +++ b/Tests/Get-JiraFilterPermission.Tests.ps1 @@ -0,0 +1,125 @@ +Describe 'Get-JiraFilterPermission' { + BeforeAll { + Remove-Module JiraPS -ErrorAction SilentlyContinue + Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + } + + InModuleScope JiraPS { + + . "$PSScriptRoot/Shared.ps1" + + #region Definitions + $jiraServer = "https://jira.example.com" + + $sampleResponse = @" +{ + "id": 10000, + "type": "global" +} +"@ + #endregion Definitions + + #region Mocks + Mock Get-JiraConfigServer -ModuleName JiraPS { + $jiraServer + } + + Mock ConvertTo-JiraFilter -ModuleName JiraPS { } + + Mock Get-JiraFilter -ModuleName JiraPS { + foreach ($_id in $Id) { + $basicFilter = New-Object -TypeName PSCustomObject -Property @{ + Id = $Id + RestUrl = "$jiraServer/rest/api/2/filter/$Id" + } + $basicFilter.PSObject.TypeNames.Insert(0, 'JiraPS.Filter') + $basicFilter + } + } + + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter {$Method -eq 'Get' -and $URI -like "$jiraServer/rest/api/*/filter/*/permission"} { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + ConvertFrom-Json $sampleResponse + } + + Mock Invoke-JiraMethod -ModuleName JiraPS { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + throw "Unidentified call to Invoke-JiraMethod" + } + #endregion Mocks + + Context "Sanity checking" { + $command = Get-Command -Name Get-JiraFilterPermission + + defParam $command 'Filter' + defParam $command 'Id' + defParam $command 'Credential' + } + + Context "Behavior testing" { + It "Retrieves the permissions of a Filter by Object" { + { Get-JiraFilter -Id 23456 | Get-JiraFilterPermission } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Get' -and + $URI -like '*/rest/api/*/filter/23456/permission' + } + } + + It "Retrieves the permissions of a Filter by Id" { + { 23456 | Get-JiraFilterPermission } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Get' -and + $URI -like '*/rest/api/*/filter/23456/permission' + } + } + } + + Context "Input testing" { + It "finds the filter by Id" { + { Get-JiraFilterPermission -Id 23456 } | Should -Not -Throw + + Assert-MockCalled -CommandName Get-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + } + + It "does not accept negative Ids" { + { Get-JiraFilterPermission -Id -1 } | Should -Throw + } + + It "can process multiple Ids" { + { Get-JiraFilterPermission -Id 23456, 23456 } | Should -Not -Throw + + Assert-MockCalled -CommandName Get-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 2 -Scope It + } + + It "allows for the filter to be passed over the pipeline" { + { Get-JiraFilter -Id 23456 | Get-JiraFilterPermission } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It + } + + It "can ony process one Filter objects" { + $filter = @() + $filter += Get-JiraFilter -Id 23456 + $filter += Get-JiraFilter -Id 23456 + + { Get-JiraFilterPermission -Filter $filter } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 2 -Scope It + } + + It "resolves positional parameters" { + { Get-JiraFilterPermission 23456 } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It + + $filter = Get-JiraFilter -Id 23456 + { Get-JiraFilterPermission $filter } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 2 -Scope It + } + } + } +} diff --git a/Tests/JiraPS.Help.Tests.ps1 b/Tests/JiraPS.Help.Tests.ps1 index 46bf7d6d..08cc814e 100644 --- a/Tests/JiraPS.Help.Tests.ps1 +++ b/Tests/JiraPS.Help.Tests.ps1 @@ -1,205 +1,260 @@ -<# - .NOTES - =========================================================================== - Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.119 - Created on: 4/12/2016 1:11 PM - Created by: June Blender - Organization: SAPIEN Technologies, Inc - Filename: *.Help.Tests.ps1 - =========================================================================== - .DESCRIPTION - To test help for the commands in a module, place this file in the module folder. - To test any module from any path, use https://github.com/juneb/PesterTDD/Module.Help.Tests.ps1 -#> - -<# -.SYNOPSIS -Gets command parameters; one per name. Prefers default parameter set. - -.DESCRIPTION -Gets one CommandParameterInfo object for each parameter in the specified -command. If a command has more than one parameter with the same name, this -function gets the parameters in the default parameter set, if one is specified. - -For example, if a command has two parameter sets: - Name, ID (default) - Name, Path -This function returns: - Name (default), ID Path - -This function is used to get parameters for help and for help testing. - -.PARAMETER Command -Enter a CommandInfo object, such as the object that Get-Command returns. You -can also pipe a CommandInfo object to the function. - -This parameter takes a CommandInfo object, instead of a command name, so -you can use the parameters of Get-Command to specify the module and version -of the command. - -.EXAMPLE -PS C:\> Get-ParametersDefaultFirst -Command (Get-Command New-Guid) -This command uses the Command parameter to specify the command to -Get-ParametersDefaultFirst - -.EXAMPLE -PS C:\> Get-Command New-Guid | Get-ParametersDefaultFirst -You can also pipe a CommandInfo object to Get-ParametersDefaultFirst - -.EXAMPLE -PS C:\> Get-ParametersDefaultFirst -Command (Get-Command BetterCredentials\Get-Credential) -You can use the Command parameter to specify the CommandInfo object. This -command runs Get-Command module-qualified name value. - -.EXAMPLE -PS C:\> $ModuleSpec = @{ModuleName='BetterCredentials';RequiredVersion=4.3} -PS C:\> Get-Command -FullyQualifiedName $ModuleSpec | Get-ParametersDefaultFirst -This command uses a Microsoft.PowerShell.Commands.ModuleSpecification object to -specify the module and version. You can also use it to specify the module GUID. -Then, it pipes the CommandInfo object to Get-ParametersDefaultFirst. -#> -function Get-ParametersDefaultFirst { - param - ( - [Parameter(Mandatory = $true, - ValueFromPipeline = $true)] - [System.Management.Automation.CommandInfo] - $Command - ) +#requires -modules BuildHelpers +#requires -modules Pester - BEGIN { - $Common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable' - $parameters = @() - } - PROCESS { - if ($defaultPSetName = $Command.DefaultParameterSet) { - $defaultParameters = ($Command.ParameterSets | Where-Object Name -eq $defaultPSetName).parameters | Where-Object Name -NotIn $common - $otherParameters = ($Command.ParameterSets | Where-Object Name -ne $defaultPSetName).parameters | Where-Object Name -NotIn $common - - $parameters += $defaultParameters - if ($parameters -and $otherParameters) { - $otherParameters | ForEach-Object { - if ($_.Name -notin $parameters.Name) { - $parameters += $_ - } - } - $parameters = $parameters | Sort-Object Name - } +Describe "Help tests" -Tag Documentation { + + BeforeAll { + Import-Module BuildHelpers + Remove-Item -Path Env:\BH* + + $projectRoot = (Resolve-Path "$PSScriptRoot/..").Path + if ($projectRoot -like "*Release") { + $projectRoot = (Resolve-Path "$projectRoot/..").Path } - else { - $parameters = $Command.ParameterSets.Parameters | Where-Object Name -NotIn $common | Sort-Object Name -Unique + Set-BuildEnvironment -BuildOutput '$ProjectPath/Release' -Path $projectRoot -ErrorAction SilentlyContinue + $env:BHManifestToTest = $env:BHPSModuleManifest + $isBuild = $PSScriptRoot -like "$env:BHBuildOutput*" + if ($isBuild) { + $Pattern = [regex]::Escape($env:BHProjectPath) + + $env:BHBuildModuleManifest = $env:BHPSModuleManifest -replace $Pattern, $env:BHBuildOutput + $env:BHManifestToTest = $env:BHBuildModuleManifest } - return $parameters + Remove-Module $env:BHProjectName -ErrorAction SilentlyContinue + Import-Module $env:BHManifestToTest + } + AfterAll { + Remove-Module $env:BHProjectName -ErrorAction SilentlyContinue + Remove-Module BuildHelpers -ErrorAction SilentlyContinue + Remove-Item -Path Env:\BH* } - END { } -} -$ModuleBase = "$PSScriptRoot\..\JiraPS" + $DefaultParams = @( + 'Verbose' + 'Debug' + 'ErrorAction' + 'WarningAction' + 'InformationAction' + 'ErrorVariable' + 'WarningVariable' + 'InformationVariable' + 'OutVariable' + 'OutBuffer' + 'PipelineVariable' + 'WhatIf' + 'Confirm' + ) -# Handles modules in version directories -$leaf = Split-Path $ModuleBase -Leaf -$parent = Split-Path $ModuleBase -Parent -$parsedVersion = $null -if ([System.Version]::TryParse($leaf, [ref]$parsedVersion)) { - $ModuleName = Split-Path $parent -Leaf -} -else { - $ModuleName = $leaf -} + $module = Get-Module $env:BHProjectName + $commands = Get-Command -Module $module -CommandType Cmdlet, Function, Workflow # Not alias + $classes = Get-ChildItem "$env:BHProjectPath/docs/en-US/classes/*" -ErrorAction SilentlyContinue + $enums = Get-ChildItem "$env:BHProjectPath/docs/en-US/enumerations/*" -ErrorAction SilentlyContinue -# Removes all versions of the module from the session before importing -Get-Module $moduleName | Remove-Module + #region Public Functions + foreach ($command in $commands) { + $commandName = $command.Name -replace $module.Prefix, '' + $markdownFile = Resolve-Path "$env:BHProjectPath/docs/en-US/commands/$commandName.md" -$Module = Import-Module $ModuleBase\$ModuleName.psd1 -PassThru -ErrorAction Stop -$commands = Get-Command -Module $module -CommandType Cmdlet, Function, Workflow # Not alias + # The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets + $help = Get-Help $command.Name -ErrorAction Stop -## When testing help, remember that help is cached at the beginning of each session. -## To test, restart session. + Context "Function $commandName's Help" { -foreach ($command in $commands) { - $commandName = $command.Name + #region PlatyPS external Help + It "is described in a markdown file" { + $markdownFile | Should -Not -BeNullOrEmpty + Test-Path $markdownFile | Should -Be $true + } - # The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets - $Help = Get-Help $commandName -ErrorAction Stop + It "does not have Comment-Based Help" { + # We use .EXAMPLE, as we test this extensivly and it is never auto-generated + $command.Definition | Should -Not -BeNullOrEmpty + $Pattern = [regex]::Escape(".EXAMPLE") - Describe "Test help for $commandName" -Tag "CommandHelp" { + $command.Definition | Should -Not -Match "^\s*$Pattern" + } - # If help is not found, synopsis in auto-generated help is the syntax diagram - It "should not be auto-generated" { - $Help.Synopsis | Should Not BeLike '*`[``]*' - } + It "has no platyPS template artifacts" { + $markdownFile | Should -Not -BeNullOrEmpty + $markdownFile | Should -Not -FileContentMatch '{{.*}}' + } - # Should be a synopsis for every function - It "gets synopsis for $commandName" { - $Help.Synopsis | Should Not beNullOrEmpty - } + It "has a link to the 'Online Version'" { + [Uri]$onlineLink = ($help.relatedLinks.navigationLink | Where-Object linkText -eq "Online Version:").Uri - # Should be a description for every function - It "gets description for $commandName" { - $Help.Description | Should Not BeNullOrEmpty - } + $onlineLink.Authority | Should -Be "atlassianps.org" + $onlineLink.Scheme | Should -Be "https" + $onlineLink.PathAndQuery | Should -Be "/docs/$env:BHProjectName/commands/$commandName/" + } - # Should be at least one example - It "gets example code from $commandName" { - ($Help.Examples.Example | Select-Object -First 1).Code | Should Not BeNullOrEmpty - } + it "has a valid HelpUri" { + $command.HelpUri | Should -Not -BeNullOrEmpty + $Pattern = [regex]::Escape("https://atlassianps.org/docs/$env:BHProjectName/commands/$commandName") - # Should be at least one example description - It "gets example help from $commandName" { - ($Help.Examples.Example.Remarks | Select-Object -First 1).Text | Should Not BeNullOrEmpty - } + $command.HelpUri | Should -Match $Pattern + } - It "has at least as many examples as ParameterSets" { - ($Help.Examples.Example | Measure-Object).Count | Should Not BeLessThan $command.ParameterSets.Count - } + It "defines the frontmatter for the homepage" { + $markdownFile | Should -Not -BeNullOrEmpty + $markdownFile | Should -FileContentMatch "Module Name: $env:BHProjectName" + $markdownFile | Should -FileContentMatchExactly "layout: documentation" + $markdownFile | Should -FileContentMatch "permalink: /docs/$env:BHProjectName/commands/$commandName/" + } + #endregion PlatyPS external Help + + #region Help Content + It "has a synopsis" { + $help.Synopsis | Should -Not -BeNullOrEmpty + } + + It "has a description" { + $help.Description.Text -join '' | Should -Not -BeNullOrEmpty + } + + It "has examples" { + ($help.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty + } + + It "has desciptions for all examples" { + foreach ($example in ($help.Examples.Example)) { + $example.remarks.Text | Should -Not -BeNullOrEmpty + } + } + + It "has at least as many examples as ParameterSets" { + ($help.Examples.Example | Measure-Object).Count | Should -BeGreaterOrEqual $command.ParameterSets.Count + } + #endregion Help Content + + #region Consistency with Code + # It "does not define parameter position for functions with only one ParameterSet" { + # if ($command.ParameterSets.Count -eq 1) { + # $command.Parameters.Keys | Foreach-Object { + # $command.Parameters[$_].ParameterSets.Values.Position | Should -BeLessThan 0 + # } + # } + # } + + It "has all ParameterSets in the Help" { + # @($command.ParameterSets).Count | Should -Be @($help.Syntax.SyntaxItem).Count + } - Context "Test parameter help for $commandName" { - # Get parameters. When >1 parameter with same name, - # get parameter from the default parameter set, if any. - if ($parameters = Get-ParametersDefaultFirst -Command $command) { - $parameterNames = $parameters.Name - $HelpParameterNames = $Help.Parameters.Parameter.Name | Sort-Object -Unique - - foreach ($parameter in $parameters) { - $parameterName = $parameter.Name - $parameterHelp = $Help.parameters.parameter | Where-Object Name -EQ $parameterName - - # Should be a description for every parameter - if ($parameterName -notmatch 'Confirm|WhatIf') { - It "gets help for parameter: $parameterName : in $commandName" { - $parameterHelp.Description.Text | Should Not BeNullOrEmpty + #region Parameters + foreach ($parameterName in $command.Parameters.Keys) { + $parameterCode = $command.Parameters[$parameterName] + + if ($help.Parameters | Get-Member -Name Parameter) { + $parameterHelp = $help.Parameters.Parameter | Where-Object Name -EQ $parameterName + + if ($parameterName -notin $DefaultParams) { + It "has a description for parameter [-$parameterName] in $commandName" { + $parameterHelp.Description.Text | Should -Not -BeNullOrEmpty } - } - # Required value in Help should match IsMandatory property of parameter - It "help for $parameterName parameter in $commandName has correct Mandatory value" { - $codeMandatory = $parameter.IsMandatory.toString() - $parameterHelp.Required | Should Be $codeMandatory - } + It "has a mandatory flag for parameter [-$parameterName] in $commandName" { + $isMandatory = $parameterCode.ParameterSets.Values.IsMandatory -contains "True" - # Parameter type in Help should match code - It "help for $commandName has correct parameter type for $parameterName" { - $codeType = $parameter.ParameterType.Name - if ($codeType -eq "Object") { - if (($parameter.Attributes) -and ($parameter.Attributes | Get-Member -Name PSTypeName)) { - $codeType = $parameter.Attributes[0].PSTypeName + $parameterHelp.Required | Should -BeLike $isMandatory.ToString() + } + + It "matches the type of the parameter [-$parameterName] in code and help of $commandName" { + $codeType = $parameterCode.ParameterType.Name + if ($codeType -eq "Object") { + if (($parameterCode.Attributes) -and ($parameterCode.Attributes | Get-Member -Name PSTypeName)) { + $codeType = $parameterCode.Attributes[0].PSTypeName + } } + # To avoid calling Trim method on a null object. + $helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() } + if ($helpType -eq "PSCustomObject") { $helpType = "PSObject" } + + $helpType | Should -Be $codeType } - # To avoid calling Trim method on a null object. - $helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() } - if ($helpType -eq "PSCustomObject") { $helpType = "PSObject" } - $helpType | Should be $codeType } } - foreach ($helpParm in $HelpParameterNames) { - # Shouldn't find extra parameters in help. - It "finds help parameter in code: $helpParm" { - $helpParm -in $parameterNames | Should Be $true + It "does not have parameters that are not in the code" { + $parameter = @() + if ($help.Parameters | Get-Member -Name Parameter) { + $parameter = $help.Parameters.Parameter.Name | Sort-Object -Unique } + foreach ($helpParm in $parameter) { + $command.Parameters.Keys | Should -Contain $helpParm + } + } + } + #endregion Parameters + #endregion Consistency with Code + } + } + #endregion Public Functions + + #region Classes + if ($classes) { + foreach ($class in $classes) { + Context "Classes $($class.BaseName) Help" { + + It "is described in a markdown file" { + $class.FullName | Should -Not -BeNullOrEmpty + Test-Path $class.FullName | Should -Be $true + } + + It "has no platyPS template artifacts" { + $class.FullName | Should -Not -BeNullOrEmpty + $class.FullName | Should -Not -FileContentMatch '{{.*}}' + } + + It "defines the frontmatter for the homepage" { + $class.FullName | Should -Not -BeNullOrEmpty + $class.FullName | Should -FileContentMatch "Module Name: $env:BHProjectName" + $class.FullName | Should -FileContentMatchExactly "layout: documentation" + $class.FullName | Should -FileContentMatch "permalink: /docs/$env:BHProjectName/classes/$commandName/" + } + } + } + + Context "Missing classes" { + It "has a documentation file for every class" { + foreach ($class in ([AtlassianPS.ServerData].Assembly.GetTypes() | Where-Object IsClass)) { + $classes.BaseName | Should -Contain $class.FullName + } + } + } + } + #endregion Classes + + #region Enumerations + if ($enums) { + foreach ($enum in $enums) { + Context "Enumeration $($enum.BaseName) Help" { + + It "is described in a markdown file" { + $enum.FullName | Should -Not -BeNullOrEmpty + Test-Path $enum.FullName | Should -Be $true + } + + It "has no platyPS template artifacts" { + $enum.FullName | Should -Not -BeNullOrEmpty + $enum.FullName | Should -Not -FileContentMatch '{{.*}}' + } + + It "defines the frontmatter for the homepage" { + $enum.FullName | Should -Not -BeNullOrEmpty + $enum.FullName | Should -FileContentMatch "Module Name: $env:BHProjectName" + $enum.FullName | Should -FileContentMatchExactly "layout: documentation" + $enum.FullName | Should -FileContentMatch "permalink: /docs/$env:BHProjectName/enumerations/$commandName/" + } + } + } + + Context "Missing classes" { + It "has a documentation file for every class" { + foreach ($enum in ([AtlassianPS.ServerData].Assembly.GetTypes() | Where-Object IsEnum)) { + $enums.BaseName | Should -Contain $enum.FullName } } } } + #endregion Enumerations } diff --git a/Tests/Remove-JiraFilterPermission.Tests.ps1 b/Tests/Remove-JiraFilterPermission.Tests.ps1 new file mode 100644 index 00000000..8d34ed47 --- /dev/null +++ b/Tests/Remove-JiraFilterPermission.Tests.ps1 @@ -0,0 +1,151 @@ +Describe 'Remove-JiraFilterPermission' { + BeforeAll { + Remove-Module JiraPS -ErrorAction SilentlyContinue + Import-Module "$PSScriptRoot/../JiraPS" -Force -ErrorAction Stop + } + + InModuleScope JiraPS { + + . "$PSScriptRoot/Shared.ps1" + + #region Definitions + $jiraServer = "https://jira.example.com" + + $filterPermission1 = New-Object -TypeName PSCustomObject -Property @{ Id = 1111 } + $filterPermission1.PSObject.TypeNames.Insert(0, 'JiraPS.FilterPermission') + $filterPermission2 = New-Object -TypeName PSCustomObject -Property @{ Id = 2222 } + $filterPermission2.Id = 2222 + $fullFilter = New-Object -TypeName PSCustomObject -Property @{ + Id = 12345 + RestUrl = "$jiraServer/rest/api/2/filter/12345" + FilterPermissions = @( + $filterPermission1 + $filterPermission2 + ) + } + $fullFilter.PSObject.TypeNames.Insert(0, 'JiraPS.Filter') + $basicFilter = New-Object -TypeName PSCustomObject -Property @{ + Id = 23456 + RestUrl = "$jiraServer/rest/api/2/filter/23456" + } + $basicFilter.PSObject.TypeNames.Insert(0, 'JiraPS.Filter') + + #endregion Definitions + + #region Mocks + Mock Get-JiraConfigServer -ModuleName JiraPS { + $jiraServer + } + + Mock Get-JiraFilter -ModuleName JiraPS { + $basicFilter + } + + Mock Get-JiraFilterPermission -ModuleName JiraPS { + $fullFilter + } + + Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter {$Method -eq 'Delete' -and $URI -like "$jiraServer/rest/api/*/filter/*/permission*"} { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + } + + Mock Invoke-JiraMethod -ModuleName JiraPS { + ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri' + throw "Unidentified call to Invoke-JiraMethod" + } + #endregion Mocks + + Context "Sanity checking" { + $command = Get-Command -Name Remove-JiraFilterPermission + + defParam $command 'Filter' + defParam $command 'FilterId' + defParam $command 'PermissionId' + defParam $command 'Credential' + } + + Context "Behavior testing" { + It "Deletes Permission from Filter Object" { + { + Get-JiraFilterPermission -Id 1 | Remove-JiraFilterPermission + } | Should Not Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Delete' -and + $URI -like '*/rest/api/*/filter/12345/permission/1111' + } + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Delete' -and + $URI -like '*/rest/api/*/filter/12345/permission/2222' + } + } + + It "Deletes Permission from FilterId + PermissionId" { + { + Remove-JiraFilterPermission -FilterId 1 -PermissionId 3333, 4444 + } | Should Not Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Delete' -and + $URI -like '*/rest/api/*/filter/23456/permission/3333' + } + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It -ParameterFilter { + $Method -eq 'Delete' -and + $URI -like '*/rest/api/*/filter/23456/permission/4444' + } + } + } + + Context "Input testing" { + It "validates the -Filter to ensure FilterPermissions" { + { Remove-JiraFilterPermission -Filter (Get-JiraFilter -Id 1) } | Should -Throw + { Remove-JiraFilterPermission -Filter (Get-JiraFilterPermission -Id 1) } | Should -Not -Throw + } + + It "finds the filter by FilterId" { + { Remove-JiraFilterPermission -FilterId 1 -PermissionId 1111 } | Should -Not -Throw + + Assert-MockCalled -CommandName Get-JiraFilter -ModuleName JiraPS -Exactly -Times 1 -Scope It + } + + It "does not accept negative FilterIds" { + { Remove-JiraFilterPermission -FilterId -1 -PermissionId 1111 } | Should -Throw + } + + It "does not accept negative PermissionIds" { + { Remove-JiraFilterPermission -FilterId 1 -PermissionId -1111 } | Should -Throw + } + + It "can only process one FilterId" { + { Remove-JiraFilterPermission -FilterId 1, 2 -PermissionId 1111 } | Should -Throw + } + + It "can process multiple PermissionIds" { + { Remove-JiraFilterPermission -FilterId 1 -PermissionId 1111, 2222 } | Should -Not -Throw + } + + It "allows for the filter to be passed over the pipeline" { + { Get-JiraFilterPermission -Id 1 | Remove-JiraFilterPermission } | Should -Not -Throw + } + + It "can ony process one Filter objects" { + $filter = @() + $filter += Get-JiraFilterPermission -Id 1 + $filter += Get-JiraFilterPermission -Id 1 + + { Remove-JiraFilterPermission -Filter $filter } | Should -Throw + } + + It "resolves positional parameters" { + { Remove-JiraFilterPermission 12345 1111 } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 1 -Scope It + + $filter = Get-JiraFilterPermission -Id 1 + { Remove-JiraFilterPermission $filter } | Should -Not -Throw + + Assert-MockCalled -CommandName Invoke-JiraMethod -ModuleName JiraPS -Exactly -Times 3 -Scope It + } + } + } +} diff --git a/Tools/build.requirements.psd1 b/Tools/build.requirements.psd1 index 7c0668f0..48501742 100644 --- a/Tools/build.requirements.psd1 +++ b/Tools/build.requirements.psd1 @@ -14,7 +14,7 @@ Parameters = @{ SkipPublisherCheck = $true } - Version = "4.1.1" + Version = "4.3.1" } platyPS = "latest" PSScriptAnalyzer = @{ diff --git a/docs/en-US/commands/Add-JiraFilterPermission.md b/docs/en-US/commands/Add-JiraFilterPermission.md new file mode 100644 index 00000000..ddfa6661 --- /dev/null +++ b/docs/en-US/commands/Add-JiraFilterPermission.md @@ -0,0 +1,231 @@ +--- +external help file: JiraPS-help.xml +Module Name: JiraPS +online version: https://atlassianps.org/docs/JiraPS/commands/Add-JiraFilterPermission/ +locale: en-US +schema: 2.0.0 +layout: documentation +permalink: /docs/JiraPS/commands/Add-JiraFilterPermission/ +--- +# Add-JiraFilterPermission + +## SYNOPSIS + +Share a Filter with other users. + +## SYNTAX + +### ByInputObject (Default) + +```powershell +Add-JiraFilterPermission [-Filter] [-Type] + [[-Value] ] [[-Credential] ] [-WhatIf] [-Confirm] + [] +``` + +### ById + +```powershell +Add-JiraFilterPermission [-Id] [-Type] [[-Value] ] + [[-Credential] ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +Share a Filter with other users, such as "Group", "Project", "ProjectRole", +"Authenticated" or "Global". + +## EXAMPLES + +### Example 1 + +```powershell +Add-JiraFilterPermission -Filter (Get-JiraFilter 12345) -Type "Global" +#------- +Add-JiraFilterPermission -Id 12345 -Type "Global" +``` + +Two methods of sharing Filter 12345 with everyone. + +### Example 2 + +```powershell +12345 | Add-JiraFilterPermission -Type "Authenticated" +``` + +Share Filter 12345 with authenticated users. + +_The Id could be read from a file._ + +### Example 3 + +```powershell +Get-JiraFilter 12345 | Add-JiraFilterPermission -Type "Group" -Value "administrators" +``` + +Share Filter 12345 only with users in the administrators groups. + +## PARAMETERS + +### -Filter + +Filter object to which the permission should be applied + +```yaml +Type: JiraPS.Filter +Parameter Sets: ByInputObject +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Id + +Id of the Filter to which the permission should be applied + +_Id can be passed over the pipeline when reading from a file._ + +```yaml +Type: UInt32[] +Parameter Sets: ById +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Type + +Type of the permission to add + +```yaml +Type: String +Parameter Sets: (All) +Aliases: +Accepted values: Group, Project, ProjectRole, Authenticated, Global + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Value + +Value for the Type of the permission. + +The Value differs per Type of the permission. + +Here is a table to know what Value to provide: +|Type |Value |Source | +|-------------|---------------------|----------------------------------------------------| +|Group |Name of the Group |Can be retrieved with `(Get-JiraGroup ...).Name` | +|Project |Id of the Project |Can be retrieved with `(Get-JiraProject ...).Id` | +|ProjectRole |Id of the ProjectRole|Can be retrieved with `(Get-JiraProjectRole ...).Id`| +|Authenticated| **must be null** | | +|Global | **must be null** | | + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Credential + +Credentials to use to connect to JIRA. +If not specified, this function will use anonymous access. + +```yaml +Type: PSCredential +Parameter Sets: (All) +Aliases: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, +-ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, +-OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. +For more information, see about_CommonParameters +(). + +## INPUTS + +### [JiraPS.Filter] + +## OUTPUTS + +### [JiraPS.Filter] + +## NOTES + +This functions does not validate the input for `-Value`. +In case the value is invalid, unexpected or missing, the API will response with +an error. + +This function requires either the `-Credential` parameter to be passed or +a persistent JIRA session. +See `New-JiraSession` for more details. +If neither are supplied, this function will run with anonymous access to JIRA. + +## RELATED LINKS + +[Get-JiraFilter](../Get-JiraFilter/) + +[Get-JiraFilterPermission](../Get-JiraFilterPermission/) + +[Remove-JiraFilterPermission](../Remove-JiraFilterPermission/) diff --git a/docs/en-US/commands/Get-JiraFilter.md b/docs/en-US/commands/Get-JiraFilter.md index 7ff88bf8..47d95c19 100644 --- a/docs/en-US/commands/Get-JiraFilter.md +++ b/docs/en-US/commands/Get-JiraFilter.md @@ -24,7 +24,8 @@ Get-JiraFilter [-Id] [-Credential ] [ ### ByInputObject ```powershell -Get-JiraFilter -InputObject [-Credential ] [] +Get-JiraFilter -InputObject [-Credential ] + [] ``` ### MyFavorite @@ -35,13 +36,14 @@ Get-JiraFilter -Favorite [-Credential ] [] ## DESCRIPTION -This function returns information about a filter in JIRA, including the JQL syntax of the filter, its owner, and sharing status. +This function returns information about a filter in JIRA, including the JQL +syntax of the filter, its owner, and sharing status. This function is only capable of returning filters by their Filter ID. This is a limitation of JIRA's REST API. -The easiest way to obtain the ID of a filter is to load the filter in the "regular" Web view of JIRA, -then copy the ID from the URL of the page. +The easiest way to obtain the ID of a filter is to load the filter in the +"regular" Web view of JIRA, then copy the ID from the URL of the page. ## EXAMPLES @@ -139,12 +141,15 @@ Accept wildcard characters: False ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. -For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, +-ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, +-OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. +For more information, see about_CommonParameters +(). ## INPUTS -### [JiraPS.Filter[]] / [String[]] +### [JiraPS.Filter] / [String] The filter to look up in JIRA. This can be a String (filter ID) or a JiraPS.Filter object. @@ -154,7 +159,8 @@ The filter to look up in JIRA. This can be a String (filter ID) or a JiraPS.Filt ## NOTES -This function requires either the `-Credential` parameter to be passed or a persistent JIRA session. +This function requires either the `-Credential` parameter to be passed or +a persistent JIRA session. See `New-JiraSession` for more details. If neither are supplied, this function will run with anonymous access to JIRA. @@ -165,3 +171,9 @@ If neither are supplied, this function will run with anonymous access to JIRA. [Set-JiraFilter](../Set-JiraFilter/) [Remove-JiraFilter](../Remove-JiraFilter/) + +[Add-JiraFilterPermission](../Add-JiraFilterPermission/) + +[Get-JiraFilterPermission](../Get-JiraFilterPermission/) + +[Remove-JiraFilterPermission](../Remove-JiraFilterPermission/) diff --git a/docs/en-US/commands/Get-JiraFilterPermission.md b/docs/en-US/commands/Get-JiraFilterPermission.md new file mode 100644 index 00000000..b9878f71 --- /dev/null +++ b/docs/en-US/commands/Get-JiraFilterPermission.md @@ -0,0 +1,140 @@ +--- +external help file: JiraPS-help.xml +Module Name: JiraPS +online version: https://atlassianps.org/docs/JiraPS/commands/Get-JiraFilterPermission/ +locale: en-US +schema: 2.0.0 +layout: documentation +permalink: /docs/JiraPS/commands/Get-JiraFilterPermission/ +--- +# Get-JiraFilterPermission + +## SYNOPSIS + +Fetch the permissions of a specific Filter. + +## SYNTAX + +### ByInputObject (Default) + +```powershell +Get-JiraFilterPermission [-Filter] [[-Credential] ] + [] +``` + +### ById + +```powershell +Get-JiraFilterPermission [-Id] [[-Credential] ] + [] +``` + +## DESCRIPTION + +This allows the user to retrieve all the sharing permissions set for a Filter. + +## EXAMPLES + +### Example 1 + +```powershell +Get-JiraFilterPermission -Filter (Get-JiraFilter 12345) +#------- +Get-JiraFilterPermission -Id 12345 +``` + +Two methods for retrieving the permissions set for Filter 12345. + +### Example 2 + +```powershell +12345 | Get-JiraFilterPermission +#------- +Get-JiraFilter 12345 | Add-JiraFilterPermission +``` + +Two methods for retrieve the permissions set for Filter 12345 by using the pipeline. + +_The Id could be read from a file._ + +## PARAMETERS + +### -Filter + +Filter object from which to retrieve the permissions + +```yaml +Type: JiraPS.Filter +Parameter Sets: ByInputObject +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Id + +Id of the Filter from which to retrieve the permissions + +```yaml +Type: UInt32[] +Parameter Sets: ById +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Credential + +Credentials to use to connect to JIRA. +If not specified, this function will use anonymous access. + +```yaml +Type: PSCredential +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, +-ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, +-OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. +For more information, see about_CommonParameters +(). + +## INPUTS + +### [JiraPS.Filter] + +## OUTPUTS + +### [JiraPS.Filter] + +## NOTES + +This function requires either the `-Credential` parameter to be passed or +a persistent JIRA session. +See `New-JiraSession` for more details. +If neither are supplied, this function will run with anonymous access to JIRA. + +## RELATED LINKS + +[Get-JiraFilter](../Get-JiraFilter/) + +[Add-JiraFilterPermission](../Add-JiraFilterPermission/) + +[Remove-JiraFilterPermission](../Remove-JiraFilterPermission/) diff --git a/docs/en-US/commands/Remove-JiraFilter.md b/docs/en-US/commands/Remove-JiraFilter.md index b5fbc5a2..66dd3b5c 100644 --- a/docs/en-US/commands/Remove-JiraFilter.md +++ b/docs/en-US/commands/Remove-JiraFilter.md @@ -18,7 +18,8 @@ Removes an existing filter. ### byInputObject (Default) ```powershell -Remove-JiraFilter [-InputObject] [-WhatIf] [-Confirm] [] +Remove-JiraFilter [-InputObject] [-WhatIf] [-Confirm] + [] ``` ### byId (Default) @@ -76,8 +77,8 @@ $listOfFilters | Remove-JiraFilter Remove filters with id "1", "2", "3" and "4". -This input allows for the ID of the filters to be stored in an array and passed to -the command. (eg: `Get-Content` from a file with the ids) +This input allows for the ID of the filters to be stored in an array and passed +to the command. (eg: `Get-Content` from a file with the ids) ## PARAMETERS @@ -169,8 +170,11 @@ Accept wildcard characters: False ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. -For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, +-ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, +-OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. +For more information, see about_CommonParameters +(). ## INPUTS @@ -180,7 +184,8 @@ For more information, see about_CommonParameters (http://go.microsoft.com/fwlink ## NOTES -This function requires either the `-Credential` parameter to be passed or a persistent JIRA session. +This function requires either the `-Credential` parameter to be passed or +a persistent JIRA session. See `New-JiraSession` for more details. If neither are supplied, this function will run with anonymous access to JIRA. diff --git a/docs/en-US/commands/Remove-JiraFilterPermission.md b/docs/en-US/commands/Remove-JiraFilterPermission.md new file mode 100644 index 00000000..f60384b7 --- /dev/null +++ b/docs/en-US/commands/Remove-JiraFilterPermission.md @@ -0,0 +1,183 @@ +--- +external help file: JiraPS-help.xml +Module Name: JiraPS +online version: https://atlassianps.org/docs/JiraPS/commands/Remove-JiraFilterPermission/ +locale: en-US +schema: 2.0.0 +layout: documentation +permalink: /docs/JiraPS/commands/Remove-JiraFilterPermission/ +--- +# Remove-JiraFilterPermission + +## SYNOPSIS + +Remove a permission of a Filter + +## SYNTAX + +### ByFilterId (Default) + +```powershell +Remove-JiraFilterPermission [-Filter] [[-Credential] ] + [-WhatIf] [-Confirm] [] +``` + +### ByFilterObject + +```powershell +Remove-JiraFilterPermission [-FilterId] [-PermissionId] + [[-Credential] ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +Remove a sharing permission of a Filter. + +## EXAMPLES + +### Example 1 + +```powershell +Remove-JiraFilterPermission -FilterId 11822 -PermissionId 1111, 2222 +``` + +Remove two share permissions of Filter with ID '11822' + +### Example 1 + +```powershell +Get-JiraFilter 11822 | Get-JiraFilterPermission | Remove-JiraFilterPermission +``` + +Remove all permissions of Filter 11822 + +## PARAMETERS + +### -Filter + +Object of the Filter from which to remove a permission. + +```yaml +Type: JiraPS.Filter +Parameter Sets: ByFilterObject +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -FilterId + +Id of the Filter from which to remove a permission. + +```yaml +Type: UInt32 +Parameter Sets: ByFilterId +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -PermissionId + +List of id's of the permissions to remove. + +```yaml +Type: UInt32[] +Parameter Sets: ByFilterId +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Credential + +Credentials to use to connect to JIRA. +If not specified, this function will use anonymous access. + +```yaml +Type: PSCredential +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. +The cmdlet is not run. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, +-ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, +-OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. +For more information, see about_CommonParameters +(). + +## INPUTS + +### System.Object + +## OUTPUTS + +### System.Object + +## NOTES + +This function requires either the `-Credential` parameter to be passed or +a persistent JIRA session. +See `New-JiraSession` for more details. +If neither are supplied, this function will run with anonymous access to JIRA. + +## RELATED LINKS + +[Get-JiraFilter](../Get-JiraFilter/) + +[Add-JiraFilterPermission](../Add-JiraFilterPermission/) + +[Get-JiraFilterPermission](../Get-JiraFilterPermission/)