I just added a route in one of my node router files and would like to add the appropriate unit test for it. The route is the following:
router.post('/addtradables', checkIsAdmin, async function(req, res, next) {
const SteamApp = require('../models/steamapp.model');
const Tradable = require('../models/tradable.model');
const User = require('../models/user.model');
const postedTradables = req.body.tradables;
if(postedTradables) {
res.json({ success: true, result: constants.PROCESS_STARTED, textResult: 'The tradables are being added' });
const adminUser = await User.findOne({ steamId: ADMIN_ID }).exec();
for(let currentKey in postedTradables) {
if(postedTradables.hasOwnProperty(currentKey)) {
const currentTradable = postedTradables[currentKey];
const appFound = currentTradable.sku ? await SteamApp.findOne({ appid: currentTradable.sku }).exec() : null;
await new Tradable( { /* object data here */ } ).save();
}
}
} else {
return res.json({ success: false, result: constants.INVALID_FORMAT, textResult: 'No tradable found, check the format' });
}
} );
As you can see, it returns an object with a code and text message so that the front end can know if the process was started or not. This is because the insertion process can take a while, depending on the input data.
Here is my Jasmine spec file:
const app = require('../../app');
const request = require('supertest');
const MongoDbTest = require('../../lib/mongodb-tests.lib');
const jwt = require('jsonwebtoken');
const SteamApp = require('../../models/steamapp.model');
const Tradable = require('../../models/tradable.model');
const User = require('../../models/user.model');
const JWT_TOKEN = process.env.JTW_KEY;
const ADMIN_ID = process.env.MASTER_STEAMID;
const constants = require('../../config/constants');
const adminUser = {
role: 'admin',
steamId: ADMIN_ID
};
const testTradable = {
sku: 1234,
barterId: 83838,
extra: 2,
type: 'gift',
title: 'Les patates volent!'
};
describe("route /addtradables", () => {
const mongod = new MongoDbTest();
let testOwner;
beforeAll(async () => {
await mongod.connect();
await new SteamApp({ appid: 1234, name: 'patate' }).save();
testOwner = await new User(adminUser).save();
} );
afterAll(async () => {
await SteamApp.deleteMany({});
await User.deleteMany({});
await mongod.close();
} );
it("devrait retourner un message indiquant que le format est incorrect lorsque c'est le cas", async () => {
const userToken = jwt.sign(adminUser, JWT_TOKEN, { algorithm: 'HS256' });
const response = await request(app).post(`/api/addtradables`).send({ patate: 'pouelle' }).set('Authorization', `Bearer ${userToken}`).expect('Content-Type', /json/);
expect(response.statusCode).toBe(200);
expect(response.body.success).toBe(false);
expect(response.body.result).toBe(constants.INVALID_FORMAT);
} );
it("devrait retourner un message indiquant que le processus a débuté lorsque le format est correct", async () => {
const userToken = jwt.sign(adminUser, JWT_TOKEN, { algorithm: 'HS256' });
const response = await request(app).post(`/api/addtradables`).send({ tradables: { 9837489374: testTradable } }).set('Authorization', `Bearer ${userToken}`).expect('Content-Type', /json/);
expect(response.statusCode).toBe(200);
expect(response.body.success).toBe(true);
/*
I WANT TO WAIT HERE! If I don't wait for the router.post call to finish the data will not be available in the database
*/
const insertedTradable = await Tradable.findOne({ appid: 1234 }).exec();
expect(insertedTradable.barterId).toBe(testTradable.barterId);
expect(insertedTradable.isGift).toBe(true);
expect(insertedTradable.copies).toBe(testTradable.extra);
expect(insertedTradable.name).toBe(testTradable.title);
} );
} );
Is there a way to spy on the router.post
call and check when everything is completed so that I can extract data from the database and check that the data was inserted properly? Short of that, what would be the best way to sleep / stop execution in the jasmine test routine while the the router.post
call wraps up? I've looked at using a done
function but since the code is inside the router I don't see how I could use done
in this scenario.