tests/PSTS.release.Tests.ps1

if ($PSScriptRoot -eq $null) {
    $PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
}

. "$PSScriptRoot\helper.ps1"

describe 'Get-PSTSReleaseDefinition' {

    # Arrange
    $data = @([ReleaseDefinition]::new(); [ReleaseDefinition]::new())

    $expectedResult = New-Object -TypeName "PSObject"


    $expectedResult | Add-Member -MemberType NoteProperty "Count" -Value $data.Count
    $expectedResult | Add-Member -MemberType NoteProperty "value" -Value $data

    arrange -result $expectedResult

    # Act
    $result = Get-PSTSReleaseDefinition -project fakeProject -releaseId fakeId

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }

    it "should return $($expectedResult.value)" {
        $result.Count | should -Be $expectedResult.value.Count
    }
}


describe 'Get-PSTSReleaseDefinitionTask' {

    # Arrange
    $data = @([ReleaseDefinitionTask]::new(); [ReleaseDefinitionTask]::new())

    $expectedResult = New-Object -TypeName "PSObject"


    $expectedResult | Add-Member -MemberType NoteProperty "Count" -Value $data.Count
    $expectedResult | Add-Member -MemberType NoteProperty "value" -Value $data

    arrange -result $expectedResult

    # Act
    $result = Get-PSTSReleaseDefinitionTask -id fakeId

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }

    it "should return $($expectedResult.value)" {
        $result.Count | should -Be $expectedResult.value.Count
    }
}


describe 'Get-PSTSReleaseDefinitionTaskTemplate' {

    Mock -Verifiable -ModuleName PSTS Get-PSTSReleaseDefinitionTask -MockWith {
        param($id)

        $rdi = New-Object -TypeName PSObject
        $rdi | Add-Member -NotePropertyName "options" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "name" -NotePropertyValue "test"
        $rdi | Add-Member -NotePropertyName "label" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "defaultValue" -NotePropertyValue "value"
        $rdi | Add-Member -NotePropertyName "required" -NotePropertyValue $false
        $rdi | Add-Member -NotePropertyName "type" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "helpMarkDown" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "visibleRule" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "groupName" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "properties" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "aliases" -NotePropertyValue $null
        $rdi | Add-Member -NotePropertyName "validation" -NotePropertyValue $null

        $version = New-Object -TypeName PSObject
        $version | Add-Member -NotePropertyName "Major" -NotePropertyValue 2
        $version | Add-Member -NotePropertyName "Minor" -NotePropertyValue 3
        $version | Add-Member -NotePropertyName "Patch" -NotePropertyValue 3
        $version | Add-Member -NotePropertyName "isTest" -NotePropertyValue $false

        $obj = [ReleaseDefinitionTask]::new()
        $obj.author = "fakeauthor"
        $obj.version = $version
        $obj.inputs +=$rdi

        return $obj
    }

    # Act
    [hashtable] $inputs = [hashtable]::new()
    $inputs.Add("test", "fakevalue") # |Out-Null
    $result = Get-PSTSReleaseDefinitionTaskTemplate -taskId "fakeTaskId" -name "fakeName" -inputs $inputs

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }

    it "should return fakeTaskId" {
        $result.taskId | should -Be "fakeTaskId"
    }

    it "should return 2.*" {
        $result.version | should -Be "2.*"
    }
}


describe 'Add-PSTSReleaseDefinition-byObject' {

    # Arrange
    $expectedResult = [ReleaseDefinition]::new()
    $expectedResult.name = "fakeRelease"

    arrange -result $expectedResult

    # Act
    $result = Add-PSTSReleaseDefinition -project fakeProject -releaseDefinition $expectedResult

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }

    it "should return $($expectedResult.value)" {
        $result.name | should -Be $expectedResult.name
    }
}

describe 'Add-PSTSReleaseDefinition-byFile' {

    # Arrange
    $expectedResult = [ReleaseDefinition]::new()
    $expectedResult.name = "fakeRelease"

    arrange -result $expectedResult

    # Act
    $file = "fakepath"
    $result = Add-PSTSReleaseDefinition -project fakeProject -inFile $file

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }

    it "should return $($expectedResult.value)" {
        $result.name | should -Be $expectedResult.name
    }
}


describe 'Add-PSTSReleaseDefinitionProperty' {

    # Arrange
    $expectedResult = [ReleaseDefinition]::new()

    arrange -result $expectedResult

    # Act
    $file = "fakepath"
    $result = Add-PSTSReleaseDefinitionProperty -releaseDefinition $expectedResult -path "fakePath" -name "fakeName"

    #Assert

    it "should return fakePath and fakeName" {
        $result.name | should -Be "fakeName"
         $result.path | should -Be "fakePath"
    }
}

describe 'Add-PSTSReleaseDefinitionTask' {

    # Arrange
    $expectedResult = Get-PSTSReleaseDefinition -inFile ".\assets\releaseDefinition.json"

    arrange -result $expectedResult

    # Act
    [ReleaseDefinitionTaskTemplate]$task = [ReleaseDefinitionTaskTemplate]::new()
    $task.name = "fakeTask"

    $result = Add-PSTSReleaseDefinitionTask -releaseDefinition $expectedResult -position 1 -task $task -envId 0

    #Assert
    it "should return $($task.name)" {
        $result.environments.deployPhases.workflowTasks.Item(1).Name | should -Be $task.name
    }
}

describe 'Add-PSTSReleaseDefinitionVariable' {

    # Arrange
    $expectedResult = Get-PSTSReleaseDefinition -inFile ".\assets\releaseDefinition.json"

    arrange -result $expectedResult

    # Act
    $vars = @{"appname"="test"; "testvar"="testVal"}

    $result = Add-PSTSReleaseDefinitionVariable -releaseDefinition $expectedResult -variables $vars -append $false

    #Assert
    it "should return test and testval" {
        $result.Variables.("appname").value | should -Be "test"
        $result.Variables.("testvar").value | should -Be "testVal"
    }

    $expectedResult = Get-PSTSReleaseDefinition -inFile ".\assets\releaseDefinition.json"
    $result = Add-PSTSReleaseDefinitionVariable -releaseDefinition $expectedResult -variables $vars -append $true

    #Assert
    it "should return test and testVal" {
        $result.Variables.("appname").value | should -Be "tetris test"
        $result.Variables.("testvar").value | should -Be "testVal"
    }

}

describe 'Export-PSTSReleaseDefinition' {

    # Arrange
    $data = Get-PSTSReleaseDefinition -inFile ".\assets\releaseDefinition.json"

    $expectedResult = New-Object -TypeName "PSObject"


    $expectedResult | Add-Member -MemberType NoteProperty "Count" -Value 1
    $expectedResult | Add-Member -MemberType NoteProperty "value" -Value @($data)

    arrange -result $expectedResult

    # Act
    Export-PSTSReleaseDefinition -project fakeProject -releaseId 1 -outFile ".\assets\out.json"

    it "should return $true" {
       Compare-Object -ReferenceObject $(Get-Content ".\assets\out.json") -DifferenceObject  $(Get-Content ".\assets\releaseDefinition.json")
    }
}

describe 'Add-PSTSReleaseDefinitionTrigger' {

    # Arrange
    $data = Get-PSTSReleaseDefinition -inFile ".\assets\releaseDefinition.json"

    # Act
    $result = Add-PSTSReleaseDefinitionTrigger -releaseDefinition $data -environment "dev" -artifactAlias "fakeArtifact" -tag "v*"

    it "should return $true" {
        $result.triggers.Item(0).sourceBranch -eq "dev" -and `
        $result.triggers.Item(0).triggerConditions.Item(0).tags.Count -eq 1 -and `
        $result.triggers.Item(0).artifactAlias -eq "fakeArtifact"


    }
}


describe 'Add-PSTSReleaseDefinitionArtefact' {

    # Arrange
    $data = Get-PSTSReleaseDefinition -inFile ".\assets\releaseDefinition.json"


 Mock -Verifiable -ModuleName PSTS Get-PSTSProject -MockWith {

        $obj = [Project]::new()
        $obj.id ="fakePrId"
        $obj.name = "fakePrName"
        return $obj
    }

 Mock -Verifiable -ModuleName PSTS Get-PSTSBuildDefinition -MockWith {

        $obj = [BuildDefinition]::new()
        $obj.id =123
        $obj.name = "fakeBuildname"
        return $obj
    }



    # Act
    $result = Add-PSTSReleaseDefinitionArtefact -project "fakeproject" -buildName "fakebuild" -aliasName "fakeAlias" -definition $data

    it "should return $true" {
        $result.artifacts.Item(0).sourceBranch -eq "dev" -and `
        $result.artifacts.Item(0).definitionReference.project.id -eq "fakePrId" -and `
        $result.artifacts.Item(0).definitionReference.project.name -eq "fakePrName" -and `
        $result.artifacts.Item(0).definitionReference.definition.name -eq "fakeBuildName" -and `
        $result.artifacts.Item(0).definitionReference.definition.Id -eq 123 -and `
        $result.artifacts.Item(0).definitionReference.definition.name -eq "fakeBuildname"

    }
}


describe 'Add-PSTSReleaseDefinitionProcessParameterInput' {

    # Arrange
    
    $input = [ProcessParameterInput]::new()
    $processParameters = new-Object -TypeName "PSObject"
    $processParameters | Add-Member -MemberType NoteProperty "inputs" -Value  $input
    $processParameters.inputs=@($input)

    $releaseDefinition = [ReleaseDefinition]::new()
    $releaseDefinition.environments = new-Object -TypeName "PSObject"
    $releaseDefinition.environments | Add-Member -MemberType NoteProperty "processParameters" -Value  $processParameters
  
    # Act
    $type="connectedService:AzureRM"
             
    $result = Add-PSTSReleaseDefinitionProcessParameterInput -type $type -serviceConnectionId "fakeserviceConnectionId" -releaseDefinition $releaseDefinition
             
    #Assert
    it "should return $true" {
        $result.environments.processParameters.inputs.label  -eq "Azure subscription" -and `
        $result.environments.processParameters.inputs.name -eq "ConnectedServiceName" -and `
        $result.environments.processParameters.inputs.Required -eq $true
                
    }

    # Act
    $type="pickList"
    $result = Add-PSTSReleaseDefinitionProcessParameterInput -type $type -webappName "fakewebappName" -releaseDefinition $releaseDefinition
             
    #Assert
    it "should return $true" {
        $result.environments.processParameters.inputs.label  -eq "App service name" -and `
        $result.environments.processParameters.inputs.name -eq "WebAppName" -and `
        $result.environments.processParameters.inputs.Required -eq $true       
    }
        
}

describe 'Update-PSTSReleaseDefinition' {

    # Arrange
    Mock -Verifiable Update-PSTSReleaseDefinition
    # Act
    Update-PSTSReleaseDefinition -project fakeProject -releaseDefinition fakeRelease

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }
}

describe 'Update-PSTSReleaseDefinitionDeployInput' {

    # Arrange
    $properties = @{
                     agentSpecification = [AgentSpecification]::new()
                     artifactsDownloadInput = [ArtifactsDownloadInput]::new()
                   }

    $DeploymentInput = New-Object psobject -Property $properties; $DeploymentInput
    $DeployPhases = new-Object -TypeName "PSObject"
    $DeployPhases | Add-Member -MemberType NoteProperty "DeploymentInput" -Value  $DeploymentInput

    $releaseDefinition = [ReleaseDefinition]::new()
    $releaseDefinition.environments = new-Object -TypeName "PSObject"
    $releaseDefinition.environments | Add-Member -MemberType NoteProperty "DeployPhases" -Value  $DeployPhases
  
    # Act
    $result = Update-PSTSReleaseDefinitionDeployInput -agentName fakeAgentName -artefactAliasName fakeArtefactAliasName -releaseDefinition $releaseDefinition

    #Assert
    It "Uses the mock" {
        Assert-VerifiableMock
    }

    it "should return $($result)" {
        $result.environments.DeployPhases.deploymentInput.agentSpecification.identifier | should -Be fakeAgentName
        $result.environments.DeployPhases.deploymentInput.artifactsDownloadInput.downloadInputs |  should -HaveCount 1
    }
}