fix: Broken header in public Help Center portal (#11704)
Fixes https://linear.app/chatwoot/issue/CW-4473/broken-header-in-help-center-portal
This commit is contained in:
@@ -29,22 +29,21 @@ describe('InitializationHelpers.navigateToLocalePage', () => {
|
||||
delete global.window;
|
||||
});
|
||||
|
||||
it('should return false if .locale-switcher is not found', () => {
|
||||
it('sets up document event listener regardless of locale-switcher existence', () => {
|
||||
document.querySelector('.locale-switcher').remove();
|
||||
const result = InitializationHelpers.navigateToLocalePage();
|
||||
expect(result).toBe(false);
|
||||
const documentSpy = vi.spyOn(document, 'addEventListener');
|
||||
InitializationHelpers.navigateToLocalePage();
|
||||
expect(documentSpy).toHaveBeenCalledWith('change', expect.any(Function));
|
||||
documentSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should add change event listener to .locale-switcher', () => {
|
||||
const localeSwitcher = document.querySelector('.locale-switcher');
|
||||
const addEventListenerSpy = vi.spyOn(localeSwitcher, 'addEventListener');
|
||||
it('adds document-level event listener to handle locale switching', () => {
|
||||
const documentSpy = vi.spyOn(document, 'addEventListener');
|
||||
|
||||
InitializationHelpers.navigateToLocalePage();
|
||||
|
||||
expect(addEventListenerSpy).toHaveBeenCalledWith(
|
||||
'change',
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(documentSpy).toHaveBeenCalledWith('change', expect.any(Function));
|
||||
documentSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ import {
|
||||
removeQueryParamsFromUrl,
|
||||
updateThemeInHeader,
|
||||
switchTheme,
|
||||
initializeThemeSwitchButtons,
|
||||
initializeToggleButton,
|
||||
initializeThemeHandlers,
|
||||
initializeMediaQueryListener,
|
||||
initializeTheme,
|
||||
} from '../portalThemeHelper.js';
|
||||
@@ -21,6 +20,7 @@ describe('portalThemeHelper', () => {
|
||||
|
||||
appearanceDropdown = document.createElement('div');
|
||||
appearanceDropdown.id = 'appearance-dropdown';
|
||||
appearanceDropdown.classList.add('appearance-menu');
|
||||
document.body.appendChild(appearanceDropdown);
|
||||
|
||||
window.matchMedia = vi.fn().mockImplementation(query => ({
|
||||
@@ -142,7 +142,7 @@ describe('portalThemeHelper', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#initializeThemeSwitchButtons', () => {
|
||||
describe('#initializeThemeHandlers', () => {
|
||||
beforeEach(() => {
|
||||
appearanceDropdown.innerHTML = `
|
||||
<button data-theme="light"><span class="check-mark-icon light-theme"></span></button>
|
||||
@@ -153,43 +153,58 @@ describe('portalThemeHelper', () => {
|
||||
|
||||
it('does nothing if the appearance dropdown is not found', () => {
|
||||
appearanceDropdown.remove();
|
||||
expect(appearanceDropdown.dataset.currentTheme).toBeUndefined();
|
||||
});
|
||||
it('should set current theme to system if no theme in localStorage', () => {
|
||||
localStorage.removeItem('theme');
|
||||
initializeThemeSwitchButtons();
|
||||
expect(appearanceDropdown.dataset.currentTheme).toBe('system');
|
||||
expect(() => initializeThemeHandlers()).not.toThrow();
|
||||
});
|
||||
|
||||
it('sets the current theme to the light theme', () => {
|
||||
localStorage.theme = 'light';
|
||||
appearanceDropdown.dataset.currentTheme = 'light';
|
||||
initializeThemeSwitchButtons();
|
||||
it('should handle theme button clicks', () => {
|
||||
initializeThemeHandlers();
|
||||
|
||||
// Simulate clicking a theme button
|
||||
const lightButton = appearanceDropdown.querySelector(
|
||||
'button[data-theme="light"]'
|
||||
);
|
||||
const clickEvent = new Event('click', { bubbles: true });
|
||||
Object.defineProperty(clickEvent, 'target', {
|
||||
value: lightButton,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
document.dispatchEvent(clickEvent);
|
||||
|
||||
expect(localStorage.theme).toBe('light');
|
||||
expect(appearanceDropdown.dataset.currentTheme).toBe('light');
|
||||
});
|
||||
|
||||
it('sets the current theme to the dark theme', () => {
|
||||
localStorage.theme = 'dark';
|
||||
appearanceDropdown.dataset.currentTheme = 'dark';
|
||||
initializeThemeSwitchButtons();
|
||||
expect(appearanceDropdown.dataset.currentTheme).toBe('dark');
|
||||
});
|
||||
});
|
||||
it('should toggle dropdown visibility on toggle button click', () => {
|
||||
initializeThemeHandlers();
|
||||
|
||||
describe('#initializeToggleButton', () => {
|
||||
it('does nothing if the theme toggle button is not found', () => {
|
||||
themeToggleButton.remove();
|
||||
initializeToggleButton();
|
||||
expect(appearanceDropdown.style.display).toBe('');
|
||||
// Initially closed
|
||||
expect(appearanceDropdown.dataset.dropdownOpen).toBeUndefined();
|
||||
|
||||
// Click to open
|
||||
themeToggleButton.click();
|
||||
expect(appearanceDropdown.dataset.dropdownOpen).toBe('true');
|
||||
|
||||
// Click to close
|
||||
themeToggleButton.click();
|
||||
expect(appearanceDropdown.dataset.dropdownOpen).toBe('false');
|
||||
});
|
||||
|
||||
it('toggles the appearance dropdown show/hide', () => {
|
||||
themeToggleButton.click();
|
||||
appearanceDropdown.style.display = 'flex';
|
||||
expect(appearanceDropdown.style.display).toBe('flex');
|
||||
themeToggleButton.click();
|
||||
appearanceDropdown.style.display = 'none';
|
||||
expect(appearanceDropdown.style.display).toBe('none');
|
||||
it('should close dropdown when clicking outside', () => {
|
||||
initializeThemeHandlers();
|
||||
|
||||
// Open dropdown
|
||||
appearanceDropdown.dataset.dropdownOpen = 'true';
|
||||
|
||||
// Click outside
|
||||
const outsideClick = new Event('click', { bubbles: true });
|
||||
Object.defineProperty(outsideClick, 'target', {
|
||||
value: document.body,
|
||||
enumerable: true,
|
||||
});
|
||||
document.dispatchEvent(outsideClick);
|
||||
|
||||
expect(appearanceDropdown.dataset.dropdownOpen).toBe('false');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user