diff --git a/src/lib/admin.js b/src/lib/admin.js index e92b09b..7c8f3e7 100644 --- a/src/lib/admin.js +++ b/src/lib/admin.js @@ -13,8 +13,9 @@ const axios = require('axios').default const mongoose = require('mongoose') const User = require('../models/users') -const jsonFiles = require('./utils/json-files') const config = require('../../config') +const JsonFiles = require('./utils/json-files') +const jsonFiles = new JsonFiles() const JSON_FILE = `system-user-${config.env}.json` const JSON_PATH = `${__dirname}/../../config/${JSON_FILE}` diff --git a/src/lib/utils/json-files.js b/src/lib/utils/json-files.js index 1e882b4..1c8031c 100644 --- a/src/lib/utils/json-files.js +++ b/src/lib/utils/json-files.js @@ -1,61 +1,75 @@ /* A utility file for reading and writing JSON files. */ - 'use strict' - const fs = require('fs') -// Writes out a JSON file of any object passed to the function. -// This is used for testing. -function writeJSON (obj, fileName) { - return new Promise(function (resolve, reject) { - try { - const fileStr = JSON.stringify(obj, null, 2) +let _this - fs.writeFile(fileName, fileStr, function (err) { - if (err) { - console.error('Error while trying to write file: ', err) - return reject(err) - } else { - // console.log(`${fileName} written successfully!`) - return resolve() +class JsonFiles { + constructor () { + this.fs = fs + + _this = this + } + + // Writes out a JSON file of any object passed to the function. + // This is used for testing. + writeJSON (obj, fileName) { + return new Promise(function (resolve, reject) { + try { + if (!obj) { + throw new Error('obj property is required') } - }) - } catch (err) { - console.error('Error trying to write out object in util.js/_writeJSON().', err) - return reject(err) - } - }) -} + if (!fileName || typeof fileName !== 'string') { + throw new Error('fileName property must be a string') + } + const fileStr = JSON.stringify(obj, null, 2) -// Read and parse a JSON file. -function readJSON (fileName) { - return new Promise(function (resolve, reject) { - try { - fs.readFile(fileName, (err, data) => { - if (err) { - if (err.code === 'ENOENT') { - console.log('Admin .json file not found!') + _this.fs.writeFile(fileName, fileStr, function (err) { + if (err) { + console.error('Error while trying to write file: ') + throw err } else { - console.log(`err: ${JSON.stringify(err, null, 2)}`) + // console.log(`${fileName} written successfully!`) + return resolve() + } + }) + } catch (err) { + console.error('Error trying to write out object in util.js/_writeJSON().') + return reject(err) + } + }) + } + + readJSON (fileName) { + return new Promise(function (resolve, reject) { + try { + if (!fileName || typeof fileName !== 'string') { + throw new Error('fileName property must be a string') + } + + _this.fs.readFile(fileName, (err, data) => { + if (err) { + if (err.code === 'ENOENT') { + console.log('Admin .json file not found!') + } else { + console.log(`err: ${JSON.stringify(err, null, 2)}`) + } + + throw err } - return reject(err) - } + const obj = JSON.parse(data) - const obj = JSON.parse(data) - - return resolve(obj) - }) - } catch (err) { - console.error('Error trying to read JSON file in util.js/_readJSON().', err) - return reject(err) - } - }) + return resolve(obj) + }) + } catch (err) { + console.error('Error trying to read JSON file in util.js/_readJSON().') + return reject(err) + } + }) + } } -module.exports = { - writeJSON, - readJSON -} +module.exports = JsonFiles diff --git a/test/a07-json-files.spec.js b/test/a07-json-files.spec.js new file mode 100644 index 0000000..850cf76 --- /dev/null +++ b/test/a07-json-files.spec.js @@ -0,0 +1,139 @@ +const assert = require('chai').assert +const fs = require('fs') +const sinon = require('sinon') + +const util = require('util') +util.inspect.defaultOptions = { depth: 1 } + +const JsonFiles = require('../src/lib/utils/json-files') + +const JSON_FILE = 'test-json-file.json' +const JSON_PATH = `${__dirname}/${JSON_FILE}` + +const deleteFile = filepath => { + try { + // Delete state if exist + fs.unlinkSync(filepath) + } catch (error) {} +} +let sandbox +let uut +describe('JsonFiles', () => { + const obj = { + json: 'file' + } + beforeEach(() => { + uut = new JsonFiles() + sandbox = sinon.createSandbox() + }) + afterEach(() => sandbox.restore()) + + after(() => { + deleteFile(JSON_PATH) + }) + describe('writeJSON()', () => { + it('should throw error if inputs is not provided', async () => { + try { + await uut.writeJSON() + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'obj property is required') + } + }) + it('should throw error if filename property is not provided', async () => { + try { + await uut.writeJSON(obj) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'fileName property must be a string') + } + }) + it('should throw error if filename property is not string', async () => { + try { + await uut.writeJSON(obj, 1) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'fileName property must be a string') + } + }) + it('should throw error if fs library return an error', async () => { + try { + // https://sinonjs.org/releases/latest/stubs/ + // About yields + sandbox.stub(uut.fs, 'writeFile').yields(new Error('test error')) + + await uut.writeJSON(obj, JSON_PATH) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'test error') + } + }) + it('should write a json file', async () => { + try { + await uut.writeJSON(obj, JSON_PATH) + + assert.isTrue(fs.existsSync(JSON_PATH)) + } catch (err) { + assert(false, 'Unexpected result') + } + }) + }) + + describe('readJSON()', () => { + it('should throw error if filename property is not provided', async () => { + try { + await uut.readJSON(obj) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'fileName property must be a string') + } + }) + it('should throw error if filename property is not string', async () => { + try { + await uut.readJSON(obj, 1) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'fileName property must be a string') + } + }) + it('should throw error if fs library return an error', async () => { + try { + // https://sinonjs.org/releases/latest/stubs/ + // About yields + sandbox.stub(uut.fs, 'readFile').yields(new Error('test error')) + + await uut.readJSON(JSON_PATH) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'test error') + } + }) + it('should throw error if file not found', async () => { + try { + const testError = new Error('test error') + testError.code = 'ENOENT' + + sandbox.stub(uut.fs, 'readFile').yields(testError) + + await uut.readJSON(JSON_PATH) + assert(false, 'Unexpected result') + } catch (err) { + assert.include(err.message, 'test error') + } + }) + + it('should read a json file', async () => { + try { + const result = await uut.readJSON(JSON_PATH) + + const objKeys = Object.keys(obj) + const resultKeys = Object.keys(result) + + assert.isObject(result) + assert.equal(objKeys.length, resultKeys.length) + } catch (err) { + assert(false, 'Unexpected result') + } + }) + }) +})