Files
orca/config/scripts/desktop-distribution/nsis/replace-cached-nsis-elevate.test.mjs
OrcaWinandOrcaWin 06178ea9af test: remove low-value build and packaging test inventories (#38593)
* test: remove low-value build and packaging test inventories

* ci: retire removed dependency resolution suite invocation

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-05 08:47:58 -08:00

162 lines
6.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { spawnSync } from 'node:child_process'
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join, resolve } from 'node:path'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import {
findCachedElevatePaths,
replaceCachedElevateHelpers,
summarizeSwap
} from './replace-cached-nsis-elevate.mjs'
// Inject app-builder-lib’s packed-path probe so tests need neither network nor warm toolset cache.
const probeFound = (path) => async () => ({ path, error: null })
const probeUnavailable = async () => ({ path: null, error: 'app-builder-lib not loadable' })
const projectRoot = resolve(import.meta.dirname, '../../../..')
const scriptPath = join(
projectRoot,
'config/scripts/desktop-distribution/nsis/replace-cached-nsis-elevate.mjs'
)
let scratch
beforeEach(() => {
scratch = mkdtempSync(join(tmpdir(), 'orca elevate swap '))
})
afterEach(() => {
rmSync(scratch, { recursive: true, force: true })
})
function makeCache(...relativeFiles) {
const cacheDir = join(scratch, 'Cache')
for (const relative of relativeFiles) {
const path = join(cacheDir, ...relative.split('/'))
mkdirSync(join(path, '..'), { recursive: true })
writeFileSync(path, 'unsigned-elevate')
}
mkdirSync(cacheDir, { recursive: true })
return cacheDir
}
describe('cached elevate.exe swap covers the real electron-builder layouts', () => {
// Model real <releaseName>/<archive>-<url hash> legacy/unified layouts; old <cache>/nsis matched neither. Custom layout is covered by probe tests.
// Allow nsis-resources overmatch: it ships plugins without elevate.exe and costs one cheap read; guessing narrower upstream naming is brittle.
// Replace all cached copies because only app-builder-lib knows which one repack chooses.
it('replaces every cached copy when several bundles are present', async () => {
const cacheDir = makeCache(
'nsis-3.0.4.1/nsis-3.0.4.1-1mx3n/elevate.exe',
'nsis@1.2.1/nsis-bundle-3.12-k4d9x/elevate.exe'
)
const signed = join(scratch, 'signed-elevate.exe')
writeFileSync(signed, 'signpath-signed-elevate')
const { replaced } = await replaceCachedElevateHelpers({
signedPath: signed,
cacheDir,
env: {},
probe: probeUnavailable
})
expect(replaced).toHaveLength(2)
for (const path of replaced) {
expect(readFileSync(path, 'utf8')).toBe('signpath-signed-elevate')
}
})
// Compare real cache scan against independent unbounded walk to catch vacuous empty matches; skip only if no bundle is cached.
})
describe('the probe, not the scan, decides whether the swap worked', () => {
// customNsisBinary uses nsis-version only as memoization key; URL-parent extraction directory can bypass nsis* scan.
it('covers a custom bundle the directory scan cannot match', async () => {
const relative = 'orca-nsis-mirror/nsis-custom-3.11-0zqp2/elevate.exe'
const cacheDir = makeCache(relative)
const packed = join(cacheDir, ...relative.split('/'))
const signed = join(scratch, 'signed-elevate.exe')
writeFileSync(signed, 'signpath-signed-elevate')
expect(findCachedElevatePaths(cacheDir, { env: {} })).toEqual([])
const result = await replaceCachedElevateHelpers({
signedPath: signed,
cacheDir,
env: {},
probe: probeFound(packed)
})
expect(result.toolsetReplaced).toBe(true)
expect(readFileSync(packed, 'utf8')).toBe('signpath-signed-elevate')
expect(summarizeSwap(result)).toEqual({ annotations: [], exitCode: 0 })
})
// Prefix-restored stale release can satisfy replaced.length while authoritative packed bundle sits outside scan; model both copies.
})
describe('a cached elevate.exe miss is not silent', () => {
// Override short-circuits downloads, so authoritative probe fails offline instead of fetching a toolset.
function runScript(cacheDir, nsisDir, signedPath) {
return spawnSync(process.execPath, [scriptPath, signedPath], {
cwd: projectRoot,
encoding: 'utf8',
env: {
...process.env,
ELECTRON_BUILDER_CACHE: cacheDir,
ELECTRON_BUILDER_NSIS_DIR: nsisDir
}
})
}
it('exits non-zero with an ::error:: annotation when no cached copy is found', () => {
const cacheDir = makeCache()
const emptyNsisDir = join(scratch, 'empty-nsis')
mkdirSync(emptyNsisDir, { recursive: true })
const signed = join(scratch, 'signed-elevate.exe')
writeFileSync(signed, 'signpath-signed-elevate')
const result = runScript(cacheDir, emptyNsisDir, signed)
expect(result.status).toBe(1)
expect(result.stdout).toContain('::error::No cached elevate.exe found')
})
it('warns on the scan-only path so green never means the probe was skipped', () => {
const cacheDir = makeCache('nsis-3.0.4.1/nsis-3.0.4.1-1mx3n/elevate.exe')
const emptyNsisDir = join(scratch, 'empty-nsis')
mkdirSync(emptyNsisDir, { recursive: true })
const signed = join(scratch, 'signed-elevate.exe')
writeFileSync(signed, 'signpath-signed-elevate')
const result = runScript(cacheDir, emptyNsisDir, signed)
expect(result.status).toBe(0)
expect(result.stdout).not.toContain('::error::')
expect(result.stdout).toContain('::warning::Could not ask app-builder-lib')
expect(
readFileSync(join(cacheDir, 'nsis-3.0.4.1', 'nsis-3.0.4.1-1mx3n', 'elevate.exe'), 'utf8')
).toBe('signpath-signed-elevate')
})
// Healthy release path replaces exact copy returned by app-builder-lib, requiring no warning.
it('exits clean when the probe resolves the copy the rebuild will pack', () => {
const cacheDir = makeCache()
const nsisDir = join(scratch, 'nsis-bundle')
mkdirSync(nsisDir, { recursive: true })
writeFileSync(join(nsisDir, 'elevate.exe'), 'unsigned-elevate')
const signed = join(scratch, 'signed-elevate.exe')
writeFileSync(signed, 'signpath-signed-elevate')
const result = runScript(cacheDir, nsisDir, signed)
expect(result.status).toBe(0)
expect(result.stdout).not.toContain('::error::')
expect(result.stdout).not.toContain('::warning::')
expect(result.stdout).toContain('the copy app-builder-lib will pack')
expect(readFileSync(join(nsisDir, 'elevate.exe'), 'utf8')).toBe('signpath-signed-elevate')
})
})