chai-http
chai-http copied to clipboard
Issue with MongoDB ObjectId in tested function?
Apologies if this is out of scope as an issue, but I'm having trouble comprehending an issue with chai-http's sent data and a tested function that appears to center on MongoDB's ObjectId type.
The tested function converts an incoming string from req.body
into an ObjectId for use with MongoDB. This works in the application. When using chai-http
for integration testing, however, it fails. MongoDB is unable to find a match for the ID and therefore makes no changes.
Oddly, when I remove the ObjectId()
conversion of the incoming string, it passes the test and errors in the real application. So the application and test are causing opposite issues that appear to come from the incoming data sent via Ajax or chai.request().post.send()
.
The issue persists across all tested functions that use the ObjectId to convert the strings, but here is one example from the application:
// tested function
// changes a poll's name and updates lastModified
// called by POST to /api/polls/:id
async function editPoll(req, res) {
const client = new MongoClient(process.env.DBURL, { useNewUrlParser: true, useUnifiedTopology: true })
const newPollName = req.body.value;
// this is causing problems with tests
// they fail with using ObjectId, but pass without it
// while the application does the opposite
const pollId = ObjectId(req.body.id);
try {
await client.connect();
const polls = await client.db(process.env.DBNAME).collection('polls');
const updateResult = await polls.updateOne(
{ _id: pollId },
{
$set: { "name": newPollName },
$currentDate: { lastModified: true }
}
).then(result => {
res.json(result);
}).catch(err => console.log(err));
} finally {
await client.close();
}
}
Here is the calling function from the application (which works with the function above). It is part of a larger export.
// calling function, from the front end application
editPoll: function (poll) {
return new Promise(function (resolve, reject) {
$.ajax({
url: resourceURL + "/" + poll.id,
data: JSON.stringify(poll),
method: "POST",
dataType: 'json',
contentType: 'application/json',
success: resolve,
error: reject
});
}).catch(function (rejected) {
console.log(rejected);
});
}
And here is the test function, which fails as is, but passes when removing the ObjectId()
type conversion in the first example above.
it('should edit the name of a poll on POST', function (done) {
chai.request(server)
.post('/api/polls/60e0b866ae9637b4478f4f23')
.send({ value: 'Edited name', id: '60e0b866ae9637b4478f4f23' })
.end((err, res) => {
if (err) { console.log(err) }
console.log(`modified ${res.body.modifiedCount}`);
res.should.have.status(200);
res.body.modifiedCount.should.be.eql(1);
done();
})
});
I've tried with and without using .set()
to change content types, but with no luck. I can't help but to think that this relates to how chai-http is sending the data to the tested function, but I can't seem to work out how. Any help is appreciated!