Exploring secure routes in Node.js with test cases using Mocha and Chai?

The function verifies whether the route is accessible or not

function checkSessionCookieValidity(req, res, next) {
      if (!isValid(req.session)) {
        return res.status(401).json({
          isLoggedIn: false
        });
      }
        return next();
 }

Within a separate file, I make a post request to a protected route using the aforementioned function

  app
     .route('/url')
     .post(utils.checkSessionCookieValidity, (req, res, next) => {})

TESTING segment

An issue arises as I am unsure how to simulate the checkSessionCookieValidity function since it necessitates a next callback which I am unable to provide in my test:

describe('testing routes', () => {
  it('should access the route body', (done) => {
    utils.checkSessionCookieValidity(req, res, 'next should be here...');
    chai.request(server)
      .post('/url')
      .end(function (error, response, body) {
        if (error) {
          done(error);
        } else {
          done();
        }
      });
  });

});

ERROR: TypeError: next is not a function

Answer №1

I have decided to use the mocking library sinonjs for this task. The goal is to mock the functionality of the isSessionCookieValid middleware and always allow it to proceed to the next middleware.

For example:

server.ts:

import express from 'express';
import * as utils from './utils';

const app = express();
const port = 3000;

app.route('/url').post(utils.isSessionCookieValid, (req, res, next) => {
  res.sendStatus(200);
});

if (require.main === module) {
  app.listen(port, () => {
    console.log(`Server is listening on port ${port}`);
  });
}

export { app };

utils.ts:

function isSessionCookieValid(req, res, next) {
  if (!isValid(req.session)) {
    return res.status(401).json({
      isLoggedIn: false,
    });
  }
  return next();
}

function isValid(session) {
  return true;
}

export { isSessionCookieValid };

server.test.ts:

import * as utils from './utils';
import sinon from 'sinon';
import chai, { expect } from 'chai';
import chaiHttp from 'chai-http';

chai.use(chaiHttp);

describe('testing routes', () => {
  it('should enter the route body', (done) => {
    const isSessionCookieValidStub = sinon.stub(utils, 'isSessionCookieValid').callsFake((req, res, next) => {
      next();
    });
    const { app } = require('./server');
    chai
      .request(app)
      .post('/url')
      .end((error, response) => {
        if (error) {
          return done(error);
        }
        sinon.assert.calledOnce(isSessionCookieValidStub);
        expect(response).to.have.status(200);
        done();
      });
  });
});

Outcome of the unit test:

  testing routes
    ✓ should enter the route body (500ms)


  1 passing (510ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |      60 |       25 |      25 |      60 |                   
 server.ts |      80 |       50 |      50 |      80 | 12-13             
 utils.ts  |      20 |        0 |       0 |      20 | 2-11              
-----------|---------|----------|---------|---------|-------------------

Source code can be found at: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/54462600

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

Customizing material-ui styles within a nested component

I am looking to modify the position of the expandIcon in an ExpansionPanel by changing the right attribute: <ExpansionPanel> <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> <Typography className={classes.heading}&g ...

Issues with ng-show functionality occurring during the initialization of the webpage

While working on a webpage using HTML, CSS, and Angular.js, I encountered an issue where the page content would not display properly upon loading. The objective was to show selected content based on user choices from a dropdown menu. Although the filtering ...

Using conditional logic to check if a column cell is empty

I need help writing a Javascript function that will loop through rows in a table and only change the background color of cells in "column2" if they are empty. My current code is not working as expected, as it colors all rows instead of just those with empt ...

Unable to attach an onClick event handler to <TableRowColumn> element using Material-UI in React

In the past, I had a feature that allowed me to change the color of the text from red to green by clicking on a table cell. After introducing Material-UI in my React app and replacing the <td> tags with <TableRowColumn> tags, I noticed that th ...

I'm facing an issue where the data I retrieved is not displaying properly in my template within nuxt 3

After fetching data from an api, I can see it logged in my async function. However, the data stored in my array is not rendering on my template in Nuxt 3 The script setup includes: //ARRAY OF ALL THE DAILY WEATHER DATA PER DAY let allDataWeather=[]; ( ...

Having trouble with installing packages through NPM in Node.js?

Whenever I try to install a package, NPM shows me an error like this: [............] /roolbackFailedOptional: verb npm-session .... followed by the final error message: npm ERR! code e503 npm ERR! 503 Service Unavailable: npm ERR! A complete log of th ...

What steps are involved in creating an xlsx file using Express and Exceljs, and then sending it to the client?

I am currently working on separating controllers and services in my Express app. One of the services I have generates an XLSX file using ExcelJS. I'm looking for a way to reuse this service without passing the response object to it. Is there a method ...

Connect the Vue component to the Vue instance

I am currently working with a Vue component that looks like this: Vue.component('number-input', { props: {}, template: `<textarea class="handsontableInput subtxt area-custom text-center text-bold" v-model="displayValue" @blur="isInput ...

Effective Methods for Transferring Information from Database Applications to Theme App Extensions without Utilizing Metafields

I am currently exploring methods to transfer information between database applications and theme app extensions. Within the backend, merchants have the ability to create, edit, and delete data which is then updated in the database. I have also experimented ...

Configuring Access-Control-Allow-Origin does not function properly in AJAX/Node.js interactions

I'm constantly encountering the same issue repeatedly: XMLHttpRequest cannot load http://localhost:3000/form. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefor ...

I am facing an issue in my Nextjs project where the Array Object is not being properly displayed

Hi there! I am new to Nextjs and currently learning. I recently created a component called TeamCard which takes imgSrc, altText, title, designation, and socialProfile as parameters. However, when attempting to display the socialProfile object array using m ...

Is it possible to retrieve a physical address using PHP or Javascript?

Is it possible to retrieve the physical address (Mac Address) using php or javascript? I need to be able to distinguish each system on my website as either being on the same network or different. Thank you ...

Having trouble with installing discord.js in Visual Studio Code

Being new to programming, I am struggling to grasp concepts related to node.js and other similar technologies. My current challenge lies in installing discord.js within Visual Studio Code. Despite attempting the command "npm install discord.js" in both th ...

An error occurred - 0x800a1391 - JavaScript runtime error: The function 'SelectAllCheckBoxes' has not been defined

I'm currently in the process of learning web development and I am trying to incorporate jQuery into my ASP .NET page. Within the header section, I have included the necessary references: <head id="Head1" runat="server"> <link href=" ...

Having trouble integrating Socket.io with Express.js?

I'm currently attempting to connect socket.io with express.js: var socket = require('./socket_chat/socket.js'); var express = require('express'), app = module.exports.app = express(); var io = require('socket.io&apo ...

Include the JS file after finishing the control processing

I've been grappling with an issue for several days now. The view I have is populated by my controller through an API call, which works perfectly fine in rendering the HTML. $http.get(url). success(function(data, status, headers, config) { ...

Retrieving information from a local JSON file in Vue.js using the jQuery $.getJSON() method

Currently, I am in the process of developing a demo application using Vuejs which involves extracting map data from a local .json file. The extracted data is then used to obtain specific information like latitude and longitude values that are necessary for ...

The initial render in a Kanban board seems to be causing issues with the functionality of react-beautiful-dnd

I recently integrated a Kanban board into my Next.js and TypeScript project. While everything seemed to be working fine, I encountered a minor glitch during the initial rendering. Interestingly, when I refreshed the page, the drag and drop functionality st ...

What causes the command prompt script to abruptly exit when verifying the npm version?

My file npm_version.cmd is not pausing and instead closes the window: npm -v @pause Conversely, I have another file called nodejs_version.cmd that does pause and keeps the window open: node -v @pause It seems like npm is causing a switch from the npm w ...

Employ variables as a jQuery selector

let myLink = "#portfolio-link-" + data[i].pf_id; I am storing an ID in a variable. $("#pf-container-1").append(portfolio); console.log(myLink); $(myLink).append(function(){ $("<button class='btn btn-inverse' id='portfo ...