I have been working on a seemingly straightforward 4-file toy solution that I thought was simple. I am looking to write a Jest test for the '/bingo' route in bingo.js which requires authentication. Below are the four files that make up this setup.
index.js
, the root file for the Express approutes/auth.js
, containing a basic authenticationPOST
endpointroutes/bingo.js
, an endpoint requiring user authenticationmiddleware/authentication.js
, a middleware for session user check
I am currently stuck and struggling to figure out how to write unit tests specifically for the bingo.js endpoint without having to run the entire application through index.js
. I do not require full end-to-end testing as that is covered by Cypress tests.
I have tried various approaches such as trying to isolate the auth step, mocking sessions, and attempting to set the session on Supertest...
If anyone could provide some guidance or at least point me in the right direction, it would be greatly appreciated.
index.js
// index.js
const express = require("express");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const app = express();
const bingoRouter = require("./routes/bingo");
const authRouter = require("./routes/auth");
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(
session({
cookie: { maxAge: 300000 },
store: new session.MemoryStore(),
saveUninitialized: true,
resave: "true",
secret: "our_really_secret_key",
})
);
app.use("/bingo", bingoRouter);
app.use("/auth", authRouter);
app.use((req, res) => {
return res.status(404).json({
error: "Not Found",
});
});
app.listen(port);
module.exports = app;
auth.js
// routes/auth.js
const express = require("express");
const router = express.Router();
const jwt = require("jsonwebtoken");
const secretKey = "our_really_secret_key";
// Authenticate user
router.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = { username: "username", password: "password", is_admin: true };
if (user && user.password === "password") {
req.session.user = user;
res.redirect("/bingo");
} else {
res.render("auth", { error: "Invalid username or password" });
}
});
bingo.js
// routes/bingo
const { isAdmin } = require("../middleware/authentication");
const express = require("express");
const router = express.Router();
router.use(isAdmin);
router.get("/", async function (req, res) {
res.render("bingo", {
user: req.session.user,
});
});
module.exports = router;
authentication.js
// middleware/authentication.js
exports.isAdmin = (req, res, next) => {
if (req.session.user && req.session.user.is_admin) {
// User is authenticated & admin, allow access to route
next();
} else {
// User is not authenticated or not admin, redirect to login page
res.redirect("/auth");
}
};