Skip to content

Commit

Permalink
feat(emplois): passage ssr + scroll restoration (#2273)
Browse files Browse the repository at this point in the history
  • Loading branch information
Naorid committed Nov 27, 2023
1 parent 9dae1e0 commit a8b83be
Show file tree
Hide file tree
Showing 16 changed files with 346 additions and 185 deletions.
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ API_ONISEP_ACCOUNT_PASSWORD=password-bidon
API_ONISEP_APPLICATION_ID=123456789

# API POLE EMPLOI
API_POLE_EMPLOI_IS_MOCK_ACTIVE=1
API_POLE_EMPLOI_OFFRES_URL=https://api.pole-emploi.io/partenaire/offresdemploi/v2/offres
API_POLE_EMPLOI_REFERENTIEL_URL=https://api.pole-emploi.io/partenaire/offresdemploi/v2/referentiel
POLE_EMPLOI_CONNECT_CLIENT_ID=POLE_EMPLOI_CONNECT_CLIENT_ID
Expand Down
89 changes: 33 additions & 56 deletions cypress/e2e/emplois.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,61 @@

import { stringify } from 'querystring';

import { aBarmanOffre, aRésultatEchantillonOffre } from '~/server/offres/domain/offre.fixture';

import { interceptGet } from '../interceptGet';
import { Success } from '~/server/errors/either';
import { Offre, RésultatsRechercheOffre } from '~/server/offres/domain/offre';
import {
getOffreRepositoryMockResults,
searchOffreRepositoryMockResults,
} from '~/server/offres/infra/repositories/mockOffre.repository';

describe('Page de recherche d’emplois', () => {
beforeEach(() => {
cy.viewport('iphone-x');
cy.intercept(
'/api/emplois*',
aRésultatEchantillonOffre(),
).as('recherche-emplois');
});

context('Parcours standard', () => {
it('affiche 15 résultats par défaut', () => {
const expectedResult = searchOffreRepositoryMockResults({ page: 1 }) as Success<RésultatsRechercheOffre>;

cy.visit('/emplois');
cy.wait('@recherche-emplois');

cy.findByRole('list', { name: /Offres demplois/i })
.children()
.should('have.length', 15);
.should('have.length', expectedResult.result.résultats.length);
cy.findByRole('list', { name: /Offres demplois/i })
.children()
.first()
.should('contain.text', 'Barman / Barmaid (H/F)');
});

it('place le focus sur le premier input du formulaire de recherche', () => {
cy.visit('/emplois');
cy.wait('@recherche-emplois');

cy.findAllByRole('textbox').first().should('have.focus');
.should('contain.text', expectedResult.result.résultats[0].intitulé);
});

context('quand l‘utilisateur rentre un mot clé', () => {
it('filtre les résultats par mot clé', () => {
const expectedResult = searchOffreRepositoryMockResults({ motClé: 'barman', page: 1 }) as Success<RésultatsRechercheOffre>;

cy.visit('/emplois');
cy.wait('@recherche-emplois');

cy.findByRole('textbox', { name: /Métier, mot-clé/i }).type('barman'),
interceptGet({
actionBeforeWaitTheCall: () =>
cy.findByRole('button', { name: /Rechercher/i }).click(),
alias: 'recherche-emplois',
path: '/api/emplois*',
response: JSON.stringify({ nombreRésultats: 1, résultats: [aBarmanOffre()] }),
});

cy.findByRole('list', { name: /Offres demplois/i }).children().should('have.length', 1);

cy.findByRole('textbox', { name: /Métier, mot-clé/i }).type('barman');

cy.findByRole('button', { name: /Rechercher/i }).click();

cy.findByRole('list', { name: /Offres demplois/i })
.children()
.should('have.length', expectedResult.result.résultats.length);
});
});

context('quand l‘utilisateur veut sélectionner la première offre', () => {
it('navigue vers le détail de l‘offre', () => {
const expectedResult = getOffreRepositoryMockResults() as Success<Offre>;

cy.visit('/emplois');
cy.wait('@recherche-emplois');

const id = aBarmanOffre().id;

interceptGet({
actionBeforeWaitTheCall: () => (
cy.findByRole('list', { name: /Offres demplois/i })
.children()
.first()
.click()
),
alias: 'get-emplois',
path: `/_next/data/*/emplois/${id}.json?id=${id}`,
response: JSON.stringify({ pageProps: { offreEmploi: aBarmanOffre() } }),
});

cy.findByRole('heading', { level: 1 }).should('contain.text', 'Barman / Barmaid (H/F)');

cy.findByRole('list', { name: /Offres demplois/i })
.children()
.first()
.click();

cy.findByRole('heading', { level: 1 }).should('contain.text', expectedResult.result.intitulé);
});
});
});
Expand All @@ -91,11 +74,11 @@ describe('Page de recherche d’emplois', () => {
typeDeContrats: 'CDI',
typeLocalisation: 'DEPARTEMENT',
};

cy.visit(`/emplois?${stringify(query)}`);
cy.wait('@recherche-emplois');

cy.findByRole('textbox', { name: /Métier, Mot-clé/i }).should('have.value', 'Informatique');
cy.findByRole('combobox', { name: /Localisation/i }).should('have.value', 'Paris (75)');
cy.findByRole('textbox', { name: /Métier, Mot-clé/i }).should('have.value', query.motCle);
cy.findByRole('combobox', { name: /Localisation/i }).should('have.value', `${query.nomLocalisation} (${query.codeLocalisation})`);

cy.findByRole('button', { name: /Filtrer ma recherche/i }).click();

Expand All @@ -111,13 +94,7 @@ describe('Page de recherche d’emplois', () => {

context('quand les paramètres de l’url ne respectent pas le schema de validation du controller', () => {
it('retourne une erreur de demande incorrecte', () => {
interceptGet({
actionBeforeWaitTheCall: () => cy.visit('/emplois?page=67'),
alias: 'recherche-emplois-failed',
path:'/api/emplois?page=67',
response: JSON.stringify({ error: "les paramètres dans l'url ne respectent pas le schema de validation" }),
statusCode: 400,
});
cy.visit('/emplois?page=67');

cy.findByText('Erreur - Demande incorrecte').should('exist');
});
Expand Down
3 changes: 3 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const moduleExports = {
NEXT_PUBLIC_APPLICATION_NAME: name,
NEXT_PUBLIC_APPLICATION_VERSION: version,
},
experimental: {
scrollRestoration: true,
},
images: {
remotePatterns: [
...getImagesRemotePattern(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
await user.click(buttonRechercher);

// THEN
expect(routerPush).toHaveBeenCalledWith({ query: 'motCle=boulanger&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'motCle=boulanger&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -84,7 +84,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
await user.click(buttonAppliquerFiltres);

// THEN
expect(routerPush).toHaveBeenCalledWith({ query: 'typeDeContrats=MIS&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'typeDeContrats=MIS&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -118,7 +118,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
await user.click(buttonAppliquerFiltres);

// THEN
expect(routerPush).toHaveBeenCalledWith({ query: 'tempsDeTravail=tempsPlein&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'tempsDeTravail=tempsPlein&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -152,7 +152,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
await user.click(buttonAppliquerFiltres);

// THEN
expect(routerPush).toHaveBeenCalledWith({ query: 'experienceExigence=D&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'experienceExigence=D&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -186,10 +186,10 @@ describe('FormulaireRechercheOffreEmploi', () => {
await user.click(buttonRechercher);

// THEN
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('nomLocalisation=Paris') }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('codePostalLocalisation=75001') }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('typeLocalisation=COMMUNE') }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('codeLocalisation=75101') }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('nomLocalisation=Paris') }, undefined, { scroll: false });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('codePostalLocalisation=75001') }, undefined, { scroll: false });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('typeLocalisation=COMMUNE') }, undefined, { scroll: false });
expect(routerPush).toHaveBeenCalledWith({ query: expect.stringContaining('codeLocalisation=75101') }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -224,7 +224,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
await user.click(buttonAppliquerFiltres);

// THEN
expect(routerPush).toHaveBeenCalledWith({ query: 'grandDomaine=C&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'grandDomaine=C&page=1' }, undefined, { scroll: false });
});
});
});
Expand Down Expand Up @@ -272,7 +272,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
const buttonRechercher = screen.getByRole('button', { name: 'Rechercher' });
await user.click(buttonRechercher);

expect(routerPush).toHaveBeenCalledWith({ query: 'typeDeContrats=CDD&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'typeDeContrats=CDD&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -300,7 +300,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
const buttonRechercher = screen.getByRole('button', { name: 'Rechercher' });
await user.click(buttonRechercher);

expect(routerPush).toHaveBeenCalledWith({ query: 'grandDomaine=C&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'grandDomaine=C&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -328,7 +328,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
const buttonRechercher = screen.getByRole('button', { name: 'Rechercher' });
await user.click(buttonRechercher);

expect(routerPush).toHaveBeenCalledWith({ query: 'experienceExigence=D&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'experienceExigence=D&page=1' }, undefined, { scroll: false });
});
});

Expand Down Expand Up @@ -356,7 +356,7 @@ describe('FormulaireRechercheOffreEmploi', () => {
const buttonRechercher = screen.getByRole('button', { name: 'Rechercher' });
await user.click(buttonRechercher);

expect(routerPush).toHaveBeenCalledWith({ query: 'tempsDeTravail=tempsPlein&page=1' }, undefined, { shallow: true });
expect(routerPush).toHaveBeenCalledWith({ query: 'tempsDeTravail=tempsPlein&page=1' }, undefined, { scroll: false });
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function FormulaireRechercheOffreEmploi() {
function updateRechercherOffreEmploiQueryParams(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const query = getFormAsQuery(event.currentTarget, queryParams);
return router.push({ query }, undefined, { shallow: true });
router.push({ query }, undefined, { scroll: false });
}

return (
Expand All @@ -96,7 +96,6 @@ export function FormulaireRechercheOffreEmploi() {
label="Métier, mot-clé"
value={inputMotCle}
name="motCle"
autoFocus
placeholder="Exemples : boulanger, informatique..."
onChange={(event: ChangeEvent<HTMLInputElement>) => setInputMotCle(event.currentTarget.value)}
/>
Expand Down
Loading

0 comments on commit a8b83be

Please sign in to comment.