Skip to content
Source
Sign inSign up

secretRequest.test.ts

133 lines5.3 KB

1import {
2 SecretProviderId,
3 SecretProviderKind,
4 SecretRequestError,
5 ThreadId,
6 TurnItemId,
7} from "@t3tools/contracts";
8import { describe, expect, it } from "vite-plus/test";
9​
10import {
11 secretRequestAnswerInput,
12 secretRequestDisplay,
13 secretRequestFailureMessage,
14 secretRequestLink,
15 secretRequestPrivacyNote,
16 secretRequestSources,
17} from "./secretRequest.ts";
18​
19describe("secretRequestDisplay", () => {
20 it("never offers the form for a request inherited from another thread", () => {
21 expect(secretRequestDisplay({ secretStatus: "pending" }, "inherited")).toEqual({
22 kind: "pending-elsewhere",
23 label: "Waiting for an answer in the original thread",
24 });
25 expect(secretRequestDisplay({ secretStatus: "saved" }, "inherited")).toMatchObject({
26 outcome: "saved",
27 });
28 });
29});
30​
31describe("secretRequestPrivacyNote", () => {
32 it("does not promise to hide a value that the agent's commands can read", () => {
33 expect(secretRequestPrivacyNote({})).toBe("Stored securely, never shown to the agent");
34 expect(secretRequestPrivacyNote({ delivery: "file" })).not.toContain("never shown");
35 });
36});
37​
38describe("secretRequestLink", () => {
39 it.each([
40 [
41 "Open this link and sign in: https://a.dev/x?s=1. Then paste the code.",
42 "https://a.dev/x?s=1",
43 ],
44 ["Open [https://a.dev/x?s=1](https://a.dev/x?s=1) and sign in.", "https://a.dev/x?s=1"],
45 ["Sign in [here](https://a.dev/login?state=abc(def)).", "https://a.dev/login?state=abc(def)"],
46 ["Sign in at https://a.dev/login?state=abc(def).", "https://a.dev/login?state=abc(def)"],
47 ["(Sign in at https://a.dev/login.)", "https://a.dev/login"],
48 ["Open **https://a.dev/x?s=1** and sign in.", "https://a.dev/x?s=1"],
49 ["Open https://a.dev/x?state=u7o_ and sign in.", "https://a.dev/x?state=u7o_"],
50 ["**Sign in at https://a.dev/device**", "https://a.dev/device"],
51 ["_Open https://a.dev/device_.", "https://a.dev/device"],
52 ["_https://a.dev/x?state=u7o_&client_id=cli_", "https://a.dev/x?state=u7o_&client_id=cli"],
53 ["Use client_id acme at https://a.dev/x?state=u7o_", "https://a.dev/x?state=u7o_"],
54 ["_Sign in_ at https://a.dev/x?state=u7o_", "https://a.dev/x?state=u7o_"],
55 ["_Required_: Open https://a.dev/x?state=u7o_", "https://a.dev/x?state=u7o_"],
56 ["(**https://a.dev/login**)", "https://a.dev/login"],
57 ["Open ***https://a.dev/device***", "https://a.dev/device"],
58 ["Open **_https://a.dev/device_**", "https://a.dev/device"],
59 [
60 "Open [https://a.dev/x?s=u7o_](https://a.dev/x?s=u7o_) and sign in.",
61 "https://a.dev/x?s=u7o_",
62 ],
63 ["Open `https://a.dev/x?s=1.` and sign in.", "https://a.dev/x?s=1."],
64 ["Open https://a.dev/x?s=1, then if needed https://a.dev/x?s=1 again.", "https://a.dev/x?s=1"],
65 ["Open https://a.dev or https://b.dev.", undefined],
66 ["Open https://a.dev (also written https://a.dev/).", "https://a.dev/"],
67 ["Paste the code the CLI printed.", undefined],
68 ])("finds the one link in a reason: %s", (reason, href) => {
69 expect(secretRequestLink({ reason })?.href).toBe(href);
70 });
71​
72 it("prefers the agent's url over a link in the reason", () => {
73 expect(
74 secretRequestLink({ url: "https://auth.acme.dev/a", reason: "See https://docs.acme.dev" })
75 ?.host,
76 ).toBe("auth.acme.dev");
77 });
78});
79​
80describe("secretRequestFailureMessage", () => {
81 it("passes through server errors but hides anything that could echo the payload", () => {
82 expect(
83 secretRequestFailureMessage(new SecretRequestError({ reason: "already_answered" })),
84 ).toBe("This secret request was already answered.");
85 expect(secretRequestFailureMessage(new Error('Expected string, got "whsec_1"'))).toBe(
86 "Could not answer the request. Try again.",
87 );
88 expect(secretRequestFailureMessage(undefined)).toBe("Could not answer the request. Try again.");
89 });
90});
91​
92describe("secretRequestSources", () => {
93 const onePassword = SecretProviderId.make("1password");
94 const providers = {
95 [onePassword]: {
96 kind: SecretProviderKind.make("one_password"),
97 label: "1Password",
98 config: { account: "my" },
99 },
100 [SecretProviderId.make("later")]: {
101 kind: SecretProviderKind.make("from_a_newer_build"),
102 label: "Later",
103 config: {},
104 },
105 };
106​
107 it("offers configured providers only when the server accepts reference answers", () => {
108 expect(secretRequestSources({ secretRequestReferences: true }, providers)).toMatchObject([
109 { id: onePassword, label: "1Password" },
110 ]);
111 expect(secretRequestSources({}, providers)).toEqual([]);
112 expect(secretRequestSources({ secretRequestReferences: true }, {})).toEqual([]);
113 });
114​
115 it("answers with a reference only in the provider's syntax", () => {
116 const [source] = secretRequestSources({ secretRequestReferences: true }, providers);
117 if (source === undefined) throw new Error("expected a source");
118 const item = { id: TurnItemId.make("item-1"), threadId: ThreadId.make("thread-1") };
119 expect(
120 secretRequestAnswerInput(item, {
121 type: "reference",
122 source,
123 reference: " op://vault/item/field ",
124 })?.answer,
125 ).toEqual({
126 type: "reference",
127 reference: { provider: onePassword, reference: "op://vault/item/field" },
128 });
129 expect(
130 secretRequestAnswerInput(item, { type: "reference", source, reference: "vault/item" }),
131 ).toBeNull();
132 });
133});