182 lines
6.6 KiB
TypeScript
182 lines
6.6 KiB
TypeScript
import { App } from '@inertiajs/react';
|
|
import type { Page } from '@inertiajs/core';
|
|
import { renderToString } from 'react-dom/server';
|
|
import { expect, test } from 'vitest';
|
|
import Entry from '@/pages/candidate/entry';
|
|
import Profile from '@/pages/candidate/profile';
|
|
import { CandidateAvailability } from '@/components/candidate-availability';
|
|
|
|
const page = {
|
|
component: 'candidate/entry',
|
|
url: '/candidaturas/1',
|
|
version: 'candidate',
|
|
props: { errors: {} },
|
|
clearHistory: false,
|
|
encryptHistory: true,
|
|
} satisfies Page;
|
|
|
|
test('received availability renders primary and additional locations without requiring a new profile format', () => {
|
|
const availability = {
|
|
province: 'Província A',
|
|
district: 'Distrito A',
|
|
locality: 'Localidade A',
|
|
};
|
|
const additional = {
|
|
province: 'Província B',
|
|
district: 'Distrito B',
|
|
locality: 'Localidade B',
|
|
};
|
|
const html = renderToString(
|
|
<CandidateAvailability
|
|
data={{ availability, additional_availability: [additional] }}
|
|
/>,
|
|
);
|
|
expect(html).toContain('Localidade A');
|
|
expect(html).toContain('Localidade B');
|
|
expect(
|
|
renderToString(<CandidateAvailability data={{ availability }} />),
|
|
).toContain('Localidade A');
|
|
expect(renderToString(<CandidateAvailability />)).toBe('');
|
|
});
|
|
test.each([true, false])(
|
|
'registration availability (%s) preserves existing login and does not promise submission',
|
|
(registration_open) => {
|
|
const initialPage = {
|
|
...page,
|
|
props: {
|
|
...page.props,
|
|
company: { id: 1, name: 'Empresa fictícia' },
|
|
portal: {
|
|
version: 2,
|
|
registration_open,
|
|
notice: 'Aviso fictício da empresa.',
|
|
},
|
|
},
|
|
};
|
|
const html = renderToString(
|
|
<App initialPage={initialPage} initialComponent={Entry} />,
|
|
);
|
|
expect(html).toContain('Entrar na minha área');
|
|
expect(html.includes('Criar a minha conta')).toBe(registration_open);
|
|
expect(html).toContain('Criar um perfil não constitui candidatura');
|
|
expect(html).not.toContain('/dashboard');
|
|
},
|
|
);
|
|
test('public entry shows published opportunities and pagination while keeping application behind candidate login', () => {
|
|
const initialPage = {
|
|
...page,
|
|
props: {
|
|
...page.props,
|
|
company: { id: 1, name: 'Empresa fictícia' },
|
|
portal: {
|
|
version: 1,
|
|
registration_open: false,
|
|
notice: 'Aviso fictício.',
|
|
},
|
|
opportunities: {
|
|
data: [
|
|
{
|
|
id: 7,
|
|
title: 'Serviço publicado',
|
|
kind: 'service',
|
|
closes_on: '2026-11-10',
|
|
description: 'Descrição pública do serviço.',
|
|
},
|
|
],
|
|
prev_page_url: null,
|
|
next_page_url: '/candidaturas/1?opportunities_page=2',
|
|
},
|
|
},
|
|
};
|
|
const html = renderToString(
|
|
<App initialPage={initialPage} initialComponent={Entry} />,
|
|
);
|
|
expect(html).toContain('Serviço publicado');
|
|
expect(html).toContain('Descrição pública do serviço.');
|
|
expect(html).toContain('Prestação de serviços');
|
|
expect(html).toContain('href="#candidate-login"');
|
|
expect(html).toContain('/candidaturas/1?opportunities_page=2');
|
|
expect(html).not.toContain('/oportunidades/7');
|
|
expect(html).not.toContain('anexos ainda está em desenvolvimento');
|
|
});
|
|
|
|
test('candidate profile renders geography and retained version without internal evaluation controls', () => {
|
|
const initialPage = {
|
|
...page,
|
|
component: 'candidate/profile',
|
|
props: {
|
|
...page.props,
|
|
companyId: 1,
|
|
email: 'test@example.invalid',
|
|
submissions: [
|
|
{
|
|
id: 8,
|
|
reference: 'CAND-FICTICIA',
|
|
created_at: '2026-10-30',
|
|
title: 'Título preservado do processo',
|
|
},
|
|
],
|
|
submissionPagination: {
|
|
prev: null,
|
|
next: '/candidaturas/1/perfil?submissions_page=2',
|
|
total: 21,
|
|
},
|
|
accessStatus: 'opportunity_unavailable',
|
|
profile: {
|
|
version: 3,
|
|
data: {
|
|
name: 'Pessoa fictícia',
|
|
phone: '',
|
|
summary: 'Perfil fictício.',
|
|
availability: {
|
|
province: 'Província fictícia',
|
|
district: 'Distrito fictício',
|
|
locality: 'Localidade fictícia',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
const html = renderToString(
|
|
<App initialPage={initialPage} initialComponent={Profile} />,
|
|
);
|
|
expect(html).toContain('value="Província fictícia"');
|
|
expect(html).toContain('value="Distrito fictício"');
|
|
expect(html).toContain('value="Localidade fictícia"');
|
|
expect(html).toContain('Guardar nova versão do perfil');
|
|
expect(html).toContain('Título preservado do processo');
|
|
expect(html).toContain('Mais comprovativos');
|
|
expect(html).toContain('/candidaturas/1/perfil?submissions_page=2');
|
|
expect(html).toContain('a oportunidade escolhida já não está disponível');
|
|
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');
|
|
});
|