83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
import * as fs from 'fs';
|
|
import * as os from 'os';
|
|
import * as path from 'path';
|
|
import sharp from 'sharp';
|
|
import {
|
|
CANONICAL_SYSTEM_ICON_KEYS,
|
|
SYSTEM_ICON_SIZE,
|
|
seedSystemCategoryIcons,
|
|
} from '../../backend/src/database/system-category-icons';
|
|
|
|
function makeTempDir(): string {
|
|
return fs.mkdtempSync(path.join(os.tmpdir(), 'hipctf-icons-'));
|
|
}
|
|
|
|
describe('seedSystemCategoryIcons', () => {
|
|
const cleanup: string[] = [];
|
|
|
|
afterEach(() => {
|
|
while (cleanup.length > 0) {
|
|
const dir = cleanup.pop();
|
|
if (dir && fs.existsSync(dir)) fs.rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it('writes six 128x128 PNGs into a fresh temp directory', async () => {
|
|
const dir = makeTempDir();
|
|
cleanup.push(dir);
|
|
|
|
const result = await seedSystemCategoryIcons(dir);
|
|
|
|
expect(result.written.length).toBe(CANONICAL_SYSTEM_ICON_KEYS.length);
|
|
expect(result.skipped.length).toBe(0);
|
|
|
|
for (const key of CANONICAL_SYSTEM_ICON_KEYS) {
|
|
const target = path.join(dir, 'icons', `${key}.png`);
|
|
expect(fs.existsSync(target)).toBe(true);
|
|
const stat = fs.statSync(target);
|
|
expect(stat.size).toBeGreaterThan(0);
|
|
const meta = await sharp(target).metadata();
|
|
expect(meta.format).toBe('png');
|
|
expect(meta.width).toBe(SYSTEM_ICON_SIZE);
|
|
expect(meta.height).toBe(SYSTEM_ICON_SIZE);
|
|
}
|
|
});
|
|
|
|
it('is idempotent and does not overwrite an existing admin-uploaded icon', async () => {
|
|
const dir = makeTempDir();
|
|
cleanup.push(dir);
|
|
|
|
const first = await seedSystemCategoryIcons(dir);
|
|
expect(first.written.length).toBe(CANONICAL_SYSTEM_ICON_KEYS.length);
|
|
|
|
const adminIconPath = path.join(dir, 'icons', 'CRY.png');
|
|
const adminMtime = fs.statSync(adminIconPath).mtimeMs;
|
|
await new Promise((r) => setTimeout(r, 25));
|
|
|
|
const second = await seedSystemCategoryIcons(dir);
|
|
expect(second.written.length).toBe(0);
|
|
expect(second.skipped.length).toBe(CANONICAL_SYSTEM_ICON_KEYS.length);
|
|
|
|
expect(fs.statSync(adminIconPath).mtimeMs).toBe(adminMtime);
|
|
for (const key of CANONICAL_SYSTEM_ICON_KEYS) {
|
|
const target = path.join(dir, 'icons', `${key}.png`);
|
|
expect(fs.statSync(target).size).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
it('creates the icons subdirectory when the parent directory is empty', async () => {
|
|
const dir = makeTempDir();
|
|
cleanup.push(dir);
|
|
|
|
const target = path.join(dir, 'icons');
|
|
expect(fs.existsSync(target)).toBe(false);
|
|
|
|
const result = await seedSystemCategoryIcons(dir);
|
|
expect(result.written.length).toBe(CANONICAL_SYSTEM_ICON_KEYS.length);
|
|
expect(fs.existsSync(target)).toBe(true);
|
|
expect(fs.readdirSync(target).sort()).toEqual(
|
|
[...CANONICAL_SYSTEM_ICON_KEYS].map((k) => `${k}.png`).sort(),
|
|
);
|
|
});
|
|
});
|