Preservar a oportunidade durante o registo e preparacao do perfil

This commit is contained in:
2026-10-30 21:22:40 +02:00
parent f5f5649cfc
commit 86b31f2840
8 changed files with 184 additions and 16 deletions
@@ -1,6 +1,7 @@
<?php
use App\Enums\PurchasingRole;
use App\Models\CandidateAccount;
use App\Models\Tenant;
use App\Models\User;
use App\Services\CandidateProfiles;
@@ -109,6 +110,32 @@ test('login rechecks selected publication and deadline and falls back to the pro
expect(DB::table('candidate_submissions')->count())->toBe(0);
});
test('selected opportunity survives registration and profile preparation until an explicit verified submission', function () {
$this->post($this->base.'/sair')->assertRedirect();
$this->postJson($this->base.'/registar', [...$this->credentials, 'email' => 'selected@example.invalid', 'opportunity_id' => $this->process->id])->assertRedirect($this->base.'/perfil');
$this->get($this->base.'/perfil')->assertInertia(fn (Assert $p) => $p->where('selectedOpportunity.id', $this->process->id)->where('profile.version', 0)->where('emailVerified', false));
$this->postJson($this->base.'/perfil', $this->profile)->assertRedirect();
$this->get($this->base.'/perfil')->assertInertia(fn (Assert $p) => $p->where('selectedOpportunity.id', $this->process->id)->where('profile.version', 1));
$this->postJson($this->base.'/oportunidades/'.$this->process->id, $this->body)->assertForbidden();
expect(DB::table('candidate_submissions')->count())->toBe(0);
$new = CandidateAccount::query()->where('email', 'selected@example.invalid')->firstOrFail();
$new->setAttribute('email_verified_at', now())->save();
$this->postJson($this->base.'/oportunidades/'.$this->process->id, $this->body)->assertRedirect()->assertSessionMissing('candidate.selected_opportunity');
expect(DB::table('candidate_submissions')->count())->toBe(1);
});
test('selection is cleared on withdrawal logout and account mismatch and malformed registration cannot create an account', function () {
$this->postJson($this->base.'/entrar', [...$this->credentials, 'opportunity_id' => $this->process->id])->assertRedirect();
app(CandidateSubmissions::class)->publish($this->admin, $this->process->id, [...$this->publication, 'version' => 1, 'active' => false]);
$this->get($this->base.'/perfil')->assertInertia(fn (Assert $p) => $p->where('selectedOpportunity', null)->where('accessStatus', 'opportunity_unavailable'))->assertSessionMissing('candidate.selected_opportunity');
$this->withSession(['candidate.selected_opportunity' => ['company' => $this->tenant->id, 'account' => $this->account->id + 999, 'id' => $this->process->id]])
->get($this->base.'/perfil')->assertInertia(fn (Assert $p) => $p->where('selectedOpportunity', null))->assertSessionMissing('candidate.selected_opportunity');
$this->post($this->base.'/sair')->assertSessionMissing('candidate.selected_opportunity');
$count = CandidateAccount::query()->count();
$this->postJson($this->base.'/registar', [...$this->credentials, 'email' => 'invalid-selection@example.invalid', 'opportunity_id' => 'https://example.invalid'])->assertUnprocessable();
expect(CandidateAccount::query()->count())->toBe($count);
});
test('electronic submission returns a scoped receipt and preserves the actual profile and answers', function () {
$this->get($this->base.'/oportunidades/'.$this->process->id)->assertInertia(fn (Assert $p) => $p->where('opportunity.description', 'Descrição pública fictícia da oportunidade.')->missing('opportunity.purpose')->missing('opportunity.selection'));
$url = $this->base.'/oportunidades/'.$this->process->id;
+28
View File
@@ -135,3 +135,31 @@ test('candidate profile renders geography and retained version without internal
expect(html).not.toContain('Aprovar');
expect(html).not.toContain('/pessoas');
});
test('a newly registered candidate can resume the selected opportunity after preparing the profile without automatic submission', () => {
const initialPage = {
...page,
component: 'candidate/profile',
props: {
...page.props,
companyId: 1,
email: 'new@example.invalid',
selectedOpportunity: { id: 7, title: 'Serviço escolhido' },
profile: {
version: 0,
data: {
name: '',
phone: '',
summary: '',
availability: { province: '', district: '', locality: '' },
},
},
},
};
const html = renderToString(
<App initialPage={initialPage} initialComponent={Profile} />,
);
expect(html).toContain('Serviço escolhido');
expect(html).toContain('/candidaturas/1/oportunidades/7');
expect(html).toContain('A candidatura só será enviada quando confirmar');
});