create(); $contracts = Contract::factory()->count(2)->create(); foreach ($contracts as $contract) { DB::table('contract_segment')->insert([ 'contract_id' => $contract->id, 'segment_id' => $segment->id, 'active' => true, 'created_at' => now(), 'updated_at' => now(), ]); } $user = User::factory()->create(); $request = $this->makeExportRequest([ 'scope' => 'current', 'columns' => ['reference', 'client'], 'page' => 1, 'per_page' => 1, ], $user); $response = app(SegmentController::class)->export($request, $segment); $this->assertInstanceOf(BinaryFileResponse::class, $response); $expectedName = $this->expectedFilename($segment); Excel::assertDownloaded($expectedName, function (SegmentContractsExport $export) { $this->assertSame(1, $export->query()->get()->count()); return true; }); } public function test_exports_full_segment_when_scope_all(): void { Excel::fake(); Carbon::setTestNow('2025-12-10 12:05:00'); $segment = Segment::factory()->create(); $contracts = Contract::factory()->count(3)->create(); foreach ($contracts as $contract) { DB::table('contract_segment')->insert([ 'contract_id' => $contract->id, 'segment_id' => $segment->id, 'active' => true, 'created_at' => now(), 'updated_at' => now(), ]); } $user = User::factory()->create(); $request = $this->makeExportRequest([ 'scope' => 'all', 'columns' => SegmentContractsExport::allowedColumns(), ], $user); $response = app(SegmentController::class)->export($request, $segment); $this->assertInstanceOf(BinaryFileResponse::class, $response); $request = $this->makeExportRequest([ 'scope' => 'all', 'columns' => SegmentContractsExport::allowedColumns(), ], $user); $expectedName = $this->expectedFilename($segment); Excel::assertDownloaded($expectedName, function (SegmentContractsExport $export) use ($contracts) { $this->assertSame($contracts->count(), $export->query()->get()->count()); return true; }); } public function test_export_filename_includes_client_name_when_filtered(): void { Excel::fake(); Carbon::setTestNow('2025-12-10 12:10:00'); $segment = Segment::factory()->create(['name' => 'VIP Segment']); $contract = Contract::factory()->create(); DB::table('contract_segment')->insert([ 'contract_id' => $contract->id, 'segment_id' => $segment->id, 'active' => true, 'created_at' => now(), 'updated_at' => now(), ]); $client = Client::factory() ->for(PersonModel::factory(['full_name' => 'Ana Novak']), 'person') ->create(); $contract->clientCase?->update(['client_id' => $client->id]); $user = User::factory()->create(); $request = $this->makeExportRequest([ 'scope' => 'all', 'columns' => ['reference'], 'client' => (string) $client->uuid, ], $user); $expectedName = $this->expectedFilename($segment, 'Ana Novak'); $response = app(SegmentController::class)->export($request, $segment); $this->assertInstanceOf(BinaryFileResponse::class, $response); Excel::assertDownloaded($expectedName, function (SegmentContractsExport $export) { $this->assertSame(1, $export->query()->get()->count()); return true; }); } public function test_column_formats_apply_to_reference_and_date_columns(): void { $export = new SegmentContractsExport( Contract::query(), ['reference', 'start_date', 'client', 'end_date'] ); $this->assertSame( [ 'A' => SegmentContractsExport::TEXT_EXCEL_FORMAT, 'B' => SegmentContractsExport::DATE_EXCEL_FORMAT, 'D' => SegmentContractsExport::DATE_EXCEL_FORMAT, ], $export->columnFormats() ); } public function test_date_values_are_converted_to_excel_serial_numbers(): void { $contract = Contract::factory()->make([ 'start_date' => '2025-10-30', ]); $export = new SegmentContractsExport( Contract::query(), ['start_date'] ); $row = $export->map($contract); $this->assertIsFloat($row[0]); $this->assertGreaterThan(40000, $row[0]); } private function makeExportRequest(array $payload, User $user): ExportSegmentContractsRequest { $request = ExportSegmentContractsRequest::create('/segments/export', 'POST', $payload); $request->setContainer($this->app); $request->setRedirector($this->app->make(Redirector::class)); $request->setUserResolver(fn () => $user); $request->setRouteResolver(fn () => (object) [ 'parameter' => fn () => null, ]); $request->validateResolved(); return $request; } private function expectedFilename(Segment $segment, ?string $clientName = null): string { $base = now()->format('dmy').'_'.$this->slugify($segment->name).'-Pogodbe'; if ($clientName) { return sprintf('%s_%s.xlsx', $base, $this->slugify($clientName)); } return sprintf('%s.xlsx', $base); } private function slugify(string $value): string { $slug = trim(preg_replace('/[^a-zA-Z0-9]+/', '-', $value), '-'); return $slug !== '' ? $slug : 'data'; } }