mediaDrop/tests/pages.test.ts
Nicolas 5ef89e87a4 feat(ui): pause, réessayer, titres tronqués et pleine largeur
- bouton Pause/Reprendre par fichier (#6)
- bouton Réessayer sur les échecs (#7)
- noms de fichiers tronqués avec ellipse + titre au survol (#5)
- contenu pleine largeur (#4)
- cible figée à l'ajout, nouvelle tentative d'init sur 429 (#1, #3)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 20:32:41 +02:00

110 lines
3.3 KiB
TypeScript
Raw 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="dropzone"');
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="dropzone"');
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('é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="dropzone"');
});
});