Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aelassas committed Feb 17, 2024
1 parent 1ec3616 commit 9aefb6c
Show file tree
Hide file tree
Showing 20 changed files with 5,884 additions and 3,135 deletions.
5 changes: 3 additions & 2 deletions api/.babelrc.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"presets": [
[
"@babel/env",
"@babel/preset-env",
{
"modules": false,
"targets": {
"node": "current"
}
}
]
],
"@babel/preset-typescript"
],
"plugins": [
"add-import-extension"
Expand Down
1 change: 0 additions & 1 deletion api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ MI_SMTP_PORT=587
MI_SMTP_USER=USER
MI_SMTP_PASS=PASS
MI_SMTP_FROM=no-reply@movinin.com
MI_ADMIN_EMAIL=admin@movinin.com
MI_CDN_USERS=/var/www/cdn/movinin/users
MI_CDN_TEMP_USERS=/var/www/cdn/movinin/temp/users
MI_CDN_PROPERTIES=/var/www/cdn/movinin/properties
Expand Down
12 changes: 12 additions & 0 deletions api/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const config = {
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
testEnvironment: 'node',
extensionsToTreatAsEsm: ['.ts'],
roots: [
'./tests/',
],
}

export default config
8,354 changes: 5,276 additions & 3,078 deletions api/package-lock.json

Large diffs are not rendered by default.

16 changes: 13 additions & 3 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"type": "module",
"scripts": {
"dev": "nodemon",
"build": "rimraf ./dist && tsc && babel dist -d dist",
"build": "rimraf dist && tsc && babel dist -d dist",
"start": "npm run build && node dist",
"test": "cross-env NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest",
"lint": "eslint --ext .ts .",
"ncu": "ncu -u"
},
Expand All @@ -26,37 +27,46 @@
},
"dependencies": {
"@babel/cli": "^7.23.9",
"@babel/core": "^7.23.9",
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
"@babel/preset-env": "^7.23.9",
"@babel/preset-typescript": "^7.23.3",
"@types/bcrypt": "^5.0.2",
"@types/compression": "^1.7.5",
"@types/cookie-parser": "^1.4.6",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.12",
"@types/jsonwebtoken": "^9.0.5",
"@types/multer": "^1.4.11",
"@types/node": "^20.11.10",
"@types/nodemailer": "^6.4.14",
"@types/supertest": "^6.0.2",
"@types/uuid": "^9.0.8",
"@types/validator": "^13.11.8",
"babel-jest": "^29.7.0",
"babel-plugin-add-import-extension": "^1.6.0",
"bcrypt": "^5.1.1",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dotenv": "^16.4.1",
"escape-string-regexp": "^5.0.0",
"expo-server-sdk": "^3.7.0",
"express": "^4.18.2",
"helmet": "^7.1.0",
"jest": "^29.7.0",
"jsonwebtoken": "^9.0.2",
"localized-strings": "^0.2.4",
"mongoose": "^8.1.1",
"movinin-helper": "file:../packages/movinin-helper",
"movinin-types": "file:../packages/movinin-types",
"movinin-helper": "file:.packages/movinin-helper",
"movinin-types": "file:.packages/movinin-types",
"multer": "^1.4.5-lts.1",
"nocache": "^4.0.0",
"nodemailer": "^6.9.8",
"rimraf": "^5.0.5",
"supertest": "^6.3.4",
"typescript": "^5.3.3",
"uuid": "^9.0.1",
"validator": "^13.11.0"
Expand Down
19 changes: 0 additions & 19 deletions api/src/server.ts → api/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import express, { Express } from 'express'
import mongoose, { ConnectOptions } from 'mongoose'
import compression from 'compression'
import helmet from 'helmet'
import nocache from 'nocache'
Expand All @@ -15,24 +14,6 @@ import notificationRoutes from './routes/notificationRoutes'
import propertyRoutes from './routes/propertyRoutes'
import userRoutes from './routes/userRoutes'

let options: ConnectOptions = {}
if (env.DB_SSL) {
options = {
tls: true,
tlsCertificateKeyFile: env.DB_SSL_CERT,
tlsCAFile: env.DB_SSL_CA,
}
}

mongoose.set('debug', env.DB_DEBUG)
mongoose.Promise = globalThis.Promise
try {
await mongoose.connect(env.DB_URI, options)
console.log('Database is connected')
} catch (err) {
console.error('Cannot connect to the database:', err)
}

const app: Express = express()

app.use(helmet.contentSecurityPolicy())
Expand Down
44 changes: 44 additions & 0 deletions api/src/common/DatabaseHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import mongoose, { ConnectOptions } from 'mongoose'
import * as env from '../config/env.config'

/**
* Connect to database
*
* @export
* @async
* @param {boolean} debug
* @returns {Promise<boolean>}
*/
export async function Connect(debug: boolean): Promise<boolean> {
let options: ConnectOptions = {}
if (env.DB_SSL) {
options = {
tls: true,
tlsCertificateKeyFile: env.DB_SSL_CERT,
tlsCAFile: env.DB_SSL_CA,
}
}

mongoose.set('debug', debug)
mongoose.Promise = globalThis.Promise
try {
await mongoose.connect(env.DB_URI, options)
console.log('Database is connected')
return true
} catch (err) {
console.error('Cannot connect to the database:', err)
return false
}
}

/**
* Close database connection
*
* @export
* @async
* @param {boolean} force
* @returns {*}
*/
export async function Close(force: boolean): Promise<void> {
await mongoose.connection.close(force)
}
17 changes: 15 additions & 2 deletions api/src/common/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,20 @@ export function isFrontend(req: Request): boolean {
/**
* Get authentification cookie name.
*
* @param {?boolean} backend
* @param {Request} req
* @returns {string}
*/
export const getAuthCookieName = (req: Request): string => (isBackend(req) ? env.BACKEND_AUTH_COOKIE_NAME : env.FRONTEND_AUTH_COOKIE_NAME)
export const getAuthCookieName = (req: Request): string => {
if (isBackend(req)) {
// Backend auth cookie name
return env.BACKEND_AUTH_COOKIE_NAME
}

if (isFrontend(req)) {
// Frontend auth cookie name
return env.FRONTEND_AUTH_COOKIE_NAME
}

// Mobile app and unit tests auth header name
return env.X_ACCESS_TOKEN
}
7 changes: 7 additions & 0 deletions api/src/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ export const FRONTEND_AUTH_COOKIE_NAME = 'mi-x-access-token-frontend'
*/
export const BACKEND_AUTH_COOKIE_NAME = 'mi-x-access-token-backend'

/**
* Mobile App and unit tests authentication header name.
*
* @type {"x-access-token"}
*/
export const X_ACCESS_TOKEN = 'x-access-token'

/**
* JWT secret. It should at least be 32 characters long, but the longer the better.
*
Expand Down
3 changes: 1 addition & 2 deletions api/src/controllers/propertyController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export async function update(req: Request, res: Response) {
}

await property.save()
return res.sendStatus(200)
return res.json(property)
}

console.error('[property.update] Property not found:', _id)
Expand Down Expand Up @@ -352,7 +352,6 @@ export async function uploadImage(req: Request, res: Response) {
}

const filename = `${Helper.getFilenameWithoutExtension(req.file.originalname)}_${uuid()}_${Date.now()}${path.extname(req.file.originalname)}`
console.log(filename)
const filepath = path.join(env.CDN_TEMP_PROPERTIES, filename)

await fs.writeFile(filepath, req.file.buffer)
Expand Down
56 changes: 29 additions & 27 deletions api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,37 @@ import process from 'node:process'
import fs from 'node:fs/promises'
import http from 'node:http'
import https from 'node:https'
import mongoose from 'mongoose'
import app from './server'
import app from './app'
import * as DatabaseHelper from './common/DatabaseHelper'
import * as env from './config/env.config'

let server: http.Server | https.Server
if (env.HTTPS) {
https.globalAgent.maxSockets = Number.POSITIVE_INFINITY
const privateKey = await fs.readFile(env.PRIVATE_KEY, 'utf8')
const certificate = await fs.readFile(env.CERTIFICATE, 'utf8')
const credentials = { key: privateKey, cert: certificate }
server = https.createServer(credentials, app)
if (await DatabaseHelper.Connect(env.DB_DEBUG)) {
let server: http.Server | https.Server
if (env.HTTPS) {
https.globalAgent.maxSockets = Number.POSITIVE_INFINITY
const privateKey = await fs.readFile(env.PRIVATE_KEY, 'utf8')
const certificate = await fs.readFile(env.CERTIFICATE, 'utf8')
const credentials = { key: privateKey, cert: certificate }
server = https.createServer(credentials, app)

server.listen(env.PORT, () => {
console.log('HTTPS server is running on Port', env.PORT)
})
} else {
server = app.listen(env.PORT, () => {
console.log('HTTP server is running on Port', env.PORT)
})
}
server.listen(env.PORT, () => {
console.log('HTTPS server is running on Port', env.PORT)
})
} else {
server = app.listen(env.PORT, () => {
console.log('HTTP server is running on Port', env.PORT)
})
}

const close = () => {
console.log('\nGracefully stopping...')
server.close(async () => {
console.log(`HTTP${env.HTTPS ? 'S' : ''} server closed`)
await mongoose.connection.close(true)
console.log('MongoDB connection closed')
process.exit(0)
})
}
const close = () => {
console.log('\nGracefully stopping...')
server.close(async () => {
console.log(`HTTP${env.HTTPS ? 'S' : ''} server closed`)
await DatabaseHelper.Close(true)
console.log('MongoDB connection closed')
process.exit(0)
})
}

['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => process.on(signal, close))
['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => process.on(signal, close))
}
Loading

0 comments on commit 9aefb6c

Please sign in to comment.