Skip to content
Source
Sign inSign up

authenticationState.test.ts

101 lines4.2 KB

1import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
2import * as NodeServices from "@effect/platform-node/NodeServices";
3import * as Layer from "effect/Layer";
4import { assert, it } from "@effect/vitest";
5import { ProviderInstanceId } from "@t3tools/contracts";
6import { AcpRegistrySettings } from "../settings.ts";
7import * as Effect from "effect/Effect";
8import * as FileSystem from "effect/FileSystem";
9import * as Schema from "effect/Schema";
10​
11import { makeAcpRegistryAuthenticationState } from "./authenticationState.ts";
12​
13const settings = Schema.decodeSync(AcpRegistrySettings)({ agentId: "devin" });
14​
15it.layer(Layer.mergeAll(NodeServices.layer, NodeCrypto.layer))("ACP sign-in confirmation", (it) => {
16 it.effect("restores explicit sign-in across driver recreation and server restart", () =>
17 Effect.gen(function* () {
18 const fs = yield* FileSystem.FileSystem;
19 const cacheDir = yield* fs.makeTempDirectoryScoped();
20 const input = {
21 cacheDir,
22 instanceId: ProviderInstanceId.make("acp_devin"),
23 settings,
24 environment: [],
25 processEnvironment: { HOME: "/home/test" },
26 };
27 const first = yield* makeAcpRegistryAuthenticationState(input);
28 assert.isFalse(yield* first.get);
29 yield* first.set(true);
30 const recreated = yield* makeAcpRegistryAuthenticationState({
31 ...input,
32 settings: { ...settings, customModels: ["new-model"] },
33 });
34 assert.isTrue(yield* recreated.get);
35 yield* recreated.set(false);
36 const restarted = yield* makeAcpRegistryAuthenticationState(input);
37 assert.isFalse(yield* restarted.get);
38 }),
39 );
40​
41 it.effect(
42 "does not carry confirmation to a different agent, method, executable, or credential environment",
43 () =>
44 Effect.gen(function* () {
45 const fs = yield* FileSystem.FileSystem;
46 const cacheDir = yield* fs.makeTempDirectoryScoped();
47 const input = {
48 cacheDir,
49 instanceId: ProviderInstanceId.make("acp_devin"),
50 settings,
51 environment: [{ name: "DEVIN_TOKEN", value: "test-only-token", sensitive: true }],
52 processEnvironment: { HOME: "/home/test" },
53 };
54 for (const change of [
55 { settings: { ...settings, agentId: "other-agent" } },
56 { settings: { ...settings, authMethodId: "enterprise" } },
57 { settings: { ...settings, commandPath: "/other/devin" } },
58 { environment: [{ name: "DEVIN_TOKEN", value: "different-token", sensitive: true }] },
59 { processEnvironment: { HOME: "/home/other" } },
60 ]) {
61 const signedIn = yield* makeAcpRegistryAuthenticationState(input);
62 yield* signedIn.set(true);
63 const changed = yield* makeAcpRegistryAuthenticationState({ ...input, ...change });
64 assert.isFalse(yield* changed.get);
65 const restoredConfig = yield* makeAcpRegistryAuthenticationState(input);
66 assert.isFalse(yield* restoredConfig.get);
67 }
68 for (const name of yield* fs.readDirectory(cacheDir)) {
69 const contents = yield* fs.readFileString(`${cacheDir}/${name}`);
70 assert.isFalse(contents.includes("test-only-token"));
71 assert.isFalse(contents.includes("different-token"));
72 }
73 }),
74 );
75​
76 it.effect("ignores damaged confirmation and keeps another instance independent", () =>
77 Effect.gen(function* () {
78 const fs = yield* FileSystem.FileSystem;
79 const cacheDir = yield* fs.makeTempDirectoryScoped();
80 const input = {
81 cacheDir,
82 instanceId: ProviderInstanceId.make("acp_devin"),
83 settings,
84 environment: [],
85 processEnvironment: {},
86 };
87 const first = yield* makeAcpRegistryAuthenticationState(input);
88 yield* first.set(true);
89 const other = yield* makeAcpRegistryAuthenticationState({
90 ...input,
91 instanceId: ProviderInstanceId.make("acp_other"),
92 });
93 assert.isFalse(yield* other.get);
94 for (const name of yield* fs.readDirectory(cacheDir)) {
95 yield* fs.writeFileString(`${cacheDir}/${name}`, "invalid");
96 }
97 const restored = yield* makeAcpRegistryAuthenticationState(input);
98 assert.isFalse(yield* restored.get);
99 }),
100 );
101});