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
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
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");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user