/auth/link and /auth/upgrade become /auth/google/connect?access=identity|read|write: one handler, one table of what each access asks Google for, the same callback markers. An unknown access is refused (422) instead of quietly meaning read, and an instance without Google answers ?link=error for a grant too, not a silent return to the app. The frontend builds the URL in lib/googleConnect, and a contract test holds it to the backend route and its access values.
22 lines
1.0 KiB
TypeScript
22 lines
1.0 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { describe, expect, it } from "vitest";
|
|
import { GOOGLE_ACCESS, googleConnectUrl } from "./googleConnect";
|
|
|
|
// The frontend builds the Google connect URL by hand, so nothing but this test notices when the
|
|
// backend route moves or its `access` values change: the click would land on a 404 or a 422 page.
|
|
const AUTH = readFileSync(new URL("../../../backend/app/routes/auth.py", import.meta.url), "utf-8");
|
|
|
|
describe("the Google connect URL", () => {
|
|
it("names the backend route", () => {
|
|
const prefix = /APIRouter\(prefix="([^"]+)"/.exec(AUTH)?.[1];
|
|
const path = /@router\.get\("([^"]+)"\)\nasync def google_connect\(/.exec(AUTH)?.[1];
|
|
expect(googleConnectUrl("read").split("?")[0]).toBe(`${prefix}${path}`);
|
|
});
|
|
|
|
it("offers exactly the access values the backend accepts", () => {
|
|
const literal = /access: Literal\[([^\]]+)\]/.exec(AUTH)?.[1] ?? "";
|
|
const accepted = [...literal.matchAll(/"([^"]+)"/g)].map((m) => m[1]);
|
|
expect(accepted).toEqual([...GOOGLE_ACCESS]);
|
|
});
|
|
});
|