diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6337c8dc..9fd4d4a9 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index edc93661..7cbf0076 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -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. diff --git a/.github/workflows/automated-tests.yaml b/.github/workflows/automated-tests.yaml index d2b1b777..affa7c22 100644 --- a/.github/workflows/automated-tests.yaml +++ b/.github/workflows/automated-tests.yaml @@ -18,7 +18,7 @@ jobs: timeout-minutes: 30 strategy: matrix: - node-version: [16.x, 18.x, 20.x] + node-version: [18.x, 20.x] steps: - name: "Checkout code" uses: actions/checkout@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aa305fd..c4b2885e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 () +- Minimum node version is now v18. v16 reached it's end of life. ### Fixed diff --git a/js/fetch.js b/js/fetch.js index b549d9ed..cf195993 100644 --- a/js/fetch.js +++ b/js/fetch.js @@ -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); - // } 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); } diff --git a/package-lock.json b/package-lock.json index 0e02d80b..0308b752 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "suncalc": "^1.9.0" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "electron": "^26.0.0" diff --git a/package.json b/package.json index cf14b51d..998ead47 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,6 @@ "fetch": "js/fetch.js" }, "engines": { - "node": ">=16" + "node": ">=18" } } diff --git a/tests/unit/modules/default/utils_spec.js b/tests/unit/modules/default/utils_spec.js index 8ffe0876..bc0baaf0 100644 --- a/tests/unit/modules/default/utils_spec.js +++ b/tests/unit/modules/default/utils_spec.js @@ -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"; + const locationHost = "localhost:8080"; + const locationProtocol = "http"; - let fetchResponse; - let fetchMock; - let urlToCall; + let fetchResponse; + let fetchMock; + let urlToCall; - beforeEach(() => { - fetchResponse = new Response(); - global.fetch = jest.fn(() => Promise.resolve(fetchResponse)); - fetchMock = global.fetch; + beforeEach(() => { + fetchResponse = new Response(); + global.fetch = jest.fn(() => Promise.resolve(fetchResponse)); + fetchMock = global.fetch; + }); + + describe("When using cors proxy", () => { + Object.defineProperty(global, "location", { + value: { + host: locationHost, + protocol: locationProtocol + } }); - describe("When using cors proxy", () => { - Object.defineProperty(global, "location", { - value: { - host: locationHost, - protocol: locationProtocol - } - }); + test("Calls correct URL once", async () => { + urlToCall = "http://www.test.com/path?param1=value1"; - test("Calls correct URL once", async () => { - urlToCall = "http://www.test.com/path?param1=value1"; + await performWebRequest(urlToCall, "json", true); - 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"; - - const headers = [ - { name: "header1", value: "value1" }, - { name: "header2", value: "value2" } - ]; - - 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?url=${urlToCall}`); }); - describe("When not using cors proxy", () => { - test("Calls correct URL once", async () => { - urlToCall = "http://www.test.com/path?param1=value1"; + test("Sends correct headers", async () => { + urlToCall = "http://www.test.com/path?param1=value1"; - await performWebRequest(urlToCall); + const headers = [ + { name: "header1", value: "value1" }, + { name: "header2", value: "value2" } + ]; - expect(fetchMock.mock.calls.length).toBe(1); - expect(fetchMock.mock.calls[0][0]).toBe(urlToCall); - }); + await performWebRequest(urlToCall, "json", true, headers); - test("Sends correct headers", async () => { - urlToCall = "http://www.test.com/path?param1=value1"; - const headers = [ - { name: "header1", value: "value1" }, - { name: "header2", value: "value2" } - ]; + expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?sendheaders=header1:value1,header2:value2&url=${urlToCall}`); + }); + }); - await performWebRequest(urlToCall, "json", false, headers); + describe("When not using cors proxy", () => { + test("Calls correct URL once", async () => { + urlToCall = "http://www.test.com/path?param1=value1"; - const expectedHeaders = { headers: { header1: "value1", header2: "value2" } }; - expect(fetchMock.mock.calls.length).toBe(1); - expect(fetchMock.mock.calls[0][1]).toStrictEqual(expectedHeaders); - }); + await performWebRequest(urlToCall); + + expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.mock.calls[0][0]).toBe(urlToCall); }); - describe("When receiving json format", () => { - test("Returns undefined when no data is received", async () => { - urlToCall = "www.test.com"; + test("Sends correct headers", async () => { + urlToCall = "http://www.test.com/path?param1=value1"; + const headers = [ + { name: "header1", value: "value1" }, + { name: "header2", value: "value2" } + ]; - const response = await performWebRequest(urlToCall); + await performWebRequest(urlToCall, "json", false, headers); - expect(response).toBe(undefined); - }); - - test("Returns object when data is received", async () => { - urlToCall = "www.test.com"; - fetchResponse = new Response('{"body": "some content"}'); - - const response = await performWebRequest(urlToCall); - - 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" } }); - - 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"); - }); + const expectedHeaders = { headers: { header1: "value1", header2: "value2" } }; + expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.mock.calls[0][1]).toStrictEqual(expectedHeaders); }); - } else { - test("Always ok, need one test", () => {}); - } + }); + + describe("When receiving json format", () => { + test("Returns undefined when no data is received", async () => { + urlToCall = "www.test.com"; + + const response = await performWebRequest(urlToCall); + + expect(response).toBe(undefined); + }); + + test("Returns object when data is received", async () => { + urlToCall = "www.test.com"; + fetchResponse = new Response('{"body": "some content"}'); + + const response = await performWebRequest(urlToCall); + + 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" } }); + + 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"); + }); + }); }); describe("formatTime", () => {