This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import type { Plugin } from "@opencode/plugin";
|
||||
import type { Context } from "@opencode/plugin/effect/plugin";
|
||||
import { Effect } from "effect";
|
||||
import quota from "../src/quota-plugin.js";
|
||||
import multiWork from "../src/multi-work.js";
|
||||
import { QuotaRpc } from "../src/quota-rpc.js";
|
||||
import { AgentsRpc } from "../src/agents-rpc.js";
|
||||
|
||||
test("Quota loads independently and retains its RPC ID and nullable status", async () => {
|
||||
let controller: ReadableStreamDefaultController<unknown>;
|
||||
const stream = new ReadableStream({
|
||||
start(value) {
|
||||
controller = value;
|
||||
},
|
||||
});
|
||||
let status: (() => Promise<null>) | undefined;
|
||||
let disposed = false;
|
||||
let modelHook = false;
|
||||
const context = {
|
||||
options: {},
|
||||
location: { directory: "/fixture" },
|
||||
integration: {
|
||||
connection: {
|
||||
async active() {
|
||||
return undefined;
|
||||
},
|
||||
},
|
||||
},
|
||||
event: {
|
||||
subscribe({ signal }: { signal: AbortSignal }) {
|
||||
signal.addEventListener("abort", () => controller.close(), { once: true });
|
||||
return stream;
|
||||
},
|
||||
},
|
||||
rpc: {
|
||||
async register(definition: typeof QuotaRpc, handlers: { status: () => Promise<null> }) {
|
||||
expect(definition.id).toBe("stanp-opencode.quota");
|
||||
status = handlers.status;
|
||||
return {
|
||||
async dispose() {
|
||||
disposed = true;
|
||||
},
|
||||
events: { async emit() {} },
|
||||
};
|
||||
},
|
||||
},
|
||||
session: {
|
||||
async hook(name: string) {
|
||||
expect(name).toBe("model.request");
|
||||
modelHook = true;
|
||||
return { async dispose() {} };
|
||||
},
|
||||
},
|
||||
};
|
||||
// SAFETY: Quota with no credentials uses only these native host services.
|
||||
// Absent agent/model/MCP APIs fail if independence regresses.
|
||||
const setup = quota.setup as (
|
||||
context: Pick<Plugin.Context, "options">,
|
||||
) => ReturnType<typeof quota.setup>;
|
||||
const cleanup = await setup(context);
|
||||
expect(quota.id).toBe("stanp-opencode.quota");
|
||||
expect(await status!()).toBeNull();
|
||||
expect(modelHook).toBe(true);
|
||||
if (cleanup) await cleanup();
|
||||
expect(disposed).toBe(true);
|
||||
});
|
||||
|
||||
test("Multi-work rejects missing Agents before any Herdr operations or registrations", async () => {
|
||||
const context = {
|
||||
rpc: (definition: typeof AgentsRpc) => {
|
||||
expect(definition.id).toBe("stanp-opencode.agents");
|
||||
return { permissions: () => Effect.fail(new Error("RPC not registered")) };
|
||||
},
|
||||
};
|
||||
// SAFETY: Missing Agents fails at the first RPC call; no other host service is accessed.
|
||||
const activate = multiWork.effect as (
|
||||
context: Pick<Context, "options">,
|
||||
) => ReturnType<typeof multiWork.effect>;
|
||||
const result = await Effect.runPromiseExit(
|
||||
Effect.scoped(activate({ ...context, options: {} })),
|
||||
);
|
||||
expect(String(result)).toContain("Multi-work requires Agents loaded before it");
|
||||
});
|
||||
Reference in New Issue
Block a user