Skip to content
This repository has been archived by the owner on Feb 7, 2022. It is now read-only.

Setup tests #6

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
19 changes: 0 additions & 19 deletions .eslintrc.js

This file was deleted.

137 changes: 137 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,138 @@
.vscode/settings.json

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
8 changes: 8 additions & 0 deletions backend/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false
16 changes: 16 additions & 0 deletions backend/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
root: true,
"env": {
"node": true,
"browser": true,
"commonjs": true,
"es2020": true,
"jest": true,
},
"extends": ["eslint:recommended", "prettier"],
plugins: ["prettier"],
"parserOptions": {
"ecmaVersion": 11
},
"rules": {}
};
File renamed without changes.
9 changes: 9 additions & 0 deletions backend/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @ts-check
const server = require("./lib/server");
const { io, connectionHandler } = require("./lib/websocket-server");
io.on("connection", connectionHandler);
// start our server
server.listen(process.env.PORT || 80, () => {
console.log(`Server started on port http://localhost:${process.env.PORT} :)`);
});

3 changes: 3 additions & 0 deletions backend/lib/plugs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { setupPlugs } = require("./utils");
const plugs = setupPlugs();
module.exports = plugs;
21 changes: 21 additions & 0 deletions backend/lib/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const basicAuth = require("express-basic-auth");
const express = require("express");
const path = require("path");
const http = require("http");

const app = express();
// initialize a simple http server
const server = http.createServer(app);

const users = {};
users[process.env.USER_NAME] = process.env.PASSWORD;

app.use(
basicAuth({
users: users,
challenge: true,
})
);
app.use(express.static(path.resolve(__dirname, '../../client')));

module.exports = server;
32 changes: 32 additions & 0 deletions backend/lib/setupPlug.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const cases = require("jest-in-case");
const { setupPlugs } = require("./utils");
const config = require("../config.json");
const { Plug } = require("tplink-smarthome-api");
describe('utilitles', () => {
test("setupPlugs", () => {
const plugs = setupPlugs();
expect(plugs).toHaveLength(config.plugs.length);
expect(plugs[0]).toBeInstanceOf(Plug);

});
});

/**
* creates an array of test cases
*/
function createTestCases() {
const plugs = setupPlugs();
const res = [];
for (let i = 0; i < config.plugs.length; i++) {
res.push({ name: `${config.plugs[i]} should match host of created plug`, ip: config.plugs[i], plug: plugs[i] });
}
return res;
}

/**
* This uses a module jest-in-case that allows to run mulitple cases at once
*
*/
cases("setupPlugs tests for all items in config.plug", opts => {
expect(opts.ip).toBe(opts.plug.host);
}, createTestCases());
18 changes: 18 additions & 0 deletions backend/lib/startCountdown.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { startCountdown } = require("./utils");
jest.useFakeTimers();
const store = {
toggles: {
exhibition: {
pgValue: 2,
lastSwitchOn: 0
}
}
};
describe('utils test', () => {
test("startCountdown to…", () => {
startCountdown(store, 10);
expect(setInterval).toHaveBeenCalledTimes(1);
expect(setInterval).toHaveBeenCalledWith(expect.any(Function), 50);

});
});
37 changes: 37 additions & 0 deletions backend/lib/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const onChange = require("on-change");
const plugs = require("./plugs");
const utils = require("./utils");
const io = require("./websocket-server");
const initialState = {
toggles: {
exhibition: {
state: false,
countdownActive: false,
pgvalue: 0,
lastSwitchOn: null,
},
},
};

const store = onChange(initialState, function (path, value, previousValue) {
// console.log('this:', this);
// console.log('path:', path);
// console.log('value:', value);
// console.log('previousValue:', previousValue);

// TODO : handle this in receiving toggle changes
if (path === "toggles.exhibition.state" && value !== previousValue) {
let i = 0;
for (const plug of plugs) {
// console.log(plug, value)
setTimeout(() => plug.setPowerState(value), i * 1000); // staggered on/off
i++;
}

if (value) utils.startCountdown(store, utils.calcMillisBeforeRestart());
}

// console.log("updating all devices")
io.emit("toggles", store.toggles);
});
module.exports = store;
45 changes: 45 additions & 0 deletions backend/lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// @ts-check
const config = require("../config.json");
const TPLinkClient = require("tplink-smarthome-api").Client;
const tplink = new TPLinkClient();
const minutesBeforeNextToggle = process.env.EXPECTED_BOOT_DURATION_IN_MIN ? parseInt(process.env.EXPECTED_BOOT_DURATION_IN_MIN) : 3;

module.exports = {
calcMillisBeforeRestart: function () {
const milliSecondsBeforeRestart = minutesBeforeNextToggle * 60 * 1000;
return milliSecondsBeforeRestart;
},
setupPlugs: function () {
const plugs = [];
for (const ip of config.plugs) {
plugs.push(tplink.getPlug({ host: ip }));
}
return plugs;
},
startCountdown: /**
* @param {{ toggles: { exhibition: {lastSwitchOn: number|Date,countdownActive: boolean; pgvalue: number}; }; }} store
* @param {number} milliSecondsBeforeRestart
*/
function (store, milliSecondsBeforeRestart) {
console.log("startCountdown");
const toggle = store.toggles.exhibition;
toggle.lastSwitchOn = new Date();
toggle.countdownActive = true;

const intervalid = setInterval(() => {
console.log('toggle.lastSwitchOn ', toggle.lastSwitchOn);
//
// The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. @jvolker
const now = new Date();
toggle.pgvalue =
(now - toggle.lastSwitchOn) / milliSecondsBeforeRestart;

if (toggle.pgvalue > 1) {
console.log("stop");
clearInterval(intervalid);
toggle.countdownActive = false;
}
// console.log(toggle.pgvalue)
}, 50);
}
};
20 changes: 20 additions & 0 deletions backend/lib/websocket-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const socketIo = require('socket.io');
const server = require('./server');
const io = socketIo.listen(server);
const store = require('./store');
const togglesHandler = (data) => {
console.log("new toggles received");
for (const key in data) {
store.toggles[key].state = data[key].state;
}
};
module.exports = {
togglesHandler,
io, connectionHandler: (socket) => {
console.log("socket.io client connected");

socket.emit("toggles", store.toggles);

socket.on("toggles", togglesHandler);
}
};
Loading