@@ -1686,3 +1686,115 @@ test('font loading: adds new font URLs when switching themes', () => {
16861686 . querySelectorAll ( 'style[data-superset-fonts]' )
16871687 . forEach ( el => el . remove ( ) ) ;
16881688} ) ;
1689+
1690+ test ( 'ThemeController uses initialMode when provided and no saved mode exists' , ( ) => {
1691+ mockGetBootstrapData . mockReturnValue (
1692+ createMockBootstrapData ( {
1693+ default : DEFAULT_THEME ,
1694+ dark : DARK_THEME ,
1695+ } ) ,
1696+ ) ;
1697+
1698+ const controller = createController ( { initialMode : ThemeMode . DEFAULT } ) ;
1699+
1700+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . DEFAULT ) ;
1701+ } ) ;
1702+
1703+ test ( 'ThemeController defaults to SYSTEM when initialMode is not provided' , ( ) => {
1704+ mockGetBootstrapData . mockReturnValue (
1705+ createMockBootstrapData ( {
1706+ default : DEFAULT_THEME ,
1707+ dark : DARK_THEME ,
1708+ } ) ,
1709+ ) ;
1710+
1711+ const controller = createController ( ) ;
1712+
1713+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . SYSTEM ) ;
1714+ } ) ;
1715+
1716+ test ( 'ThemeController saved mode takes precedence over initialMode' , ( ) => {
1717+ mockGetBootstrapData . mockReturnValue (
1718+ createMockBootstrapData ( {
1719+ default : DEFAULT_THEME ,
1720+ dark : DARK_THEME ,
1721+ } ) ,
1722+ ) ;
1723+
1724+ mockLocalStorage . getItem . mockReturnValue ( ThemeMode . DARK ) ;
1725+
1726+ const controller = createController ( { initialMode : ThemeMode . DEFAULT } ) ;
1727+
1728+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . DARK ) ;
1729+ } ) ;
1730+
1731+ test ( 'ThemeController with initialMode DEFAULT applies light theme even when system prefers dark' , ( ) => {
1732+ mockGetBootstrapData . mockReturnValue (
1733+ createMockBootstrapData ( {
1734+ default : DEFAULT_THEME ,
1735+ dark : DARK_THEME ,
1736+ } ) ,
1737+ ) ;
1738+
1739+ mockMatchMedia . mockReturnValue ( {
1740+ matches : true , // system prefers dark
1741+ addEventListener : jest . fn ( ) ,
1742+ removeEventListener : jest . fn ( ) ,
1743+ } ) ;
1744+
1745+ const controller = createController ( { initialMode : ThemeMode . DEFAULT } ) ;
1746+
1747+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . DEFAULT ) ;
1748+ const lastCall =
1749+ mockSetConfig . mock . calls [ mockSetConfig . mock . calls . length - 1 ] [ 0 ] ;
1750+ expect ( lastCall . token . colorBgBase ) . toBe ( DEFAULT_THEME . token ! . colorBgBase ) ;
1751+ } ) ;
1752+
1753+ test ( 'ThemeController with initialMode still allows setThemeMode after init' , ( ) => {
1754+ mockGetBootstrapData . mockReturnValue (
1755+ createMockBootstrapData ( {
1756+ default : DEFAULT_THEME ,
1757+ dark : DARK_THEME ,
1758+ } ) ,
1759+ ) ;
1760+
1761+ const controller = createController ( { initialMode : ThemeMode . DEFAULT } ) ;
1762+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . DEFAULT ) ;
1763+
1764+ controller . setThemeMode ( ThemeMode . DARK ) ;
1765+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . DARK ) ;
1766+
1767+ controller . setThemeMode ( ThemeMode . SYSTEM ) ;
1768+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . SYSTEM ) ;
1769+ } ) ;
1770+
1771+ test ( 'ThemeController initialMode is ignored when no dark theme exists' , ( ) => {
1772+ mockGetBootstrapData . mockReturnValue (
1773+ createMockBootstrapData ( {
1774+ default : DEFAULT_THEME ,
1775+ dark : { } ,
1776+ } ) ,
1777+ ) ;
1778+
1779+ const controller = createController ( { initialMode : ThemeMode . SYSTEM } ) ;
1780+
1781+ // Should still be DEFAULT because there's no dark theme available
1782+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . DEFAULT ) ;
1783+ } ) ;
1784+
1785+ test ( 'ThemeController invalid initialMode falls back to SYSTEM' , ( ) => {
1786+ mockGetBootstrapData . mockReturnValue (
1787+ createMockBootstrapData ( {
1788+ default : DEFAULT_THEME ,
1789+ dark : DARK_THEME ,
1790+ } ) ,
1791+ ) ;
1792+
1793+ const controller = createController ( {
1794+ initialMode : 'invalid' as ThemeMode ,
1795+ } ) ;
1796+
1797+ // Invalid initialMode should be rejected by isValidThemeMode,
1798+ // falling through to the default SYSTEM mode
1799+ expect ( controller . getCurrentMode ( ) ) . toBe ( ThemeMode . SYSTEM ) ;
1800+ } ) ;
0 commit comments