mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
Fix localization issue with hardcoded English strings (#8736)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -8,6 +8,29 @@ import userEvent from "@testing-library/user-event";
|
||||
import { HomeHeader } from "#/components/features/home/home-header";
|
||||
import OpenHands from "#/api/open-hands";
|
||||
|
||||
// Mock the translation function
|
||||
vi.mock("react-i18next", async () => {
|
||||
const actual = await vi.importActual("react-i18next");
|
||||
return {
|
||||
...actual,
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => {
|
||||
// Return a mock translation for the test
|
||||
const translations: Record<string, string> = {
|
||||
"HOME$LETS_START_BUILDING": "Let's start building",
|
||||
"HOME$LAUNCH_FROM_SCRATCH": "Launch from Scratch",
|
||||
"HOME$LOADING": "Loading...",
|
||||
"HOME$OPENHANDS_DESCRIPTION": "OpenHands is an AI software engineer",
|
||||
"HOME$NOT_SURE_HOW_TO_START": "Not sure how to start?",
|
||||
"HOME$READ_THIS": "Read this"
|
||||
};
|
||||
return translations[key] || key;
|
||||
},
|
||||
i18n: { language: "en" },
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
const renderHomeHeader = () => {
|
||||
const RouterStub = createRoutesStub([
|
||||
{
|
||||
@@ -38,7 +61,7 @@ describe("HomeHeader", () => {
|
||||
renderHomeHeader();
|
||||
|
||||
const launchButton = screen.getByRole("button", {
|
||||
name: /launch from scratch/i,
|
||||
name: /Launch from Scratch/i,
|
||||
});
|
||||
await userEvent.click(launchButton);
|
||||
|
||||
@@ -60,11 +83,11 @@ describe("HomeHeader", () => {
|
||||
renderHomeHeader();
|
||||
|
||||
const launchButton = screen.getByRole("button", {
|
||||
name: /launch from scratch/i,
|
||||
name: /Launch from Scratch/i,
|
||||
});
|
||||
await userEvent.click(launchButton);
|
||||
|
||||
expect(launchButton).toHaveTextContent(/Loading/i);
|
||||
expect(launchButton).toHaveTextContent(/Loading.../i);
|
||||
expect(launchButton).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,11 @@ describe("Check for hardcoded English strings", () => {
|
||||
const text = container.textContent;
|
||||
|
||||
// List of English strings that should be translated
|
||||
const hardcodedStrings = ["What do you want to build?"];
|
||||
const hardcodedStrings = [
|
||||
"What do you want to build?",
|
||||
"Launch from Scratch",
|
||||
"Read this"
|
||||
];
|
||||
|
||||
// Check each string
|
||||
hardcodedStrings.forEach((str) => {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { render } from "@testing-library/react";
|
||||
import { test, expect, describe, vi } from "vitest";
|
||||
import { HomeHeader } from "#/components/features/home/home-header";
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock("#/hooks/mutation/use-create-conversation", () => ({
|
||||
useCreateConversation: () => ({
|
||||
mutate: vi.fn(),
|
||||
isPending: false,
|
||||
isSuccess: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("#/hooks/use-is-creating-conversation", () => ({
|
||||
useIsCreatingConversation: () => false,
|
||||
}));
|
||||
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe("Check for hardcoded English strings in Home components", () => {
|
||||
test("HomeHeader should not have hardcoded English strings", () => {
|
||||
const { container } = render(<HomeHeader />);
|
||||
|
||||
// Get all text content
|
||||
const text = container.textContent;
|
||||
|
||||
// List of English strings that should be translated
|
||||
const hardcodedStrings = [
|
||||
"Launch from Scratch",
|
||||
"Read this",
|
||||
];
|
||||
|
||||
// Check each string
|
||||
hardcodedStrings.forEach((str) => {
|
||||
expect(text).not.toContain(str);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,7 @@ export function HomeHeader() {
|
||||
onClick={() => createConversation({})}
|
||||
isDisabled={isCreatingConversation}
|
||||
>
|
||||
{!isCreatingConversation && "Launch from Scratch"}
|
||||
{!isCreatingConversation && t("HOME$LAUNCH_FROM_SCRATCH")}
|
||||
{isCreatingConversation && t("HOME$LOADING")}
|
||||
</BrandButton>
|
||||
</div>
|
||||
@@ -48,7 +48,7 @@ export function HomeHeader() {
|
||||
rel="noopener noreferrer"
|
||||
className="underline underline-offset-2"
|
||||
>
|
||||
Read this
|
||||
{t("HOME$READ_THIS")}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,36 @@
|
||||
{
|
||||
"HOME$LAUNCH_FROM_SCRATCH": {
|
||||
"en": "Launch from Scratch",
|
||||
"ja": "ゼロから始める",
|
||||
"zh-CN": "从零开始",
|
||||
"zh-TW": "從零開始",
|
||||
"ko-KR": "처음부터 시작",
|
||||
"no": "Start fra bunnen",
|
||||
"it": "Inizia da zero",
|
||||
"pt": "Começar do zero",
|
||||
"es": "Comenzar desde cero",
|
||||
"ar": "البدء من الصفر",
|
||||
"fr": "Démarrer de zéro",
|
||||
"tr": "Sıfırdan başla",
|
||||
"de": "Von Grund auf starten",
|
||||
"uk": "Почати з нуля"
|
||||
},
|
||||
"HOME$READ_THIS": {
|
||||
"en": "Read this",
|
||||
"ja": "こちらを読む",
|
||||
"zh-CN": "阅读此内容",
|
||||
"zh-TW": "閱讀此內容",
|
||||
"ko-KR": "이것을 읽어보세요",
|
||||
"no": "Les dette",
|
||||
"it": "Leggi questo",
|
||||
"pt": "Leia isto",
|
||||
"es": "Leer esto",
|
||||
"ar": "اقرأ هذا",
|
||||
"fr": "Lire ceci",
|
||||
"tr": "Bunu oku",
|
||||
"de": "Lies dies",
|
||||
"uk": "Прочитайте це"
|
||||
},
|
||||
"AUTH$LOGGING_BACK_IN": {
|
||||
"en": "Logging back into OpenHands...",
|
||||
"ja": "OpenHandsに再ログインしています...",
|
||||
|
||||
Reference in New Issue
Block a user