mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
fix(admin): the phone addon list wordmark follows an OS theme switch under auto
With the appearance set to auto, switching the OS between light and dark left the TREK wordmark in the phone admin addon header in the old colour (dark text on a dark page or the reverse) until something else made the screen render again. The desktop header switches right away. Cause: the phone worked the flag out from the dark_mode setting and window.matchMedia during render, and nothing re-renders the screen when the media query flips. The desktop uses useIsDark, which watches the .dark class that applyAppearance() writes. Fix: MAdminAddonManager uses useIsDark like AddonManager. Red test: FE-MOB-AADD-037 (new, MAdminAddonManager.test.tsx) failed with "Expected the element to have attribute: src="/text-light.svg"" after the .dark class was added under auto. Changed assertions in tests/unit/mobile/admin/MAdminAddonManager.test.tsx: - FE-MOB-AADD-003 (renamed from "dark mode and auto+prefers-dark swap the wordmark" to "the dark palette swaps the wordmark"): it expected window.matchMedia to be called with "(prefers-color-scheme: dark)"; that expectation is gone, since the screen now reads the .dark class. The test now sets that class instead of the dark_mode setting and a matchMedia stub, and still expects src "/text-light.svg". afterEach removes the class again.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { type ComponentType } from 'react'
|
||||
import { useTranslation } from '../../../i18n'
|
||||
import { useSettingsStore } from '../../../store/settingsStore'
|
||||
import { useIsDark } from '../../../hooks/useIsDark'
|
||||
import {
|
||||
Puzzle, ListChecks, Wallet, FileText, CalendarDays, Globe, Briefcase, Image, Terminal, Link2, Compass, BookOpen,
|
||||
Sparkles, Luggage, Plane, Server, Cloud, Bookmark, Users, Check, Loader2,
|
||||
@@ -56,8 +56,7 @@ function AddonIcon({ name, size = 18, enabled = true }: AddonIconProps) {
|
||||
|
||||
export default function MAdminAddonManager({ bagTrackingEnabled, onToggleBagTracking, collabFeatures, onToggleCollabFeature }: { bagTrackingEnabled?: boolean; onToggleBagTracking?: () => void; collabFeatures?: CollabFeatures; onToggleCollabFeature?: (key: string) => void }) {
|
||||
const { t } = useTranslation()
|
||||
const dm = useSettingsStore(s => s.settings.dark_mode)
|
||||
const dark = dm === true || dm === 'dark' || (dm === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
const dark = useIsDark()
|
||||
const {
|
||||
addons, loading, handleToggle, tripAddons, globalAddons, integrationAddons, providerOptions, documentProviderOptions,
|
||||
} = useAddonManager()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// FE-MOB-AADD-001 to FE-MOB-AADD-036
|
||||
// FE-MOB-AADD-001 to FE-MOB-AADD-037
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { delay, http, HttpResponse } from 'msw';
|
||||
import { render, screen, waitFor, within } from '../../../helpers/render';
|
||||
import { act, render, screen, waitFor, within } from '../../../helpers/render';
|
||||
import { server } from '../../../helpers/msw/server';
|
||||
import { resetAllStores, seedStore } from '../../../helpers/store';
|
||||
import { buildSettings } from '../../../helpers/factories';
|
||||
@@ -67,6 +67,7 @@ beforeEach(() => {
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
document.documentElement.classList.remove('dark');
|
||||
});
|
||||
|
||||
describe('MAdminAddonManager', () => {
|
||||
@@ -92,21 +93,13 @@ describe('MAdminAddonManager', () => {
|
||||
expect(screen.getByAltText('TREK')).toHaveAttribute('src', '/text-dark.svg');
|
||||
});
|
||||
|
||||
it('FE-MOB-AADD-003: dark mode and auto+prefers-dark swap the wordmark', async () => {
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'dark' }) });
|
||||
const { unmount } = render(<MAdminAddonManager />);
|
||||
await screen.findByText('No addons available');
|
||||
expect(screen.getByAltText('TREK')).toHaveAttribute('src', '/text-light.svg');
|
||||
unmount();
|
||||
|
||||
const matchMedia = vi.fn().mockReturnValue({ matches: true, addEventListener: vi.fn(), removeEventListener: vi.fn() });
|
||||
vi.stubGlobal('matchMedia', matchMedia);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'auto' }) });
|
||||
it('FE-MOB-AADD-003: the dark palette swaps the wordmark', async () => {
|
||||
// The wordmark reads the .dark class, the same source applyAppearance() writes
|
||||
// for dark and for auto under a dark OS theme.
|
||||
document.documentElement.classList.add('dark');
|
||||
render(<MAdminAddonManager />);
|
||||
await screen.findByText('No addons available');
|
||||
expect(screen.getByAltText('TREK')).toHaveAttribute('src', '/text-light.svg');
|
||||
expect(matchMedia).toHaveBeenCalledWith('(prefers-color-scheme: dark)');
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it('FE-MOB-AADD-004: a failing load toasts the addon error', async () => {
|
||||
@@ -757,4 +750,15 @@ describe('MAdminAddonManager', () => {
|
||||
expect(document.querySelector('svg.lucide-sparkles')).toBeInTheDocument();
|
||||
expect(document.querySelector('svg.lucide-puzzle')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-MOB-AADD-037: under auto the wordmark follows an OS theme switch without a re-render', async () => {
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'auto' }) });
|
||||
render(<MAdminAddonManager />);
|
||||
await screen.findByText('No addons available');
|
||||
expect(screen.getByAltText('TREK')).toHaveAttribute('src', '/text-dark.svg');
|
||||
|
||||
// applyAppearance() flips the .dark class when the OS theme changes under auto.
|
||||
act(() => document.documentElement.classList.add('dark'));
|
||||
await waitFor(() => expect(screen.getByAltText('TREK')).toHaveAttribute('src', '/text-light.svg'));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user