Files
ArtPlayer/test/pages-recovery.test.js

35 lines
1.8 KiB
JavaScript

import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import fs from 'node:fs'
import path from 'node:path'
// eslint-disable-next-line test/no-import-node-test -- Validate stale bytes and restoration ownership before directory replacement.
import test from 'node:test'
import { consumerDirectory, removeConsumer } from '../scripts/package-consumer.mjs'
import { replaceRehearsalSite, verifyRestoredTree } from '../scripts/pages/recovery.ts'
const contents = 'old'
const expected = { 'index.html': { bytes: contents.length, objectId: createHash('sha1').update(`blob ${contents.length}\0${contents}`).digest('hex') } }
test('site recovery rejects same-size corruption and incomplete preparation before replacing live files', () => {
const run = consumerDirectory()
try {
const site = path.join(run, 'site')
const prepared = path.join(run, 'prepared')
fs.mkdirSync(site)
fs.mkdirSync(prepared)
fs.writeFileSync(path.join(site, 'index.html'), 'new')
fs.writeFileSync(path.join(prepared, 'index.html'), 'bad')
assert.throws(() => verifyRestoredTree(prepared, expected), /Git blob differs/)
assert.throws(() => replaceRehearsalSite(run, expected), /Git blob differs/)
assert.equal(fs.readFileSync(path.join(site, 'index.html'), 'utf8'), 'new')
assert(!fs.existsSync(path.join(run, 'failed-site')))
fs.writeFileSync(path.join(prepared, 'index.html'), contents)
fs.writeFileSync(path.join(prepared, 'extra.js'), '')
assert.throws(() => replaceRehearsalSite(run, expected), /missing or additional/)
fs.unlinkSync(path.join(prepared, 'extra.js'))
replaceRehearsalSite(run, expected)
assert.equal(fs.readFileSync(path.join(site, 'index.html'), 'utf8'), 'old')
assert.equal(fs.readFileSync(path.join(run, 'failed-site/index.html'), 'utf8'), 'new')
}
finally { removeConsumer(run) }
})