Files
wx-win-agent/scripts/windows/Test-DatabaseMerged.ps1
T
rogee 30df7ae433 feat: expand merged chat records directly from read-only databases
Add db merged with exact account/chat/local-ID selection and shard ambiguity checks. Preserve Int64 composite message types and parse bounded, DTD-free embedded record XML, including duplicate messages and source metadata. Revalidate cached keys against current page-1 HMAC; replace the SQL write probe with sqlite3_db_readonly. Core tests: 129 passed. Windows Session 0 database validation: 5/5; all 16 text/sender/source-ID/timestamp entries matched independent XML parsing. Read-only UI baseline: 3/3; zero sends.
2026-09-06 20:10:04 +08:00

44 lines
3.2 KiB
PowerShell

param(
[Parameter(Mandatory=$true)][string]$Executable,
[Parameter(Mandatory=$true)][string]$OutputDirectory,
[Parameter(Mandatory=$true)][string]$Account,
[string]$ChatId='filehelper',
[Parameter(Mandatory=$true)][long]$LocalId,
[Parameter(Mandatory=$true)][int]$ExpectedCount
)
$ErrorActionPreference='Stop'
$exe=(Resolve-Path $Executable).Path
if(Test-Path $OutputDirectory){throw 'Use a fresh evidence directory.'}
$out=(New-Item -ItemType Directory $OutputDirectory).FullName
$checks=New-Object System.Collections.Generic.List[object]
function Check([string]$Name,[string[]]$Arguments,[int]$ExpectedExit=0){
$raw=(& $exe @Arguments 2> "$out\$Name.stderr.txt" | Out-String)
$code=$LASTEXITCODE
$raw | Set-Content "$out\$Name.json" -Encoding UTF8
$checks.Add(@{Stage=$Name;ExitCode=$code;ExpectedExit=$ExpectedExit})
if($code -ne $ExpectedExit){throw "$Name returned unexpected exit code."}
return ($raw | ConvertFrom-Json)
}
try {
$default=Check 'merged-default' @('db','merged','--account',$Account,'--chat',$ChatId,'--local-id',"$LocalId",'--timeout','60')
if($default.record.count -ne $ExpectedCount){throw 'Unexpected record count.'}
if($null -ne $default.record.title -or $null -ne $default.record.description -or @($default.record.messages | Where-Object {$null -ne $_.text -or $null -ne $_.senderName}).Count){throw 'Default output leaked record content.'}
$full=Check 'merged-content.private' @('db','merged','--account',$Account,'--chat',$ChatId,'--local-id',"$LocalId",'--include-content','--timeout','60')
if($full.record.count -ne $ExpectedCount -or $full.parent.LocalId -ne $LocalId){throw 'Selected record mismatch.'}
if(@($full.record.messages | Where-Object {$_.dataType -ne 1 -or $null -eq $_.text -or !$_.senderName -or !$_.timestamp -or !$_.sourceServerId}).Count){throw 'Expected complete text-message metadata in this fixture.'}
if(@($full.record.messages.path | Select-Object -Unique).Count -ne $ExpectedCount){throw 'Message paths are not unique.'}
$metadata=Check 'database-readonly' @('db','query','--account',$Account,'--database',$full.database,'--timeout','60')
if(!$metadata.metadata.WritesRejected){throw 'Database is not reported read-only.'}
$invalid=Check 'invalid-id' @('db','merged','--account',$Account,'--chat',$ChatId,'--local-id','0','--timeout','30') 1
if($invalid.error -ne 'InvalidArgument'){throw 'Wrong invalid-ID error.'}
$missing=Check 'missing-id' @('db','merged','--account',$Account,'--chat',$ChatId,'--local-id','9223372036854775807','--timeout','60') 1
if($missing.error -ne 'ControlNotFound'){throw 'Wrong missing-ID error.'}
} catch {
@{Message=$_.Exception.Message;Line=$_.InvocationInfo.ScriptLineNumber} | ConvertTo-Json | Set-Content "$out\error.json" -Encoding UTF8
} finally {
$success=($checks.Count -eq 5 -and @($checks | Where-Object {$_.ExitCode -ne $_.ExpectedExit}).Count -eq 0 -and !(Test-Path "$out\error.json"))
@{Success=$success;Checks=@($checks.ToArray());ProcessSessionId=[Diagnostics.Process]::GetCurrentProcess().SessionId;RecordCount=$ExpectedCount;SendsAttempted=0;BinarySha256=(Get-FileHash $exe -Algorithm SHA256).Hash} |
ConvertTo-Json -Depth 6 | Set-Content "$out\summary.json" -Encoding UTF8
}
if(!$success){exit 1}