-
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathprompts-handler.test.ts
More file actions
123 lines (111 loc) · 4.1 KB
/
Copy pathprompts-handler.test.ts
File metadata and controls
123 lines (111 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { describe, expect, it } from "vitest";
import { BUILTIN_PROMPTS, type PromptsConfig } from "perplexity-user-mcp/prompts-config";
import {
deletePromptHandler,
resetPromptHandler,
savePromptHandler,
} from "../src/webview/prompts-handler.js";
/**
* Pure handlers for prompts:save / delete / reset, extracted from
* DashboardProvider. The merge/upsert/read/write primitives are covered by the
* mcp-server prompts-config tests; here we verify the extension-side validation
* and dispatch. The postActionResult/postPromptsState wiring is exercised by the
* smoke checklist in docs/smoke-tests.md.
*/
function makeDeps(initial: PromptsConfig = { overrides: {}, custom: [] }) {
let config: PromptsConfig = initial;
let writes = 0;
return {
deps: {
read: () => config,
write: (c: PromptsConfig) => {
config = c;
writes += 1;
},
},
current: () => config,
writeCount: () => writes,
};
}
const validCustom = {
name: "my-cmd",
description: "mine",
arguments: [{ name: "q", description: "the query", required: true }],
template: "Search: {q}",
};
describe("savePromptHandler", () => {
it("persists a valid custom prompt", () => {
const h = makeDeps();
const out = savePromptHandler(validCustom, h.deps);
expect(out.ok).toBe(true);
expect(h.current().custom.map((c) => c.name)).toEqual(["my-cmd"]);
});
it("rejects an invalid name without writing", () => {
const h = makeDeps();
const out = savePromptHandler({ ...validCustom, name: "Bad Name" }, h.deps);
expect(out).toEqual({ ok: false, error: expect.stringContaining("Invalid command name") });
expect(h.writeCount()).toBe(0);
});
it("rejects an empty template without writing", () => {
const h = makeDeps();
const out = savePromptHandler({ ...validCustom, template: " " }, h.deps);
expect(out).toEqual({ ok: false, error: expect.stringContaining("Template cannot be empty") });
expect(h.writeCount()).toBe(0);
});
it("writes an override (not a custom entry) for a built-in name", () => {
const builtin = BUILTIN_PROMPTS[0].name;
const h = makeDeps();
const out = savePromptHandler({ ...validCustom, name: builtin }, h.deps);
expect(out.ok).toBe(true);
expect(h.current().overrides[builtin]).toBeDefined();
expect(h.current().custom).toHaveLength(0);
});
it("drops arguments without names and coerces required", () => {
const h = makeDeps();
savePromptHandler(
{
name: "argy",
description: "",
arguments: [
{ name: "keep", description: "", required: 1 as unknown as boolean },
{ name: "", description: "nameless", required: true },
],
template: "{keep}",
},
h.deps,
);
const saved = h.current().custom[0];
expect(saved.arguments).toEqual([{ name: "keep", description: "", required: true }]);
});
it("rejects a missing payload", () => {
const h = makeDeps();
expect(savePromptHandler(undefined, h.deps).ok).toBe(false);
expect(h.writeCount()).toBe(0);
});
});
describe("deletePromptHandler", () => {
it("removes the named custom prompt", () => {
const h = makeDeps({ overrides: {}, custom: [{ name: "a", description: "", arguments: [], template: "x" }] });
const out = deletePromptHandler("a", h.deps);
expect(out.ok).toBe(true);
expect(h.current().custom).toHaveLength(0);
});
it("rejects an empty name", () => {
const h = makeDeps();
expect(deletePromptHandler("", h.deps).ok).toBe(false);
expect(h.writeCount()).toBe(0);
});
});
describe("resetPromptHandler", () => {
it("clears a built-in override", () => {
const builtin = BUILTIN_PROMPTS[0].name;
const h = makeDeps({ overrides: { [builtin]: { name: builtin, description: "x", arguments: [], template: "y" } }, custom: [] });
const out = resetPromptHandler(builtin, h.deps);
expect(out.ok).toBe(true);
expect(h.current().overrides[builtin]).toBeUndefined();
});
it("is a no-op (still ok) when there is no override", () => {
const h = makeDeps();
expect(resetPromptHandler(BUILTIN_PROMPTS[0].name, h.deps).ok).toBe(true);
});
});