15

I'm testing my API endpoints with supertest, and it works great, but i can't figure out how to test if a file download is successful.

In my routes file i have defined the endpoint to be:

app.get('/api/attachment/:id/file', attachment.getFile);

and the function getFile() looks something like this:

exports.getFile = function(req, res, next) {
    Attachment.getById(req.params.id, function(err, att) {
        [...]
        if (att) {
            console.log('File found!');
            return res.download(att.getPath(), att.name);
        }

Then, in my test file, I try the following:

describe('when trying to download file', function() {
    it('should respond with "200 OK"', function(done) {
        request(url)
        .get('/api/attachment/' + attachment._id + '/file');
        .expect(200)
        .end(function(err, res) {
            if (err) {
                return done(err);
            }
            return done();
        });
    });
});

I know for sure that the file is found, because it logs out File found!. It also works fine if i try manually, but for some reason, mocha returns Error: expected 200 "OK", got 404 "Not Found".

I've experimented with different mime-types and supertest .set("Accept-Encoding": "*"), but nothing works.

Anyone know how to do this?

Martin Hallén
  • 1,492
  • 1
  • 12
  • 27
  • If you try the download with the chrome dev tools open does it show any errors? I'm wondering if you are essentially sending the file as a 404 error page. – Arcath Oct 20 '15 at 13:16
  • @mart0903, did you ever find a solution to this problem? – David Cruwys Dec 13 '15 at 20:29
  • 2
    You can add the optional callback function `res.download` to see what the exact error is. My guess would be that you're getting this error because res.download usually prompts the browser to inform the user to download the attachment and there's no way to prompt the user since you're doing this programmatically. – Quy Dec 13 '15 at 23:34
  • @DavidCruwys: I'm afraid not. I'm not working on this project anymore, but we ended up not having good tests for this criterion. – Martin Hallén Dec 14 '15 at 14:17
  • @Quy: That is interesting, I will definitely check it out next time I face this problem. Do not work for the same company anymore. – Martin Hallén Dec 14 '15 at 14:17

2 Answers2

3

Either the problem has been fixed in the libraries, or there is a bug in some other part of your code. Your example runs fine, and gives

  when trying to download file
File found!
    ✓ should respond with "200 OK"
bolav
  • 6,938
  • 2
  • 18
  • 42
0

When testing for a download file, it is not enough to validate the response status from the server, it will be even better if you can somehow validate the response data.

For download data, the content of the file are usually passed in the http response as text, with the file type as Content-Type, and the attachment and filename stored in Content-Disposition.

Depending on how detailed you would like to go, you can try the following:

    const response = await request(url)
            .get('/api/attachment/' + attachment._id + '/file');
    expect(response.headers["content-type"]).toEqual("image/png");
    expect(response.text).toMatchSnapshot(); // Use only if the file is deterministic.

Using jest or any other snapshot framework, you can achieve a more reliable test.

This may be coming late, but I'm dropping this here for future reference and to help others who might be facing something similar.

Akinjiola Toni
  • 658
  • 7
  • 9