Parcourir la source

Add db link to ws server. Better testing fn. Added db test

rigwild il y a 5 ans
Parent
commit
bf7c7c72b3

+ 9 - 5
server/database/controllers/Data.js

@@ -1,24 +1,28 @@
 'use strict'
 
 import DataModel from '../models/Data'
-import { dbLogger } from '../../../config'
+import { dbLogger, TEST_MODE } from '../../../config'
 import { formatLog } from '../../functions'
 
 export default class Data {
+  static log(data) {
+    if (!TEST_MODE) dbLogger.info(formatLog(data))
+  }
+
   static async add(dataObj) {
     const doc = await DataModel.create({ data: dataObj })
-    dbLogger.info(formatLog(`New document was added. id=${doc.id}`))
+    this.log(`New document was added. id=${doc.id}`)
     return doc
   }
 
   static async del(dataId) {
     const doc = await DataModel.findByIdAndDelete(dataId)
-    dbLogger.info(formatLog(`A document was deleted. id=${doc.id}`))
+    this.log(`A document was deleted. id=${doc.id}`)
   }
 
   static async update(dataId, newDataObj) {
-    const doc = await DataModel.findByIdAndUpdate(dataId, newDataObj, { new: true })
-    dbLogger.info(formatLog(`A document was updated. id=${doc.id}`))
+    const doc = await DataModel.findByIdAndUpdate(dataId, { $set: { data: newDataObj } }, { new: true })
+    this.log(`A document was updated. id=${doc.id}`)
     return doc
   }
 

+ 3 - 3
server/database/index.js

@@ -1,14 +1,14 @@
 'use strict'
 
 import mongoose from 'mongoose'
-import { mongoDatabaseURI, dbLogger } from '../../config'
+import { mongoDatabaseURI, dbLogger, TEST_MODE } from '../../config'
 import { formatLog, formatError } from '../functions'
 
 const connectDb = async () => {
-  await mongoose.connect(mongoDatabaseURI, { useNewUrlParser: true })
+  await mongoose.connect(mongoDatabaseURI, { useNewUrlParser: true, useFindAndModify: false })
   mongoose.connection.on('error', err => dbLogger.error(formatError(err)))
 
-  dbLogger.info(formatLog('The database connection was established.'))
+  if (!TEST_MODE) dbLogger.info(formatLog('The database connection was established.'))
 }
 
 export default connectDb

+ 2 - 3
server/webSocket/index.js

@@ -2,10 +2,9 @@
 
 import WebSocket from 'ws'
 import { formatLog, formatError } from '../functions'
-import { wsLogger } from '../../config'
+import { wsLogger, TEST_MODE } from '../../config'
 import messageHandler from './messageHandler'
 
-
 /**
  * @typedef {function} ErrorLogger
  * @param {Error} err an Error object
@@ -18,7 +17,7 @@ import messageHandler from './messageHandler'
  */
 export const errorHandler = ws => err => {
   ws.send(err.message)
-  wsLogger.error(formatError(err))
+  if (!TEST_MODE) wsLogger.error(formatError(err))
 }
 
 /**

+ 4 - 2
server/webSocket/messageHandler.js

@@ -1,7 +1,8 @@
 'use strict'
 
 import { formatLog } from '../functions'
-import { wsLogger } from '../../config'
+import { wsLogger, TEST_MODE } from '../../config'
+import DataController from '../database/controllers/Data'
 
 /**
  * @typedef {Function} MessageHandler
@@ -21,7 +22,8 @@ const messageHandler = ws => async data => {
     throw new Error('Invalid JSON data.')
   }
 
-  wsLogger.info(formatLog(json, 'message'))
+  await DataController.add(json)
+  if (!TEST_MODE) wsLogger.info(formatLog(json, 'message'))
   ws.send('ok')
 }
 

+ 33 - 7
test/api/_test_functions.js

@@ -2,9 +2,13 @@
 
 import path from 'path'
 import express from 'express'
+import WebSocket from 'ws'
 import serveStatic from 'serve-static'
 import routes from '../../server/routes'
 import { apiPrefix, imageServedUrl, imagesPath } from '../../config'
+import connectDb from '../../server/database'
+import { errorHandler as wsErrorHandler } from '../../server/webSocket'
+import wsMessageHandler from '../../server/webSocket/messageHandler'
 
 // Path to `test` directory
 export const testDir = path.resolve(__dirname, '..')
@@ -13,15 +17,25 @@ export const testDir = path.resolve(__dirname, '..')
 export const json = obj => 'JSON DATA : ' + (JSON.stringify(obj, null, 2) || obj)
 
 /**
- * Uses supertest to open an Express server on an ephemeral port.
+ * @typedef PluginConfig
+ * @property {boolean} [webSocket=false] should the server start with a WebSocket server
+ * @property {boolean} [database=false] should the server start with a WebSocket server
+ */
+/**
+ * Open an Express server not listening to any port.
  * The server serves images in `test/images`, all api routes and
  * uses a custom error handler (no logging to stdout).
  *
  * Using `request` (supertest) on this object will start the server
- *
+ * on an ephemeral port.
+ * @param {PluginConfig} plugins plugins that should be loaded with the server
  * @returns {object} an Express server
  */
-export const serve = () => {
+const serve = async (plugins = { webSocket: false, database: false }) => {
+  // Connect to db
+  if (plugins && plugins.database) await connectDb()
+
+  // Open a HTTP server
   const app = express()
   app.use(imageServedUrl, serveStatic(imagesPath))
   app.use(apiPrefix, routes)
@@ -31,10 +45,22 @@ export const serve = () => {
       data: err.data || undefined
     })
   })
+
+  // Open a WebSocket server
+  if (plugins && plugins.webSocket) {
+    const wss = new WebSocket.Server({ server: app })
+    wss.on('error', err => {
+      throw err
+    })
+    wss.on('connection', ws => {
+      ws.on('message', data => wsMessageHandler(ws)(data).catch(wsErrorHandler(ws)))
+      ws.on('error', wsErrorHandler(ws))
+    })
+  }
+
   return app
 }
 
-// Before each tests, start a server
-export const beforeEachTests = async t => {
-  t.context.server = serve()
-}
+// Pass a server to test context
+export const getTestServer = async (t, plugins) => (t.context.server = await serve(plugins))
+

+ 30 - 0
test/api/databaseWebSocket.js

@@ -0,0 +1,30 @@
+'use strict'
+
+import test from 'ava'
+import WebSocket from 'ws'
+import request from 'supertest'
+import { json, getTestServer } from './_test_functions'
+import DataController from '../../server/database/controllers/Data'
+
+// Database testing
+
+// Before all tests, connect to the database
+test.beforeEach(t => getTestServer(t, { database: true, webSocket: true }))
+
+test('Check database is working', async t => {
+  await request(t.context.server)
+
+  const testData = { test_database: 'add', test_database_obj: { msg: 'Hello world' } }
+  const doc = await DataController.add(testData)
+  t.deepEqual(doc.data, testData, json(doc))
+
+  const findDoc = await DataController.find(doc.id)
+  t.deepEqual(findDoc.data, testData, json(findDoc))
+
+  testData.test_database = 'updated'
+  const updateTo = { newObject: 'test', newProperties: { test: true } }
+  const docUpdated = await DataController.update(doc.id, updateTo)
+  t.deepEqual(docUpdated.data, updateTo, json(docUpdated))
+
+  t.notThrowsAsync(await DataController.del(doc.id))
+})

+ 2 - 2
test/api/getImage.js

@@ -3,12 +3,12 @@
 import test from 'ava'
 import request from 'supertest'
 import { apiPrefix, imageServedUrl } from '../../config'
-import { json, beforeEachTests } from './_test_functions'
+import { json, getTestServer } from './_test_functions'
 
 // ROUTE /getImage
 
 // Before each tests, start a server
-test.beforeEach(beforeEachTests)
+test.beforeEach(getTestServer)
 
 test('GET /getImage', async t => {
   const res = await request(t.context.server)

+ 3 - 3
test/api/getImageExtracts.js

@@ -6,12 +6,12 @@ import sharp from 'sharp'
 import fs from 'fs-extra'
 import path from 'path'
 import { apiPrefix, imageServedUrl, imagesPath } from '../../config'
-import { json, beforeEachTests } from './_test_functions'
+import { json, getTestServer } from './_test_functions'
 
 // ROUTE /getImageExtracts
 
 // Before each tests, start a server
-test.beforeEach(beforeEachTests)
+test.beforeEach(getTestServer)
 
 test('GET /getImageExtracts', async t => {
   const res = await request(t.context.server)
@@ -79,7 +79,7 @@ test.serial('GET /getImageExtracts?sceneName=bathroom&imageQuality=10&horizontal
   t.is(res2.header['content-type'], 'image/png', json(res2))
 })
 
-test.serial('Extracts were successfully generated', async t => {
+test.serial('Check extracts were successfully generated', async t => {
   // Check the extract on the file system
   const extracts = path.resolve(imagesPath, 'bathroom', 'extracts')
   const aBathroomConfig = path.resolve(extracts, 'x5_y2')

+ 2 - 2
test/api/listScenes.js

@@ -3,12 +3,12 @@
 import test from 'ava'
 import request from 'supertest'
 import { apiPrefix } from '../../config'
-import { json, beforeEachTests } from './_test_functions'
+import { json, getTestServer } from './_test_functions'
 
 // ROUTE /listScenes
 
 // Before each tests, start a server
-test.beforeEach(beforeEachTests)
+test.beforeEach(getTestServer)
 
 test('GET /listScenes', async t => {
   const res = await request(t.context.server)

+ 2 - 2
test/api/listScenesQualities.js

@@ -3,12 +3,12 @@
 import test from 'ava'
 import request from 'supertest'
 import { apiPrefix } from '../../config'
-import { json, beforeEachTests } from './_test_functions'
+import { json, getTestServer } from './_test_functions'
 
 // ROUTE /listSceneQualities
 
 // Before each tests, start a server
-test.beforeEach(beforeEachTests)
+test.beforeEach(getTestServer)
 
 test('GET /listSceneQualities', async t => {
   const res = await request(t.context.server)