Csv.Tests.ps1

####################################################################################################
# Declarations
####################################################################################################

# Set InformationPreference
$InformationPreference = "Continue"

####################################################################################################
# Functions
####################################################################################################

# Add modules folder to path if not already added
if (!$env:PSModulePath.EndsWith(";$(Get-Location)\Modules")) {
    $env:PSModulePath += ";$(Get-Location)\Modules"
}

# Import functions from BitTitan.Runbooks.Modules
Import-Module BitTitan.Runbooks.Common -Force

####################################################################################################
# The tests
####################################################################################################

describe "Modules/BitTitan.Modules.Common/Csv/ConvertTo-CsvObject" -Tags "module", "common", "unit" {

    # Prepare the input
    $csvString = @"
sep=,
"name1","name2","name3"
"1 ",2,"-1"
True,"False","TRUE "
"@


    it "converts a CSV string to a CSV object with no additional processing" {
        # Call the function
        $csvObject = ConvertTo-CsvObject $csvString -ConvertBooleans:$false

        # Verify the output
        $csvObject.GetType().Name | Should Be "Object[]"
        $csvObject.length | Should Be 2
        $csvObject[0].name1 | Should Be "1 "
        $csvObject[0].name2 | Should Be 2
        $csvObject[0].name3 | Should Be "-1"
        $csvObject[1].name1 | Should Be "True"
        $csvObject[1].name2 | Should Be "False"
        $csvObject[1].name3 | Should Be "TRUE "
    }

    it "converts a CSV string to a CSV object converting the booleans" {
        # Call the function
        $csvObject = ConvertTo-CsvObject $csvString

        # Verify the output
        $csvObject.GetType().Name | Should Be "Object[]"
        $csvObject.length | Should Be 2
        $csvObject[0].name1 | Should Be "1 "
        $csvObject[0].name2 | Should Be 2
        $csvObject[0].name3 | Should Be "-1"
        $csvObject[1].name1 | Should Be $true
        $csvObject[1].name2 | Should Be $false
        $csvObject[1].name3 | Should Be $true
    }

    it "converts a CSV string to a CSV object converting the booleans and trimming the strings" {
        # Call the function
        $csvObject = ConvertTo-CsvObject $csvString -TrimStrings

        # Verify the output
        $csvObject.GetType().Name | Should Be "Object[]"
        $csvObject.length | Should Be 2
        $csvObject[0].name1 | Should Be "1"
        $csvObject[0].name2 | Should Be 2
        $csvObject[0].name3 | Should Be "-1"
        $csvObject[1].name1 | Should Be $true
        $csvObject[1].name2 | Should Be $false
        $csvObject[1].name3 | Should Be $true
    }

    it "converts a CSV string to a CSV object converting the booleans and trimming the strings and converting the numbers" {
        # Call the function
        $csvObject = ConvertTo-CsvObject $csvString -TrimStrings -ConvertIntegersMaxLength 2

        # Verify the output
        $csvObject.GetType().Name | Should Be "Object[]"
        $csvObject.length | Should Be 2
        $csvObject[0].name1 | Should Be 1
        $csvObject[0].name2 | Should Be 2
        $csvObject[0].name3 | Should Be -1
        $csvObject[1].name1 | Should Be $true
        $csvObject[1].name2 | Should Be $false
        $csvObject[1].name3 | Should Be $true
    }
}

describe "Modules/BitTitan.Modules.Common/Csv/ConvertTo-CsvString" -Tags "module", "common", "unit" {

    # Prepare the input
    $csvObject = @(
        [PSCustomObject]@{
            Name1 = "1"
            Name2 = $true
            Name3 = $false
        },
        [PSCustomObject]@{
            Name1 = 2
            Name2 = $false
            Name3 = $true
        }
    )

    context "when there are no complications" {

        it "converts a CSV object to a CSV string" {
            # Call the function
            $csvString = ConvertTo-CsvString $csvObject

            # Verify the output
            $expectedOutput = @"
sep=,
"name1","name2","name3"
"1","True","False"
"2","False","True"
 
"@

            $csvString | Should Be $expectedOutput
        }
    }
}

describe "Modules/BitTitan.Runbooks.Common/Csv/Get-FilteredCsvString" -Tags "module", "common", "unit" {

    context "when given a CSV and no specified columns" {
        # Set up the function parameters
        $csv = @"
sep=,
"name1","name2","name3"
"1","True","False"
"2","False","True"
 
"@

        $columns = ""

        it "returns the same CSV" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "and"

            # Verify the output
            $filteredCsv | Should Be $csv
        }
    }

    context "when given a CSV and one specified column" {
        # Set up the function parameters
        $csv = @"
sep=,
"name1","name2","name3"
"1","True","False"
"2","False","True"
 
"@

        $columns = "name2"

        it "filters the CSV by the column using 'and' filtering" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "and"

            # Verify the output_
            $expectedCsv = @"
sep=,
"name1","name2","name3"
"1","True","False"
 
"@

            $filteredCsv | Should Be $expectedCsv
        }

        it "filters the CSV by the column using 'or' filtering" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "or"

            # Verify the output_
            $expectedCsv = @"
sep=,
"name1","name2","name3"
"1","True","False"
 
"@

            $filteredCsv | Should Be $expectedCsv
        }
    }

    context "when given a CSV and more than one specified column" {
        # Set up the function parameters
        $csv = @"
sep=,
"name1","name2","name3"
"1","True","False"
"2","False","True"
 
"@

        $columns = "name2, name3"

        it "filters the CSV by columns using 'and' filtering" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "and"

            # Verify the output_
            $expectedCsv = ""
            $filteredCsv | Should Be $expectedCsv
        }

        it "filters the CSV by the column using 'or' filtering" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "or"

            # Verify the output_
            $expectedCsv = @"
sep=,
"name1","name2","name3"
"1","True","False"
"2","False","True"
 
"@

            $filteredCsv | Should Be $expectedCsv
        }
    }

    context "when given a CSV and a column which does not exist" {
        # Set up the function parameters
        $csv = @"
sep=,
"name1","name2","name3"
"1","True","False"
"2","False","True"
 
"@

        $columns = "name4"

        it "filters the CSV by columns using 'and' filtering" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "and"

            # Verify the output_
            $expectedCsv = ""
            $filteredCsv | Should Be $expectedCsv
        }

        it "filters the CSV by the column using 'or' filtering" {
            # Call the function
            $filteredCsv = Get-FilteredCsvString -Csv $csv -Columns $columns -Filtering "or"

            # Verify the output_
            $expectedCsv = ""
            $filteredCsv | Should Be $expectedCsv
        }
    }
}