Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download of Attachments #323

Merged
merged 4 commits into from
Dec 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions JiraPS/Public/Get-JiraIssueAttachment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,6 @@ function Get-JiraIssueAttachment {

ConvertTo-JiraAttachment -InputObject $attachments
}
else {
$errorMessage = @{
Category = "ObjectNotFound"
CategoryActivity = "Searching for resource"
Message = "This issue does not have any attachments"
}
Write-Error @errorMessage
}
}

end {
Expand Down
68 changes: 68 additions & 0 deletions JiraPS/Public/Get-JiraIssueAttachmentFile.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
function Get-JiraIssueAttachmentFile {
# .ExternalHelp ..\JiraPS-help.xml
[CmdletBinding()]
[OutputType([Bool])]
param (
[Parameter( Mandatory, ValueFromPipeline )]
[PSTypeName('JiraPS.Attachment')]
$Attachment,

[ValidateScript(
{
if (-not (Test-Path $_)) {
$errorItem = [System.Management.Automation.ErrorRecord]::new(
([System.ArgumentException]"Path not found"),
'ParameterValue.FileNotFound',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$_
)
$errorItem.ErrorDetails = "Invalid path '$_'."
$PSCmdlet.ThrowTerminatingError($errorItem)
}
else {
return $true
}
}
)]
[String]
$Path,

[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)"

foreach ($_Attachment in $Attachment) {
if ($Path) {
$filename = Join-Path $Path $_Attachment.Filename
}
else {
$filename = $_Attachment.Filename
}

$iwParameters = @{
Uri = $_Attachment.Content
Method = 'Get'
Headers = @{"Accept" = $_Attachment.MediaType}
OutFile = $filename
Credential = $Credential
}

$result = Invoke-JiraMethod @iwParameters
(-not $result)
}
}

end {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function ended"
}
}
154 changes: 154 additions & 0 deletions Tests/Functions/Get-JiraIssueAttachmentFile.Unit.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#requires -modules BuildHelpers
#requires -modules @{ ModuleName = "Pester"; ModuleVersion = "4.4.0" }

Describe "Get-JiraIssueAttachmentFile" -Tag 'Unit' {

BeforeAll {
Remove-Item -Path Env:\BH*
$projectRoot = (Resolve-Path "$PSScriptRoot/../..").Path
if ($projectRoot -like "*Release") {
$projectRoot = (Resolve-Path "$projectRoot/..").Path
}

Import-Module BuildHelpers
Set-BuildEnvironment -BuildOutput '$ProjectPath/Release' -Path $projectRoot -ErrorAction SilentlyContinue

$env:BHManifestToTest = $env:BHPSModuleManifest
$script:isBuild = $PSScriptRoot -like "$env:BHBuildOutput*"
if ($script:isBuild) {
$Pattern = [regex]::Escape($env:BHProjectPath)

$env:BHBuildModuleManifest = $env:BHPSModuleManifest -replace $Pattern, $env:BHBuildOutput
$env:BHManifestToTest = $env:BHBuildModuleManifest
}

Import-Module "$env:BHProjectPath/Tools/BuildTools.psm1"

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*
}

InModuleScope JiraPS {

. "$PSScriptRoot/../Shared.ps1"

$jiraServer = 'http://jiraserver.example.com'
$issueID = 41701
$issueKey = 'IT-3676'

$attachments = @"
[
{
"self": "$jiraServer/rest/api/2/attachment/10013",
"id": "10013",
"filename": "foo.pdf",
"author": {
"self": "$jiraServer/rest/api/2/user?username=admin",
"name": "admin",
"key": "admin",
"accountId": "000000:000000-0000-0000-0000-ab899c878d00",
"emailAddress": "admin@example.com",
"avatarUrls": { },
"displayName": "Admin",
"active": true,
"timeZone": "Europe/Berlin"
},
"created": "2017-10-16T10:06:29.399+0200",
"size": 60444,
"mimeType": "application/pdf",
"content": "$jiraServer/secure/attachment/10013/foo.pdf"
},
{
"self": "$jiraServer/rest/api/2/attachment/10010",
"id": "10010",
"filename": "bar.pdf",
"author": {
"self": "$jiraServer/rest/api/2/user?username=admin",
"name": "admin",
"key": "admin",
"accountId": "000000:000000-0000-0000-0000-ab899c878d00",
"emailAddress": "admin@example.com",
"avatarUrls": { },
"displayName": "Admin",
"active": true,
"timeZone": "Europe/Berlin"
},
"created": "2017-10-16T09:06:48.070+0200",
"size": 438098,
"mimeType": "'application/pdf'",
"content": "$jiraServer/secure/attachment/10010/bar.pdf"
}
]
"@

Mock Get-JiraIssueAttachment -ModuleName JiraPS {
$object = ConvertFrom-Json -InputObject $attachments
$object[0].PSObject.TypeNames.Insert(0, 'JiraPS.Attachment')
$object[1].PSObject.TypeNames.Insert(0, 'JiraPS.Attachment')
$object
}

Mock Invoke-JiraMethod -ModuleName JiraPS -ParameterFilter {
$Method -eq 'Get' -and
$URI -like "$jiraServer/secure/attachment/*"
} {
ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri', 'OutFile'
}

# Generic catch-all. This will throw an exception if we forgot to mock something.
Mock Invoke-JiraMethod -ModuleName JiraPS {
ShowMockInfo 'Invoke-JiraMethod' 'Method', 'Uri'
throw "Unidentified call to Invoke-JiraMethod"
}

#############
# Tests
#############

It 'only accepts JiraPS.Attachment as input' {
{ Get-JiraIssueAttachmentFile -Attachment (Get-Date) } | Should Throw
{ Get-JiraIssueAttachmentFile -Attachment (Get-ChildItem) } | Should Throw
{ Get-JiraIssueAttachmentFile -Attachment @('foo', 'bar') } | Should Throw
{ Get-JiraIssueAttachmentFile -Attachment (Get-JiraIssueAttachment -Issue "Foo") } | Should Not Throw
}

It 'takes the issue input over the pipeline' {
{ Get-JiraIssueAttachment -Issue "Foo" | Get-JiraIssueAttachmentFile } | Should Not Throw
}

It 'uses Invoke-JiraMethod for saving to disk' {
$script:ShowMockData = $true
Get-JiraIssueAttachment -Issue "Foo" | Get-JiraIssueAttachmentFile
Get-JiraIssueAttachment -Issue "Foo" | Get-JiraIssueAttachmentFile -Path "../"

$assertMockCalledSplat = @{
CommandName = 'Invoke-JiraMethod'
ModuleName = "JiraPS"
ParameterFilter = {
$OutFile -in @("foo.pdf", "bar.pdf")
}
Exactly = $true
Times = 2
Scope = 'It'
}
Assert-MockCalled @assertMockCalledSplat

$assertMockCalledSplat = @{
CommandName = 'Invoke-JiraMethod'
ModuleName = "JiraPS"
ParameterFilter = {
$OutFile -like "..*.pdf"
}
Exactly = $true
Times = 2
Scope = 'It'
}
Assert-MockCalled @assertMockCalledSplat
}
}
}
2 changes: 2 additions & 0 deletions docs/en-US/commands/Get-JiraIssueAttachment.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ If neither are supplied, this function will run with anonymous access to JIRA.

## RELATED LINKS

[Get-JiraAttachmentFile](../Get-JiraAttachmentFile/)

[Add-JiraIssueAttachment](../Add-JiraIssueAttachment/)

[Get-JiraIssue](../Get-JiraIssue/)
Expand Down
138 changes: 138 additions & 0 deletions docs/en-US/commands/Get-JiraIssueAttachmentFile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
external help file: JiraPS-help.xml
Module Name: JiraPS
online version: https://atlassianps.org/docs/JiraPS/commands/Get-JiraIssueAttachmentFile/
locale: en-US
schema: 2.0.0
layout: documentation
permalink: /docs/JiraPS/commands/Get-JiraIssueAttachmentFile/
---
# Get-JiraIssueAttachmentFile

## SYNOPSIS

Save an attachment to disk.

## SYNTAX

```powershell
Get-JiraIssueAttachmentFile [-Attachment] <JiraPS.Attachment> [[-Path] <String>]]
[[-Credential] <PSCredential>] [<CommonParameters>]
```

## DESCRIPTION

This function downloads an attachment of an issue to the local disk.

## EXAMPLES

### EXAMPLE 1

```powershell
Get-JiraIssueAttachmentFile (Get-JiraIssueAttachment -Issue TEST-001)
```

This example downloads all attachments from issue TEST-001 to the current
working directory.

### EXAMPLE 2

```powershell
Get-JiraIssue TEST-002 | Get-JiraIssueAttachment | Get-JiraIssueAttachmentFile
```

This example illustrates use of the pipeline to download all attachments from
issue TEST-002.

### EXAMPLE 3

```powershell
Get-JiraIssue TEST-002 |
Get-JiraIssueAttachment -FileName "*.png" |
Get-JiraIssueAttachmentFile -Path "c:\temp
```

Download all attachments of issue TEST-002 where the filename ends in `.png`
to a specific location.

## PARAMETERS

### -Attachment

Attachment which will be downloaded.

```yaml
Type: JiraPS.Attachment
Parameter Sets: (All)
Aliases:

Required: True
Position: 1
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```

### -Path

Path in which to store to attachment.

The name of the file will be appended to the Path provided.

```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
```

### 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).

## INPUTS

### [JiraPS.Attachment]

## OUTPUTS

### [Bool]

## 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-JiraAttachment](../Get-JiraAttachmentFile/)

[Add-JiraIssueAttachmentFile](../Add-JiraIssueAttachmentFile/)

[Get-JiraIssue](../Get-JiraIssue/)

[Remove-JiraIssueAttachmentFile](../Remove-JiraIssueAttachmentFile/)