From 79c7906fbaf8dc729b9b5ed7ebbc7a97d2fd45e6 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Sat, 9 Nov 2024 16:03:26 -0600 Subject: [PATCH 01/10] add support for compliments file refresh and testcases --- CHANGELOG.md | 1 + modules/default/compliments/compliments.js | 45 ++++++++++++++++++- .../modules/compliments/compliments_file.js | 17 +++++++ .../compliments/compliments_file_change.js | 19 ++++++++ tests/electron/modules/compliments_spec.js | 16 +++++++ tests/mocks/compliments_file.json | 5 +++ 6 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 tests/configs/modules/compliments/compliments_file.js create mode 100644 tests/configs/modules/compliments/compliments_file_change.js create mode 100644 tests/mocks/compliments_file.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 579eff945d..7ae9045545 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ _This release is scheduled to be released on 2025-01-01._ - [linter] re-added `eslint-plugin-import`now that it supports ESLint v9 (#3586) - [docs] Added step for npm publishing in release process (#3595) - [core] Add GitHub workflow to run spellcheck a few days before each release. +- [compliments] add support for refreshing remote compliments file, and testcases ### Removed diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 4c4bef471f..ea99eaca43 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -1,4 +1,8 @@ /* global Cron */ +/* global global */ + +console.log("window name='"+window.name+"'") +const compliments_test_mode=(window.name=='jsdom')?true:false Module.register("compliments", { // Module config defaults. @@ -12,14 +16,17 @@ Module.register("compliments", { }, updateInterval: 30000, remoteFile: null, + remoteFileRefreshInterval: null, fadeSpeed: 4000, morningStartTime: 3, morningEndTime: 12, afternoonStartTime: 12, afternoonEndTime: 17, random: true, - specialDayUnique: false + specialDayUnique: false, }, + urlSuffix:"", + compliments_new:null, lastIndexUsed: -1, // Set currentweather from module currentWeatherType: "", @@ -41,6 +48,14 @@ Module.register("compliments", { const response = await this.loadComplimentFile(); this.config.compliments = JSON.parse(response); this.updateDom(); + if (this.config.remoteFileRefreshInterval !== null) { + this.remoteFileRefreshFunc = setInterval(async () => { + const response = await this.loadComplimentFile(); + this.compliments_new = JSON.parse(response); + }, + this.config.remoteFileRefreshInterval + ) + } } let minute_sync_delay = 1; // loop thru all the configured when events @@ -185,7 +200,14 @@ Module.register("compliments", { async loadComplimentFile () { const isRemote = this.config.remoteFile.indexOf("http://") === 0 || this.config.remoteFile.indexOf("https://") === 0, url = isRemote ? this.config.remoteFile : this.file(this.config.remoteFile); - const response = await fetch(url); + // because we may be fetching the same url, + // we need to force the server to not give us the cached result + // create an extra property (ignored by the server handler) just so the url string is different + // that will never be the same, using the ms value of date + if(this.config.remoteFileRefreshInterval!=null) + this.urlSuffix= "?dummy="+Date.now() + // + const response = await fetch(url+this.urlSuffix); return await response.text(); }, @@ -236,6 +258,25 @@ Module.register("compliments", { compliment.lastElementChild.remove(); wrapper.appendChild(compliment); } + // if a new set of compliments was loaded from the refresh task + // we do this here to make sure no other function is using the compliments list + if(this.compliments_new){ + // use them + if(JSON.stringify(this.config.compliments)!== JSON.stringify(this.compliments_new)){ + // only reset if the contents changes + this.config.compliments = this.compliments_new + // reset the index + this.lastIndexUsed = -1; + } + } + // in test mode only + //if (compliments_test_mode) { + // check for (undocumented) remote file2 to change test new load + if(this.config.remoteFile2!== null && this.config.remoteFileRefreshInterval!==null){ + console.log("running in test"); + this.config.remoteFile=this.config.remoteFile2 + } + //} return wrapper; }, diff --git a/tests/configs/modules/compliments/compliments_file.js b/tests/configs/modules/compliments/compliments_file.js new file mode 100644 index 0000000000..d73e1b5c10 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_file.js @@ -0,0 +1,17 @@ +let config = { + address: "0.0.0.0", + ipWhitelist: [], + modules: [ + { + module: "compliments", + position: "bottom_bar", + config: { + updateInterval: 3000, + remoteFile: "http://localhost:8080/tests/mocks/compliments_test.json" + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/tests/configs/modules/compliments/compliments_file_change.js b/tests/configs/modules/compliments/compliments_file_change.js new file mode 100644 index 0000000000..51fd4f6408 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_file_change.js @@ -0,0 +1,19 @@ +let config = { + address: "0.0.0.0", + ipWhitelist: [], + modules: [ + { + module: "compliments", + position: "bottom_bar", + config: { + updateInterval: 3000, + remoteFileRefreshInterval: 1500, + remoteFile: "http://localhost:8080/tests/mocks/compliments_test.json", + remoteFile2: "http://localhost:8080/tests/mocks/compliments_file.json" + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/tests/electron/modules/compliments_spec.js b/tests/electron/modules/compliments_spec.js index 15c3c37c08..8626b503c8 100644 --- a/tests/electron/modules/compliments_spec.js +++ b/tests/electron/modules/compliments_spec.js @@ -78,6 +78,22 @@ describe("Compliments module", () => { await expect(doTest(["just a test"])).resolves.toBe(true); }); }); + }); + describe("Feature remote compliments file", () => { + describe("get list from remote file", () => { + it("shows 'Remote compliment file works!' as only anytime list set", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_file.js", "01 Jan 2022 10:00:00 GMT"); + await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true); + }); + }); + describe("get updated list from remote file", () => { + it("shows 'test in morning' as test time set to 10am", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_file_change.js", "01 Jan 2022 10:00:00 GMT"); + await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true); + await new Promise((r) => setTimeout(r, 10000)); + await expect(doTest(["test in morning"])).resolves.toBe(true); + }); + }); }); }); diff --git a/tests/mocks/compliments_file.json b/tests/mocks/compliments_file.json new file mode 100644 index 0000000000..89171b16ed --- /dev/null +++ b/tests/mocks/compliments_file.json @@ -0,0 +1,5 @@ +{ + "morning": ["test in morning"], + "afternoon": ["test in afternoon"], + "evening": ["test in evening"] +} From 93c387519f9bed38e4e1304af7babaaaf081c43f Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Mon, 11 Nov 2024 17:31:54 -0600 Subject: [PATCH 02/10] add check for minimum refresh time --- modules/default/compliments/compliments.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index ea99eaca43..9805690205 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -27,6 +27,7 @@ Module.register("compliments", { }, urlSuffix:"", compliments_new:null, + refreshMinimumDelay:15*60*60*1000, // 15 minutes lastIndexUsed: -1, // Set currentweather from module currentWeatherType: "", @@ -48,13 +49,17 @@ Module.register("compliments", { const response = await this.loadComplimentFile(); this.config.compliments = JSON.parse(response); this.updateDom(); - if (this.config.remoteFileRefreshInterval !== null) { - this.remoteFileRefreshFunc = setInterval(async () => { - const response = await this.loadComplimentFile(); - this.compliments_new = JSON.parse(response); - }, - this.config.remoteFileRefreshInterval - ) + if (this.config.remoteFileRefreshInterval !== null){ + if(this.config.remoteFileRefreshInterval>=this.refreshMinimumDelay) { + setInterval(async () => { + const response = await this.loadComplimentFile(); + this.compliments_new = JSON.parse(response); + }, + this.config.remoteFileRefreshInterval + ) + } else { + Log.error(this.name+" remoteFileRefreshInterval less than minimum") + } } } let minute_sync_delay = 1; From ff3853efd7acfd58acad9532cb3d85d668f98325 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Mon, 11 Nov 2024 17:35:00 -0600 Subject: [PATCH 03/10] add check for minimum refresh time change from null to 0 --- modules/default/compliments/compliments.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 9805690205..fde055848d 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -16,7 +16,7 @@ Module.register("compliments", { }, updateInterval: 30000, remoteFile: null, - remoteFileRefreshInterval: null, + remoteFileRefreshInterval: 0, fadeSpeed: 4000, morningStartTime: 3, morningEndTime: 12, @@ -49,8 +49,8 @@ Module.register("compliments", { const response = await this.loadComplimentFile(); this.config.compliments = JSON.parse(response); this.updateDom(); - if (this.config.remoteFileRefreshInterval !== null){ - if(this.config.remoteFileRefreshInterval>=this.refreshMinimumDelay) { + if (this.config.remoteFileRefreshInterval !== 0){ + if(this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay) { setInterval(async () => { const response = await this.loadComplimentFile(); this.compliments_new = JSON.parse(response); From 2f12e2ce24f71eef19e83cb62e59c754f0a71b02 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Mon, 11 Nov 2024 17:52:25 -0600 Subject: [PATCH 04/10] change remotefileinterval to 0 from null --- modules/default/compliments/compliments.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index fde055848d..cb0fa840f1 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -1,9 +1,6 @@ /* global Cron */ /* global global */ -console.log("window name='"+window.name+"'") -const compliments_test_mode=(window.name=='jsdom')?true:false - Module.register("compliments", { // Module config defaults. defaults: { @@ -50,7 +47,7 @@ Module.register("compliments", { this.config.compliments = JSON.parse(response); this.updateDom(); if (this.config.remoteFileRefreshInterval !== 0){ - if(this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay) { + if(this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay || window.intest) { setInterval(async () => { const response = await this.loadComplimentFile(); this.compliments_new = JSON.parse(response); From b90768255dcaa76c255cd141cc7d95a3c84356d7 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 12 Nov 2024 08:18:11 -0600 Subject: [PATCH 05/10] change test mode variable name, add bypass minimum refresh interval check in test mode --- modules/default/compliments/compliments.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index cb0fa840f1..f94685ba35 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -47,7 +47,7 @@ Module.register("compliments", { this.config.compliments = JSON.parse(response); this.updateDom(); if (this.config.remoteFileRefreshInterval !== 0){ - if(this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay || window.intest) { + if((this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay) || window.mmTestMode == 'true') { setInterval(async () => { const response = await this.loadComplimentFile(); this.compliments_new = JSON.parse(response); @@ -271,14 +271,14 @@ Module.register("compliments", { this.lastIndexUsed = -1; } } - // in test mode only - //if (compliments_test_mode) { - // check for (undocumented) remote file2 to change test new load + // only in test mode + if (window.mmTestMode === 'true') { + // check for (undocumented) remoteFile2 to test new file load if(this.config.remoteFile2!== null && this.config.remoteFileRefreshInterval!==null){ - console.log("running in test"); - this.config.remoteFile=this.config.remoteFile2 + // switch the file so that next time it will be loaded from a changed file + this.config.remoteFile=this.config.remoteFile2 } - //} + } return wrapper; }, From 049b10c0ae4dce1355b91186134a7989e43bc689 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 12 Nov 2024 08:52:45 -0600 Subject: [PATCH 06/10] fix null vs 0 test for file refresh interval --- modules/default/compliments/compliments.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index f94685ba35..e742d3c9e4 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -206,7 +206,7 @@ Module.register("compliments", { // we need to force the server to not give us the cached result // create an extra property (ignored by the server handler) just so the url string is different // that will never be the same, using the ms value of date - if(this.config.remoteFileRefreshInterval!=null) + if(this.config.remoteFileRefreshInterval!=0) this.urlSuffix= "?dummy="+Date.now() // const response = await fetch(url+this.urlSuffix); @@ -274,7 +274,7 @@ Module.register("compliments", { // only in test mode if (window.mmTestMode === 'true') { // check for (undocumented) remoteFile2 to test new file load - if(this.config.remoteFile2!== null && this.config.remoteFileRefreshInterval!==null){ + if(this.config.remoteFile2!== null && this.config.remoteFileRefreshInterval!==0){ // switch the file so that next time it will be loaded from a changed file this.config.remoteFile=this.config.remoteFile2 } From c69ac71269fc74f6640a2c32d399a8bb1801a27c Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 12 Nov 2024 09:06:37 -0600 Subject: [PATCH 07/10] clear new object so we don't waste cycles between refreshes --- modules/default/compliments/compliments.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index e742d3c9e4..1966c7341b 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -267,6 +267,8 @@ Module.register("compliments", { if(JSON.stringify(this.config.compliments)!== JSON.stringify(this.compliments_new)){ // only reset if the contents changes this.config.compliments = this.compliments_new + // clear new file list so we don't waste cycles comparing between refreshes + this.compliments_new = null // reset the index this.lastIndexUsed = -1; } From b55cdf58c3a9379016b4d60f560b8019ba27413b Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 12 Nov 2024 09:18:31 -0600 Subject: [PATCH 08/10] move clear new object so we don't waste cycles between refreshes --- modules/default/compliments/compliments.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 1966c7341b..7b4be90253 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -267,11 +267,11 @@ Module.register("compliments", { if(JSON.stringify(this.config.compliments)!== JSON.stringify(this.compliments_new)){ // only reset if the contents changes this.config.compliments = this.compliments_new - // clear new file list so we don't waste cycles comparing between refreshes - this.compliments_new = null // reset the index this.lastIndexUsed = -1; } + // clear new file list so we don't waste cycles comparing between refreshes + this.compliments_new = null } // only in test mode if (window.mmTestMode === 'true') { From 4bac9e3929848d5abbba41ce1d08d427a6514773 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 12 Nov 2024 14:09:19 -0600 Subject: [PATCH 09/10] remove unused variable comment --- modules/default/compliments/compliments.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 7b4be90253..b4493ad6ca 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -1,5 +1,4 @@ /* global Cron */ -/* global global */ Module.register("compliments", { // Module config defaults. From 52326ec492596578f472d03b3fae01b166559d6e Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 12 Nov 2024 14:22:57 -0600 Subject: [PATCH 10/10] fix lint issues --- modules/default/compliments/compliments.js | 42 +++++++++++----------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index b4493ad6ca..9f9270f199 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -19,11 +19,11 @@ Module.register("compliments", { afternoonStartTime: 12, afternoonEndTime: 17, random: true, - specialDayUnique: false, + specialDayUnique: false }, - urlSuffix:"", - compliments_new:null, - refreshMinimumDelay:15*60*60*1000, // 15 minutes + urlSuffix: "", + compliments_new: null, + refreshMinimumDelay: 15 * 60 * 60 * 1000, // 15 minutes lastIndexUsed: -1, // Set currentweather from module currentWeatherType: "", @@ -45,16 +45,15 @@ Module.register("compliments", { const response = await this.loadComplimentFile(); this.config.compliments = JSON.parse(response); this.updateDom(); - if (this.config.remoteFileRefreshInterval !== 0){ - if((this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay) || window.mmTestMode == 'true') { + if (this.config.remoteFileRefreshInterval !== 0) { + if ((this.config.remoteFileRefreshInterval >= this.refreshMinimumDelay) || window.mmTestMode === "true") { setInterval(async () => { - const response = await this.loadComplimentFile(); - this.compliments_new = JSON.parse(response); - }, - this.config.remoteFileRefreshInterval - ) + const response = await this.loadComplimentFile(); + this.compliments_new = JSON.parse(response); + }, + this.config.remoteFileRefreshInterval); } else { - Log.error(this.name+" remoteFileRefreshInterval less than minimum") + Log.error(`${this.name} remoteFileRefreshInterval less than minimum`); } } } @@ -205,10 +204,9 @@ Module.register("compliments", { // we need to force the server to not give us the cached result // create an extra property (ignored by the server handler) just so the url string is different // that will never be the same, using the ms value of date - if(this.config.remoteFileRefreshInterval!=0) - this.urlSuffix= "?dummy="+Date.now() + if (this.config.remoteFileRefreshInterval !== 0) this.urlSuffix = `?dummy=${Date.now()}`; // - const response = await fetch(url+this.urlSuffix); + const response = await fetch(url + this.urlSuffix); return await response.text(); }, @@ -261,23 +259,23 @@ Module.register("compliments", { } // if a new set of compliments was loaded from the refresh task // we do this here to make sure no other function is using the compliments list - if(this.compliments_new){ + if (this.compliments_new) { // use them - if(JSON.stringify(this.config.compliments)!== JSON.stringify(this.compliments_new)){ + if (JSON.stringify(this.config.compliments) !== JSON.stringify(this.compliments_new)) { // only reset if the contents changes - this.config.compliments = this.compliments_new + this.config.compliments = this.compliments_new; // reset the index this.lastIndexUsed = -1; } // clear new file list so we don't waste cycles comparing between refreshes - this.compliments_new = null + this.compliments_new = null; } // only in test mode - if (window.mmTestMode === 'true') { + if (window.mmTestMode === "true") { // check for (undocumented) remoteFile2 to test new file load - if(this.config.remoteFile2!== null && this.config.remoteFileRefreshInterval!==0){ + if (this.config.remoteFile2 !== null && this.config.remoteFileRefreshInterval !== 0) { // switch the file so that next time it will be loaded from a changed file - this.config.remoteFile=this.config.remoteFile2 + this.config.remoteFile = this.config.remoteFile2; } } return wrapper;