Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 33s
CI / tests-integration (push) Successful in 1m42s
CI / tests-unit (push) Successful in 1m47s
CI / tests-ui (push) Successful in 2m30s
CI / preflight (push) Skipped
CI / deploy (push) Failing after 2m56s
- add countArticles() (published-only, mirrors news-list) and warm total_articles - localize homepage metadata; bind articleCount to both stats; unique photo alts - drop duplicate news date and the mascot preload priorities - extract shared AuthPageFrame/AuthUsersCards used by /login and /register - login: localized noindex metadata, session redirect via safeRedirectPath, ?from passthrough from proxy, unified auth roster cache keys, registered notice - register: localized metadata, session redirect to /me, unified cache keys - add resend-verification flow on /verify with rate-limited non-enumerable action - add safeRedirectPath() with unit tests - register form: live requirements checklist + password mismatch guard - login form: unverified state with resend-link CTA - honour prefers-reduced-motion in TypewriterText - add 6 translations across all 25 locales
47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const compactCallSites = new Map<string, number>([
|
|
["src/components/top-header.tsx", 1],
|
|
// /login and /register render their rosters through this shared frame.
|
|
["src/components/auth/auth-page-frame.tsx", 1],
|
|
["src/app/(site)/friends/page.tsx", 1],
|
|
["src/app/(site)/guilds/[id]/page.tsx", 1],
|
|
["src/app/(site)/leaderboard/page.tsx", 1],
|
|
["src/app/(site)/me/page.tsx", 1],
|
|
["src/app/(site)/messages/page.tsx", 2],
|
|
["src/app/(site)/page.tsx", 2],
|
|
["src/app/(site)/radio/leaderboard/page.tsx", 1],
|
|
["src/app/(site)/radio/shouts/page.tsx", 1],
|
|
["src/app/(site)/rankings/page.tsx", 1],
|
|
["src/app/(site)/search/page.tsx", 1],
|
|
["src/app/(site)/u/[username]/page.tsx", 2],
|
|
]);
|
|
|
|
function source(path: string): string {
|
|
return readFileSync(resolve(process.cwd(), path), "utf8");
|
|
}
|
|
|
|
describe("public avatar presentation contract", () => {
|
|
it.each([...compactCallSites])(
|
|
"uses the shared thumbnail in %s",
|
|
(path, expectedCount) => {
|
|
const matches = source(path).match(/<UserAvatarThumbnail\b/g) ?? [];
|
|
expect(matches).toHaveLength(expectedCount);
|
|
},
|
|
);
|
|
|
|
it("preserves explicit full-avatar previews", () => {
|
|
expect(source("src/app/(site)/me/page.tsx")).toContain(
|
|
"avatarImageUrl(user.look",
|
|
);
|
|
expect(source("src/app/(site)/settings/page.tsx")).toContain(
|
|
"avatarImageUrl(user.look",
|
|
);
|
|
expect(source("src/app/(site)/u/[username]/page.tsx")).toContain(
|
|
"avatarImageUrl(user.look",
|
|
);
|
|
});
|
|
});
|