fix(frontend): detruit les graphiques avec leur composant

Chart.js conserve chaque instance dans un registre lie au canvas et lui
attache un observateur de redimensionnement. Sans destroy, tout survit a la
destruction du composant, et une re-creation sur le meme canvas echoue avec
"Canvas is already in use".

Les doubles de test gagnent destroy : TestBed detruit les fixtures apres
chaque test, un mock sans cette methode fait tomber les specs existantes.
This commit is contained in:
Johan LEROY
2026-09-16 09:20:17 +02:00
parent 7b9406965e
commit 0259f66b62
4 changed files with 90 additions and 8 deletions
@@ -1,16 +1,28 @@
import { TestBed } from '@angular/core/testing';
import { vi } from 'vitest';
import { Chart } from 'chart.js';
import { SiteLoadChart } from './site-load-chart';
vi.mock('chart.js', () => {
class ChartMock {
update = vi.fn();
data = { datasets: [{}] };
static instances: ChartMock[] = [];
static register = vi.fn();
update = vi.fn();
destroy = vi.fn();
data = { datasets: [{}] };
constructor() {
ChartMock.instances.push(this);
}
}
return { Chart: ChartMock, registerables: [] };
});
type ChartDouble = { destroy: ReturnType<typeof vi.fn> };
function lastChart(): ChartDouble | undefined {
return (Chart as unknown as { instances: ChartDouble[] }).instances.at(-1);
}
describe('SiteLoadChart', () => {
it('se crée sans erreur avec une liste de sites valide', () => {
TestBed.configureTestingModule({ imports: [SiteLoadChart] });
@@ -35,4 +47,25 @@ describe('SiteLoadChart', () => {
expect(() => fixture.detectChanges()).not.toThrow();
});
it('détruit le graphique quand le composant est détruit', () => {
TestBed.configureTestingModule({ imports: [SiteLoadChart] });
const fixture = TestBed.createComponent(SiteLoadChart);
fixture.componentRef.setInput('sites', [
{
site_id: 'S1',
site_name: 'A',
current_consumption_kw: 50,
capacity_kw: 100,
load_percent: 50,
data_quality: 'good',
},
]);
fixture.detectChanges();
const chart = lastChart();
fixture.destroy();
expect(chart?.destroy).toHaveBeenCalledTimes(1);
});
});