Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Scripts/Sales Reconciliation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

select CONCAT(YEAR(transactiondate),'-', FORMAT(transactiondate, 'MM')),
/*select CONCAT(YEAR(transactiondate),'-', FORMAT(transactiondate, 'MM')),
count(*) as 'count',
SUM(case [transaction].TransactionType
WHEN 'Logon' THEN 1
Expand All @@ -20,7 +20,7 @@ SUM([transaction].TransactionAmount) as totalamount
from [transaction]
group by CONCAT(YEAR(transactiondate),'-', FORMAT(transactiondate, 'MM'))
order by CONCAT(YEAR(transactiondate),'-', FORMAT(transactiondate, 'MM')) asc

*/

fromAll()
.when({
Expand Down
Binary file added Scripts/Scavenge.xml
Binary file not shown.
78 changes: 78 additions & 0 deletions Scripts/Tests/Scavenge.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
Describe 'scavenge.ps1' {
It 'posts to /admin/scavenge after trimming a trailing slash from BaseUrl' {
$scriptUnderTest = (Resolve-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'scavenge.ps1')).Path
$expectedUri = 'http://localhost:2113/admin/scavenge'
$captured = [pscustomobject]@{
Count = 0
Uri = $null
Headers = $null
}

Mock Invoke-RestMethod {
$captured.Count++
$captured.Uri = $Uri
$captured.Headers = $Headers
@{ status = 'ok' }
} -ParameterFilter {
$Method -eq 'Post'
}

& $scriptUnderTest -BaseUrl 'http://localhost:2113/'

$captured.Count | Should -Be 1
$captured.Uri | Should -Be $expectedUri
$captured.Headers.Accept | Should -Be 'application/json'
$captured.Headers.'Content-Type' | Should -Be 'application/json'
$captured.Headers.ContainsKey('Authorization') | Should -BeFalse
}

It 'adds a Basic Authorization header when username and password are both provided' {
$scriptUnderTest = (Resolve-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'scavenge.ps1')).Path
$expectedUri = 'http://localhost:2113/admin/scavenge'
$expectedAuth = 'Basic ' + [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes('alice:secret'))
$captured = [pscustomobject]@{
Count = 0
Uri = $null
Headers = $null
}

Mock Invoke-RestMethod {
$captured.Count++
$captured.Uri = $Uri
$captured.Headers = $Headers
@{ status = 'ok' }
} -ParameterFilter {
$Method -eq 'Post'
}

& $scriptUnderTest -BaseUrl 'http://localhost:2113' -Username 'alice' -Password 'secret'

$captured.Count | Should -Be 1
$captured.Uri | Should -Be $expectedUri
$captured.Headers.Authorization | Should -Be $expectedAuth
}

It 'does not add an Authorization header when only one credential is supplied' {
$scriptUnderTest = (Resolve-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'scavenge.ps1')).Path
$captured = [pscustomobject]@{
Count = 0
Uri = $null
Headers = $null
}

Mock Invoke-RestMethod {
$captured.Count++
$captured.Uri = $Uri
$captured.Headers = $Headers
@{ status = 'ok' }
} -ParameterFilter {
$Method -eq 'Post'
}

& $scriptUnderTest -BaseUrl 'http://localhost:2113' -Username 'alice'

$captured.Count | Should -Be 1
$captured.Uri | Should -Be 'http://localhost:2113/admin/scavenge'
$captured.Headers.ContainsKey('Authorization') | Should -BeFalse
}
}
28 changes: 28 additions & 0 deletions Scripts/scavenge.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
param(
[string]$BaseUrl = "http://localhost:2113",
[string]$Username,
[string]$Password
)

$BaseUrl = $BaseUrl.TrimEnd('/')
$uri = "$BaseUrl/admin/scavenge"

$headers = @{
Accept = 'application/json'
'Content-Type' = 'application/json'
}

if ($Username -and $Password) {
$pair = "$Username`:$Password"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$encoded = [Convert]::ToBase64String($bytes)
$headers['Authorization'] = "Basic $encoded"
}

try {
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers
}
catch {
Write-Error "POST to $uri failed: $($_.Exception.Message)"
exit 1
}
113 changes: 113 additions & 0 deletions docs/superpowers/plans/2026-07-09-scavenge-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Scavenge Script Tests Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Add focused unit tests for `Scripts/scavenge.ps1` that cover request construction and authentication header behavior.

**Architecture:** Keep the existing script unchanged unless a test exposes a real behavioral gap. Add one Pester test file alongside the existing script tests so the new coverage stays in the same style and location as the current PowerShell tests.

**Tech Stack:** PowerShell, Pester

## Global Constraints

- Keep tests local and deterministic; do not hit the real `http://localhost:2113` service.
- Follow the existing script-test style in `Scripts/Tests/Invoke-DailySettlementProcessing.Tests.ps1`.

---

### Task 1: Add scavenge script tests

**Files:**
- Create: `Scripts/Tests/Scavenge.Tests.ps1`

**Interfaces:**
- Consumes: `Scripts/scavenge.ps1`
- Produces: Pester coverage for the POST target URI and auth header branching

- [ ] **Step 1: Write the test file**

```powershell
Describe 'scavenge.ps1' {
It 'posts to /admin/scavenge after trimming a trailing slash from BaseUrl' {
$scriptUnderTest = (Resolve-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'scavenge.ps1')).Path
$expectedUri = 'http://localhost:2113/admin/scavenge'
$captured = [pscustomobject]@{
Count = 0
Uri = $null
Headers = $null
}

Mock Invoke-RestMethod {
$captured.Count++
$captured.Uri = $Uri
$captured.Headers = $Headers
@{ status = 'ok' }
} -ParameterFilter {
$Method -eq 'Post'
}

& $scriptUnderTest -BaseUrl 'http://localhost:2113/'

$captured.Count | Should -Be 1
$captured.Uri | Should -Be $expectedUri
$captured.Headers.Accept | Should -Be 'application/json'
$captured.Headers.'Content-Type' | Should -Be 'application/json'
$captured.Headers.ContainsKey('Authorization') | Should -BeFalse
}

It 'adds a Basic Authorization header when username and password are both provided' {
$scriptUnderTest = (Resolve-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'scavenge.ps1')).Path
$expectedUri = 'http://localhost:2113/admin/scavenge'
$expectedAuth = 'Basic ' + [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes('alice:secret'))
$captured = [pscustomobject]@{
Count = 0
Uri = $null
Headers = $null
}

Mock Invoke-RestMethod {
$captured.Count++
$captured.Uri = $Uri
$captured.Headers = $Headers
@{ status = 'ok' }
} -ParameterFilter {
$Method -eq 'Post'
}

& $scriptUnderTest -BaseUrl 'http://localhost:2113' -Username 'alice' -Password 'secret'

$captured.Count | Should -Be 1
$captured.Uri | Should -Be $expectedUri
$captured.Headers.Authorization | Should -Be $expectedAuth
}

It 'does not add an Authorization header when only one credential is supplied' {
$scriptUnderTest = (Resolve-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'scavenge.ps1')).Path
$captured = [pscustomobject]@{
Count = 0
Uri = $null
Headers = $null
}

Mock Invoke-RestMethod {
$captured.Count++
$captured.Uri = $Uri
$captured.Headers = $Headers
@{ status = 'ok' }
} -ParameterFilter {
$Method -eq 'Post'
}

& $scriptUnderTest -BaseUrl 'http://localhost:2113' -Username 'alice'

$captured.Count | Should -Be 1
$captured.Uri | Should -Be 'http://localhost:2113/admin/scavenge'
$captured.Headers.ContainsKey('Authorization') | Should -BeFalse
}
}
```

- [ ] **Step 2: Run the test file**

Run: `Invoke-Pester Scripts/Tests/Scavenge.Tests.ps1`
Expected: all three tests pass
Loading