node.js – Mocha after all hook throwing error but functioning correctly – Uncaught Reference error

I am new to testing, and I am using Mocha, Chai and Supertest to write unit tests for my ExpressJS application. My tests are all working – even the hooks that throw errors are functioning as expected, which is why I am so confused.

I am getting the error Uncaught ReferenceError: deleted is not defined for both my after hooks. The hooks are supposed to delete accounts made for the tests in the database – and they are doing that. All the other tests pass without any errors.

Here is my code

const server = require('../src/server.js');
const request = require('supertest');
const chai = require('chai');
const expect = chai.expect;

const existingUser = {
  username: 'supertest-test',
  password: 'b1gl3g3nd',
  email: 'supertest-test@example.com',
  name: 'Supertest Test'
};

describe('User endpoints', () => {
  before('setup test user', async () => {
    const res = await request(server)
      .post('/register')
      .set('Accept', 'application/json')
      .send(existingUser);
    expect(res.status).to.equal(302);
    expect(res.headers['location']).to.equal('/profile');
  });

  after('delete test user', (done) => {
    const agent = request.agent(server);

    agent
      .post('/login')
      .set('Accept', 'application/json')
      .send({ username: existingUser.username, password: existingUser.password })
      .end((err, res) => {
        if (err) {
          return done(err);
        }
        agent
          .delete('/profile')
          .set('Accept', 'application/json')
          .send()
          .expect(200)
          .end((err, res) => {
            if (err) {
              return done(err);
            }
            expect(res.body.info).to.be.equal(`Deleted user ${existingUser.username}`);
            return done();
          });
      });
  });

  // register user
  describe('POST /register', () => {
    const newUser = {
      username: 'test',
      password: 'b1gl3g3nd',
      email: 'test@example.com',
      name: 'Test Account'
    };

    after('delete register test user', (done) => {
      const agent = request.agent(server);

      agent
        .post('/login')
        .set('Accept', 'application/json')
        .send({ username: newUser.username, password: newUser.password })
        .end((err, res) => {
          if (err) {
            return done(err);
          }
          agent
            .delete('/profile')
            .set('Accept', 'application/json')
            .send()
            .expect(200)
            .end((err, res) => {
              if (err) {
                return done(err);
              }
              expect(res.body.info).to.be.equal(`Deleted user ${newUser.username}`);
              return done();
            });
        });
    });

    describe('failure', () => {
      it('return 403 when username already in use', async () => {
        const res = await request(server)
          .post('/register')
          .set('Accept', 'application/json')
          .send(existingUser);
        expect(res.headers['content-type']).to.match(/json/);
        expect(res.status).to.equal(403);
        expect(res.body.error).to.equal('Username already exists');
      });

      it('return 403 when email already in use', async () => {
        const res = await request(server)
          .post('/register')
          .set('Accept', 'application/json')
          .send({...existingUser, username: 'test-new'});
        expect(res.headers['content-type']).to.match(/json/);
        expect(res.status).to.equal(403);
        expect(res.body.error).to.equal('Email already in use');
      });

      it('return 500 when creating user with invalid body', async () => {
        const res = await request(server)
          .post('/register')
          .set('Accept', 'application/json')
          .send({ username: 'asd', email: 'sfqs', name: 's' });
        expect(res.headers['content-type']).to.match(/json/);
        expect(res.status).to.equal(500);
        expect(res.body.error).to.be.not.null;
      });

      it('return 500 when creating user with an empty body', async () => {
        const res = await request(server)
          .post('/register')
          .set('Accept', 'application/json')
          .send({});
        expect(res.headers['content-type']).to.match(/json/);
        expect(res.status).to.equal(500);
        expect(res.body.error).to.be.not.null;
      });
    });

    describe('success', () => {
      it('redirect to /profile', async () => {
        const res = await request(server)
          .post('/register')
          .set('Accept', 'application/json')
          .send(newUser);
        expect(res.status).to.equal(302);
        expect(res.headers['location']).to.equal('/profile');
      });
    });
  });

  // login
  describe('GET /login', () => {
    it('return 200 saying to login with post', async () => {
      const res = await request(server)
        .get('/login')
        .set('Accept', 'application/json');
      expect(res.headers['content-type']).to.match(/json/);
      expect(res.status).to.equal(200);
      expect(res.body.info).to.equal('Login with POST');
    });
  });

  describe('POST /login', () => {
    describe('failure', () => {
      it('return 400 and error message when giving no credentials', async () => {
        const res = await request(server)
          .post('/login')
          .set('Accept', 'application/json')
          .send({});
        expect(res.status).to.equal(302);
        // passport redirects to 'login' header is set to that not '/login'
        expect(res.headers['location']).to.equal('login');
        expect(res.body.error).to.not.be.null;
      });

      it('return 400 and error message when using invalid credentials', async () => {
        const res = await request(server)
          .post('/login')
          .set('Accept', 'application/json')
          .send({ username: 'doesnotexist', password: 'totallywrongpassword' });
        expect(res.status).to.equal(302);
        // passport redirects to 'login' header is set to that not '/login'
        expect(res.headers['location']).to.equal('login');
        expect(res.body.error).to.not.be.null;
      });

      it('return 401 if already logged in', (done) => {
        const agent = request.agent(server);

        agent
          .post('/login')
          .set('Accept', 'application/json')
          .send({ username: existingUser.username, password: existingUser.password })
          .end((err, res) => {
            if (err) {
              return done(err);
            }
            agent
              .post('/login')
              .set('Accept', 'application/json')
              .send({ username: existingUser.username, password: existingUser.password })
              .expect(401)
              .end((err, res) => {
                if (err) {
                  return done(err);
                }
                expect(res.body.error).to.equal('Already logged in');
                return done()
              });
          });
      });
    });

    describe('success', () => {
      it('redirect to /profile', async () => {
        const res = await request(server)
          .post('/login')
          .set('Accept', 'application/json')
          .send({ username: existingUser.username, password: existingUser.password });
        expect(res.status).to.equal(302);
        expect(res.headers['location']).to.equal('/profile');
      });
    });
  });
});

This is the output of npm test:

> epstore@1.0.0 test
> cross-env NODE_ENV=test mocha --exit



  User endpoints
    POST /register
      failure
        ✔ return 403 when username already in use
        ✔ return 403 when email already in use
        ✔ return 500 when creating user with invalid body
        ✔ return 500 when creating user with an empty body
      success
        ✔ redirect to /profile (60ms)
      1) "after all" hook: delete register test user in "POST /register"
    GET /login
      ✔ return 200 saying to login with post
    POST /login
      failure
        ✔ return 400 and error message when giving no credentials
        ✔ return 400 and error message when using invalid credentials
        ✔ return 401 if already logged in (54ms)
      success
        ✔ redirect to /profile (51ms)
    2) "after all" hook: delete test user in "User endpoints"


  10 passing (436ms)
  2 failing

  1) User endpoints
       POST /register
         "after all" hook: delete register test user in "POST /register":
     Uncaught ReferenceError: deleted is not defined
      at /home/harry/codecademy/fullstack/projects/epstore/src/routes/profile.js:30:59
      at /home/harry/codecademy/fullstack/projects/epstore/node_modules/passport/lib/sessionmanager.js:90:7
      at Immediate.<anonymous> (node_modules/express-session/session/store.js:54:5)
      at process.processImmediate (node:internal/timers:471:21)

  2) User endpoints
       "after all" hook: delete test user in "User endpoints":
     Uncaught ReferenceError: deleted is not defined
      at /home/harry/codecademy/fullstack/projects/epstore/src/routes/profile.js:30:59
      at /home/harry/codecademy/fullstack/projects/epstore/node_modules/passport/lib/sessionmanager.js:90:7
      at Immediate.<anonymous> (node_modules/express-session/session/store.js:54:5)
      at process.processImmediate (node:internal/timers:471:21)

Leave a Comment