@@ -44,64 +44,159 @@ describe("LanguageBox Class", () => {
4444
4545 beforeEach ( ( ) => {
4646 jest . clearAllMocks ( ) ;
47+ // Reset storage to initial state
48+ mockActivity . storage . languagePreference = "enUS" ;
49+ mockActivity . storage . kanaPreference = null ;
4750 languageBox = new LanguageBox ( mockActivity ) ;
4851 } ) ;
4952
50- it ( "should reload the window when OnClick is called" , ( ) => {
51- const reloadSpy = jest . spyOn ( languageBox , "reload" ) . mockImplementation ( ( ) => { } ) ;
52- languageBox . OnClick ( ) ;
53- expect ( reloadSpy ) . toHaveBeenCalled ( ) ;
54- reloadSpy . mockRestore ( ) ;
53+ // ===== CONSTRUCTOR TESTS =====
54+ describe ( "Constructor" , ( ) => {
55+ it ( "should initialize successfully" , ( ) => {
56+ expect ( languageBox ) . toBeDefined ( ) ;
57+ } ) ;
58+
59+ it ( "should have language property initialized" , ( ) => {
60+ expect ( languageBox . _language ) . toBeDefined ( ) ;
61+ } ) ;
5562 } ) ;
5663
57- it ( "should display 'already set' message when the selected language is the same" , ( ) => {
58- localStorage . getItem . mockReturnValue ( "enUS" ) ;
59- mockActivity . textMsg . mockImplementation ( ) ;
64+ // ===== ONCLICK TEST =====
65+ describe ( "OnClick method" , ( ) => {
66+ it ( "should call reload method when OnClick is called" , ( ) => {
67+ const reloadSpy = jest . spyOn ( languageBox , "reload" ) . mockImplementation ( ( ) => { } ) ;
68+ languageBox . OnClick ( ) ;
69+ expect ( reloadSpy ) . toHaveBeenCalled ( ) ;
70+ reloadSpy . mockRestore ( ) ;
71+ } ) ;
72+ } ) ;
6073
61- languageBox . _language = "enUS" ;
62- languageBox . hide ( ) ;
74+ // ===== HIDE METHOD - BASIC TESTS =====
75+ describe ( "hide method" , ( ) => {
76+ it ( "should display 'already set' message when the selected language is the same" , ( ) => {
77+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
78+ mockActivity . textMsg . mockImplementation ( ) ;
6379
64- expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
65- "Music Blocks is already set to this language."
66- ) ;
67- } ) ;
80+ languageBox . _language = "enUS" ;
81+ languageBox . hide ( ) ;
6882
69- it ( "should display the refresh message when a new language is selected" , ( ) => {
70- localStorage . getItem . mockReturnValue ( "ja" ) ;
71- mockActivity . textMsg . mockImplementation ( ) ;
83+ expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
84+ "Music Blocks is already set to this language."
85+ ) ;
86+ } ) ;
7287
73- languageBox . _language = "enUS" ;
74- languageBox . hide ( ) ;
88+ it ( "should display the refresh message when a new language is selected" , ( ) => {
89+ localStorage . getItem . mockReturnValue ( "ja" ) ;
90+ mockActivity . textMsg . mockImplementation ( ) ;
7591
76- expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
77- expect . stringContaining ( "Refresh your browser to change your language preference." )
78- ) ;
79- } ) ;
92+ languageBox . _language = "enUS" ;
93+ languageBox . hide ( ) ;
8094
81- it ( "should display the correct message when hide is called for 'ja'" , ( ) => {
82- localStorage . getItem . mockReturnValue ( "enUS" ) ;
83- mockActivity . textMsg . mockImplementation ( ) ;
95+ expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
96+ expect . stringContaining ( "Refresh your browser to change your language preference." )
97+ ) ;
98+ } ) ;
8499
85- languageBox . _language = "ja" ;
86- languageBox . hide ( ) ;
100+ it ( "should display the correct message when hide is called for 'ja'" , ( ) => {
101+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
102+ mockActivity . textMsg . mockImplementation ( ) ;
87103
88- expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
89- expect . stringContaining ( "言語を変えるには、ブラウザをこうしんしてください。" )
90- ) ;
91- } ) ;
104+ languageBox . _language = "ja" ;
105+ languageBox . hide ( ) ;
106+
107+ expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
108+ expect . stringContaining ( "言語を変えるには、ブラウザをこうしんしてください。" )
109+ ) ;
110+ } ) ;
111+
112+ it ( "should display kana message when Japanese language is selected with kana preference" , ( ) => {
113+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
114+ mockActivity . storage . kanaPreference = "kana" ;
115+ mockActivity . textMsg . mockImplementation ( ) ;
116+
117+ languageBox . _language = "ja" ;
118+ languageBox . hide ( ) ;
119+
120+ expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
121+ expect . stringContaining ( "げんごを かえるには、ブラウザを こうしんしてください。" )
122+ ) ;
123+ } ) ;
124+
125+ it ( "should display kanji message when Japanese language is selected with kanji preference" , ( ) => {
126+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
127+ mockActivity . storage . kanaPreference = "kanji" ;
128+ mockActivity . textMsg . mockImplementation ( ) ;
129+
130+ languageBox . _language = "ja-kanji" ;
131+ languageBox . hide ( ) ;
132+
133+ expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
134+ expect . stringContaining ( "言語を変えるには、ブラウザをこうしんしてください。" )
135+ ) ;
136+ } ) ;
137+
138+ it ( "should handle when localStorage.getItem returns null" , ( ) => {
139+ localStorage . getItem . mockReturnValue ( null ) ;
140+ mockActivity . textMsg . mockImplementation ( ) ;
141+
142+ languageBox . _language = "enUS" ;
143+ languageBox . hide ( ) ;
144+
145+ expect ( mockActivity . textMsg ) . toHaveBeenCalled ( ) ;
146+ } ) ;
147+
148+ it ( "should handle French (fr) language correctly" , ( ) => {
149+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
150+ mockActivity . textMsg . mockImplementation ( ) ;
151+
152+ languageBox . _language = "fr" ;
153+ languageBox . hide ( ) ;
154+
155+ expect ( mockActivity . textMsg ) . toHaveBeenCalled ( ) ;
156+ } ) ;
157+
158+ it ( "should handle German (de) language correctly" , ( ) => {
159+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
160+ mockActivity . textMsg . mockImplementation ( ) ;
161+
162+ languageBox . _language = "de" ;
163+ languageBox . hide ( ) ;
164+
165+ expect ( mockActivity . textMsg ) . toHaveBeenCalled ( ) ;
166+ } ) ;
92167
93- it ( "should attach click listeners to language links when hide is called" , ( ) => {
94- const mockLinks = [ { addEventListener : jest . fn ( ) } , { addEventListener : jest . fn ( ) } ] ;
95- document . querySelectorAll . mockReturnValue ( mockLinks ) ;
168+ it ( "should call activity.textMsg exactly once per hide() call" , ( ) => {
169+ localStorage . getItem . mockReturnValue ( "enUS" ) ;
170+ mockActivity . textMsg . mockImplementation ( ) ;
171+
172+ languageBox . _language = "enUS" ;
173+ languageBox . hide ( ) ;
174+
175+ expect ( mockActivity . textMsg ) . toHaveBeenCalledTimes ( 1 ) ;
176+ } ) ;
177+
178+ it ( "should attach click listeners to language links when hide is called" , ( ) => {
179+ const mockLinks = [ { addEventListener : jest . fn ( ) } , { addEventListener : jest . fn ( ) } ] ;
180+ document . querySelectorAll . mockReturnValue ( mockLinks ) ;
181+
182+ languageBox . hide ( ) ;
96183
97- languageBox . hide ( ) ;
184+ mockLinks . forEach ( link => {
185+ expect ( link . addEventListener ) . toHaveBeenCalledWith ( "click" , expect . any ( Function ) ) ;
186+ } ) ;
187+ } ) ;
188+
189+ it ( "should query for language elements in the DOM" , ( ) => {
190+ const mockLinks = [ { addEventListener : jest . fn ( ) } ] ;
191+ document . querySelectorAll . mockReturnValue ( mockLinks ) ;
98192
99- mockLinks . forEach ( link => {
100- expect ( link . addEventListener ) . toHaveBeenCalledWith ( "click" , expect . any ( Function ) ) ;
193+ languageBox . hide ( ) ;
194+
195+ expect ( document . querySelectorAll ) . toHaveBeenCalled ( ) ;
101196 } ) ;
102197 } ) ;
103198
104- // Test each language selection method
199+ // ===== LANGUAGE SELECTION TESTS =====
105200 describe ( "Language selection methods" , ( ) => {
106201 it ( "should set language to enUS and call hide when enUS_onclick is called" , ( ) => {
107202 const hideSpy = jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
@@ -268,19 +363,75 @@ describe("LanguageBox Class", () => {
268363 } ) ;
269364 } ) ;
270365
271- // Test Japanese kana preference
366+ // ===== LANGUAGE PREFERENCE TESTS =====
367+ describe ( "Language preference updates" , ( ) => {
368+ it ( "should update storage.languagePreference when language changes" , ( ) => {
369+ jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
370+
371+ languageBox . enUS_onclick ( ) ;
372+ expect ( mockActivity . storage . languagePreference ) . toBe ( "enUS" ) ;
373+ } ) ;
374+
375+ it ( "should store kanji preference when ja_onclick is called" , ( ) => {
376+ jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
377+
378+ languageBox . ja_onclick ( ) ;
379+ expect ( mockActivity . storage . kanaPreference ) . toBe ( "kanji" ) ;
380+ } ) ;
381+
382+ it ( "should store kana preference when kana_onclick is called" , ( ) => {
383+ jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
384+
385+ languageBox . kana_onclick ( ) ;
386+ expect ( mockActivity . storage . kanaPreference ) . toBe ( "kana" ) ;
387+ } ) ;
388+ } ) ;
389+
390+ // ===== JAPANESE VARIANT HANDLING =====
272391 describe ( "Japanese kana handling" , ( ) => {
273- it ( "should display kana message when Japanese language is selected with kana preference" , ( ) => {
274- localStorage . getItem . mockReturnValue ( "enUS" ) ;
275- mockActivity . storage . kanaPreference = "kana" ;
276- mockActivity . textMsg . mockImplementation ( ) ;
392+ it ( "should switch between ja-kanji and ja-kana correctly" , ( ) => {
393+ const hideSpy = jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
277394
278- languageBox . _language = "ja" ;
279- languageBox . hide ( ) ;
395+ languageBox . ja_onclick ( ) ;
396+ expect ( languageBox . _language ) . toBe ( "ja-kanji" ) ;
397+ expect ( mockActivity . storage . kanaPreference ) . toBe ( "kanji" ) ;
280398
281- expect ( mockActivity . textMsg ) . toHaveBeenCalledWith (
282- expect . stringContaining ( "げんごを かえるには、ブラウザを こうしんしてください。" )
283- ) ;
399+ languageBox . kana_onclick ( ) ;
400+ expect ( languageBox . _language ) . toBe ( "ja-kana" ) ;
401+ expect ( mockActivity . storage . kanaPreference ) . toBe ( "kana" ) ;
284402 } ) ;
285403 } ) ;
286- } ) ;
404+
405+ // ===== SEQUENTIAL LANGUAGE CHANGES =====
406+ describe ( "Sequential language changes" , ( ) => {
407+ it ( "should update language correctly when changing multiple times" , ( ) => {
408+ const hideSpy = jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
409+
410+ languageBox . enUS_onclick ( ) ;
411+ expect ( languageBox . _language ) . toBe ( "enUS" ) ;
412+
413+ languageBox . ja_onclick ( ) ;
414+ expect ( languageBox . _language ) . toBe ( "ja-kanji" ) ;
415+
416+ languageBox . es_onclick ( ) ;
417+ expect ( languageBox . _language ) . toBe ( "es" ) ;
418+
419+ expect ( hideSpy ) . toHaveBeenCalledTimes ( 3 ) ;
420+ } ) ;
421+
422+ it ( "should handle switching from Spanish to Korean and back" , ( ) => {
423+ const hideSpy = jest . spyOn ( languageBox , "hide" ) . mockImplementation ( ) ;
424+
425+ languageBox . es_onclick ( ) ;
426+ expect ( languageBox . _language ) . toBe ( "es" ) ;
427+
428+ languageBox . ko_onclick ( ) ;
429+ expect ( languageBox . _language ) . toBe ( "ko" ) ;
430+
431+ languageBox . es_onclick ( ) ;
432+ expect ( languageBox . _language ) . toBe ( "es" ) ;
433+
434+ expect ( hideSpy ) . toHaveBeenCalledTimes ( 3 ) ;
435+ } ) ;
436+ } ) ;
437+ } ) ;
0 commit comments