// The image library: every picture this account generated, across all three // features, with thumbnails rather than originals and a delete that removes the // bytes and not only the row. const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const read = file => fs.readFileSync(path.join(__dirname, '..', file), 'utf8'); test('the listing is the owner’s own finished images, newest first', () => { const route = read('src/routes/generatedImages.js'); assert.match(route, /router\.get\('\/generated-images'/); // Scoped by owner in the statement, not filtered afterwards. assert.match(route, /owner_id=\$1 AND stage='done'/); assert.match(route, /ORDER BY created_at DESC/); // Unfinished jobs have nothing to show; listing one puts a broken frame in a // gallery. assert.match(route, /Only finished jobs/); }); test('paging is keyset, not OFFSET', () => { // A gallery that grows while you scroll repeats or skips a row under OFFSET. const route = read('src/routes/generatedImages.js'); assert.match(route, /created_at < \$/); assert.doesNotMatch(route, /\bOFFSET\s+\$?\d/i, 'no SQL OFFSET; the word in a comment is fine'); assert.match(route, /nextBefore/); }); test('a prompt that cannot be decrypted does not cost the gallery its picture', () => { const route = read('src/routes/generatedImages.js'); assert.match(route, /try \{ prompt = String\(encryption\.decryptString/); assert.match(route, /catch \(e\) \{ prompt = ''; \}/); }); test('deleting removes the bytes before the row, and refuses if it cannot', () => { // A row without its object is a broken image in a gallery; an object without // its row is only wasted space. Only one of those is allowed to happen. const lib = read('src/utils/generatedImages.js'); assert.match(lib, /async function discard\(id, owner\)/); const discard = lib.slice(lib.indexOf('async function discard')); const storageFirst = discard.indexOf('getStorage().remove(id)'); const rowSecond = discard.indexOf('DELETE FROM generated_image_jobs'); assert.ok(storageFirst > -1 && rowSecond > storageFirst, 'storage must be removed first'); assert.match(discard.slice(0, 800), /throw failure\(503, 'Image storage is unavailable; nothing was deleted'\)/); }); test('deleting removes the previews too, not just the original', () => { // Both derived widths live under their own prefix. Missing them leaves paid-for // bytes in the bucket that are still readable. const storage = read('src/utils/generatedImageStorage.js'); assert.match(storage, /async remove\(id\)/); assert.match(storage, /\['assets\/' \+ id\]\.concat\(THUMB_WIDTHS\.map/); }); test('the thumbnail widths have one definition', () => { // Two copies drift: a width written but never deleted is paid for once and // then left in the bucket forever. const storage = read('src/utils/generatedImageStorage.js'); const lib = read('src/utils/generatedImages.js'); assert.match(storage, /const THUMB_WIDTHS = Object\.freeze\(\[256, 640\]\)/); assert.match(lib, /const \{ THUMB_WIDTHS \} = storageUtil/); assert.doesNotMatch(lib, /THUMB_WIDTHS = Object\.freeze/, 'not defined twice'); assert.deepEqual(require('../src/utils/generatedImages').THUMB_WIDTHS, [256, 640]); }); test('a borrowed id deletes nothing rather than someone else’s picture', () => { const route = read('src/routes/generatedImages.js'); assert.match(route, /SELECT id FROM generated_image_jobs WHERE id=\$1 AND owner_id=\$2/); const lib = read('src/utils/generatedImages.js'); assert.match(lib, /DELETE FROM generated_image_jobs WHERE id=\$1 AND owner_id=\$2/); }); test('the grid asks for the stored preview, not the original', () => { // Thirty tiles at full size is thirty full-size downloads. const ui = read('public/js/myResources.js'); assert.match(ui, /setAttribute\('data-image-thumb', '256'\)/); assert.match(ui, /hydrateImage\(img, image\.imageUrl\)/, 'fetched through the authenticated loader, never a bare src'); }); test('the caption is a model-written prompt and never reaches the page as HTML', () => { const ui = read('public/js/myResources.js'); const tile = ui.slice(ui.indexOf('function imageTile'), ui.indexOf('function openImage')); assert.match(tile, /text\.textContent = image\.prompt/); assert.doesNotMatch(tile, /innerHTML/); }); test('the images tab loads on first open, not on page load', () => { // Most visits never open it, and it costs a query plus a thumbnail per tile. const ui = read('public/js/myResources.js'); assert.match(ui, /if \(!docs && !imagesLoaded\) loadImages\(true\)/); });