210 lines
6.5 KiB
PHP
210 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Exports\SegmentContractsExport;
|
|
use App\Http\Controllers\SegmentController;
|
|
use App\Http\Requests\ExportSegmentContractsRequest;
|
|
use App\Models\Client;
|
|
use App\Models\Contract;
|
|
use App\Models\Person\Person as PersonModel;
|
|
use App\Models\Segment;
|
|
use App\Models\User;
|
|
use Illuminate\Routing\Redirector;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
|
|
class SegmentExportTest extends \Tests\TestCase
|
|
{
|
|
public function test_exports_only_current_page_when_requested(): void
|
|
{
|
|
Excel::fake();
|
|
Carbon::setTestNow('2025-12-10 12:00:00');
|
|
|
|
$segment = Segment::factory()->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';
|
|
}
|
|
}
|