From 3a87f2bd50a811f554d6cfaf085fede7aede6c76 Mon Sep 17 00:00:00 2001 From: Jess Pomfret Date: Tue, 12 May 2020 18:41:34 +0100 Subject: [PATCH] Adding functionality for Project Cards (#163) Covers: - List project cards - Get a project card - Create a project card - Update a project card - Delete a project card - Move a project card --- GitHubProjectCards.ps1 | 531 +++++++++++++++++++++++++++++ PowerShellForGitHub.psd1 | 12 +- Tests/GitHubProjectCards.tests.ps1 | 233 +++++++++++++ 3 files changed, 773 insertions(+), 3 deletions(-) create mode 100644 GitHubProjectCards.ps1 create mode 100644 Tests/GitHubProjectCards.tests.ps1 diff --git a/GitHubProjectCards.ps1 b/GitHubProjectCards.ps1 new file mode 100644 index 00000000..33395df2 --- /dev/null +++ b/GitHubProjectCards.ps1 @@ -0,0 +1,531 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +function Get-GitHubProjectCard +{ +<# + .DESCRIPTION + Get the cards for a given Github Project Column. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Column + ID of the column to retrieve cards for. + + .PARAMETER ArchivedState + Only cards with this ArchivedState are returned. + Options are all, archived, or NotArchived (default). + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .PARAMETER NoStatus + If this switch is specified, long-running commands will run on the main thread + with no command line status update. When not specified, those commands run in + the background, enabling the command prompt to provide status information. + If not supplied here, the DefaultNoStatus configuration property value will be used. + + .EXAMPLE + Get-GitHubProjectCard -Column 999999 + + Get the the not_archived cards for column 999999. + + .EXAMPLE + Get-GitHubProjectCard -Column 999999 -ArchivedState All + + Gets all the cards for column 999999, no matter the ArchivedState. + + .EXAMPLE + Get-GitHubProjectCard -Column 999999 -ArchivedState Archived + + Gets the archived cards for column 999999. + + .EXAMPLE + Get-GitHubProjectCard -Card 999999 + + Gets the card with ID 999999. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'Column')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification = "Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")] + param( + [Parameter(Mandatory, ParameterSetName = 'Column')] + [int64] $Column, + + [Parameter(Mandatory, ParameterSetName = 'Card')] + [int64] $Card, + + [ValidateSet('All', 'Archived', 'NotArchived')] + [string] $ArchivedState = 'NotArchived', + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = [String]::Empty + $description = [String]::Empty + + if ($PSCmdlet.ParameterSetName -eq 'Column') + { + $telemetryProperties['Column'] = $true + + $uriFragment = "/projects/columns/$Column/cards" + $description = "Getting cards for column $Column" + } + elseif ($PSCmdlet.ParameterSetName -eq 'Card') + { + $telemetryProperties['Card'] = $true + + $uriFragment = "/projects/columns/cards/$Card" + $description = "Getting project card $Card" + } + + if ($PSBoundParameters.ContainsKey('ArchivedState')) + { + $getParams = @() + $Archived = $ArchivedState.ToLower().Replace('notarchived','not_archived') + $getParams += "archived_state=$Archived" + + $uriFragment = "$uriFragment`?" + ($getParams -join '&') + $description += " with ArchivedState '$Archived'" + } + + $params = @{ + 'UriFragment' = $uriFragment + 'Description' = $description + 'AccessToken' = $AccessToken + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + 'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus) + 'AcceptHeader' = 'application/vnd.github.inertia-preview+json' + } + + return Invoke-GHRestMethodMultipleResult @params +} + +function New-GitHubProjectCard +{ +<# + .DESCRIPTION + Creates a new card for a Github project. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Column + ID of the column to create a card for. + + .PARAMETER Note + The name of the column to create. + + .PARAMETER ContentId + The issue or pull request ID you want to associate with this card. + + .PARAMETER ContentType + The type of content you want to associate with this card. + Required if you provide ContentId. + Use Issue when ContentId is an issue ID and use PullRequest when ContentId is a pull request id. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .PARAMETER NoStatus + If this switch is specified, long-running commands will run on the main thread + with no command line status update. When not specified, those commands run in + the background, enabling the command prompt to provide status information. + If not supplied here, the DefaultNoStatus configuration property value will be used. + + .EXAMPLE + New-GitHubProjectCard -Column 999999 -Note 'Note on card' + + Creates a card on column 999999 with the note 'Note on card'. + + .EXAMPLE + New-GitHubProjectCard -Column 999999 -ContentId 888888 -ContentType Issue + + Creates a card on column 999999 for the issue with ID 888888. + + .EXAMPLE + New-GitHubProjectCard -Column 999999 -ContentId 888888 -ContentType Issue + + Creates a card on column 999999 for the issue with ID 888888. + + .EXAMPLE + New-GitHubProjectCard -Column 999999 -ContentId 777777 -ContentType PullRequest + + Creates a card on column 999999 for the pull request with ID 777777. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'Note')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification = "Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")] + param( + + [Parameter(Mandatory)] + [int64] $Column, + + [Parameter(Mandatory, ParameterSetName = 'Note')] + [string] $Note, + + [Parameter(Mandatory, ParameterSetName = 'Content')] + [int64] $ContentId, + + [Parameter(Mandatory, ParameterSetName = 'Content')] + [ValidateSet('Issue', 'PullRequest')] + [string] $ContentType, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = "/projects/columns/$Column/cards" + $apiDescription = "Creating project card" + + if ($PSCmdlet.ParameterSetName -eq 'Note') + { + $telemetryProperties['Note'] = $true + + $hashBody = @{ + 'note' = $Note + } + } + elseif ($PSCmdlet.ParameterSetName -eq 'Content') + { + $telemetryProperties['Content'] = $true + + $hashBody = @{ + 'content_id' = $ContentId + 'content_type' = $ContentType + } + } + + $params = @{ + 'UriFragment' = $uriFragment + 'Body' = (ConvertTo-Json -InputObject $hashBody) + 'Method' = 'Post' + 'Description' = $apiDescription + 'AccessToken' = $AccessToken + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + 'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus) + 'AcceptHeader' = 'application/vnd.github.inertia-preview+json' + } + + return Invoke-GHRestMethod @params +} + +function Set-GitHubProjectCard +{ +<# + .DESCRIPTION + Modify a GitHub Project Card. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Card + ID of the card to modify. + + .PARAMETER Note + The note content for the card. Only valid for cards without another type of content, + so this cannot be specified if the card already has a content_id and content_type. + + .PARAMETER Archive + Archive a project card. + + .PARAMETER Restore + Restore a project card. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .PARAMETER NoStatus + If this switch is specified, long-running commands will run on the main thread + with no command line status update. When not specified, those commands run in + the background, enabling the command prompt to provide status information. + If not supplied here, the DefaultNoStatus configuration property value will be used. + + .EXAMPLE + Set-GitHubProjectCard -Card 999999 -Note UpdatedNote + + Sets the card note to 'UpdatedNote' for the card with ID 999999. + + .EXAMPLE + Set-GitHubProjectCard -Card 999999 -Archive + + Archives the card with ID 999999. + + .EXAMPLE + Set-GitHubProjectCard -Card 999999 -Restore + + Restores the card with ID 999999. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'Note')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification = "Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")] + param( + [Parameter(Mandatory)] + [int64] $Card, + + [string] $Note, + + [Parameter(ParameterSetName = 'Archive')] + [switch] $Archive, + + [Parameter(ParameterSetName = 'Restore')] + [switch] $Restore, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = "/projects/columns/cards/$Card" + $apiDescription = "Updating card $Card" + + $hashBody = @{} + + if ($PSBoundParameters.ContainsKey('Note')) + { + $telemetryProperties['Note'] = $true + $hashBody.add('note', $Note) + } + + if ($Archive) + { + $telemetryProperties['Archive'] = $true + $hashBody.add('archived', $true) + } + + if ($Restore) + { + $telemetryProperties['Restore'] = $true + $hashBody.add('archived', $false) + } + + $params = @{ + 'UriFragment' = $uriFragment + 'Description' = $apiDescription + 'Body' = (ConvertTo-Json -InputObject $hashBody) + 'AccessToken' = $AccessToken + 'Method' = 'Patch' + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + 'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus) + 'AcceptHeader' = 'application/vnd.github.inertia-preview+json' + } + + return Invoke-GHRestMethod @params +} + +function Remove-GitHubProjectCard +{ +<# + .DESCRIPTION + Removes a project card. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Card + ID of the card to remove. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .PARAMETER NoStatus + If this switch is specified, long-running commands will run on the main thread + with no command line status update. When not specified, those commands run in + the background, enabling the command prompt to provide status information. + If not supplied here, the DefaultNoStatus configuration property value will be used. + + .EXAMPLE + Remove-GitHubProjectCard -Card 999999 + + Remove project card with ID 999999. + + .EXAMPLE + Remove-GitHubProjectCard -Card 999999 -Confirm:$False + + Remove project card with ID 999999 without prompting for confirmation. +#> + [CmdletBinding( + SupportsShouldProcess, + ConfirmImpact = 'High')] + [Alias('Delete-GitHubProjectCard')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification = "Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")] + param( + [Parameter(Mandatory)] + [int64] $Card, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = "/projects/columns/cards/$Card" + $description = "Deleting card $Card" + + if ($PSCmdlet.ShouldProcess($Card, "Remove card")) + { + $params = @{ + 'UriFragment' = $uriFragment + 'Description' = $description + 'AccessToken' = $AccessToken + 'Method' = 'Delete' + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + 'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus) + 'AcceptHeader' = 'application/vnd.github.inertia-preview+json' + } + + return Invoke-GHRestMethod @params + } +} + +function Move-GitHubProjectCard +{ +<# + .DESCRIPTION + Move a GitHub Project Card. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Card + ID of the card to move. + + .PARAMETER Top + Moves the card to the top of the column. + + .PARAMETER Bottom + Moves the card to the bottom of the column. + + .PARAMETER After + Moves the card to the position after the card ID specified. + + .PARAMETER ColumnId + The ID of a column in the same project to move the card to. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .PARAMETER NoStatus + If this switch is specified, long-running commands will run on the main thread + with no command line status update. When not specified, those commands run in + the background, enabling the command prompt to provide status information. + If not supplied here, the DefaultNoStatus configuration property value will be used. + + .EXAMPLE + Move-GitHubProjectCard -Card 999999 -Top + + Moves the project card with ID 999999 to the top of the column. + + .EXAMPLE + Move-GitHubProjectCard -Card 999999 -Bottom + + Moves the project card with ID 999999 to the bottom of the column. + + .EXAMPLE + Move-GitHubProjectCard -Card 999999 -After 888888 + + Moves the project card with ID 999999 to the position after the card ID 888888. + Within the same column. + + .EXAMPLE + Move-GitHubProjectCard -Card 999999 -After 888888 -ColumnId 123456 + + Moves the project card with ID 999999 to the position after the card ID 888888, in + the column with ID 123456. +#> + [CmdletBinding( + SupportsShouldProcess)] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification = "Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")] + param( + [Parameter(Mandatory)] + [int64] $Card, + + [switch] $Top, + + [switch] $Bottom, + + [int64] $After, + + [int64] $ColumnId, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = "/projects/columns/cards/$Card/moves" + $apiDescription = "Updating card $Card" + + if (-not ($Top -xor $Bottom -xor ($After -gt 0))) + { + $message = 'You must use one (and only one) of the parameters Top, Bottom or After.' + Write-Log -Message $message -level Error + throw $message + } + elseif ($Top) + { + $position = 'top' + } + elseif ($Bottom) + { + $position = 'bottom' + } + else + { + $position = "after:$After" + } + + $hashBody = @{ + 'position' = $Position + } + + if ($PSBoundParameters.ContainsKey('ColumnId')) + { + $telemetryProperties['ColumnId'] = $true + $hashBody.add('column_id', $ColumnId) + } + + $params = @{ + 'UriFragment' = $uriFragment + 'Description' = $apiDescription + 'Body' = (ConvertTo-Json -InputObject $hashBody) + 'AccessToken' = $AccessToken + 'Method' = 'Post' + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + 'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus) + 'AcceptHeader' = 'application/vnd.github.inertia-preview+json' + } + + return Invoke-GHRestMethod @params +} \ No newline at end of file diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index 426b9343..87df79c9 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -33,6 +33,7 @@ 'GitHubMiscellaneous.ps1', 'GitHubOrganizations.ps1', 'GitHubProjects.ps1', + 'GitHubProjectCards.ps1', 'GitHubProjectColumns.ps1', 'GitHubPullRequests.ps1', 'GitHubReleases.ps1', @@ -70,6 +71,7 @@ 'Get-GitHubOrganizationMember', 'Get-GitHubPathTraffic', 'Get-GitHubProject', + 'Get-GitHubProjectCard', 'Get-GitHubProjectColumn', 'Get-GitHubPullRequest', 'Get-GitHubRateLimit', @@ -93,14 +95,16 @@ 'Invoke-GHRestMethod', 'Invoke-GHRestMethodMultipleResult', 'Lock-GitHubIssue', - 'Move-GitHubRepositoryOwnership', + 'Move-GitHubProjectCard', 'Move-GitHubProjectColumn', + 'Move-GitHubRepositoryOwnership', 'New-GithubAssignee', 'New-GitHubComment', 'New-GitHubIssue', 'New-GitHubLabel', 'New-GitHubMilestone', 'New-GitHubProject', + 'New-GitHubProjectCard', 'New-GitHubProjectColumn', 'New-GitHubPullRequest', 'New-GitHubRepository', @@ -111,6 +115,7 @@ 'Remove-GitHubLabel', 'Remove-GitHubMilestone', 'Remove-GitHubProject', + 'Remove-GitHubProjectCard', 'Remove-GitHubProjectColumn', 'Remove-GitHubRepository', 'Rename-GitHubRepository', @@ -123,6 +128,7 @@ 'Set-GitHubLabel', 'Set-GitHubMilestone', 'Set-GitHubProject', + 'Set-GitHubProjectCard', 'Set-GitHubProjectColumn', 'Set-GitHubRepositoryTopic', 'Split-GitHubUri', @@ -141,6 +147,7 @@ 'Delete-GitHubLabel', 'Delete-GitHubMilestone', 'Delete-GitHubProject', + 'Delete-GitHubProjectCard', 'Delete-GitHubProjectColumn' 'Delete-GitHubRepository', 'Get-GitHubBranch', @@ -195,5 +202,4 @@ # HelpInfo URI of this module # HelpInfoURI = '' -} - +} \ No newline at end of file diff --git a/Tests/GitHubProjectCards.tests.ps1 b/Tests/GitHubProjectCards.tests.ps1 new file mode 100644 index 00000000..0b286e8b --- /dev/null +++ b/Tests/GitHubProjectCards.tests.ps1 @@ -0,0 +1,233 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Tests for GitHubProjectCards.ps1 module +#> + +# This is common test code setup logic for all Pester test files +$moduleRootPath = Split-Path -Path $PSScriptRoot -Parent +. (Join-Path -Path $moduleRootPath -ChildPath 'Tests\Common.ps1') + +try +{ + # Define Script-scoped, readOnly, hidden variables. + @{ + defaultProject = "TestProject_$([Guid]::NewGuid().Guid)" + defaultColumn = "TestColumn" + defaultColumnTwo = "TestColumnTwo" + + defaultCard = "TestCard" + defaultCardTwo = "TestCardTwo" + defaultCardUpdated = "TestCard_Updated" + defaultArchivedCard = "TestCard_Archived" + + defaultIssue = "TestIssue" + }.GetEnumerator() | ForEach-Object { + Set-Variable -Force -Scope Script -Option ReadOnly -Visibility Private -Name $_.Key -Value $_.Value + } + + $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit + $project = New-GitHubProject -Owner $script:ownerName -Repository $repo.name -Name $defaultProject + + $column = New-GitHubProjectColumn -Project $project.id -Name $defaultColumn + $columntwo = New-GitHubProjectColumn -Project $project.id -Name $defaultColumnTwo + + $issue = New-GitHubIssue -Owner $script:ownerName -RepositoryName $repo.name -Title $defaultIssue + + Describe 'Getting Project Cards' { + BeforeAll { + $card = New-GitHubProjectCard -Column $column.id -Note $defaultCard + $cardArchived = New-GitHubProjectCard -Column $column.id -Note $defaultArchivedCard + $null = Set-GitHubProjectCard -Card $cardArchived.id -Archive + } + AfterAll { + $null = Remove-GitHubProjectCard -Card $card.id -Confirm:$false + } + + Context 'Get cards for a column' { + $results = Get-GitHubProjectCard -Column $column.id + It 'Should get cards' { + $results | Should Not BeNullOrEmpty + } + + It 'Note is correct' { + $results.note | Should be $defaultCard + } + } + + Context 'Get all cards for a column' { + $results = Get-GitHubProjectCard -Column $column.id -ArchivedState All + It 'Should get all cards' { + $results.Count | Should Be 2 + } + } + + Context 'Get archived cards for a column' { + $results = Get-GitHubProjectCard -Column $column.id -ArchivedState Archived + It 'Should get archived card' { + $results | Should Not BeNullOrEmpty + } + + It 'Note is correct' { + $results.note | Should be $defaultArchivedCard + } + + It 'Should be archived' { + $results.Archived | Should be $true + } + } + } + + Describe 'Modify card' { + BeforeAll { + $card = New-GitHubProjectCard -Column $column.id -Note $defaultCard + $cardTwo = New-GitHubProjectCard -Column $column.id -Note $defaultCardTwo + $cardArchived = New-GitHubProjectCard -Column $column.id -Note $defaultArchivedCard + } + AfterAll { + $null = Remove-GitHubProjectCard -Card $card.id -Confirm:$false + } + + Context 'Modify card note' { + $null = Set-GitHubProjectCard -Card $card.id -Note $defaultCardUpdated + $results = Get-GitHubProjectCard -Card $card.id + + It 'Should get card' { + $results | Should Not BeNullOrEmpty + } + + It 'Note has been updated' { + $results.note | Should be $defaultCardUpdated + } + } + + Context 'Archive a card' { + $null = Set-GitHubProjectCard -Card $cardArchived.id -Archive + $results = Get-GitHubProjectCard -Card $cardArchived.id + + It 'Should get card' { + $results | Should Not BeNullOrEmpty + } + + It 'Card is archived' { + $results.Archived | Should be $true + } + } + + Context 'Restore a card' { + $null = Set-GitHubProjectCard -Card $cardArchived.id -Restore + $results = Get-GitHubProjectCard -Card $cardArchived.id + + It 'Should get card' { + $results | Should Not BeNullOrEmpty + } + + It 'Card is not archived' { + $results.Archived | Should be $false + } + } + + Context 'Move card position within column' { + $null = Move-GitHubProjectCard -Card $cardTwo.id -Top + $results = Get-GitHubProjectCard -Column $column.id + + It 'Card is now top' { + $results[0].note | Should be $defaultCardTwo + } + } + + Context 'Move card using after parameter' { + $null = Move-GitHubProjectCard -Card $cardTwo.id -After $card.id + $results = Get-GitHubProjectCard -Column $column.id + + It 'Card now exists in new column' { + $results[1].note | Should be $defaultCardTwo + } + } + + Context 'Move card to another column' { + $null = Move-GitHubProjectCard -Card $cardTwo.id -Top -ColumnId $columnTwo.id + $results = Get-GitHubProjectCard -Column $columnTwo.id + + It 'Card now exists in new column' { + $results[0].note | Should be $defaultCardTwo + } + } + + Context 'Move command throws appropriate error' { + It 'Appropriate error is thrown' { + { Move-GitHubProjectCard -Card $cardTwo.id -Top -Bottom } | Should Throw 'You must use one (and only one) of the parameters Top, Bottom or After.' + } + } + } + + Describe 'Create Project Cards' -tag new { + Context 'Create project card with note' { + BeforeAll { + $card = @{id = 0} + } + AfterAll { + $null = Remove-GitHubProjectCard -Card $card.id -Confirm:$false + Remove-Variable -Name card + } + + $card.id = (New-GitHubProjectCard -Column $column.id -Note $defaultCard).id + $results = Get-GitHubProjectCard -Card $card.id + + It 'Card exists' { + $results | Should Not BeNullOrEmpty + } + + It 'Note is correct' { + $results.note | Should be $defaultCard + } + } + + Context 'Create project card from issue' { + BeforeAll { + $card = @{id = 0} + } + AfterAll { + $null = Remove-GitHubProjectCard -Card $card.id -Confirm:$false + Remove-Variable -Name card + } + + $card.id = (New-GitHubProjectCard -Column $column.id -ContentId $issue.id -ContentType 'Issue').id + $results = Get-GitHubProjectCard -Card $card.id + + It 'Card exists' { + $results | Should Not BeNullOrEmpty + } + + It 'Content url is for an issue' { + $results.content_url | Should match 'issues' + } + } + } + + Describe 'Remove card' { + Context 'Remove card' { + BeforeAll { + $card = New-GitHubProjectCard -Column $column.id -Note $defaultCard + } + + $null = Remove-GitHubProjectCard -Card $card.id -Confirm:$false + It 'Project card should be removed' { + {Get-GitHubProjectCard -Card $card.id} | Should Throw + } + } + } + + Remove-GitHubProject -Project $project.id -Confirm:$false +} +finally +{ + if (Test-Path -Path $script:originalConfigFile -PathType Leaf) + { + # Restore the user's configuration to its pre-test state + Restore-GitHubConfiguration -Path $script:originalConfigFile + $script:originalConfigFile = $null + } +} \ No newline at end of file