commit13
This commit is contained in:
@@ -523,3 +523,147 @@ test('the person concluding technical clarification cannot approve the hiring se
|
||||
hiringCommand($this, $this->approver, $record, 'confirm', ['outcome' => 'approved'])->assertForbidden();
|
||||
$this->get('/pessoas')->assertInertia(fn (Assert $page) => $page->where('workdesk.counts.approvals', 0));
|
||||
});
|
||||
|
||||
test('people reports reuse only visible processes and export filtered facts without private fields', function () {
|
||||
$record = hiringCreate($this);
|
||||
$this->actingAs($this->approver)->postJson('/pessoas', [...$this->body, 'operation_key' => (string) Str::uuid(), 'title' => 'PROCESSO RESERVADO', 'kind' => 'staff'])->assertRedirect();
|
||||
$this->actingAs($this->preparer)->get('/pessoas/relatorios')->assertOk()->assertInertia(fn (Assert $page) => $page
|
||||
->component('people/reports')->where('processes.total', 1)->has('summary', 1)
|
||||
->where('processes.data.0.id', $record->id)->missing('processes.data.0.rules')->missing('processes.data.0.contract'));
|
||||
$csv = $this->get('/pessoas/relatorios.csv')->assertOk();
|
||||
expect($csv->streamedContent())->toContain('PES-'.$record->id)->not->toContain('PROCESSO RESERVADO');
|
||||
expect($csv->headers->get('Cache-Control'))->toContain('no-store');
|
||||
$this->get('/pessoas/relatorios?kind=staff')->assertInertia(fn (Assert $page) => $page->where('processes.total', 0)->has('summary', 0));
|
||||
$this->get('/pessoas/relatorios?status=selected')->assertInertia(fn (Assert $page) => $page->where('processes.total', 0));
|
||||
$this->get('/pessoas/relatorios?search=PES-'.$record->id)->assertInertia(fn (Assert $page) => $page->where('processes.total', 1));
|
||||
DB::table('people_process_access')->where('people_process_id', $record->id)->where('user_id', $this->preparer->id)->update(['expires_at' => now()->subMinute()]);
|
||||
$this->get('/pessoas/relatorios')->assertInertia(fn (Assert $page) => $page->where('processes.total', 0));
|
||||
expect($this->get('/pessoas/relatorios.csv')->streamedContent())->not->toContain('PES-'.$record->id);
|
||||
});
|
||||
|
||||
test('people report dates and csv protect scope and spreadsheet cells', function () {
|
||||
$this->body['title'] = '=FORMULA DE ENSAIO';
|
||||
$record = hiringCreate($this);
|
||||
$csv = $this->get('/pessoas/relatorios.csv')->assertOk()->streamedContent();
|
||||
expect($csv)->toContain("'=FORMULA DE ENSAIO");
|
||||
$this->get('/pessoas/relatorios?from='.today()->addDay()->toDateString())->assertInertia(fn (Assert $page) => $page->where('processes.total', 0));
|
||||
$this->getJson('/pessoas/relatorios?from=2026-11-02&to=2026-11-01')->assertUnprocessable();
|
||||
$foreign = User::factory()->create(['tenant_id' => Tenant::query()->create(['name' => 'Empresa distinta'])->id, 'purchasing_role' => PurchasingRole::Admin]);
|
||||
$this->actingAs($foreign)->get('/pessoas/relatorios')->assertInertia(fn (Assert $page) => $page->where('processes.total', 0));
|
||||
expect($this->get('/pessoas/relatorios.csv')->streamedContent())->not->toContain('PES-'.$record->id);
|
||||
});
|
||||
|
||||
test('application report reuses eligible assessments and preserves approved selection counts without private content', function () {
|
||||
$record = hiringAssessment($this);
|
||||
$application = DB::table('people_applications')->sole();
|
||||
$url = '/pessoas/relatorios?view=applications';
|
||||
$this->actingAs($this->preparer)->get($url)->assertInertia(fn (Assert $page) => $page
|
||||
->where('applicationMetrics.'.$record->id.'.registered', 1)
|
||||
->where('applicationMetrics.'.$record->id.'.evaluation_pending', 1)
|
||||
->where('applicationMetrics.'.$record->id.'.evaluation_unstarted', 1));
|
||||
hiringCommand($this, $this->reviewer, $record, 'evaluate', ['application_id' => $application->id, 'answers' => [
|
||||
['score' => '8', 'evidence' => 'Evidência fictícia de competências.'], ['score' => '7', 'evidence' => 'Evidência fictícia de experiência.'],
|
||||
]])->assertRedirect();
|
||||
$this->actingAs($this->preparer)->get($url)->assertInertia(fn (Assert $page) => $page
|
||||
->where('applicationMetrics.'.$record->id.'.evaluation_complete', 1)
|
||||
->where('applicationMetrics.'.$record->id.'.evaluation_pending', 0)
|
||||
->missing('applicationMetrics.'.$record->id.'.reviews')->missing('applicationMetrics.'.$record->id.'.name'));
|
||||
hiringCommand($this, $this->preparer, $record, 'select', ['application_id' => $application->id])->assertRedirect();
|
||||
hiringCommand($this, $this->approver, $record, 'confirm', ['outcome' => 'approved'])->assertRedirect();
|
||||
DB::table('people_process_access')->where('people_process_id', $record->id)->where('user_id', $this->reviewer->id)->update(['expires_at' => now()->subMinute()]);
|
||||
$this->actingAs($this->preparer)->get($url)->assertInertia(fn (Assert $page) => $page
|
||||
->where('applicationMetrics.'.$record->id.'.basis', 'selection_snapshot')
|
||||
->where('applicationMetrics.'.$record->id.'.evaluation_complete', 1));
|
||||
$this->actingAs($this->approver)->get($url)->assertInertia(fn (Assert $page) => $page
|
||||
->where('applicationMetrics.'.$record->id.'.portal_received', null));
|
||||
expect($this->get('/pessoas/relatorios.csv?view=applications')->streamedContent())->toContain('Sem acesso')->toContain('Selecção preservada')->not->toContain($application->name);
|
||||
});
|
||||
|
||||
test('selection report follows return approval and draft while restricting contract metadata', function (string $kind) {
|
||||
$record = hiringAssessment($this, $kind);
|
||||
$application = DB::table('people_applications')->sole();
|
||||
$url = '/pessoas/relatorios?view=selections';
|
||||
$prefix = 'selectionMetrics.'.$record->id.'.';
|
||||
$this->actingAs($this->preparer)->get($url)->assertInertia(fn (Assert $page) => $page
|
||||
->where($prefix.'selection_state', 'Sem proposta de selecção')->where($prefix.'contract_reference', null));
|
||||
hiringCommand($this, $this->reviewer, $record, 'evaluate', ['application_id' => $application->id, 'answers' => [
|
||||
['score' => '8', 'evidence' => 'Evidência fictícia de competências.'], ['score' => '7', 'evidence' => 'Evidência fictícia de experiência.'],
|
||||
]])->assertRedirect();
|
||||
hiringCommand($this, $this->preparer, $record, 'select', ['application_id' => $application->id])->assertRedirect();
|
||||
$this->get($url)->assertInertia(fn (Assert $page) => $page->where($prefix.'selection_state', 'Proposta por conferir'));
|
||||
hiringCommand($this, $this->approver, $record, 'confirm', ['outcome' => 'returned'])->assertRedirect();
|
||||
$this->get($url)->assertInertia(fn (Assert $page) => $page->where($prefix.'selection_state', 'Proposta devolvida'));
|
||||
hiringCommand($this, $this->preparer, $record, 'select', ['application_id' => $application->id])->assertRedirect();
|
||||
hiringCommand($this, $this->approver, $record, 'confirm', ['outcome' => 'approved'])->assertRedirect();
|
||||
$this->get($url)->assertInertia(fn (Assert $page) => $page->where($prefix.'selection_state', 'Selecção aprovada')->where($prefix.'pending', 'Preparar minuta contratual'));
|
||||
hiringCommand($this, $this->preparer, $record, 'contract', ['reference' => '=MINUTA-RESERVADA', 'starts_on' => today()->toDateString(), 'terms' => 'TERMOS-CONTRATUAIS-RESERVADOS-NAO-EXPORTAR'])->assertRedirect();
|
||||
$this->get($url)->assertInertia(fn (Assert $page) => $page->where($prefix.'contract_reference', '=MINUTA-RESERVADA')->missing($prefix.'terms'));
|
||||
$csv = $this->get('/pessoas/relatorios.csv?view=selections')->streamedContent();
|
||||
expect($csv)->toContain("'=MINUTA-RESERVADA")->not->toContain('TERMOS-CONTRATUAIS-RESERVADOS');
|
||||
$this->actingAs($this->approver)->get($url)->assertInertia(fn (Assert $page) => $page
|
||||
->where($prefix.'contract_reference', 'Sem acesso')->where($prefix.'contract_starts_on', 'Sem acesso'));
|
||||
expect($this->get('/pessoas/relatorios.csv?view=selections')->streamedContent())->not->toContain('MINUTA-RESERVADA');
|
||||
DB::table('people_process_access')->where('people_process_id', $record->id)->where('user_id', $this->approver->id)->update(['expires_at' => now()->subMinute()]);
|
||||
$this->get($url)->assertInertia(fn (Assert $page) => $page->where('selectionMetrics', [])->where('processes.total', 0));
|
||||
})->with(['service', 'staff']);
|
||||
|
||||
test('deadline report distinguishes process alerts from personal tasks and respects expired access', function () {
|
||||
$record = hiringCreate($this);
|
||||
$this->travel(2)->days();
|
||||
$url = '/pessoas/relatorios?view=deadlines';
|
||||
$this->actingAs($this->preparer)->get($url)->assertInertia(fn (Assert $p) => $p
|
||||
->where('deadlineReport.tasks', 0)->where('deadlineReport.alerts', 1)->where('deadlineReport.overdue_items', 1)
|
||||
->where('deadlineReport.items.0.days_overdue', 2)
|
||||
->where('deadlineReport.items.0.responsibility', 'Alerta do processo; sem atribuição pessoal'));
|
||||
expect($this->get('/pessoas/relatorios.csv?view=deadlines')->streamedContent())->toContain('PES-'.$record->id)->toContain('Dias de atraso');
|
||||
DB::table('people_process_access')->where('people_process_id', $record->id)->where('user_id', $this->preparer->id)->update(['expires_at' => now()->subMinute()]);
|
||||
$this->get($url)->assertInertia(fn (Assert $p) => $p->has('deadlineReport.items', 0)->where('deadlineReport.overdue_items', 0));
|
||||
expect($this->get('/pessoas/relatorios.csv?view=deadlines')->streamedContent())->not->toContain('PES-'.$record->id);
|
||||
});
|
||||
|
||||
test('deadline report reuses only the current actors work and never invents evaluation deadlines', function () {
|
||||
$record = hiringAssessment($this);
|
||||
$url = '/pessoas/relatorios?view=deadlines';
|
||||
$this->actingAs($this->reviewer)->get($url)->assertInertia(fn (Assert $p) => $p
|
||||
->where('deadlineReport.tasks', 1)->where('deadlineReport.without_deadline', 1)->where('deadlineReport.overdue_items', 0)
|
||||
->where('deadlineReport.items.0.due_on', null)->where('deadlineReport.items.0.days_overdue', null)
|
||||
->where('deadlineReport.items.0.responsibility', 'Minha intervenção autorizada')
|
||||
->missing('deadlineReport.items.0.answers')->missing('deadlineReport.items.0.score_minor'));
|
||||
expect($this->get('/pessoas/relatorios.csv?view=deadlines')->streamedContent())->toContain('Sem prazo definido')->toContain('Não determinável');
|
||||
$this->actingAs($this->preparer)->get($url)->assertInertia(fn (Assert $p) => $p->where('deadlineReport.tasks', 0));
|
||||
});
|
||||
|
||||
test('deadline windows distinguish future today and overdue calendar dates', function () {
|
||||
$this->body['closes_on'] = today()->addDays(2)->toDateString();
|
||||
hiringCreate($this);
|
||||
$this->actingAs($this->reviewer);
|
||||
$base = '/pessoas/relatorios?view=deadlines&deadline_window=';
|
||||
$this->get($base.'future')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 1)->where('deadlineReport.approvals', 1));
|
||||
$this->get($base.'today')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 0));
|
||||
$this->travel(2)->days();
|
||||
$this->get($base.'today')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 1)->where('deadlineReport.items.0.days_overdue', 0));
|
||||
$this->get($base.'overdue')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 0));
|
||||
$this->travel(1)->days();
|
||||
$this->get($base.'overdue')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 1)->where('deadlineReport.items.0.days_overdue', 1));
|
||||
$this->get($base.'undated')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 0));
|
||||
$this->getJson($base.'invalid')->assertUnprocessable();
|
||||
$this->getJson('/pessoas/relatorios?view=deadlines&deadline_page=0')->assertUnprocessable();
|
||||
});
|
||||
|
||||
test('deadline totals cover all matching occurrences while screen pagination and csv keep the same scope', function () {
|
||||
$record = hiringCreate($this);
|
||||
hiringCommand($this, $this->reviewer, $record, 'open')->assertRedirect();
|
||||
foreach (range(1, 30) as $number) {
|
||||
hiringCommand($this, $this->preparer, $record, 'apply', ['operation_key' => (string) Str::uuid(), 'name' => 'Pessoa fictícia '.$number,
|
||||
'reference' => 'CAND-'.$number, 'summary' => 'Experiência fictícia pertinente ao processo.', 'received_on' => today()->toDateString()])->assertRedirect();
|
||||
}
|
||||
hiringCommand($this, $this->preparer, $record, 'close')->assertRedirect();
|
||||
$this->actingAs($this->reviewer);
|
||||
$url = '/pessoas/relatorios?view=deadlines&deadline_window=undated';
|
||||
$this->get($url)->assertInertia(fn (Assert $p) => $p->where('deadlineReport.tasks', 30)->where('deadlineReport.total_items', 30)
|
||||
->where('deadlineReport.matching_processes', 1)->has('deadlineReport.items', 25)->where('deadlineReport.pagination.last_page', 2));
|
||||
$this->get($url.'&deadline_page=2')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.tasks', 30)->has('deadlineReport.items', 5));
|
||||
$csv = $this->get('/pessoas/relatorios.csv?view=deadlines&deadline_window=undated&deadline_page=2')->streamedContent();
|
||||
expect(substr_count($csv, 'Avaliar candidatura #'))->toBe(30);
|
||||
$this->get('/pessoas/relatorios?view=deadlines&deadline_window=overdue')->assertInertia(fn (Assert $p) => $p->where('deadlineReport.total_items', 0));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user