'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'); });