chantier: durcissement reprise headless inter-projets + persistance profils Opencode
- Implémentation reprise de session Opencode headless (conversational_recovery) - Persistance des profils IA Opencode dans .ideai/memory avec JSON Schema - Gestion des permissions MCP pour agents externes - Tests QA verts : structured_launch_d3, conversation_log, tickets_missing_carnet, agents, ProfilesSettings
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { fireEvent, render, screen, waitFor, within } from "@testing-library/react";
|
||||
|
||||
import { DIProvider } from "@/app/di";
|
||||
@ -221,4 +221,70 @@ describe("ProfilesSettings", () => {
|
||||
),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it("creates OpenCode profiles through the OpenCode clone flow and persists them for agent pickers", async () => {
|
||||
const profile = new MockProfileGateway();
|
||||
const cloneOpenCodeSpy = vi.spyOn(profile, "cloneOpenCodeProfileFromSeed");
|
||||
const cloneGenericSpy = vi.spyOn(profile, "cloneProfileFromSeed");
|
||||
renderSettings(profile);
|
||||
await waitReady();
|
||||
|
||||
fireEvent.click(screen.getByRole("tab", { name: "OpenCode-local" }));
|
||||
await waitReady();
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Creer un profil" }));
|
||||
|
||||
const name = await screen.findByDisplayValue("OpenCode + llama.cpp copy");
|
||||
expect(name).toBeTruthy();
|
||||
await waitFor(async () => {
|
||||
const saved = await profile.listProfiles();
|
||||
expect(saved.map((p) => p.name)).toContain("OpenCode + llama.cpp copy");
|
||||
expect(saved.some((p) => p.structuredAdapter === "openCode")).toBe(true);
|
||||
});
|
||||
expect(cloneOpenCodeSpy).toHaveBeenCalledWith({
|
||||
name: "OpenCode + llama.cpp copy",
|
||||
opencode: expect.objectContaining({
|
||||
baseURL: "http://localhost:8080/v1",
|
||||
model: "qwen3-coder-30b",
|
||||
}),
|
||||
});
|
||||
expect(cloneGenericSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("duplicates OpenCode profiles through the OpenCode clone flow and preserves their local config", async () => {
|
||||
const profile = new MockProfileGateway();
|
||||
renderSettings(profile);
|
||||
await waitReady();
|
||||
|
||||
fireEvent.click(screen.getByRole("tab", { name: "OpenCode-local" }));
|
||||
await waitReady();
|
||||
await createProfile();
|
||||
|
||||
const row = screen.getAllByRole("listitem")[0];
|
||||
fireEvent.change(within(row).getByLabelText("OpenCode + llama.cpp copy base url"), {
|
||||
target: { value: "http://localhost:9090/v1" },
|
||||
});
|
||||
fireEvent.change(within(row).getByLabelText("OpenCode + llama.cpp copy model"), {
|
||||
target: { value: "local-special" },
|
||||
});
|
||||
fireEvent.click(within(row).getByRole("button", { name: "Enregistrer" }));
|
||||
|
||||
await waitFor(async () => {
|
||||
const saved = await profile.listProfiles();
|
||||
expect(saved[0]?.opencode?.baseURL).toBe("http://localhost:9090/v1");
|
||||
});
|
||||
|
||||
fireEvent.click(within(screen.getAllByRole("listitem")[0]).getByRole("button", {
|
||||
name: "Dupliquer",
|
||||
}));
|
||||
|
||||
await waitFor(async () => {
|
||||
const saved = await profile.listProfiles();
|
||||
const copies = saved.filter((p) => p.structuredAdapter === "openCode");
|
||||
expect(copies).toHaveLength(2);
|
||||
expect(copies[1]?.name).toBe("OpenCode + llama.cpp copy copy");
|
||||
expect(copies[1]?.opencode?.baseURL).toBe("http://localhost:9090/v1");
|
||||
expect(copies[1]?.opencode?.model).toBe("local-special");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user