Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ When submitting a new issue, please supply the following information:

**Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3/4, Windows, Mac, Linux, System V UNIX).

**Node Version**: Make sure it's version 16 or later (recommended is 18).
**Node Version**: Make sure it's version 18 or later (recommended is 20).

**MagicMirror² Version**: Please let us know which version of MagicMirror² you are running. It can be found in the `package.json` file.

Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ When submitting a new issue, please supply the following information:

**Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3/4, Windows, Mac, Linux, System V UNIX).

**Node Version**: Make sure it's version 16 or later (recommended is 18).
**Node Version**: Make sure it's version 18 or later (recommended is 20).

**MagicMirror² Version**: Please let us know which version of MagicMirror² you are running. It can be found in the `package.json` file.

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/automated-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
node-version: [18.x, 20.x]
Comment thread
rejas marked this conversation as resolved.
steps:
- name: "Checkout code"
uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ _This release is scheduled to be released on 2023-10-01._
- Update issue template
- Update dependencies incl. electron to v26
- Replace pretty-quick by lint-staged (<https://github.com/azz/pretty-quick/issues/164>)
- Minimum node version is now v18. v16 reached it's end of life.

### Fixed

Expand Down
11 changes: 2 additions & 9 deletions js/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,8 @@
* @class
*/
async function fetch(url, options = {}) {
// const nodeVersion = process.version.match(/^v(\d+)\.*/)[1];
// if (nodeVersion >= 18) {
// // node version >= 18
// return global.fetch(url, options);
Comment thread
KristjanESPERANTO marked this conversation as resolved.
// } else {
// // node version < 18
// const nodefetch = require("node-fetch");
// return nodefetch(url, options);
// }
// return global.fetch(url, options);

const nodefetch = require("node-fetch");
return nodefetch(url, options);
}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@
"fetch": "js/fetch.js"
},
"engines": {
"node": ">=16"
"node": ">=18"
}
}
152 changes: 73 additions & 79 deletions tests/unit/modules/default/utils_spec.js
Original file line number Diff line number Diff line change
@@ -1,113 +1,107 @@
global.moment = require("moment-timezone");
const { performWebRequest, formatTime } = require("../../../../modules/default/utils");

const nodeVersion = process.version.match(/^v(\d+)\.*/)[1];

describe("Default modules utils tests", () => {
describe("performWebRequest", () => {
if (nodeVersion > 18) {
const locationHost = "localhost:8080";
const locationProtocol = "http";

let fetchResponse;
let fetchMock;
let urlToCall;

beforeEach(() => {
fetchResponse = new Response();
global.fetch = jest.fn(() => Promise.resolve(fetchResponse));
fetchMock = global.fetch;
});
const locationHost = "localhost:8080";
const locationProtocol = "http";

describe("When using cors proxy", () => {
Object.defineProperty(global, "location", {
value: {
host: locationHost,
protocol: locationProtocol
}
});
let fetchResponse;
let fetchMock;
let urlToCall;

test("Calls correct URL once", async () => {
urlToCall = "http://www.test.com/path?param1=value1";
beforeEach(() => {
fetchResponse = new Response();
global.fetch = jest.fn(() => Promise.resolve(fetchResponse));
fetchMock = global.fetch;
});

await performWebRequest(urlToCall, "json", true);
describe("When using cors proxy", () => {
Object.defineProperty(global, "location", {
value: {
host: locationHost,
protocol: locationProtocol
}
});

expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?url=${urlToCall}`);
});
test("Calls correct URL once", async () => {
urlToCall = "http://www.test.com/path?param1=value1";

await performWebRequest(urlToCall, "json", true);

expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?url=${urlToCall}`);
});

test("Sends correct headers", async () => {
urlToCall = "http://www.test.com/path?param1=value1";
test("Sends correct headers", async () => {
urlToCall = "http://www.test.com/path?param1=value1";

const headers = [
{ name: "header1", value: "value1" },
{ name: "header2", value: "value2" }
];
const headers = [
{ name: "header1", value: "value1" },
{ name: "header2", value: "value2" }
];

await performWebRequest(urlToCall, "json", true, headers);
await performWebRequest(urlToCall, "json", true, headers);

expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?sendheaders=header1:value1,header2:value2&url=${urlToCall}`);
});
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?sendheaders=header1:value1,header2:value2&url=${urlToCall}`);
});
});

describe("When not using cors proxy", () => {
test("Calls correct URL once", async () => {
urlToCall = "http://www.test.com/path?param1=value1";
describe("When not using cors proxy", () => {
test("Calls correct URL once", async () => {
urlToCall = "http://www.test.com/path?param1=value1";

await performWebRequest(urlToCall);
await performWebRequest(urlToCall);

expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(urlToCall);
});
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(urlToCall);
});

test("Sends correct headers", async () => {
urlToCall = "http://www.test.com/path?param1=value1";
const headers = [
{ name: "header1", value: "value1" },
{ name: "header2", value: "value2" }
];
test("Sends correct headers", async () => {
urlToCall = "http://www.test.com/path?param1=value1";
const headers = [
{ name: "header1", value: "value1" },
{ name: "header2", value: "value2" }
];

await performWebRequest(urlToCall, "json", false, headers);
await performWebRequest(urlToCall, "json", false, headers);

const expectedHeaders = { headers: { header1: "value1", header2: "value2" } };
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][1]).toStrictEqual(expectedHeaders);
});
const expectedHeaders = { headers: { header1: "value1", header2: "value2" } };
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][1]).toStrictEqual(expectedHeaders);
});
});

describe("When receiving json format", () => {
test("Returns undefined when no data is received", async () => {
urlToCall = "www.test.com";
describe("When receiving json format", () => {
test("Returns undefined when no data is received", async () => {
urlToCall = "www.test.com";

const response = await performWebRequest(urlToCall);
const response = await performWebRequest(urlToCall);

expect(response).toBe(undefined);
});
expect(response).toBe(undefined);
});

test("Returns object when data is received", async () => {
urlToCall = "www.test.com";
fetchResponse = new Response('{"body": "some content"}');
test("Returns object when data is received", async () => {
urlToCall = "www.test.com";
fetchResponse = new Response('{"body": "some content"}');

const response = await performWebRequest(urlToCall);
const response = await performWebRequest(urlToCall);

expect(response.body).toBe("some content");
});
expect(response.body).toBe("some content");
});

test("Returns expected headers when data is received", async () => {
urlToCall = "www.test.com";
fetchResponse = new Response('{"body": "some content"}', { headers: { header1: "value1", header2: "value2" } });
test("Returns expected headers when data is received", async () => {
urlToCall = "www.test.com";
fetchResponse = new Response('{"body": "some content"}', { headers: { header1: "value1", header2: "value2" } });

const response = await performWebRequest(urlToCall, "json", false, undefined, ["header1"]);
const response = await performWebRequest(urlToCall, "json", false, undefined, ["header1"]);

expect(response.headers.length).toBe(1);
expect(response.headers[0].name).toBe("header1");
expect(response.headers[0].value).toBe("value1");
});
expect(response.headers.length).toBe(1);
expect(response.headers[0].name).toBe("header1");
expect(response.headers[0].value).toBe("value1");
});
} else {
test("Always ok, need one test", () => {});
}
});
});

describe("formatTime", () => {
Expand Down