tests/oauth-consent.spec.ts
Rama main · réplica de lectura del repositorio original.
import { expect } from "@playwright/test";
import { OAuthGrant } from "../apps/backend/src/database/models";
import { createOAuthClient } from "../apps/backend/src/database/seeds";
import {
OAUTH_SCOPE_LIST,
serializeScopes,
} from "../apps/backend/src/oauth/scopes";
import { loggedTest } from "./logged-test";
import { ensureTeamOwner, getUniqueTestIdentifier, screenshot } from "./util";
const REDIRECT_URI = "http://localhost:4001/callback";
/** A syntactically valid S256 challenge; the consent screen only forwards it. */
const CODE_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM";
const consentTest = loggedTest.extend<{ authorizeUrl: string }>({
authorizeUrl: async ({ user, team }, use, testInfo) => {
await ensureTeamOwner({ team: team.team, user: user.user });
const client = await createOAuthClient({
clientId: `argos-cli-${getUniqueTestIdentifier(testInfo)}`,
redirectUris: [REDIRECT_URI],
knownAppId: "argos-cli",
});
const params = new URLSearchParams({
client_id: client.clientId,
redirect_uri: REDIRECT_URI,
response_type: "code",
// Request every scope so the screen offers every preset.
scope: serializeScopes(OAUTH_SCOPE_LIST),
code_challenge: CODE_CHALLENGE,
code_challenge_method: "S256",
});
await use(`/oauth/authorize?${params.toString()}`);
},
});
consentTest("oauth consent screen", async ({ page, authorizeUrl }) => {
await page.goto(authorizeUrl);
await expect(
page.getByRole("heading", { name: "Authorize Argos CLI" }),
).toBeVisible();
await expect(
page.getByRole("radio", { name: "Read and write" }),
).toBeChecked();
await screenshot(page, "oauth-consent");
await page.getByRole("radio", { name: "Custom" }).click();
// Every scope resource must render a titled group — a resource missing from
// the frontend's SCOPE_GROUPS map falls back to its raw key (e.g. "media").
for (const label of [
"Profile",
"Projects",
"Builds",
"Reviews",
"Comments",
"Media",
"Organization",
]) {
await expect(page.getByText(label, { exact: true })).toBeVisible();
}
await screenshot(page, "oauth-consent-custom");
});
consentTest(
"oauth consent grants the chosen preset and remembers it",
async ({ page, authorizeUrl, user }) => {
await page.route(`${REDIRECT_URI}?*`, (route) =>
route.fulfill({ contentType: "text/plain", body: "Authorized" }),
);
await page.goto(authorizeUrl);
await page.getByRole("radio", { name: "Read only" }).click();
await page.getByRole("button", { name: "Authorize Argos CLI" }).click();
await page.waitForURL(`${REDIRECT_URI}?*`);
const grant = await OAuthGrant.query()
.findOne({ userId: user.user.id })
.throwIfNotFound();
expect(grant.scopes).toEqual([
"profile",
"projects:read",
"comments:read",
"media:read",
]);
await page.goto(authorizeUrl);
await expect(page.getByRole("radio", { name: "Read only" })).toBeChecked();
},
);