mediaDrop/tests/pages.test.ts
Nicolas 01fa3a9efe feat(ui): bouton « Tout réessayer »
Relance en une fois tous les fichiers en échec ; la barre de file reste
visible tant qu'il y en a et indique leur nombre.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 08:54:22 +02:00

124 lines
3.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { FastifyInstance } from 'fastify';
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import { buildApp } from '../src/app.js';
import type { OidcConfig } from '../src/config.js';
import {
login,
makeConfig,
makeTempDir,
oneTarget,
removeDir,
SESSION_COOKIE,
startStubIdp,
type StubIdp,
} from './helpers.js';
let idp: StubIdp;
let app: FastifyInstance;
let uploadDir: string;
function oidcOverride(ref: StubIdp): OidcConfig {
return {
issuer: ref.issuer,
clientId: ref.clientId,
clientSecret: ref.clientSecret,
scopes: ['openid', 'profile', 'email'],
};
}
beforeAll(async () => {
idp = await startStubIdp();
});
afterAll(async () => {
await idp.close();
});
beforeEach(async () => {
uploadDir = await makeTempDir();
app = await buildApp(makeConfig({ targets: oneTarget(uploadDir), oidc: oidcOverride(idp) }), {
logger: false,
});
await app.ready();
});
afterEach(async () => {
await app.close();
await removeDir(uploadDir);
});
describe('GET /', () => {
it('sans session : sert la page de connexion, pas la page de dépôt', async () => {
const res = await app.inject({ method: 'GET', url: '/' });
expect(res.statusCode).toBe(200);
expect(res.headers['content-type']).toContain('text/html');
expect(res.body).toContain('href="/auth/login"');
expect(res.body).not.toContain('id="zones"');
expect(res.body).not.toContain('Se déconnecter');
});
it('avec session valide : sert la page de dépôt avec le nom injecté', async () => {
const cookie = await login(app, idp, { name: 'Alice' });
const res = await app.inject({
method: 'GET',
url: '/',
cookies: { [SESSION_COOKIE]: cookie },
});
expect(res.statusCode).toBe(200);
expect(res.body).toContain('Connecté : Alice');
expect(res.body).toContain('Se déconnecter');
expect(res.body).toContain('id="zones"');
expect(res.body).not.toContain('{{USER_NAME}}');
expect(res.body).not.toContain('href="/auth/login"');
});
it('page de dépôt : boutons pause/réessayer, titres tronquables, pleine largeur', async () => {
const cookie = await login(app, idp);
const res = await app.inject({
method: 'GET',
url: '/',
cookies: { [SESSION_COOKIE]: cookie },
});
expect(res.body).toContain('class="pause"');
expect(res.body).toContain('class="retry"');
expect(res.body).toContain('text-overflow: ellipsis');
expect(res.body).not.toContain('max-width: 640px');
});
it('page de dépôt : une zone par cible, plus de menu déroulant ni de second sélecteur', async () => {
const cookie = await login(app, idp);
const res = await app.inject({
method: 'GET',
url: '/',
cookies: { [SESSION_COOKIE]: cookie },
});
expect(res.body).toContain('id="zones"');
expect(res.body).toContain('id="queuePause"');
expect(res.body).toContain('id="queueRetry"');
expect(res.body).not.toContain('targetSelect');
expect(res.body).not.toContain('dirPicker');
});
it('échappe le nom d’utilisateur avant de l’insérer dans le HTML', async () => {
const cookie = await login(app, idp, { name: '<script>alert(1)</script>' });
const res = await app.inject({
method: 'GET',
url: '/',
cookies: { [SESSION_COOKIE]: cookie },
});
expect(res.body).not.toContain('<script>alert(1)</script>');
expect(res.body).toContain('&lt;script&gt;alert(1)&lt;/script&gt;');
});
it('session invalide (cookie illisible) : retombe sur la page de connexion', async () => {
const res = await app.inject({
method: 'GET',
url: '/',
cookies: { [SESSION_COOKIE]: 'cookie-bidon' },
});
expect(res.statusCode).toBe(200);
expect(res.body).toContain('href="/auth/login"');
expect(res.body).not.toContain('id="zones"');
});
});