import { describe, it, expect } from 'vitest'; import fs from 'fs'; import path from 'path'; import { parseDat, verifyHashesAgainstDat, DatDatabase } from '../../src/services/datVerifier'; const FIXTURE = path.resolve('tests/fixtures/sample.dat.xml'); describe('services/datVerifier', () => { it('parseDat parses simple DAT XML', () => { const xml = fs.readFileSync(FIXTURE, 'utf8'); const dat: DatDatabase = parseDat(xml); expect(dat).toBeTruthy(); expect(Array.isArray(dat.games)).toBe(true); expect(dat.games.length).toBe(2); const g0 = dat.games[0]; expect(g0.name).toBe('Game Alpha'); expect(g0.roms.length).toBeGreaterThan(0); expect(g0.roms[0].name).toBe('alpha1.bin'); expect(g0.roms[0].crc).toBeDefined(); expect(g0.roms[0].md5).toBeDefined(); const g1 = dat.games[1]; expect(g1.name).toBe('Game Beta'); expect(g1.roms.some((r) => r.name === 'beta2.rom')).toBe(true); }); it('verifyHashesAgainstDat finds match by CRC', () => { const xml = fs.readFileSync(FIXTURE, 'utf8'); const dat = parseDat(xml); const match = verifyHashesAgainstDat(dat, { crc: 'DEADBEEF' }); expect(match).not.toBeNull(); expect(match?.gameName).toBe('Game Beta'); expect(match?.romName).toBe('beta1.rom'); expect(match?.matchedOn).toBe('crc'); }); it('verifyHashesAgainstDat finds match by MD5, SHA1 and size', () => { const xml = fs.readFileSync(FIXTURE, 'utf8'); const dat = parseDat(xml); const md5match = verifyHashesAgainstDat(dat, { md5: '11111111111111111111111111111111' }); expect(md5match).not.toBeNull(); expect(md5match?.gameName).toBe('Game Alpha'); expect(md5match?.romName).toBe('alpha1.bin'); expect(md5match?.matchedOn).toBe('md5'); const sha1match = verifyHashesAgainstDat(dat, { sha1: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', }); expect(sha1match).not.toBeNull(); expect(sha1match?.gameName).toBe('Game Alpha'); expect(sha1match?.romName).toBe('alpha2.bin'); expect(sha1match?.matchedOn).toBe('sha1'); const sizematch = verifyHashesAgainstDat(dat, { size: 4000 }); expect(sizematch).not.toBeNull(); expect(sizematch?.gameName).toBe('Game Beta'); expect(sizematch?.romName).toBe('beta2.rom'); expect(sizematch?.matchedOn).toBe('size'); }); it('verifyHashesAgainstDat returns null when no match', () => { const xml = fs.readFileSync(FIXTURE, 'utf8'); const dat = parseDat(xml); const noMatch = verifyHashesAgainstDat(dat, { md5: 'ffffffffffffffffffffffffffffffff' }); expect(noMatch).toBeNull(); }); });