mirror of
https://github.com/MichMich/MagicMirror.git
synced 2026-04-24 06:47:07 +00:00
Since the project's inception, I've missed a clear separation between default and third-party modules. This increases complexity within the project (exclude `modules`, but not `modules/default`), but the mixed use is particularly problematic in Docker setups. Therefore, with this pull request, I'm moving the default modules to a different directory. ~~I've chosen `default/modules`, but I'm not bothered about it; `defaultmodules` or something similar would work just as well.~~ Changed to `defaultmodules`. Let me know if there's a majority in favor of this change.
154 lines
4.6 KiB
JavaScript
154 lines
4.6 KiB
JavaScript
describe("Compliments module", () => {
|
|
let complimentsModule;
|
|
|
|
beforeEach(() => {
|
|
// Mock global dependencies
|
|
global.Module = {
|
|
register: vi.fn((name, moduleDefinition) => {
|
|
complimentsModule = moduleDefinition;
|
|
})
|
|
};
|
|
global.Log = {
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn()
|
|
};
|
|
global.Cron = vi.fn();
|
|
|
|
// Load the module
|
|
const defaults = require("../../../../../js/defaults");
|
|
require(`../../../../../${defaults.defaultModulesDir}/compliments/compliments`);
|
|
|
|
// Setup module instance
|
|
complimentsModule.config = { ...complimentsModule.defaults };
|
|
complimentsModule.name = "compliments";
|
|
complimentsModule.file = vi.fn((path) => `http://localhost:8080/${defaults.defaultModulesDir}/compliments/${path}`);
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe("loadComplimentFile", () => {
|
|
describe("HTTP error handling", () => {
|
|
it("should return null and log error on HTTP 404", async () => {
|
|
complimentsModule.config.remoteFile = "http://example.com/missing.json";
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: false,
|
|
status: 404,
|
|
statusText: "Not Found"
|
|
}));
|
|
|
|
const result = await complimentsModule.loadComplimentFile();
|
|
|
|
expect(result).toBeNull();
|
|
expect(Log.error).toHaveBeenCalledWith("[compliments] HTTP error: 404 Not Found");
|
|
});
|
|
|
|
it("should return null and log error on HTTP 500", async () => {
|
|
complimentsModule.config.remoteFile = "http://example.com/error.json";
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: false,
|
|
status: 500,
|
|
statusText: "Internal Server Error"
|
|
}));
|
|
|
|
const result = await complimentsModule.loadComplimentFile();
|
|
|
|
expect(result).toBeNull();
|
|
expect(Log.error).toHaveBeenCalledWith("[compliments] HTTP error: 500 Internal Server Error");
|
|
});
|
|
|
|
it("should return content on successful HTTP 200", async () => {
|
|
complimentsModule.config.remoteFile = "http://example.com/compliments.json";
|
|
const expectedContent = "{\"anytime\":[\"Test compliment\"]}";
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: true,
|
|
status: 200,
|
|
text: () => Promise.resolve(expectedContent)
|
|
}));
|
|
|
|
const result = await complimentsModule.loadComplimentFile();
|
|
|
|
expect(result).toBe(expectedContent);
|
|
expect(Log.error).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("Cache-busting with query parameters", () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date("2025-01-01T12:00:00.000Z"));
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it("should add cache-busting parameter to URL without query params", async () => {
|
|
complimentsModule.config.remoteFile = "http://example.com/compliments.json";
|
|
complimentsModule.config.remoteFileRefreshInterval = 60000;
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: true,
|
|
text: () => Promise.resolve("{}")
|
|
}));
|
|
|
|
await complimentsModule.loadComplimentFile();
|
|
|
|
expect(fetch).toHaveBeenCalledWith(expect.stringContaining("?dummy=1735732800000"));
|
|
});
|
|
|
|
it("should add cache-busting parameter to URL with existing query params", async () => {
|
|
complimentsModule.config.remoteFile = "http://example.com/compliments.json?lang=en";
|
|
complimentsModule.config.remoteFileRefreshInterval = 60000;
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: true,
|
|
text: () => Promise.resolve("{}")
|
|
}));
|
|
|
|
await complimentsModule.loadComplimentFile();
|
|
|
|
const calledUrl = fetch.mock.calls[0][0];
|
|
expect(calledUrl).toContain("lang=en");
|
|
expect(calledUrl).toContain("&dummy=1735732800000");
|
|
expect(calledUrl).not.toContain("?dummy=");
|
|
});
|
|
|
|
it("should not add cache-busting parameter when remoteFileRefreshInterval is 0", async () => {
|
|
complimentsModule.config.remoteFile = "http://example.com/compliments.json";
|
|
complimentsModule.config.remoteFileRefreshInterval = 0;
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: true,
|
|
text: () => Promise.resolve("{}")
|
|
}));
|
|
|
|
await complimentsModule.loadComplimentFile();
|
|
|
|
expect(fetch).toHaveBeenCalledWith("http://example.com/compliments.json");
|
|
});
|
|
|
|
it("should not add cache-busting parameter to local files", async () => {
|
|
complimentsModule.config.remoteFile = "compliments.json";
|
|
complimentsModule.config.remoteFileRefreshInterval = 60000;
|
|
|
|
global.fetch = vi.fn(() => Promise.resolve({
|
|
ok: true,
|
|
text: () => Promise.resolve("{}")
|
|
}));
|
|
|
|
await complimentsModule.loadComplimentFile();
|
|
|
|
const calledUrl = fetch.mock.calls[0][0];
|
|
expect(calledUrl).toBe("http://localhost:8080/defaultmodules/compliments/compliments.json");
|
|
expect(calledUrl).not.toContain("dummy=");
|
|
});
|
|
});
|
|
});
|
|
});
|