fixed merge conflicts. Some tests are broken

This commit is contained in:
Chris Troutner
2023-10-22 17:43:28 -07:00
119 changed files with 6515 additions and 14551 deletions
+8
View File
@@ -0,0 +1,8 @@
[
{
"srcDir": "",
"destDir": "",
"files": "**/*.js",
"command": "npm run lint"
}
]
+1 -1
View File
@@ -1,5 +1,5 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2022 Permissionless Software Foundation Copyright (c) 2021-2023 Permissionless Software Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+21 -17
View File
@@ -8,23 +8,26 @@
*/ */
// npm libraries // npm libraries
const Koa = require('koa') import Koa from 'koa'
const bodyParser = require('koa-bodyparser')
const convert = require('koa-convert') import bodyParser from 'koa-bodyparser'
const logger = require('koa-logger') import convert from 'koa-convert'
const mongoose = require('mongoose') import logger from 'koa-logger'
const session = require('koa-generic-session') import mongoose from 'mongoose'
const passport = require('koa-passport') import session from 'koa-generic-session'
const mount = require('koa-mount') import passport from 'koa-passport'
const serve = require('koa-static') import mount from 'koa-mount'
const cors = require('kcors') import serve from 'koa-static'
import cors from 'kcors'
// Local libraries // Local libraries
const config = require('../config') // this first. import config from '../config/index.js' // this first.
const AdminLib = require('../src/adapters/admin')
const errorMiddleware = require('../src/controllers/rest-api/middleware/error') import AdminLib from '../src/adapters/admin.js'
const { wlogger } = require('../src/adapters/wlogger') import errorMiddleware from '../src/controllers/rest-api/middleware/error.js'
const Controllers = require('../src/controllers') import wlogger from '../src/adapters/wlogger.js'
import Controllers from '../src/controllers/index.js'
import { applyPassportMods } from '../config/passport.js'
class Server { class Server {
constructor () { constructor () {
@@ -70,7 +73,8 @@ class Server {
app.use(mount('/logs', serve(`${process.cwd()}/config/logs`))) app.use(mount('/logs', serve(`${process.cwd()}/config/logs`)))
// User Authentication // User Authentication
require('../config/passport') // require('../config/passport')
applyPassportMods(passport)
app.use(passport.initialize()) app.use(passport.initialize())
app.use(passport.session()) app.use(passport.session())
@@ -131,4 +135,4 @@ class Server {
} }
} }
module.exports = Server export default Server
+10 -2
View File
@@ -5,15 +5,22 @@
/* eslint no-unneeded-ternary:0 */ /* eslint no-unneeded-ternary:0 */
// Hack to get __dirname back.
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
import * as url from 'url'
// Get the version from the package.json file. // Get the version from the package.json file.
const pkgInfo = require('../../package.json') import { readFileSync } from 'fs'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const pkgInfo = JSON.parse(readFileSync(`${__dirname.toString()}/../../package.json`))
const version = pkgInfo.version const version = pkgInfo.version
const ipfsCoordName = process.env.COORD_NAME const ipfsCoordName = process.env.COORD_NAME
? process.env.COORD_NAME ? process.env.COORD_NAME
: 'ipfs-bch-wallet-service' : 'ipfs-bch-wallet-service'
module.exports = { export default {
// Configure TCP port. // Configure TCP port.
port: process.env.PORT || 5005, port: process.env.PORT || 5005,
@@ -47,6 +54,7 @@ module.exports = {
: 'demo', : 'demo',
// IPFS settings. // IPFS settings.
useIpfs: process.env.DISABLE_IPFS ? false : true, // Disable IPFS flag
isCircuitRelay: process.env.ENABLE_CIRCUIT_RELAY ? true : false, isCircuitRelay: process.env.ENABLE_CIRCUIT_RELAY ? true : false,
// SSL domain used for websocket connection via browsers. // SSL domain used for websocket connection via browsers.
crDomain: process.env.CR_DOMAIN ? process.env.CR_DOMAIN : '', crDomain: process.env.CR_DOMAIN ? process.env.CR_DOMAIN : '',
+1 -1
View File
@@ -4,7 +4,7 @@
specified. specified.
*/ */
module.exports = { export default {
session: 'secret-boilerplate-token', session: 'secret-boilerplate-token',
token: 'secret-jwt-token', token: 'secret-jwt-token',
database: 'mongodb://localhost:27017/ipfs-bch-consumer-dev', database: 'mongodb://localhost:27017/ipfs-bch-consumer-dev',
+1 -1
View File
@@ -7,7 +7,7 @@
so as not to conflict with the default host port of 27017 for MongoDB. so as not to conflict with the default host port of 27017 for MongoDB.
*/ */
module.exports = { export default {
session: 'secret-boilerplate-token', session: 'secret-boilerplate-token',
token: 'secret-jwt-token', token: 'secret-jwt-token',
// database: 'mongodb://172.17.0.1:5555/ipfs-service-prod', // database: 'mongodb://172.17.0.1:5555/ipfs-service-prod',
+1 -1
View File
@@ -4,7 +4,7 @@
This is the environment run by the test suite. This is the environment run by the test suite.
*/ */
module.exports = { export default {
session: 'secret-boilerplate-token', session: 'secret-boilerplate-token',
token: 'secret-jwt-token', token: 'secret-jwt-token',
database: 'mongodb://localhost:27017/ipfs-bch-consumer-test', database: 'mongodb://localhost:27017/ipfs-bch-consumer-test',
+19 -4
View File
@@ -1,6 +1,21 @@
const common = require('./env/common') import common from './env/common.js'
const env = process.env.CONSUMER_ENV || 'development' import development from './env/development.js'
const config = require(`./env/${env}`) import production from './env/production.js'
import test from './env/test.js'
module.exports = Object.assign({}, common, config) const env = process.env.SVC_ENV || 'development'
console.log(`Loading config for this environment: ${env}`)
let config = development
if (env === 'test') {
config = test
} else if (env === 'prod') {
config = production
}
// const importStr = `./env/${env}.js`
// console.log('importStr: ', importStr)
// import config from importStr
export default Object.assign({}, common, config)
+34 -28
View File
@@ -1,30 +1,6 @@
const passport = require('koa-passport') // import passport from 'koa-passport';
const User = require('../src/adapters/localdb/models/users') import User from '../src/adapters/localdb/models/users.js'
const Strategy = require('passport-local') import Strategy from 'passport-local'
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findById(id, '-password')
done(null, user)
} catch (err) {
done(err)
}
})
passport.use(
'local',
new Strategy(
{
usernameField: 'email',
passwordField: 'password'
},
passportCallback
)
)
async function passportCallback (email, password, done) { async function passportCallback (email, password, done) {
try { try {
@@ -49,5 +25,35 @@ async function passportCallback (email, password, done) {
} }
} }
function applyPassportMods (passport) {
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findById(id, '-password')
done(null, user)
} catch (err) {
done(err)
}
})
passport.use(
'local',
new Strategy(
{
usernameField: 'email',
passwordField: 'password'
},
passportCallback
)
)
return true
}
// For testing // For testing
module.exports = { passport, passportCallback } // export default { passport, passportCallback };
// export default applyPassportMods
export { applyPassportMods, passportCallback }
+1 -1
View File
@@ -1,4 +1,4 @@
const Server = require('./bin/server.js') import Server from './bin/server.js'
const server = new Server() const server = new Server()
server.startServer() server.startServer()
+5146 -13903
View File
File diff suppressed because it is too large Load Diff
+9 -14
View File
@@ -3,17 +3,18 @@
"version": "1.0.0", "version": "1.0.0",
"description": "A (local) REST API that proxies BCH wallet services delivered over IPFS (global).", "description": "A (local) REST API that proxies BCH wallet services delivered over IPFS (global).",
"main": "index.js", "main": "index.js",
"type": "module",
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",
"test": "npm run test:all", "test": "npm run test:all",
"test:all": "export CONSUMER_ENV=test && nyc --reporter=text mocha --exit --timeout 15000 --recursive test/unit test/e2e/automated/", "test:all": "export CONSUMER_ENV=test && c8 --reporter=text mocha --exit --timeout 15000 --recursive test/unit test/e2e/automated/",
"test:unit": "export CONSUMER_ENV=test && mocha --exit --timeout 15000 --recursive test/unit/", "test:unit": "export CONSUMER_ENV=test && mocha --exit --timeout 15000 --recursive test/unit/",
"test:e2e:auto": "export CONSUMER_ENV=test && mocha --exit --timeout 15000 test/e2e/automated/", "test:e2e:auto": "export CONSUMER_ENV=test && mocha --exit --timeout 15000 test/e2e/automated/",
"test:temp": "export CONSUMER_ENV=test && mocha --exit --timeout 15000 -g '#rate-limit' test/unit/json-rpc/", "test:temp": "export CONSUMER_ENV=test && mocha --exit --timeout 15000 -g '#rate-limit' test/unit/json-rpc/",
"lint": "standard --env mocha --fix", "lint": "standard --env mocha --fix",
"docs": "./node_modules/.bin/apidoc -i src/ -o docs", "docs": "./node_modules/.bin/apidoc -i src/ -o docs",
"coverage": "nyc report --reporter=text-lcov | coveralls", "coverage": "c8 report --reporter=text-lcov | coveralls",
"coverage:report": "export CONSUMER_ENV=test && nyc --reporter=html mocha --exit --timeout 15000 --recursive test/unit/ test/e2e/automated/" "coverage:report": "export CONSUMER_ENV=test && c8 --reporter=html mocha --exit --timeout 15000 --recursive test/unit/ test/e2e/automated/"
}, },
"author": "Chris Troutner <chris.troutner@gmail.com>", "author": "Chris Troutner <chris.troutner@gmail.com>",
"license": "MIT", "license": "MIT",
@@ -27,9 +28,8 @@
"axios": "0.27.2", "axios": "0.27.2",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"glob": "7.1.6", "glob": "7.1.6",
"ipfs": "0.62.3", "ipfs-coord-esm": "9.1.13",
"ipfs-coord": "8.0.8", "ipfs-http-client": "58.0.0",
"ipfs-http-client": "55.0.0",
"jsonrpc-lite": "2.2.0", "jsonrpc-lite": "2.2.0",
"jsonwebtoken": "8.5.1", "jsonwebtoken": "8.5.1",
"jwt-bch-lib": "1.3.0", "jwt-bch-lib": "1.3.0",
@@ -45,6 +45,7 @@
"koa-static": "5.0.0", "koa-static": "5.0.0",
"koa2-ratelimit": "0.9.1", "koa2-ratelimit": "0.9.1",
"line-reader": "0.4.0", "line-reader": "0.4.0",
"minimal-slp-wallet": "5.11.1",
"mongoose": "5.13.14", "mongoose": "5.13.14",
"node-fetch": "npm:@achingbrain/node-fetch@2.6.7", "node-fetch": "npm:@achingbrain/node-fetch@2.6.7",
"nodemailer": "6.7.5", "nodemailer": "6.7.5",
@@ -56,21 +57,15 @@
}, },
"devDependencies": { "devDependencies": {
"apidoc": "0.51.1", "apidoc": "0.51.1",
"c8": "7.12.0",
"chai": "4.3.0", "chai": "4.3.0",
"coveralls": "3.1.0", "coveralls": "3.1.0",
"eslint": "7.19.0",
"eslint-config-prettier": "7.2.0",
"eslint-config-standard": "16.0.2",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-standard": "4.0.0",
"husky": "4.3.8", "husky": "4.3.8",
"lodash.clonedeep": "4.5.0", "lodash.clonedeep": "4.5.0",
"mocha": "10.0.0", "mocha": "10.0.0",
"nyc": "15.1.0",
"semantic-release": "19.0.3", "semantic-release": "19.0.3",
"sinon": "9.2.4", "sinon": "9.2.4",
"standard": "16.0.3", "standard": "17.0.0",
"uuid": "8.3.2" "uuid": "8.3.2"
}, },
"release": { "release": {
+12 -13
View File
@@ -14,10 +14,16 @@ services:
restart: always restart: always
ipfs-bch-consumer: ipfs-bch-consumer:
image: ipfs/go-ipfs:v0.14.0 # https://github.com/christroutner/trickle-ipfs
image: christroutner/trickle-ipfs:v1.0.1
#build:
# context: ./
# dockerfile: Dockerfile
container_name: ipfs-bch-consumer container_name: ipfs-bch-consumer
environment: environment:
MY_ENV_VAR: 'placeholder' IPFS_DAEMON_ARGUMENTS: '--enable-pubsub-experiment --migrate=true --agent-version-suffix=docker --routing=dhtclient'
UPLOAD_KBPS: '1000'
DOWNLOAD_KBPS: '1000'
logging: logging:
driver: 'json-file' driver: 'json-file'
options: options:
@@ -29,18 +35,11 @@ services:
- 4003:4003 - 4003:4003
- 172.17.0.1:5001:5001 - 172.17.0.1:5001:5001
- 172.17.0.1:8080:8080 - 172.17.0.1:8080:8080
command: [
'./start-ipfs.sh'
]
volumes: volumes:
- ../data/go-ipfs/data:/data/ipfs - ../data/go-ipfs/data:/root/.ipfs
# - ../../swarm.key:/data/ipfs/swarm.key
# https://docs.docker.com/compose/compose-file/compose-file-v3/#command
# https://github.com/ipfs/go-ipfs/blob/91c52657166bcf86f2476926e4fe56694dc26562/Dockerfile#L115
command:
[
'daemon',
'--migrate=true',
'--agent-version-suffix=docker',
'--enable-pubsub-experiment'
]
restart: always restart: always
bch-consumer: bch-consumer:
+1 -1
View File
@@ -13,7 +13,7 @@ export COORD_NAME=trout-dev-bch-wallet-consumer
export MNEMONIC="stomach mean catch march census author cousin size south romance pumpkin trap" export MNEMONIC="stomach mean catch march census author cousin size south romance pumpkin trap"
# 0 = less verbose. 3 = most verbose # 0 = less verbose. 3 = most verbose
export DEBUG_LEVEL=1 export DEBUG_LEVEL=0
# Production settings that use external IPFS node. # Production settings that use external IPFS node.
# https://github.com/christroutner/docker-ipfs # https://github.com/christroutner/docker-ipfs
+18 -8
View File
@@ -13,16 +13,24 @@
in the Adapter directory. in the Adapter directory.
*/ */
'use strict' // Global npm libraries
const axios = require('axios').default import axios from 'axios'
const mongoose = require('mongoose') import mongoose from 'mongoose'
const User = require('../adapters/localdb/models/users')
const config = require('../../config') // Local libraries
const JsonFiles = require('../adapters/json-files') import User from '../adapters/localdb/models/users.js'
import config from '../../config/index.js'
import JsonFiles from '../adapters/json-files.js'
// Hack to get __dirname back.
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const jsonFiles = new JsonFiles() const jsonFiles = new JsonFiles()
const JSON_FILE = `system-user-${config.env}.json` const JSON_FILE = `system-user-${config.env}.json`
const JSON_PATH = `${__dirname.toString()}/../../config/${JSON_FILE}` const JSON_PATH = `${__dirname.toString()}../../config/${JSON_FILE}`
const LOCALHOST = `http://localhost:${config.port}` const LOCALHOST = `http://localhost:${config.port}`
const context = {} const context = {}
@@ -82,6 +90,8 @@ class Admin {
// applications like the Task Manager and the test scripts can access. // applications like the Task Manager and the test scripts can access.
await jsonFiles.writeJSON(context, JSON_PATH) await jsonFiles.writeJSON(context, JSON_PATH)
// console.log('context: ', context)
// console.log('JSON_PATH: ', JSON_PATH)
return context return context
} catch (err) { } catch (err) {
@@ -169,4 +179,4 @@ class Admin {
} }
} }
module.exports = Admin export default Admin
+6 -5
View File
@@ -4,11 +4,11 @@
*/ */
// Public npm libraries // Public npm libraries
const { v4: uid } = require('uuid') import { v4 as uid } from 'uuid'
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
// Local libraries // Local libraries
const { wlogger } = require('../wlogger') import wlogger from '../wlogger.js'
let _this let _this
@@ -319,7 +319,7 @@ class BchAdapter {
const rpcData = { const rpcData = {
endpoint: 'txHistory', endpoint: 'txHistory',
address: address, address,
sortOrder, sortOrder,
page page
} }
@@ -625,4 +625,5 @@ class BchAdapter {
} }
} }
module.exports = BchAdapter // module.exports = BchAdapter
export default BchAdapter
+5 -6
View File
@@ -3,13 +3,12 @@
*/ */
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
import config from '../../config/index.js'
import NodeMailer from '../adapters/nodemailer.js'
import wlogger from '../adapters/wlogger.js'
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
const config = require('../../config')
const NodeMailer = require('../adapters/nodemailer')
const nodemailer = new NodeMailer() const nodemailer = new NodeMailer()
const { wlogger } = require('../adapters/wlogger')
let _this let _this
@@ -60,4 +59,4 @@ class ContactLib {
} }
} }
} }
module.exports = ContactLib export default ContactLib
+4 -3
View File
@@ -5,8 +5,9 @@
for this file. for this file.
*/ */
const JwtLib = require('jwt-bch-lib') import JwtLib from 'jwt-bch-lib'
const BCHJS = require('@psf/bch-js')
import BCHJS from '@psf/bch-js'
class FullStackJWT { class FullStackJWT {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -98,4 +99,4 @@ class FullStackJWT {
} }
} }
module.exports = FullStackJWT export default FullStackJWT
+20 -14
View File
@@ -5,21 +5,22 @@
*/ */
// Public NPM libraries // Public NPM libraries
const BCHJS = require('@psf/bch-js') import BCHJS from '@psf/bch-js'
// Load individual adapter libraries. // Load individual adapter libraries.
const IPFSAdapter = require('./ipfs') import IPFSAdapter from './ipfs/index.js'
const LocalDB = require('./localdb') import LocalDB from './localdb/index.js'
const LogsAPI = require('./logapi') import LogsAPI from './logapi.js'
const Passport = require('./passport') import Passport from './passport.js'
const Nodemailer = require('./nodemailer') import Nodemailer from './nodemailer.js'
// const { wlogger } = require('./wlogger') import BCH from './bch/index.js'
const JSONFiles = require('./json-files') import P2WDB from './p2wdb/index.js'
const FullStackJWT = require('./fullstack-jwt')
const BCH = require('./bch')
const P2WDB = require('./p2wdb')
const config = require('../../config') // const { wlogger } = require('./wlogger')
import JSONFiles from './json-files.js'
import FullStackJWT from './fullstack-jwt.js'
import config from '../../config/index.js'
class Adapters { class Adapters {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -61,7 +62,12 @@ class Adapters {
// Start the IPFS node. // Start the IPFS node.
// Do not start these adapters if this is an e2e test. // Do not start these adapters if this is an e2e test.
if (this.config.env !== 'test') { if (this.config.env !== 'test') {
await this.ipfs.start() if (this.config.useIpfs) {
await this.ipfs.start()
}
} else {
// These lines are here to ensure code coverage hits 100%.
console.log('Not starting IPFS node since this is an e2e test.')
} }
console.log('Async Adapters have been started.') console.log('Async Adapters have been started.')
@@ -74,4 +80,4 @@ class Adapters {
} }
} }
module.exports = Adapters export default Adapters
+5 -4
View File
@@ -3,9 +3,10 @@
*/ */
// Local libraries // Local libraries
const IpfsAdapter = require('./ipfs') import IpfsAdapter from './ipfs.js'
const IpfsCoordAdapter = require('./ipfs-coord')
const config = require('../../../config') import IpfsCoordAdapter from './ipfs-coord.js'
import config from '../../../config/index.js'
class IPFS { class IPFS {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -191,4 +192,4 @@ class IPFS {
} }
} }
module.exports = IPFS export default IPFS
+16 -8
View File
@@ -5,13 +5,16 @@
*/ */
// Global npm libraries // Global npm libraries
const IpfsCoord = require('ipfs-coord') import IpfsCoord from 'ipfs-coord-esm'
const BCHJS = require('@psf/bch-js')
const publicIp = require('public-ip') // import BCHJS from '@psf/bch-js'
const semver = require('semver') import SlpWallet from 'minimal-slp-wallet'
import publicIp from 'public-ip'
import semver from 'semver'
// Local libraries // Local libraries
const config = require('../../../config') import config from '../../../config/index.js'
// const JSONRPC = require('../../controllers/json-rpc/') // const JSONRPC = require('../../controllers/json-rpc/')
// The minimum version of ipfs-bch-wallet-service that this wallet can work with. // The minimum version of ipfs-bch-wallet-service that this wallet can work with.
@@ -41,7 +44,8 @@ class IpfsCoordAdapter {
// Encapsulate dependencies // Encapsulate dependencies
this.IpfsCoord = IpfsCoord this.IpfsCoord = IpfsCoord
this.ipfsCoord = {} this.ipfsCoord = {}
this.bchjs = new BCHJS() // this.bchjs = new BCHJS()
this.wallet = new SlpWallet()
this.config = config this.config = config
this.publicIp = publicIp this.publicIp = publicIp
this.semver = semver this.semver = semver
@@ -70,6 +74,9 @@ class IpfsCoordAdapter {
async start () { async start () {
const circuitRelayInfo = {} const circuitRelayInfo = {}
// Wait for the BCH wallet to create the wallet.
await this.wallet.walletInfoPromise
// If configured as a Circuit Relay, get the public IP addresses for this node. // If configured as a Circuit Relay, get the public IP addresses for this node.
if (this.config.isCircuitRelay) { if (this.config.isCircuitRelay) {
try { try {
@@ -91,8 +98,9 @@ class IpfsCoordAdapter {
ipfs: this.ipfs, ipfs: this.ipfs,
type: 'node.js', type: 'node.js',
// type: 'browser', // type: 'browser',
wallet: this.wallet,
privateLog: console.log, // Default to console.log
bchjs: this.bchjs, bchjs: this.bchjs,
privateLog: this.peerInputHandler,
isCircuitRelay: this.config.isCircuitRelay, isCircuitRelay: this.config.isCircuitRelay,
circuitRelayInfo, circuitRelayInfo,
apiInfo: this.config.apiInfo, apiInfo: this.config.apiInfo,
@@ -318,4 +326,4 @@ class IpfsCoordAdapter {
} }
} }
module.exports = IpfsCoordAdapter export default IpfsCoordAdapter
+14 -13
View File
@@ -11,13 +11,14 @@
// Global npm libraries // Global npm libraries
// const IPFS = require('ipfs') // const IPFS = require('ipfs')
// const IPFS = require('@chris.troutner/ipfs') // const IPFS = require('@chris.troutner/ipfs')
const IPFSembedded = require('ipfs') // import IPFSembedded from 'ipfs';
const IPFSexternal = require('ipfs-http-client')
const fs = require('fs') import { create } from 'ipfs-http-client'
const http = require('http') import fs from 'fs'
import http from 'http'
// Local libraries // Local libraries
const config = require('../../../config') import config from '../../../config/index.js'
const IPFS_DIR = './.ipfsdata/ipfs' const IPFS_DIR = './.ipfsdata/ipfs'
@@ -25,17 +26,17 @@ class IpfsAdapter {
constructor (localConfig) { constructor (localConfig) {
// Encapsulate dependencies // Encapsulate dependencies
this.config = config this.config = config
this.fs = fs
this.create = create
// Choose the IPFS constructor based on the config settings. // Choose the IPFS constructor based on the config settings.
this.IPFS = IPFSembedded // default // this.IPFS = IPFSembedded // default
if (this.config.isProduction) { // if (this.config.isProduction) {
this.IPFS = IPFSexternal // this.IPFS = IPFSexternal
} // }
// Properties of this class instance. // Properties of this class instance.
this.isReady = false this.isReady = false
this.fs = fs
} }
// Start an IPFS node. // Start an IPFS node.
@@ -85,7 +86,7 @@ class IpfsAdapter {
} }
// Create a new IPFS node. // Create a new IPFS node.
this.ipfs = await this.IPFS.create(ipfsOptions) this.ipfs = await this.create(ipfsOptions)
// Set the 'server' profile so the node does not scan private networks. // Set the 'server' profile so the node does not scan private networks.
await this.ipfs.config.profiles.apply('server') await this.ipfs.config.profiles.apply('server')
@@ -137,4 +138,4 @@ class IpfsAdapter {
// } // }
} }
module.exports = IpfsAdapter export default IpfsAdapter
+5 -4
View File
@@ -1,8 +1,8 @@
/* /*
A utility file for reading and writing JSON files. A utility file for reading and writing JSON files.
*/ */
'use strict'
const fs = require('fs') import fs from 'fs'
let _this let _this
@@ -57,7 +57,8 @@ class JsonFiles {
console.log(`err: ${JSON.stringify(err, null, 2)}`) console.log(`err: ${JSON.stringify(err, null, 2)}`)
} }
throw err // throw err
return reject(err)
} }
const obj = JSON.parse(data) const obj = JSON.parse(data)
@@ -72,4 +73,4 @@ class JsonFiles {
} }
} }
module.exports = JsonFiles export default JsonFiles
+2 -2
View File
@@ -3,7 +3,7 @@
*/ */
// Load Mongoose models. // Load Mongoose models.
const Users = require('./models/users') import Users from './models/users.js'
class LocalDB { class LocalDB {
constructor () { constructor () {
@@ -12,4 +12,4 @@ class LocalDB {
} }
} }
module.exports = LocalDB export default LocalDB
+8 -5
View File
@@ -1,7 +1,10 @@
const mongoose = require('mongoose') // Global npm libraries
const bcrypt = require('bcryptjs') import mongoose from 'mongoose'
const config = require('../../../../config') import bcrypt from 'bcryptjs'
const jwt = require('jsonwebtoken') import jwt from 'jsonwebtoken'
// Local libraries
import config from '../../../../config/index.js'
const User = new mongoose.Schema({ const User = new mongoose.Schema({
type: { type: String, default: 'user' }, type: { type: String, default: 'user' },
@@ -51,4 +54,4 @@ User.methods.generateToken = function generateToken () {
} }
// export default mongoose.model('user', User) // export default mongoose.model('user', User)
module.exports = mongoose.model('user', User) export default mongoose.model('user', User)
+9 -4
View File
@@ -1,9 +1,14 @@
const lineReader = require('line-reader') import lineReader from 'line-reader'
const fs = require('fs') import fs from 'fs'
const config = require('../../config') import config from '../../config/index.js'
// Hack to get __dirname back.
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
import * as url from 'url'
let _this let _this
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
class LogsApi { class LogsApi {
constructor () { constructor () {
@@ -169,4 +174,4 @@ class LogsApi {
} }
} }
module.exports = LogsApi export default LogsApi
+4 -5
View File
@@ -3,11 +3,10 @@
*/ */
'use strict' 'use strict'
const nodemailer = require('nodemailer') import nodemailer from 'nodemailer'
const config = require('../../config') import config from '../../config/index.js'
import wlogger from './wlogger.js'
const { wlogger } = require('./wlogger')
let _this let _this
@@ -150,4 +149,4 @@ class NodeMailer {
} }
} }
module.exports = NodeMailer export default NodeMailer
+5 -4
View File
@@ -4,11 +4,11 @@
*/ */
// Public npm libraries // Public npm libraries
const { v4: uid } = require('uuid') import { v4 as uid } from 'uuid'
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
// Local libraries // Local libraries
const { wlogger } = require('../wlogger') import wlogger from '../wlogger.js'
let _this let _this
@@ -264,4 +264,5 @@ class P2wdbAdapter {
} }
} }
module.exports = P2wdbAdapter // module.exports = P2wdbAdapter
export default P2wdbAdapter
+2 -2
View File
@@ -2,7 +2,7 @@
koa-passport is an authorization library used for different authentication schemes. koa-passport is an authorization library used for different authentication schemes.
*/ */
const passport = require('koa-passport') import passport from 'koa-passport'
let _this let _this
class Passport { class Passport {
@@ -32,4 +32,4 @@ class Passport {
} }
} }
module.exports = Passport export default Passport
+12 -4
View File
@@ -6,10 +6,17 @@
'use strict' 'use strict'
const winston = require('winston') // Global npm libraries
require('winston-daily-rotate-file') import winston from 'winston'
import 'winston-daily-rotate-file'
const config = require('../../config') // Local libraries
import config from '../../config/index.js'
// Hack to get __dirname back.
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
class Wlogger { class Wlogger {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -69,4 +76,5 @@ logger.outputToConsole()
const wlogger = logger.wlogger const wlogger = logger.wlogger
module.exports = { wlogger, Wlogger } export { wlogger as default, Wlogger }
// export default wlogger
+15 -16
View File
@@ -8,25 +8,21 @@
// const EventEmitter = require('events') // const EventEmitter = require('events')
// Local libraries // Local libraries
const config = require('../../config') import Adapters from '../adapters/index.js'
const Adapters = require('../adapters') import JSONRPC from './json-rpc/index.js'
const JSONRPC = require('./json-rpc') import UseCases from '../use-cases/index.js'
const UseCases = require('../use-cases') import RESTControllers from './rest-api/index.js'
const RESTControllers = require('./rest-api') import TimerControllers from './timer-controllers.js'
import config from '../../config/index.js'
class Controllers { class Controllers {
constructor (localConfig = {}) { constructor (localConfig = {}) {
// Encapsulate dependencies // Encapsulate dependencies
this.config = config
// Initialize EventEmitters used to pass event-driven data around the app.
// this.eventEmitter = new EventEmitter()
// localConfig.eventEmitter = this.eventEmitter
// Initialize Clean Architecture classes. Inject dependencies.
this.adapters = new Adapters(localConfig) this.adapters = new Adapters(localConfig)
localConfig.adapters = this.adapters localConfig.adapters = this.adapters
this.useCases = new UseCases(localConfig) this.useCases = new UseCases(localConfig)
this.timerControllers = new TimerControllers({ adapters: this.adapters, useCases: this.useCases })
this.config = config
} }
// Spin up any adapter libraries that have async startup needs. // Spin up any adapter libraries that have async startup needs.
@@ -56,10 +52,13 @@ class Controllers {
// Wait for any startup processes to complete for the Adapters libraries. // Wait for any startup processes to complete for the Adapters libraries.
// await this.adapters.start() // await this.adapters.start()
// Attach the REST controllers to the Koa app. if (this.config.useIpfs) {
// this.attachRESTControllers(app) // Attach JSON RPC controllers
this.attachRPCControllers()
}
this.attachRPCControllers() // Attach and start the timer controllers
this.timerControllers.startTimers()
} }
// Add the JSON RPC router to the ipfs-coord adapter. // Add the JSON RPC router to the ipfs-coord adapter.
@@ -76,4 +75,4 @@ class Controllers {
} }
} }
module.exports = Controllers export default Controllers
+3 -3
View File
@@ -6,10 +6,10 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
// Local libraries // Local libraries
const config = require('../../../../config') import config from '../../../../config/index.js'
class AboutRPC { class AboutRPC {
constructor (localConfig) { constructor (localConfig) {
@@ -48,4 +48,4 @@ class AboutRPC {
} }
} }
module.exports = AboutRPC export default AboutRPC
+5 -4
View File
@@ -3,13 +3,14 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
// Local libraries // Local libraries
// const AuthLib = require('../../lib/auth') // const AuthLib = require('../../lib/auth')
// const UserLib = require('../../../use-cases/user') // const UserLib = require('../../../use-cases/user')
const { wlogger } = require('../../../adapters/wlogger') import wlogger from '../../../adapters/wlogger.js'
const RateLimit = require('../rate-limit')
import RateLimit from '../rate-limit.js'
class AuthRPC { class AuthRPC {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -173,4 +174,4 @@ class AuthRPC {
} }
} }
module.exports = AuthRPC export default AuthRPC
+7 -6
View File
@@ -3,13 +3,14 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
// Local support libraries // Local support libraries
const { wlogger } = require('../../adapters/wlogger') import wlogger from '../../adapters/wlogger.js'
const UserController = require('./users')
const AuthController = require('./auth') import UserController from './users/index.js'
const AboutController = require('./about') import AuthController from './auth/index.js'
import AboutController from './about/index.js'
let _this let _this
@@ -213,4 +214,4 @@ class JSONRPC {
} }
} }
module.exports = JSONRPC export default JSONRPC
+2 -2
View File
@@ -4,7 +4,7 @@
/* eslint no-useless-catch: 0 */ /* eslint no-useless-catch: 0 */
// Local libraries // Local libraries
const RateLimitLib = require('koa2-ratelimit').RateLimit import { RateLimit as RateLimitLib } from 'koa2-ratelimit'
class RateLimit { class RateLimit {
constructor (options) { constructor (options) {
@@ -80,4 +80,4 @@ class RateLimit {
} }
} }
module.exports = RateLimit export default RateLimit
+5 -4
View File
@@ -3,12 +3,13 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
// Local libraries // Local libraries
// const UserLib = require('../../../use-cases/user') // const UserLib = require('../../../use-cases/user')
const Validators = require('../validators') import Validators from '../validators.js'
const RateLimit = require('../rate-limit')
import RateLimit from '../rate-limit.js'
class UserRPC { class UserRPC {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -533,4 +534,4 @@ class UserRPC {
// TODO create deleteUser() // TODO create deleteUser()
} }
module.exports = UserRPC export default UserRPC
+4 -3
View File
@@ -4,10 +4,11 @@
/* eslint no-useless-catch: 0 */ /* eslint no-useless-catch: 0 */
// Public npm libraries // Public npm libraries
const jwt = require('jsonwebtoken') import jwt from 'jsonwebtoken'
// Local libraries // Local libraries
const config = require('../../../config') import config from '../../../config/index.js'
// const UserModel = require('../../adapters/localdb/models/users') // const UserModel = require('../../adapters/localdb/models/users')
class Validators { class Validators {
@@ -93,4 +94,4 @@ class Validators {
} }
} }
module.exports = Validators export default Validators
+2 -2
View File
@@ -1,4 +1,4 @@
const Passport = require('../../../adapters/passport') import Passport from '../../../adapters/passport.js'
const passport = new Passport() const passport = new Passport()
let _this let _this
@@ -96,4 +96,4 @@ class AuthRESTController {
} }
} }
module.exports = AuthRESTController export default AuthRESTController
+3 -3
View File
@@ -3,10 +3,10 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const AuthRESTController = require('./controller') import AuthRESTController from './controller.js'
class AuthRouter { class AuthRouter {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -48,4 +48,4 @@ class AuthRouter {
} }
} }
module.exports = AuthRouter export default AuthRouter
+4 -3
View File
@@ -2,8 +2,8 @@
REST API Controller library for the /bch route REST API Controller library for the /bch route
*/ */
const { wlogger } = require('../../../adapters/wlogger') import wlogger from '../../../adapters/wlogger.js'
const config = require('../../../../config') import config from '../../../../config/index.js'
// let _this // let _this
@@ -739,4 +739,5 @@ class BchRESTControllerLib {
} }
} }
module.exports = BchRESTControllerLib // module.exports = BchRESTControllerLib
export default BchRESTControllerLib
+5 -4
View File
@@ -3,11 +3,11 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const BchRESTControllerLib = require('./controller') import BchRESTControllerLib from './controller.js'
const Validators = require('../middleware/validators') import Validators from '../middleware/validators.js'
let _this let _this
@@ -118,4 +118,5 @@ class BchRouter {
} }
} }
module.exports = BchRouter // module.exports = BchRouter
export default BchRouter
@@ -3,9 +3,9 @@
*/ */
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' import ContactLib from '../../../adapters/contact.js'
const ContactLib = require('../../../adapters/contact') process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
const contactLib = new ContactLib() const contactLib = new ContactLib()
let _this let _this
@@ -74,4 +74,4 @@ class ContactController {
} }
} }
} }
module.exports = ContactController export default ContactController
+3 -3
View File
@@ -3,10 +3,10 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const ContactRESTControllerLib = require('./controller') import ContactRESTControllerLib from './controller.js'
class ContactRouter { class ContactRouter {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -53,4 +53,4 @@ class ContactRouter {
} }
} }
module.exports = ContactRouter export default ContactRouter
+10 -10
View File
@@ -6,15 +6,15 @@
// Public npm libraries. // Public npm libraries.
// Load the REST API Controllers. // Local libraries
const AuthRESTController = require('./auth') import AuthRESTController from './auth/index.js'
const UserRouter = require('./users') import UserRouter from './users/index.js'
const ContactRESTController = require('./contact') import ContactRESTController from './contact/index.js'
const LogsRESTController = require('./logs') import LogsRESTController from './logs/index.js'
const BchRESTController = require('./bch') import BchRESTController from './bch/index.js'
const IpfsRESTController = require('./ipfs') import IpfsRESTController from './ipfs/index.js'
const P2wdbRESTController = require('./p2wdb') import P2wdbRESTController from './p2wdb/index.js'
const PriceRESTController = require('./price') import PriceRESTController from './price/index.js'
class RESTControllers { class RESTControllers {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -75,4 +75,4 @@ class RESTControllers {
} }
} }
module.exports = RESTControllers export default RESTControllers
+3 -2
View File
@@ -2,7 +2,7 @@
REST API Controller library for the /ipfs route REST API Controller library for the /ipfs route
*/ */
const { wlogger } = require('../../../adapters/wlogger') import wlogger from '../../../adapters/wlogger.js'
let _this let _this
@@ -95,4 +95,5 @@ class IpfsRESTControllerLib {
} }
} }
module.exports = IpfsRESTControllerLib // module.exports = IpfsRESTControllerLib
export default IpfsRESTControllerLib
+5 -4
View File
@@ -3,11 +3,11 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const IPFSRESTControllerLib = require('./controller') import IPFSRESTControllerLib from './controller.js'
const Validators = require('../middleware/validators') import Validators from '../middleware/validators.js'
// let _this // let _this
@@ -65,4 +65,5 @@ class BchRouter {
// } // }
} }
module.exports = BchRouter // module.exports = BchRouter
export default BchRouter
+2 -2
View File
@@ -1,4 +1,4 @@
const LogsApiLib = require('../../../adapters/logapi') import LogsApiLib from '../../../adapters/logapi.js'
const logsApiLib = new LogsApiLib() const logsApiLib = new LogsApiLib()
let _this let _this
@@ -62,4 +62,4 @@ class LogsApi {
} }
} }
module.exports = LogsApi export default LogsApi
+3 -3
View File
@@ -3,10 +3,10 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const LogsRESTControllerLib = require('./controller') import LogsRESTControllerLib from './controller.js'
class LogsRouter { class LogsRouter {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -52,4 +52,4 @@ class LogsRouter {
} }
} }
module.exports = LogsRouter export default LogsRouter
+2 -2
View File
@@ -1,4 +1,4 @@
module.exports = function errorMiddleware () { export default function errorMiddleware () {
return async (ctx, next) => { return async (ctx, next) => {
try { try {
await next() await next()
@@ -8,4 +8,4 @@ module.exports = function errorMiddleware () {
ctx.app.emit('error', err, ctx) ctx.app.emit('error', err, ctx)
} }
} }
} };
@@ -1,11 +1,24 @@
/* /*
REST API validator middleware. REST API validator middleware.
These are a series of functions that ensure the user making a REST API
matches a user in the database (or not). In can do fine-grain user control
such as telling the difference between an admin, a normal user, and an
anonymous user.
This middleware is used to gatekeep access to different REST API resources.
CT 9/17/22:
This library was lightly refactored to make it work with the new unit tests.
This not and the commented code below can be deleted once it is verified that
this refactor did not result in any breaking changes.
*/ */
const User = require('../../../adapters/localdb/models/users') import User from '../../../adapters/localdb/models/users.js'
const config = require('../../../../config')
const jwt = require('jsonwebtoken') import config from '../../../../config/index.js'
const { wlogger } = require('../../../adapters/wlogger') import jwt from 'jsonwebtoken'
import wlogger from '../../../adapters/wlogger.js'
let _this let _this
@@ -20,12 +33,10 @@ class Validators {
async ensureUser (ctx, next) { async ensureUser (ctx, next) {
try { try {
// console.log(`getToken: ${typeof (getToken)}`)
const token = _this.getToken(ctx) const token = _this.getToken(ctx)
if (!token) { if (!token) {
// console.log(`Err: Token not provided.`) throw new Error('Token could not be retrieved from header')
ctx.throw(401)
} }
let decoded = null let decoded = null
@@ -34,20 +45,23 @@ class Validators {
// console.log(`config: ${JSON.stringify(config, null, 2)}`) // console.log(`config: ${JSON.stringify(config, null, 2)}`)
decoded = _this.jwt.verify(token, config.token) decoded = _this.jwt.verify(token, config.token)
} catch (err) { } catch (err) {
// console.log(`Err: Token could not be decoded: ${err}`) throw new Error('Could not verify JWT')
ctx.throw(401)
} }
ctx.state.user = await _this.User.findById(decoded.id, '-password') ctx.state.user = await _this.User.findById(decoded.id, '-password')
if (!ctx.state.user) { if (!ctx.state.user) {
// console.log(`Err: Could not find user.`) // console.log('Err: Could not find user.')
ctx.throw(401) throw new Error('Could not find user')
} }
// return next() // return next()
return true return true
} catch (error) { } catch (error) {
ctx.throw(401) // console.log('Ensure user error: ', error)
// console.log('ctx: ', ctx)
ctx.status = 401
ctx.throw(401, error.message)
} }
} }
@@ -60,7 +74,8 @@ class Validators {
if (!token) { if (!token) {
// console.log(`Err: Token not provided.`) // console.log(`Err: Token not provided.`)
ctx.throw(401) // ctx.throw(401)
throw new Error('Token could not be retrieved from header')
} }
let decoded = null let decoded = null
@@ -70,22 +85,26 @@ class Validators {
decoded = _this.jwt.verify(token, config.token) decoded = _this.jwt.verify(token, config.token)
} catch (err) { } catch (err) {
// console.log(`Err: Token could not be decoded: ${err}`) // console.log(`Err: Token could not be decoded: ${err}`)
ctx.throw(401) // ctx.throw(401)
throw new Error('Could not verify JWT')
} }
ctx.state.user = await _this.User.findById(decoded.id, '-password') ctx.state.user = await _this.User.findById(decoded.id, '-password')
if (!ctx.state.user) { if (!ctx.state.user) {
// console.log(`Err: Could not find user.`) // console.log(`Err: Could not find user.`)
ctx.throw(401) // ctx.throw(401)
throw new Error('Could not find user')
} }
if (ctx.state.user.type !== 'admin') { if (ctx.state.user.type !== 'admin') {
ctx.throw(401, 'not admin') // ctx.throw(401, 'not admin')
throw new Error('User is not an admin')
} }
// return next() // return next()
return true return true
} catch (error) { } catch (error) {
ctx.status = 401
ctx.throw(401, error.message) ctx.throw(401, error.message)
} }
} }
@@ -101,7 +120,8 @@ class Validators {
if (!token) { if (!token) {
// console.log(`Err: Token not provided.`) // console.log(`Err: Token not provided.`)
ctx.throw(401) // ctx.throw(401)
throw new Error('Token could not be retrieved from header')
} }
// The user ID targeted in this API call. // The user ID targeted in this API call.
@@ -114,14 +134,16 @@ class Validators {
// console.log(`config: ${JSON.stringify(config, null, 2)}`) // console.log(`config: ${JSON.stringify(config, null, 2)}`)
decoded = _this.jwt.verify(token, config.token) decoded = _this.jwt.verify(token, config.token)
} catch (err) { } catch (err) {
// console.log(`Err: Token could not be decoded: ${err}`) console.log(`Err: Token could not be decoded: ${err}`)
ctx.throw(401) // ctx.throw(401)
throw new Error('Could not verify JWT')
} }
ctx.state.user = await _this.User.findById(decoded.id, '-password') ctx.state.user = await _this.User.findById(decoded.id, '-password')
if (!ctx.state.user) { if (!ctx.state.user) {
// console.log(`Err: Could not find user.`) // console.log(`Err: Could not find user.`)
ctx.throw(401) // ctx.throw(401)
throw new Error('Could not find user')
} }
// console.log('ctx.state.user: ', ctx.state.user) // console.log('ctx.state.user: ', ctx.state.user)
@@ -135,7 +157,8 @@ class Validators {
// If they don't match, then the calling user better be an admin. // If they don't match, then the calling user better be an admin.
if (ctx.state.user.type !== 'admin') { if (ctx.state.user.type !== 'admin') {
ctx.throw(401, 'not admin') // ctx.throw(401, 'not admin')
throw new Error('User is not an admin')
} else { } else {
wlogger.verbose("It's ok. The user is an admin.") wlogger.verbose("It's ok. The user is an admin.")
} }
@@ -144,6 +167,8 @@ class Validators {
// return next() // return next()
return true return true
} catch (error) { } catch (error) {
// console.log('Error in ensureTargetUserOrAdmin(): ', error)
ctx.status = 401
ctx.throw(401, error.message) ctx.throw(401, error.message)
} }
} }
@@ -166,4 +191,4 @@ class Validators {
} }
} }
module.exports = Validators export default Validators
+3 -2
View File
@@ -2,7 +2,7 @@
REST API Controller library for the /p2wdb route REST API Controller library for the /p2wdb route
*/ */
const { wlogger } = require('../../../adapters/wlogger') import wlogger from '../../../adapters/wlogger.js'
// let _this // let _this
@@ -135,4 +135,5 @@ class P2wdbRESTControllerLib {
} }
} }
module.exports = P2wdbRESTControllerLib // module.exports = P2wdbRESTControllerLib
export default P2wdbRESTControllerLib
+5 -4
View File
@@ -3,11 +3,11 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const P2wdbRESTControllerLib = require('./controller') import P2wdbRESTControllerLib from './controller.js'
const Validators = require('../middleware/validators') import Validators from '../middleware/validators.js'
let _this let _this
@@ -98,4 +98,5 @@ class P2wdbRouter {
// } // }
} }
module.exports = P2wdbRouter // module.exports = P2wdbRouter
export default P2wdbRouter
+4 -3
View File
@@ -2,8 +2,8 @@
REST API Controller library for the /bch route REST API Controller library for the /bch route
*/ */
const axios = require('axios') import axios from 'axios'
const { wlogger } = require('../../../adapters/wlogger') import wlogger from '../../../adapters/wlogger.js'
// let _this // let _this
@@ -105,4 +105,5 @@ class PriceRESTControllerLib {
} }
} }
module.exports = PriceRESTControllerLib // module.exports = PriceRESTControllerLib
export default PriceRESTControllerLib
+5 -4
View File
@@ -3,11 +3,11 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const PriceRESTControllerLib = require('./controller') import PriceRESTControllerLib from './controller.js'
const Validators = require('../middleware/validators') import Validators from '../middleware/validators.js'
let _this let _this
@@ -68,4 +68,5 @@ class PriceRouter {
} }
} }
module.exports = PriceRouter // module.exports = PriceRouter
export default PriceRouter
+5 -5
View File
@@ -2,7 +2,7 @@
REST API Controller library for the /user route REST API Controller library for the /user route
*/ */
const { wlogger } = require('../../../adapters/wlogger') import wlogger from '../../../adapters/wlogger.js'
let _this let _this
@@ -36,7 +36,7 @@ class UserRESTControllerLib {
* @apiGroup REST Users * @apiGroup REST Users
* *
* @apiExample Example usage: * @apiExample Example usage:
* curl -H "Content-Type: application/json" -X POST -d '{ "user": { "email": "email@format.com", "name": "my name", "password": "secretpasas" } }' localhost:5001/users * curl -H "Content-Type: application/json" -X POST -d '{ "user": { "email": "email@format.com", "name": "my name", "password": "secretpasas" } }' localhost:5010/users
* *
* @apiParam {Object} user User object (required) * @apiParam {Object} user User object (required)
* @apiParam {String} user.email Email * @apiParam {String} user.email Email
@@ -124,7 +124,7 @@ class UserRESTControllerLib {
ctx.body = { users } ctx.body = { users }
} catch (err) { } catch (err) {
wlogger.error('Error in users/controller.js/getUsers(): '.err) wlogger.error('Error in users/controller.js/getUsers(): ', err)
ctx.throw(422, err.message) ctx.throw(422, err.message)
} }
} }
@@ -136,7 +136,7 @@ class UserRESTControllerLib {
* @apiGroup REST Users * @apiGroup REST Users
* *
* @apiExample Example usage: * @apiExample Example usage:
* curl -H "Content-Type: application/json" -X GET localhost:5000/users/56bd1da600a526986cf65c80 * curl -H "Content-Type: application/json" -X GET localhost:5010/users/56bd1da600a526986cf65c80
* *
* @apiSuccess {Object} users User object * @apiSuccess {Object} users User object
* @apiSuccess {ObjectId} users._id User id * @apiSuccess {ObjectId} users._id User id
@@ -281,4 +281,4 @@ class UserRESTControllerLib {
} }
} }
module.exports = UserRESTControllerLib export default UserRESTControllerLib
+5 -4
View File
@@ -3,11 +3,12 @@
*/ */
// Public npm libraries. // Public npm libraries.
const Router = require('koa-router') import Router from 'koa-router'
// Local libraries. // Local libraries.
const UserRESTControllerLib = require('./controller') import UserRESTControllerLib from './controller.js'
const Validators = require('../middleware/validators')
import Validators from '../middleware/validators.js'
let _this let _this
@@ -85,4 +86,4 @@ class UserRouter {
} }
} }
module.exports = UserRouter export default UserRouter
+65
View File
@@ -0,0 +1,65 @@
/*
This Controller library is concerned with timer-based functions that are
kicked off periodicially.
*/
import config from '../../config/index.js'
class TimerControllers {
constructor (localConfig = {}) {
// Dependency Injection.
this.adapters = localConfig.adapters
if (!this.adapters) {
throw new Error(
'Instance of Adapters library required when instantiating Timer Controller libraries.'
)
}
this.useCases = localConfig.useCases
if (!this.useCases) {
throw new Error(
'Instance of Use Cases library required when instantiating Timer Controller libraries.'
)
}
this.debugLevel = localConfig.debugLevel
// Encapsulate dependencies
this.config = config
// Bind 'this' object to all subfunctions.
this.exampleTimerFunc = this.exampleTimerFunc.bind(this)
// this.startTimers()
}
// Start all the time-based controllers.
startTimers () {
// Any new timer control functions can be added here. They will be started
// when the server starts.
this.optimizeWalletHandle = setInterval(this.exampleTimerFunc, 60000 * 10)
return true
}
stopTimers () {
clearInterval(this.optimizeWalletHandle)
}
// Replace this example function with your own timer handler.
exampleTimerFunc (negativeTest) {
try {
console.log('Example timer controller executed.')
if (negativeTest) throw new Error('test error')
return true
} catch (err) {
console.error('Error in exampleTimerFunc(): ', err)
// Note: Do not throw an error. This is a top-level function.
return false
}
}
}
export default TimerControllers
+1 -1
View File
@@ -21,4 +21,4 @@ class User {
} }
} }
module.exports = User export default User
+2 -2
View File
@@ -4,7 +4,7 @@
https://troutsblog.com/blog/clean-architecture https://troutsblog.com/blog/clean-architecture
*/ */
const UserUseCases = require('./user') import UserUseCases from './user.js'
class UseCases { class UseCases {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -39,4 +39,4 @@ class UseCases {
} }
} }
module.exports = UseCases export default UseCases
+4 -3
View File
@@ -3,8 +3,9 @@
functions are called by the /user REST API endpoints. functions are called by the /user REST API endpoints.
*/ */
const UserEntity = require('../entities/user') import UserEntity from '../entities/user.js'
const { wlogger } = require('../adapters/wlogger')
import wlogger from '../adapters/wlogger.js'
class UserLib { class UserLib {
constructor (localConfig = {}) { constructor (localConfig = {}) {
@@ -181,4 +182,4 @@ class UserLib {
} }
} }
module.exports = UserLib export default UserLib
+9 -6
View File
@@ -5,15 +5,18 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const axios = require('axios').default
import axios from 'axios'
// const sinon = require('sinon') // const sinon = require('sinon')
// Local support libraries // Local support libraries
const config = require('../../../config') import config from '../../../config/index.js'
const Server = require('../../../bin/server')
const testUtils = require('../../utils/test-utils') import Server from '../../../bin/server.js'
const AdminLib = require('../../../src/adapters/admin') import testUtils from '../../utils/test-utils.js'
import AdminLib from '../../../src/adapters/admin.js'
const adminLib = new AdminLib() const adminLib = new AdminLib()
// const request = supertest.agent(app.listen()) // const request = supertest.agent(app.listen())
+16 -15
View File
@@ -1,21 +1,25 @@
const testUtils = require('../../utils/test-utils') import testUtils from '../../utils/test-utils.js'
const assert = require('chai').assert import { assert } from 'chai'
const config = require('../../../config') import config from '../../../config/index.js'
const axios = require('axios').default import axios from 'axios'
const sinon = require('sinon') import sinon from 'sinon'
import util from 'util'
const util = require('util') import UserController from '../../../src/controllers/rest-api/users/controller.js'
import Adapters from '../../../src/adapters/index.js'
import UseCases from '../../../src/use-cases/index.js'
// import UserController from '../../../src/controllers/rest-api/users/controller.js'
// import Adapters from '../../../src/adapters/index.js'
import EventEmitter from 'events'
util.inspect.defaultOptions = { depth: 1 } util.inspect.defaultOptions = { depth: 1 }
const LOCALHOST = `http://localhost:${config.port}` const LOCALHOST = `http://localhost:${config.port}`
const context = {} const context = {}
const UserController = require('../../../src/controllers/rest-api/users/controller')
const Adapters = require('../../../src/adapters')
const EventEmitter = require('events')
const adapters = new Adapters({ eventEmitter: new EventEmitter() }) const adapters = new Adapters({ eventEmitter: new EventEmitter() })
const UseCases = require('../../../src/use-cases/') // import UseCases from '../../../src/use-cases/index.js'
let uut let uut
let sandbox let sandbox
@@ -40,7 +44,7 @@ describe('Users', () => {
// Get the JWT used to log in as the admin 'system' user. // Get the JWT used to log in as the admin 'system' user.
const adminJWT = await testUtils.getAdminJWT() const adminJWT = await testUtils.getAdminJWT()
// console.log(`adminJWT: ${admi nJWT}`) console.log(`adminJWT: ${adminJWT}`)
context.adminJWT = adminJWT context.adminJWT = adminJWT
// const admin = await testUtils.loginAdminUser() // const admin = await testUtils.loginAdminUser()
@@ -72,9 +76,6 @@ describe('Users', () => {
await axios(options) await axios(options)
/* console.log(
`result stringified: ${JSON.stringify(result.data, null, 2)}`
) */
assert(false, 'Unexpected result') assert(false, 'Unexpected result')
} catch (err) { } catch (err) {
assert(err.response.status === 422, 'Error code 422 expected.') assert(err.response.status === 422, 'Error code 422 expected.')
+7 -7
View File
@@ -1,15 +1,15 @@
const config = require('../../../config') import config from '../../../config/index.js'
const axios = require('axios').default import axios from 'axios'
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
import { context as mockContext } from '../../unit/mocks/ctx-mock.js'
import ContactController from '../../../src/controllers/rest-api/contact/controller.js'
// Mock data // Mock data
// const mockData = require('./mocks/contact-mocks') // const mockData = require('./mocks/contact-mocks')
const LOCALHOST = `http://localhost:${config.port}` const LOCALHOST = `http://localhost:${config.port}`
const mockContext = require('../../unit/mocks/ctx-mock').context
const ContactController = require('../../../src/controllers/rest-api/contact/controller')
let uut let uut
let sandbox let sandbox
+7 -9
View File
@@ -1,17 +1,15 @@
const config = require('../../../config') import config from '../../../config/index.js'
const assert = require('chai').assert import { assert } from 'chai'
import axios from 'axios'
import sinon from 'sinon'
import util from 'util'
const axios = require('axios').default import LogsController from '../../../src/controllers/rest-api/logs/controller.js'
const sinon = require('sinon') import { context as mockContext } from '../../unit/mocks/ctx-mock.js'
const util = require('util')
util.inspect.defaultOptions = { depth: 1 } util.inspect.defaultOptions = { depth: 1 }
const LOCALHOST = `http://localhost:${config.port}` const LOCALHOST = `http://localhost:${config.port}`
const LogsController = require('../../../src/controllers/rest-api/logs/controller')
const mockContext = require('../../unit/mocks/ctx-mock').context
let sandbox let sandbox
let uut let uut
describe('LogsApi', () => { describe('LogsApi', () => {
@@ -1,12 +1,10 @@
const assert = require('chai').assert /*
const testUtils = require('../../utils/test-utils') import { assert } from 'chai';
import testUtils from '../../utils/test-utils.js';
const Validators = require('../../../src/controllers/rest-api/middleware/validators') import Validators from '../../../src/controllers/rest-api/middleware/validators.js';
import sinon from 'sinon';
const sinon = require('sinon') import { context as mockContext } from '../../unit/mocks/ctx-mock.js';
const mockContext = require('../../unit/mocks/ctx-mock').context import util from 'util';
const util = require('util')
util.inspect.defaultOptions = { depth: 1 } util.inspect.defaultOptions = { depth: 1 }
const context = {} const context = {}
@@ -303,3 +301,4 @@ describe('Validators', () => {
}) })
}) })
}) })
*/
+4 -7
View File
@@ -1,10 +1,7 @@
const assert = require('chai').assert import { assert } from 'chai'
import Admin from '../../../src/adapters/admin.js'
const Admin = require('../../../src/adapters/admin') import sinon from 'sinon'
import util from 'util'
const sinon = require('sinon')
const util = require('util')
util.inspect.defaultOptions = { depth: 1 } util.inspect.defaultOptions = { depth: 1 }
let sandbox let sandbox
+6 -3
View File
@@ -3,11 +3,12 @@
*/ */
// Global npm libraries // Global npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local libraries // Local libraries
const Adapters = require('../../../src/adapters') import Adapters from '../../../src/adapters/index.js'
describe('#adapters', () => { describe('#adapters', () => {
let uut, sandbox let uut, sandbox
@@ -26,6 +27,8 @@ describe('#adapters', () => {
it('should start the async adapters', async () => { it('should start the async adapters', async () => {
// Mock dependencies // Mock dependencies
uut.config.getJwtAtStartup = true uut.config.getJwtAtStartup = true
uut.config.useIpfs = true
uut.config.env = 'not-a-test'
sandbox.stub(uut.fullStackJwt, 'getJWT').resolves() sandbox.stub(uut.fullStackJwt, 'getJWT').resolves()
sandbox.stub(uut.fullStackJwt, 'instanceBchjs').resolves() sandbox.stub(uut.fullStackJwt, 'instanceBchjs').resolves()
sandbox.stub(uut.ipfs, 'start').resolves() sandbox.stub(uut.ipfs, 'start').resolves()
+8 -7
View File
@@ -5,19 +5,20 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
const EventEmitter = require('events') import EventEmitter from 'events'
const cloneDeep = require('lodash.clonedeep') import cloneDeep from 'lodash.clonedeep'
// Local support libraries // Local support libraries
// const testUtils = require('../../utils/test-utils') // const testUtils = require('../../utils/test-utils')
// Unit under test (uut) // Unit under test (uut)
const BchAdapter = require('../../../src/adapters/bch') import BchAdapter from '../../../src/adapters/bch/index.js'
const adapters = require('../mocks/adapters') import adapters from '../mocks/adapters/index.js'
import mockDataLib from '../mocks/use-cases/rest-api-mocks.js'
const eventEmitter = new EventEmitter() const eventEmitter = new EventEmitter()
const mockDataLib = require('../mocks/use-cases/rest-api-mocks')
describe('#bch-use-case', () => { describe('#bch-use-case', () => {
let uut let uut
+3 -4
View File
@@ -1,7 +1,6 @@
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
import ContactLib from '../../../src/adapters/contact.js'
const ContactLib = require('../../../src/adapters/contact')
let uut let uut
let sandbox let sandbox
@@ -3,10 +3,10 @@
*/ */
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const FullStackJWT = require('../../../src/adapters/fullstack-jwt') import sinon from 'sinon'
import FullStackJWT from '../../../src/adapters/fullstack-jwt.js'
describe('#FullStackJWT', () => { describe('#FullStackJWT', () => {
let sandbox let sandbox
+26 -11
View File
@@ -2,15 +2,15 @@
Unit tests for the IPFS Adapter. Unit tests for the IPFS Adapter.
*/ */
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
const cloneDeep = require('lodash.clonedeep') import cloneDeep from 'lodash.clonedeep'
import IPFSCoordAdapter from '../../../src/adapters/ipfs/ipfs-coord.js'
const IPFSCoordAdapter = require('../../../src/adapters/ipfs/ipfs-coord') // import IPFSMock from '../mocks/ipfs-mock.js'
const IPFSMock = require('../mocks/ipfs-mock') import create from '../mocks/ipfs-mock.js'
const IPFSCoordMock = require('../mocks/ipfs-coord-mock') import IPFSCoordMock from '../mocks/ipfs-coord-mock.js'
const config = require('../../../config') import config from '../../../config/index.js'
const mockDataLib = require('../mocks/adapters/ipfs-coord-mocks') import mockDataLib from '../mocks/adapters/ipfs-coord-mocks.js'
describe('#IPFS', () => { describe('#IPFS', () => {
let uut let uut
@@ -18,7 +18,7 @@ describe('#IPFS', () => {
let mockData let mockData
beforeEach(() => { beforeEach(() => {
const ipfs = IPFSMock.create() const ipfs = create()
uut = new IPFSCoordAdapter({ ipfs }) uut = new IPFSCoordAdapter({ ipfs })
sandbox = sinon.createSandbox() sandbox = sinon.createSandbox()
@@ -76,7 +76,7 @@ describe('#IPFS', () => {
it('should get the public IP address if this node is a Circuit Relay', async () => { it('should get the public IP address if this node is a Circuit Relay', async () => {
// Mock dependencies. // Mock dependencies.
uut.IpfsCoord = IPFSCoordMock uut.IpfsCoord = IPFSCoordMock
sandbox.stub(uut.publicIp, 'v4').returns('123') sandbox.stub(uut.publicIp, 'v4').resolves('123')
// Force Circuit Relay // Force Circuit Relay
uut.config.isCircuitRelay = true uut.config.isCircuitRelay = true
@@ -86,6 +86,21 @@ describe('#IPFS', () => {
assert.equal(result, true) assert.equal(result, true)
}) })
it('should exit quietly if this node is a Circuit Relay and there is an issue getting the IP address', async () => {
// Mock dependencies.
uut.IpfsCoord = IPFSCoordMock
sandbox.stub(uut.publicIp, 'v4').rejects(new Error('test error'))
// Force Circuit Relay
uut.config.isCircuitRelay = true
const result = await uut.start()
// console.log('result: ', result)
assert.equal(result, true)
})
it('should return a promise that resolves into an instance of IPFS in production mode', async () => { it('should return a promise that resolves into an instance of IPFS in production mode', async () => {
uut.config.isProduction = true uut.config.isProduction = true
// Mock dependencies. // Mock dependencies.
+12 -8
View File
@@ -2,20 +2,22 @@
Unit tests for the index.js file for the IPFS and ipfs-coord libraries. Unit tests for the index.js file for the IPFS and ipfs-coord libraries.
*/ */
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const IPFSLib = require('../../../src/adapters/ipfs') import sinon from 'sinon'
const IPFSMock = require('../mocks/ipfs-mock') import IPFSLib from '../../../src/adapters/ipfs/index.js'
const IPFSCoordMock = require('../mocks/ipfs-coord-mock') // import IPFSMock from '../mocks/ipfs-mock.js'
const EventEmitter = require('events') // import create from '../mocks/ipfs-mock.js'
import IPFSCoordMock from '../mocks/ipfs-coord-mock.js'
// import EventEmiter from 'events'
describe('#IPFS-adapter-index', () => { describe('#IPFS-adapter-index', () => {
let uut let uut
let sandbox let sandbox
beforeEach(() => { beforeEach(() => {
uut = new IPFSLib({ eventEmitter: new EventEmitter() }) // uut = new IPFSLib({ eventEmitter: new EventEmitter() })
uut = new IPFSLib({ })
sandbox = sinon.createSandbox() sandbox = sinon.createSandbox()
}) })
@@ -25,7 +27,9 @@ describe('#IPFS-adapter-index', () => {
describe('#start', () => { describe('#start', () => {
it('should return a promise that resolves into an instance of IPFS.', async () => { it('should return a promise that resolves into an instance of IPFS.', async () => {
// Mock dependencies. // Mock dependencies.
uut.ipfsAdapter = new IPFSMock() uut.ipfsAdapter = {
start: async () => {}
}
uut.IpfsCoordAdapter = IPFSCoordMock uut.IpfsCoordAdapter = IPFSCoordMock
const result = await uut.start() const result = await uut.start()
+9 -8
View File
@@ -2,11 +2,12 @@
Unit tests for the IPFS Adapter. Unit tests for the IPFS Adapter.
*/ */
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const IPFSLib = require('../../../src/adapters/ipfs/ipfs') import sinon from 'sinon'
const IPFSMock = require('../mocks/ipfs-mock') import IPFSLib from '../../../src/adapters/ipfs/ipfs.js'
const config = require('../../../config') import create from '../mocks/ipfs-mock.js'
import config from '../../../config/index.js'
// config.isProduction = true; // config.isProduction = true;
describe('#IPFS-adapter', () => { describe('#IPFS-adapter', () => {
@@ -44,7 +45,7 @@ describe('#IPFS-adapter', () => {
describe('#start', () => { describe('#start', () => {
it('should return a promise that resolves into an instance of IPFS.', async () => { it('should return a promise that resolves into an instance of IPFS.', async () => {
// Mock dependencies. // Mock dependencies.
uut.IPFS = IPFSMock uut.create = create
const result = await uut.start() const result = await uut.start()
// console.log('result: ', result) // console.log('result: ', result)
@@ -56,7 +57,7 @@ describe('#IPFS-adapter', () => {
it('should return a promise that resolves into an instance of IPFS in production mode.', async () => { it('should return a promise that resolves into an instance of IPFS in production mode.', async () => {
// Mock dependencies. // Mock dependencies.
uut.IPFS = IPFSMock uut.create = create
uut.config.isProduction = true uut.config.isProduction = true
const result = await uut.start() const result = await uut.start()
// console.log('result: ', result) // console.log('result: ', result)
@@ -69,7 +70,7 @@ describe('#IPFS-adapter', () => {
it('should catch and throw an error', async () => { it('should catch and throw an error', async () => {
try { try {
// Force an error // Force an error
sandbox.stub(uut.IPFS, 'create').rejects(new Error('test error')) sandbox.stub(uut, 'create').rejects(new Error('test error'))
await uut.start() await uut.start()
+10 -6
View File
@@ -1,11 +1,15 @@
const assert = require('chai').assert import { assert } from 'chai'
const fs = require('fs') import fs from 'fs'
const sinon = require('sinon') import sinon from 'sinon'
import util from 'util'
const util = require('util') import JsonFiles from '../../../src/adapters/json-files.js'
// Hack to get __dirname back.
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
import * as url from 'url'
util.inspect.defaultOptions = { depth: 1 } util.inspect.defaultOptions = { depth: 1 }
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const JsonFiles = require('../../../src/adapters/json-files')
const JSON_FILE = 'test-json-file.json' const JSON_FILE = 'test-json-file.json'
const JSON_PATH = `${__dirname.toString()}/${JSON_FILE}` const JSON_PATH = `${__dirname.toString()}/${JSON_FILE}`
+9 -6
View File
@@ -1,12 +1,15 @@
const assert = require('chai').assert import { assert } from 'chai'
import sinon from 'sinon'
import util from 'util'
const sinon = require('sinon') import LogsApiLib from '../../../src/adapters/logapi.js'
import mockData from '../mocks/log-api-mock.js'
const util = require('util') // Hack to get __dirname back.
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
import * as url from 'url'
util.inspect.defaultOptions = { depth: 1 } util.inspect.defaultOptions = { depth: 1 }
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const LogsApiLib = require('../../../src/adapters/logapi')
const mockData = require('../mocks/log-api-mock')
const context = {} const context = {}
let sandbox let sandbox
@@ -3,10 +3,10 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const NodeMailer = require('../../../src/adapters/nodemailer') import sinon from 'sinon'
import NodeMailer from '../../../src/adapters/nodemailer.js'
let sandbox let sandbox
let uut let uut
+3 -4
View File
@@ -1,7 +1,6 @@
const assert = require('chai').assert import { assert } from 'chai'
const PassportLib = require('../../../src/adapters/passport') import PassportLib from '../../../src/adapters/passport.js'
import sinon from 'sinon'
const sinon = require('sinon')
let uut let uut
let sandbox let sandbox
+7 -6
View File
@@ -2,16 +2,17 @@
Unit tests for the users Mongoose model. Unit tests for the users Mongoose model.
*/ */
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const mongoose = require('mongoose') import sinon from 'sinon'
import mongoose from 'mongoose'
import User from '../../../src/adapters/localdb/models/users.js'
import config from '../../../config/index.js'
// Set the environment variable to signal this is a test. // Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test' process.env.SVC_ENV = 'test'
const User = require('../../../src/adapters/localdb/models/users')
const config = require('../../../config')
describe('#User-Adapter', () => { describe('#User-Adapter', () => {
// let uut // let uut
let sandbox let sandbox
+3 -4
View File
@@ -1,7 +1,6 @@
const assert = require('chai').assert import { assert } from 'chai'
const { Wlogger } = require('../../../src/adapters/wlogger') import { Wlogger } from '../../../src/adapters/wlogger.js'
import sinon from 'sinon'
const sinon = require('sinon')
let uut let uut
let sandbox let sandbox
+5 -2
View File
@@ -4,9 +4,9 @@
// Public npm libraries // Public npm libraries
// const assert = require('chai').assert // const assert = require('chai').assert
const sinon = require('sinon') import sinon from 'sinon'
const Controllers = require('../../../src/controllers') import Controllers from '../../../src/controllers/index.js'
describe('#Controllers', () => { describe('#Controllers', () => {
let uut let uut
@@ -28,6 +28,9 @@ describe('#Controllers', () => {
attachRPCRouter: () => {} attachRPCRouter: () => {}
} }
// Mock the timer controllers
sandbox.stub(uut.timerControllers, 'startTimers').returns()
const app = { const app = {
use: () => {} use: () => {}
} }
+11 -9
View File
@@ -3,19 +3,21 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const jsonrpc = require('jsonrpc-lite')
const sinon = require('sinon') import jsonrpc from 'jsonrpc-lite'
const { v4: uid } = require('uuid') import sinon from 'sinon'
import { v4 as uid } from 'uuid'
// Local libraries.
import JSONRPC from '../../../../src/controllers/json-rpc/index.js'
import adapters from '../../mocks/adapters/index.js'
import UseCasesMock from '../../mocks/use-cases/index.js'
// Set the environment variable to signal this is a test. // Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test' process.env.SVC_ENV = 'test'
// Local libraries.
const JSONRPC = require('../../../../src/controllers/json-rpc')
const adapters = require('../../mocks/adapters')
const UseCasesMock = require('../../mocks/use-cases')
describe('#JSON RPC', () => { describe('#JSON RPC', () => {
let uut let uut
let sandbox let sandbox
@@ -5,18 +5,20 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
const sinon = require('sinon')
const assert = require('chai').assert import sinon from 'sinon'
const { v4: uid } = require('uuid') import { assert } from 'chai'
import { v4 as uid } from 'uuid'
// Local libraries
import Validators from '../../../../src/controllers/json-rpc/validators.js'
import adapters from '../../mocks/adapters/index.js'
// Set the environment variable to signal this is a test. // Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test' process.env.SVC_ENV = 'test'
// Local libraries
const Validators = require('../../../../src/controllers/json-rpc/validators')
const adapters = require('../../mocks/adapters')
describe('#validators', () => { describe('#validators', () => {
let uut let uut
let sandbox let sandbox
@@ -5,15 +5,16 @@
*/ */
// Public npm libraries // Public npm libraries
const sinon = require('sinon') import sinon from 'sinon'
const assert = require('chai').assert
import { assert } from 'chai'
// Local libraries
import RateLimit from '../../../../src/controllers/json-rpc/rate-limit.js'
// Set the environment variable to signal this is a test. // Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test' process.env.SVC_ENV = 'test'
// Local libraries
const RateLimit = require('../../../../src/controllers/json-rpc/rate-limit')
describe('#rate-limit', () => { describe('#rate-limit', () => {
let uut let uut
let sandbox let sandbox
@@ -3,11 +3,12 @@
*/ */
// Public npm libraries // Public npm libraries
const sinon = require('sinon') import sinon from 'sinon'
const assert = require('chai').assert
import { assert } from 'chai'
// Local libraries // Local libraries
const AboutRPC = require('../../../../src/controllers/json-rpc/about') import AboutRPC from '../../../../src/controllers/json-rpc/about/index.js'
describe('#AboutRPC', () => { describe('#AboutRPC', () => {
let uut let uut
@@ -3,20 +3,22 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
const sinon = require('sinon')
const assert = require('chai').assert import sinon from 'sinon'
const { v4: uid } = require('uuid') import { assert } from 'chai'
import { v4 as uid } from 'uuid'
// Local libraries
import AuthRPC from '../../../../src/controllers/json-rpc/auth/index.js'
import RateLimit from '../../../../src/controllers/json-rpc/rate-limit.js'
import adapters from '../../mocks/adapters/index.js'
import UseCasesMock from '../../mocks/use-cases/index.js'
// Set the environment variable to signal this is a test. // Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test' process.env.SVC_ENV = 'test'
// Local libraries
const AuthRPC = require('../../../../src/controllers/json-rpc/auth')
const RateLimit = require('../../../../src/controllers/json-rpc/rate-limit')
const adapters = require('../../mocks/adapters')
const UseCasesMock = require('../../mocks/use-cases')
describe('#AuthRPC', () => { describe('#AuthRPC', () => {
let uut let uut
let sandbox let sandbox
@@ -3,19 +3,21 @@
*/ */
// Public npm libraries // Public npm libraries
const jsonrpc = require('jsonrpc-lite') import jsonrpc from 'jsonrpc-lite'
const sinon = require('sinon')
const assert = require('chai').assert import sinon from 'sinon'
const { v4: uid } = require('uuid') import { assert } from 'chai'
import { v4 as uid } from 'uuid'
// Local libraries
import UserRPC from '../../../../src/controllers/json-rpc/users/index.js'
import adapters from '../../mocks/adapters/index.js'
import UseCasesMock from '../../mocks/use-cases/index.js'
// Set the environment variable to signal this is a test. // Set the environment variable to signal this is a test.
process.env.SVC_ENV = 'test' process.env.SVC_ENV = 'test'
// Local libraries
const UserRPC = require('../../../../src/controllers/json-rpc/users')
const adapters = require('../../mocks/adapters')
const UseCasesMock = require('../../mocks/use-cases')
describe('#UserRPC', () => { describe('#UserRPC', () => {
let uut let uut
let sandbox let sandbox
@@ -3,21 +3,25 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases')
import UseCasesMock from '../../../mocks/use-cases/index.js'
// const app = require('../../../mocks/app-mock') // const app = require('../../../mocks/app-mock')
const AuthRESTController = require('../../../../../src/controllers/rest-api/auth/controller') import AuthRESTController from '../../../../../src/controllers/rest-api/auth/controller.js'
import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
let uut let uut
let sandbox let sandbox
let ctx let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('#Auth-REST-Router', () => { describe('#Auth-REST-Router', () => {
// const testUser = {} // const testUser = {}
@@ -3,15 +3,19 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases')
import UseCasesMock from '../../../mocks/use-cases/index.js'
// const app = require('../../../mocks/app-mock') // const app = require('../../../mocks/app-mock')
const AuthRouter = require('../../../../../src/controllers/rest-api/auth') import AuthRouter from '../../../../../src/controllers/rest-api/auth/index.js'
let uut let uut
let sandbox let sandbox
// let ctx // let ctx
@@ -3,20 +3,21 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases') import UseCasesMock from '../../../mocks/use-cases/index.js'
const BchController = require('../../../../../src/controllers/rest-api/bch/controller') import BchController from '../../../../../src/controllers/rest-api/bch/controller.js'
// import { context } from '../../../../unit/mocks/ctx-mock.js'
// import blah '../../../../unit/mocks/ctx-mock.js'
// console.log('blah: ', blah)
let uut let uut
let sandbox let sandbox
let ctx let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('#BCH-REST-Controller', () => { describe('#BCH-REST-Controller', () => {
// const testUser = {} // const testUser = {}
@@ -27,7 +28,7 @@ describe('#BCH-REST-Controller', () => {
sandbox = sinon.createSandbox() sandbox = sinon.createSandbox()
// Mock the context object. // Mock the context object.
ctx = mockContext() // ctx = mockContext()
}) })
afterEach(() => sandbox.restore()) afterEach(() => sandbox.restore())
@@ -3,15 +3,15 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases') import UseCasesMock from '../../../mocks/use-cases/index.js'
// const app = require('../../../mocks/app-mock') // const app = require('../../../mocks/app-mock')
const BchRouter = require('../../../../../src/controllers/rest-api/bch') import BchRouter from '../../../../../src/controllers/rest-api/bch/index.js'
let uut let uut
let sandbox let sandbox
// let ctx // let ctx
@@ -3,16 +3,16 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const ContactController = require('../../../../../src/controllers/rest-api/contact/controller') import sinon from 'sinon'
import ContactController from '../../../../../src/controllers/rest-api/contact/controller.js'
import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
let uut let uut
let sandbox let sandbox
let ctx let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('Contact', () => { describe('Contact', () => {
before(async () => { before(async () => {
}) })
@@ -3,15 +3,19 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases')
import UseCasesMock from '../../../mocks/use-cases/index.js'
// const app = require('../../../mocks/app-mock') // const app = require('../../../mocks/app-mock')
const ContactRouter = require('../../../../../src/controllers/rest-api/contact') import ContactRouter from '../../../../../src/controllers/rest-api/contact/index.js'
let uut let uut
let sandbox let sandbox
// let ctx // let ctx
@@ -3,16 +3,16 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const LogsApiController = require('../../../../../src/controllers/rest-api/logs/controller') import sinon from 'sinon'
import LogsApiController from '../../../../../src/controllers/rest-api/logs/controller.js'
import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
let uut let uut
let sandbox let sandbox
let ctx let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('Logapi', () => { describe('Logapi', () => {
before(async () => { before(async () => {
}) })
@@ -3,15 +3,19 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases')
import UseCasesMock from '../../../mocks/use-cases/index.js'
// const app = require('../../../mocks/app-mock') // const app = require('../../../mocks/app-mock')
const LogsRouter = require('../../../../../src/controllers/rest-api/logs') import LogsRouter from '../../../../../src/controllers/rest-api/logs/index.js'
let uut let uut
let sandbox let sandbox
// let ctx // let ctx
@@ -0,0 +1,306 @@
/*
Unit tests for the REST API middleware that validates users.
*/
// Public npm libraries
import { assert } from 'chai'
import sinon from 'sinon'
// Local libraries
import Validators from '../../../../../src/controllers/rest-api/middleware/validators.js'
import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
describe('#Validators', () => {
let uut
let ctx
let sandbox
beforeEach(() => {
uut = new Validators()
// Mock the context object.
ctx = mockContext()
sandbox = sinon.createSandbox()
})
afterEach(() => sandbox.restore())
describe('#getToken', () => {
it('should return null if no header is provided', () => {
const result = uut.getToken(ctx)
assert.equal(result, null)
})
it('should return null if header is not in two parts', () => {
ctx.request.header.authorization = 'Bearer'
const result = uut.getToken(ctx)
assert.equal(result, null)
})
it('should return null if first part of header does not container the word bearer', () => {
ctx.request.header.authorization = 'some thing'
const result = uut.getToken(ctx)
assert.equal(result, null)
})
it('should return the JWT token from the header', () => {
const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzMjNiNTUwNzgxYWYzNTc4YzI0ZmU5YiIsImlhdCI6MTY2MzQ0NDczNCwiZXhwIjoxNjYzNTMxMTM0fQ.BY5sOfXc4z5axS98CdTfyqnO9y2wijOlwnv52rcvxHA'
ctx.request.header.authorization = `Bearer ${jwt}`
const result = uut.getToken(ctx)
assert.equal(result, jwt)
})
})
describe('#ensureUser', () => {
it('should throw error if token is not provided', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns()
await uut.ensureUser(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if token can not be verified', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
await uut.ensureUser(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if user can not be found in database', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves(false)
await uut.ensureUser(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should return true if the user is verified', async () => {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ user: 'alice' })
const result = await uut.ensureUser(ctx)
assert.equal(result, true)
})
})
describe('#ensureUser', () => {
it('should throw error if token is not provided', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns()
await uut.ensureAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if token can not be verified', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
await uut.ensureAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if user can not be found in database', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves(false)
await uut.ensureAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if user is not an admin', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ type: 'user' })
await uut.ensureAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should return true if the user is an admin', async () => {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ type: 'admin' })
const result = await uut.ensureAdmin(ctx)
assert.equal(result, true)
})
})
describe('#ensureTargetUserOrAdmin', () => {
it('should throw error if token is not provided', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns()
await uut.ensureTargetUserOrAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if token can not be verified', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
ctx.params = {
id: '456'
}
await uut.ensureTargetUserOrAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if user can not be found in database', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves(false)
ctx.params = {
id: '456'
}
await uut.ensureTargetUserOrAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error if user is not an admin', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ type: 'user' })
ctx.params = {
id: '456'
}
await uut.ensureTargetUserOrAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should throw error is user is not admin or target user', async () => {
try {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ type: 'user', _id: '123' })
ctx.params = {
id: '456'
}
await uut.ensureTargetUserOrAdmin(ctx)
assert.fail('Unexpected result')
} catch (err) {
assert.equal(ctx.status, 401)
}
})
it('should return true if the user is an admin', async () => {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ type: 'admin', _id: '123' })
ctx.params = {
id: '456'
}
const result = await uut.ensureTargetUserOrAdmin(ctx)
assert.equal(result, true)
})
it('should return true if the user is the target user', async () => {
// Mock dependencies and force desired code path
sandbox.stub(uut, 'getToken').returns('fake-jwt')
sandbox.stub(uut.jwt, 'verify').returns({})
sandbox.stub(uut.User, 'findById').resolves({ type: 'user', _id: '123' })
ctx.params = {
id: '123'
}
const result = await uut.ensureTargetUserOrAdmin(ctx)
assert.equal(result, true)
})
})
})
@@ -3,14 +3,17 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local libraries // Local libraries
const RESTControllers = require('../../../../src/controllers/rest-api/') import RESTControllers from '../../../../src/controllers/rest-api/index.js'
// const mockContext = require('../../../unit/mocks/ctx-mock').context // const mockContext = require('../../../unit/mocks/ctx-mock').context
const adapters = require('../../mocks/adapters') import adapters from '../../mocks/adapters/index.js'
const UseCasesMock = require('../../mocks/use-cases')
import UseCasesMock from '../../mocks/use-cases/index.js'
describe('#RESTControllers', () => { describe('#RESTControllers', () => {
let uut let uut
@@ -3,20 +3,19 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon') import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases') import UseCasesMock from '../../../mocks/use-cases/index.js'
import UserController from '../../../../../src/controllers/rest-api/users/controller.js'
const UserController = require('../../../../../src/controllers/rest-api/users/controller') import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
let uut let uut
let sandbox let sandbox
let ctx let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('#Users-REST-Controller', () => { describe('#Users-REST-Controller', () => {
// const testUser = {} // const testUser = {}
@@ -3,15 +3,19 @@
*/ */
// Public npm libraries // Public npm libraries
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
import sinon from 'sinon'
// Local support libraries // Local support libraries
const adapters = require('../../../mocks/adapters') import adapters from '../../../mocks/adapters/index.js'
const UseCasesMock = require('../../../mocks/use-cases')
import UseCasesMock from '../../../mocks/use-cases/index.js'
// const app = require('../../../mocks/app-mock') // const app = require('../../../mocks/app-mock')
const UserRouter = require('../../../../../src/controllers/rest-api/users') import UserRouter from '../../../../../src/controllers/rest-api/users/index.js'
let uut let uut
let sandbox let sandbox
// let ctx // let ctx
@@ -0,0 +1,82 @@
/*
Unit tests for the timer-controller.js Controller library
*/
// Public npm libraries
import { assert } from 'chai'
import sinon from 'sinon'
// Local libraries
import TimerControllers from '../../../src/controllers/timer-controllers.js'
import adapters from '../mocks/adapters/index.js'
import UseCasesMock from '../mocks/use-cases/index.js'
describe('#Timer-Controllers', () => {
let uut
let sandbox
beforeEach(() => {
sandbox = sinon.createSandbox()
const useCases = new UseCasesMock()
uut = new TimerControllers({ adapters, useCases })
})
afterEach(() => {
sandbox.restore()
uut.stopTimers()
})
describe('#constructor', () => {
it('should throw an error if adapters are not passed in', () => {
try {
uut = new TimerControllers()
assert.fail('Unexpected code path')
} catch (err) {
assert.include(
err.message,
'Instance of Adapters library required when instantiating Timer Controller libraries.'
)
}
})
it('should throw an error if useCases are not passed in', () => {
try {
uut = new TimerControllers({ adapters })
assert.fail('Unexpected code path')
} catch (err) {
assert.include(
err.message,
'Instance of Use Cases library required when instantiating Timer Controller libraries.'
)
}
})
})
describe('#startTimers', () => {
it('should start the timers', () => {
const result = uut.startTimers()
uut.stopTimers()
assert.equal(result, true)
})
})
describe('#exampleTimerFunc', () => {
it('should kick off the Use Case', async () => {
const result = await uut.exampleTimerFunc()
assert.equal(result, true)
})
it('should return false on error', async () => {
const result = await uut.exampleTimerFunc(true)
assert.equal(result, false)
})
})
})
+3 -3
View File
@@ -2,10 +2,10 @@
Unit tests for the User entity library. Unit tests for the User entity library.
*/ */
const assert = require('chai').assert import { assert } from 'chai'
const sinon = require('sinon')
const User = require('../../../src/entities/user') import sinon from 'sinon'
import User from '../../../src/entities/user.js'
let sandbox let sandbox
let uut let uut

Some files were not shown because too many files have changed in this diff Show More