Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 30s
CI / tests-integration (push) Successful in 1m40s
CI / tests-unit (push) Successful in 1m51s
CI / tests-ui (push) Successful in 2m43s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m10s
Effect renders need a little over 4s, which the 4s primary timeout cut off, so every avatar with the default effect fell through to an unreachable public fallback and rendered as a placeholder. Raise the primary budget above the observed render cost and shorten the fallback budget. Also stop the proxy from stamping no-store over the avatar and media responses, so browsers keep the long-lived Cache-Control the route already sends, and recreate the imaging cache directories with the container user on every deploy, since root ownership made those cache writes fail silently.
76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
// @ts-nocheck
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { getAvatarUrl } from "./imager";
|
|
import { FALLBACK_TIMEOUT_MS, PRIMARY_TIMEOUT_MS } from "./imager-upstream";
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllEnvs();
|
|
});
|
|
|
|
describe("getAvatarUrl", () => {
|
|
beforeEach(() => {
|
|
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "https://img.example.com");
|
|
});
|
|
|
|
it("builds a query string with defaults (omits default params)", () => {
|
|
const url = getAvatarUrl("hd-180-1");
|
|
expect(url.startsWith("/api/imaging/avatar?")).toBe(true);
|
|
expect(url).toContain("figure=hd-180-1");
|
|
expect(url).not.toContain("direction=2");
|
|
expect(url).not.toContain("head_direction=3");
|
|
expect(url).not.toContain("size=m");
|
|
expect(url).toContain("img_format=apng");
|
|
expect(url).toContain("effect=14");
|
|
});
|
|
|
|
it("honors custom options", () => {
|
|
const url = getAvatarUrl("hd-180-1", {
|
|
size: "l",
|
|
direction: 1,
|
|
headDirection: 2,
|
|
headOnly: true,
|
|
gesture: "sml",
|
|
action: "sit",
|
|
});
|
|
expect(url).toContain("size=l");
|
|
expect(url).toContain("direction=1");
|
|
expect(url).toContain("head_direction=2");
|
|
expect(url).toContain("headonly=1");
|
|
expect(url).toContain("gesture=sml");
|
|
expect(url).toContain("action=sit");
|
|
});
|
|
|
|
it("escapes figure values in the query string", () => {
|
|
const url = getAvatarUrl("hd-180-1&x=1");
|
|
expect(url).not.toContain("&x=1");
|
|
});
|
|
|
|
it("allows custom img_format", () => {
|
|
const url = getAvatarUrl("hd-180-1", { img_format: "png" });
|
|
expect(url).toContain("img_format=png");
|
|
});
|
|
|
|
it("allows custom effect", () => {
|
|
const url = getAvatarUrl("hd-180-1", { effect: 0 });
|
|
expect(url).toContain("effect=0");
|
|
});
|
|
|
|
it("uses the local runtime proxy when no env var is set", () => {
|
|
vi.stubEnv("NEXT_PUBLIC_IMAGER_URL", "");
|
|
const url = getAvatarUrl("hd-180-1");
|
|
expect(url.startsWith("/api/imaging/avatar?")).toBe(true);
|
|
expect(url).toContain("img_format=apng");
|
|
expect(url).toContain("effect=14");
|
|
});
|
|
});
|
|
|
|
describe("upstream render budgets", () => {
|
|
it("keeps enough headroom for APNG effect renders", () => {
|
|
expect(PRIMARY_TIMEOUT_MS).toBeGreaterThanOrEqual(8_000);
|
|
});
|
|
|
|
it("does not stack a long fallback wait on a slow primary", () => {
|
|
expect(FALLBACK_TIMEOUT_MS).toBeLessThan(PRIMARY_TIMEOUT_MS);
|
|
});
|
|
});
|