downloadSales( $this->tenant(), collect([$this->sale()]), 'America/La_Paz', ); $this->assertExcelResponse( $response, 'ventas_acme_20260824_135300.xlsx', function (string $path): void { $sheet = IOFactory::load($path)->getActiveSheet(); $this->assertSame('Ventas', $sheet->getTitle()); $this->assertSame('Cliente Test', $sheet->getCell('C2')->getValue()); $this->assertSame('Confirmado', $sheet->getCell('E2')->getValue()); $this->assertSame(25000.0, $sheet->getCell('F2')->getValue()); }, ); } public function test_it_downloads_the_modification_history_as_an_excel_file(): void { $sale = $this->sale(); $admin = (new User)->forceFill([ 'id' => 10, 'nombre_apellido' => 'Admin Test', 'email' => 'admin@example.test', ]); $modification = (new ValueChange)->forceFill([ 'id' => 1, 'trackable_id' => $sale->id, 'attribute' => 'status', 'old_value' => Purchase::STATUS_PENDING_PAYMENT, 'new_value' => Purchase::STATUS_PAID, 'changed_at' => now(), 'actor_type' => 'user', ]); $modification->setRelation('trackable', $sale); $modification->setRelation('user', $admin); $response = app(AdminAppSaleExcelService::class)->downloadModifications( $this->tenant(), collect([$modification]), 'America/La_Paz', ); $this->assertExcelResponse( $response, 'historial_modificaciones_acme_20260824_135300.xlsx', function (string $path): void { $sheet = IOFactory::load($path)->getActiveSheet(); $this->assertSame('Modificaciones', $sheet->getTitle()); $this->assertSame('#15', $sheet->getCell('C2')->getValue()); $this->assertSame('pending_payment', $sheet->getCell('F2')->getValue()); $this->assertSame('paid', $sheet->getCell('G2')->getValue()); $this->assertSame('Admin Test', $sheet->getCell('H2')->getValue()); }, ); } /** @param callable(string): void $assertSpreadsheet */ private function assertExcelResponse( StreamedResponse $response, string $filename, callable $assertSpreadsheet, ): void { $this->assertSame( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', $response->headers->get('content-type'), ); $this->assertStringContainsString( "attachment; filename={$filename}", (string) $response->headers->get('content-disposition'), ); ob_start(); ($response->getCallback())(); $contents = ob_get_clean(); $this->assertIsString($contents); $this->assertStringStartsWith('PK', $contents); $path = tempnam(sys_get_temp_dir(), 'shopit_excel_'); $this->assertNotFalse($path); try { file_put_contents($path, $contents); $assertSpreadsheet($path); } finally { @unlink($path); } } private function tenant(): Tenant { return (new Tenant)->forceFill([ 'codigo' => 'acme', 'nombre' => 'Acme Eventos', ]); } private function sale(): Purchase { return (new Purchase)->forceFill([ 'id' => 15, 'created_at' => now(), 'nombre_apellido' => 'Cliente Test', 'quantity' => 2, 'status' => Purchase::STATUS_PAID, 'total' => '25000.00', 'tickets_count' => 2, ]); } }