Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some tests for GitDsc #87

Closed
wants to merge 12 commits into from
10 changes: 7 additions & 3 deletions resources/GitDsc/GitDsc.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@
'GitClone',
'GitRemote',
'GitConfigUserName',
'GitConfigUserEmail',
'GitConfigFile'
'GitConfigUserEmail'
)

# List of all modules packaged with this module
Expand All @@ -101,7 +100,12 @@
PSData = @{

# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('PSDscResource_GitClone', 'PSDscResource_GitRemote', 'PSDscResource_GitConfigUserName', 'PSDscResource_GitConfigUserEmail', 'PSDscResource_GitConfigFile')
Tags = @(
'PSDscResource_GitClone',
'PSDscResource_GitRemote',
'PSDscResource_GitConfigUserName',
'PSDscResource_GitConfigUserEmail'
)

# A URL to the license for this module.
# LicenseUri = ''
Expand Down
36 changes: 12 additions & 24 deletions resources/GitDsc/GitDsc.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ class GitClone {
if ($gitRemoteValue -like $this.HttpsUrl) {
$currentState.Ensure = [Ensure]::Present
}
}
catch {
} catch {
# Failed to execute `git remote`. Ensure state is `absent`
}
}
Expand Down Expand Up @@ -114,8 +113,7 @@ class GitRemote {
try {
$gitRemoteValue = Invoke-GitRemote("get-url $($this.RemoteName)")
$currentState.Ensure = ($gitRemoteValue -like $this.RemoteUrl) ? [Ensure]::Present : [Ensure]::Absent
}
catch {
} catch {
$currentState.Ensure = [Ensure]::Absent
}

Expand All @@ -133,16 +131,13 @@ class GitRemote {
if ($this.Ensure -eq [Ensure]::Present) {
try {
Invoke-GitRemote("add $($this.RemoteName) $($this.RemoteUrl)")
}
catch {
} catch {
throw 'Failed to add remote repository.'
}
}
else {
} else {
try {
Invoke-GitRemote("remove $($this.RemoteName)")
}
catch {
} catch {
throw 'Failed to remove remote repository.'
}
}
Expand Down Expand Up @@ -174,12 +169,10 @@ class GitConfigUserName {
if ($this.ProjectDirectory) {
if (Test-Path -Path $this.ProjectDirectory) {
Set-Location $this.ProjectDirectory
}
else {
} else {
throw 'Project directory does not exist.'
}
}
else {
} else {
throw 'Project directory parameter must be specified for non-system and non-global configurations.'
}
}
Expand All @@ -206,8 +199,7 @@ class GitConfigUserName {

if ($this.Ensure -eq [Ensure]::Present) {
$configArgs = ConstructGitConfigUserArguments -Arguments "user.name '$($this.UserName)'" -ConfigLocation $this.ConfigLocation
}
else {
} else {
$configArgs = ConstructGitConfigUserArguments -Arguments '--unset user.name' -ConfigLocation $this.ConfigLocation
}

Expand Down Expand Up @@ -240,12 +232,10 @@ class GitConfigUserEmail {
if ($this.ProjectDirectory) {
if (Test-Path -Path $this.ProjectDirectory) {
Set-Location $this.ProjectDirectory
}
else {
} else {
throw 'Project directory does not exist.'
}
}
else {
} else {
throw 'Project directory parameter must be specified for non-system and non-global configurations.'
}
}
Expand All @@ -272,8 +262,7 @@ class GitConfigUserEmail {

if ($this.Ensure -eq [Ensure]::Present) {
$configArgs = ConstructGitConfigUserArguments -Arguments "user.email $($this.UserEmail)" -ConfigLocation $this.ConfigLocation
}
else {
} else {
$configArgs = ConstructGitConfigUserArguments -Arguments '--unset user.email' -ConfigLocation $this.ConfigLocation
}

Expand All @@ -290,8 +279,7 @@ function Assert-Git {
try {
Invoke-Git -Command 'help'
return
}
catch {
} catch {
throw 'Git is not installed'
}
}
Expand Down
102 changes: 102 additions & 0 deletions tests/GitDsc/GitDsc.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
using module GitDsc

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

<#
.Synopsis
Pester tests related to the GitDsc PowerShell module.
#>

BeforeAll {
if ($null -eq (Get-Module -ListAvailable -Name PSDesiredStateConfiguration)) {
Install-Module -Name PSDesiredStateConfiguration -Force -SkipPublisherCheck
}

# Because the module asserts that Git is installed before it will load, the function needs to be mocked
# This ensures that the tests can run even on a machine that does not have Git installed
Mock Assert-Git -ModuleName GitDsc { return $true }
Import-Module GitDsc

}

Describe 'List available DSC resources' {
It 'Shows DSC Resources' {
$expectedDSCResources = 'GitClone', 'GitRemote', 'GitConfigUserName', 'GitConfigUserEmail'
$availableDSCResources = (Get-DscResource -Module GitDsc).Name
$availableDSCResources.count | Should -Be 4
$availableDSCResources | Where-Object { $expectedDSCResources -notcontains $_ } | Should -BeNullOrEmpty -ErrorAction Stop
}
}

InModuleScope -ModuleName GitDsc {
Describe 'GitClone' {

BeforeAll {
Mock Invoke-GitClone -Verifiable
$global:HttpsUrl = 'https://github.com/microsoft/winget-dsc.git'
$global:TestGitRoot = Join-Path -Path $env:TEMP -ChildPath $(New-Guid)
}

$script:gitCloneResource = [GitClone]::new()
Write-Output $gitCloneResource

It 'New folder starts without cloned repo' {
$gitCloneResource.HttpsUrl = $global:HttpsUrl
$gitCloneResource.RootDirectory = $global:TestGitRoot
$initialState = $gitCloneResource.Get()
$initialState.Ensure | Should -Be 'Absent'
}

It 'Set throws when ensuring absent' {
$gitCloneResource.Ensure = [Ensure]::Absent
{ $gitCloneResource.Set() } | Should -Throw
}

It 'Calls Invoke-GitClone when ensuring present' {
$gitCloneResource.HttpsUrl = $global:HttpsUrl
$gitCloneResource.RootDirectory = $global:TestGitRoot
$gitCloneResource.Ensure = [Ensure]::Present
# Run the setter
{ $gitCloneResource.Set() } | Should -Not -Throw
# The setter should create the root directory if it doesn't exist
Test-Path $global:TestGitRoot | Should -Be $true
# Git clone should have been called once
Assert-MockCalled Invoke-GitClone -Exactly 1
}

It 'Test should fail when remote does not match' {
Mock Invoke-GitRemote { return 'https://github.com/Trenly/winget-dsc.git' }

$gitCloneResource.HttpsUrl = $global:HttpsUrl
$gitCloneResource.RootDirectory = $global:TestGitRoot
$gitCloneResource.Ensure = [Ensure]::Present

$gitCloneResource.Test() | Should -Be $false
}

It 'Test should succeed when remote matches' {
# The folder has to be created here so that the DSC resource can attempt to fetch the remote from within it
New-Item -ItemType Directory -Path $(Join-Path -Path $global:TestGitRoot -ChildPath 'winget-dsc') -Force

Mock Invoke-GitRemote -Verifiable { return 'https://github.com/microsoft/winget-dsc.git' }

$gitCloneResource.HttpsUrl = $global:HttpsUrl
$gitCloneResource.RootDirectory = $global:TestGitRoot
$gitCloneResource.Ensure = [Ensure]::Present

$gitCloneResource.Test() | Should -Be $true
Assert-MockCalled Invoke-GitRemote -Exactly 1
}

AfterAll {
# Clean up cloned folder
Remove-Item -Recurse -Force $global:TestGitRoot -ErrorAction 'SilentlyContinue'
}
}
}

AfterAll {
}
Loading