0

To start, my stack :

  • MongoDB Native
  • NodeJS
  • Express
  • Mocha/Chai/Supertest
  • Passport for auth

My error :

I have "Error: Timeout of 100000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.".

This error appears only on the signin.test.ts file, and only on the first test of my file.

Example :

if my first test is signin user :

log test if signin user error

and if my first test is an other test (for example, test "user does not exist") :

log test if other first test error

This error also appears only when my test db is remote (mongodb atlas url for the connection). If my db is local, I have no error.

My code :

db.ts

import { MongoClient, Db } from 'mongodb'

let defaultDbname = 'DBProd'
const options = {}

let url: any = process.env.MONGODB_URI

if (process.env.NODE_ENV === 'dev') {
    url = process.env.MONGODB_URI
    defaultDbname = 'DBDev'
}

if (process.env.NODE_ENV === 'test') {
    url = process.env.MONGODB_URI_TEST
    defaultDbname = 'DBTest'
}

const client = new MongoClient(url, options)

export let db: Db

export const connect = async (dbName: string = defaultDbname) => {
    const conn = await client.connect()
    db = conn.db(dbName)
    console.log('Database connected')
    return client
}

In app.ts, call connect()

import { connect } from './database/db'
connect()
....

Part of my tests in signin.test.ts :

describe('POST /api/authentication/signin', function () {
    it('respond with 200, signin user', async function () {
        const res = await request(app)
            .post('/api/authentication/signin')
            .send({
                email: 'client@test.fr',
                password: 'Password123456789*'
            })
            .set('Accept', 'application/json')

        expect(res.statusCode).to.equal(200)
        expect(res.body.isAuthenticated).to.equal(true)
        expect(res.body.user.email).to.equal('client@test.fr')
        expect(res.body).to.have.property('token').to.be.an('string')
    })

    it('respond with 400, user does not exist', async function () {
        const res = await request(app)
            .post('/api/authentication/signin')
            .send({
                email: 'email@ttee.fr',
                password: 'Password123456789*'
            })
            .set('Accept', 'application/json')

        expect(res.statusCode).to.equal(400)
        expect(res.body.message).to.equal("L'utilisateur n'existe pas.")
    })

......

Passport local strategy in passport.config.ts

passport.use('local', new LocalStrategy({              
    usernameField: 'email',
    passwordField: 'password'
}, (username, password, done) => {
    if (!Validator.isValidEmail(username)) {
        return done(null, false, { message: 'Le format de l\'email est incorrect.' })
    }
    if (!Validator.isValidPassword(password)) {
        return done(null, false, { message: 'Votre mot de passe doit contenir au moins 8 caractères, une minuscule, une majuscule, un chiffre et un symbole spécial.' })
    }

    const getUser = async () => {
        try {
            const user = await db.collection('user').findOne({ email: username })
    
            if (!user) {
                return done(null, false, { message: 'L\'utilisateur n\'existe pas.' })
            }
    
            const userPassword = _.get(user, 'password')  
            const match = await comparePassword(password, userPassword)
    
            if (match) {
                done(null, user)
            } else {
                done(null, false, { message: 'Le mot de passe ne correspond pas.' })
            }
        } catch(err) {
            throw err
        }
    }

    getUser()
}))

signin.controller.ts

export const userSignIn = (req: Request, res: Response, next: NextFunction) => {
    passport.authenticate('local', { session: false }, async (err, user, info) => {
        if (err) {
            next(err)
        }

        if (!user) {
            return res.status(400).json({ message: info.message })
        }

        if (user) {
            const { _id, email, role } = user
            const token = signToken(_id)

            res.status(200).json({
                message: 'Authentification réussie.',
                isAuthenticated: true,
                user: {
                    email: email,
                    role: role
                },
                token
            })

            console.info('User signed in', user)
        }
    }
    )(req, res)
}

PS: I have "--timeout 10000" in cmd line.

0 Answers0