From ce823d45640ed41dccb5d158ec07a7eed476b181 Mon Sep 17 00:00:00 2001 From: Marco Blessing Date: Wed, 21 Mar 2018 12:16:09 +0100 Subject: [PATCH] Increase code coverage (#22) --- appveyor.yml | 2 +- src/Helper/Get-RandomKey.ps1 | 1 + src/Helper/Test-Module.ps1 | 4 +- .../01_Set-ChallengeFile.Tests.ps1 | 60 +++++++++++++++++ .../01_Test-ChallengeFile.Tests.ps1 | 38 +++++++++++ tests/Helper/01_Get-ModuleBase.Tests.ps1 | 25 +++++++ tests/Helper/01_Get-RandomKey.Tests.ps1 | 39 +++++++++++ tests/Helper/01_Test-Module.Tests.ps1 | 65 +++++++++++++++++++ .../Item/02_New-CredentialStoreItem.Tests.ps1 | 37 +++++++++++ tests/Store/01_Get-CredentialStore.Tests.ps1 | 10 +++ tests/Store/01_New-CredentialStore.Tests.ps1 | 6 ++ tests/Store/01_Test-CredentialStore.Tests.ps1 | 9 +++ tools/AppVeyor.psm1 | 1 - 13 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 tests/ChallengeFile/01_Set-ChallengeFile.Tests.ps1 create mode 100644 tests/ChallengeFile/01_Test-ChallengeFile.Tests.ps1 create mode 100644 tests/Helper/01_Get-ModuleBase.Tests.ps1 create mode 100644 tests/Helper/01_Get-RandomKey.Tests.ps1 create mode 100644 tests/Helper/01_Test-Module.Tests.ps1 diff --git a/appveyor.yml b/appveyor.yml index d1f3a05..db82d20 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,7 +20,7 @@ image: Visual Studio 2017 install: - ps: Import-Module .\tools\AppVeyor.psm1 - - ps: Invoke-InstallDependencies -Verbose + - ps: Invoke-InstallDependencies environment: NuGetToken: diff --git a/src/Helper/Get-RandomKey.ps1 b/src/Helper/Get-RandomKey.ps1 index 206f400..907160a 100644 --- a/src/Helper/Get-RandomKey.ps1 +++ b/src/Helper/Get-RandomKey.ps1 @@ -32,6 +32,7 @@ function Get-RandomKey { [CmdletBinding()] param( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [ValidateSet(16, 24, 32)] [string]$size ) diff --git a/src/Helper/Test-Module.ps1 b/src/Helper/Test-Module.ps1 index 75d7720..f116459 100644 --- a/src/Helper/Test-Module.ps1 +++ b/src/Helper/Test-Module.ps1 @@ -83,14 +83,14 @@ Could not find the required {0} called {1}. Please install the required {0} to r } 'PSSnapin' { - if (Get-PSSnapin -Name $Name -Registered) { + if (Get-PSSnapin -Name $Name -Registered -ErrorAction SilentlyContinue) { return $true } else { if ($StopIfFails) { Write-Error -Message $Message -ErrorAction Stop -Category NotInstalled - return $false } + return $false } } diff --git a/tests/ChallengeFile/01_Set-ChallengeFile.Tests.ps1 b/tests/ChallengeFile/01_Set-ChallengeFile.Tests.ps1 new file mode 100644 index 0000000..0a68473 --- /dev/null +++ b/tests/ChallengeFile/01_Set-ChallengeFile.Tests.ps1 @@ -0,0 +1,60 @@ +#region HEADER +$RepoRoot = (Get-GitDirectory).replace('\.git', '') +$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' +$sut = $sut -replace "\d{2}`_", '' +$suthome = (Get-ChildItem -Path $RepoRoot -Exclude ".\tests\" -Filter $sut -Recurse).FullName +# Skip try loading the source file if it doesn't exists. +If ($suthome.Length -gt 0) { + . $suthome +} +Else { + Write-Warning ("Could not find source file {0}" -f $sut) +} + +# load additional functions defined in the repository. Replace the expression . +. (Get-ChildItem -Path $RepoRoot -Filter "Get-RandomKey.ps1" -Recurse).FullName + +#endregion HEADER + +Describe "Set-ChallengeFile" { + Context "Tests with custom path" { + It "Working dir and path not exist" { + {Set-ChallengeFile -Path 'C:\PSCredentialStore\Challenge.bin'} | Should -Not -Throw + } + It "No parameter and non file should return true" { + if (Test-Path -Path ("{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData)) { + Remove-Item -Path ("{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData) + } + Set-ChallengeFile + Test-Path -Path ("{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData) | Should -Be $true + } + It "Existing Credential file should return error" { + { Set-ChallengeFile } | Should -Throw + Remove-Item -Path ("{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData) + } + It "Use -Force switch should create a new challenge file" { + # prepare for test and clean up old data + if (Test-Path -Path ("{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData)) { + Remove-Item -Path ("{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData) + } + Set-ChallengeFile + { Set-ChallengeFile -Force } | Should -Not -Throw + } + It "Test directory creation for shared store" { + if (Test-Path -Path ("{0}\PSCredentialStore" -f $env:ProgramData)) { + Remove-Item -Path ("{0}\PSCredentialStore" -f $env:ProgramData) -Force -Recurse + } + Set-ChallengeFile + Test-Path -Path ("{0}\PSCredentialStore" -f $env:ProgramData) | Should -Be $true + } + } + Context "General Exception handling" { + Mock New-Item {throw "foobar exception"} + It "Test exception handling if the root directory could not be created" { + if (Test-Path -Path ("{0}\PSCredentialStore" -f $env:ProgramData)) { + Remove-Item -Path ("{0}\PSCredentialStore" -f $env:ProgramData) -Force -Recurse + } + { Set-ChallengeFile } | Should -Throw "Could not create the parent data dir" + } + } +} diff --git a/tests/ChallengeFile/01_Test-ChallengeFile.Tests.ps1 b/tests/ChallengeFile/01_Test-ChallengeFile.Tests.ps1 new file mode 100644 index 0000000..285fddc --- /dev/null +++ b/tests/ChallengeFile/01_Test-ChallengeFile.Tests.ps1 @@ -0,0 +1,38 @@ +#region HEADER +$RepoRoot = (Get-GitDirectory).replace('\.git', '') +$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' +$sut = $sut -replace "\d{2}`_", '' +$suthome = (Get-ChildItem -Path $RepoRoot -Exclude ".\tests\" -Filter $sut -Recurse).FullName +# Skip try loading the source file if it doesn't exists. +If ($suthome.Length -gt 0) { + . $suthome +} +Else { + Write-Warning ("Could not find source file {0}" -f $sut) +} + +# load additional functions defined in the repository. Replace the expression . +#. (Get-ChildItem -Path $RepoRoot -Filter "Test-ChallengeFile.ps1" -Recurse).FullName + +#endregion HEADER + +Describe "Test-ChallengeFile" { + Context "Basic input tests" { + Mock Test-Path {return $true} + It "No parameter with existing challenge file" { + {Test-ChallengeFile} | Should -Not -Throw + } + It "No parameter and existing file should return true" { + Test-ChallengeFile | Should -Be $true + } + } + Context "Execute with parameter" { + $TestChFile = "{0}\resources\cs\Challenge.bin" -f $RepoRoot + It "Provide valid path" { + Test-ChallengeFile -Path $TestChFile | Should -Be $true + } + It "Provide fake path" { + Test-ChallengeFile -Path "C:\notexisting.bin" | Should -Be $false + } + } +} diff --git a/tests/Helper/01_Get-ModuleBase.Tests.ps1 b/tests/Helper/01_Get-ModuleBase.Tests.ps1 new file mode 100644 index 0000000..55ba4f6 --- /dev/null +++ b/tests/Helper/01_Get-ModuleBase.Tests.ps1 @@ -0,0 +1,25 @@ +#region HEADER +$RepoRoot = (Get-GitDirectory).replace('\.git', '') +$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' +$sut = $sut -replace "\d{2}`_", '' +$suthome = (Get-ChildItem -Path $RepoRoot -Exclude ".\tests\" -Filter $sut -Recurse).FullName +# Skip try loading the source file if it doesn't exists. +If ($suthome.Length -gt 0) { + . $suthome +} +Else { + Write-Warning ("Could not find source file {0}" -f $sut) +} + +# load additional functions defined in the repository. Replace the expression . +# . (Get-ChildItem -Path $RepoRoot -Filter ".ps1" -Recurse).FullName + +#endregion HEADER + +Describe "Get-ModuleBase" { + Context "Basic syntax check" { + It "Test1: Should not throw" { + { Get-ModuleBase } | Should -Not -Throw + } + } +} diff --git a/tests/Helper/01_Get-RandomKey.Tests.ps1 b/tests/Helper/01_Get-RandomKey.Tests.ps1 new file mode 100644 index 0000000..f6ab645 --- /dev/null +++ b/tests/Helper/01_Get-RandomKey.Tests.ps1 @@ -0,0 +1,39 @@ +#region HEADER +$RepoRoot = (Get-GitDirectory).replace('\.git', '') +$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' +$sut = $sut -replace "\d{2}`_", '' +$suthome = (Get-ChildItem -Path $RepoRoot -Exclude ".\tests\" -Filter $sut -Recurse).FullName +# Skip try loading the source file if it doesn't exists. +If ($suthome.Length -gt 0) { + . $suthome +} +Else { + Write-Warning ("Could not find source file {0}" -f $sut) +} + +# load additional functions defined in the repository. Replace the expression . +# . (Get-ChildItem -Path $RepoRoot -Filter ".ps1" -Recurse).FullName + +#endregion HEADER + +Describe "Get-RandomKey" { + Context "Basic input tests" { + It "Test1: Should throw if wrong size is given" { + {Get-RandomKey -size 43} | Should -Throw + } + } + Context "Basic syntax check" { + It "Test1: Should return a key with a length of 16" { + $Key = Get-RandomKey -size 16 + $Key.length | Should -Be 16 + } + It "Test2: Should return a key with a length of 24" { + $Key = Get-RandomKey -size 24 + $Key.length | Should -Be 24 + } + It "Test3: Should return a key with a length of 32" { + $Key = Get-RandomKey -size 32 + $Key.length | Should -Be 32 + } + } +} diff --git a/tests/Helper/01_Test-Module.Tests.ps1 b/tests/Helper/01_Test-Module.Tests.ps1 new file mode 100644 index 0000000..675a2dc --- /dev/null +++ b/tests/Helper/01_Test-Module.Tests.ps1 @@ -0,0 +1,65 @@ +#region HEADER +$RepoRoot = (Get-GitDirectory).replace('\.git', '') +$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' +$sut = $sut -replace "\d{2}`_", '' +$suthome = (Get-ChildItem -Path $RepoRoot -Exclude ".\tests\" -Filter $sut -Recurse).FullName +# Skip try loading the source file if it doesn't exists. +If ($suthome.Length -gt 0) { + . $suthome +} +Else { + Write-Warning ("Could not find source file {0}" -f $sut) +} + +# load additional functions defined in the repository. Replace the expression . +#. (Get-ChildItem -Path $RepoRoot -Filter ".ps1" -Recurse).FullName + +#endregion HEADER + +Describe "Test-ModuleName" { + Context "Basic input tests" { + It "Testing standard module should not throw" { + { Test-Module -Name 'PowerShellGet' -Type Module } | Should -Not -Throw + } + It "Existing module should return true" { + Test-Module -Name 'PowerShellGet' -Type Module | Should -Be $true + } + } + Context "Custom Type tests" { + It "Using custom type should throw" { + { Test-Module -Name "foobarr" -Type Custom} | Should -Throw + } + } + Context "Working with PSSnapins" { + It "Loading first PSSnaping should not throw " { + $Snap = Get-PSSnapin -Registered | Select-Object -First 1 + { Test-Module -Name $Snap.Name -Type PSSnapin } | Should -Not -Throw + } + It "Loading first PSSnaping should return true" { + $Snap = Get-PSSnapin -Registered | Select-Object -First 1 + Test-Module -Name $Snap.Name -Type PSSnapin | Should -Be $true + } + It "Not existing PSSnaping should return false" { + Test-Module -Name 'foobar2000' -Type PSSnapin | Should -Be $false + } + It "StopifFails switch should thrown an error" { + {Test-Module -Name 'foobar2000' -Type PSSnapin -StopIfFails }| Should -Throw + } + } + Context "Working with modules" { + It "Loading first module should not throw " { + $Mod = Get-Module -ListAvailable | Select-Object -First 1 + { Test-Module -Name $Mod.Name -Type Module } | Should -Not -Throw + } + It "Loading first module should return true" { + $Snap = Get-Module -ListAvailable | Select-Object -First 1 + Test-Module -Name $Snap.Name -Type Module | Should -Be $true + } + It "Not existing module should return false" { + Test-Module -Name 'foobar2000' -Type Module | Should -Be $false + } + It "StopifFails switch should thrown an error" { + {Test-Module -Name 'foobar2000' -Type Module -StopIfFails }| Should -Throw + } + } +} diff --git a/tests/Item/02_New-CredentialStoreItem.Tests.ps1 b/tests/Item/02_New-CredentialStoreItem.Tests.ps1 index f1914bb..6b711ef 100644 --- a/tests/Item/02_New-CredentialStoreItem.Tests.ps1 +++ b/tests/Item/02_New-CredentialStoreItem.Tests.ps1 @@ -61,5 +61,42 @@ Describe "New-CredentialStoreItem" { $res = Get-Member -InputObject $tmpCS -Name $RemoteHost -Membertype Properties $res.Name | Should Be $RemoteHost } + It "Adds Item with identifier to shared store" { + $tmpCS = 'C:\CredentialStore.json' + $UserName = "myuser" + $Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force + $mycreds = New-Object -TypeName PSCredential -ArgumentList $UserName, $Password + $RemoteHost = "foobar2" + New-CredentialStoreItem -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds -Identifier 'Foo' + $writtenItem = Get-CredentialStoreItem -Path $tmpCS -RemoteHost $RemoteHost -Identifier 'Foo' + ($writtenItem.UserName -eq $UserName) -and ($writtenItem.Password.Length -gt 0) | Should -Be $true + } } + Context "Test optional parameter lookup" { + Mock Get-Credential { + $UserName = 'testuser' + $Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force + return [PSCredential]::new($UserName, $Password) + + } + It "Test missing Credential" { + $tmpCS = 'C:\CredentialStore.json' + New-CredentialStoreItem -Path $tmpCs -Shared -RemoteHost 'foobar3' + $writtenItem = Get-CredentialStoreItem -Path $tmpCS -Shared -RemoteHost 'foobar3' + $writtenItem.UserName | Should -Be "testuser" + } + } + Context "General Exception handling" { + Mock Test-CredentialStore {return $false} + Mock Get-Credential { + $UserName = 'myUser' + $Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force + return [PSCredential]::new($UserName, $Password) + + } + It "Missing CredentialStore should throw" { + { New-CredentialStoreItem -Path 'C:\missingStore.json' -RemoteHost 'notrelevant' } | Should -Throw "Could not add anything" + } + } + } diff --git a/tests/Store/01_Get-CredentialStore.Tests.ps1 b/tests/Store/01_Get-CredentialStore.Tests.ps1 index a0cab26..e52f147 100644 --- a/tests/Store/01_Get-CredentialStore.Tests.ps1 +++ b/tests/Store/01_Get-CredentialStore.Tests.ps1 @@ -33,5 +33,15 @@ Describe "Get-CredentialStore" { {Get-CredentialStore -Path $TestCredentialStore} | Should Not Throw } + It "Test3: Not existing path should return false" { + { Get-CredentialStore -Path 'C:\foobar\CredentialStore.json' -Shared }| Should -Throw "Could not find the CredentialStore." + } + } + Context "Testing invalid json data" { + Mock Test-CredentialStore {return $true} + Mock Get-Content {return '"foo":"bar",'} + It "Should throw with invalid CredentialStore" { + { Get-Credentialstore -Path "C:\dummy.json"} | Should -Throw "Unknown CredentialStore format. Invalid JSON file." + } } } diff --git a/tests/Store/01_New-CredentialStore.Tests.ps1 b/tests/Store/01_New-CredentialStore.Tests.ps1 index dfc47b0..b9d2eee 100644 --- a/tests/Store/01_New-CredentialStore.Tests.ps1 +++ b/tests/Store/01_New-CredentialStore.Tests.ps1 @@ -92,6 +92,12 @@ Describe "New-CredentialStore" { {New-CredentialStore -Path $pCS -Shared -Force} | Should Not Throw } } + Context "Test exception handling" { + Mock Out-File {throw "foobar exception"} + It "JSON Converstion should fail and throw" { + { New-CredentialStore -Path "C:\dummy.json"} | Should -Throw + } + } } # Cleanup test stores and restore existing ones. diff --git a/tests/Store/01_Test-CredentialStore.Tests.ps1 b/tests/Store/01_Test-CredentialStore.Tests.ps1 index 693184f..b32738f 100644 --- a/tests/Store/01_Test-CredentialStore.Tests.ps1 +++ b/tests/Store/01_Test-CredentialStore.Tests.ps1 @@ -36,5 +36,14 @@ Describe "Test-CredentialStore" { $res | Should Be $False $WarningPreference = $oWarningPreference } + It "Test4: Not existing path should return false" { + Test-CredentialStore -Path 'C:\foobar\CredentialStore.json' | Should -Be $false + } + It "Test5: testing private CredentialStore path" { + if (Test-Path -Path ("{0}\CredentialStore.json" -f $env:APPDATA) ) { + Remove-Item -Path ("{0}\CredentialStore.json" -f $env:APPDATA) + } + Test-CredentialStore | Should -Be $false + } } } diff --git a/tools/AppVeyor.psm1 b/tools/AppVeyor.psm1 index 71e1e85..ac35426 100644 --- a/tools/AppVeyor.psm1 +++ b/tools/AppVeyor.psm1 @@ -154,7 +154,6 @@ Function Invoke-CoverageReport() { [String]$RepoToken = $Env:CoverallsToken ) - Import-Module ('.\src\{0}.psm1' -f $CALLSIGN) -Verbose -Force $FileMap = New-PesterFileMap -SourceRoot '.\src' -PesterRoot '.\tests' $CoverageReport = New-CoverageReport -PesterFileMap $FileMap -RepoToken $RepoToken Write-Host "CoverageReport JSON:" -ForegroundColor Yellow