import { describe, it, expect, beforeAll, beforeEach, vi } from 'vitest'; import request from 'supertest'; import { createApp } from '../../server.js'; import * as icons from '../../lib/health/icons.js'; import { tmpdir } from 'node:os'; import path from 'node:path'; let app; const PNG = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 1, 2, 3]); beforeAll(() => { app = createApp(); }); beforeEach(() => { icons._setCacheDir(path.join(tmpdir(), 'void-icons-' + Date.now() + '-' + Math.random().toString(36).slice(2))); icons._setFetcher(null); }); describe('icon cache', () => { it('rejects an invalid slug', async () => { const res = await request(app).get('/api/icons/..%2f..%2fetc%2fpasswd.png'); expect(res.status).toBe(400); }); it('fetches once on miss then serves from cache', async () => { const fetcher = vi.fn().mockResolvedValue(PNG); icons._setFetcher(fetcher); const r1 = await request(app).get('/api/icons/gitea.png'); expect(r1.status).toBe(200); expect(r1.headers['content-type']).toContain('image/png'); await request(app).get('/api/icons/gitea.png'); expect(fetcher).toHaveBeenCalledTimes(1); }); it('404s when upstream has no icon', async () => { icons._setFetcher(vi.fn().mockResolvedValue(null)); expect((await request(app).get('/api/icons/nope.png')).status).toBe(404); }); });