Some checks failed
CI / lint-and-test (push) Failing after 45s
- Added Node.js setup and webapp testing steps to the CI workflow for improved integration. - Updated HTML to link multiple CSS files for better modularity and organization of styles. - Removed deprecated `style.css` and introduced new CSS files for base styles, calendar, day detail, hints, markers, states, and duty list to enhance maintainability and readability. - Implemented new styles for improved presentation of duty information and user interactions. - Added unit tests for new API functions and contact link rendering to ensure functionality and reliability.
153 lines
5.4 KiB
JavaScript
153 lines
5.4 KiB
JavaScript
/**
|
|
* Unit tests for theme: getTheme, applyThemeParamsToCss, applyTheme, initTheme.
|
|
*/
|
|
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
|
|
|
|
describe("theme", () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe("getTheme", () => {
|
|
it("returns Telegram.WebApp.colorScheme when set", async () => {
|
|
globalThis.window.Telegram = { WebApp: { colorScheme: "light" } };
|
|
vi.spyOn(document.documentElement.style, "getPropertyValue").mockReturnValue("");
|
|
const { getTheme } = await import("./theme.js");
|
|
expect(getTheme()).toBe("light");
|
|
});
|
|
|
|
it("falls back to --tg-color-scheme CSS when TWA has no colorScheme", async () => {
|
|
globalThis.window.Telegram = { WebApp: {} };
|
|
vi.spyOn(globalThis, "getComputedStyle").mockReturnValue({
|
|
getPropertyValue: vi.fn().mockReturnValue("dark"),
|
|
});
|
|
const { getTheme } = await import("./theme.js");
|
|
expect(getTheme()).toBe("dark");
|
|
});
|
|
|
|
it("falls back to matchMedia prefers-color-scheme dark", async () => {
|
|
globalThis.window.Telegram = { WebApp: {} };
|
|
vi.spyOn(globalThis, "getComputedStyle").mockReturnValue({
|
|
getPropertyValue: vi.fn().mockReturnValue(""),
|
|
});
|
|
vi.spyOn(globalThis, "matchMedia").mockReturnValue({
|
|
matches: true,
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
});
|
|
const { getTheme } = await import("./theme.js");
|
|
expect(getTheme()).toBe("dark");
|
|
});
|
|
|
|
it("returns light when matchMedia prefers light", async () => {
|
|
globalThis.window.Telegram = { WebApp: {} };
|
|
vi.spyOn(globalThis, "getComputedStyle").mockReturnValue({
|
|
getPropertyValue: vi.fn().mockReturnValue(""),
|
|
});
|
|
vi.spyOn(globalThis, "matchMedia").mockReturnValue({
|
|
matches: false,
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
});
|
|
const { getTheme } = await import("./theme.js");
|
|
expect(getTheme()).toBe("light");
|
|
});
|
|
|
|
it("falls back to matchMedia when getComputedStyle throws", async () => {
|
|
globalThis.window.Telegram = { WebApp: {} };
|
|
vi.spyOn(globalThis, "getComputedStyle").mockImplementation(() => {
|
|
throw new Error("getComputedStyle not available");
|
|
});
|
|
vi.spyOn(globalThis, "matchMedia").mockReturnValue({
|
|
matches: true,
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
});
|
|
const { getTheme } = await import("./theme.js");
|
|
expect(getTheme()).toBe("dark");
|
|
});
|
|
});
|
|
|
|
describe("applyThemeParamsToCss", () => {
|
|
it("does nothing when Telegram.WebApp or themeParams missing", async () => {
|
|
globalThis.window.Telegram = undefined;
|
|
const setProperty = vi.fn();
|
|
document.documentElement.style.setProperty = setProperty;
|
|
const { applyThemeParamsToCss } = await import("./theme.js");
|
|
applyThemeParamsToCss();
|
|
expect(setProperty).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("sets --tg-theme-* CSS variables from themeParams", async () => {
|
|
globalThis.window.Telegram = {
|
|
WebApp: {
|
|
themeParams: {
|
|
bg_color: "#ffffff",
|
|
text_color: "#000000",
|
|
hint_color: "#888888",
|
|
},
|
|
},
|
|
};
|
|
const setProperty = vi.fn();
|
|
document.documentElement.style.setProperty = setProperty;
|
|
const { applyThemeParamsToCss } = await import("./theme.js");
|
|
applyThemeParamsToCss();
|
|
expect(setProperty).toHaveBeenCalledWith("--tg-theme-bg-color", "#ffffff");
|
|
expect(setProperty).toHaveBeenCalledWith("--tg-theme-text-color", "#000000");
|
|
expect(setProperty).toHaveBeenCalledWith("--tg-theme-hint-color", "#888888");
|
|
});
|
|
});
|
|
|
|
describe("applyTheme", () => {
|
|
beforeEach(() => {
|
|
document.documentElement.dataset.theme = "";
|
|
});
|
|
|
|
it("sets data-theme on documentElement from getTheme", async () => {
|
|
const theme = await import("./theme.js");
|
|
vi.spyOn(theme, "getTheme").mockReturnValue("light");
|
|
theme.applyTheme();
|
|
expect(document.documentElement.dataset.theme).toBe("light");
|
|
});
|
|
|
|
it("calls setBackgroundColor and setHeaderColor when TWA present", async () => {
|
|
const setBackgroundColor = vi.fn();
|
|
const setHeaderColor = vi.fn();
|
|
globalThis.window.Telegram = {
|
|
WebApp: {
|
|
setBackgroundColor: setBackgroundColor,
|
|
setHeaderColor: setHeaderColor,
|
|
themeParams: null,
|
|
},
|
|
};
|
|
const { applyTheme } = await import("./theme.js");
|
|
applyTheme();
|
|
expect(setBackgroundColor).toHaveBeenCalledWith("bg_color");
|
|
expect(setHeaderColor).toHaveBeenCalledWith("bg_color");
|
|
});
|
|
});
|
|
|
|
describe("initTheme", () => {
|
|
it("runs without throwing when TWA present", async () => {
|
|
globalThis.window.Telegram = { WebApp: {} };
|
|
const { initTheme } = await import("./theme.js");
|
|
expect(() => initTheme()).not.toThrow();
|
|
});
|
|
|
|
it("adds matchMedia change listener when no TWA", async () => {
|
|
globalThis.window.Telegram = undefined;
|
|
const addEventListener = vi.fn();
|
|
vi.spyOn(globalThis, "matchMedia").mockReturnValue({
|
|
matches: false,
|
|
addEventListener,
|
|
removeEventListener: vi.fn(),
|
|
});
|
|
const { initTheme } = await import("./theme.js");
|
|
initTheme();
|
|
expect(addEventListener).toHaveBeenCalledWith("change", expect.any(Function));
|
|
});
|
|
});
|
|
});
|