import { i18n } from "@lingui/core";
import { msg } from "@lingui/core/macro";
import { screen } from "@testing-library/react";
import CharacterCount from "@tiptap/extension-character-count";
import { useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import * as React from "react";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { _EditorFooter, countWords } from "../../src/components/PortableTextEditor";
import { render } from "../utils/render.tsx";
// The msg macro hashes to the same message id as the corresponding macro call
// in EditorFooter, so this catalog binds translations for exactly the messages
// the footer renders.
const deMessages = {
[msg`{words, plural, one {# word} other {# words}}`.id!]:
"{words, plural, one {# Wort} other {# Wörter}}",
[msg`{characters, plural, one {# character} other {# characters}}`.id!]:
"{characters, plural, one {# Zeichen} other {# Zeichen}}",
[msg`{readingTime, plural, one {# min read} other {# min read}}`.id!]:
"{readingTime, plural, one {# Minute Lesezeit} other {# Min. Lesezeit}}",
};
beforeAll(() => {
i18n.loadAndActivate({ locale: "de", messages: deMessages });
});
afterAll(() => {
i18n.loadAndActivate({ locale: "en", messages: {} });
});
function FooterHarness({ content }: { content: string }) {
const editor = useEditor({
extensions: [StarterKit, CharacterCount.configure({ wordCounter: countWords })],
content,
immediatelyRender: true,
});
if (!editor) return null;
return <_EditorFooter editor={editor} />;
}
describe("EditorFooter localization", () => {
it("renders the metrics translated when the active catalog provides them", async () => {
void render();
await vi.waitFor(() => {
expect(screen.getByText("3 Wörter")).toBeTruthy();
});
expect(screen.getByText("17 Zeichen")).toBeTruthy();
expect(screen.getByText("1 Minute Lesezeit")).toBeTruthy();
});
it("uses the catalog's plural rules for the singular branch", async () => {
void render();
await vi.waitFor(() => {
expect(screen.getByText("1 Wort")).toBeTruthy();
});
expect(screen.getByText("5 Zeichen")).toBeTruthy();
});
});