1- import { render , screen } from "@testing-library/react" ;
1+ import { render , screen , fireEvent } from "@testing-library/react" ;
22import "@testing-library/jest-dom" ;
33import Navbar from "../../components/Navbar" ;
44import { MemoryRouter } from "react-router-dom" ;
5- import { vi } from "vitest" ;
6-
7- vi . mock ( "react-i18next" , ( ) => ( {
8- useTranslation : ( ) => ( {
9- t : ( key : string ) => {
10- const map : Record < string , string > = {
11- "navbar.templatePlayground" : "Template Playground" ,
12- "navbar.github" : "Github" , // the original test asserted for Github with a capital G
13- } ;
14- return map [ key ] || key ;
15- } ,
16- i18n : { language : "en" , changeLanguage : vi . fn ( ) } ,
17- } ) ,
18- } ) ) ;
5+ import { vi , describe , it , expect , afterEach } from "vitest" ;
6+ import { mockChangeLanguage } from "../../utils/testing/i18nMock" ;
7+
8+ vi . mock ( "react-i18next" , async ( ) => {
9+ const { reactI18nextMock } = await import ( "../../utils/testing/i18nMock" ) ;
10+ return {
11+ useTranslation : ( ) => ( {
12+ t : ( key : string ) => {
13+ const map : Record < string , string > = {
14+ "navbar.templatePlayground" : "Template Playground" ,
15+ "navbar.github" : "GitHub" ,
16+ "navbar.help" : "Help" ,
17+ "navbar.learn" : "Learn Now" ,
18+ "navbar.discord" : "Discord" ,
19+ "navbar.about" : "About" ,
20+ "navbar.community" : "Community" ,
21+ "navbar.issues" : "Issues" ,
22+ "navbar.documentation" : "Documentation" ,
23+ "navbar.info" : "Info" ,
24+ "navbar.language" : "Language" ,
25+ } ;
26+ return map [ key ] || key ;
27+ } ,
28+ i18n : reactI18nextMock . useTranslation ( ) . i18n ,
29+ } ) ,
30+ } ;
31+ } ) ;
1932
2033const renderNavbar = ( ) => {
2134 render (
@@ -25,6 +38,11 @@ const renderNavbar = () => {
2538 ) ;
2639} ;
2740
41+ afterEach ( ( ) => {
42+ mockChangeLanguage . mockClear ( ) ;
43+ localStorage . clear ( ) ;
44+ } ) ;
45+
2846describe ( "Navbar" , ( ) => {
2947 it ( "renders logo and title on small screens" , ( ) => {
3048 renderNavbar ( ) ;
@@ -36,10 +54,10 @@ describe("Navbar", () => {
3654 expect ( title ) . toBeInTheDocument ( ) ;
3755 } ) ;
3856
39- it ( "renders Github link on all screens" , ( ) => {
57+ it ( "renders GitHub link on all screens" , ( ) => {
4058 renderNavbar ( ) ;
4159
42- const githubLink = screen . getByRole ( "link" , { name : / G i t h u b / i } ) ;
60+ const githubLink = screen . getByRole ( "link" , { name : / G i t H u b / i } ) ;
4361 expect ( githubLink ) . toBeInTheDocument ( ) ;
4462 } ) ;
4563
@@ -55,3 +73,32 @@ describe("Navbar", () => {
5573 } ) ;
5674 } ) ;
5775} ) ;
76+
77+ describe ( "Language Switching" , ( ) => {
78+ it ( "selecting a language calls i18n.changeLanguage with the correct code" , ( ) => {
79+ renderNavbar ( ) ;
80+
81+ // Click the language switcher button to open the dropdown
82+ const langButton = screen . getByText ( "English" , { exact : false } ) . closest ( "button" ) ;
83+ expect ( langButton ) . toBeInTheDocument ( ) ;
84+ fireEvent . click ( langButton ! ) ;
85+
86+ // Click the "Français" option in the dropdown
87+ const frenchOption = screen . getByText ( "Français" ) ;
88+ fireEvent . click ( frenchOption ) ;
89+
90+ // Assert changeLanguage was called with 'fr'
91+ expect ( mockChangeLanguage ) . toHaveBeenCalledWith ( "fr" ) ;
92+ } ) ;
93+
94+ it ( "persisted language from localStorage is reflected in the UI on render" , ( ) => {
95+ // Pre-set localStorage to simulate a previously saved language
96+ localStorage . setItem ( "i18nextLng" , "es" ) ;
97+
98+ renderNavbar ( ) ;
99+
100+ // The displayed language label should reflect Spanish
101+ const spanishLabel = screen . getByText ( "Español" , { exact : false } ) ;
102+ expect ( spanishLabel ) . toBeInTheDocument ( ) ;
103+ } ) ;
104+ } ) ;
0 commit comments