Get 404 http error when testing app with jest but work correctly when runnnig the app

56 Views Asked by At

I'm getting a 404 HTTP error for the second test (should return 200 on sign-in and login pages) when testing my app with the code below :

const request = require('supertest');
const express = require('express');

const app = require('../app');


// test jwt middleware
describe('jwt middleware', () => {
    it('should return 401 if no token provided', async () => {
        const res = await request(app).get('/income/category/')
        expect(res.statusCode).toBe(401)

    });
    it('should return 200 on sign-in and login pages', async () => {
        let res = await request(app).post('/user/sign-in/').send({username: "test", password: "test"})
        expect(res.statusCode).toBe(200)
        res = await request(app).post('/user/login/').send({username: "test", password: "test"})
        expect(res.statusCode).toBe(200)
    })
});

The thing I don't understand is that the app work correctly if I run it with *npm run dev *but when I run npm run test which run *"export NODE_ENV=test && jest --forceExit --runInBand" *it's broken.

Here is the route code for the user/sign-in and user/log-in :

const express = require('express');
const router = express.Router();
const {getDB} = require("../config/database");
const {hash, compare} = require("bcrypt");
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');

// get config vars
dotenv.config();

router.post('/sign-in', async (req, res) => {
    const db = getDB();
    // check username and password are provided
    if (!req.body.username || !req.body.password) {
        return res.status(400).json({message: "Username and password required."})
    }

    // check user doesn't already exist
    console.log(db)
    const user = await db.collection('user').findOne({username: req.body.username})
    if (user) {
        return res.status(409).json({message: "User already exists."})
    }

    try {
        // hash password
        const hashedPassword = await hash(req.body.password, 10)

        // insert user into database

        await db.collection('user').insertOne({
            username: req.body.username,
            password: hashedPassword
        })
    } catch (e) {
        return res.status(500).json({message: "Error creating user."})
    }
    // return response
    res.json({message: "User created."})
});


router.post('/login', async (req, res) => {
    const db = getDB();
    try {
        /*
            Check if the user exists in the database.
            If the user doesn't exist, return a 404 error
         */
        const user = await db.collection('user').findOne({username: req.body.username});
        if (!user) {
            return res.status(404).send('Cannot find user');
        }

        // Use bcrypt to compare the incoming password with the hashed password in the database
        if (await compare(req.body.password, user.password)) {
            res.json({token: jwt.sign({id: user['_id']}, process.env.TOKEN_SECRET, {expiresIn: '1800s'})});
        } else {
            res.json({message: 'Incorrect password'});
        }
    } catch (e) {
        res.status(500).send();
    }
});

module.exports = router;

I thought the problem was a wrong URL, but I get into my JWT middleware and the request URL is correct, so it returns next() :

const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');
// get config vars
dotenv.config();

module.exports = (req, res, next) => {
    // don't check for token on sign-in or login
    if (req.url === '/user/sign-in/' || req.url === '/user/login/') {
        return next()
    }

    // The user must be logged in to access any other route
    if (!req.headers['authorization']) {
        return res.status(401).json({message: "Unauthorized"})
    }

    // check token is valid
    const jwtToken = req.headers['authorization'];
    jwt.verify(jwtToken, process.env.TOKEN_SECRET, (err, user) => {
        if (err) return res.sendStatus(401)
        req.userId = user.id
        next()
    })
}
0

There are 0 best solutions below