Teren-app/tests/Feature/Reports/NewReportsTest.php
Simon Pocrnjič 63e0958b66 Dev branch
2025-11-02 12:31:01 +01:00

203 lines
9.0 KiB
PHP

<?php
use App\Models\Action;
use App\Models\Activity;
use App\Models\Client;
use App\Models\ClientCase;
use App\Models\Decision;
use App\Models\Permission;
use App\Models\Person\Person;
use App\Models\Person\PersonGroup;
use App\Models\Person\PersonType;
use App\Models\Role;
use App\Models\Segment;
use App\Models\User;
function makeUserWithPermissions(array $perms = ['reports-view', 'reports-export']): \App\Models\User
{
$user = User::factory()->create();
$role = Role::create(['name' => 'Tester', 'slug' => 'tester']);
foreach ($perms as $slug) {
$p = Permission::firstOrCreate(['slug' => $slug], ['name' => strtoupper(str_replace('-', ' ', $slug))]);
$role->permissions()->syncWithoutDetaching($p->id);
}
$role->users()->syncWithoutDetaching($user->id);
return $user;
}
it('shows reports index with permission', function () {
$user = makeUserWithPermissions(['reports-view']);
$this->actingAs($user);
$resp = $this->get(route('reports.index'));
$resp->assertOk();
});
it('counts actions/decisions correctly', function () {
$user = makeUserWithPermissions(['reports-view']);
$this->actingAs($user);
$action = Action::factory()->create(['name' => 'Klic']);
$decision = Decision::create(['name' => 'Uspešno']);
$group = new PersonGroup;
$group->name = 'grp';
$group->save();
$type = PersonType::create(['name' => 'tip']);
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
$client = Client::create(['person_id' => $person->id]);
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
$resp = $this->getJson(route('reports.data', 'actions-decisions-counts'));
$resp->assertOk();
$json = $resp->json();
expect($json['data'][0]['action_name'])->toBe('Klic');
expect($json['data'][0]['decision_name'])->toBe('Uspešno');
expect($json['data'][0]['activities_count'])->toBe(3);
});
it('lists active contracts filtered by client', function () {
$user = makeUserWithPermissions(['reports-view']);
$this->actingAs($user);
// minimal person/client scaffolding
$group = new PersonGroup; $group->name = 'grp'; $group->save();
$type = PersonType::create(['name' => 'tip']);
$p1 = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
$p2 = Person::create(['first_name' => 'Bojan', 'last_name' => 'Drugi', 'full_name' => 'Bojan Drugi', 'group_id' => $group->id, 'type_id' => $type->id]);
$clientA = App\Models\Client::create(['person_id' => $p1->id]);
$clientB = App\Models\Client::create(['person_id' => $p2->id]);
$caseA = ClientCase::create(['client_id' => $clientA->id, 'person_id' => $p1->id, 'client_ref' => 'A']);
$caseB = ClientCase::create(['client_id' => $clientB->id, 'person_id' => $p2->id, 'client_ref' => 'B']);
$ctype = new App\Models\ContractType;
$ctype->name = 'Standard';
$ctype->save();
// Active contract for client A
App\Models\Contract::create([
'reference' => 'A-001',
'client_case_id' => $caseA->id,
'type_id' => $ctype->id,
'start_date' => now()->subDays(10)->toDateString(),
'end_date' => null,
]);
// Inactive for client A (ended yesterday)
App\Models\Contract::create([
'reference' => 'A-OLD',
'client_case_id' => $caseA->id,
'type_id' => $ctype->id,
'start_date' => now()->subMonths(2)->toDateString(),
'end_date' => now()->subDay()->toDateString(),
]);
// Active but for different client B (should be excluded by client filter)
App\Models\Contract::create([
'reference' => 'B-001',
'client_case_id' => $caseB->id,
'type_id' => $ctype->id,
'start_date' => now()->subDays(3)->toDateString(),
'end_date' => null,
]);
$resp = $this->getJson(route('reports.data', ['slug' => 'active-contracts', 'client_uuid' => $clientA->uuid, 'as_of' => now()->toDateString()]));
$resp->assertOk();
$json = $resp->json();
// Should list exactly the active one for client A
expect($json['data'])->toBeArray();
// Filter only references from result
$refs = array_map(fn ($r) => $r['contract_reference'] ?? null, $json['data']);
expect($refs)->toContain('A-001');
expect($refs)->not->toContain('A-OLD');
expect($refs)->not->toContain('B-001');
});
it('counts activities per segment', function () {
$user = makeUserWithPermissions(['reports-view']);
$this->actingAs($user);
$segment = Segment::create(['name' => 'Prioriteta A', 'description' => 'desc', 'active' => true]);
$action = Action::factory()->create(['segment_id' => $segment->id]);
$decision = Decision::create(['name' => 'OK']);
$group = new PersonGroup;
$group->name = 'grp';
$group->save();
$type = PersonType::create(['name' => 'tip']);
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
$client = Client::create(['person_id' => $person->id]);
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
$resp = $this->getJson(route('reports.data', 'segment-activity-counts'));
$resp->assertOk();
$json = $resp->json();
expect($json['data'][0]['segment_name'])->toBe('Prioriteta A');
expect($json['data'][0]['activities_count'])->toBe(2);
});
it('groups activities per day', function () {
$user = makeUserWithPermissions(['reports-view']);
$this->actingAs($user);
$action = Action::factory()->create();
$decision = Decision::create(['name' => 'OK']);
$group = new PersonGroup;
$group->name = 'grp';
$group->save();
$type = PersonType::create(['name' => 'tip']);
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
$client = Client::create(['person_id' => $person->id]);
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
// Create two today and one yesterday (explicit timestamps via insert to avoid auto-timestamp override)
Activity::query()->insert([
['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now(), 'updated_at' => now()],
['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now(), 'updated_at' => now()],
['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id, 'created_at' => now()->subDay(), 'updated_at' => now()->subDay()],
]);
$resp = $this->getJson(route('reports.data', ['slug' => 'activities-per-period', 'period' => 'day']));
$resp->assertOk();
$json = collect($resp->json('data'));
// Find today row
$todayRow = $json->first(function ($r) {
return str_starts_with((string) $r['period'], date('Y-m-d'));
});
expect($todayRow)->not()->toBeNull();
expect($todayRow['activities_count'])->toBe(2);
});
it('counts activities per decision only', function () {
$user = makeUserWithPermissions(['reports-view']);
$this->actingAs($user);
$decision = Decision::create(['name' => 'OK']);
$group = new PersonGroup;
$group->name = 'grp';
$group->save();
$type = PersonType::create(['name' => 'tip']);
$person = Person::create(['first_name' => 'Ana', 'last_name' => 'Test', 'full_name' => 'Ana Test', 'group_id' => $group->id, 'type_id' => $type->id]);
$client = Client::create(['person_id' => $person->id]);
$case = ClientCase::create(['client_id' => $client->id, 'person_id' => $person->id, 'client_ref' => 'X']);
$action = Action::factory()->create();
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
Activity::create(['action_id' => $action->id, 'decision_id' => $decision->id, 'client_case_id' => $case->id]);
$resp = $this->getJson(route('reports.data', 'decisions-counts'));
$resp->assertOk();
$json = $resp->json();
expect($json['data'][0]['decision_name'])->toBe('OK');
expect($json['data'][0]['activities_count'])->toBe(3);
});