Tests/GitHubMilestones.tests.ps1
# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. <# .Synopsis Tests for GitHubMilestones.ps1 module #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification='Suppress false positives in Pester code blocks')] param() # 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. @{ defaultMilestoneDueOn = (Get-Date).AddYears(1).ToUniversalTime() }.GetEnumerator() | ForEach-Object { Set-Variable -Force -Scope Script -Option ReadOnly -Visibility Private -Name $_.Key -Value $_.Value } Describe 'Creating a milestone' { BeforeAll { $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit $commonParams = @{ 'State' = 'Closed' 'DueOn' = $script:defaultMilestoneDueOn 'Description' = 'Milestone description' } $title = 'Milestone title' } AfterAll { $repo | Remove-GitHubRepository -Force } Context 'Using the parameter' { BeforeAll { $milestone = New-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name -Title $title @commonParams } AfterAll { $milestone | Remove-GitHubMilestone -Force } $returned = Get-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name -Milestone $milestone.MilestoneNumber It 'Should exist' { $returned.id | Should -Be $milestone.id } It 'Should have the correct creation properties' { $milestone.title | Should -Be $title $milestone.state | Should -Be $commonParams['State'] $milestone.description | Should -Be $commonParams['Description'] # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $milestone.due_on).Date | Should -Be $commonParams['DueOn'].Date } It 'Should have the expected type and additional properties' { $milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $milestone.RepositoryUrl | Should -Be $repo.RepositoryUrl $milestone.MilestoneId | Should -Be $milestone.id $milestone.MilestoneNumber | Should -Be $milestone.number $milestone.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } } Context 'Using the pipeline for the repo' { BeforeAll { $milestone = $repo | New-GitHubMilestone -Title $title @commonParams } AfterAll { $milestone | Remove-GitHubMilestone -Force } $returned = $milestone | Get-GitHubMilestone It 'Should exist' { $returned.id | Should -Be $milestone.id } It 'Should have the correct creation properties' { $milestone.title | Should -Be $title $milestone.state | Should -Be $commonParams['State'] $milestone.description | Should -Be $commonParams['Description'] # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $milestone.due_on).Date | Should -Be $commonParams['DueOn'].Date } It 'Should have the expected type and additional properties' { $milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $milestone.RepositoryUrl | Should -Be $repo.RepositoryUrl $milestone.MilestoneId | Should -Be $milestone.id $milestone.MilestoneNumber | Should -Be $milestone.number $milestone.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } } Context 'Using the pipeline for the title' { BeforeAll { $milestone = $title | New-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name @commonParams } AfterAll { $milestone | Remove-GitHubMilestone -Force } $returned = $repo | Get-GitHubMilestone -Milestone $milestone.MilestoneNumber It 'Should exist' { $returned.id | Should -Be $milestone.id } It 'Should have the correct creation properties' { $milestone.title | Should -Be $title $milestone.state | Should -Be $commonParams['State'] $milestone.description | Should -Be $commonParams['Description'] # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $milestone.due_on).Date | Should -Be $commonParams['DueOn'].Date } It 'Should have the expected type and additional properties' { $milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $milestone.RepositoryUrl | Should -Be $repo.RepositoryUrl $milestone.MilestoneId | Should -Be $milestone.id $milestone.MilestoneNumber | Should -Be $milestone.number $milestone.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } } Context 'That is due at different times of the day' { # We'll be testing to make sure that regardless of the time in the timestamp, we'll get the desired date. $title = 'Milestone title' It "Should have the expected due_on date even if early morning" { $milestone = $repo | New-GitHubMilestone -Title 'Due early in the morning' -State "Closed" -DueOn $defaultMilestoneDueOn.date.AddHours(1) # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $milestone.due_on).Date | Should -Be $defaultMilestoneDueOn.Date } It "Should have the expected due_on date even if late evening" { $milestone = $repo | New-GitHubMilestone -Title 'Due late in the evening' -State "Closed" -DueOn $defaultMilestoneDueOn.date.AddHours(23) # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $milestone.due_on).Date | Should -Be $defaultMilestoneDueOn.Date } } } Describe 'Associating milestones with issues' { BeforeAll { $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit $milestone = $repo | New-GitHubMilestone -Title 'Milestone Title' $issue = $repo | New-GitHubIssue -Title 'Issue Title' } AfterAll { $repo | Remove-GitHubRepository -Force } Context 'Adding milestone to an issue' { It 'Should not have any open issues associated with it' { $issue.milestone | Should -BeNullOrEmpty $milestone.open_issues | Should -Be 0 } $issue = $issue | Set-GitHubIssue -Milestone $milestone.MilestoneNumber -PassThru $milestone = $milestone | Get-GitHubMilestone It "Should be associated to the milestone now" { $issue.milestone.number | Should -Be $milestone.MilestoneNumber $milestone.open_issues | Should -Be 1 } $issue = $issue | Set-GitHubIssue -Milestone 0 -PassThru $milestone = $milestone | Get-GitHubMilestone It 'Should no longer be associated to the milestone' { $issue.milestone | Should -BeNullOrEmpty $milestone.open_issues | Should -Be 0 } $issue = $issue | Set-GitHubIssue -Milestone $milestone.MilestoneNumber -PassThru $milestone = $milestone | Get-GitHubMilestone It "Should be associated to the milestone again" { $issue.milestone.number | Should -Be $milestone.MilestoneNumber $milestone.open_issues | Should -Be 1 } $milestone | Remove-GitHubMilestone -Force $issue = Get-GitHubIssue -Uri $repo.svn_url -Issue $issue.number It 'Should have removed the association when the milestone was deleted' { $issue.milestone | Should -BeNullOrEmpty } } } Describe 'Getting milestones' { BeforeAll { $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit $title = 'Milestone title' } AfterAll { $repo | Remove-GitHubRepository -Force } Context 'Getting a specific milestone' { BeforeAll { $closedMilestone = 'C' | New-GitHubMilestone -Uri $repo.RepositoryUrl -State 'Closed' $openMilestone = 'O' | New-GitHubMilestone -Uri $repo.RepositoryUrl -State 'Open' } AfterAll { $closedMilestone | Remove-GitHubMilestone -Force $openMilestone | Remove-GitHubMilestone -Force } $milestone = $closedMilestone $returned = Get-GitHubMilestone -Uri $repo.RepositoryUrl -Milestone $milestone.MilestoneNumber It 'Should get the right milestone as a parameter' { $returned.MilestoneId | Should -Be $milestone.MilestoneId } It 'Should have the expected type and additional properties' { $returned.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $returned.RepositoryUrl | Should -Be $repo.RepositoryUrl $returned.MilestoneId | Should -Be $returned.id $returned.MilestoneNumber | Should -Be $returned.number $returned.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } $milestone = $openMilestone $returned = $openMilestone | Get-GitHubMilestone It 'Should get the right milestone via the pipeline' { $returned.MilestoneId | Should -Be $milestone.MilestoneId } It 'Should have the expected type and additional properties' { $returned.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $returned.RepositoryUrl | Should -Be $repo.RepositoryUrl $returned.MilestoneId | Should -Be $returned.id $returned.MilestoneNumber | Should -Be $returned.number $returned.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } } Context 'Getting multiple milestones' { BeforeAll { $today = (Get-Date).ToUniversalTime() $nextWeek = (Get-Date).AddDays(7).ToUniversalTime() $numClosedMilestones = 3 $numOpenMilestones = 4 $closed = 1..$numClosedMilestones | ForEach-Object { $repo | New-GitHubMilestone -Title "Closed $_" -State 'Closed' -DueOn $today } $open = 1..$numOpenMilestones | ForEach-Object { $repo | New-GitHubMilestone -Title "Open $_" -State 'Open' -DueOn $nextWeek } } AfterAll { $closed | Remove-GitHubMilestone -Force $open | Remove-GitHubMilestone -Force } It 'Should have the expected number of milestones' { $milestones = @(Get-GitHubMilestone -Uri $repo.RepositoryUrl -State 'All') $milestones.Count | Should -Be ($numClosedMilestones + $numOpenMilestones) } It 'Should have the expected number of open milestones' { $milestones = @($repo | Get-GitHubMilestone -State 'Open') $milestones.Count | Should -Be $numOpenMilestones } It 'Should have the expected number of closed milestones' { $milestones = @(Get-GitHubMilestone -Uri $repo.RepositoryUrl -State 'Closed') $milestones.Count | Should -Be $numClosedMilestones } It 'Should sort them the right way | DueOn, Descending' { $milestones = @(Get-GitHubMilestone -Uri $repo.RepositoryUrl -State 'All' -Sort 'DueOn' -Direction 'Descending') $milestones[0].state | Should -Be 'Open' } It 'Should sort them the right way | DueOn, Ascending' { $milestones = @(Get-GitHubMilestone -Uri $repo.RepositoryUrl -State 'All' -Sort 'DueOn' -Direction 'Ascending') $milestones[0].state | Should -Be 'Closed' } } } Describe 'Editing a milestone' { BeforeAll { $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit $createParams = @{ 'Title' = 'Created Title' 'State' = 'Open' 'Description' = 'Created Description' 'DueOn' = (Get-Date).ToUniversalTime() } $editParams = @{ 'Title' = 'Edited Title' 'State' = 'Closed' 'Description' = 'Edited Description' 'DueOn' = (Get-Date).AddDays(7).ToUniversalTime() 'PassThru' = $true } } AfterAll { $repo | Remove-GitHubRepository -Force } Context 'Using the parameter' { BeforeAll { $milestone = New-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name @createParams $edited = Set-GitHubMilestone -Uri $milestone.RepositoryUrl -Milestone $milestone.MilestoneNumber @editParams } AfterAll { $milestone | Remove-GitHubMilestone -Force } It 'Should be editable via the parameter' { $edited.id | Should -Be $milestone.id $edited.title | Should -Be $editParams['Title'] $edited.state | Should -Be $editParams['State'] $edited.description | Should -Be $editParams['Description'] # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $edited.due_on).Date | Should -Be $editParams['DueOn'].Date } It 'Should have the expected type and additional properties' { $edited.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $edited.RepositoryUrl | Should -Be $repo.RepositoryUrl $edited.MilestoneId | Should -Be $milestone.id $edited.MilestoneNumber | Should -Be $milestone.number $edited.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } } Context 'Using the pipeline' { BeforeAll { $milestone = New-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name @createParams $edited = $milestone | Set-GitHubMilestone @editParams } AfterAll { $milestone | Remove-GitHubMilestone -Force } It 'Should be editable via the pipeline' { $edited.id | Should -Be $milestone.id $edited.title | Should -Be $editParams['Title'] $edited.state | Should -Be $editParams['State'] $edited.description | Should -Be $editParams['Description'] # GitHub drops the time that is attached to 'due_on', so it's only relevant # to compare the dates against each other. (Get-Date -Date $edited.due_on).Date | Should -Be $editParams['DueOn'].Date } It 'Should have the expected type and additional properties' { $edited.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone' $edited.RepositoryUrl | Should -Be $repo.RepositoryUrl $edited.MilestoneId | Should -Be $milestone.id $edited.MilestoneNumber | Should -Be $milestone.number $edited.creator.PSObject.TypeNames[0] | Should -Be 'GitHub.User' } } } Describe 'Deleting a milestone' { BeforeAll { $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit } AfterAll { $repo | Remove-GitHubRepository -Force } Context 'Using the parameter' { $milestone = $repo | New-GitHubMilestone -Title 'Milestone title' -State "Closed" -DueOn $defaultMilestoneDueOn Remove-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name -Milestone $milestone.MilestoneNumber -Force It 'Should be deleted' { { Get-GitHubMilestone -OwnerName $repo.owner.login -RepositoryName $repo.name -Milestone $milestone.MilestoneNumber } | Should -Throw } } Context 'Using the pipeline' { $milestone = $repo | New-GitHubMilestone -Title 'Milestone title' -State "Closed" -DueOn $defaultMilestoneDueOn $milestone | Remove-GitHubMilestone -Force It 'Should be deleted' { { $milestone | Get-GitHubMilestone } | Should -Throw } } } } 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 } } |