59 lines
3.5 KiB
JavaScript
59 lines
3.5 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const os = require('node:os');
|
|
const path = require('node:path');
|
|
const test = require('node:test');
|
|
const database = require('../../src/database');
|
|
const { createStorageInventoryService } = require('../../src/services/storage-inventory-service');
|
|
|
|
async function fixture(t) {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-drive-locator-'));
|
|
database.configure({ dataDir: root, logger: { info() {}, warn() {}, error() {} } });
|
|
await database.initialize();
|
|
t.after(() => { database.close(); fs.rmSync(root, { recursive: true, force: true }); });
|
|
return createStorageInventoryService({ db: database, now: () => 10_000 });
|
|
}
|
|
|
|
const snapshot = (devices, overrides = {}) => ({ scope: 'server', adapterId: 'usb-monitor', source: 'udev', observedAt: 1_000, completeCoverage: true, devices, ...overrides });
|
|
const drive = (fingerprint, mountPath, displayName = fingerprint) => ({ stableFingerprint: fingerprint, displayName, deviceType: 'usb', volumes: [{ stableVolumeKey: `uuid-${fingerprint}`, mountPath, capabilities: { canCopy: true } }] });
|
|
|
|
test('friendly label persists across disconnect and reconnect observations', async t => {
|
|
const service = await fixture(t);
|
|
const first = service.observe(snapshot([drive('serial-a', '/mnt/usb', 'Vendor Disk')]));
|
|
const id = first.devices[0].id;
|
|
service.setFriendlyLabel({ deviceId: id, label: 'Blue Archive' });
|
|
service.observe(snapshot([], { observedAt: 2_000 }));
|
|
const reconnected = service.observe(snapshot([drive('serial-a', '/media/usb', 'Renamed by OS')], { observedAt: 3_000 }));
|
|
assert.equal(reconnected.devices.length, 1);
|
|
assert.equal(reconnected.devices[0].id, id);
|
|
assert.equal(reconnected.devices[0].displayName, 'Blue Archive');
|
|
assert.equal(reconnected.devices[0].observedDisplayName, 'Renamed by OS');
|
|
assert.equal(reconnected.devices[0].volumes[0].mountPath, '/media/usb');
|
|
});
|
|
|
|
test('same mountpoint with a different fingerprint remains a different device', async t => {
|
|
const service = await fixture(t);
|
|
const result = service.observe(snapshot([drive('serial-a', '/mnt/usb'), drive('serial-b', '/mnt/usb')]));
|
|
assert.equal(result.devices.length, 2);
|
|
assert.notEqual(result.devices[0].id, result.devices[1].id);
|
|
assert.deepEqual(new Set(result.devices.map(item => item.stableFingerprint)), new Set(['serial-a', 'serial-b']));
|
|
});
|
|
|
|
test('locator exposes contained titles, required drive label and last-seen evidence', async t => {
|
|
const service = await fixture(t);
|
|
const inventory = service.observe(snapshot([drive('serial-a', '/mnt/usb')], { observedAt: 4_000 }));
|
|
const device = inventory.devices[0];
|
|
const volume = device.volumes[0];
|
|
service.setFriendlyLabel({ deviceId: device.id, label: 'Blue Archive' });
|
|
database.runMutatingSqlWithParams("INSERT INTO titles (platform, title_id, name, sort_name) VALUES ('ps5', 'PPSA00001', 'Locator Game', 'Locator Game')", {});
|
|
const titleId = Number(database.runQuery('SELECT last_insert_rowid() AS id')[0].id);
|
|
database.runMutatingSqlWithParams(`INSERT INTO local_copies (title_id, volume_id, relative_path, last_seen_at, availability_state) VALUES (@titleId, @volumeId, 'PPSA00001', 4000, 'available')`, { titleId, volumeId: volume.id });
|
|
const locator = service.locateTitles({ titleId: 'PPSA00001' });
|
|
assert.equal(locator.records.length, 1);
|
|
assert.equal(locator.records[0].deviceLabel, 'Blue Archive');
|
|
assert.equal(locator.records[0].deviceLastSeenAt, 4_000);
|
|
assert.equal(locator.records[0].titleName, 'Locator Game');
|
|
});
|