Files
R3ap3r 3178b8f4f7 Aurora SpotiRip desktop and web app
- Spotify playlist, library, album and artist browsing with in-app playback
- Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks
- Electron desktop app (castLabs Widevine) with a permanent sidebar layout
- Linux and Windows packaging scripts
2026-09-25 23:20:57 -05:00

118 lines
3.9 KiB
TypeScript

import { switchToDarkMode, switchToLightMode, switchToAutoMode, getCurrentThemeMode } from "./themeMode";
function createMediaQueryList(initialMatches: boolean, query = "(prefers-color-scheme: dark)") {
let currentMatches = initialMatches;
const mql: Partial<MediaQueryList> = {
get matches() {
return currentMatches;
},
media: query,
onchange: null,
addListener: () => {},
removeListener: () => {},
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => false,
};
return Object.assign(mql, {
setMatches(newMatches: boolean) {
currentMatches = newMatches;
},
}) as MediaQueryList & { setMatches: (matches: boolean) => void };
}
describe("themeMode helper", () => {
let originalMatchMedia: typeof window.matchMedia;
beforeAll(() => {
originalMatchMedia = window.matchMedia;
});
afterAll(() => {
window.matchMedia = originalMatchMedia;
});
beforeEach(() => {
document.body.className = "";
});
it("should add the 'dark' class when switching to dark mode", () => {
switchToDarkMode();
expect(document.body.classList.contains("dark")).toBeTrue();
});
it("should remove the 'dark' class when switching to light mode", () => {
document.body.classList.add("dark");
switchToLightMode();
expect(document.body.classList.contains("dark")).toBeFalse();
});
it("should apply dark mode automatically when user prefers dark", () => {
window.matchMedia = (query: string): MediaQueryList =>
createMediaQueryList(true, query);
switchToAutoMode();
expect(document.body.classList.contains("dark")).toBeTrue();
});
it("should apply light mode automatically when user does not prefer dark", () => {
document.body.classList.add("dark");
window.matchMedia = (query: string): MediaQueryList =>
createMediaQueryList(false, query);
switchToAutoMode();
expect(document.body.classList.contains("dark")).toBeFalse();
});
it("should update theme when system preference changes in auto mode upon re-calling switchToAutoMode", () => {
window.matchMedia = (query: string): MediaQueryList =>
createMediaQueryList(false, query);
switchToAutoMode();
expect(document.body.classList.contains("dark")).toBeFalse();
window.matchMedia = (query: string): MediaQueryList =>
createMediaQueryList(true, query);
switchToAutoMode();
expect(document.body.classList.contains("dark")).toBeTrue();
window.matchMedia = (query: string): MediaQueryList =>
createMediaQueryList(false, query);
switchToAutoMode();
expect(document.body.classList.contains("dark")).toBeFalse();
});
it("should update theme when media query change event is triggered", () => {
const dummyMediaQuery = createMediaQueryList(false);
window.matchMedia = (query: string): MediaQueryList => dummyMediaQuery;
switchToAutoMode();
expect(document.body.classList.contains("dark")).toBeFalse();
dummyMediaQuery.setMatches(true);
if (dummyMediaQuery.onchange) {
dummyMediaQuery.onchange({ matches: true } as MediaQueryListEvent);
}
expect(document.body.classList.contains("dark")).toBeTrue();
dummyMediaQuery.setMatches(false);
if (dummyMediaQuery.onchange) {
dummyMediaQuery.onchange({ matches: false } as MediaQueryListEvent);
}
expect(document.body.classList.contains("dark")).toBeFalse();
});
it("getCurrentThemeMode should return 'dark' when dark mode is set manually", () => {
switchToDarkMode();
expect(getCurrentThemeMode()).toBe("dark");
});
it("getCurrentThemeMode should return 'light' when light mode is set manually", () => {
switchToLightMode();
expect(getCurrentThemeMode()).toBe("light");
});
it("getCurrentThemeMode should return 'auto' when auto mode is enabled", () => {
window.matchMedia = (query: string): MediaQueryList =>
createMediaQueryList(true, query);
switchToAutoMode();
expect(getCurrentThemeMode()).toBe("auto");
});
});