




















@@ -9,6 +9,11 @@ const clientState = vi.hoisted(() => ({
99stopAndWaitSpy: vi.fn(async () => undefined),
1010}));
111112+const bootstrapState = vi.hoisted(() => ({
13+url: "ws://127.0.0.1:18789",
14+auth: { token: "secret" as string | undefined, password: undefined as string | undefined },
15+}));
16+1217class MockGatewayClient {
1318private readonly opts: Record<string, unknown>;
1419@@ -50,8 +55,8 @@ class MockGatewayClient {
50555156vi.mock("./client-bootstrap.js", () => ({
5257resolveGatewayClientBootstrap: vi.fn(async () => ({
53-url: "ws://127.0.0.1:18789",
54-auth: { token: "secret", password: undefined },
58+url: bootstrapState.url,
59+auth: bootstrapState.auth,
5560})),
5661}));
5762@@ -69,6 +74,8 @@ describe("withOperatorApprovalsGatewayClient", () => {
6974clientState.requestSpy.mockReset().mockResolvedValue(undefined);
7075clientState.stopSpy.mockReset();
7176clientState.stopAndWaitSpy.mockReset().mockResolvedValue(undefined);
77+bootstrapState.url = "ws://127.0.0.1:18789";
78+bootstrapState.auth = { token: "secret", password: undefined };
7279});
73807481it("waits for hello before running the callback and stops cleanly", async () => {
@@ -86,13 +93,43 @@ describe("withOperatorApprovalsGatewayClient", () => {
8693);
87948895expect(clientState.options?.scopes).toEqual(["operator.approvals"]);
96+expect(clientState.options?.deviceIdentity).toBeNull();
8997expect(clientState.requestSpy).toHaveBeenCalledWith("exec.approval.resolve", {
9098id: "req-123",
9199decision: "allow-once",
92100});
93101expect(clientState.stopAndWaitSpy).toHaveBeenCalledTimes(1);
94102});
95103104+it("keeps device identity for remote shared-auth approval clients", async () => {
105+bootstrapState.url = "wss://gateway.example/ws";
106+107+await withOperatorApprovalsGatewayClient(
108+{
109+config: {} as never,
110+clientDisplayName: "Matrix approval (@owner:example.org)",
111+},
112+async () => undefined,
113+);
114+115+expect(clientState.options).not.toHaveProperty("deviceIdentity", null);
116+expect(clientState.options?.deviceIdentity).toBeUndefined();
117+});
118+119+it("keeps device identity for loopback approval clients without shared auth", async () => {
120+bootstrapState.auth = { token: undefined, password: undefined };
121+122+await withOperatorApprovalsGatewayClient(
123+{
124+config: {} as never,
125+clientDisplayName: "Matrix approval (@owner:example.org)",
126+},
127+async () => undefined,
128+);
129+130+expect(clientState.options?.deviceIdentity).toBeUndefined();
131+});
132+96133it("surfaces close failures before hello", async () => {
97134clientState.startMode = "close";
98135此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。