. $PSScriptRoot\..\..\Load-PesterModules.ps1 $here = Split-Path -Parent $MyInvocation.MyCommand.Path $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.tests\.', '.' $functionPath = Join-Path -Path $here -ChildPath $sut Write-Host "Overriding SUT: $functionPath" Import-Module $functionPath -Force $moduleForMock = '' InModuleScope 'Alkami.DevOps.SystemEngineering' { Describe 'New-SftpUser' { $fakeAccountName = 'FakeyMcFakeAccount-SFTP' $fakePassword = 'ThisIsAPassword' $generatedPassword = '@ut0Generated' Mock -CommandName Get-SupportedAwsRegions -ModuleName $moduleForMock -MockWith { return @( 'us-east-1' ) } Mock -CommandName Get-LogLeadName -ModuleName $moduleForMock -MockWith { return 'New-SftpUser.tests' } Mock -CommandName New-SecurePassword -ModuleName $moduleForMock -MockWith { return $generatedPassword } Mock -CommandName Get-SftpUserDefaultSecretString -ModuleName $moduleForMock -MockWith { return '' } Mock -CommandName Get-LMFunctionConfiguration -ModuleName $moduleForMock -MockWith { return @{ 'Role' = 'TestArn' } } Mock -CommandName New-SECSecret -ModuleName $moduleForMock -MockWith {} Mock -CommandName Write-AlkamiSecretResourcePolicy -ModuleName $moduleForMock -MockWith {} Mock -CommandName New-Item -ModuleName $moduleForMock -MockWith {} Mock -CommandName Write-Error -ModuleName $moduleForMock -MockWith {} Mock -CommandName Import-AWSModule -ModuleName $moduleForMock -MockWith {} Mock -CommandName Write-Verbose -ModuleName $moduleForMock -MockWith {} Mock -CommandName Add-SECSecretToRegion -ModuleName $moduleForMock -MockWith {} Context 'Parameter Validation' { It 'Throws if Username is Null' { { New-SftpUser -Username $null } | Should -Throw } It 'Throws if Username is Empty' { { New-SftpUser -Username '' } | Should -Throw } It 'Throws if Password is Null' { { New-SftpUser -Username $fakeAccountName -Password $null } | Should -Throw } It 'Throws if Password is Empty' { { New-SftpUser -Username $fakeAccountName -Password '' } | Should -Throw } It 'Throws if Profile Name is Null' { { New-SftpUser -Username $fakeAccountName -ProfileName $null } | Should -Throw } It 'Throws if Profile Name is Empty' { { New-SftpUser -Username $fakeAccountName -ProfileName '' } | Should -Throw } It 'Throws if Profile Name is Not in Supported List' { { New-SftpUser -Username $fakeAccountName -ProfileName 'temp-test' } | Should -Throw } It 'Throws if Region is Not in Supported List' { { New-SftpUser -Username $fakeAccountName -Region 'Test' } | Should -Throw } It 'Throws if Home Directory Suffix Override Does Not Match Regex' { { New-SftpUser -Username $fakeAccountName -HomeDirectorySuffixOverride '/---/TEST!!' } | Should -Throw } It 'Throws if Child Subdirectories Does Not Match Regex' { { New-SftpUser -Username $fakeAccountName -ChildSubdirectories @('/---/TEST!!') } | Should -Throw } It 'Throws if Replication Region is Not in Supported List' { { New-SftpUser -Username $fakeAccountName -ReplicationRegion 'Test' } | Should -Throw } } Context 'Error Handling' { Mock -CommandName New-SftpPasswordHash -ModuleName $moduleForMock -MockWith { return $null } It 'Writes Error and Returns Null If Password Hash Fails' { New-SftpUser -Username $fakeAccountName | Should -BeNull Assert-MockCalled -CommandName Write-Error ` -ParameterFilter { $Message -match 'Unable to generate password hash for SFTP user.' } -Times 1 -Exactly -Scope It Assert-MockCalled -CommandName New-SECSecret -Times 0 -Exactly -Scope It Assert-MockCalled -CommandName New-Item -Times 0 -Exactly -Scope It } } Context 'Logic' { Mock -CommandName New-SftpPasswordHash -ModuleName $moduleForMock -MockWith { return $fakePassword } It 'Converts Username to Lowercase' { $result = New-SftpUser -Username $fakeAccountName $result.Username | Should -BeExactly $fakeAccountName.ToLower() } It 'Uses Password if Provided' { $result = New-SftpUser -Username $fakeAccountName -Password $fakePassword $result.Password | Should -BeExactly $fakePassword } It 'Uses Generated Password if Not Provided' { $result = New-SftpUser -Username $fakeAccountName $result.Password | Should -BeExactly $generatedPassword } It 'Uses Username as Home Directory Suffix By Default' { $result = New-SftpUser -Username $fakeAccountName Assert-MockCalled -CommandName Write-Verbose ` -ParameterFilter { $Message -match "Home directory suffix determined to be '$($result.Username)'" } -Times 1 -Exactly -Scope It } It 'Uses Home Directory Suffix Override Parameter When Provided' { $suffix = 'test1-root/test2-subdir' New-SftpUser -Username $fakeAccountName -HomeDirectorySuffixOverride $suffix -Confirm:$false Assert-MockCalled -CommandName Write-Verbose ` -ParameterFilter { $Message -match "Home directory suffix determined to be '$suffix'" } -Times 1 -Exactly -Scope It } It 'Creates Staging and Production Subdirectories by Default' { New-SftpUser -Username $fakeAccountName Assert-MockCalled -CommandName New-item -Times 1 -Exactly -Scope It ` -ParameterFilter { $Path.EndsWith('Staging') } Assert-MockCalled -CommandName New-item -Times 1 -Exactly -Scope It ` -ParameterFilter { $Path.EndsWith('Production') } } It 'Uses ChildSubdirectories Parameter If Provided' { New-SftpUser -Username $fakeAccountName -ChildSubdirectories @( 'TestSubdir' ) Assert-MockCalled -CommandName New-item -Times 0 -Exactly -Scope It ` -ParameterFilter { $Path.EndsWith('Staging') } Assert-MockCalled -CommandName New-item -Times 0 -Exactly -Scope It ` -ParameterFilter { $Path.EndsWith('Production') } Assert-MockCalled -CommandName New-item -Times 1 -Exactly -Scope It ` -ParameterFilter { $Path.EndsWith('TestSubdir') } } It 'Creates AWS Secret for the User' { New-SftpUser -Username $fakeAccountName Assert-MockCalled -CommandName New-SECSecret -Times 1 -Exactly -Scope It ` -ParameterFilter { $Name -eq $fakeAccountName.ToLower() } } It 'Creates Resource Policy on New AWS Secret' { New-SftpUser -Username $fakeAccountName Assert-MockCalled -CommandName Get-LMFunctionConfiguration -Times 1 -Exactly -Scope It Assert-MockCalled -CommandName Write-AlkamiSecretResourcePolicy -Times 1 -Exactly -Scope It ` -ParameterFilter { $SecretName -eq $fakeAccountName.ToLower() } } It 'Resource Policy Contains SFTP Lambda Auth ARN' { New-SftpUser -Username $fakeAccountName Assert-MockCalled -CommandName Get-LMFunctionConfiguration -Times 1 -Exactly -Scope It Assert-MockCalled -CommandName Write-AlkamiSecretResourcePolicy -Times 1 -Exactly -Scope It ` -ParameterFilter { $SecretAccessExtraArns[0] -ceq 'TestArn' } } It 'Replicates New AWS Secret to us-west-2 by Default' { New-SftpUser -Username $fakeAccountName Assert-MockCalled -CommandName Write-Verbose -Times 1 -Exactly -Scope It ` -ParameterFilter { $Message -match 'Replicating newly created secret to us-west-2' } Assert-MockCalled -CommandName Add-SECSecretToRegion -Times 1 -Exactly -Scope It ` -ParameterFilter { $SecretId -eq $fakeAccountName.ToLower() } } It 'Does Not Replicate New AWS Secret if Parameter is Null' { New-SftpUser -Username $fakeAccountName -ReplicationRegion $null Assert-MockCalled -CommandName Write-Verbose -Times 0 -Exactly -Scope It ` -ParameterFilter { $Message -match 'Replicating newly created secret' } Assert-MockCalled -CommandName Add-SECSecretToRegion -Times 0 -Exactly -Scope It } It 'Does Not Replicate New AWS Secret if Parameter is Empty' { New-SftpUser -Username $fakeAccountName -ReplicationRegion '' Assert-MockCalled -CommandName Write-Verbose -Times 0 -Exactly -Scope It ` -ParameterFilter { $Message -match 'Replicating newly created secret' } Assert-MockCalled -CommandName Add-SECSecretToRegion -Times 0 -Exactly -Scope It } } } }