jestjssupertestsuperagentformidable

How to read an attachement from res of supertest?


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.


Solution

  • 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);