diff --git a/.env.example b/.env.example index c92ea5f2..4f0892b0 100644 --- a/.env.example +++ b/.env.example @@ -5,3 +5,4 @@ NEXT_PUBLIC_MATOMO_ENABLED = false NEXT_PUBLIC_PASTEK_CHAT_ID = 2 NEXT_PUBLIC_TEST_NUMBER_ENABLED = true NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES = "https://1000jours-blues-preprod.dev.fabrique.social.gouv.fr/ressources" +NEXT_PUBLIC_CALENDLY_LINK="https://calendly.com/test1000jfabnum/30min" \ No newline at end of file diff --git a/.github/workflows/preproduction.yml b/.github/workflows/preproduction.yml index e4070088..fdd162d2 100644 --- a/.github/workflows/preproduction.yml +++ b/.github/workflows/preproduction.yml @@ -30,6 +30,7 @@ jobs: NEXT_PUBLIC_PASTEK_CHAT_ID=2 NEXT_PUBLIC_TEST_NUMBER_ENABLED=true NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES=https://1000jours-blues-preprod.dev.fabrique.social.gouv.fr/ressources + NEXT_PUBLIC_CALENDLY_LINK=https://calendly.com/test1000jfabnum/30min deploy: name: Deploy application diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 9f46201e..d7a16015 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -28,6 +28,7 @@ jobs: NEXT_PUBLIC_PASTEK_CHAT_ID=1 NEXT_PUBLIC_TEST_NUMBER_ENABLED=false NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES=https://1000jours-blues.fabrique.social.gouv.fr/ressources + NEXT_PUBLIC_CALENDLY_LINK=https://calendly.com/rdv-nos1000jours/30min deploy: name: Deploy application diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml index fde56f21..fab0551b 100644 --- a/.github/workflows/review.yml +++ b/.github/workflows/review.yml @@ -30,6 +30,7 @@ jobs: NEXT_PUBLIC_PASTEK_CHAT_ID=2 NEXT_PUBLIC_TEST_NUMBER_ENABLED=true NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES=https://1000jours-blues-preprod.dev.fabrique.social.gouv.fr/ressources + NEXT_PUBLIC_CALENDLY_LINK=https://calendly.com/test1000jfabnum/30min deploy: name: Deploy review branch diff --git a/Dockerfile b/Dockerfile index 39c68804..7a6909a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,9 @@ ENV NEXT_PUBLIC_PASTEK_CHAT_ID=$NEXT_PUBLIC_PASTEK_CHAT_ID ARG NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES ENV NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES=$NEXT_PUBLIC_LANDING_PAGE_BLUES_RESOURCES +ARG NEXT_PUBLIC_CALENDLY_LINK +ENV NEXT_PUBLIC_CALENDLY_LINK=$NEXT_PUBLIC_CALENDLY_LINK + RUN yarn --production --frozen-lockfile --prefer-offline && yarn cache clean RUN yarn build diff --git a/__tests__/components/ab-testing/measuring-intentions.test.js b/__tests__/components/ab-testing/measuring-intentions.test.js deleted file mode 100644 index f7f70c76..00000000 --- a/__tests__/components/ab-testing/measuring-intentions.test.js +++ /dev/null @@ -1,735 +0,0 @@ -import { fireEvent, render, screen } from "@testing-library/react" -import "@testing-library/jest-dom" -import { - SCORE_LEVEL_BAD, - SCORE_LEVEL_GOOD, -} from "../../../src/utils/score-level.utils" -import { - contacterAToutMoment, - demandeDeDetails, - estLePlusAdapte, - nePasSavoir, - seRapprocheDeLaRealite, -} from "../../../src/utils/ab-testing/measuring-intentions.utils" -import { displayComponentsByTest } from "../../../src/components/ab-testing/intentions/MeasuringIntentions" -import * as ContactMamanBlues from "../../../src/components/results/ContactMamanBlues" - -describe("UI de MeasuringIntentions", () => { - const findLabelEstLePlusAdapte = (value) => - estLePlusAdapte.reponses.find((item) => item.value === value).label - const findLabelDemandeDeDetailsLvl3 = (value) => - demandeDeDetails.lvl3.reponses.find((item) => item.value === value).label - - const mockSetState = jest.fn() - jest.mock("react", () => ({ - useState: (initial) => [initial, mockSetState], - })) - - // Bloc Elise - const mamanBluesBlocToBeInTheDocument = () => { - expect( - screen.getByRole("img", { - name: "Portrait d'Elise : présidente de l'association Maman Blues", - }) - ).toBeInTheDocument() - expect( - screen.getByRole("button", { name: ContactMamanBlues.buttonLabel }) - ).toBeInTheDocument() - } - - const mamanBluesBlocNotToBeInTheDocument = () => { - expect(screen.queryByRole("img", { name: "Portrait d'Elise" })).toBeNull() - } - - const onClickMaybeButton = async (maybeButton) => { - // Action - fireEvent.click(maybeButton) - - // Affichage du bouton - expect(maybeButton).not.toBeInTheDocument() - expect( - await screen.queryByText("Je ne suis pas sûr(e)") - ).not.toBeInTheDocument() - } - - const onClickNoButton = async (noButton) => { - // Action - fireEvent.click(noButton) - - // Phrase spécifique - expect(noButton).not.toBeInTheDocument() - expect(await screen.queryByText("Non")).not.toBeInTheDocument() - } - - describe("Reponse EPDS : Je vais bien", () => { - test("Test A => aucun retour", async () => { - expect( - displayComponentsByTest({ testId: "A", scoreLevel: SCORE_LEVEL_GOOD }) - ).toBeNull() - - expect(screen.queryByRole("button", { name: "Retour" })).toBeNull() - }) - - describe("Test B", () => { - let yesButton, noButton, maybeButton - - beforeEach(() => { - render( - displayComponentsByTest({ - testId: "B", - scoreLevel: SCORE_LEVEL_GOOD, - showBackButton: false, - setShowBackButton: mockSetState, - }) - ) - - yesButton = screen.getByRole("button", { name: "Oui" }) - noButton = screen.getByRole("button", { name: "Non" }) - maybeButton = screen.getByRole("button", { - name: "Je ne suis pas sûr(e)", - }) - - // Buttons - expect(yesButton).toBeInTheDocument() - expect(noButton).toBeInTheDocument() - expect(maybeButton).toBeInTheDocument() - expect( - screen.queryByRole("button", { name: "Retour" }) - ).not.toBeInTheDocument() - }) - - test("Réponse : Oui => affichage du portrait", async () => { - // Action - fireEvent.click(yesButton) - - // Phrase spécifique - expect(yesButton).not.toBeInTheDocument() - expect(await screen.queryByText("Oui")).not.toBeInTheDocument() - expect( - await screen.findByText( - "Vous allez bien, n'hésitez pas à revenir plus tard et vous questionner régulièrement. Sachez qu'Elise peut répondre à vos questions si vous en avez besoin." - ) - ).toBeVisible() - - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - test("Réponse : Je ne suis pas sûr(e) => affichage du portrait", async () => { - onClickMaybeButton(maybeButton) - expect(await screen.findByText(nePasSavoir)).toBeVisible() - - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - describe("Réponse : Non", () => { - test("Affichage de la nouvelle question", async () => { - onClickNoButton(noButton) - - expect(await screen.findByText(seRapprocheDeLaRealite)).toBeVisible() - expect( - await screen.getByRole("button", { - name: "Malgré le résultat, je n'ai pas l'impression d'aller bien", - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: "Autre chose : nous le dire", - }) - ).toBeInTheDocument() - - // Bloc Elise - mamanBluesBlocNotToBeInTheDocument() - }) - - test("Réponse : je ne vais pas bien => affichage du portrait", async () => { - // Action - fireEvent.click(noButton) - - // Nouvelle question - const badButton = screen.getByRole("button", { - name: "Malgré le résultat, je n'ai pas l'impression d'aller bien", - }) - const otherButton = screen.getByRole("button", { - name: "Autre chose : nous le dire", - }) - expect(badButton).toBeInTheDocument() - expect(otherButton).toBeInTheDocument() - - // Action - fireEvent.click(badButton) - - // Phrase spécifique - expect(badButton).not.toBeInTheDocument() - expect( - await screen.findByText( - "Malgré le résultat, je n'ai pas l'impression d'aller bien" - ) - ).toBeVisible() - expect( - await screen.findByText( - "Nous vous conseillons de vous entretenir avec Elise. Elle saura vous apporter conseil." - ) - ).toBeVisible() - - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - test("Réponse : autre chose => affichage textarea", async () => { - // Action - fireEvent.click(noButton) - - // Nouvelle question - const badButton = screen.getByRole("button", { - name: "Malgré le résultat, je n'ai pas l'impression d'aller bien", - }) - const otherButton = screen.getByRole("button", { - name: "Autre chose : nous le dire", - }) - expect(badButton).toBeInTheDocument() - expect(otherButton).toBeInTheDocument() - - // Action - fireEvent.click(otherButton) - - // Phrase spécifique - expect(otherButton).not.toBeInTheDocument() - expect( - await screen.findByText("Autre chose : nous le dire") - ).toBeVisible() - expect( - await screen.findByText( - "Expliquez-nous pourquoi vous êtes venu.es passer le test." - ) - ).toBeVisible() - expect( - screen.getByRole("textbox", { - name: "textValueOther", - }) - ).toBeInTheDocument() - - // Bloc Elise - mamanBluesBlocNotToBeInTheDocument() - }) - }) - }) - - describe("Test C", () => { - let yesButton, noButton, maybeButton - - beforeEach(() => { - render( - displayComponentsByTest({ - testId: "C", - scoreLevel: SCORE_LEVEL_GOOD, - showBackButton: false, - setShowBackButton: mockSetState, - }) - ) - - yesButton = screen.getByRole("button", { name: "Oui" }) - noButton = screen.getByRole("button", { name: "Non" }) - maybeButton = screen.getByRole("button", { - name: "Je ne suis pas sûr(e)", - }) - - // Buttons - expect(yesButton).toBeInTheDocument() - expect(noButton).toBeInTheDocument() - expect(maybeButton).toBeInTheDocument() - expect( - screen.queryByRole("button", { name: "Retour" }) - ).not.toBeInTheDocument() - }) - - afterEach(() => { - mamanBluesBlocNotToBeInTheDocument() - }) - - test("Réponse : Oui => affichage du portrait", async () => { - // Action - fireEvent.click(yesButton) - - // Phrase spécifique - expect( - await screen.findByText( - "Vous allez bien, n'hésitez pas à revenir plus tard et vous questionner régulièrement. Sachez qu'Elise peut répondre à vos questions si vous en avez besoin." - ) - ).toBeVisible() - }) - - test("Réponse : Je ne suis pas sûr(e) => affichage du portrait", async () => { - // Action - fireEvent.click(maybeButton) - - // Phrase spécifique - expect(await screen.findByText(nePasSavoir)).toBeVisible() - }) - - describe("Réponse : Non", () => { - test("Affichage de la nouvelle question", async () => { - // Action - fireEvent.click(noButton) - - // Phrase spécifique - expect(await screen.findByText(seRapprocheDeLaRealite)).toBeVisible() - expect( - await screen.getByRole("button", { - name: "Malgré le résultat, je n'ai pas l'impression d'aller bien", - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: "Autre chose : nous le dire", - }) - ).toBeInTheDocument() - }) - - test("Réponse : je ne vais pas bien => affichage du portrait", async () => { - // Action - fireEvent.click(noButton) - - // Nouvelle question - const badButton = screen.getByRole("button", { - name: "Malgré le résultat, je n'ai pas l'impression d'aller bien", - }) - const otherButton = screen.getByRole("button", { - name: "Autre chose : nous le dire", - }) - expect(badButton).toBeInTheDocument() - expect(otherButton).toBeInTheDocument() - - // Action - fireEvent.click(badButton) - - // Phrase spécifique - expect( - await screen.findByText( - "Nous vous conseillons de vous entretenir avec Elise. Elle saura vous apporter conseil." - ) - ).toBeVisible() - }) - - test("Réponse : autre chose => affichage textarea", async () => { - // Action - fireEvent.click(noButton) - - // Nouvelle question - const badButton = screen.getByRole("button", { - name: "Malgré le résultat, je n'ai pas l'impression d'aller bien", - }) - const otherButton = screen.getByRole("button", { - name: "Autre chose : nous le dire", - }) - expect(badButton).toBeInTheDocument() - expect(otherButton).toBeInTheDocument() - - // Action - fireEvent.click(otherButton) - - // Phrase spécifique - expect( - await screen.findByText( - "Expliquez-nous pourquoi vous êtes venu.es passer le test." - ) - ).toBeVisible() - expect( - screen.getByRole("textbox", { - name: "textValueOther", - }) - ).toBeInTheDocument() - }) - }) - }) - }) - - describe("Reponse EPDS : Je ne vais pas bien", () => { - test("Test A => affichage portrait", async () => { - expect( - displayComponentsByTest({ testId: "A", scoreLevel: SCORE_LEVEL_BAD }) - ).toBeNull() - - expect(screen.queryByRole("button", { name: "Retour" })).toBeNull() - // On ne peut pas vérifier si le bloc de contact est présent car il est hors du bloc généré par `displayComponentsByTest` - }) - - describe("Test B", () => { - let yesButton, noButton, maybeButton - - beforeEach(() => { - render( - displayComponentsByTest({ - testId: "B", - scoreLevel: SCORE_LEVEL_BAD, - showBackButton: false, - setShowBackButton: mockSetState, - }) - ) - - yesButton = screen.getByRole("button", { name: "Oui" }) - noButton = screen.getByRole("button", { name: "Non" }) - maybeButton = screen.getByRole("button", { - name: "Je ne suis pas sûr(e)", - }) - - // Buttons - expect(yesButton).toBeInTheDocument() - expect(noButton).toBeInTheDocument() - expect(maybeButton).toBeInTheDocument() - expect( - screen.queryByRole("button", { name: "Retour" }) - ).not.toBeInTheDocument() - }) - - describe("Réponse : Oui", () => { - test("Affichage de la nouvelle question + réponses", async () => { - // Action - fireEvent.click(yesButton) - - // Phrase spécifique - expect(yesButton).not.toBeInTheDocument() - expect(await screen.queryByText("Oui")).not.toBeInTheDocument() - - expect( - await screen.findByText("Prenez une des actions suivantes.") - ).toBeVisible() - - // Nouveaux boutons - expect( - await screen.getByRole("button", { - name: findLabelEstLePlusAdapte("quiJoindre"), - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: findLabelEstLePlusAdapte("quoiFaire"), - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: findLabelEstLePlusAdapte("seTourner"), - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: findLabelEstLePlusAdapte("aucune"), - }) - ).toBeInTheDocument() - - // Bloc Elise - mamanBluesBlocNotToBeInTheDocument() - }) - - describe("Réponses spécifiques", () => { - let quiJoindre, quoiFaire, seTourner, aucune - - beforeEach(() => { - // Action - fireEvent.click(yesButton) - - quiJoindre = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("quiJoindre"), - }) - quoiFaire = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("quoiFaire"), - }) - seTourner = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("seTourner"), - }) - aucune = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("aucune"), - }) - }) - - afterEach(() => { - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - test("Réponse : Je sais qui joindre => formulaire", async () => { - // Action - fireEvent.click(quiJoindre) - - // Phrases spécifiques - expect( - await screen.findByText(findLabelEstLePlusAdapte("quiJoindre")) - ).toBeVisible() - expect(await screen.findByText(contacterAToutMoment)).toBeVisible() - - // Formaulaire - expect( - await screen.findByText( - "Recevez votre résultat au questionnaire par mail pour le partager à votre professionnel de santé :" - ) - ).toBeVisible() - expect( - screen.getByRole("form", { - name: "formToSendMail", - }) - ).toBeInTheDocument() - expect(await screen.findByText("Votre mail * :")).toBeVisible() - }) - - test("Réponse : Je sais quoi faire => formulaire", async () => { - // Action - fireEvent.click(quoiFaire) - - // Phrases spécifiques - expect( - await screen.findByText(findLabelEstLePlusAdapte("quoiFaire")) - ).toBeVisible() - expect(await screen.findByText(contacterAToutMoment)).toBeVisible() - - // Formaulaire - expect( - await screen.queryByText( - "Recevez votre résultat au questionnaire par mail pour le partager à votre professionnel de santé :" - ) - ).toBeNull() - expect( - screen.getByRole("form", { - name: "formToSendMail", - }) - ).toBeInTheDocument() - expect( - await screen.findByText("L'email de votre proche * :") - ).toBeVisible() - }) - - test("Réponse : Je ne sais pas vers qui me tourner => texte", async () => { - // Action - fireEvent.click(seTourner) - - expect( - await screen.findByText(findLabelEstLePlusAdapte("seTourner")) - ).toBeVisible() - }) - - test("Réponse : Aucune des trois : je vous explique => textarea", async () => { - // Action - fireEvent.click(aucune) - - // Phrases spécifiques - expect( - await screen.findByText(findLabelEstLePlusAdapte("aucune")) - ).toBeVisible() - expect( - await screen.findByText(estLePlusAdapte.commentaires.aucune) - ).toBeVisible() - expect(await screen.findByText(contacterAToutMoment)).toBeVisible() - - // Text Area - expect( - screen.getByRole("textbox", { - name: "textValueOther", - }) - ).toBeInTheDocument() - }) - }) - }) - - test("Réponse : Je ne suis pas sûr(e) => affichage du portrait", async () => { - onClickMaybeButton(maybeButton) - expect(await screen.findByText(nePasSavoir)).toBeVisible() - - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - describe("Réponse : Non", () => { - test("Affichage de la nouvelle question & réponses", async () => { - onClickNoButton(noButton) - expect(await screen.findByText(seRapprocheDeLaRealite)).toBeVisible() - - // Nouveaux boutons - expect( - await screen.getByRole("button", { - name: findLabelDemandeDeDetailsLvl3("bien"), - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: "J'ai fait le test par curiosité", - }) - ).toBeInTheDocument() - expect( - await screen.getByRole("button", { - name: "Je suis professionnel de santé", - }) - ).toBeInTheDocument() - }) - - describe("Réponses spécifiques", () => { - let bien, curiosite, proSante - - beforeEach(() => { - // Action - fireEvent.click(noButton) - - bien = screen.getByRole("button", { - name: findLabelDemandeDeDetailsLvl3("bien"), - }) - curiosite = screen.getByRole("button", { - name: "J'ai fait le test par curiosité", - }) - proSante = screen.getByRole("button", { - name: "Je suis professionnel de santé", - }) - }) - - test("Réponse : Malgré le résultat, je l'impression que tout va bien => texte", async () => { - // Action - fireEvent.click(bien) - - expect( - await screen.findByText(findLabelDemandeDeDetailsLvl3("bien")) - ).toBeVisible() - - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - test("Réponse : J'ai fait le test par curiosité => texte", async () => { - // Action - fireEvent.click(curiosite) - - expect( - await screen.findByText("J'ai fait le test par curiosité") - ).toBeVisible() - - // Bloc Elise - mamanBluesBlocToBeInTheDocument() - }) - - test("Réponse : Je suis professionnel de santé => texte", async () => { - // Action - fireEvent.click(proSante) - - expect( - await screen.findByText("Je suis professionnel de santé") - ).toBeVisible() - - // Bloc Elise - mamanBluesBlocNotToBeInTheDocument() - }) - }) - }) - }) - - describe("Test C", () => { - let yesButton, noButton, maybeButton - - beforeEach(() => { - render( - displayComponentsByTest({ - testId: "C", - scoreLevel: SCORE_LEVEL_BAD, - showBackButton: false, - setShowBackButton: mockSetState, - }) - ) - - yesButton = screen.getByRole("button", { name: "Oui" }) - noButton = screen.getByRole("button", { name: "Non" }) - maybeButton = screen.getByRole("button", { - name: "Je ne suis pas sûr(e)", - }) - - // Buttons - expect(yesButton).toBeInTheDocument() - expect(noButton).toBeInTheDocument() - expect(maybeButton).toBeInTheDocument() - expect( - screen.queryByRole("button", { name: "Retour" }) - ).not.toBeInTheDocument() - }) - - afterEach(() => { - mamanBluesBlocNotToBeInTheDocument() - }) - - describe("Réponse : Oui", () => { - let quiJoindre, quoiFaire, seTourner, aucune - - beforeEach(() => { - // Action - fireEvent.click(yesButton) - - quiJoindre = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("quiJoindre"), - }) - quoiFaire = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("quoiFaire"), - }) - seTourner = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("seTourner"), - }) - aucune = screen.getByRole("button", { - name: findLabelEstLePlusAdapte("aucune"), - }) - }) - - test("Réponse : Je sais qui joindre => formulaire", async () => { - // Action - fireEvent.click(quiJoindre) - }) - - test("Réponse : Je sais quoi faire => formulaire", async () => { - // Action - fireEvent.click(quoiFaire) - }) - - test("Réponse : Je ne sais pas vers qui me tourner => texte", async () => { - // Action - fireEvent.click(seTourner) - }) - - test("Réponse : Aucune des trois : je vous explique => textarea", async () => { - // Action - fireEvent.click(aucune) - }) - }) - - test("Réponse : Je ne suis pas sûr(e)", async () => { - // Action - fireEvent.click(maybeButton) - }) - - describe("Réponse : Non", () => { - let bien, curiosite, proSante - - beforeEach(() => { - // Action - fireEvent.click(noButton) - - bien = screen.getByRole("button", { - name: findLabelDemandeDeDetailsLvl3("bien"), - }) - curiosite = screen.getByRole("button", { - name: "J'ai fait le test par curiosité", - }) - proSante = screen.getByRole("button", { - name: "Je suis professionnel de santé", - }) - }) - - test("Réponse : Malgré le résultat, je l'impression que tout va bien => texte", async () => { - // Action - fireEvent.click(bien) - }) - - test("Réponse : J'ai fait le test par curiosité => texte", async () => { - // Action - fireEvent.click(curiosite) - }) - - test("Réponse : Je suis professionnel de santé => texte", async () => { - // Action - fireEvent.click(proSante) - }) - }) - }) - }) -}) diff --git a/__tests__/utils/ab-testing/ab-testing.utils.test.js b/__tests__/utils/ab-testing/ab-testing.utils.test.js index 986f45ac..0705d5ec 100644 --- a/__tests__/utils/ab-testing/ab-testing.utils.test.js +++ b/__tests__/utils/ab-testing/ab-testing.utils.test.js @@ -24,15 +24,11 @@ describe("Utils", () => { trackerSpy = jest.spyOn(TrackerUtils, "track") }) - test("Should return tracker with CATEG.test, course name and label", () => { + test("Should return tracker with label", () => { localStorage.setItem(STORAGE_TEST_ABC, "A") AbTestingUtils.trackerForAbTesting("my label") - expect(trackerSpy).toHaveBeenCalledWith( - TrackerUtils.CATEG.test, - `${TrackerUtils.ACTION.parcours}A`, - "my label" - ) + expect(trackerSpy).toHaveBeenCalledWith("Test_A", "my label") }) }) }) diff --git a/__tests__/utils/contact.utils.test.js b/__tests__/utils/contact.utils.test.js index 4ab24a41..b67a8689 100644 --- a/__tests__/utils/contact.utils.test.js +++ b/__tests__/utils/contact.utils.test.js @@ -2,13 +2,24 @@ import { RequestContact, STORAGE_SOURCE } from "../../src/constants/constants" import * as ContactUtils from "../../src/utils/contact.utils" import * as TrackerUtils from "../../src/utils/tracker.utils" +/** + * @param {RequestContact.type} contactType + * @param {*} label + */ +const sendTrackerContactConfirmed = (contactType) => { + if (contactType === "chat") { + TrackerUtils.trackerForContact(`Ouverture ${contactType}`) + } else { + TrackerUtils.trackerForContact(`Confirmation ${contactType}`) + } +} + describe("Contact Utils", () => { describe("sendTrackerContactConfirmed", () => { let trackerSpy localStorage.setItem(STORAGE_SOURCE, "1000-premiers-jours") - const source = localStorage.getItem(STORAGE_SOURCE) beforeEach(() => { - trackerSpy = jest.spyOn(TrackerUtils, "track") + trackerSpy = jest.spyOn(TrackerUtils, "trackerForContact") }) afterEach(() => { @@ -16,31 +27,19 @@ describe("Contact Utils", () => { }) test("Should send tracker with email confirmation", () => { - ContactUtils.sendTrackerContactConfirmed(RequestContact.type.email) - expect(trackerSpy).toHaveBeenCalledWith( - TrackerUtils.CATEG.contact, - TrackerUtils.ACTION.contact_confirm_sent, - `${TrackerUtils.CONTACT_SENT.mail} - ${source}` - ) + sendTrackerContactConfirmed(RequestContact.type.email) + expect(trackerSpy).toHaveBeenCalledWith("Confirmation email") }) test("Should send tracker with sms confirmation", () => { - ContactUtils.sendTrackerContactConfirmed(RequestContact.type.sms) - expect(trackerSpy).toHaveBeenCalledWith( - TrackerUtils.CATEG.contact, - TrackerUtils.ACTION.contact_confirm_sent, - `${TrackerUtils.CONTACT_SENT.sms} - ${source}` - ) + sendTrackerContactConfirmed(RequestContact.type.sms) + expect(trackerSpy).toHaveBeenCalledWith(`Confirmation sms`) }) test("Should send tracker with chat opening", () => { - ContactUtils.sendTrackerContactConfirmed(RequestContact.type.chat) + sendTrackerContactConfirmed(RequestContact.type.chat) expect(trackerSpy).toHaveBeenCalled() - expect(trackerSpy).toHaveBeenCalledWith( - TrackerUtils.CATEG.contact, - TrackerUtils.ACTION.contact_confirm_sent, - `${TrackerUtils.CONTACT_SENT.chat} - ${source}` - ) + expect(trackerSpy).toHaveBeenCalledWith("Ouverture chat") }) }) diff --git a/pages/ab-testing/demographic-data-survey.js b/pages/ab-testing/demographic-data-survey.js index 31c5fd79..644d48e9 100644 --- a/pages/ab-testing/demographic-data-survey.js +++ b/pages/ab-testing/demographic-data-survey.js @@ -23,6 +23,7 @@ import { updateRadioButtonSelectedInList, } from "../../src/utils/main.utils" import * as StorageUtils from "../../src/utils/storage.utils" +import * as TrackerUtils from "../../src/utils/tracker.utils" import * as DemographicDataUtils from "../../src/utils/ab-testing/demographic-data.utils" import { JobSelector } from "../../src/components/JobSelector" import { DepartmentCodeSelector } from "../../src/components/DepartmentCodeSelector" @@ -205,12 +206,9 @@ export default function DemographicDataSurvey() { cspLibelle: jobValue.libelle, }, }) - - const trackerLabel = demographicData?.isAfterEpds - ? demographicData?.buttonLabelInInfoDemographicSurvey - : "Envoyer" - DemographicDataUtils.trackerForDemographie( - `Questionnaire démographique - ${trackerLabel}` + TrackerUtils.track( + TrackerUtils.CATEG.demography, + TrackerUtils.ACTION.end_demo ) } diff --git a/pages/contact/contact-confirmed.js b/pages/contact/contact-confirmed.js index bdf0a7e7..bac93c7e 100644 --- a/pages/contact/contact-confirmed.js +++ b/pages/contact/contact-confirmed.js @@ -6,15 +6,19 @@ import { RequestContact, STORAGE_CONTACT_TYPE, STORAGE_SOURCE, + STORAGE_IS_BACK_RESULTS, + STORAGE_SCORE, } from "../../src/constants/constants" import {} from "@dataesr/react-dsfr" import { WidgetHeader } from "../../src/components/WidgetHeader" import * as StorageUtils from "../../src/utils/storage.utils" +import * as TrackerUtils from "../../src/utils/tracker.utils" export default function ContactConfirmed() { const router = useRouter() const contactType = StorageUtils.getInLocalStorage(STORAGE_CONTACT_TYPE) + const score = StorageUtils.getInLocalStorage(STORAGE_SCORE) const websiteSource = StorageUtils.getInLocalStorage(STORAGE_SOURCE) const localeSelected = StorageUtils.getLocaleInLocalStorage() @@ -31,6 +35,13 @@ export default function ContactConfirmed() { ) const goToResults = () => { + localStorage.setItem(STORAGE_IS_BACK_RESULTS, true) + + if (TrackerUtils.seuilScore(score)) { + TrackerUtils.trackerForResults( + `${TrackerUtils.seuilScore(score)} (retour a mon résultat)` + ) + } router.push({ pathname: "/results", }) diff --git a/pages/contact/contact-form.js b/pages/contact/contact-form.js index 26c2802b..f4daa9af 100644 --- a/pages/contact/contact-form.js +++ b/pages/contact/contact-form.js @@ -13,6 +13,7 @@ import { STORAGE_SOURCE, STORAGE_TEST_DEMOGRAPHIC_DPT_CODE, STORAGE_TEST_DEMOGRAPHIC_DPT_LIBELLE, + CALENDLY_LINK } from "../../src/constants/constants" import { stringIsNotNullNorEmpty, @@ -164,16 +165,10 @@ export default function ContactForm() { } const sendTrackerContactType = (typeContact) => { - TrackerUtils.genericTracker( - TrackerUtils.CATEG.contact, - TrackerUtils.NAME.contact_confirm_sent - ) if (typeContact) { - TrackerUtils.track( - TrackerUtils.CATEG.contact, - TrackerUtils.ACTION.contact_confirm_sent, - `${ContactUtils.trackerContactName(typeContact)} - ${websiteSource}` - ) + TrackerUtils.trackerForContact(TrackerUtils.ACTION.confirmation) + TrackerUtils.trackerForContact(ContactUtils.trackerContactName(typeContact)) + AbTestingUtils.trackerForAbTesting(TrackerUtils.ACTION.confirmation) AbTestingUtils.trackerForAbTesting(ContactUtils.trackerContactName(typeContact)) } } @@ -328,7 +323,7 @@ export default function ContactForm() { {contactType === RequestContact.type.rendezvous && ( <> - -
{queryShareResponses}
- -
{contacterAToutMoment}
- {displayMamanBlues && } - - ) -} diff --git a/src/components/ab-testing/intentions/MeasuringIntentions.js b/src/components/ab-testing/intentions/MeasuringIntentions.js deleted file mode 100644 index 74d46d52..00000000 --- a/src/components/ab-testing/intentions/MeasuringIntentions.js +++ /dev/null @@ -1,97 +0,0 @@ -import React, { useEffect, useState } from "react" -import { clearIntentionsData } from "../../../utils/ab-testing/measuring-intentions.utils" -import { BeCloseToRealityQuestion } from "./BeCloseToRealityQuestion" -import * as Icon from "react-bootstrap-icons" -import { TEST } from "../../../utils/ab-testing/ab-testing.utils" - -const TEST_NUMBER_ENABLED = process.env.NEXT_PUBLIC_TEST_NUMBER_ENABLED - -export const MeasuringIntentions = ({ scoreLevel, setTestStarted }) => { - // Test C visible par défaut si l'on utilise pas l'AB testing - const [test, setTest] = useState(TEST.C) - const [component, setComponent] = useState() - const [showBackButton, setShowBackButton] = useState(false) - - useEffect(() => { - clearIntentionsData() - if (test != undefined && component == undefined) { - updateComponent() - } - }, [test, component]) - - useEffect(() => { - setTestStarted(showBackButton) - - if (showBackButton) { - updateComponent() - } - }, [showBackButton]) - - const updateComponent = () => { - const content = displayComponentsByTest({ - testId: test, - scoreLevel: scoreLevel, - onReset, - showBackButton, - setShowBackButton, - }) - - setComponent(content) - } - - const onReset = () => { - setComponent(undefined) - setShowBackButton(false) - } - - const showTestNumber = () => - TEST_NUMBER_ENABLED === "true" ?
Test {test}
: null - - return
{component}
-} - -export const displayComponentsByTest = ({ - testId, - scoreLevel, - onReset, - showBackButton, - setShowBackButton, -}) => { - if (testId == TEST.B) { - const contentTestB = ( - - ) - return cardComponentAndRetryButton(contentTestB, onReset, showBackButton) - } - - if (testId == TEST.C) { - const contentTestC = ( - - ) - return cardComponentAndRetryButton(contentTestC, onReset, showBackButton) - } - - return null -} - -const cardComponentAndRetryButton = (content, onReset, showBackButton) => ( -
- {showBackButton && ( - - )} - {content} -
-) diff --git a/src/components/ab-testing/intentions/TextAreaToSendDetails.js b/src/components/ab-testing/intentions/TextAreaToSendDetails.js deleted file mode 100644 index 5cb62572..00000000 --- a/src/components/ab-testing/intentions/TextAreaToSendDetails.js +++ /dev/null @@ -1,89 +0,0 @@ -import { gql, useMutation } from "@apollo/client" -import { EPDS_SAVE_COMMENTS } from "@socialgouv/nos1000jours-lib" -import { useEffect, useState } from "react" -import { client } from "../../../../apollo-client" -import { STORAGE_SCORE } from "../../../constants/constants" -import { LoaderFoButton } from "../../../utils/main.utils" -import { - contacterAToutMoment, - trackerForIntentions, -} from "../../../utils/ab-testing/measuring-intentions.utils" -import { ContactMamanBlues } from "../../results/ContactMamanBlues" -import * as StorageUtils from "../../../utils/storage.utils" - -export const TextAreaToSendDetails = ({ - scoreLevel, - displayMamanBlues = true, -}) => { - const [textValue, setTextValue] = useState("") - const [sendDetails, setSendDetails] = useState(false) - const [isLoading, setLoading] = useState(false) - const [sendSuccessful, setSendSuccessful] = useState(false) - - const handleSendDetails = () => setSendDetails(true) - - const [sendCommentsQuery] = useMutation(gql(EPDS_SAVE_COMMENTS), { - client: client, - onCompleted: () => { - setLoading(false) - setSendSuccessful(true) - }, - onError: (err) => { - console.error(err) - setLoading(false) - }, - }) - - const sendCommentsRequest = async () => { - const score = parseInt(StorageUtils.getInLocalStorage(STORAGE_SCORE)) - - await sendCommentsQuery({ - variables: { - score: score, - commentaire: textValue, - }, - }) - } - - useEffect(() => { - if (sendDetails) { - setLoading(true) - sendCommentsRequest() - - trackerForIntentions(scoreLevel, "Envoi du commentaire") - } - }, [sendDetails]) - - return ( -
-