77 lines
3.3 KiB
JavaScript
77 lines
3.3 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
const path = require('node:path');
|
|
|
|
function deferred() {
|
|
let resolve, reject;
|
|
const promise = new Promise((yes, no) => { resolve = yes; reject = no; });
|
|
return { promise, resolve, reject };
|
|
}
|
|
|
|
function fixture() {
|
|
const context = vm.createContext({ document: { addEventListener() {}, getElementById() {} },
|
|
window: {}, console: { error() {} }, escapeHtml: value => value });
|
|
const Manager = vm.runInContext(fs.readFileSync(path.join(__dirname, '../../web/js/gallery.js'), 'utf8') + '\nGalleryManager;', context, { filename: path.join(__dirname, '../../web/js/gallery.js') });
|
|
const manager = Object.create(Manager.prototype);
|
|
const requests = new Map();
|
|
manager.extractImageMetadata = url => {
|
|
const pending = deferred();
|
|
requests.set(url, pending);
|
|
return pending.promise;
|
|
};
|
|
manager.displayMetadata = (metadata, panel) => {
|
|
panel.innerHTML = metadata?.positivePrompt || 'No metadata';
|
|
manager.currentMetadata = metadata;
|
|
};
|
|
manager.stopViewerSlideshow = () => {};
|
|
return { manager, requests, panel: { innerHTML: '', isConnected: true } };
|
|
}
|
|
|
|
test('a late response cannot overwrite the selected image or copy state', async () => {
|
|
const { manager, requests, panel } = fixture();
|
|
const first = manager.loadImageMetadata('old.png', panel);
|
|
const second = manager.loadImageMetadata('new.png', panel);
|
|
requests.get('new.png').resolve({ positivePrompt: 'new prompt' });
|
|
await second;
|
|
requests.get('old.png').resolve({ positivePrompt: 'old prompt' });
|
|
await first;
|
|
assert.equal(panel.innerHTML, 'new prompt');
|
|
assert.equal(manager.currentMetadata.positivePrompt, 'new prompt');
|
|
});
|
|
|
|
test('navigation clears old action data while the new request is pending', async () => {
|
|
const { manager, requests, panel } = fixture();
|
|
manager.currentMetadata = { positivePrompt: 'old prompt' };
|
|
const pending = manager.loadImageMetadata('new.png', panel);
|
|
assert.equal(manager.currentMetadata, null);
|
|
requests.get('new.png').resolve(null);
|
|
await pending;
|
|
assert.equal(manager.currentMetadata, null);
|
|
});
|
|
|
|
test('a stale error cannot replace newer metadata', async () => {
|
|
const { manager, requests, panel } = fixture();
|
|
const first = manager.loadImageMetadata('old.png', panel);
|
|
const second = manager.loadImageMetadata('new.png', panel);
|
|
requests.get('new.png').resolve({ positivePrompt: 'new prompt' });
|
|
await second;
|
|
requests.get('old.png').reject(new Error('old request failed'));
|
|
await first;
|
|
assert.equal(panel.innerHTML, 'new prompt');
|
|
});
|
|
|
|
for (const close of ['destroy viewer', 'remove modal']) {
|
|
test(`closing via ${close} prevents pending metadata from restoring action data`, async () => {
|
|
const { manager, requests, panel } = fixture();
|
|
const pending = manager.loadImageMetadata('old.png', panel);
|
|
if (close === 'destroy viewer') manager.destroyViewer();
|
|
else panel.isConnected = false;
|
|
requests.get('old.png').resolve({ positivePrompt: 'closed prompt' });
|
|
await pending;
|
|
assert.equal(manager.currentMetadata, null);
|
|
assert.notEqual(panel.innerHTML, 'closed prompt');
|
|
});
|
|
}
|