Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ test.describe("Contributions", () => {
);

await page
.getByRole("button", {
name: "Afficher les informations sans sélectionner une convention collective",
})
.getByLabel("Je ne souhaite pas renseigner ma convention collective.")
.check({ force: true });
await page
.getByRole("button", { name: "Afficher les informations" })
.click();
await expect(
page.getByText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
} from "../utils/useLocalStorage";
import { useRouter } from "next/navigation";
import { ContributionGenericAgreementSearch } from "./ContributionGenericAgreementSearch";
import { Button } from "@codegouvfr/react-dsfr/Button";
import { fr } from "@codegouvfr/react-dsfr";

type Props = {
contribution: Contribution;
Expand All @@ -33,8 +31,6 @@ export function ContributionGeneric({ contribution }: Props) {
emitAgreementUntreatedEvent,
emitDisplayAgreementContent,
emitDisplayGeneralContent,
emitDisplayGenericContent,
emitClickP3,
} = useContributionTracking();
const genericTitleRef = useRef<HTMLDivElement>(null);

Expand Down Expand Up @@ -94,8 +90,6 @@ export function ContributionGeneric({ contribution }: Props) {
scrollToTitle();
if (selectedAgreement) {
emitDisplayGeneralContent(getTitle());
} else {
emitDisplayGenericContent(getTitle());
}
} else {
emitDisplayAgreementContent(getTitle());
Expand All @@ -106,40 +100,24 @@ export function ContributionGeneric({ contribution }: Props) {
/>

{!isNoCDT && !isAgreementValid(contribution, selectedAgreement) && (
<>
{!displayGeneric && (
<Button
className={fr.cx("fr-mb-6w")}
priority="tertiary no outline"
onClick={() => {
setDisplayGeneric(true);
scrollToTitle();
emitClickP3(getTitle());
}}
>
Afficher les informations sans sélectionner une convention
collective
</Button>
)}
<ContributionGenericContent
ref={genericTitleRef}
contribution={contribution}
relatedItems={relatedItems}
displayGeneric={displayGeneric}
alertText={
selectedAgreement &&
!isAgreementSupported(contribution, selectedAgreement) && (
<p>
<strong>
Cette réponse correspond à ce que prévoit le code du
travail, elle ne tient pas compte des spécificités de la{" "}
{selectedAgreement.shortTitle}
</strong>
</p>
)
}
/>
</>
<ContributionGenericContent
ref={genericTitleRef}
contribution={contribution}
relatedItems={relatedItems}
displayGeneric={displayGeneric}
alertText={
selectedAgreement &&
!isAgreementSupported(contribution, selectedAgreement) && (
<p>
<strong>
Cette réponse correspond à ce que prévoit le code du travail,
elle ne tient pas compte des spécificités de la{" "}
{selectedAgreement.shortTitle}
</strong>
</p>
)
}
/>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import Image from "next/image";
import AgreementSearch from "../convention-collective/AgreementSearch.svg";
import { useRouter } from "next/navigation";

import { Agreement } from "src/modules/outils/indemnite-depart/types";
import {
Agreement,
AgreementRoute,
} from "src/modules/outils/indemnite-depart/types";
import {
isAgreementSupported,
isAgreementUnextended,
Expand All @@ -16,6 +19,7 @@ import { Contribution } from "./type";
import Link from "../common/Link";
import BlueCard from "../common/BlueCard";
import { AgreementSearchForm } from "../convention-collective/AgreementSearch/AgreementSearchForm";
import { AccessibleAlert } from "../outils/common/components/AccessibleAlert";

type Props = {
onAgreementSelect: (agreement?: Agreement) => void;
Expand All @@ -26,6 +30,9 @@ type Props = {
personalizeTitleRef: React.RefObject<HTMLParagraphElement | null>;
};

const MISSING_ROUTE_ERROR =
"Veuillez sélectionner l'une des options ci-dessus pour afficher les informations.";

export function ContributionGenericAgreementSearch({
contribution,
onAgreementSelect,
Expand All @@ -35,8 +42,12 @@ export function ContributionGenericAgreementSearch({
personalizeTitleRef,
}: Props) {
const router = useRouter();
const { slug } = contribution;
const { slug, isNoCDT } = contribution;
const [isValid, setIsValid] = useState(false);
const [selectedRoute, setSelectedRoute] = useState<
AgreementRoute | undefined
>();
const [showMissingRouteError, setShowMissingRouteError] = useState(false);

useEffect(() => {
setIsValid(isAgreementValid(contribution, selectedAgreement));
Expand All @@ -45,7 +56,7 @@ export function ContributionGenericAgreementSearch({
const selectedAgreementAlert = (agreement: Agreement) => {
const isSupported = isAgreementSupported(contribution, agreement);
const isUnextended = isAgreementUnextended(contribution, agreement);
if (contribution.isNoCDT) {
if (isNoCDT) {
if (isUnextended && agreement.url)
return (
<>
Expand Down Expand Up @@ -90,6 +101,27 @@ export function ContributionGenericAgreementSearch({
if (!isSupported)
return <>Vous pouvez consulter les informations générales ci-dessous.</>;
};

const noAgreementBanner = (
<AccessibleAlert
title="Information"
description={
<p>
Vous pouvez passer cette étape et poursuivre la simulation qui vous
fournira un résultat basé sur le code du travail. Nous vous
recommandons de renseigner votre convention collective qui peut
prévoir un résultat plus favorable que celui définit par le code du
travail.
</p>
}
severity="info"
className={["fr-mt-2w"]}
data-testid="no-agreement-banner"
/>
);

const isButtonDisplayed = (isNoCDT && isValid) || !isNoCDT;

return (
<BlueCard>
<div className={fr.cx("fr-grid-row")}>
Expand Down Expand Up @@ -123,12 +155,30 @@ export function ContributionGenericAgreementSearch({
);
personalizeTitle?.focus();
}}
showNoAgreementOption={!isNoCDT}
noAgreementContent={noAgreementBanner}
onRouteChange={(route) => {
setSelectedRoute(route);
setShowMissingRouteError(false);
}}
error={showMissingRouteError ? MISSING_ROUTE_ERROR : undefined}
/>
{((contribution.isNoCDT && isValid) || !contribution.isNoCDT) && (
{isButtonDisplayed && (
<Button
className={fr.cx("fr-mt-2w")}
type="button"
onClick={(event) => {
if (!selectedRoute) {
event.preventDefault();
setShowMissingRouteError(true);
return;
}
setShowMissingRouteError(false);
if (selectedRoute === "no-agreement") {
event.preventDefault();
onDisplayClick(false);
return;
}
onDisplayClick(isValid && !!selectedAgreement);
if (isValid && selectedAgreement) {
router.push(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,32 +235,31 @@ describe("<ContributionGeneric />", () => {
]);
});

it("afficher les infos - sans CC", async () => {
it("afficher les infos - sans radio sélectionné : le clic sur le bouton principal est bloqué et n'envoie aucun évènement", async () => {
expect(sendEvent).toHaveBeenCalledTimes(0);

render(<ContributionGeneric contribution={contribution} />);
expect(ui.generic.buttonDisplayInfo.get()).toBeInTheDocument();
fireEvent.click(ui.generic.buttonDisplayInfo.get());
expect(sendEvent).toHaveBeenCalledTimes(1);
expect(sendEvent).toHaveBeenLastCalledWith({
action: "click_afficher_les_informations_sans_CC",
category: "contribution",
name: "/contribution/my-contrib",
});
expect(ui.generic.missingRouteError.query()).toBeInTheDocument();
expect(sendEvent).toHaveBeenCalledTimes(0);
});

it("voir les infos générales", () => {
it("voir les infos générales via l'option « Je ne souhaite pas renseigner ma convention collective »", () => {
expect(sendEvent).toHaveBeenCalledTimes(0);

render(<ContributionGeneric contribution={contribution} />);

fireEvent.click(ui.generic.linkDisplayInfo.get());

fireEvent.click(ui.generic.radioNoAgreement.get());
expect(sendEvent).toHaveBeenCalledTimes(1);
expect(sendEvent).toHaveBeenCalledWith({
expect(sendEvent).toHaveBeenLastCalledWith({
action: "click_p3",
category: "cc_search_type_of_users",
name: "/contribution/my-contrib",
});

fireEvent.click(ui.generic.buttonDisplayInfo.get());
// No additional event is emitted: click_p3 already captures the intent
expect(sendEvent).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,34 @@ describe("<ContributionLayout />", () => {
});
});

it("should display correctly when no agreement is selected", async () => {
fireEvent.click(ccUi.radio.agreementSearchOption.get());
it("should display the no-agreement banner and the generic content when the no-agreement option is selected", async () => {
fireEvent.click(ui.generic.radioNoAgreement.get());
expect(ui.generic.noAgreementBanner.query()).toBeInTheDocument();
expect(ccUi.buttonDisplayInfo.query()).toBeInTheDocument();
expect(ui.generic.linkDisplayInfo.query()).toBeInTheDocument();
expect(rendering.getByText("my content")).toBeInTheDocument();
fireEvent.click(ui.generic.linkDisplayInfo.get());
expect(ui.generic.linkDisplayInfo.query()).not.toBeInTheDocument();

fireEvent.click(ccUi.buttonDisplayInfo.get());

expect(rendering.getByText("my content")).toBeInTheDocument();
expect(pushMock).not.toHaveBeenCalled();
});

it("should display an error when clicking 'Afficher les informations' without selecting any radio option", async () => {
expect(ui.generic.missingRouteError.query()).not.toBeInTheDocument();

fireEvent.click(ccUi.buttonDisplayInfo.get());

expect(ui.generic.missingRouteError.query()).toBeInTheDocument();
expect(pushMock).not.toHaveBeenCalled();
});

it("should hide the error when a radio option is selected after the error is shown", async () => {
fireEvent.click(ccUi.buttonDisplayInfo.get());
expect(ui.generic.missingRouteError.query()).toBeInTheDocument();

fireEvent.click(ui.generic.radioNoAgreement.get());

expect(ui.generic.missingRouteError.query()).not.toBeInTheDocument();
});

it("should display correctly when a treated agreement is selected", async () => {
Expand All @@ -140,14 +160,11 @@ describe("<ContributionLayout />", () => {
])
);
fireEvent.click(ccUi.radio.agreementSearchOption.get());
expect(ui.generic.linkDisplayInfo.query()).toBeInTheDocument();
await userEvent.click(ccUi.searchByName.input.get());
await userEvent.type(ccUi.searchByName.input.get(), "16");

fireEvent.click(ccUi.searchByName.autocompleteLines.IDCC16.name.get());

expect(ui.generic.linkDisplayInfo.query()).not.toBeInTheDocument();

fireEvent.click(ccUi.buttonDisplayInfo.get());
expect(pushMock).toHaveBeenCalledTimes(1);
expect(pushMock).toHaveBeenCalledWith("/contribution/16-slug");
Expand Down Expand Up @@ -183,7 +200,6 @@ describe("<ContributionLayout />", () => {

await ccUi.searchByName.autocompleteLines.IDCC1388.name.find();
fireEvent.click(ccUi.searchByName.autocompleteLines.IDCC1388.name.get());
expect(ui.generic.linkDisplayInfo.query()).toBeInTheDocument();

expect(ccUi.warning.title.query()).toBeInTheDocument();
expect(ccUi.warning.nonTreatedAgreement.query()).toBeInTheDocument();
Expand All @@ -192,10 +208,9 @@ describe("<ContributionLayout />", () => {
category: "outil",
name: "1388",
});
expect(ccUi.warning.title.query()).toBeInTheDocument();
fireEvent.click(ui.generic.linkDisplayInfo.get());
fireEvent.click(ccUi.buttonDisplayInfo.get());
expect(pushMock).not.toHaveBeenCalled();
expect(ui.generic.nonTreatedInfo.query()).toBeInTheDocument();
expect(ui.generic.linkDisplayInfo.query()).not.toBeInTheDocument();
});
});

Expand All @@ -208,10 +223,13 @@ describe("<ContributionLayout />", () => {
});
it("should display correctly when no agreement is selected", () => {
fireEvent.click(ccUi.radio.agreementSearchOption.get());
expect(ui.generic.linkDisplayInfo.query()).not.toBeInTheDocument();
expect(ccUi.buttonDisplayInfo.query()).not.toBeInTheDocument();
});

it("should not display the no-agreement option in noCDT mode", () => {
expect(ui.generic.radioNoAgreement.query()).not.toBeInTheDocument();
});

it("should display correctly when a treated agreement is selected", async () => {
(searchAgreement as jest.Mock).mockImplementation(() =>
Promise.resolve([
Expand Down Expand Up @@ -266,7 +284,6 @@ describe("<ContributionLayout />", () => {
await userEvent.click(ccUi.searchByName.input.get());
await userEvent.type(ccUi.searchByName.input.get(), "1388");
fireEvent.click(ccUi.searchByName.autocompleteLines.IDCC1388.name.get());
expect(ui.generic.linkDisplayInfo.query()).not.toBeInTheDocument();
expect(ccUi.buttonDisplayInfo.query()).not.toBeInTheDocument();
expect(ccUi.warning.title.query()).toBeInTheDocument();
expect(ccUi.warning.noCdtNonTreatedAgreement.query()).toBeInTheDocument();
Expand Down Expand Up @@ -302,7 +319,6 @@ describe("<ContributionLayout />", () => {
await userEvent.click(ccUi.searchByName.input.get());
await userEvent.type(ccUi.searchByName.input.get(), "29");
fireEvent.click(ccUi.searchByName.autocompleteLines.IDCC29.name.get());
expect(ui.generic.linkDisplayInfo.query()).not.toBeInTheDocument();
expect(ccUi.buttonDisplayInfo.query()).not.toBeInTheDocument();
expect(ccUi.warning.title.query()).toBeInTheDocument();
expect(ccUi.warning.noCdtUnextendedAgreement.query()).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { byText } from "testing-library-selector";
import { byLabelText, byTestId, byText } from "testing-library-selector";
import { searchAgreement } from "../../convention-collective";

export const ui = {
generic: {
buttonDisplayInfo: byText(/Afficher les informations$/),
linkDisplayInfo: byText(
"Afficher les informations sans sélectionner une convention collective"
),
nonTreatedInfo: byText(
/Cette réponse correspond à ce que prévoit le code du travail/
),
missingRouteError: byText(
/Veuillez sélectionner l'une des options ci-dessus/
),
noAgreementBanner: byTestId("no-agreement-banner"),
radioNoAgreement: byLabelText(
/Je ne souhaite pas renseigner ma convention collective\./
),
},
};
export const mockAgreementSearch = (idcc) =>
Expand Down
Loading
Loading