Laravel Livewire testing download
Published: 2021-09-18 09:46:03

---
title: Laravel Livewire testing download
published: true
date: 2021-04-27 11:37:16 UTC
tags: 
canonical_url: https://dcblog.dev/laravel-livewire-testing-download
---

 ![Laravel Livewire testing download](https://dcblog.dev/assets/images/blog/laravel-framework/Laravel-Livewire/laravel-livewire-testing-download.png) 

testing Laravel Livewire components for the most part is a case of setting a property or method and testing the property has been set or can be seen. Testing a download is a little tricker to do.

I've seen some posts advising to check the headers and compare the content-disposition against an expected filename.

```php
self::assertTrue($response->headers->get('content-disposition') == "attachment; filename='$expected_pdf_name'");
```

The problem in Laravel Livewire you don't have access to a $response object unless you assign the component but even that you don't have access to the headers array.

## The Solution

Inspecting the **$response** from a component that fires a download interestingly does have an effects part that contains download which in turn contains name and content, so it's possible to compare the name from the response with the expected download name.

Let's try this out!

Here's an export method of an existing component

The download is performed in this case by [https://laravel-excel.com/](https://laravel-excel.com/) the export expects 2 params the format and optionally a timestamp.

```php
public function export(string $format, \DateTime $timestamp = null): Bool|BinaryFileResponse
{
    $params = [
        'name' => $this->name,
        'created_at' => $this->created_at
    ];

    if ($timestamp === null) {
        $timestamp = now();
    }

    if ($format === 'xlsx') {
        return (new CustomersExport($params))->download("customers-$timestamp.xlsx");
    }

    if ($format === 'csv') {
        return (new CustomersExport($params))->download("customers-$timestamp.csv", Excel::CSV);
    }

    if ($format === 'pdf') {
        return (new CustomersExport($params))->download("customers-$timestamp.pdf", Excel::DOMPDF);
    }

    return true;
}
```

Now in the test assign **$response** to the component call the export method and pass in the format (xlsx) and the timestamp.

Next set the expected filename and then the actual bu reading the response's payload and looking inside **['effects']['download']['name']** this will return the name from the download.

Then you can assert the expected and actual are identical.

```php
/ **@test** /
public function can_export_xlsx(): void
{
    $timestamp = now();

    $response = Livewire::test(Customers::class)
        ->call('export', 'xlsx', $timestamp)
        ->assertStatus(200);

    $expected = "customers-$timestamp.xlsx";
    $actual = $response->payload['effects']['download']['name'];

    self::assertSame($expected, $actual);

}
```

There may be a more direct way to test the download from Laravel Livewire but this appears like a good solution, if the component returns anything other then a 200 response the test will fail likewise if the response of the download does not match the expected filename the test will fail.