I am encountering a strange issue when working with Chai.request.agent. Below is my test code:
const chai = require("chai");
const chaiHttp = require("chai-http");
chai.use(chaiHttp);
let agent;
beforeEach(() => {
agent = chai.request.agent(app);
});
afterEach(() => {
agent.close();
});
it("should do something", async () => {
//Log in
const res = await agent.post("/api/my-endpoint").send(userDetails);
expect(res).to.have.cookie("my-cookie");
//Test endpoint
const res2 = await agent.get("/api/my-other-endpoint");
expect(res2).to.have.status(200);
});
The second request is sent to an endpoint that checks for the presence of my-cookie, returning a 401 if it is not present and a 200 if it is. I am getting a 401 here, and I know it is triggered by the lack of my-cookie as console.logs are logged from the piece of code that handles the check.
Here is the endpoint code:
router.post("/my-endpoint", async function (req, res) {
try {
const token = jwt.sign(
{ id: 4 },
process.env.SECRET,
{ expiresIn: "12h" }
);
res.cookie("my-cookie", token, {
httpOnly: true,
maxAge: 60 * 60 * 12 * 1000,
secure: true,
sameSite: "strict",
});
res.sendStatus(200);
} catch (error) {
console.error(error);
res.status(500).json({ message: "ERROR: log in failed" });
}
});
router.get("/my-other-endpoint", async function (req, res) {
try {
const cookies = req.cookies;
if (!cookies?.my-cookie) {
console.log("No cookie"); //This gets logged
return res.sendStatus(401);
} else {
res.sendStatus(204);
}
} catch (error) {
console.error(error);
res.status(500).json({ message: "ERROR" });
}
});
I have tried copying the promise chaining example from the docs but when I use this approach the second request does not run
Set the secure
option to false
or unset it.
app.js
:
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.post('/my-endpoint', function (req, res) {
res
.cookie('my-cookie', 'abc123', {
httpOnly: true,
maxAge: 60 * 60 * 12 * 1000,
// secure: true,
sameSite: 'strict',
})
.sendStatus(200);
});
app.get('/my-other-endpoint', function (req, res) {
console.log('my-cookie: ', req.cookies['my-cookie']);
if (!req.cookies['my-cookie']) {
console.log('No cookie');
res.sendStatus(401);
} else {
res.sendStatus(204);
}
});
module.exports = app;
app.test.js
:
const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('./app');
chai.use(chaiHttp);
const { expect } = chai;
let agent;
beforeEach(() => {
agent = chai.request.agent(app);
});
afterEach(() => {
agent.close();
});
it('should do something', async () => {
const res = await agent.post('/my-endpoint').send({});
expect(res).to.have.cookie('my-cookie');
const res2 = await agent.get('/my-other-endpoint');
expect(res2).to.have.status(204);
});
Test result:
my-cookie: abc123
✓ should do something
1 passing (18ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 84.61 | 50 | 100 | 84.61 |
app.js | 84.61 | 50 | 100 | 84.61 | 21-22
----------|---------|----------|---------|---------|-------------------