diff --git a/GitHubProjects.ps1 b/GitHubProjects.ps1 new file mode 100644 index 00000000..8c60d22f --- /dev/null +++ b/GitHubProjects.ps1 @@ -0,0 +1,512 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +function Get-GitHubProject +{ +<# + .DESCRIPTION + Get the projects for a given Github user, repository or organization. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OwnerName + Owner of the repository. + If not supplied here, the DefaultOwnerName configuration property value will be used. + + .PARAMETER RepositoryName + Name of the repository. + If not supplied here, the DefaultRepositoryName configuration property value will be used. + + .PARAMETER Uri + Uri for the repository. + The OwnerName and RepositoryName will be extracted from here instead of needing to provide + them individually. + + .PARAMETER OrganizationName + The name of the organization to get projects for. + + .PARAMETER UserName + The name of the user to get projects for. + + .PARAMETER Project + ID of the project to retrieve. + + .PARAMETER State + Only projects with this state are returned. + + .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-GitHubProject -OwnerName Microsoft -RepositoryName PowerShellForGitHub + + Get the projects for the Microsoft\PowerShellForGitHub repository. + + .EXAMPLE + Get-GitHubProject -OrganizationName Microsoft + + Get the projects for the Microsoft organization. + + .EXAMPLE + Get-GitHubProject -Uri https://github.com/Microsoft/PowerShellForGitHub + + Get the projects for the Microsoft\PowerShellForGitHub repository using the Uri. + + .EXAMPLE + Get-GitHubProject -UserName GitHubUser + + Get the projects for the user GitHubUser. + + .EXAMPLE + Get-GitHubProject -OwnerName Microsoft -RepositoryName PowerShellForGitHub -State Closed + + Get closed projects from the Microsoft\PowerShellForGitHub repo. + + .EXAMPLE + Get-GitHubProject -Project 4378613 + + Get a project by id, with this parameter you don't need any other information. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'Elements')] + [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 = 'Elements')] + [string] $OwnerName, + + [Parameter(Mandatory, ParameterSetName = 'Elements')] + [string] $RepositoryName, + + [Parameter(Mandatory, ParameterSetName = 'Uri')] + [string] $Uri, + + [Parameter(Mandatory, ParameterSetName = 'Organization')] + [string] $OrganizationName, + + [Parameter(Mandatory, ParameterSetName = 'User')] + [string] $UserName, + + [Parameter(Mandatory, ParameterSetName = 'Project')] + [int64] $Project, + + [ValidateSet('Open', 'Closed', 'All')] + [string] $State, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = [String]::Empty + $description = [String]::Empty + if ($PSCmdlet.ParameterSetName -eq 'Project') + { + $telemetryProperties['Project'] = Get-PiiSafeString -PlainText $Project + + $uriFragment = "/projects/$Project" + $description = "Getting project $project" + } + elseif ($PSCmdlet.ParameterSetName -in ('Elements', 'Uri')) + { + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + $uriFragment = "/repos/$OwnerName/$RepositoryName/projects" + $description = "Getting projects for $RepositoryName" + } + elseif ($PSCmdlet.ParameterSetName -eq 'Organization') + { + $telemetryProperties['OrganizationName'] = Get-PiiSafeString -PlainText $OrganizationName + + $uriFragment = "/orgs/$OrganizationName/projects" + $description = "Getting projects for $OrganizationName" + } + elseif ($PSCmdlet.ParameterSetName -eq 'User') + { + $telemetryProperties['UserName'] = Get-PiiSafeString -PlainText $UserName + + $uriFragment = "/users/$UserName/projects" + $description = "Getting projects for $UserName" + } + + if ($PSBoundParameters.ContainsKey('State')) + { + $getParams = @() + $State = $State.ToLower() + $getParams += "state=$State" + + $uriFragment = "$uriFragment`?" + ($getParams -join '&') + $description += " with state '$state'" + } + + $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-GitHubProject +{ +<# + .DESCRIPTION + Creates a new Github project for the given repository + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OwnerName + Owner of the repository. + If not supplied here, the DefaultOwnerName configuration property value will be used. + + .PARAMETER RepositoryName + Name of the repository. + If not supplied here, the DefaultRepositoryName configuration property value will be used. + + .PARAMETER Uri + Uri for the repository. + The OwnerName and RepositoryName will be extracted from here instead of needing to provide + them individually. + + .PARAMETER OrganizationName + The name of the organization to create the project under. + + .PARAMETER UserProject + If this switch is specified creates a project for your user. + + .PARAMETER Name + The name of the project to create. + + .PARAMETER Description + Short description for the new project. + + .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-GitHubProject -OwnerName Microsoft -RepositoryName PowerShellForGitHub -Name TestProject + + Creates a project called 'TestProject' for the Microsoft\PowerShellForGitHub repository. + + .EXAMPLE + New-GitHubProject -OrganizationName Microsoft -Name TestProject -Description 'This is just a test project' + + Create a project for the Microsoft organization called 'TestProject' with a description. + + .EXAMPLE + New-GitHubProject -Uri https://github.com/Microsoft/PowerShellForGitHub -Name TestProject + + Create a project for the Microsoft\PowerShellForGitHub repository using the Uri called 'TestProject'. + + .EXAMPLE + New-GitHubProject -UserProject -Name 'TestProject' + + Creates a project for the signed in user called 'TestProject'. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'Elements')] + [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 = 'Elements')] + [string] $OwnerName, + + [Parameter(Mandatory, ParameterSetName = 'Elements')] + [string] $RepositoryName, + + [Parameter(Mandatory, ParameterSetName = 'Uri')] + [string] $Uri, + + [Parameter(Mandatory, ParameterSetName = 'Organization')] + [string] $OrganizationName, + + [Parameter(Mandatory, ParameterSetName = 'User')] + [switch] $UserProject, + + [Parameter(Mandatory)] + [string] $Name, + + [string] $Description, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + $telemetryProperties['Name'] = Get-PiiSafeString -PlainText $Name + + $uriFragment = [String]::Empty + $apiDescription = [String]::Empty + if ($PSCmdlet.ParameterSetName -in ('Elements', 'Uri')) + { + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + $uriFragment = "/repos/$OwnerName/$RepositoryName/projects" + $apiDescription = "Creating project for $RepositoryName" + } + elseif ($PSCmdlet.ParameterSetName -eq 'Organization') + { + $telemetryProperties['OrganizationName'] = Get-PiiSafeString -PlainText $OrganizationName + + $uriFragment = "/orgs/$OrganizationName/projects" + $apiDescription = "Creating project for $OrganizationName" + } + elseif ($PSCmdlet.ParameterSetName -eq 'User') + { + $telemetryProperties['User'] = $true + + $uriFragment = "/user/projects" + $apiDescription = "Creating project for user" + } + + $hashBody = @{ + 'name' = $Name + } + + if ($PSBoundParameters.ContainsKey('Description')) + { + $hashBody.add('body', $Description) + } + + $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-GitHubProject +{ +<# + .DESCRIPTION + Modify a GitHub Project. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Project + ID of the project to modify. + + .PARAMETER Description + Short description for the project. + + .PARAMETER State + Set the state of the project. + + .PARAMETER OrganizationPermission + Set the permission level that determines whether all members of the project's + organization can see and/or make changes to the project. + Only available for organization projects. + + .PARAMETER Private + Sets the visibility of a project board. + Only available for organization and user projects. + Note: Updating a project's visibility requires admin access to the project. + + .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-GitHubProject -Project 999999 -State Closed + + Set the project with ID '999999' to closed. + + .EXAMPLE + $project = Get-GitHubProject -OwnerName Microsoft -RepositoryName PowerShellForGitHub | Where-Object Name -eq 'TestProject' + Set-GitHubProject -Project $project.id -State Closed + + Get the ID for the 'TestProject' project for the Microsoft\PowerShellForGitHub + repository and set state to closed. +#> + [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] $Project, + + [string] $Description, + + [ValidateSet('Open', 'Closed')] + [string] $State, + + [ValidateSet('Read', 'Write', 'Admin', 'None')] + [string] $OrganizationPermission, + + [switch] $Private, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = "projects/$Project" + $apiDescription = "Updating project $Project" + + $hashBody = @{} + + if ($PSBoundParameters.ContainsKey('Description')) + { + $hashBody.add('body', $Description) + $apiDescription += " description" + } + + if ($PSBoundParameters.ContainsKey('State')) + { + $hashBody.add('state', $State) + $apiDescription += ", state to '$State'" + } + + if ($PSBoundParameters.ContainsKey('Private')) + { + $hashBody.add('private', $Private.ToBool()) + $apiDescription += ", private to '$Private'" + } + + if ($PSBoundParameters.ContainsKey('OrganizationPermission')) + { + $hashBody.add('organization_permission', $OrganizationPermission.ToLower()) + $apiDescription += ", organization_permission to '$OrganizationPermission'" + } + + $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-GitHubProject +{ +<# + .DESCRIPTION + Removes the projects for a given Github repository. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER Project + ID of the project 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-GitHubProject -Project 4387531 + + Remove project with ID '4387531'. + + .EXAMPLE + $project = Get-GitHubProject -OwnerName Microsoft -RepositoryName PowerShellForGitHub | Where-Object Name -eq 'TestProject' + Remove-GitHubProject -Project $project.id + + Get the ID for the 'TestProject' project for the Microsoft\PowerShellForGitHub + repository and then remove the project. +#> + [CmdletBinding( + SupportsShouldProcess, + ConfirmImpact = 'High')] + [Alias('Delete-GitHubProject')] + [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] $Project, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $telemetryProperties = @{} + + $uriFragment = "projects/$Project" + $description = "Deleting project $Project" + + if ($PSCmdlet.ShouldProcess($project, "Remove project")) + { + $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 + } + +} diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index 67903012..5b1554ee 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -32,6 +32,7 @@ 'GitHubMilestones.ps1', 'GitHubMiscellaneous.ps1', 'GitHubOrganizations.ps1', + 'GitHubProjects.ps1', 'GitHubPullRequests.ps1', 'GitHubReleases.ps1', 'GitHubRepositories.ps1', @@ -67,6 +68,7 @@ 'Get-GitHubMilestone', 'Get-GitHubOrganizationMember', 'Get-GitHubPathTraffic', + 'Get-GitHubProject', 'Get-GitHubPullRequest', 'Get-GitHubRateLimit', 'Get-GitHubReferrerTraffic', @@ -95,6 +97,7 @@ 'New-GitHubIssue', 'New-GitHubLabel', 'New-GitHubMilestone', + 'New-GitHubProject', 'New-GitHubPullRequest', 'New-GitHubRepository', 'New-GitHubRepositoryFork', @@ -103,6 +106,7 @@ 'Remove-GitHubIssueLabel', 'Remove-GitHubLabel', 'Remove-GitHubMilestone', + 'Remove-GitHubProject', 'Remove-GitHubRepository', 'Rename-GitHubRepository', 'Reset-GitHubConfiguration', @@ -113,6 +117,7 @@ 'Set-GitHubIssueLabel', 'Set-GitHubLabel', 'Set-GitHubMilestone', + 'Set-GitHubProject', 'Set-GitHubRepositoryTopic', 'Split-GitHubUri', 'Test-GitHubAssignee', @@ -129,6 +134,7 @@ 'Delete-GitHubComment', 'Delete-GitHubLabel', 'Delete-GitHubMilestone', + 'Delete-GitHubProject', 'Delete-GitHubRepository', 'Get-GitHubBranch', 'Transfer-GitHubRepositoryOwnership' diff --git a/Tests/GitHubProjects.tests.ps1 b/Tests/GitHubProjects.tests.ps1 new file mode 100644 index 00000000..6674a3e2 --- /dev/null +++ b/Tests/GitHubProjects.tests.ps1 @@ -0,0 +1,332 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Tests for GitHubProjects.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. + @{ + defaultUserProject = "TestProject_$([Guid]::NewGuid().Guid)" + defaultUserProjectDesc = "This is my desc for user project" + modifiedUserProjectDesc = "Desc has been modified" + + defaultRepoProject = "TestRepoProject_$([Guid]::NewGuid().Guid)" + defaultRepoProjectDesc = "This is my desc for repo project" + modifiedRepoProjectDesc = "Desc has been modified" + + defaultOrgProject = "TestOrgProject_$([Guid]::NewGuid().Guid)" + defaultOrgProjectDesc = "This is my desc for org project" + modifiedOrgProjectDesc = "Desc has been modified" + + defaultProjectClosed = "TestClosedProject" + defaultProjectClosedDesc = "I'm a closed project" + }.GetEnumerator() | ForEach-Object { + Set-Variable -Force -Scope Script -Option ReadOnly -Visibility Private -Name $_.Key -Value $_.Value + } + + $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit + + Describe 'Getting Project' { + + Context 'Get User projects' { + BeforeAll { + $project = New-GitHubProject -UserProject -Name $defaultUserProject -Description $defaultUserProjectDesc + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $results = Get-GitHubProject -UserName $script:ownerName | Where-Object Name -eq $defaultUserProject + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultUserProject + } + + It 'Description is correct' { + $results.body | Should be $defaultUserProjectDesc + } + } + + Context 'Get Organization projects' { + BeforeAll { + $project = New-GitHubProject -OrganizationName $script:organizationName -Name $defaultOrgProject -Description $defaultOrgProjectDesc + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $results = Get-GitHubProject -OrganizationName $script:organizationName | Where-Object Name -eq $defaultOrgProject + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultOrgProject + } + + It 'Description is correct' { + $results.body | Should be $defaultOrgProjectDesc + } + } + + Context 'Get Repo projects' { + BeforeAll { + $project = New-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name -Name $defaultRepoProject -Description $defaultRepoProjectDesc + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $results = Get-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name | Where-Object Name -eq $defaultRepoProject + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultRepoProject + } + + It 'Description is correct' { + $results.body | Should be $defaultRepoProjectDesc + } + } + + Context 'Get a closed Repo project' { + BeforeAll { + $project = New-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name -Name $defaultProjectClosed -Description $defaultProjectClosedDesc + $null = Set-GitHubProject -Project $project.id -State Closed + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $results = Get-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name -State 'Closed' | Where-Object Name -eq $defaultProjectClosed + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultProjectClosed + } + + It 'Description is correct' { + $results.body | Should be $defaultProjectClosedDesc + } + + It 'State is correct' { + $results.state | Should be "Closed" + } + } + } + + Describe 'Modify Project' { + Context 'Modify User projects' { + BeforeAll { + $project = New-GitHubProject -UserProject -Name $defaultUserProject -Description $defaultUserProjectDesc + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $null = Set-GitHubProject -Project $project.id -Description $modifiedUserProjectDesc + $results = Get-GitHubProject -Project $project.id + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultUserProject + } + + It 'Description should be updated' { + $results.body | Should be $modifiedUserProjectDesc + } + } + + Context 'Modify Organization projects' { + BeforeAll { + $project = New-GitHubProject -OrganizationName $script:organizationName -Name $defaultOrgProject -Description $defaultOrgProjectDesc + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $null = Set-GitHubProject -Project $project.id -Description $modifiedOrgProjectDesc -Private:$false -OrganizationPermission Admin + $results = Get-GitHubProject -Project $project.id + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultOrgProject + } + + It 'Description should be updated' { + $results.body | Should be $modifiedOrgProjectDesc + } + + It 'Visibility should be updated to public' { + $results.private | Should be $false + } + + It 'Organization permission should be updated to admin' { + $results.organization_permission | Should be 'admin' + } + + } + + Context 'Modify Repo projects' { + BeforeAll { + $project = New-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name -Name $defaultRepoProject -Description $defaultRepoProjectDesc + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + } + + $null = Set-GitHubProject -Project $project.id -Description $modifiedRepoProjectDesc + $results = Get-GitHubProject -Project $project.id + It 'Should get project' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultRepoProject + } + + It 'Description should be updated' { + $results.body | Should be $modifiedRepoProjectDesc + } + } + } + + Describe 'Create Project' { + Context 'Create User projects' { + BeforeAll { + $project = @{id = 0} + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + Remove-Variable project + } + + $project.id = (New-GitHubProject -UserProject -Name $defaultUserProject -Description $defaultUserProjectDesc).id + $results = Get-GitHubProject -Project $project.id + It 'Project exists' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultUserProject + } + + It 'Description should be updated' { + $results.body | Should be $defaultUserProjectDesc + } + } + + Context 'Create Organization projects' { + BeforeAll { + $project = @{id = 0} + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + Remove-Variable project + } + + $project.id = (New-GitHubProject -OrganizationName $script:organizationName -Name $defaultOrgProject -Description $defaultOrgProjectDesc).id + $results = Get-GitHubProject -Project $project.id + It 'Project exists' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultOrgProject + } + + It 'Description should be updated' { + $results.body | Should be $defaultOrgProjectDesc + } + } + + Context 'Create Repo projects' { + BeforeAll { + $project = @{id = 0} + } + AfterAll { + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + Remove-Variable project + } + + $project.id = (New-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name -Name $defaultRepoProject -Description $defaultRepoProjectDesc).id + $results = Get-GitHubProject -Project $project.id + It 'Project Exists' { + $results | Should Not BeNullOrEmpty + } + + It 'Name is correct' { + $results.name | Should be $defaultRepoProject + } + + It 'Description should be updated' { + $results.body | Should be $defaultRepoProjectDesc + } + } + } + + Describe 'Remove Project' { + Context 'Remove User projects' { + BeforeAll { + $project = New-GitHubProject -UserProject -Name $defaultUserProject -Description $defaultUserProjectDesc + } + + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + It 'Project should be removed' { + {Get-GitHubProject -Project $project.id} | Should Throw + } + } + + Context 'Remove Organization projects' { + BeforeAll { + $project = New-GitHubProject -OrganizationName $script:organizationName -Name $defaultOrgProject -Description $defaultOrgProjectDesc + } + + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + It 'Project should be removed' { + {Get-GitHubProject -Project $project.id} | Should Throw + } + } + + Context 'Remove Repo projects' { + BeforeAll { + $project = New-GitHubProject -OwnerName $script:ownerName -RepositoryName $repo.name -Name $defaultRepoProject -Description $defaultRepoProjectDesc + } + + $null = Remove-GitHubProject -Project $project.id -Confirm:$false + It 'Project should be removed' { + {Get-GitHubProject -Project $project.id} | Should Throw + } + } + } + + Remove-GitHubRepository -Uri $repo.svn_url +} +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 + } +}