Tests/GitHubIssues.tests.ps1

# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

<#
.Synopsis
   Tests for GitHubIssues.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
{
    Describe 'Getting issues for a repository' {
        BeforeAll {
            $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
        }

        AfterAll {
            Remove-GitHubRepository -Uri $repo.RepositoryUrl -Confirm:$false
        }

        Context 'Getting all issues for a repository with parameters' {
            $currentIssues = @(Get-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name)

            $numIssues = 2
            1..$numIssues |
                ForEach-Object { New-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Title ([Guid]::NewGuid().Guid) } |
                Out-Null

            $issues = @(Get-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name)
            It 'Should return expected number of issues' {
                $issues.Count | Should -Be ($numIssues + $currentIssues.Count)
            }
        }

        Context 'Getting all issues for a repository with the repo on the pipeline' {
            $currentIssues = @($repo | Get-GitHubIssue)

            $numIssues = 2
            1..$numIssues |
                ForEach-Object { $repo | New-GitHubIssue -Title ([Guid]::NewGuid().Guid) } |
                Out-Null

            $issues = @($repo | Get-GitHubIssue)
            It 'Should return expected number of issues' {
                $issues.Count | Should -Be ($numIssues + $currentIssues.Count)
            }
        }

        Context 'Getting a specific issue with parameters' {
            $issue = New-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Title ([Guid]::NewGuid().Guid)

            $result = Get-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Issue $issue.number
            It 'Should be the expected Issue' {
                $result.id | Should -Be $issue.id
            }

            It 'Should have the expected property values' {
                $result.user.login | Should -Be $script:ownerName
                $result.labels | Should -BeNullOrEmpty
                $result.milestone | Should -BeNullOrEmpty
                $result.assignee | Should -BeNullOrEmpty
                $result.assignees | Should -BeNullOrEmpty
                $result.closed_by | Should -BeNullOrEmpty
                $result.repository | Should -BeNullOrEmpty
            }

            It 'Should have the expected type and additional properties' {
                $result.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $result.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $result.IssueId | Should -Be $result.id
                $result.IssueNumber | Should -Be $result.number
                $result.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
            }
        }

        Context 'Getting a specific issue with the repo on the pipeline' {
            $issue = $repo | New-GitHubIssue -Title ([Guid]::NewGuid().Guid)

            $result = $repo | Get-GitHubIssue -Issue $issue.number
            It 'Should be the expected Issue' {
                $result.id | Should -Be $issue.id
            }

            It 'Should have the expected property values' {
                $result.user.login | Should -Be $script:ownerName
                $result.labels | Should -BeNullOrEmpty
                $result.milestone | Should -BeNullOrEmpty
                $result.assignee | Should -BeNullOrEmpty
                $result.assignees | Should -BeNullOrEmpty
                $result.closed_by | Should -BeNullOrEmpty
                $result.repository | Should -BeNullOrEmpty
            }

            It 'Should have the expected type and additional properties' {
                $result.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $result.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $result.IssueId | Should -Be $result.id
                $result.IssueNumber | Should -Be $result.number
                $result.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
            }
        }

        Context 'Getting a specific issue with the issue on the pipeline' {
            $issue = $repo | New-GitHubIssue -Title ([Guid]::NewGuid().Guid)

            $result = $issue | Get-GitHubIssue -Issue $issue.number
            It 'Should be the expected Issue' {
                $result.id | Should -Be $issue.id
            }

            It 'Should have the expected property values' {
                $result.user.login | Should -Be $script:ownerName
                $result.labels | Should -BeNullOrEmpty
                $result.milestone | Should -BeNullOrEmpty
                $result.assignee | Should -BeNullOrEmpty
                $result.assignees | Should -BeNullOrEmpty
                $result.closed_by | Should -BeNullOrEmpty
                $result.repository | Should -BeNullOrEmpty
            }

            It 'Should have the expected type and additional properties' {
                $result.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $result.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $result.IssueId | Should -Be $result.id
                $result.IssueNumber | Should -Be $result.number
                $result.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
            }
        }

        Context 'When issues are retrieved with a specific MediaTypes' {
            $newIssue = New-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Title ([guid]::NewGuid()) -Body ([Guid]::NewGuid())

            $issues = @(Get-GitHubIssue -Uri $repo.svn_url -Issue $newIssue.number -MediaType 'Html')
            It 'Should return an issue with body_html' {
                $issues[0].body_html | Should -Not -Be $null
            }
        }
    }

    Describe 'Date-specific Issue tests' {
        BeforeAll {
            $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
        }

        AfterAll {
            Remove-GitHubRepository -Uri $repo.RepositoryUrl -Confirm:$false
        }

        Context 'Date specific scenarios' {
            $existingIssues = @($repo | Get-GitHubIssue -State All)

            $newIssues = @()
            for ($i = 0; $i -lt 4; $i++)
            {
                $newIssues += New-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Title ([Guid]::NewGuid().Guid)
            }

            $newIssues[0] = Set-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Issue $newIssues[0].number -State Closed -PassThru
            $newIssues[-1] = Set-GitHubIssue -OwnerName $script:ownerName -RepositoryName $repo.name -Issue $newIssues[-1].number -State Closed -PassThru

            $existingOpenIssues = @($existingIssues | Where-Object { $_.state -eq 'open' })
            $newOpenIssues = @($newIssues | Where-Object { $_.state -eq 'open' })
            $issues = @($repo | Get-GitHubIssue)
            It 'Should return only open issues' {
                $issues.Count | Should -Be ($newOpenIssues.Count + $existingOpenIssues.Count)
            }

            $issues = @($repo | Get-GitHubIssue -State All)
            It 'Should return all issues' {
                $issues.Count | Should -Be ($newIssues.Count + $existingIssues.Count)
            }

            $createdOnOrAfterDate = Get-Date -Date $newIssues[0].created_at
            $createdOnOrBeforeDate = Get-Date -Date $newIssues[2].created_at
            $issues = @(($repo | Get-GitHubIssue) |
                Where-Object { ($_.created_at -ge $createdOnOrAfterDate) -and ($_.created_at -le $createdOnOrBeforeDate) })

            It 'Smart object date conversion works for comparing dates' {
                $issues.Count | Should -Be 2
            }

            $createdDate = Get-Date -Date $newIssues[1].created_at
            $issues = @(Get-GitHubIssue -Uri $repo.svn_url -State All |
                Where-Object { ($_.created_at -ge $createdDate) -and ($_.state -eq 'closed') })

            It 'Able to filter based on date and state' {
                $issues.Count | Should -Be 1
            }
        }
    }
    Describe 'Creating issues' {
        BeforeAll {
            $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
            $milestone = $repo | New-GitHubMilestone -Title ([Guid]::NewGuid().Guid)
        }

        AfterAll {
            Remove-GitHubRepository -Uri $repo.RepositoryUrl -Confirm:$false
        }

        Context 'Creating an Issue with parameters' {
            $params = @{
                'OwnerName' = $script:ownerName
                'RepositoryName' = $repo.name
                'Title' = '-issue title-'
                'Body' = '-issue body-'
                'Assignee' = $script:ownerName
                'Milestone' = $milestone.number
                'Label' = 'bug'
                'MediaType' = 'Raw'
            }

            $issue = New-GitHubIssue @params

            It 'Should have the expected property values' {
                $issue.title | Should -Be $params.Title
                $issue.body | Should -Be $params.Body
                $issue.assignee.login | Should -Be $params.Assignee
                $issue.assignees.Count | Should -Be 1
                $issue.assignees[0].login | Should -Be $params.Assignee
                $issue.milestone.number | Should -Be $params.Milestone
                $issue.labels.Count | Should -Be 1
                $issue.labels[0].name | Should -Contain $params.Label
            }

            It 'Should have the expected type and additional properties' {
                $issue.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $issue.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $issue.IssueId | Should -Be $issue.id
                $issue.IssueNumber | Should -Be $issue.number
                $issue.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $issue.assignee.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $issue.assignees[0].PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $issue.milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone'
                $issue.labels[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Label'
            }
        }

        Context 'Creating an Issue with the repo on the pipeline' {
            $params = @{
                'Title' = '-issue title-'
                'Body' = '-issue body-'
                'Assignee' = $script:ownerName
                'Milestone' = $milestone.number
                'Label' = 'bug'
                'MediaType' = 'Raw'
            }

            $issue = $repo | New-GitHubIssue @params

            It 'Should have the expected property values' {
                $issue.title | Should -Be $params.Title
                $issue.body | Should -Be $params.Body
                $issue.assignee.login | Should -Be $params.Assignee
                $issue.assignees.Count | Should -Be 1
                $issue.assignees[0].login | Should -Be $params.Assignee
                $issue.milestone.number | Should -Be $params.Milestone
                $issue.labels.Count | Should -Be 1
                $issue.labels[0].name | Should -Contain $params.Label
            }

            It 'Should have the expected type and additional properties' {
                $issue.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $issue.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $issue.IssueId | Should -Be $issue.id
                $issue.IssueNumber | Should -Be $issue.number
                $issue.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $issue.assignee.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $issue.assignees[0].PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $issue.milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone'
                $issue.labels[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Label'
            }
        }
    }

    Describe 'Updating issues' {
        BeforeAll {
            $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
            $milestone = $repo | New-GitHubMilestone -Title ([Guid]::NewGuid().Guid)
            $title = 'issue title'
        }

        AfterAll {
            Remove-GitHubRepository -Uri $repo.RepositoryUrl -Confirm:$false
        }

        Context 'Updating an Issue with parameters' {
            $issue = New-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Title $title
            It 'Should have the expected property values' {
                $issue.title | Should -Be $title
                $issue.body | Should -BeNullOrEmpty
                $issue.assignee.login | Should -BeNullOrEmpty
                $issue.assignees | Should -BeNullOrEmpty
                $issue.milestone | Should -BeNullOrEmpty
                $issue.labels | Should -BeNullOrEmpty
            }

            $params = @{
                'OwnerName' = $script:ownerName
                'RepositoryName' = $repo.name
                'Issue' = $issue.number
                'Title' = '-new title-'
                'Body' = '-new body-'
                'Assignee' = $script:ownerName
                'Milestone' = $milestone.number
                'Label' = 'bug'
                'MediaType' = 'Raw'
            }

            $updated = Set-GitHubIssue @params -PassThru
            It 'Should have the expected property values' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.title | Should -Be $params.Title
                $updated.body | Should -Be $params.Body
                $updated.assignee.login | Should -Be $params.Assignee
                $updated.assignees.Count | Should -Be 1
                $updated.assignees[0].login | Should -Be $params.Assignee
                $updated.milestone.number | Should -Be $params.Milestone
                $updated.labels.Count | Should -Be 1
                $updated.labels[0].name | Should -Contain $params.Label
            }

            It 'Should have the expected type and additional properties' {
                $updated.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $updated.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $updated.IssueId | Should -Be $updated.id
                $updated.IssueNumber | Should -Be $updated.number
                $updated.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.assignee.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.assignees[0].PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone'
                $updated.labels[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Label'
            }
        }

        Context 'Updating an Issue with the repo on the pipeline' {
            $issue = New-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Title $title
            It 'Should have the expected property values' {
                $issue.title | Should -Be $title
                $issue.body | Should -BeNullOrEmpty
                $issue.assignee.login | Should -BeNullOrEmpty
                $issue.assignees | Should -BeNullOrEmpty
                $issue.milestone | Should -BeNullOrEmpty
                $issue.labels | Should -BeNullOrEmpty
            }

            $params = @{
                'Issue' = $issue.number
                'Title' = '-new title-'
                'Body' = '-new body-'
                'Assignee' = $script:ownerName
                'Milestone' = $milestone.number
                'Label' = 'bug'
                'MediaType' = 'Raw'
            }

            $updated = $repo | Set-GitHubIssue @params -PassThru
            It 'Should have the expected property values' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.title | Should -Be $params.Title
                $updated.body | Should -Be $params.Body
                $updated.assignee.login | Should -Be $params.Assignee
                $updated.assignees.Count | Should -Be 1
                $updated.assignees[0].login | Should -Be $params.Assignee
                $updated.milestone.number | Should -Be $params.Milestone
                $updated.labels.Count | Should -Be 1
                $updated.labels[0].name | Should -Contain $params.Label
            }

            It 'Should have the expected type and additional properties' {
                $updated.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $updated.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $updated.IssueId | Should -Be $updated.id
                $updated.IssueNumber | Should -Be $updated.number
                $updated.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.assignee.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.assignees[0].PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone'
                $updated.labels[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Label'
            }
        }

        Context 'Updating an Issue with the issue on the pipeline' {
            $issue = New-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Title $title
            It 'Should have the expected property values' {
                $issue.title | Should -Be $title
                $issue.body | Should -BeNullOrEmpty
                $issue.assignee.login | Should -BeNullOrEmpty
                $issue.assignees | Should -BeNullOrEmpty
                $issue.milestone | Should -BeNullOrEmpty
                $issue.labels | Should -BeNullOrEmpty
            }

            $params = @{
                'Title' = '-new title-'
                'Body' = '-new body-'
                'Assignee' = $script:ownerName
                'Milestone' = $milestone.number
                'Label' = 'bug'
                'MediaType' = 'Raw'
            }

            $updated = $issue | Set-GitHubIssue @params -PassThru
            It 'Should have the expected property values' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.title | Should -Be $params.Title
                $updated.body | Should -Be $params.Body
                $updated.assignee.login | Should -Be $params.Assignee
                $updated.assignees.Count | Should -Be 1
                $updated.assignees[0].login | Should -Be $params.Assignee
                $updated.milestone.number | Should -Be $params.Milestone
                $updated.labels.Count | Should -Be 1
                $updated.labels[0].name | Should -Contain $params.Label
            }

            It 'Should have the expected type and additional properties' {
                $updated.PSObject.TypeNames[0] | Should -Be 'GitHub.Issue'
                $updated.RepositoryUrl | Should -Be $repo.RepositoryUrl
                $updated.IssueId | Should -Be $updated.id
                $updated.IssueNumber | Should -Be $updated.number
                $updated.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.assignee.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.assignees[0].PSObject.TypeNames[0] | Should -Be 'GitHub.User'
                $updated.milestone.PSObject.TypeNames[0] | Should -Be 'GitHub.Milestone'
                $updated.labels[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Label'
            }
        }
    }

    Describe 'Locking and unlocking issues' {
        BeforeAll {
            $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
        }

        AfterAll {
            Remove-GitHubRepository -Uri $repo.RepositoryUrl -Confirm:$false
        }

        Context 'Locking and unlocking an Issue with parameters' {
            $issue = New-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Title ([Guid]::NewGuid().Guid)
            It 'Should be unlocked' {
                $issue.locked | Should -BeFalse
                $issue.active_lock_reason | Should -BeNullOrEmpty
            }

            $reason = 'Resolved'
            Lock-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number -Reason $reason
            $updated = Get-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number
            It 'Should be locked' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.locked | Should -BeTrue
                $updated.active_lock_reason | Should -Be $reason
            }

            Unlock-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number
            $updated = Get-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number
            It 'Should be unlocked again' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.locked | Should -BeFalse
                $updated.active_lock_reason | Should -BeNullOrEmpty
            }
        }

        Context 'Locking and unlocking an Issue with the repo on the pipeline' {
            $issue = $repo | New-GitHubIssue -Title ([Guid]::NewGuid().Guid)
            It 'Should be unlocked' {
                $issue.locked | Should -BeFalse
                $issue.active_lock_reason | Should -BeNullOrEmpty
            }

            $reason = 'Resolved'
            $repo | Lock-GitHubIssue -Issue $issue.number -Reason $reason
            $updated = $repo | Get-GitHubIssue -Issue $issue.number
            It 'Should be locked' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.locked | Should -BeTrue
                $updated.active_lock_reason | Should -Be $reason
            }

            $repo | Unlock-GitHubIssue -Issue $issue.number
            $updated = $repo | Get-GitHubIssue -Issue $issue.number
            It 'Should be unlocked again' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.locked | Should -BeFalse
                $updated.active_lock_reason | Should -BeNullOrEmpty
            }
        }

        Context 'Locking and unlocking an Issue with the issue on the pipeline' {
            $issue = New-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Title ([Guid]::NewGuid().Guid)
            It 'Should be unlocked' {
                $issue.locked | Should -BeFalse
                $issue.active_lock_reason | Should -BeNullOrEmpty
            }

            $reason = 'Resolved'
            $issue | Lock-GitHubIssue -Reason $reason
            $updated = $issue | Get-GitHubIssue
            It 'Should be locked' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.locked | Should -BeTrue
                $updated.active_lock_reason | Should -Be $reason
            }

            $issue | Unlock-GitHubIssue
            $updated = $issue | Get-GitHubIssue
            It 'Should be unlocked again' {
                $updated.id | Should -Be $issue.id
                $updated.number | Should -Be $issue.number
                $updated.locked | Should -BeFalse
                $updated.active_lock_reason | Should -BeNullOrEmpty
            }
        }
    }

    Describe 'Issue Timeline' {
        BeforeAll {
            $repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
        }

        AfterAll {
            Remove-GitHubRepository -Uri $repo.RepositoryUrl -Confirm:$false
        }

        Context 'Getting the Issue timeline with parameters' {
            $issue = New-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Title ([Guid]::NewGuid().Guid)
            $timeline = @(Get-GitHubIssueTimeline -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number)
            It 'Should have no events so far' {
                $timeline.Count | Should -Be 0
            }

            Lock-GitHubIssue -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number

            $timeline = @(Get-GitHubIssueTimeline -OwnerName $script:OwnerName -RepositoryName $repo.name -Issue $issue.number)
            It 'Should have an event now' {
                $timeline.Count | Should -Be 1
                $timeline[0].event | Should -Be 'locked'
            }

            It 'Should have the expected type and additional properties' {
                $timeline[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Event'
                $timeline[0].RepositoryUrl | Should -Be $repo.RepositoryUrl
                $timeline[0].EventId | Should -Be $timeline[0].id
                $timeline[0].actor.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
            }
        }

        Context 'Getting the Issue timeline with the repo on the pipeline' {
            $issue = $repo | New-GitHubIssue -Title ([Guid]::NewGuid().Guid)
            $timeline = @($repo | Get-GitHubIssueTimeline -Issue $issue.number)
            It 'Should have no events so far' {
                $timeline.Count | Should -Be 0
            }

            $repo | Lock-GitHubIssue -Issue $issue.number
            $timeline = @($repo | Get-GitHubIssueTimeline -Issue $issue.number)
            It 'Should have an event now' {
                $timeline.Count | Should -Be 1
                $timeline[0].event | Should -Be 'locked'
            }

            It 'Should have the expected type and additional properties' {
                $timeline[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Event'
                $timeline[0].RepositoryUrl | Should -Be $repo.RepositoryUrl
                $timeline[0].EventId | Should -Be $timeline[0].id
                $timeline[0].actor.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
            }
        }

        Context 'Getting the Issue timeline with the issue on the pipeline' {
            $issue = $repo | New-GitHubIssue -Title ([Guid]::NewGuid().Guid)
            $timeline = @($issue | Get-GitHubIssueTimeline)
            It 'Should have no events so far' {
                $timeline.Count | Should -Be 0
            }

            $issue | Lock-GitHubIssue
            $timeline = @($issue | Get-GitHubIssueTimeline)
            It 'Should have an event now' {
                $timeline.Count | Should -Be 1
                $timeline[0].event | Should -Be 'locked'
            }

            It 'Should have the expected type and additional properties' {
                $timeline[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Event'
                $timeline[0].RepositoryUrl | Should -Be $repo.RepositoryUrl
                $timeline[0].EventId | Should -Be $timeline[0].id
                $timeline[0].actor.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
            }
        }
    }
}
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
    }
}