From 1b670028a352817e7337a2d6aaf31e388d830cdf Mon Sep 17 00:00:00 2001 From: GregoireDucharme Date: Tue, 7 Jan 2025 09:33:58 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20permet=20l'acc=C3=A8s=20en=20lecture=20?= =?UTF-8?q?seul=20au=20nouvel=20OC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SingleItemCertificationBodyForm.test.js | 211 +++++++++++------- .../forms/SingleItemCertificationBodyForm.vue | 25 ++- .../forms/fields/AnnotationsSelector.vue | 5 + .../forms/fields/ConversionLevelSelector.vue | 2 +- .../forms/fields/CultureSelector.vue | 2 +- .../forms/fields/CultureTypeSelector.vue | 2 +- src/components/records/Header.test.js | 19 +- src/components/records/Header.vue | 16 +- src/components/records/Table/FeatureGroup.vue | 48 +++- src/components/records/Table/index.test.js | 58 +++++ src/components/records/Table/index.vue | 19 +- src/components/setup/Flow/Preview.vue | 2 +- src/components/widgets/Modal.vue | 5 + .../[numeroBio]/[recordId]/index.vue | 5 +- src/pages/exploitations/[numeroBio]/index.vue | 35 ++- src/stores/permissions.js | 8 +- src/stores/permissions.test.js | 19 +- src/stores/record.js | 1 + src/utils/__fixtures__/operator.json | 5 +- .../__fixtures__/record-with-features.json | 1 + 20 files changed, 378 insertions(+), 110 deletions(-) diff --git a/src/components/forms/SingleItemCertificationBodyForm.test.js b/src/components/forms/SingleItemCertificationBodyForm.test.js index 429da978..da149071 100644 --- a/src/components/forms/SingleItemCertificationBodyForm.test.js +++ b/src/components/forms/SingleItemCertificationBodyForm.test.js @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { defineComponent, markRaw } from "vue"; import { createTestingPinia } from "@pinia/testing"; import { flushPromises, mount } from "@vue/test-utils"; @@ -12,15 +12,19 @@ import { CERTIFICATION_BODY_DECISION, LEVEL_AB, LEVEL_C1, + LEVEL_C2, + LEVEL_C3, LEVEL_CONVENTIONAL, } from "@/referentiels/ab.js"; import record from "@/utils/__fixtures__/record-with-features.json" assert { type: "json" }; import EditForm from "@/components/forms/SingleItemCertificationBodyForm.vue"; import TableComponent from "@/components/records/Table/index.vue"; +import { useOperatorStore } from "@/stores/operator"; const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false }); const recordStore = useRecordStore(pinia); +const operatorStore = useOperatorStore(pinia); const permissions = usePermissions(pinia); const storage = useCartoBioStorage(pinia); @@ -51,97 +55,146 @@ describe("SingleItemCertificationBodyForm", () => { document.body.outerHTML = ""; }); - test("we assign a certification state", async () => { - const form = wrapper.getComponent(EditForm); - - // if "Conventionnel", there is no date field - await form.find(`#conversion-${LEVEL_CONVENTIONAL}`).setValue(); - expect(form.find("#engagement_date").exists()).toEqual(false); + describe("item is not readonly", async () => { + beforeAll(async () => { + operatorStore.operator = { + organismeCertificateur: { + id: 1, + }, + }; + }); + test("we assign a certification state", async () => { + const form = wrapper.getComponent(EditForm); - // if AB, date field is not mandatory - await form.find(`#conversion-${LEVEL_AB}`).setValue(); - expect(form.find("#engagement_date").attributes()).not.toHaveProperty("required"); + // if "Conventionnel", there is no date field + await form.find(`#conversion-${LEVEL_CONVENTIONAL}`).setValue(); + expect(form.find("#engagement_date").exists()).toEqual(false); - // date field is mandatory otherwise - await form.find(`#conversion-${LEVEL_C1}`).setValue(); - expect(form.find("#engagement_date").attributes()).toHaveProperty("required", ""); - }); + // if AB, date field is not mandatory + await form.find(`#conversion-${LEVEL_AB}`).setValue(); + expect(form.find("#engagement_date").attributes()).not.toHaveProperty("required"); - test("we toggle expanded annotations", async () => { - const form = wrapper.getComponent(EditForm); + // date field is mandatory otherwise + await form.find(`#conversion-${LEVEL_C1}`).setValue(); + expect(form.find("#engagement_date").attributes()).toHaveProperty("required", ""); + }); - // We have all the tags tags and no expand button - expect(form.findAll(".fr-tags-group--annotations > .annotation-choice")).toHaveLength(5); - expect(form.find(".fr-tags-group--annotations > .annotation--more").attributes()).toHaveProperty("hidden"); + test("we toggle expanded annotations", async () => { + const form = wrapper.getComponent(EditForm); - // expect(form.find('.fr-tags-group--annotations > .annotation--more').attributes()).not.toHaveProperty('hidden') - // await form.find('.fr-tags-group--annotations > .annotation--more button').trigger('click') + // We have all the tags tags and no expand button + expect(form.findAll(".fr-tags-group--annotations > .annotation-choice")).toHaveLength(5); + expect(form.find(".fr-tags-group--annotations > .annotation--more").attributes()).toHaveProperty("hidden"); - const expectedChoices = Object.keys(AnnotationTags); - expect(form.findAll(".fr-tags-group--annotations > .annotation-choice")).toHaveLength(expectedChoices.length); - }); + // expect(form.find('.fr-tags-group--annotations > .annotation--more').attributes()).not.toHaveProperty('hidden') + // await form.find('.fr-tags-group--annotations > .annotation--more button').trigger('click') - test("we select three choices, and two reasons", async () => { - const form = wrapper.getComponent(EditForm); + const expectedChoices = Object.keys(AnnotationTags); + expect(form.findAll(".fr-tags-group--annotations > .annotation-choice")).toHaveLength(expectedChoices.length); + }); - // We have 5 tags - await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.DOWNGRADED} button`).trigger("click"); - await form - .find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.REDUCED_CONVERSION_PERIOD} button`) - .trigger("click"); - await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.RISKY} button`).trigger("click"); + test("we select three choices, and two reasons", async () => { + const form = wrapper.getComponent(EditForm); + + // We have 5 tags + await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.DOWNGRADED} button`).trigger("click"); + await form + .find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.REDUCED_CONVERSION_PERIOD} button`) + .trigger("click"); + await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.RISKY} button`).trigger("click"); + + expect(form.find("#downgraded_state").element.value).toEqual(CERTIFICATION_BODY_DECISION.PENDING); + expect(form.find("#downgraded_state").element.selectedOptions[0].textContent).toEqual("En cours de traitement"); + + expect(form.find("#reduced_conversion_period_state").element.value).toEqual(CERTIFICATION_BODY_DECISION.PENDING); + expect(form.find("#reduced_conversion_period_state").element.selectedOptions[0].textContent).toEqual( + "En cours de traitement", + ); + + // we toggle and cancel the tag + await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.SURVEYED} button`).trigger("click"); + await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.SURVEYED} button`).trigger("click"); + + await form.find("#reduced_conversion_period_state").setValue(CERTIFICATION_BODY_DECISION.REJECTED); + await form.find("#downgraded_state").setValue(CERTIFICATION_BODY_DECISION.ACCEPTED); + + // click and assess server update + axios.__createMock.patch.mockResolvedValueOnce({ data: record }); + axios.__createMock.get.mockResolvedValueOnce({ data: record }); + await form.find(".fr-modal__footer button.fr-btn").trigger("click"); + + await flushPromises(); + expect(wrapper.findComponent(EditForm).exists()).toEqual(false); + expect(axios.__createMock.patch).toHaveBeenCalled(); + expect(axios.__createMock.patch.mock.lastCall).toMatchObject([ + "/v2/audits/054f0d70-c3da-448f-823e-81fcf7c2bf6e/parcelles/2", + { + properties: { + annotations: [ + { + code: ANNOTATIONS.DOWNGRADED, + metadata: { + [ANNOTATIONS.METADATA_STATE]: CERTIFICATION_BODY_DECISION.ACCEPTED, + }, + }, + { + code: ANNOTATIONS.REDUCED_CONVERSION_PERIOD, + metadata: { + [ANNOTATIONS.METADATA_STATE]: CERTIFICATION_BODY_DECISION.REJECTED, + }, + }, + { + code: ANNOTATIONS.RISKY, + }, + ], + }, + }, + { + headers: { + "If-Unmodified-Since": expect.any(String), + }, + }, + ]); + }); + }); - expect(form.find("#downgraded_state").element.value).toEqual(CERTIFICATION_BODY_DECISION.PENDING); - expect(form.find("#downgraded_state").element.selectedOptions[0].textContent).toEqual("En cours de traitement"); + describe("item is readonly", async () => { + beforeAll(async () => { + operatorStore.operator = { + organismeCertificateur: { + id: 2, + }, + }; + }); + test("certification state are disabled", async () => { + const form = wrapper.getComponent(EditForm); + + expect(form.find(`#conversion-${LEVEL_CONVENTIONAL}`).isDisabled()).toEqual(true); + expect(form.find(`#conversion-${LEVEL_C1}`).isDisabled()).toEqual(true); + expect(form.find(`#conversion-${LEVEL_C2}`).isDisabled()).toEqual(true); + expect(form.find(`#conversion-${LEVEL_C3}`).isDisabled()).toEqual(true); + expect(form.find(`#conversion-${LEVEL_AB}`).isDisabled()).toEqual(true); + }); - expect(form.find("#reduced_conversion_period_state").element.value).toEqual(CERTIFICATION_BODY_DECISION.PENDING); - expect(form.find("#reduced_conversion_period_state").element.selectedOptions[0].textContent).toEqual( - "En cours de traitement", - ); + test("annotations are disabled", async () => { + const form = wrapper.getComponent(EditForm); - // we toggle and cancel the tag - await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.SURVEYED} button`).trigger("click"); - await form.find(`.fr-tags-group--annotations > .annotation--${ANNOTATIONS.SURVEYED} button`).trigger("click"); + // We have all the tags tags and no expand button + expect(form.findAll(".fr-tags-group--annotations > .annotation-choice")).toHaveLength(5); + expect(form.find(".fr-tags-group--annotations > .annotation--more").attributes()).toHaveProperty("hidden"); - await form.find("#reduced_conversion_period_state").setValue(CERTIFICATION_BODY_DECISION.REJECTED); - await form.find("#downgraded_state").setValue(CERTIFICATION_BODY_DECISION.ACCEPTED); + // expect(form.find('.fr-tags-group--annotations > .annotation--more').attributes()).not.toHaveProperty('hidden') + // await form.find('.fr-tags-group--annotations > .annotation--more button').trigger('click') - // click and assess server update - axios.__createMock.patch.mockResolvedValueOnce({ data: record }); - axios.__createMock.get.mockResolvedValueOnce({ data: record }); - await form.find(".fr-modal__footer button.fr-btn").trigger("click"); + const expectedChoices = Object.keys(AnnotationTags); + expect(form.findAll(".fr-tags-group--annotations > .annotation-choice")).toHaveLength(expectedChoices.length); - await flushPromises(); - expect(wrapper.findComponent(EditForm).exists()).toEqual(false); - expect(axios.__createMock.patch).toHaveBeenCalled(); - expect(axios.__createMock.patch.mock.lastCall).toMatchObject([ - "/v2/audits/054f0d70-c3da-448f-823e-81fcf7c2bf6e/parcelles/2", - { - properties: { - annotations: [ - { - code: ANNOTATIONS.DOWNGRADED, - metadata: { - [ANNOTATIONS.METADATA_STATE]: CERTIFICATION_BODY_DECISION.ACCEPTED, - }, - }, - { - code: ANNOTATIONS.REDUCED_CONVERSION_PERIOD, - metadata: { - [ANNOTATIONS.METADATA_STATE]: CERTIFICATION_BODY_DECISION.REJECTED, - }, - }, - { - code: ANNOTATIONS.RISKY, - }, - ], - }, - }, - { - headers: { - "If-Unmodified-Since": expect.any(String), - }, - }, - ]); + const annotations = form.findAll(".fr-tags-group--annotations > .annotation-choice > button"); + expect(annotations[0].isDisabled()).toEqual(true); + expect(annotations[1].isDisabled()).toEqual(true); + expect(annotations[2].isDisabled()).toEqual(true); + expect(annotations[3].isDisabled()).toEqual(true); + expect(annotations[4].isDisabled()).toEqual(true); + }); }); }); diff --git a/src/components/forms/SingleItemCertificationBodyForm.vue b/src/components/forms/SingleItemCertificationBodyForm.vue index 352a1b1a..8a22a1a1 100644 --- a/src/components/forms/SingleItemCertificationBodyForm.vue +++ b/src/components/forms/SingleItemCertificationBodyForm.vue @@ -12,6 +12,7 @@ :required="requiredName" :class="{ 'fr-input--error': nameErrors.size }" ref="autofocusedElement" + :disabled="readonly" />
{{ result.errorMessage }}. @@ -41,6 +42,7 @@ :feature-id="feature.properties.id" :cultures="patch.cultures" @change="($cultures) => (patch.cultures = $cultures)" + :disabled-input="readonly" /> @@ -53,7 +55,7 @@ > @@ -78,9 +80,10 @@ v-if="permissions.canAddAnnotations" v-model="patch.annotations" :feature-id="feature.properties.id" + :readonly="readonly" /> -
+