Checksuming axios downloaded files in jest

I recently had the need to make a test where I confirm the file in a backend server is the same as the one available in the front end client. Due to the fact that frontend frameworks like vue can have a lot logic this test is important for me as it allows me to validate the backend-frontend integration.

function mytest(image_data_list) {
   return Promise.all(image_data_list.map(image_data => axios.get(image_data.url, {
                adapter: require('axios/lib/adapters/http'),
                responseType: 'arraybuffer'
            })
            .then((response) => {
                expect(
                    crypto.createHash("sha256")
                        .update(response.data)
                        .digest("base64"))
                    .toBe(image_data.sha256);
            })
            .catch( (error) => {
                    reject(`check failed`);
                }
            )
     ))
}

Now i am going to try to describe in pseudo code what happens.

function mytest(image_data_list) {

Here our test function takes a list of objects with each object containing the url and sha256. It is not obvious from the function signature because…javascript is not explicitly statically typed but that is besides the point.

return Promise.all(image_data_list.map(image_data => axios.get(image_data.url, {
                adapter: require('axios/lib/adapters/http'),
                responseType: 'arraybuffer'
            })

The test framework I normally use is called jest, and it likes tests to return promises. If you do not return the promise to the caller(the framework) the test code may actually never run, giving you false test positives(One more pitfall, I hate it).

So given we have a list of url data to test and that axios.get returns a promise it seems fit to use the Promise.all. As javascript is so functional we end up with using map to map all the url data to checksum tests promises.

There are 2 properties set for the configuration of axios.get: adapter and responseType.

The adapter property is a trick to skip jest’s jsdom XMLHttpRequests which set the HOST as localhost leading to CORS issues. More about it here.

The responseType is set as arraybuffer because we need to have raw unprocessed access to the response data. If this would not be the case we could potentially end up with different hashes. Fortunately for us the the crypto library’s update method can take an array buffer as input.

If the hash check fails expect will reject the promise and will make your test fail.