testing express router with several different handlers

I have been testing my guard middleware and everything appears to be functioning correctly, but my expect statement is failing.

/// auth.test.js

const request = require('supertest');
const express = require('express');
const app = require('../../app');
const authMiddleware = require('./auth.middleware');

const mockRes = () => {
  const res = {};
  res.status = jest.fn().mockReturnValue(res);
  res.sendStatus = jest.fn().mockReturnValue(res);
  res.send = jest.fn().mockReturnValue(res);
  return res;
};

describe('Authorization', () => {
  const guardedRouter = express.Router();

  guardedRouter.get(
    '/guardedandauthenticated',
    [authMiddleware.authenticate, authMiddleware.authorize('admin')],
    (req, res, _next) => {
      console.log('seems to be working');
      res.status(200);
      console.log('res is 200000000');
    },
  );

  let accessToken = '';
  beforeAll(async () => {
    const res = await request(app).post('/auth/login').send({
      username: 'admin',
      password: 'admin',
    });
    expect(res.status).toBe(200);
    accessToken = res.body.accessToken;
  });


  it('should allow access to authorized roles', () => {
    const response = mockRes();
    // @ts-ignore
    guardedRouter.handle(
      {
        headers: { authorization: `Bearer ${accessToken}` },
        url: '/guardedandauthenticated',
        method: 'GET',
      },
      response,
    );
    // THIS EXPECTATION IS FAILED
    expect(response.status).toHaveBeenCalledWith(200);
  });
});

/// auth.middleware.js

module.exports.authorize = role => {
  return async (req, res, next) => {
    if (!req.user) {
      return res.status(403).send({
        message: 'Unauthorized! No token provided!',
      });
    }
    if (req.user.role === undefined) {
      const privileges = await userService.getUserPrivileges(req.user.id);
      req.user.role = privileges.map(f => f.privilege_name);
    }
    const userRoles = req.user.role;

    const rolesToCheck = Array.isArray(role) ? role : [role];
    if (!rolesToCheck.every(r => userRoles.includes(r))) {
      return res.status(403).send({
        message: `Unauthorized! Required privileges are: ${userRoles.toString()}`,
      });
    }
    return next();
  };
};

/// jest outcome

expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: 200

Number of calls: 0

I have made some cleanups in the code, similar assertions are passing successfully, and the code appears to be operational. It's possible that the way I set up the router is incorrect, or maybe I'm missing something crucial. The console messages within the router are showing up in the jest output, indicating that it is functioning correctly. Thanks in Advance,

Answer №1

It turned out that the issue was related to Jest, where you need to explicitly inform Jest when your test is done.

  it('should allow access to authorized roles', async done => {
    const res = { statusCode: 100 };
    res.status = function (code) {
      res.statusCode = code;
      return res;
    };
    // @ts-ignore
    guardedRouter.handle(
      {
        headers: { authorization: `Bearer ${accessToken}` },
        url: '/guardedandauthenticated',
        method: 'GET',
      },
      res,
    );
    setTimeout(() => {
      done();
      expect(res.statusCode).toBe(200);
    }, 300);
  });

I added a done callback to the test case to check the value after the handler finishes execution. However, using a timer for this verification doesn't seem like the ideal solution. The problem lies in the fact that the handle function calls three functions, one of which is asynchronous, making it difficult to determine the correct outcome without setting a delay. I'm looking for a solution that doesn't rely on timers, so if anyone has any suggestions, please share them!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for halting the movement of marquee text once it reaches the center briefly before resuming animation

Is there a way to make text slide in, pause when centered, and then repeat the process? I'm looking for some help with this animation. Here is the code snippet: <marquee direction="left" id="artistslide"> <span id="currentartist">< ...

Presentation with multi-directional animations

Curious to know if it's possible to create a unique slideshow that scrolls in multiple directions? The concept is to display various projects when scrolling up and down, and different images within each project when scrolling left and right. Is this i ...

Update the styling of each div element within a designated list

Looking for a way to assist my colorblind friend, I am attempting to write a script. This is the layout of the page he is on: <div class="message-pane-wrapper candy-has-subject"> <ul class="message-pane"> <li><div style=" ...

Unable to fetch local file using ajax from a local HTML page

According to Same Origin Policy, the SOP should not be applied to the file:// protocol. However, I'm having trouble with my code. I am running a testing page from my local system, and both when I try to access abc.txt in the same directory as the HTML ...

Implementing a Javascript solution to eliminate the # from a URL for seamless operation without #

I am currently using the pagepiling jQuery plugin for sliding pages with anchors and it is functioning perfectly. However, I would like to have it run without displaying the '#' in the URL when clicking on a link like this: www.mysite.com/#aboutm ...

Nativescript apps are unable to utilize Node modules

I am currently facing an issue with integrating multiple plugins into my Nativescript application. The computed path to locate these installed plugins appears to be incorrect, and I am unable to locate any guidance on how to rectify this issue. Is there a ...

Creating a Robust Next.js Build with Tailor-Made Server (Nest.js)

I'm in need of assistance with compiling/building my project using Next.js while utilizing a custom server. Currently, I have integrated Nest.js (a TypeScript Node.js Framework) as the backend and nested Next.js within it. The integration seems to be ...

the display outcome appears fuzzy and lacks sharpness

Currently, I am engaged in prototyping and showcasing data in a 3D format using three.js (version 68). The intended outcome of the entire animation is to have a collection of colored spheres representing protons and neutrons, each colored based on a specif ...

Avoid changing the regex pattern if it is surrounded by a specific character

I want to change all occurrences of strings enclosed by - with strings enclosed by ~, unless the string is again surrounded by *. For instance, consider this string... The -quick- *brown -f-ox* jumps. ...should be altered to... The ~quick~ *brown -f-ox ...

Is there a way to retrieve the content of an element using JavaScript?

I'm currently working on retrieving the value and content of an option element. I've managed to obtain the value using this.value as shown in the code snippet below: <select name='name' id='name' onchange='someFunctio ...

Modeling a versatile user system in Mongoose for various user types

I am in the process of creating a unique social networking platform for students and teachers using the MEAN stack. Each student will have their own distinct account page separate from the teachers. There is only one registration page where both teachers ...

What could be causing the issue with my dependency injection in my Angular application?

Let's get started angular.module('app', [ 'ngCookies', 'ngResource', 'ngSanitize', 'ngRoute' ]) This is my simple factory. Nothing fancy here angular.module('app') .factory(&apos ...

The React form data was sent to the Express backend, but upon receipt, it was

Currently, I am working on image uploading in my MERN app. I am utilizing the express-fileupload package for this purpose. The issue I am facing is that while sending an image from the frontend in FormData, the backend is receiving null values. Frontend c ...

What are the essential files needed in Kendo UI Core for a mobile app?

Several months ago, I created a trial Kendo mobile app but now I want to verify it using the most recent version of Kendo UI Core. In my previous project, I referenced the following files: <link href="../styles/kendo.common.min.css" rel="stylesheet" / ...

Having issues retrieving and utilizing response status code following the initial then() method in a Promise

My goal is to utilize the response status code, which is initially available in the first then function along with the JSON response data. However, I am encountering a SyntaxError: Unexpected token U in JSON at position 0. Here is the snippet of the promi ...

405 error: NGINX blocking POST method in Django DRF Vue.js application

I have encountered a strange issue while building my ecommerce site. Everything seems to be working fine, except for the forms. When attempting to post content, I keep receiving a 405 method get not allowed error. It's confusing as I am trying to use ...

Using Mongoose to Implement the Repository Pattern in Node.js

As a newcomer to node.js with a background in .net, I am interested in applying some of the design patterns I used with c#.net. However, I am encountering challenges due to the differences in object-oriented nature between c# and JavaScript. Specifically, ...

Error in Webpack: JSX elements that are adjacent must be enclosed within a wrapper tag

After adding a new component and integrating it into my Main component, I encountered an error when running webpack. The error message displayed was: "Adjacent JSX elements must be wrapped in an enclosing tag" Below is the snippet of code where the iss ...

The ReactJS component is unable to resolve the specified domain name

Whenever I utilize a component like const React = require('react'); const dns = require('dns'); class DnsResolver extends React.Component { componentDidMount() { dns.resolve('https://www.google.com', (err, addres ...

The eval() function does not run scripts from external sources with a src attribute

Instead of using eval() to execute all <script> tags after completely rewriting a div, I have encountered an issue. The following code snippet works for inline-scripts, but it doesn't have the same effect on external scripts like: <script sr ...