project-nomad/admin/tests/unit/superseded_resource.spec.ts

119 lines
3.5 KiB
TypeScript

import * as assert from 'node:assert/strict'
import { test } from 'node:test'
import { join } from 'node:path'
import { decideSupersededDeletion } from '../../app/utils/superseded_resource.js'
const STORAGE = join('/app', 'storage', 'zim')
const OLD = join(STORAGE, 'ifixit_en_all_2026-03.zim')
const NEW = join(STORAGE, 'ifixit_en_all_2026-05.zim')
test('first install (no prior row) deletes nothing', () => {
const d = decideSupersededDeletion({
existing: null,
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'first_install')
})
test('superseded prior version is deleted', () => {
const d = decideSupersededDeletion({
existing: { file_path: OLD, version: '2026-03' },
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, true)
assert.equal(d.reason, 'superseded')
assert.equal(d.path, OLD)
})
test('same file path is never deleted (re-download)', () => {
const d = decideSupersededDeletion({
existing: { file_path: NEW, version: '2026-05' },
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'same_file')
})
test('old file is NOT deleted until the new file is confirmed on disk', () => {
const d = decideSupersededDeletion({
existing: { file_path: OLD, version: '2026-03' },
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: false,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'new_file_missing')
})
test('downgrade / reinstall of an older version does not wipe the newer file', () => {
const d = decideSupersededDeletion({
existing: { file_path: NEW, version: '2026-05' },
newFilePath: OLD,
newVersion: '2026-03',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'not_newer')
})
test('equal version is not considered newer', () => {
const d = decideSupersededDeletion({
existing: { file_path: join(STORAGE, 'ifixit_en_all_2026-05a.zim'), version: '2026-05' },
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'not_newer')
})
test('refuses to delete a path outside the storage directory', () => {
const d = decideSupersededDeletion({
existing: { file_path: '/etc/passwd', version: '2026-03' },
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'outside_storage')
})
test('refuses a traversal escape that only looks like it is under storage', () => {
const d = decideSupersededDeletion({
existing: { file_path: join(STORAGE, '..', 'mysql', 'data.ibd'), version: '2026-03' },
newFilePath: NEW,
newVersion: '2026-05',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, false)
assert.equal(d.reason, 'outside_storage')
})
test('YYYY-MM-DD versions order correctly against YYYY-MM', () => {
const d = decideSupersededDeletion({
existing: { file_path: OLD, version: '2026-05' },
newFilePath: NEW,
newVersion: '2026-05-12',
newFileExists: true,
storageBaseDir: STORAGE,
})
assert.equal(d.delete, true)
assert.equal(d.reason, 'superseded')
})