Files
IdeA/frontend/src/adapters/project.test.ts
Blomios b9f8ed303e feat(backend,domain,infrastructure,application,app-tauri,web-server,frontend): suppression d'un projet du registre IdeA sans toucher son dossier disque — #308 (QA verte)
cause: l'utilisateur ne pouvait pas retirer un projet du registre IdeA (projects.json) ; la seule issue laissait l'entrée fantôme dans la liste des projets, sans capacité générique de retrait.

domain: port ProjectStore::remove_project(id) -> Option<Project> avec implémentation par défaut « not supported » pour ne pas casser les stores spécialisés.

infrastructure: FsProjectStore implémente remove_project — retire l'entrée du registre persisté et la renvoie, None si id inconnu, ordre relatif du registre préservé ; test store dédié.

application: use case RemoveProjectFromRegistry (remove.rs) — NotFound explicite si id absent, retourne le projet retiré + registre rafraîchi.

backend/app-tauri/web-server: DTO RemoveProjectRequestDto/RemoveProjectResponseDto (removed, projects, restore_state, was_open), adapter partagé remove_project_for_adapter réutilisé par la commande Tauri remove_project et la route HTTP — même contrat desktop/web ; remove_project_and_deactivate désactive le projet s'il était ouvert, purge l'entrée open-projects restore correspondante et renvoie was_open/restore_state ; test adapter vérifiant le contrat de bout en bout (entrée retirée, restore purgé, root intact).

frontend: DTO + ProjectGateway.removeProject (HTTP + mock), ProjectsView expose un menu d'actions projet (ProjectActionsMenu) avec entrée Retirer, RemoveProjectDialog — confirmation explicite précisant que le dossier disque n'est pas supprimé, invalidation/rechargement de la liste des projets après succès (useProjects), tests ProjectsView/projects/adapters/httpInvoker/services.

QA verte: cargo targeted tests/check OK (domain, application project_usecases, infrastructure project_store, backend, app-tauri, web-server), npm targeted/typecheck/build OK ; suite npm test complète rouge non bloquante hors #308 (échecs préexistants listProjectSettings/web). Vérifications Git: git diff --check OK, cargo fmt --all -- --check OK.

fichiers .ideai/tickets/308/, tickets/counter.json, tickets/index.json, attachments/ et scripts/ hors périmètre et préservés en worktree (sync store traité séparément) ; aucun push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 18:27:15 +02:00

67 lines
2.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
const invoke = vi.fn();
vi.mock("@tauri-apps/api/core", () => ({
invoke: (...args: unknown[]) => invoke(...args),
}));
import { TauriProjectGateway } from "./project";
describe("TauriProjectGateway invoke payloads", () => {
beforeEach(() => invoke.mockReset().mockResolvedValue({}));
it("reads and updates the project context under .ideai", async () => {
invoke.mockResolvedValueOnce("# shared");
await expect(new TauriProjectGateway().readProjectContext("proj-1")).resolves.toBe(
"# shared",
);
expect(invoke).toHaveBeenCalledWith("read_project_context", {
projectId: "proj-1",
});
await new TauriProjectGateway().updateProjectContext("proj-1", "# next");
expect(invoke).toHaveBeenCalledWith("update_project_context", {
request: { projectId: "proj-1", content: "# next" },
});
});
it("maps the open-project restore commands to their exact request envelopes", async () => {
const gateway = new TauriProjectGateway();
await gateway.restoreOpenProjects();
expect(invoke).toHaveBeenCalledWith("restore_open_projects");
await gateway.retryOpenProjectRestore();
expect(invoke).toHaveBeenCalledWith("retry_open_project_restore", {
request: {},
});
await gateway.retryOpenProjectRestore("proj-1");
expect(invoke).toHaveBeenCalledWith("retry_open_project_restore", {
request: { projectId: "proj-1" },
});
await gateway.removeProjectFromRestore("proj-1");
expect(invoke).toHaveBeenCalledWith("remove_project_from_restore", {
request: { projectId: "proj-1" },
});
await gateway.saveOpenProjectRestoreOrder(["proj-2", "proj-1"]);
expect(invoke).toHaveBeenCalledWith("save_open_project_restore_order", {
request: { orderedProjectIds: ["proj-2", "proj-1"] },
});
await gateway.readOpenProjectRestoreState();
expect(invoke).toHaveBeenCalledWith("read_open_project_restore_state");
});
it("removes a project through the shared request envelope", async () => {
const gateway = new TauriProjectGateway();
await gateway.removeProject("proj-1");
expect(invoke).toHaveBeenCalledWith("remove_project", {
request: { projectId: "proj-1" },
});
});
});