mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 10:06:21 +00:00
fix(cli): address code-review findings on OAuth PR
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { startLoopback, type LoopbackHandle } from "./loopback.js";
|
||||
|
||||
describe("auth/loopback", () => {
|
||||
let active: LoopbackHandle | null = null;
|
||||
|
||||
afterEach(async () => {
|
||||
if (active) {
|
||||
await active.close().catch(() => {});
|
||||
active = null;
|
||||
}
|
||||
});
|
||||
|
||||
it("captures `code` when state matches", async () => {
|
||||
const handle = await startLoopback({ state: "expected_state", timeoutMs: 5_000 });
|
||||
active = handle;
|
||||
const redirect = new URL(handle.redirectUri);
|
||||
const callback = new URL(`${handle.redirectUri}?code=abc123&state=expected_state`);
|
||||
|
||||
const fetchPromise = fetch(callback.toString());
|
||||
const result = await handle.result;
|
||||
const res = await fetchPromise;
|
||||
|
||||
expect(result.code).toBe("abc123");
|
||||
expect(result.redirectUri).toContain(redirect.host);
|
||||
expect(res.status).toBe(200);
|
||||
const body = await res.text();
|
||||
expect(body).toContain("Signed in");
|
||||
});
|
||||
|
||||
async function expectRejection(args: {
|
||||
expectedState: string;
|
||||
query: string;
|
||||
pattern: RegExp;
|
||||
}): Promise<void> {
|
||||
const handle = await startLoopback({ state: args.expectedState, timeoutMs: 5_000 });
|
||||
active = handle;
|
||||
await fetch(`${handle.redirectUri}?${args.query}`).catch(() => {});
|
||||
await expect(handle.result).rejects.toThrow(args.pattern);
|
||||
}
|
||||
|
||||
it("rejects when state does not match", async () => {
|
||||
await expectRejection({
|
||||
expectedState: "expected",
|
||||
query: "code=abc&state=wrong",
|
||||
pattern: /state mismatch/i,
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects when the IdP returns an error", async () => {
|
||||
await expectRejection({
|
||||
expectedState: "s",
|
||||
query: "error=access_denied&error_description=user+denied&state=s",
|
||||
pattern: /access_denied/,
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects when code is missing from the callback", async () => {
|
||||
await expectRejection({ expectedState: "s", query: "state=s", pattern: /code/ });
|
||||
});
|
||||
|
||||
it("times out when no callback arrives", async () => {
|
||||
const handle = await startLoopback({ state: "s", timeoutMs: 200 });
|
||||
active = handle;
|
||||
await expect(handle.result).rejects.toThrow(/timed out/i);
|
||||
});
|
||||
|
||||
it("404s non-callback paths and does not resolve the flow", async () => {
|
||||
const handle = await startLoopback({ state: "s", timeoutMs: 1_000 });
|
||||
active = handle;
|
||||
const res = await fetch(`${handle.redirectUri.replace("/oauth/callback", "/other")}`);
|
||||
expect(res.status).toBe(404);
|
||||
// Flow is still waiting — kill it via timeout.
|
||||
await expect(handle.result).rejects.toThrow(/timed out/i);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user