import { test, expect } from 'vitest'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; import { computeHashesFromStream } from '../../src/services/checksumService'; import { streamArchiveEntry } from '../../src/services/archiveReader'; import { createHash } from 'crypto'; function hasBinary(bin: string): boolean { try { execSync(`which ${bin}`, { stdio: 'ignore' }); return true; } catch (e) { return false; } } const wantIntegration = process.env.INTEGRATION === '1'; const canCreate = hasBinary('7z') || hasBinary('zip'); if (!wantIntegration) { test.skip('archiveReader integration tests require INTEGRATION=1', () => {}); } else if (!canCreate) { test.skip('archiveReader integration tests skipped: no archive creation tool (7z or zip) available', () => {}); } else { test('reads entry from zip using system tools', async () => { const tmpDir = await fs.mkdtemp(path.join(process.cwd(), 'tmp-arc-')); const inner = path.join(tmpDir, 'game.rom'); const content = 'QUASAR-INTEGRATION-TEST'; await fs.writeFile(inner, content); const archivePath = path.join(tmpDir, 'simple.zip'); // create zip using available tool if (hasBinary('7z')) { execSync(`7z a -tzip ${JSON.stringify(archivePath)} ${JSON.stringify(inner)}`, { stdio: 'ignore', }); } else { execSync(`zip -j ${JSON.stringify(archivePath)} ${JSON.stringify(inner)}`, { stdio: 'ignore', }); } const stream = await streamArchiveEntry(archivePath, path.basename(inner)); expect(stream).not.toBeNull(); const hashes = await computeHashesFromStream(stream as any); const expectedMd5 = createHash('md5').update(content).digest('hex'); expect(hashes.md5).toBe(expectedMd5); await fs.rm(tmpDir, { recursive: true, force: true }); }); }