@@ -572,10 +572,129 @@ public function test_conflict_detector_enqueued_when_enabled_webfont() {
572572 /**
573573 * We do not test the v4 font face shim inline style has the detection ignore
574574 * attr, since we can't filter the inline style tag.
575- *
575+ *
576576 * (Probably we'll have a separate mechanism for ignoring that, if the
577577 * conflict detector reports it.)
578578 */
579579 }
580+
581+ /**
582+ * Regression test for JavaScript translations on the admin settings page.
583+ *
584+ * The admin bundle (font-awesome-official-admin) is not registered until the
585+ * admin_enqueue_scripts hook fires (inside maybe_enqueue_admin_assets ->
586+ * enqueue_admin_js_assets). wp_set_script_translations() must therefore run
587+ * *after* that registration, or WP_Scripts::print_translations() bails early
588+ * (empty textdomain) and never emits the inline setLocaleData script, leaving
589+ * the settings page in English regardless of the site locale.
590+ *
591+ * This drives the real admin_enqueue_scripts flow and asserts that the admin
592+ * script ends up with its textdomain associated, and that the setLocaleData
593+ * inline script is produced.
594+ */
595+ public function test_admin_script_translations_are_set () {
596+ // Enable conflict detection so the admin JS bundle is enqueued on
597+ // admin_enqueue_scripts regardless of the current screen. This lets us
598+ // exercise the real enqueue flow without standing up a settings-page
599+ // screen_id.
600+ $ later = time () + ( 10 * 60 );
601+ update_option (
602+ FontAwesome::CONFLICT_DETECTION_OPTIONS_KEY ,
603+ array_merge (
604+ FontAwesome::DEFAULT_CONFLICT_DETECTION_OPTIONS ,
605+ array ( 'detectConflictsUntil ' => $ later )
606+ )
607+ );
608+
609+ // set_up() pre-registers a stub for the admin handle so unrelated tests
610+ // can satisfy the conflict detector's dependency. Deregister it here so
611+ // this test reproduces the real runtime, where the admin bundle is not
612+ // registered until admin_enqueue_scripts fires. (Otherwise the premature,
613+ // buggy wp_set_script_translations() call would find the stub already
614+ // registered and the bug would be masked.)
615+ wp_deregister_script ( FontAwesome::ADMIN_RESOURCE_HANDLE );
616+
617+ // There is no real .json translation file installed in the test
618+ // environment, so short-circuit the file lookup with fake translation
619+ // data. print_translations() still bails on an empty textdomain, so this
620+ // filter does not paper over the bug being tested.
621+ $ fake_translations = wp_json_encode (
622+ array (
623+ 'domain ' => 'messages ' ,
624+ 'locale_data ' => array (
625+ 'messages ' => array (
626+ '' => array (
627+ 'domain ' => 'messages ' ,
628+ 'lang ' => 'ja ' ,
629+ ),
630+ 'Settings ' => array ( '設定 ' ),
631+ ),
632+ ),
633+ )
634+ );
635+
636+ add_filter (
637+ 'pre_load_script_translations ' ,
638+ function ( $ translations , $ file , $ handle , $ domain ) use ( $ fake_translations ) {
639+ if ( FontAwesome::ADMIN_RESOURCE_HANDLE === $ handle && 'font-awesome ' === $ domain ) {
640+ return $ fake_translations ;
641+ }
642+ return $ translations ;
643+ },
644+ 10 ,
645+ 4
646+ );
647+
648+ // Run the plugin's init. This registers the admin_enqueue_scripts
649+ // callback. On the buggy code, this is also where wp_set_script_translations()
650+ // was (incorrectly) called -- too early, before the admin bundle exists.
651+ fa ()->init ();
652+
653+ $ this ->assertFalse (
654+ wp_script_is ( FontAwesome::ADMIN_RESOURCE_HANDLE , 'registered ' ),
655+ 'Precondition: the admin bundle must not be registered until admin_enqueue_scripts runs. '
656+ );
657+
658+ // A current screen must be set, since WordPress core callbacks on
659+ // admin_enqueue_scripts (e.g. wp_auth_check_load) read
660+ // get_current_screen()->id.
661+ set_current_screen ( 'settings_page_font-awesome ' );
662+
663+ // Fire the admin_enqueue_scripts hook. This registers/enqueues the admin
664+ // bundle and -- with the fix -- associates the textdomain with it.
665+ do_action ( 'admin_enqueue_scripts ' , 'settings_page_font-awesome ' );
666+
667+ $ wp_scripts = wp_scripts ();
668+
669+ $ this ->assertArrayHasKey (
670+ FontAwesome::ADMIN_RESOURCE_HANDLE ,
671+ $ wp_scripts ->registered ,
672+ 'The admin bundle should be registered after admin_enqueue_scripts. '
673+ );
674+
675+ // Root cause from the bug report: the script object's textdomain property
676+ // was never set, so print_translations() returned early.
677+ $ this ->assertEquals (
678+ 'font-awesome ' ,
679+ $ wp_scripts ->registered [ FontAwesome::ADMIN_RESOURCE_HANDLE ]->textdomain ,
680+ 'The admin script must have its textdomain set to font-awesome. '
681+ );
682+
683+ // With the textdomain set, print_translations() should emit the inline
684+ // setLocaleData script -- the <script id="font-awesome-official-admin-js-translations">
685+ // element that was reported as absent from the DOM.
686+ $ translations_output = $ wp_scripts ->print_translations ( FontAwesome::ADMIN_RESOURCE_HANDLE , false );
687+
688+ $ this ->assertNotFalse (
689+ $ translations_output ,
690+ 'print_translations() must not return false; otherwise no setLocaleData script is output. '
691+ );
692+
693+ $ this ->assertStringContainsString (
694+ 'wp.i18n.setLocaleData ' ,
695+ $ translations_output ,
696+ 'The translations output should call wp.i18n.setLocaleData. '
697+ );
698+ }
580699}
581700
0 commit comments