Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed8f3ab02e | |||
| 67d69c52e9 | |||
| ed9ba80938 | |||
| edb1501f40 | |||
| 5854940f75 | |||
| 02f83e6633 | |||
| d4c7aa5a92 | |||
| 15381257e5 | |||
| 1c09d40253 | |||
| 1d0c8b43bc | |||
| 445fa8a429 | |||
| dd47a1b7e2 | |||
| c65cde9fbc | |||
| c18f68bc46 | |||
| 51a3a15a4f | |||
| 0451788a13 | |||
| 34fcb73d32 | |||
| 172922ba61 | |||
| 24f2e90cc9 | |||
| 135af8dfb8 | |||
| c5c9f81c50 | |||
| 68da95104b | |||
| 6ec0944a32 | |||
| 9cdcfeddff | |||
| 8e1a5f187a | |||
| dfb34f240b | |||
| 0c40d07bcd | |||
| 3cdf0a6610 | |||
| d1d2366c4a | |||
| fb2a87ed84 | |||
| d8dfb1d1fe | |||
| 305ec3c2fb | |||
| e9d6aa255f |
@@ -8,7 +8,25 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
container:
|
||||||
|
image: catthehacker/ubuntu:pwsh-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Run pester tests and verify all tests pass
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Changing to repository directory: ${{ github.workspace }}"
|
||||||
|
Set-Location -Path ${{ github.workspace }}
|
||||||
|
Write-Host "Running Pester tests"
|
||||||
|
Invoke-Pester -Path . -PassThru | Select-Object -ExpandProperty FailedCount | Should -Be 0 -ErrorAction stop
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
|
needs: test
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
container:
|
container:
|
||||||
image: catthehacker/ubuntu:pwsh-latest
|
image: catthehacker/ubuntu:pwsh-latest
|
||||||
@@ -22,9 +40,9 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
$creds = New-Object System.Management.Automation.PSCredential('actions', ('{{ secrets.PACKAGES_TOKEN }}' | ConvertTo-SecureString -AsPlainText -Force))
|
$creds = New-Object System.Management.Automation.PSCredential('actions', ('{{ secrets.PACKAGES_TOKEN }}' | ConvertTo-SecureString -AsPlainText -Force))
|
||||||
try {
|
try {
|
||||||
Register-PSRepository -Name 'GiteaPrivate' `
|
Register-PSRepository -Name 'GiteaPublic' `
|
||||||
-SourceLocation 'https://gitea.norwichct.tech/api/packages/cityofnorwich/nuget' `
|
-SourceLocation 'https://gitea.norwichct.tech/api/packages/public/nuget' `
|
||||||
-PublishLocation 'https://gitea.norwichct.tech/api/packages/cityofnorwich/nuget' `
|
-PublishLocation 'https://gitea.norwichct.tech/api/packages/public/nuget' `
|
||||||
-installationPolicy Trusted `
|
-installationPolicy Trusted `
|
||||||
-Credential $creds
|
-Credential $creds
|
||||||
}
|
}
|
||||||
@@ -54,9 +72,9 @@ jobs:
|
|||||||
Set-Location -Path ${{ github.workspace }}
|
Set-Location -Path ${{ github.workspace }}
|
||||||
$moduleVersion = git describe --tags
|
$moduleVersion = git describe --tags
|
||||||
Write-Host "Module version: $moduleVersion"
|
Write-Host "Module version: $moduleVersion"
|
||||||
$module = get-childItem -path . -Directory -Exclude ".*" | Select-Object -ExpandProperty Name
|
$module = get-childItem -path . -Directory -Exclude (".*", "Tests") | Select-Object -ExpandProperty Name
|
||||||
Write-Host "Publishing module $module to Gitea"
|
Write-Host "Publishing module $module to Gitea"
|
||||||
Publish-Module -Path $module -Repository 'GiteaPrivate' -NuGetApiKey "${{ secrets.PACKAGES_TOKEN }}"
|
Publish-Module -Path $module -Repository 'GiteaPublic' -NuGetApiKey "${{ secrets.PACKAGES_TOKEN }}"
|
||||||
Write-Host "Module $module published to Gitea"
|
Write-Host "Module $module published to Gitea"
|
||||||
|
|
||||||
- name: Create draft release
|
- name: Create draft release
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
RootModule = 'PS-GiteaUtilities.psm1'
|
RootModule = 'PS-GiteaUtilities.psm1'
|
||||||
|
|
||||||
# Version number of this module.
|
# Version number of this module.
|
||||||
ModuleVersion = '1.0.0'
|
ModuleVersion = '1.5.0'
|
||||||
|
|
||||||
# Supported PSEditions
|
# Supported PSEditions
|
||||||
# CompatiblePSEditions = @()
|
# CompatiblePSEditions = @()
|
||||||
@@ -69,7 +69,7 @@ PowerShellVersion = '5.1'
|
|||||||
# NestedModules = @()
|
# NestedModules = @()
|
||||||
|
|
||||||
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||||
FunctionsToExport = 'Get-GiteaFileContent', 'Invoke-GiteaFileDownload'
|
FunctionsToExport = 'Set-GiteaConfiguration', 'Get-GiteaConfiguration', 'Get-GiteaFileContent', 'Invoke-GiteaFileDownload', 'Get-GiteaChildItem', 'Get-GiteaReleases'
|
||||||
|
|
||||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||||
CmdletsToExport = '*'
|
CmdletsToExport = '*'
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
173
Tests/Get-GiteaChildItem.Tests.ps1
Normal file
173
Tests/Get-GiteaChildItem.Tests.ps1
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
# Get-GiteaChildItem.Tests.ps1
|
||||||
|
|
||||||
|
# Import the module under test
|
||||||
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities\PS-GiteaUtilities.psm1'
|
||||||
|
Import-Module -Name $modulePath -Force
|
||||||
|
|
||||||
|
Describe 'Get-GiteaChildItem' {
|
||||||
|
|
||||||
|
BeforeEach {
|
||||||
|
# Mock config load
|
||||||
|
Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
giteaURL = 'https://mock.gitea.com'
|
||||||
|
defaultOwner = 'mockuser'
|
||||||
|
defaultRepo = 'mockrepo'
|
||||||
|
defaultBranch = 'main'
|
||||||
|
token = 'mocktoken'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mock LFS config
|
||||||
|
Mock -CommandName Get-GiteaLFSConfiguration -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @(".lfs")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mock web call to list files
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
name = "file1.txt"
|
||||||
|
path = "file1.txt"
|
||||||
|
type = "file"
|
||||||
|
size = 123
|
||||||
|
sha = "abc123"
|
||||||
|
download_url = "https://mock.gitea.com/file1.txt"
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
name = "subdir"
|
||||||
|
path = "subdir"
|
||||||
|
type = "dir"
|
||||||
|
size = 0
|
||||||
|
sha = $null
|
||||||
|
download_url = $null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When listing basic items' {
|
||||||
|
It 'Should return files and directories correctly' {
|
||||||
|
$result = Get-GiteaChildItem -repoOwner 'mockuser' -repoName 'mockrepo' -Path '' -token 'mocktoken'
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Count | Should -BeGreaterThan 0
|
||||||
|
|
||||||
|
$file = $result | Where-Object { $_.type -eq 'file' }
|
||||||
|
$dir = $result | Where-Object { $_.type -eq 'dir' }
|
||||||
|
|
||||||
|
$file.name | Should -Be 'file1.txt'
|
||||||
|
$dir.name | Should -Be 'subdir'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When filtering only files' {
|
||||||
|
It 'Should return only files when -File is used' {
|
||||||
|
$result = Get-GiteaChildItem -repoOwner 'mockuser' -repoName 'mockrepo' -Path '' -token 'mocktoken' -File
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Count | Should -Be 1
|
||||||
|
$result[0].type | Should -Be 'file'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When recursing into directories' {
|
||||||
|
BeforeEach {
|
||||||
|
# Mock recursion call
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
param($Uri)
|
||||||
|
|
||||||
|
if ($Uri -like "*subdir*") {
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
name = "nestedfile.txt"
|
||||||
|
path = "subdir/nestedfile.txt"
|
||||||
|
type = "file"
|
||||||
|
size = 456
|
||||||
|
sha = "def456"
|
||||||
|
download_url = "https://mock.gitea.com/subdir/nestedfile.txt"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
name = "file1.txt"
|
||||||
|
path = "file1.txt"
|
||||||
|
type = "file"
|
||||||
|
size = 123
|
||||||
|
sha = "abc123"
|
||||||
|
download_url = "https://mock.gitea.com/file1.txt"
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
name = "subdir"
|
||||||
|
path = "subdir"
|
||||||
|
type = "dir"
|
||||||
|
size = 0
|
||||||
|
sha = $null
|
||||||
|
download_url = $null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should retrieve nested files when -Recurse is used' {
|
||||||
|
$result = Get-GiteaChildItem -repoOwner 'mockuser' -repoName 'mockrepo' -Path '' -token 'mocktoken' -Recurse
|
||||||
|
|
||||||
|
$nested = $result | Where-Object { $_.Path -eq 'subdir/nestedfile.txt' }
|
||||||
|
|
||||||
|
$nested | Should -Not -BeNullOrEmpty
|
||||||
|
$nested.size | Should -Be 456
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When recursion depth limit is enforced' {
|
||||||
|
BeforeEach {
|
||||||
|
# Same recursion mock as above
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
param($Uri)
|
||||||
|
|
||||||
|
if ($Uri -like "*subdir*") {
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
name = "nestedfile.txt"
|
||||||
|
path = "subdir/nestedfile.txt"
|
||||||
|
type = "file"
|
||||||
|
size = 456
|
||||||
|
sha = "def456"
|
||||||
|
download_url = "https://mock.gitea.com/subdir/nestedfile.txt"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
name = "file1.txt"
|
||||||
|
path = "file1.txt"
|
||||||
|
type = "file"
|
||||||
|
size = 123
|
||||||
|
sha = "abc123"
|
||||||
|
download_url = "https://mock.gitea.com/file1.txt"
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
name = "subdir"
|
||||||
|
path = "subdir"
|
||||||
|
type = "dir"
|
||||||
|
size = 0
|
||||||
|
sha = $null
|
||||||
|
download_url = $null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should not recurse deeper than depth limit' {
|
||||||
|
$result = Get-GiteaChildItem -repoOwner 'mockuser' -repoName 'mockrepo' -Path '' -token 'mocktoken' -Recurse -Depth 0
|
||||||
|
|
||||||
|
$nested = $result | Where-Object { $_.Path -eq 'subdir/nestedfile.txt' }
|
||||||
|
$nested | Should -BeNullOrEmpty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
Tests/Get-GiteaConfiguration.tests.ps1
Normal file
75
Tests/Get-GiteaConfiguration.tests.ps1
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Get-GiteaConfiguration.Tests.ps1
|
||||||
|
|
||||||
|
# Import the module under test
|
||||||
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities\PS-GiteaUtilities.psm1'
|
||||||
|
Import-Module -Name $modulePath -Force
|
||||||
|
|
||||||
|
Describe 'Get-GiteaConfiguration' {
|
||||||
|
|
||||||
|
Context 'When configuration file exists' {
|
||||||
|
BeforeEach {
|
||||||
|
# Mock filesystem and import
|
||||||
|
Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $true }
|
||||||
|
Mock -CommandName Import-Clixml -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
giteaURL = 'https://gitea.example.com'
|
||||||
|
token = 'ABC123'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should import configuration and return it' {
|
||||||
|
$result = Get-GiteaConfiguration
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.giteaURL | Should -Be 'https://gitea.example.com'
|
||||||
|
$result.token | Should -Be 'ABC123'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should create global variables when LoadVariables is used' {
|
||||||
|
# Remove any existing variables first
|
||||||
|
Remove-Variable -Name giteaURL, token -Scope Global -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
Get-GiteaConfiguration -LoadVariables
|
||||||
|
|
||||||
|
(Get-Variable -Name giteaURL -Scope Global).Value | Should -Be 'https://gitea.example.com'
|
||||||
|
(Get-Variable -Name token -Scope Global).Value | Should -Be 'ABC123'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should overwrite existing variables when Force is used' {
|
||||||
|
# Set initial variables
|
||||||
|
Set-Variable -Name giteaURL -Value 'OldURL' -Scope Global
|
||||||
|
Set-Variable -Name token -Value 'OldToken' -Scope Global
|
||||||
|
|
||||||
|
Get-GiteaConfiguration -LoadVariables -Force
|
||||||
|
|
||||||
|
(Get-Variable -Name giteaURL -Scope Global).Value | Should -Be 'https://gitea.example.com'
|
||||||
|
(Get-Variable -Name token -Scope Global).Value | Should -Be 'ABC123'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should not overwrite existing variables without Force' {
|
||||||
|
# Set initial variables
|
||||||
|
Set-Variable -Name giteaURL -Value 'OldURL' -Scope Global
|
||||||
|
Set-Variable -Name token -Value 'OldToken' -Scope Global
|
||||||
|
|
||||||
|
Get-GiteaConfiguration -LoadVariables
|
||||||
|
|
||||||
|
(Get-Variable -Name giteaURL -Scope Global).Value | Should -Be 'OldURL'
|
||||||
|
(Get-Variable -Name token -Scope Global).Value | Should -Be 'OldToken'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When configuration file does not exist' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $false }
|
||||||
|
Mock -CommandName Write-Warning -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should return null and warn the user' {
|
||||||
|
$result = Get-GiteaConfiguration
|
||||||
|
|
||||||
|
$result | Should -BeNullOrEmpty
|
||||||
|
Assert-MockCalled -CommandName Write-Warning -ModuleName PS-GiteaUtilities -Times 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
119
Tests/Get-GiteaFileContent.Tests.ps1
Normal file
119
Tests/Get-GiteaFileContent.Tests.ps1
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# Get-GiteaFileContent.Tests.ps1
|
||||||
|
|
||||||
|
# Import the module under test
|
||||||
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities\PS-GiteaUtilities.psm1'
|
||||||
|
Import-Module -Name $modulePath -Force
|
||||||
|
|
||||||
|
Describe 'Get-GiteaFileContent' {
|
||||||
|
|
||||||
|
Context 'When all parameters are provided' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
content = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello World'))
|
||||||
|
size = 11
|
||||||
|
sha = 'fake-sha'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should return file content without decoding by default' {
|
||||||
|
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'README.md' -token 'abc123'
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Success | Should -Be $true
|
||||||
|
$result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello World')))
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should decode content when -decode is used' {
|
||||||
|
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'README.md' -token 'abc123' -decode
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Success | Should -Be $true
|
||||||
|
$result.Content | Should -Be 'Hello World'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When missing parameters and config is loaded' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
giteaURL = 'https://mock.gitea.com'
|
||||||
|
defaultOwner = 'mockuser'
|
||||||
|
defaultRepo = 'mockrepo'
|
||||||
|
defaultBranch = 'main'
|
||||||
|
token = 'mocktoken'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
content = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Mock Config Content'))
|
||||||
|
size = 20
|
||||||
|
sha = 'mock-sha'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should load configuration from Get-GiteaConfiguration if not all parameters are given' {
|
||||||
|
$result = Get-GiteaFileContent -filePath 'test.ps1'
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Path | Should -Be 'test.ps1'
|
||||||
|
$result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Mock Config Content')))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When API call fails' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith { throw "API call failed" }
|
||||||
|
Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should capture error and mark result as unsuccessful' {
|
||||||
|
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'badfile.ps1' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Success | Should -Be $false
|
||||||
|
$result.Error | Should -Match 'API call failed'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Context 'Parameter validation' {
|
||||||
|
It 'Should throw if required parameters are missing and no config' {
|
||||||
|
Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith { return $null }
|
||||||
|
|
||||||
|
{ Get-GiteaFileContent -filePath 'something.ps1' } | Should -Throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When decoding file content' {
|
||||||
|
BeforeEach {
|
||||||
|
# Simulate API returning Base64 content
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
content = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello from API!'))
|
||||||
|
size = 15
|
||||||
|
sha = 'fake-sha-for-decode'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should return base64 encoded content by default (no decode switch)' {
|
||||||
|
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'testfile.txt' -token 'abc123'
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Success | Should -Be $true
|
||||||
|
$result.Content | Should -Be ([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello from API!')))
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should decode base64 content into plain text when -decode is used' {
|
||||||
|
$result = Get-GiteaFileContent -repoOwner 'user' -repoName 'repo' -filePath 'testfile.txt' -token 'abc123' -decode
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Success | Should -Be $true
|
||||||
|
$result.Content | Should -Be 'Hello from API!'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
117
Tests/Get-GiteaReleases.Tests.ps1
Normal file
117
Tests/Get-GiteaReleases.Tests.ps1
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Get-GiteaReleases.Tests.ps1
|
||||||
|
|
||||||
|
# Import the module
|
||||||
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities\PS-GiteaUtilities.psm1'
|
||||||
|
Import-Module -Name $modulePath -Force
|
||||||
|
|
||||||
|
Describe 'Get-GiteaReleases' {
|
||||||
|
|
||||||
|
BeforeEach {
|
||||||
|
# Mock configuration load
|
||||||
|
Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{
|
||||||
|
giteaURL = 'https://mock.gitea.com'
|
||||||
|
defaultOwner = 'mockuser'
|
||||||
|
token = 'mocktoken'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mock API response
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @(
|
||||||
|
@{
|
||||||
|
id = 1
|
||||||
|
tag_name = "v1.0"
|
||||||
|
target_commitish = "main"
|
||||||
|
name = "Release 1"
|
||||||
|
body = "Initial release"
|
||||||
|
url = "https://mock.gitea.com/api/v1/releases/1"
|
||||||
|
html_url = "https://mock.gitea.com/releases/v1.0"
|
||||||
|
tarball_url = "https://mock.gitea.com/releases/v1.0.tar.gz"
|
||||||
|
zipball_url = "https://mock.gitea.com/releases/v1.0.zip"
|
||||||
|
upload_url = "https://mock.gitea.com/releases/uploads"
|
||||||
|
draft = $false
|
||||||
|
prerelease = $false
|
||||||
|
created_at = "2024-01-01T00:00:00Z"
|
||||||
|
published_at = "2024-01-01T01:00:00Z"
|
||||||
|
author = @{
|
||||||
|
id = 101
|
||||||
|
username = "devuser"
|
||||||
|
email = "dev@norwichct.org"
|
||||||
|
avatar_url = "https://mock.gitea.com/avatar.jpg"
|
||||||
|
html_url = "https://mock.gitea.com/devuser"
|
||||||
|
}
|
||||||
|
assets = @(
|
||||||
|
@{
|
||||||
|
id = 201
|
||||||
|
name = "tool.exe"
|
||||||
|
size = 123456
|
||||||
|
download_count = 42
|
||||||
|
created_at = "2024-01-01T00:30:00Z"
|
||||||
|
uuid = "uuid-1234"
|
||||||
|
browser_download_url = "https://mock.gitea.com/releases/assets/tool.exe"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'Basic usage' {
|
||||||
|
It 'Should return a list of release objects' {
|
||||||
|
$result = Get-GiteaReleases -repoOwner 'mockuser' -repoName 'mockrepo' -token 'mocktoken'
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result[0].Name | Should -Be 'Release 1'
|
||||||
|
$result[0].Author.Username | Should -Be 'devuser'
|
||||||
|
$result[0].Assets.Count | Should -Be 1
|
||||||
|
$result[0].Assets[0].Name | Should -Be 'tool.exe'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'Optional switches affect URL' {
|
||||||
|
It 'Should include draft=true and pre-release=true in URL if switches are set' {
|
||||||
|
$calledUrl = $null
|
||||||
|
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
param($Uri)
|
||||||
|
$script:calledUrl = $Uri
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
Get-GiteaReleases -repoOwner 'mockuser' -repoName 'mockrepo' -includeDrafts -includePreReleases -page 2 -limit 10 -token 'mocktoken'
|
||||||
|
|
||||||
|
$script:calledUrl | Should -Match 'draft=true'
|
||||||
|
$script:calledUrl | Should -Match 'pre-release=true'
|
||||||
|
$script:calledUrl | Should -Match 'page=2'
|
||||||
|
$script:calledUrl | Should -Match 'limit=10'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When required params are missing and no config' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith { return $null }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should throw when required parameters are not supplied' {
|
||||||
|
{ Get-GiteaReleases -repoName 'mockrepo' } | Should -Throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When API call fails' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Invoke-RestMethod -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
throw "API call failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should catch and handle the error' {
|
||||||
|
$null = Get-GiteaReleases -repoOwner 'mockuser' -repoName 'mockrepo' -token 'mocktoken'
|
||||||
|
# Expect no throw, Write-Error should catch it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
150
Tests/Invoke-GiteaFileDownload.Tests.ps1
Normal file
150
Tests/Invoke-GiteaFileDownload.Tests.ps1
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
# Invoke-GiteaFileDownload.Tests.ps1
|
||||||
|
|
||||||
|
# Import the module under test
|
||||||
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities\PS-GiteaUtilities.psm1'
|
||||||
|
Import-Module -Name $modulePath -Force
|
||||||
|
|
||||||
|
Describe 'Invoke-GiteaFileDownload' {
|
||||||
|
|
||||||
|
BeforeEach {
|
||||||
|
# Always mock Get-GiteaConfiguration to avoid needing real config
|
||||||
|
Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
return @{ token = 'mocktoken' }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Correct webClient Mock: headers, download, dispose
|
||||||
|
Mock -CommandName New-Object -ModuleName PS-GiteaUtilities -ParameterFilter { $TypeName -eq 'System.Net.WebClient' } -MockWith {
|
||||||
|
$headers = New-Object System.Net.WebHeaderCollection
|
||||||
|
|
||||||
|
# Create a real object
|
||||||
|
$webClient = New-Object PSObject
|
||||||
|
|
||||||
|
# Add Headers
|
||||||
|
Add-Member -InputObject $webClient -MemberType NoteProperty -Name Headers -Value $headers
|
||||||
|
|
||||||
|
# Add a DownloadFile method
|
||||||
|
Add-Member -InputObject $webClient -MemberType ScriptMethod -Name DownloadFile -Value {
|
||||||
|
param($url, $path)
|
||||||
|
# Fake download (do nothing)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a Dispose method
|
||||||
|
Add-Member -InputObject $webClient -MemberType ScriptMethod -Name Dispose -Value {
|
||||||
|
# Fake dispose (do nothing)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $webClient
|
||||||
|
}
|
||||||
|
# Mock filesystem behavior
|
||||||
|
Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $false }
|
||||||
|
Mock -CommandName New-Item -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
|
||||||
|
# Clean captured download data before each test
|
||||||
|
$script:LastDownloadUrl = $null
|
||||||
|
$script:LastDownloadPath = $null
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When all parameters are valid' {
|
||||||
|
It 'Should download a file successfully' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' -token 'abc123'
|
||||||
|
|
||||||
|
$result | Should -Not -BeNullOrEmpty
|
||||||
|
$result.Result | Should -Be 'Success'
|
||||||
|
$result.Path | Should -Match 'file\.txt$'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When specifying an outputPath' {
|
||||||
|
It 'Should create a path based on outputPath' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' `
|
||||||
|
-outputPath 'docs/manual/' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Path | Should -Match 'docs[\\/]+manual[\\/]+file\.txt$'
|
||||||
|
$result.Result | Should -Be 'Success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When specifying an outputName' {
|
||||||
|
It 'Should download file and name it based on outputName' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' `
|
||||||
|
-outputName 'newfile.txt' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Path | Should -Match 'newfile\.txt$'
|
||||||
|
$result.Result | Should -Be 'Success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When specifying an outputName and outputPath' {
|
||||||
|
It 'Should download file and name it based on outputName' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' `
|
||||||
|
-outputPath 'docs/manual/' -outputName 'newfile.txt' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Path | Should -Match 'docs[\\/]+manual[\\/]+newfile\.txt$'
|
||||||
|
$result.Result | Should -Be 'Success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When using -PreserveRelativePath' {
|
||||||
|
It 'Should preserve the relative path structure' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' `
|
||||||
|
-PreserveRelativePath -token 'abc123'
|
||||||
|
|
||||||
|
$result.Path | Should -Match 'path[\\/]+to[\\/]+file\.txt$'
|
||||||
|
$result.Result | Should -Be 'Success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When skipping directories' {
|
||||||
|
It 'Should skip items with type = dir' {
|
||||||
|
$result = Invoke-GiteaFileDownload -outputPath 'docs/' -type 'dir' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Result | Should -Be 'Skipped'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When file exists and -Force is not used' {
|
||||||
|
BeforeEach {
|
||||||
|
# Simulate file already exists
|
||||||
|
Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
param($Path, $PathType)
|
||||||
|
if ($PathType -eq 'Leaf') { return $true } else { return $false }
|
||||||
|
}
|
||||||
|
Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should not overwrite existing file without Force' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/existingfile.txt' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Result | Should -Be 'Skipped'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When download fails' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName New-Object -ModuleName PS-GiteaUtilities -ParameterFilter { $TypeName -eq 'System.Net.WebClient' } -MockWith {
|
||||||
|
$headers = New-Object System.Net.WebHeaderCollection
|
||||||
|
|
||||||
|
$webClient = New-Object PSObject
|
||||||
|
Add-Member -InputObject $webClient -MemberType NoteProperty -Name Headers -Value $headers
|
||||||
|
Add-Member -InputObject $webClient -MemberType ScriptMethod -Name DownloadFile -Value {
|
||||||
|
throw "Download failed intentionally"
|
||||||
|
}
|
||||||
|
Add-Member -InputObject $webClient -MemberType ScriptMethod -Name Dispose -Value {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
return $webClient
|
||||||
|
}
|
||||||
|
Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $false }
|
||||||
|
Mock -CommandName New-Item -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should capture error and mark download as failed' {
|
||||||
|
$result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/badfile.txt' -token 'abc123'
|
||||||
|
|
||||||
|
$result.Result | Should -Be 'Failure'
|
||||||
|
$result.Error | Should -Match 'Failed to download'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
Tests/Set-GiteaConfiguration.Tests.ps1
Normal file
64
Tests/Set-GiteaConfiguration.Tests.ps1
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# Set-GiteaConfiguration.Tests.ps1
|
||||||
|
|
||||||
|
Describe 'Set-GiteaConfiguration' {
|
||||||
|
|
||||||
|
BeforeAll {
|
||||||
|
# Import the module dynamically
|
||||||
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities\PS-GiteaUtilities.psm1'
|
||||||
|
Import-Module -Name $modulePath -Force
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'Parameter Validation' {
|
||||||
|
It 'Should throw a MissingArgument exception if required parameters are missing' {
|
||||||
|
{ Set-GiteaConfiguration -giteaURL -token} | Should -Throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Context 'Configuration Setup' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $false }
|
||||||
|
Mock -CommandName New-Item -ModuleName PS-GiteaUtilities -MockWith { return $null }
|
||||||
|
Mock -CommandName Export-Clixml -ModuleName PS-GiteaUtilities -MockWith { return $null }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should create the configuration directory if it does not exist' {
|
||||||
|
Set-GiteaConfiguration -giteaURL 'https://gitea.example.com' -token 'ABC123' -defaultOwner 'testuser' -defaultRepo 'testrepo'
|
||||||
|
|
||||||
|
Assert-MockCalled -CommandName New-Item -ModuleName PS-GiteaUtilities -Times 1
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should export the configuration to an XML file' {
|
||||||
|
Set-GiteaConfiguration -giteaURL 'https://gitea.example.com' -token 'ABC123' -defaultOwner 'testuser' -defaultRepo 'testrepo'
|
||||||
|
|
||||||
|
Assert-MockCalled -CommandName Export-Clixml -ModuleName PS-GiteaUtilities -Times 1
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should set defaultBranch to "main" if not specified' {
|
||||||
|
# Important: override the Export-Clixml mock to capture the config
|
||||||
|
Mock -CommandName Export-Clixml -ModuleName PS-GiteaUtilities -MockWith {
|
||||||
|
param($Path, $InputObject)
|
||||||
|
$script:CapturedConfig = $InputObject
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-GiteaConfiguration -giteaURL 'https://gitea.example.com' -token 'ABC123' -defaultOwner 'testuser' -defaultRepo 'testrepo'
|
||||||
|
|
||||||
|
$script:CapturedConfig.defaultBranch | Should -Be 'main'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'When directory already exists' {
|
||||||
|
BeforeEach {
|
||||||
|
Mock -CommandName Test-Path -MockWith { $true }
|
||||||
|
Mock -CommandName New-Item -MockWith { throw "Should not be called" }
|
||||||
|
Mock -CommandName Export-Clixml -MockWith { return $null }
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Should not attempt to create the directory' {
|
||||||
|
Set-GiteaConfiguration -giteaURL 'https://gitea.example.com' -token 'ABC123' -defaultOwner 'testuser' -defaultRepo 'testrepo'
|
||||||
|
|
||||||
|
Assert-MockCalled -CommandName New-Item -Times 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user