Tests/PSMultiLog.tests.ps1

$ParentPath = Split-Path -Path (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) -Parent
Import-Module -Name (Join-Path -Path $ParentPath -ChildPath "PSMultiLog.psm1")


#-------------------------------------------------------------------------------
# File Logging
#-------------------------------------------------------------------------------
Describe Start-FileLog {
    throw "TODO"
}

Describe Stop-FileLog {
    throw "TODO"
}

Describe Write-FileLog {
    throw "TODO"
}

#-------------------------------------------------------------------------------
# E-mail Logging
#-------------------------------------------------------------------------------
Describe Start-EmailLog {
    InModuleScope PSMultiLog {
        It "Enables E-mail Logging" {
            $Script:Settings["Email"].Enabled | Should Be $false
            Start-EmailLog
            $Script:Settings["Email"].Enabled | Should Be $true
            Stop-EmailLog
        }

        It "Clears the entry cache" {
            $Script:LogEntries.Count | Should Be 0
            Start-EmailLog
            Write-Log -EntryType Information -Message "Test"
            Stop-EmailLog -RetainEntryCache
            $Script:LogEntries.Count | Should Be 1
            Start-EmailLog -ClearEntryCache
            $Script:LogEntries.Count | Should Be 0
            Stop-EmailLog
        }
    }
}

Describe Stop-EmailLog {
    InModuleScope PSMultiLog {
        It "Disables Email Logging" {
            Start-EmailLog
            $Script:Settings["Email"].Enabled | Should Be $true
            Stop-EmailLog
            $Script:Settings["Email"].Enabled | Should Be $false

        }

        It "Clears the entry cache" {
            Start-EmailLog -ClearEntryCache
            Write-Log -EntryType Information -Message "Test"
            $Script:LogEntries.Count | Should Be 1

            Stop-EmailLog
            $Script:LogEntries.Count | Should Be 0
        }

        It "Retains the entry cache" {
            Start-EmailLog -ClearEntryCache
            Write-Log -EntryType Information -Message "Test"
            $Script:LogEntries.Count | Should Be 1

            Stop-EmailLog -RetainEntryCache
            $Script:LogEntries.Count | Should Be 1

            # Just to make sure the entry cache is cleared.
            Stop-EmailLog
        }
    }
}

Describe Send-EmailLog {
    throw "TODO"
}

Describe Write-EmailLog {
    InModuleScope PSMultiLog {
        It "Writes to the entry cache" {
            Start-EmailLog -ClearEntryCache
            $Script:LogEntries.Count | Should Be 0

            Write-EmailLog -Entry "Dummy Entry"
            $Script:LogEntries.Count | Should Be 1
        }
    }
}

#-------------------------------------------------------------------------------
# Event Log Logging
#-------------------------------------------------------------------------------
Describe Start-EventLogLog {
    throw "TODO"
}

Describe Stop-EventLogLog {
    throw "TODO"
}

Describe Write-EventLogLog {
    throw "TODO"
}

#-------------------------------------------------------------------------------
# Host Logging
#-------------------------------------------------------------------------------
Describe Start-HostLog {
    InModuleScope PSMultiLog {
        It "Enables Host Logging" {
            $Script:Settings["Host"].Enabled | Should Be $false
            Start-HostLog
            $Script:Settings["Host"].Enabled | Should Be $true
        }

        It "Sets the log level" {
            Start-HostLog
            $Script:Settings["Host"].LogLevel | Should Be 0

            Start-HostLog -LogLevel "Error"
            $Script:Settings["Host"].LogLevel | Should Be 0

            Start-HostLog -LogLevel "Warning"
            $Script:Settings["Host"].LogLevel | Should Be 1

            Start-HostLog -LogLevel "Information"
            $Script:Settings["Host"].LogLevel | Should Be 2
        }
    }
}

Describe Stop-HostLog {
    InModuleScope PSMultiLog {
        It "Disables Host Logging" {
            Start-HostLog
            $Script:Settings["Host"].Enabled | Should Be $true

            Stop-HostLog
            $Script:Settings["Host"].Enabled | Should Be $false
        }
    }
}

Describe Write-HostLog {
    InModuleScope PSMultiLog {
        $Timestamp = Get-Date
        $TimestampString = $Timestamp.ToString("u")
        $Entry = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Information"
            LogLevel = 2
            Message = "Hello, World!"
            Exception = $null
            EventId = 1000
        }

        It "Writes to the host" {
            Mock Write-Host {}
            Write-HostLog -Entry $Entry
            Assert-MockCalled Write-Host 3
        }
    }
}

#-------------------------------------------------------------------------------
# PassThru Logging
#-------------------------------------------------------------------------------
Describe Start-PassThruLog {
    InModuleScope PSMultiLog {
        It "Enables PassThru Logging" {
            $Script:Settings["PassThru"].Enabled | Should Be $false
            Start-PassThruLog
            $Script:Settings["PassThru"].Enabled | Should Be $true
        }

        It "Sets the log level" {
            Start-PassThruLog
            $Script:Settings["PassThru"].LogLevel | Should Be 0

            Start-PassThruLog -LogLevel "Error"
            $Script:Settings["PassThru"].LogLevel | Should Be 0

            Start-PassThruLog -LogLevel "Warning"
            $Script:Settings["PassThru"].LogLevel | Should Be 1

            Start-PassThruLog -LogLevel "Information"
            $Script:Settings["PassThru"].LogLevel | Should Be 2
        }
    }
}

Describe Stop-PassThruLog {
    InModuleScope PSMultiLog {
        It "Disables PassThru Logging" {
            Start-PassThruLog
            $Script:Settings["PassThru"].Enabled | Should Be $true

            Stop-PassThruLog
            $Script:Settings["PassThru"].Enabled | Should Be $false
        }
    }
}

Describe Write-PassThruLog {
    InModuleScope PSMultiLog {
        $Timestamp = Get-Date
        $TimestampString = $Timestamp.ToString("u")
        $InfoEntry = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Information"
            LogLevel = 2
            Message = "Hello, World!"
            Exception = $null
            EventId = 1000
        }

        $WarningEntry = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Warning"
            LogLevel = 1
            Message = "This is a warning."
            Exception = $null
            EventId = 1000
        }

        $ErrorEntry = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Error"
            LogLevel = 0
            Message = "This is an error."
            Exception = New-Object -TypeName Exception -ArgumentList "Exception message."
            EventId = 1000
        }

        $ErrorEntryNoException = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Error"
            LogLevel = 0
            Message = "This is an error."
            Exception = $null
            EventId = 1000
        }

        It "Writes to the Verbose stream" {
            Mock Write-Verbose {}
            Write-PassThruLog -Entry $InfoEntry
            Assert-MockCalled Write-Verbose 1
        }

        It "Writes to the Warning stream" {
            Mock Write-Warning {}
            Write-PassThruLog -Entry $WarningEntry
            Assert-MockCalled Write-Warning 1
        }

        It "Writes to the Error stream" {
            Mock Write-Error {}
            Write-PassThruLog -Entry $ErrorEntry
            Assert-MockCalled Write-Error 1
        }

        It "Writes to the Error stream when no Exception is included" {
            Mock Write-Error {}
            Write-PassThruLog -Entry $ErrorEntryNoException
            Assert-MockCalled Write-Error 1
        }
    }
}

#-------------------------------------------------------------------------------
# Write-Log, the main event
#-------------------------------------------------------------------------------
Describe Write-Log {
    throw "TODO"
}

#-------------------------------------------------------------------------------
# Internal Functions
#-------------------------------------------------------------------------------
Describe Get-LogLevel {
    InModuleScope PSMultiLog {
        It "Returns expected values" {
            Get-LogLevel -EntryType "Information" | Should Be 2
            Get-LogLevel -EntryType "Warning" | Should Be 1
            Get-LogLevel -EntryType "Error" | Should Be 0
        }

        It "Throws on invalid EntryType" {
            {Get-LogLevel -EntryType "Foo"} | Should Throw
        }
    }
}

Describe Format-LogMessage {
    InModuleScope PSMultiLog {
        $Timestamp = Get-Date
        $TimestampString = $Timestamp.ToString("u")
        $InfoEntry = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Information"
            LogLevel = 2
            Message = "Hello, World!"
            Exception = $null
            EventId = 1000
        }

        $ErrorEntry = New-Object -TypeName psobject -Property @{
            Timestamp = $Timestamp
            EntryType = "Error"
            LogLevel = 0
            Message = "This is an error."
            Exception = New-Object -TypeName Exception -ArgumentList "Exception message."
            EventId = 1000
        }

    
        It "Formats a message" {
            Format-LogMessage -Entry $InfoEntry | Should BeExactly "[$TimestampString] - Hello, World!"
        }

        It "Includes Exception information" {
            Format-LogMessage -Entry $ErrorEntry -Exception | Should BeExactly "[$TimestampString] - This is an error. - Exception: Exception message."
        }

        It "Includes type information" {
            Format-LogMessage -Entry $InfoEntry -Type | Should BeExactly "[$TimestampString] - INFO - Hello, World!"
        }

        It "Includes type and Exception information" {
            Format-LogMessage -Entry $ErrorEntry -Type -Exception | Should BeExactly "[$TimestampString] - ERRR - This is an error. - Exception: Exception message."
        }
    }
}

Describe ConvertTo-HtmlUnorderedList {
    InModuleScope PSMultiLog {
        $Objects = @("One", "Two", "Three")

        It "Performs basic formatting" {
            ConvertTo-HtmlUnorderedList -InputObject $Objects | Should BeExactly "<ul>`n<li>One</li>`n<li>Two</li>`n<li>Three</li>`n</ul>`n"
        }

        It "Executes a ScriptBlock to perform formatting" {
            ConvertTo-HtmlUnorderedList -FormatScript {"TEST! $_"} -InputObject $Objects | Should BeExactly "<ul>`n<li>TEST! One</li>`n<li>TEST! Two</li>`n<li>TEST! Three</li>`n</ul>`n"
        }
    }
}

Remove-Module PSMultiLog