lint: fix biome issues in new test files and helpers
CI / check (push) Failing after 34s
CI / preflight (push) Skipped
CI / deploy (push) Skipped

This commit is contained in:
openhands committed 2026-09-21 18:19:39 +02:00
1 parent 99eb3af17b
commit 93862c2275
41 files changed
+488 -314

No files matched your search

+58 -18
View File
@@ -3,9 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
const state = vi.hoisted(() => ({
allowed: [] as string[],
saveCmsTranslation: vi.fn(),
translationError: vi.fn<
(code: string, args?: { key?: string }) => string
>(),
translationError: vi.fn<(code: string, args?: { key?: string }) => string>(),
patchJson5: vi.fn(),
readFile: vi.fn(),
writeFile: vi.fn(),
@@ -81,7 +79,11 @@ vi.mock("node:fs/promises", () => ({
readFile: state.readFile,
writeFile: state.writeFile,
mkdir: vi.fn(),
default: { readFile: state.readFile, writeFile: state.writeFile, mkdir: vi.fn() },
default: {
readFile: state.readFile,
writeFile: state.writeFile,
mkdir: vi.fn(),
},
}));
vi.mock("@/lib/cms-translations", () => ({
@@ -97,10 +99,13 @@ const mockGetClientTranslationFile = vi.hoisted(() => vi.fn());
vi.mock("@/lib/client-translation-files", async (importOriginal) => {
const original =
await importOriginal<typeof import("@/lib/client-translation-files")>();
return { ...original, getClientTranslationFile: mockGetClientTranslationFile };
return {
...original,
getClientTranslationFile: mockGetClientTranslationFile,
};
});
import { CLIENT_TRANSLATION_FILES, getClientTranslationFile } from "@/lib/client-translation-files";
import { CLIENT_TRANSLATION_FILES } from "@/lib/client-translation-files";
import { saveClientTranslations, saveTranslations } from "./translations";
const snapshot = { messages: { "a.b": "x" }, revision: "ab".repeat(32) };
@@ -173,7 +178,11 @@ describe("saveTranslations", () => {
it("rejects an unsupported locale and a malformed revision", async () => {
expect(
await saveTranslations({ locale: "xx" as never, revision: "a".repeat(64), changes: {} }),
await saveTranslations({
locale: "xx" as never,
revision: "a".repeat(64),
changes: {},
}),
).toMatchObject({ ok: false, error: "Validation failed" });
expect(
await saveTranslations({ locale: "en", revision: "short", changes: {} }),
@@ -183,7 +192,11 @@ describe("saveTranslations", () => {
it("requires the settings edit permission", async () => {
state.allowed = [];
expect(
await saveTranslations({ locale: "en", revision: "a".repeat(64), changes: {} }),
await saveTranslations({
locale: "en",
revision: "a".repeat(64),
changes: {},
}),
).toEqual({ ok: false, error: "Unauthorized" });
});
});
@@ -191,12 +204,18 @@ describe("saveTranslations", () => {
describe("saveClientTranslations", () => {
it("reports an unknown file id", async () => {
mockGetClientTranslationFile.mockReturnValueOnce(undefined);
const res = await saveClientTranslations({ fileId: "badge-texts-en", data: {} });
const res = await saveClientTranslations({
fileId: "badge-texts-en",
data: {},
});
expect(res).toEqual({ ok: false, error: "Unknown file" });
});
it("refuses to write read-only files", async () => {
const res = await saveClientTranslations({ fileId: "ui-texts-en", data: {} });
const res = await saveClientTranslations({
fileId: "ui-texts-en",
data: {},
});
expect(res).toEqual({ ok: false, error: "File is read-only" });
expect(state.writeFile).not.toHaveBeenCalled();
});
@@ -207,7 +226,10 @@ describe("saveClientTranslations", () => {
fileId: "badge-texts-en",
data: { x: "y" },
});
expect(res).toEqual({ ok: true, data: { commentsLost: false, unpatchedKeys: [] } });
expect(res).toEqual({
ok: true,
data: { commentsLost: false, unpatchedKeys: [] },
});
expect(state.writeFile).toHaveBeenCalledWith(
expect.stringContaining("badge-texts-en.json"),
JSON.stringify({ x: "y" }, null, 4),
@@ -217,12 +239,18 @@ describe("saveClientTranslations", () => {
it("writes a surgical JSON5 patch when every key is patchable", async () => {
state.readFile.mockResolvedValue('{"greeting": "hi",}');
state.patchJson5.mockReturnValue({ content: '{"greeting": "ciao",}', unpatchedKeys: [] });
state.patchJson5.mockReturnValue({
content: '{"greeting": "ciao",}',
unpatchedKeys: [],
});
const res = await saveClientTranslations({
fileId: "ui-texts-it",
data: { greeting: "ciao" },
});
expect(res).toEqual({ ok: true, data: { commentsLost: false, unpatchedKeys: [] } });
expect(res).toEqual({
ok: true,
data: { commentsLost: false, unpatchedKeys: [] },
});
expect(state.patchJson5).toHaveBeenCalledWith(
'{"greeting": "hi",}',
{ greeting: "hi" },
@@ -237,7 +265,10 @@ describe("saveClientTranslations", () => {
it("falls back to re-serialization and flags comment loss for unpatched keys", async () => {
state.readFile.mockResolvedValue('{"known": "old",}');
state.patchJson5.mockReturnValue({ content: '{"known": "old",}', unpatchedKeys: ["brand-new"] });
state.patchJson5.mockReturnValue({
content: '{"known": "old",}',
unpatchedKeys: ["brand-new"],
});
const res = await saveClientTranslations({
fileId: "ui-texts-it",
data: { known: "new", "brand-new": "val" },
@@ -260,18 +291,27 @@ describe("saveClientTranslations", () => {
fileId: "external-texts",
data: { x: "1" },
});
expect(res).toEqual({ ok: true, data: { commentsLost: true, unpatchedKeys: ["x"] } });
expect(res).toEqual({
ok: true,
data: { commentsLost: true, unpatchedKeys: ["x"] },
});
expect(state.patchJson5).toHaveBeenCalledWith("[1,2,3]", {}, { x: "1" });
});
it("validates fileId against the whitelist", async () => {
const res = await saveClientTranslations({ fileId: "hack" as never, data: {} });
const res = await saveClientTranslations({
fileId: "hack" as never,
data: {},
});
expect(res).toMatchObject({ ok: false, error: "Validation failed" });
});
it("requires the settings edit permission", async () => {
state.allowed = [];
const res = await saveClientTranslations({ fileId: "ui-texts-it", data: {} });
const res = await saveClientTranslations({
fileId: "ui-texts-it",
data: {},
});
expect(res).toEqual({ ok: false, error: "Unauthorized" });
});
@@ -281,4 +321,4 @@ describe("saveClientTranslations", () => {
saveClientTranslations({ fileId: "ui-texts-it", data: {} }),
).rejects.toThrow("EACCES");
});
});
});