Fork Horse repository, listed by its owner. Publisher snapshot.

packages/forkhorse-mcp/__tests__/fixtures.ts

Snapshot at 34e3175

Containing directory

3,126 bytes · typescriptView raw
1import { createCoreClient } from "../src/core";
2import type { AgentIdentity, ClaimBinding, CoreClient } from "../src/core";
3
4/** In-process, labeled FH-003/FH-005 fixture. It performs no provider calls. */
5export class FixtureCore {
6  tokens = new Map<string, AgentIdentity>([
7    ["api_fixture_builder", { project: "demo", agent: "builder" }],
8  ]);
9  claims: ClaimBinding[] = [{ packet: "FH-004", agent: "builder", repoName: "demo--builder-1" }];
10  work: unknown[] = [];
11  requests: Pick<Request, "url" | "method" | "headers" | "json">[] = [];
12  enrollments = 0;
13  forks = 1;
14  failure: number | undefined;
15  payload: unknown;
16  client: CoreClient = createCoreClient({
17    authenticate: async (token) => this.tokens.get(token) ?? null,
18    enrollAgent: async (_owner, project, agent) => {
19      this.enrollments++;
20      const apiToken = `api_fixture_oauth_${this.enrollments}`;
21      this.tokens.set(apiToken, { project, agent });
22      return { apiToken, project, agent };
23    },
24    fetch: async (request) => {
25      this.requests.push(request.clone());
26      if (this.failure)
27        return Response.json(
28          { secret: "provider_fixture_exception_do_not_echo" },
29          { status: this.failure },
30        );
31      if (this.payload !== undefined) return Response.json(this.payload);
32      const path = new URL(request.url).pathname;
33      if (path.endsWith("/me")) return Response.json({ work: this.work });
34      if (path.endsWith("/state")) return Response.json({ claims: this.claims, fixture: true });
35      if (path.endsWith("/join"))
36        return Response.json({ repoName: `demo--builder-${++this.forks}`, fixture: true });
37      if (path.endsWith("/claim")) {
38        const input = (await request.json()) as { repoName?: string };
39        const binding = {
40          packet: "FH-004",
41          agent: "builder",
42          repoName: input.repoName ?? `demo--builder-${this.forks}`,
43        };
44        this.claims = [binding];
45        return Response.json(binding);
46      }
47      return Response.json({ fixture: true, sha: "a".repeat(40) });
48    },
49  });
50}
51
52/** Minimal in-memory KV semantics used by the real OAuth library in these Node tests. */
53export function fixtureKv(): KVNamespace {
54  const values = new Map<string, string>();
55  return {
56    async get(key: string, type?: string | { type?: string }) {
57      const value = values.get(key);
58      if (value === undefined) return null;
59      return (typeof type === "string" ? type : type?.type) === "json" ? JSON.parse(value) : value;
60    },
61    async put(key: string, value: string) {
62      values.set(key, value);
63    },
64    async delete(key: string) {
65      values.delete(key);
66    },
67    async list(options?: { prefix?: string }) {
68      return {
69        keys: [...values.keys()]
70          .filter((key) => key.startsWith(options?.prefix ?? ""))
71          .map((name) => ({ name })),
72        list_complete: true,
73        cacheStatus: null,
74      };
75    },
76  } as unknown as KVNamespace;
77}
78export function fixtureContext(): ExecutionContext {
79  return { props: {}, waitUntil() {}, passThroughOnException() {} } as unknown as ExecutionContext;
80}
81