Livewireでのファイルダウンロードテスト
Livewireを使ったファイルダウンロード処理のテストを書く際、一癖あったためまとめる
テスト対象のコンポーネント
downloadメソッドが呼ばれたら、csvファイルをダウンロードする
サンプルコード
code:CsvDownload.php
class CsvDownload extends Component
{
public function render(): View
{
return view('livewire.download')
}
public function download(): StreamResponse
{
$filename = 'users_' . date('Y-m-d_H-i-s') . '.csv';
$headerColumns = 'ID', '名前', 'メールアドレス';
$data = [
'id' => 1, 'name' => '田中太郎', 'email' => 'tanaka@example.com',
'id' => 2, 'name' => '佐藤花子', 'email' => 'sato@example.com',
'id' => 3, 'name' => '鈴木一郎', 'email' => 'suzuki@example.com',
'id' => 4, 'name' => '山田美咲', 'email' => 'yamada@example.com',
];
return Response::streamDownload(
function() use ($headerColumns, $data) {
$stream = fopen('php://temp', 'w');
fputcsv($stream, $headerColumns);
foreach($data as $row) {
fputcsv($stream, $row);
}
fclose($stream);
},
$filename,
'Content-Type' => 'text/csv'
)
}
}
テストコード
Livewireでは、ファイルダウンロード時にファイルコンテンツをbase64にエンコードしてフロントエンドに渡し、クライアント側でデコードしバイナリに変換してダウンロードするようにしている
ajaxでダウンロード処理をする際は、上記のようなフローになるっぽい
https://qiita.com/kenta8813/items/d0307c258d61ecebb064
また、クライアントで実行されるダウンロード処理・データや、画面更新などの副作用処理・データはLivewire Componentのレスポンスに含まれているeffects プロパティ内に含まれている
画面を非同期更新する際は、Livewireがいい感じにupdateエンドポイントを叩いて、そのレスポンスに含まれているeffectsの値を使って画面を更新している
https://scrapbox.io/files/6846de11dd56a34dfe0b99f2.png
なのでLivewire::testで`ファイルダウンロードのテストをする際も、上記のことを把握しておかないと、あれ?ダウンロード対象のコンテンツがないぞ?となる、、
サンプルコード
code:CsvDownloadTest.php
class CsvDownloadTest extends TestCase
{
public function test_download(): void
{
$response = Livewire::test(CsvDownload::class)
->call('download');
// ダウンロードコンテンツを取得
$download = $response->effects'download';
// ファイルコンテンツはbase64化されていることに注意
$base64Content = $download'content';
// デコードして下のデータに変換
$content = base64_decode($base64Content);
$actualRows = expload("\n", $content)
$this->assertSame('ID,名前,メールアドレス', $actualRows0);
}
}
補足
base64化している該当コード
https://github.com/livewire/livewire/blob/d970beb2520f779f4676f902bf5ac06f73612309/src/Features/SupportFileDownloads/SupportFileDownloads.php#L12-L39
#Laravel #Livewire