fix(plugins): isole les contributions plugin en erreur et durcit menus.ts
Le chargement de l'archive hello-plugin (build/hello-plugin-0.1.0.zip) vidait la fenêtre principale : une contribution plugin fautive remontait jusqu'au rendu global au lieu de rester locale à la cellule. Ajoute un boundary local dans PluginLayoutCellView/PluginLayoutSelectorSection et durcit menus.ts/loader.ts/registry.ts contre les entrées de menu ou contributions malformées. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
* F4 — `PluginLayoutCellView` (ticket #43, carnet §10 F4 acceptance criteria:
|
||||
* "rendu composant mock, state roundtrip, fallback sans mutation du layout").
|
||||
*/
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
import type { CustomPluginLayoutCell } from "@/domain";
|
||||
@ -39,7 +39,11 @@ function MockLayoutComponent(props: PluginLayoutProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function stubPlugin(): LoadedPlugin {
|
||||
function ThrowingLayoutComponent(_props: PluginLayoutProps): JSX.Element {
|
||||
throw new Error("plugin layout render failed");
|
||||
}
|
||||
|
||||
function stubPlugin(component = MockLayoutComponent): LoadedPlugin {
|
||||
const contributes = {
|
||||
menus: [],
|
||||
menuItems: [],
|
||||
@ -47,7 +51,7 @@ function stubPlugin(): LoadedPlugin {
|
||||
mcpServers: [],
|
||||
};
|
||||
const layouts = new PluginLayoutRegistry("dev.acme.gitgraph", new Set(["dev.acme.gitgraph.layout"]));
|
||||
layouts.register({ type: "dev.acme.gitgraph.layout", component: MockLayoutComponent });
|
||||
layouts.register({ type: "dev.acme.gitgraph.layout", component });
|
||||
return {
|
||||
pluginId: "dev.acme.gitgraph",
|
||||
displayName: "Git Graph",
|
||||
@ -110,4 +114,18 @@ describe("PluginLayoutCellView", () => {
|
||||
// The cell object itself is untouched — the domain identity/state survive.
|
||||
expect(testCell).toEqual(cell());
|
||||
});
|
||||
|
||||
it("isolates a plugin layout render failure to the plugin cell fallback", () => {
|
||||
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
try {
|
||||
const registry = new PluginRuntimeRegistry();
|
||||
registry.add(stubPlugin(ThrowingLayoutComponent));
|
||||
renderCell(registry);
|
||||
|
||||
expect(screen.getByText("Layout indisponible")).toBeTruthy();
|
||||
expect(screen.queryByTestId("state")).toBeNull();
|
||||
} finally {
|
||||
consoleError.mockRestore();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user