Tests/Set-DotEnv.Tests.ps1

BeforeAll {

    Set-StrictMode -Version "Latest"

    . "$PSScriptRoot\..\Source\ConvertFrom-DotEnv.ps1"
    . "$PSScriptRoot\..\Source\Set-DotEnvValue.ps1"
    . "$PSScriptRoot\..\Source\Set-DotEnv.ps1"

}

Describe "Set-DotEnv" {

    Context "Using -Values" {

        Context "When the file does not exist" {

            It "Creates the file with every key=value pair" {

                $path = Join-Path -Path $TestDrive -ChildPath "missing.env"

                Set-DotEnv -Path $path -Values @{ KEY_ONE = "value one"; KEY_TWO = "value two" }

                $content = Get-Content -Path $path

                $content | Should -Contain "KEY_ONE=value one"
                $content | Should -Contain "KEY_TWO=value two"

            }

        }

        Context "When the file exists" {

            BeforeEach {

                $script:testEnvPath = Join-Path -Path $TestDrive -ChildPath "test.env"

                @(
                    "# comment line"
                    "KEY_ONE=old value"
                ) | Set-Content -Path $testEnvPath

            }

            It "Replaces existing keys and appends new ones" {

                Set-DotEnv -Path $testEnvPath -Values @{ KEY_ONE = "new value"; KEY_TWO = "value two" }

                $content = Get-Content -Path $testEnvPath

                $content | Should -Contain "KEY_ONE=new value"
                $content | Should -Contain "KEY_TWO=value two"
                $content | Should -Not -Contain "KEY_ONE=old value"

            }

            It "Preserves other lines" {

                Set-DotEnv -Path $testEnvPath -Values @{ KEY_ONE = "new value" }

                Get-Content -Path $testEnvPath | Should -Contain "# comment line"

            }

        }

        It "Accepts the file path from the pipeline" {

            $firstPath = Join-Path -Path $TestDrive -ChildPath "first.env"
            $secondPath = Join-Path -Path $TestDrive -ChildPath "second.env"

            $firstPath, $secondPath | Set-DotEnv -Values @{ KEY_ONE = "value one" }

            Get-Content -Path $firstPath | Should -Contain "KEY_ONE=value one"
            Get-Content -Path $secondPath | Should -Contain "KEY_ONE=value one"

        }

    }

    Context "Under -WhatIf" {

        It "Does not create the file" {

            $path = Join-Path -Path $TestDrive -ChildPath "whatif.env"

            Set-DotEnv -Path $path -Values @{ KEY_ONE = "value one" } -WhatIf

            Test-Path -Path $path | Should -BeFalse

        }

    }

    Context "Using -Text instead of -Values" {

        BeforeEach {

            $script:testEnvPath = Join-Path -Path $TestDrive -ChildPath "test.env"

            "KEY_ONE=old value" | Set-Content -Path $testEnvPath

        }

        It "Sets every key from a multi-line KEY=VALUE formatted string" {

            $text = @(
                "# comment line"
                "KEY_ONE=new value"
                "KEY_TWO=value two"
            ) -join "`n"

            Set-DotEnv -Path $testEnvPath -Text $text

            $content = Get-Content -Path $testEnvPath

            $content | Should -Contain "KEY_ONE=new value"
            $content | Should -Contain "KEY_TWO=value two"

        }

        It "Throws when a non-comment, non-blank line is not in KEY=VALUE format" {

            { Set-DotEnv -Path $testEnvPath -Text "not a key value line" } | Should -Throw

        }

    }

}