I have an express end point "/api/posts/:id" that returns some metadata about a post and the post file itself through res.attachment(post.fileName).send(post)
. (Note I'm not sure if this is correct)
I'm trying to test it using supertest. After
const res = await request(server).get("/api/posts/a");
I can read the post metadata through res.body
. But how do I read the attachment (i.e. the file)?
Edit:
It seems that I need to use a library like formidable to read the returned file. res.files is null by default but formidable populates it. So I tried doing that inside my jest test file as follows:
const res = await request(server).get(`/api/posts/${post._id}`);
const form = formidable();
form.parse(res, (err, fields, files) => {
console.log("inside parse");
expect(0).toBe(1);
});
But this didn't work. The console did not log "inside parse" and in fact the case passed even though expect(0).toBe(1) should make it fail.
Before answering I just want to point out that the way I was sending the post is incorrect. So I ended up sending the file on its own through res.sendFile(post.fileName)
Moving on to reading the file when testing. As mentioned above I had to use formidable to populate the res.files parameter. Additionally I had to modify my jest test function to make it wait for formidable's callback to finish:
it("returns 200 with post file when given existing post id", async (done) => {
...
const res = await request(server).get(`/api/posts/${post._id}`);
const form = formidable();
form.parse(res, (err, fields, files) => {
try {
expect(0).toBe(1);
done();
} catch (error) {
done(error);
}
});
});
Edit:
A better approach that I found would be to use the supertest expect via:
const expectedFile = await fsPromises.readFile(filename);
request(server)
.get(`/api/posts/${post._id}/file`)
.expect(200, expectedFile, done);