Testing file downloads

[00:01] Let's go ahead and test drive a download report feature. We already have a reports controller test so let's open that and add a new test below download report.

[00:12] For this test to work we need an authenticated user, an existing report with an existing file on disk, and then we need to make a request and assert that the correct file was returned.

[00:40] To authenticate a user we need to create it first and we can use the user factory, and then to sign it in we can call this acting as, and pass the user

[00:54] So now we have an authenticated user.

[01:01] The next step is to have a report with a file on disk. So let's create it: report equals report create, we'll give it a name, and a path. For this to work we need a path to a real file.

[01:22] We can create one using the file class. Make sure is the one under illuminate http testing though; create, then we pass the file name and the size in kilobytes. Now to save it on disk we can call the store method, pass in the directory, and the disk, and this will return the file path.

[01:49] The next step is to make a request that will return the file associated with this report. And we can do this get, it will be a get request to a route, let's say, reports dot show, and we'll need to pass in the report id as a parameter.

[02:11] Finally we can assert that the response has a successfull status code, and for the harderst part, we need to asser tthat the downloaded file matches the one we have here. But in order to do that we'll need to swap the current file system with the fake one.

[02:29] And we can use the storage facade for that. Storage, fake, and then pass in the disk.

[02:36] Another thing that we need is to store the file in a variable so we can compare it with what we get back.

[02:47] Now for the final assertion we can say storage should receive disk with local and return an instance of storage, and we can grab this from here. So storage equals storage, fake, local, and then we can continue with: should receive download with the report path and return our file.

[03:29] This whole thing basically translates to storage disk local, download report file. So this right here matches the sequence so we have storage that receives disk with the local as argument; this will return an instance of storage, and then we'll call download with the report path and receive our file back.

[04:01] Let's remove this whole thing and run the test. Of course it will fail because there is no reports dot show route. So let's add it.

[04:13] Route, get,report, slash report as a parameter, reports controller, calling the show action, and name it reports dot show.

[04:27] Now let's open the controller and add the show action; public function show, and we should receive the report via route model binding, and here we need to return: storage disk local download report path

[04:54] And if we rerun the tests it should all pass. And it does. Let's go over the tests one more time.

[05:03] So we swap the file system with a fake disk, we authenticate a user, we then prepare a report with an existing file, make a request to the server, and assert that the request was successfull. And then we assert that the correct file was returned.

[05:23] That's it that's how you can test file downloads in laravel applications. Don't forget to like subscribe and click the bell button. Bye!

Create an account to view the code snippets of this episode.