From 89caff6d561333cc06f6d2d8421dad6332293fe8 Mon Sep 17 00:00:00 2001 From: Pierre Vasseur <132562606+PierreVasseur@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:10:43 +0200 Subject: [PATCH] Feat: add zod to concepts (#903) * delete unused file * fix validation for links * unecessary return * unfinished * delete unused folder * fix validation * fix double check on scopenote * fix: improve zod validation for concept * improve zod once again * add and reshape tests * fix test * add messages to notes and set title to red if scopenote too long * fix error messages for codelists --------- Co-authored-by: Emmanuel --- .husky/pre-commit | 1 - .kubernetes/deployment.yml | 25 - .kubernetes/ingress.yml | 18 - .kubernetes/service.yml | 11 - .../components/note-edition/index.tsx | 55 +- .../note-edition/note-edition.spec.tsx | 13 +- .../modules-codelists/i18n/dictionary.js | 12 + src/packages/modules-codelists/utils/index.js | 17 +- .../modules-codelists/utils/index.spec.js | 12 +- .../edition-creation/controls/validation.js | 166 ++-- .../controls/validation.spec.js | 324 ++++--- .../modules-concepts/edition-creation/home.js | 4 +- .../edition-creation/notes.js | 35 +- .../distributions/validation.spec.js | 14 +- .../document/edition/validation.js | 4 +- .../families/edition/validation.spec.js | 22 +- .../indicators/edition/validation.spec.js | 30 +- .../operations/edition/validation.spec.js | 14 +- .../series/edition/validation.spec.js | 4 +- .../components/edition/validation.spec.js | 22 +- .../edition/validation.spec.js | 24 +- swagger.yaml | 914 ------------------ 22 files changed, 381 insertions(+), 1360 deletions(-) delete mode 100644 .husky/pre-commit delete mode 100644 .kubernetes/deployment.yml delete mode 100644 .kubernetes/ingress.yml delete mode 100644 .kubernetes/service.yml delete mode 100644 swagger.yaml diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100644 index 72c4429bc..000000000 --- a/.husky/pre-commit +++ /dev/null @@ -1 +0,0 @@ -npm test diff --git a/.kubernetes/deployment.yml b/.kubernetes/deployment.yml deleted file mode 100644 index 3bab7d340..000000000 --- a/.kubernetes/deployment.yml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: bauhaus -spec: - replicas: 1 - selector: - matchLabels: - app: bauhaus - template: - metadata: - labels: - app: bauhaus - spec: - containers: - - name: bauhaus - image: nicolaslaval/bauhaus:3.0.8 - env: - - name: API_BASE_HOST - value: 'https://bauhaus-api.toto.fr/api' - - name: API_MODE - # server or local - value: 'server' - - name: APPLICATIONS - value: 'concepts,classifications,operations,structures' diff --git a/.kubernetes/ingress.yml b/.kubernetes/ingress.yml deleted file mode 100644 index 3979943f7..000000000 --- a/.kubernetes/ingress.yml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: bauhaus - annotations: - kubernetes.io/ingress.class: nginx -spec: - tls: - - hosts: - - bauhaus.todo.fr - rules: - - host: bauhaus.todo.fr - http: - paths: - - path: / - backend: - serviceName: bauhaus - servicePort: http diff --git a/.kubernetes/service.yml b/.kubernetes/service.yml deleted file mode 100644 index 6e1021473..000000000 --- a/.kubernetes/service.yml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: bauhaus -spec: - ports: - - name: http - targetPort: 80 - port: 80 - selector: - app: bauhaus diff --git a/src/packages/components/note-edition/index.tsx b/src/packages/components/note-edition/index.tsx index 85e1564e5..81500c55c 100644 --- a/src/packages/components/note-edition/index.tsx +++ b/src/packages/components/note-edition/index.tsx @@ -1,45 +1,56 @@ import NoteOneLangEdition from './note-one-lang-edition'; -import D from '../../deprecated-locales'; +import { ClientSideError } from '../errors-bloc'; type NoteEditionTypes = { - noteLg1: string; + notes: any; + noteLg1Name: string; + noteLg2Name: string; handleChangeLg1: (value: string) => void; - noteLg2: string; handleChangeLg2: (value: string) => void; maxLength: number; + errorMessage: { errorMessage: string[]; fields: any }; }; export const NoteEdition = ({ - noteLg1, + notes, + noteLg1Name, + noteLg2Name, handleChangeLg1, - noteLg2, handleChangeLg2, maxLength, + errorMessage, }: Readonly) => { + const noteLg1 = notes[noteLg1Name]; + const noteLg2 = notes[noteLg2Name]; return (
- + <> + + +
- + <> + + +
- {maxLength && ( -
-
- {maxLength} {D.scopeNoteChar} -
-
- )}
); }; diff --git a/src/packages/components/note-edition/note-edition.spec.tsx b/src/packages/components/note-edition/note-edition.spec.tsx index 7c1f298cf..723b63688 100644 --- a/src/packages/components/note-edition/note-edition.spec.tsx +++ b/src/packages/components/note-edition/note-edition.spec.tsx @@ -5,11 +5,20 @@ describe('note-edition', () => { it('renders without crashing', () => { render( ); }); diff --git a/src/packages/modules-codelists/i18n/dictionary.js b/src/packages/modules-codelists/i18n/dictionary.js index 141cb701f..55c186be8 100644 --- a/src/packages/modules-codelists/i18n/dictionary.js +++ b/src/packages/modules-codelists/i18n/dictionary.js @@ -43,14 +43,26 @@ const dictionary = { fr: 'Uri Liste : commence par http://rdf.insee.fr/codes/', en: 'Uri Liste : starts with http://rdf.insee.fr/codes/', }, + lastListUriSegmentTitleShort: { + fr: 'Uri Liste', + en: 'Uri Liste', + }, lastCodeUriSegmentTitle: { fr: "Uri des codes, singulier de l'URI de la liste : commence par http://rdf.insee.fr/codes/", en: 'Uri of codes, singular from list URI : starts with http://rdf.insee.fr/codes/', }, + lastCodeUriSegmentTitleShort: { + fr: 'Uri des codes', + en: 'Uri of codes', + }, lastClassUriSegmentTitle: { fr: 'Uri class owl : commence par http://rdf.insee.fr/codes/concept/', en: 'Uri class owl : starts with http://rdf.insee.fr/codes/concept/', }, + lastClassUriSegmentTitleShort: { + fr: 'Uri class owl', + en: 'Uri class owl', + }, codelistsSearchTitle: { fr: 'Listes de codes - Recherche', en: 'Code lists - Search', diff --git a/src/packages/modules-codelists/utils/index.js b/src/packages/modules-codelists/utils/index.js index 536f3cf4c..d8a811204 100644 --- a/src/packages/modules-codelists/utils/index.js +++ b/src/packages/modules-codelists/utils/index.js @@ -11,22 +11,22 @@ export const formatLabel = (component) => { const CodesList = z.object({ lastListUriSegment: z .string({ - required_error: D.mandatoryProperty(D.lastListUriSegmentTitle), + required_error: D.mandatoryProperty(D.lastListUriSegmentTitleShort), }) .trim() - .min(1, { message: D.mandatoryProperty(D.lastListUriSegmentTitle) }), + .min(1, { message: D.mandatoryProperty(D.lastListUriSegmentTitleShort) }), lastCodeUriSegment: z .string({ - required_error: D.mandatoryProperty(D.lastCodeUriSegmentTitle), + required_error: D.mandatoryProperty(D.lastCodeUriSegmentTitleShort), }) .trim() - .min(1, { message: D.mandatoryProperty(D.lastCodeUriSegmentTitle) }), + .min(1, { message: D.mandatoryProperty(D.lastCodeUriSegmentTitleShort) }), lastClassUriSegment: z .string({ - required_error: D.mandatoryProperty(D.lastClassUriSegmentTitle), + required_error: D.mandatoryProperty(D.lastClassUriSegmentTitleShort), }) .trim() - .min(1, { message: D.mandatoryProperty(D.lastClassUriSegmentTitle) }), + .min(1, { message: D.mandatoryProperty(D.lastClassUriSegmentTitleShort) }), id: z .string({ required_error: D.mandatoryProperty(D.idTitle) }) .trim() @@ -105,9 +105,8 @@ const Code = (shouldCheckDuplicate, codes) => .trim() .min(1, { message: D.mandatoryProperty(D.idTitle) }) .refine( - (value) => { - return !shouldCheckDuplicate || !codes.find((c) => c.code === value); - }, + (value) => + !shouldCheckDuplicate || !codes.find((c) => c.code === value), { message: D.ErrorDoubleCode, } diff --git a/src/packages/modules-codelists/utils/index.spec.js b/src/packages/modules-codelists/utils/index.spec.js index 06d2c5586..ad63efb98 100644 --- a/src/packages/modules-codelists/utils/index.spec.js +++ b/src/packages/modules-codelists/utils/index.spec.js @@ -13,13 +13,13 @@ describe('validateCodelist', () => { const result = validateCodelist(codelist); expect(result.errorMessage).toContain( - D.mandatoryProperty(D.lastListUriSegmentTitle) + D.mandatoryProperty(D.lastListUriSegmentTitleShort) ); expect(result.errorMessage).toContain( - D.mandatoryProperty(D.lastCodeUriSegmentTitle) + D.mandatoryProperty(D.lastCodeUriSegmentTitleShort) ); expect(result.errorMessage).toContain( - D.mandatoryProperty(D.lastClassUriSegmentTitle) + D.mandatoryProperty(D.lastClassUriSegmentTitleShort) ); expect(result.errorMessage).toContain(D.mandatoryProperty(D.idTitle)); expect(result.errorMessage).toContain(D.mandatoryProperty(D1.labelTitle)); @@ -30,13 +30,13 @@ describe('validateCodelist', () => { ); expect(result.fields.lastListUriSegment).toBe( - D.mandatoryProperty(D.lastListUriSegmentTitle) + D.mandatoryProperty(D.lastListUriSegmentTitleShort) ); expect(result.fields.lastCodeUriSegment).toBe( - D.mandatoryProperty(D.lastCodeUriSegmentTitle) + D.mandatoryProperty(D.lastCodeUriSegmentTitleShort) ); expect(result.fields.lastClassUriSegment).toBe( - D.mandatoryProperty(D.lastClassUriSegmentTitle) + D.mandatoryProperty(D.lastClassUriSegmentTitleShort) ); expect(result.fields.id).toBe(D.mandatoryProperty(D.idTitle)); expect(result.fields.labelLg1).toBe(D.mandatoryProperty(D1.labelTitle)); diff --git a/src/packages/modules-concepts/edition-creation/controls/validation.js b/src/packages/modules-concepts/edition-creation/controls/validation.js index 402e6d954..20f41aa69 100644 --- a/src/packages/modules-concepts/edition-creation/controls/validation.js +++ b/src/packages/modules-concepts/edition-creation/controls/validation.js @@ -1,111 +1,67 @@ import { htmlIsEmpty, htmlLength } from '../../../utils/html-utils'; import D, { D1 } from '../../../deprecated-locales'; +import { z } from 'zod'; +import { formatValidation } from '../../../utils/validation'; -export const scndWithoutFirst = (first, second) => { - return !htmlIsEmpty(second) && htmlIsEmpty(first); -}; - -export const checkPrefLabelLg1Existing = ( - concepts, - prefLabelLg1, - initialPrefLabelFr -) => { - return ( - prefLabelLg1 !== initialPrefLabelFr && - concepts.map((concept) => concept.label).indexOf(prefLabelLg1) !== -1 - ); -}; - -const validate = ( - oldGeneral, - newGeneral, +const Concept = ( + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote, + scopeNoteLg1CanBeEmpty +) => + z.object({ + prefLabelLg1: z + .string({ required_error: D.mandatoryProperty(D1.labelTitle) }) + .trim() + .min(1, { message: D.mandatoryProperty(D1.labelTitle) }) + .refine( + (value) => + value === oldLabelLg1 || + !conceptsWithLinks.map((concept) => concept.label).includes(value), + + { message: D.duplicatedLabel } + ), + creator: z + .string({ required_error: D.mandatoryProperty(D.creatorTitle) }) + .min(1, { message: D.mandatoryProperty(D.creatorTitle) }), + disseminationStatus: z + .string({ + required_error: D.mandatoryProperty(D.disseminationStatusTitle), + }) + .min(1, { message: D.mandatoryProperty(D.disseminationStatusTitle) }), + scopeNoteLg1: z + .string() + .refine((value) => htmlLength(value) <= maxLengthScopeNote, { + message: D.tooLongScopeNote(maxLengthScopeNote), + }) + .refine((value) => scopeNoteLg1CanBeEmpty || !htmlIsEmpty(value), { + message: D.emptyScopeNoteLg1, + }), + scopeNoteLg2: z + .string() + .refine((value) => htmlLength(value) <= maxLengthScopeNote, { + message: D.tooLongScopeNote(maxLengthScopeNote), + }), + definitionLg1: z.string().refine((value) => !htmlIsEmpty(value), { + message: D.emptyDefinitionLg1, + }), + }); + +export const validate = ( + general, notes, + oldLabelLg1, conceptsWithLinks, maxLengthScopeNote -) => { - const errorMessage = []; - const fields = {}; - - const isPrefLabelLg1Existing = checkPrefLabelLg1Existing( - conceptsWithLinks, - newGeneral.prefLabelLg1, - oldGeneral.prefLabelLg1 - ); - - if (!newGeneral.prefLabelLg1) { - errorMessage.push(D.mandatoryProperty(D1.labelTitle)); - fields.prefLabelLg1 = D.mandatoryProperty(D1.labelTitle); - } - if (isPrefLabelLg1Existing) { - errorMessage.push(D.duplicatedLabel); - fields.prefLabelLg1 = D.duplicatedLabel; - } - - if (!newGeneral.creator) { - errorMessage.push(D.mandatoryProperty(D.creatorTitle)); - fields.creator = D.mandatoryProperty(D.creatorTitle); - } - if (!newGeneral.disseminationStatus) { - errorMessage.push(D.mandatoryProperty(D.disseminationStatusTitle)); - fields.disseminationStatus = D.mandatoryProperty( - D.disseminationStatusTitle - ); - } - - if (htmlIsEmpty(notes.definitionLg1)) { - errorMessage.push(D.emptyDefinitionLg1); - fields.definitionLg1 = D.emptyDefinitionLg1; - } - - const isStatusPublicAndEmptyScopeNote = - newGeneral.disseminationStatus.includes('Public') && - htmlIsEmpty(notes.scopeNoteLg1); - - if (isStatusPublicAndEmptyScopeNote) { - errorMessage.push(D.emptyScopeNoteLg1); - fields.scopeNoteLg1 = D.emptyScopeNoteLg1; - } - - const hasScopeNoteLg2NotLg1 = scndWithoutFirst( - notes.scopeNoteLg1, - notes.scopeNoteLg2 - ); - - if (hasScopeNoteLg2NotLg1) { - errorMessage.push(D.hasScopeNoteLg2NotLg1); - fields.scopeNoteLg1 = D.hasScopeNoteLg2NotLg1; - } - - if (htmlLength(notes.scopeNoteLg1) > maxLengthScopeNote) { - errorMessage.push(D.tooLongScopeNote(maxLengthScopeNote)); - fields.scopeNoteLg1 = D.tooLongScopeNote(maxLengthScopeNote); - } - if (htmlLength(notes.scopeNoteLg2) > maxLengthScopeNote) { - errorMessage.push(D.tooLongScopeNote(maxLengthScopeNote)); - fields.scopeNoteLg2 = D.tooLongScopeNote(maxLengthScopeNote); - } - - const hasEditorialNoteLg2NotLg1 = scndWithoutFirst( - notes.editorialNoteLg1, - notes.editorialNoteLg2 - ); - - if (hasEditorialNoteLg2NotLg1) { - errorMessage.push(D.hasEditorialNoteLg2NotLg1); - fields.editorialNoteLg1 = D.hasEditorialNoteLg2NotLg1; - } - - const hasChangeNoteLg2NotLg1 = scndWithoutFirst( - notes.changeNoteLg1, - notes.changeNoteLg2 - ); - - if (hasChangeNoteLg2NotLg1) { - errorMessage.push(D.hasChangeNoteLg2NotLg1); - fields.changeNoteLg1 = D.hasChangeNoteLg2NotLg1; - } - - return { errorMessage, fields }; -}; - -export default validate; +) => + formatValidation( + Concept( + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote, + !general.disseminationStatus.includes('Public') + ) + )({ + ...general, + ...notes, + }); diff --git a/src/packages/modules-concepts/edition-creation/controls/validation.spec.js b/src/packages/modules-concepts/edition-creation/controls/validation.spec.js index 759a9024d..feac2b58d 100644 --- a/src/packages/modules-concepts/edition-creation/controls/validation.spec.js +++ b/src/packages/modules-concepts/edition-creation/controls/validation.spec.js @@ -1,184 +1,208 @@ -import validator, { - scndWithoutFirst, - checkPrefLabelLg1Existing, -} from './validation'; -import * as HTMLUtils from '../../../utils/html-utils'; -import D, { D1 } from '../../../deprecated-locales'; - -jest.mock('../../../utils/html-utils', () => ({ - htmlIsEmpty: jest.fn(), - htmlLength: jest.fn(), -})); - -describe('scndWithoutFirst', () => { - it('should return true when second is not empty and first is empty', () => { - HTMLUtils.htmlIsEmpty.mockImplementation((html) => html === ''); - - const result = scndWithoutFirst('', 'not empty'); - expect(result).toBe(true); - }); +import { validate } from './validation'; - it('should return false when first is not empty', () => { - HTMLUtils.htmlIsEmpty.mockImplementation((html) => html === ''); +describe('validation', function () { + it('should return an error for creator', function () { + const general = { + prefLabelLg1: 'prefLabelLg1', + disseminationStatus: 'Public', + }; - const result = scndWithoutFirst('not empty', 'not empty'); - expect(result).toBe(false); - }); + const notes = { + scopeNoteLg1: 'scopeNote1', + scopeNoteLg2: 'scopeNote2', + definitionLg1: 'definitionLg1', + }; - it('should return false when second is empty', () => { - HTMLUtils.htmlIsEmpty.mockImplementation((html) => html === ''); + const oldLabelLg1 = 'oldLabelLg1'; - const result = scndWithoutFirst('', ''); - expect(result).toBe(false); - }); -}); + const conceptsWithLinks = [{ label: 'existingLabel' }]; -describe('checkPrefLabelLg1Existing', () => { - it('should return true when prefLabelLg1 exists in concepts and is different from initialPrefLabelFr', () => { - const concepts = [{ label: 'existingLabel' }]; - const result = checkPrefLabelLg1Existing( - concepts, - 'existingLabel', - 'initialLabel' - ); - expect(result).toBe(true); + const maxLengthScopeNote = 350; + + expect( + validate( + general, + notes, + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote + ) + ).toEqual({ + errorMessage: ['The property Owner is required.'], + fields: { + prefLabelLg1: '', + creator: 'The property Owner is required.', + disseminationStatus: '', + scopeNoteLg1: '', + scopeNoteLg2: '', + definitionLg1: '', + }, + }); }); - it('should return false when prefLabelLg1 is the same as initialPrefLabelFr', () => { - const concepts = [{ label: 'existingLabel' }]; - const result = checkPrefLabelLg1Existing( - concepts, - 'initialLabel', - 'initialLabel' - ); - expect(result).toBe(false); - }); + it('should return an error if prefLabelLg1 already exists', function () { + const general = { + prefLabelLg1: 'prefLabelLg1', + creator: 'creator', + disseminationStatus: 'Public', + }; - it('should return false when prefLabelLg1 does not exist in concepts', () => { - const concepts = [{ label: 'otherLabel' }]; - const result = checkPrefLabelLg1Existing( - concepts, - 'nonExistingLabel', - 'initialLabel' - ); - expect(result).toBe(false); - }); -}); + const notes = { + scopeNoteLg1: 'scopeNote1', + scopeNoteLg2: 'scopeNote2', + definitionLg1: 'definitionLg1', + }; -describe('validator', () => { - it('should return errors for missing mandatory fields and duplicated label', () => { - HTMLUtils.htmlIsEmpty.mockReturnValue(true); - HTMLUtils.htmlLength.mockReturnValue(0); + const oldLabelLg1 = 'oldLabelLg1'; + + const conceptsWithLinks = [{ label: 'prefLabelLg1' }]; + + const maxLengthScopeNote = 350; + + expect( + validate( + general, + notes, + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote + ) + ).toEqual({ + errorMessage: ['This label already exists'], + fields: { + prefLabelLg1: 'This label already exists', + creator: '', + disseminationStatus: '', + scopeNoteLg1: '', + scopeNoteLg2: '', + definitionLg1: '', + }, + }); + }); - const oldGeneral = { prefLabelLg1: 'oldLabel' }; - const newGeneral = { - prefLabelLg1: '', - creator: '', + it('should return an error if scopeNoteLg1 and scopeNoteLg2 are too long', function () { + const general = { + prefLabelLg1: 'prefLabelLg1', + creator: 'creator', disseminationStatus: 'Public', }; + const notes = { - definitionLg1: '', - scopeNoteLg1: '', - scopeNoteLg2: '', - editorialNoteLg1: '', - editorialNoteLg2: '', - changeNoteLg1: '', - changeNoteLg2: '', + scopeNoteLg1: 'x'.repeat(351), + scopeNoteLg2: 'y'.repeat(351), + definitionLg1: 'definitionLg1', }; - const conceptsWithLinks = [{ label: 'duplicatedLabel' }]; - const maxLengthScopeNote = 100; - - const result = validator( - oldGeneral, - newGeneral, - notes, - conceptsWithLinks, - maxLengthScopeNote - ); - - expect(result.errorMessage).toContain(D.mandatoryProperty(D1.labelTitle)); - expect(result.errorMessage).toContain(D.mandatoryProperty(D.creatorTitle)); - expect(result.errorMessage).toContain(D.emptyDefinitionLg1); - expect(result.errorMessage).toContain(D.emptyScopeNoteLg1); - - expect(result.fields.prefLabelLg1).toBe(D.mandatoryProperty(D1.labelTitle)); - expect(result.fields.creator).toBe(D.mandatoryProperty(D.creatorTitle)); - expect(result.fields.definitionLg1).toBe(D.emptyDefinitionLg1); - expect(result.fields.scopeNoteLg1).toBe(D.emptyScopeNoteLg1); - }); - it('should return error for too long scope notes', () => { - HTMLUtils.htmlIsEmpty.mockReturnValue(false); - HTMLUtils.htmlLength.mockImplementation((html) => html.length); + const oldLabelLg1 = 'oldLabelLg1'; - const oldGeneral = { prefLabelLg1: 'oldLabel' }; - const newGeneral = { - prefLabelLg1: 'newLabel', + const conceptsWithLinks = [{ label: 'existingLabel' }]; + + const maxLengthScopeNote = 350; + + expect( + validate( + general, + notes, + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote + ) + ).toEqual({ + errorMessage: [ + 'Short definition is limited to 350 characters', + 'Short definition is limited to 350 characters', + ], + fields: { + prefLabelLg1: '', + creator: '', + disseminationStatus: '', + scopeNoteLg1: 'Short definition is limited to 350 characters', + scopeNoteLg2: 'Short definition is limited to 350 characters', + definitionLg1: '', + }, + }); + }); + + it('should return an error if disseminationStatus is Public and scopeNoteLg1 is empty', function () { + const general = { + prefLabelLg1: 'prefLabelLg1', creator: 'creator', disseminationStatus: 'Public', }; + const notes = { - definitionLg1: 'definition', - scopeNoteLg1: 'a'.repeat(101), - scopeNoteLg2: 'a'.repeat(101), - editorialNoteLg1: '', - editorialNoteLg2: '', - changeNoteLg1: '', - changeNoteLg2: '', + scopeNoteLg1: '', + scopeNoteLg2: 'scopeNote2', + definitionLg1: 'definitionLg1', }; + + const oldLabelLg1 = 'oldLabelLg1'; + const conceptsWithLinks = [{ label: 'existingLabel' }]; - const maxLengthScopeNote = 100; - - const result = validator( - oldGeneral, - newGeneral, - notes, - conceptsWithLinks, - maxLengthScopeNote - ); - - expect(result.errorMessage).toContain( - D.tooLongScopeNote(maxLengthScopeNote) - ); - expect(result.fields.scopeNoteLg1).toBe( - D.tooLongScopeNote(maxLengthScopeNote) - ); - expect(result.fields.scopeNoteLg2).toBe( - D.tooLongScopeNote(maxLengthScopeNote) - ); - }); - it('should pass validation for valid input', () => { - HTMLUtils.htmlIsEmpty.mockReturnValue(false); - HTMLUtils.htmlLength.mockImplementation((html) => html.length); + const maxLengthScopeNote = 350; + + expect( + validate( + general, + notes, + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote + ) + ).toEqual({ + errorMessage: [ + 'As dissemination status is public, short definition has to be completed', + ], + fields: { + prefLabelLg1: '', + creator: '', + disseminationStatus: '', + scopeNoteLg1: + 'As dissemination status is public, short definition has to be completed', + scopeNoteLg2: '', + definitionLg1: '', + }, + }); + }); - const oldGeneral = { prefLabelLg1: 'oldLabel' }; - const newGeneral = { - prefLabelLg1: 'newLabel', + it('should no error', function () { + const general = { + prefLabelLg1: 'prefLabelLg1', creator: 'creator', disseminationStatus: 'Public', }; + const notes = { - definitionLg1: 'definition', scopeNoteLg1: 'scopeNote1', scopeNoteLg2: 'scopeNote2', - editorialNoteLg1: 'editorialNote1', - editorialNoteLg2: 'editorialNote2', - changeNoteLg1: 'changeNote1', - changeNoteLg2: 'changeNote2', + definitionLg1: 'definitionLg1', }; + + const oldLabelLg1 = 'oldLabelLg1'; + const conceptsWithLinks = [{ label: 'existingLabel' }]; - const maxLengthScopeNote = 100; - - const result = validator( - oldGeneral, - newGeneral, - notes, - conceptsWithLinks, - maxLengthScopeNote - ); - - expect(result.errorMessage).toHaveLength(0); - expect(result.fields).toEqual({}); + + const maxLengthScopeNote = 350; + + expect( + validate( + general, + notes, + oldLabelLg1, + conceptsWithLinks, + maxLengthScopeNote + ) + ).toEqual({ + errorMessage: [], + fields: { + prefLabelLg1: '', + creator: '', + disseminationStatus: '', + scopeNoteLg1: '', + scopeNoteLg2: '', + definitionLg1: '', + }, + }); }); }); diff --git a/src/packages/modules-concepts/edition-creation/home.js b/src/packages/modules-concepts/edition-creation/home.js index 19ab13134..038b70c7a 100644 --- a/src/packages/modules-concepts/edition-creation/home.js +++ b/src/packages/modules-concepts/edition-creation/home.js @@ -7,7 +7,7 @@ import NotesEdition from './notes'; import LinksEdition from './links'; import D from '../../deprecated-locales'; import { VERSIONING, NO_VERSIONING } from '../../sdk/constants'; -import validate from './controls/validation'; +import { validate } from './controls/validation'; import { areNotesImpactingVersionChanged } from '../utils/notes'; import isVersioningPossible from '../../modules-concepts/utils/is-versioning-possible'; @@ -170,9 +170,9 @@ class ConceptEditionCreation extends Component { ]; const errorMessage = validate( - this.getOriginalData().general, general, notes, + this.getOriginalData().general.prefLabelLg1, conceptsWithLinks, maxLengthScopeNote ); diff --git a/src/packages/modules-concepts/edition-creation/notes.js b/src/packages/modules-concepts/edition-creation/notes.js index 265c4513f..b95b7473f 100644 --- a/src/packages/modules-concepts/edition-creation/notes.js +++ b/src/packages/modules-concepts/edition-creation/notes.js @@ -2,22 +2,17 @@ import { useState } from 'react'; import { Tabs, Tab } from 'react-bootstrap'; import { NoteEdition } from '../../components'; import { D1 } from '../../deprecated-locales'; -import { htmlIsEmpty } from '../../utils/html-utils'; +import { htmlIsEmpty, htmlLength } from '../../utils/html-utils'; const noteTypes = (maxLengthScopeNote) => [ { rawTitle: 'conceptsScopeNote', - // should be highlighted only if `scopeNoteLg1` is empty and - //`disseminationStatus.includes('Public')` - redLg1Empty: (disseminationStatus) => - disseminationStatus.includes('Public'), noteLg1Name: 'scopeNoteLg1', noteLg2Name: 'scopeNoteLg2', maxLength: maxLengthScopeNote, }, { rawTitle: 'conceptsDefinition', - redLg1Empty: () => true, noteLg1Name: 'definitionLg1', noteLg2Name: 'definitionLg2', }, @@ -50,6 +45,7 @@ const NotesEdition = ({ maxLengthScopeNote, langs, handleChange, + errorMessage, }) => { const [activeTab, setActiveTab] = useState(0); const handlers = handleFieldChange(handleChange, maxLengthScopeNote); @@ -63,33 +59,36 @@ const NotesEdition = ({ justified > {noteTypes(maxLengthScopeNote).map( - ( - { rawTitle, noteLg1Name, noteLg2Name, redLg1Empty, maxLength }, - i - ) => { + ({ rawTitle, noteLg1Name, noteLg2Name, maxLength }, i) => { const noteLg1 = notes[noteLg1Name]; const noteLg2 = notes[noteLg2Name]; - //note fr empty and we value the `redFrEmptpy` function to know if - //given the dissemination status, it should be highlighted or not - let noteEdition; + + //we value the note to know if the title should be highlighted or not const highlight = - redLg1Empty && - htmlIsEmpty(noteLg1) && - redLg1Empty(disseminationStatus); + (noteLg1Name === 'definitionLg1' && htmlIsEmpty(noteLg1)) || + (noteLg1Name === 'scopeNoteLg1' && + htmlIsEmpty(noteLg1) && + disseminationStatus.includes('Public')) || + (noteLg1Name === 'scopeNoteLg1' && + (htmlLength(noteLg1) > 100 || htmlLength(noteLg2) > 100)); const title = highlight ? (
{D1[rawTitle]}
) : ( D1[rawTitle] ); + + let noteEdition; if (activeTab === i) { noteEdition = ( ); } diff --git a/src/packages/modules-datasets/distributions/validation.spec.js b/src/packages/modules-datasets/distributions/validation.spec.js index 09af63a27..ca98bc9d8 100644 --- a/src/packages/modules-datasets/distributions/validation.spec.js +++ b/src/packages/modules-datasets/distributions/validation.spec.js @@ -4,30 +4,30 @@ describe('validation', function () { it('should return an error for labelLg1', function () { expect( validate({ - labelLg2: 'labelLg2', idDataset: 'id', + labelLg2: 'labelLg2', }) ).toEqual({ errorMessage: ['The property Intitulé is required.'], fields: { + idDataset: '', labelLg1: 'The property Intitulé is required.', labelLg2: '', - idDataset: '', }, }); }); it('should return an error for labelLg2', function () { expect( validate({ - labelLg1: 'labelLg1', idDataset: 'id', + labelLg1: 'labelLg1', }) ).toEqual({ errorMessage: ['The property Title is required.'], fields: { + idDataset: '', labelLg1: '', labelLg2: 'The property Title is required.', - idDataset: '', }, }); }); @@ -42,25 +42,25 @@ describe('validation', function () { 'The property Jeu de Données is required.', ], fields: { + idDataset: 'The property Jeu de Données is required.', labelLg1: '', labelLg2: '', - idDataset: 'The property Jeu de Données is required.', }, }); }); it('should return no error', function () { expect( validate({ + idDataset: 'id', labelLg1: 'labelLg2', labelLg2: 'labelLg2', - idDataset: 'id', }) ).toEqual({ errorMessage: [], fields: { + idDataset: '', labelLg1: '', labelLg2: '', - idDataset: '', }, }); }); diff --git a/src/packages/modules-operations/document/edition/validation.js b/src/packages/modules-operations/document/edition/validation.js index c4af2a5f9..a2c91cd82 100644 --- a/src/packages/modules-operations/document/edition/validation.js +++ b/src/packages/modules-operations/document/edition/validation.js @@ -27,7 +27,9 @@ const Link = Base.extend({ }) .startsWith('http', { message: D.badUrl, - }), + }) + .trim() + .min(1, { message: D.mandatoryProperty(D.titleLink) }), }); const File = z.object({ diff --git a/src/packages/modules-operations/families/edition/validation.spec.js b/src/packages/modules-operations/families/edition/validation.spec.js index f799a9d5a..37ce32cb0 100644 --- a/src/packages/modules-operations/families/edition/validation.spec.js +++ b/src/packages/modules-operations/families/edition/validation.spec.js @@ -1,39 +1,35 @@ import { validate } from './validation'; -describe('validation', function() { - it('should return an error for prefLabelLg1', function() { +describe('validation', function () { + it('should return an error for prefLabelLg1', function () { expect( validate({ prefLabelLg1: '', prefLabelLg2: 'prefLabelLg2', }) ).toEqual({ - errorMessage: [ - 'The property Intitulé is required.', - ], + errorMessage: ['The property Intitulé is required.'], fields: { prefLabelLg1: 'The property Intitulé is required.', prefLabelLg2: '', }, }); }); - it('should return an error for prefLabelLg2', function() { + it('should return an error for prefLabelLg2', function () { expect( validate({ prefLabelLg1: 'prefLabelLg1', prefLabelLg2: '', }) ).toEqual({ - errorMessage: [ - 'The property Title is required.', - ], + errorMessage: ['The property Title is required.'], fields: { prefLabelLg1: '', prefLabelLg2: 'The property Title is required.', }, }); }); - it('should return an error for prefLabelLg1 and prefLabelLg2', function() { + it('should return an error for prefLabelLg1 and prefLabelLg2', function () { expect( validate({ prefLabelLg1: '', @@ -50,11 +46,11 @@ describe('validation', function() { }, }); }); - it('should return no error', function() { + it('should return no error', function () { expect( validate({ - prefLabelLg1: 'prefLabelLg2', - prefLabelLg2: 'prefLabelLg2' + prefLabelLg1: 'prefLabelLg1', + prefLabelLg2: 'prefLabelLg2', }) ).toEqual({ errorMessage: [], diff --git a/src/packages/modules-operations/indicators/edition/validation.spec.js b/src/packages/modules-operations/indicators/edition/validation.spec.js index a014d0249..18a204075 100644 --- a/src/packages/modules-operations/indicators/edition/validation.spec.js +++ b/src/packages/modules-operations/indicators/edition/validation.spec.js @@ -1,7 +1,7 @@ import { validate } from './validation'; -describe('validate', function() { - it('should return an error for prefLabelLg1', function() { +describe('validation', function () { + it('should return an error for prefLabelLg1', function () { expect( validate({ prefLabelLg1: '', @@ -9,9 +9,7 @@ describe('validate', function() { creators: ['creator'], }) ).toEqual({ - errorMessage: [ - 'The property Intitulé is required.', - ], + errorMessage: ['The property Intitulé is required.'], fields: { prefLabelLg1: 'The property Intitulé is required.', prefLabelLg2: '', @@ -19,7 +17,7 @@ describe('validate', function() { }, }); }); - it('should return an error for prefLabelLg2', function() { + it('should return an error for prefLabelLg2', function () { expect( validate({ prefLabelLg1: 'prefLabelLg1', @@ -27,9 +25,7 @@ describe('validate', function() { creators: ['creator'], }) ).toEqual({ - errorMessage: [ - 'The property Title is required.', - ], + errorMessage: ['The property Title is required.'], fields: { prefLabelLg1: '', prefLabelLg2: 'The property Title is required.', @@ -37,16 +33,14 @@ describe('validate', function() { }, }); }); - it('should return an error for creators', function() { + it('should return an error for creators', function () { expect( validate({ prefLabelLg1: 'prefLabelLg1', prefLabelLg2: 'prefLabelLg2', }) ).toEqual({ - errorMessage: [ - 'The property Owner is required.', - ], + errorMessage: ['The property Owner is required.'], fields: { prefLabelLg1: '', prefLabelLg2: '', @@ -54,7 +48,7 @@ describe('validate', function() { }, }); }); - it('should return an error if creators is an empty array', function() { + it('should return an error if creators is an empty array', function () { expect( validate({ prefLabelLg1: 'prefLabelLg1', @@ -62,9 +56,7 @@ describe('validate', function() { creators: [], }) ).toEqual({ - errorMessage: [ - 'The property Owner is required.', - ], + errorMessage: ['The property Owner is required.'], fields: { prefLabelLg1: '', prefLabelLg2: '', @@ -72,7 +64,7 @@ describe('validate', function() { }, }); }); - it('should return no error', function() { + it('should return no error', function () { expect( validate({ prefLabelLg1: 'prefLabelLg1', @@ -82,9 +74,9 @@ describe('validate', function() { ).toEqual({ errorMessage: [], fields: { - creators: '', prefLabelLg1: '', prefLabelLg2: '', + creators: '', }, }); }); diff --git a/src/packages/modules-operations/operations/edition/validation.spec.js b/src/packages/modules-operations/operations/edition/validation.spec.js index 3e8a80624..4c7900de4 100644 --- a/src/packages/modules-operations/operations/edition/validation.spec.js +++ b/src/packages/modules-operations/operations/edition/validation.spec.js @@ -1,35 +1,35 @@ import { validate } from './validation'; -describe('validate', function () { +describe('validation', function () { it('should return an error for prefLabelLg1', function () { expect( validate({ + series: { id: 'i' }, prefLabelLg1: '', prefLabelLg2: 'prefLabelLg2', - series: { id: 'i' }, }) ).toEqual({ errorMessage: ['The property Intitulé is required.'], fields: { + series: '', prefLabelLg1: 'The property Intitulé is required.', prefLabelLg2: '', - series: '', }, }); }); it('should return an error for prefLabelLg2', function () { expect( validate({ + series: { id: 'i' }, prefLabelLg1: 'prefLabelLg1', prefLabelLg2: '', - series: { id: 'i' }, }) ).toEqual({ errorMessage: ['The property Title is required.'], fields: { + series: '', prefLabelLg1: '', prefLabelLg2: 'The property Title is required.', - series: '', }, }); }); @@ -51,16 +51,16 @@ describe('validate', function () { it('should return no error', function () { expect( validate({ + series: { id: 'i' }, prefLabelLg1: 'prefLabelLg1', prefLabelLg2: 'prefLabelLg2', - series: { id: 'i' }, }) ).toEqual({ errorMessage: [], fields: { + series: '', prefLabelLg1: '', prefLabelLg2: '', - series: '', }, }); }); diff --git a/src/packages/modules-operations/series/edition/validation.spec.js b/src/packages/modules-operations/series/edition/validation.spec.js index 4936419a7..49736d4f6 100644 --- a/src/packages/modules-operations/series/edition/validation.spec.js +++ b/src/packages/modules-operations/series/edition/validation.spec.js @@ -73,9 +73,9 @@ describe('validation', function () { it('should return no error', function () { expect( validate({ - prefLabelLg1: 'prefLabelLg2', - prefLabelLg2: 'prefLabelLg2', family: { id: 'i' }, + prefLabelLg1: 'prefLabelLg1', + prefLabelLg2: 'prefLabelLg2', creators: ['creator'], accrualPeriodicityCode: 'accrualPeriodicityCode', typeCode: 'typeCode', diff --git a/src/packages/modules-structures/components/edition/validation.spec.js b/src/packages/modules-structures/components/edition/validation.spec.js index bf2fd2b97..82a7afc9b 100644 --- a/src/packages/modules-structures/components/edition/validation.spec.js +++ b/src/packages/modules-structures/components/edition/validation.spec.js @@ -1,7 +1,7 @@ -import { validate } from "./validation"; +import { validate } from './validation'; -describe('validation', function() { - it('should return an error for identifiant', function() { +describe('validation', function () { + it('should return an error for identifiant', function () { expect( validate({ labelLg1: 'labelLg1', @@ -9,9 +9,7 @@ describe('validation', function() { type: 'type', }) ).toEqual({ - errorMessage: [ - 'The property Notation is required.', - ], + errorMessage: ['The property Notation is required.'], fields: { identifiant: 'The property Notation is required.', labelLg1: '', @@ -20,7 +18,7 @@ describe('validation', function() { }, }); }); - it('should return an error for labelLg1 and labelLg2', function() { + it('should return an error for labelLg1 and labelLg2', function () { expect( validate({ identifiant: 'id', @@ -39,7 +37,7 @@ describe('validation', function() { }, }); }); - it('should return an error for type', function() { + it('should return an error for type', function () { expect( validate({ identifiant: 'id', @@ -47,9 +45,7 @@ describe('validation', function() { labelLg2: 'labelLg2', }) ).toEqual({ - errorMessage: [ - 'The property Type is required.', - ], + errorMessage: ['The property Type is required.'], fields: { identifiant: '', labelLg1: '', @@ -58,7 +54,7 @@ describe('validation', function() { }, }); }); - it('should return no error', function() { + it('should return no error', function () { expect( validate({ identifiant: 'id', @@ -76,4 +72,4 @@ describe('validation', function() { }, }); }); -}); \ No newline at end of file +}); diff --git a/src/packages/modules-structures/edition/validation.spec.js b/src/packages/modules-structures/edition/validation.spec.js index b4af5a5d6..8f47b81d0 100644 --- a/src/packages/modules-structures/edition/validation.spec.js +++ b/src/packages/modules-structures/edition/validation.spec.js @@ -1,7 +1,7 @@ import { validate } from './validation'; -describe('validation', function() { - it('should return an error for id', function() { +describe('validation', function () { + it('should return an error for id', function () { expect( validate({ identifiant: '', @@ -9,9 +9,7 @@ describe('validation', function() { labelLg2: 'labelLg2', }) ).toEqual({ - errorMessage: [ - 'The property Notation is required.', - ], + errorMessage: ['The property Notation is required.'], fields: { identifiant: 'The property Notation is required.', labelLg1: '', @@ -19,7 +17,7 @@ describe('validation', function() { }, }); }); - it('should return an error for labelLg1', function() { + it('should return an error for labelLg1', function () { expect( validate({ identifiant: 'id', @@ -27,9 +25,7 @@ describe('validation', function() { labelLg2: 'labelLg2', }) ).toEqual({ - errorMessage: [ - 'The property Libellé is required.', - ], + errorMessage: ['The property Libellé is required.'], fields: { identifiant: '', labelLg1: 'The property Libellé is required.', @@ -37,7 +33,7 @@ describe('validation', function() { }, }); }); - it('should return an error for labelLg2', function() { + it('should return an error for labelLg2', function () { expect( validate({ identifiant: 'id', @@ -45,9 +41,7 @@ describe('validation', function() { labelLg2: '', }) ).toEqual({ - errorMessage: [ - 'The property Label is required.', - ], + errorMessage: ['The property Label is required.'], fields: { identifiant: '', labelLg1: '', @@ -55,7 +49,7 @@ describe('validation', function() { }, }); }); - it('should not return any error', function() { + it('should return no error', function () { expect( validate({ identifiant: 'id', @@ -68,7 +62,7 @@ describe('validation', function() { identifiant: '', labelLg1: '', labelLg2: '', - } + }, }); }); }); diff --git a/swagger.yaml b/swagger.yaml deleted file mode 100644 index dbc04f6ce..000000000 --- a/swagger.yaml +++ /dev/null @@ -1,914 +0,0 @@ -swagger: '2.0' -info: - description: This is an API spcification for Concepts API - version: 1.0.0 - title: Swagger Concepts API - contact: - email: nicolas.laval@insee.fr -host: 'localhost:6969' -basePath: /gncs-core-refactor/ws -tags: - - name: management - - name: concepts - description: Everything about Concepts - - name: collections - description: Everything about Collections -schemes: - - http -paths: - /stamps: - get: - tags: - - management - summary: List of stamps - description: '' - operationId: getStamps - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: string - /disseminationStatus: - get: - tags: - - management - summary: List of dissemination status - description: '' - operationId: getDisseminationStatus - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - label: - type: string - id: - type: string - /roles: - get: - tags: - - management - summary: List of roles - description: '' - operationId: getRoles - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - persons: - type: array - items: - type: object - properties: - stamp: - type: string - id: - type: string - label: - type: string - id: - type: string - label: - type: string - /agents: - get: - tags: - - management - summary: List of agents - description: '' - operationId: getAgents - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - label: - type: string - url: - type: string - /private/role/add: - post: - tags: - - management - summary: Add agents to user roles - description: '' - operationId: setAddRole - consumes: - - application/json - parameters: - - name: Agents to add - in: body - description: Add agents to user roles - required: true - schema: - type: array - items: - type: object - properties: - id: - type: string - roles: - type: array - items: - type: string - responses: - '204': - description: 'Agents added' - schema: - type: string - /private/role/delete: - post: - tags: - - management - summary: Delete agent from role - description: '' - operationId: setDeleteRole - consumes: - - application/json - parameters: - - name: Agent to delete - in: body - description: Delete agent from role - required: true - schema: - type: object - properties: - id: - type: string - role: - type: string - responses: - '204': - description: 'Agent deleted from role' - schema: - type: string - /concepts/concepts: - get: - tags: - - concepts - summary: List of concepts - description: '' - operationId: getConcepts - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - id: - type: string - label: - type: string - /concepts/concepts/search: - get: - tags: - - concepts - summary: List of concepts for advanced search - description: '' - operationId: getConceptsSearch - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - id: - type: string - label: - type: string - created: - type: string - format: dateTime - modified: - type: string - format: dateTime - disseminationStatus: - type: string - validationStatus: - type: string - definition: - type: string - creator: - type: string - /concepts/concepts/toValidate: - get: - tags: - - concepts - summary: List of concepts to validate - description: '' - operationId: getConceptsToValidate - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - id: - type: string - label: - type: string - '/concepts/concept/{id}': - get: - tags: - - concepts - summary: Generals attributs of concept - description: '' - operationId: getConceptByID - produces: - - application/json - parameters: - - name: id - in: path - description: ID of concept to fetch - required: true - type: string - responses: - '200': - description: successful operation - schema: - type: object - properties: - id: - type: string - prefLabelLg1: - type: string - prefLabelLg2: - type: string - altLabelLg1: - type: string - altLabelLg2: - type: string - creator: - type: string - contributor: - type: string - disseminationStatus: - type: string - additionnalMaterial: - type: string - created: - type: string - format: dateTime - modified: - type: string - format: dateTime - valid: - type: string - format: dateTime - conceptVersion: - type: string - isValidated: - type: string - enum: - - Validé - - Provisoire - '/concepts/concept/{id}/links': - get: - tags: - - concepts - summary: Linked concepts of concept - description: '' - operationId: getConceptLinksByID - produces: - - application/json - parameters: - - name: id - in: path - description: ID of concept to fetch - required: true - type: string - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - id: - type: string - typeOfLink: - type: string - enum: - - broader - - narrower - - references - - succeed - - related - prefLabelLg1: - type: string - prefLabelLg2: - type: string - '/concepts/concept/{id}/notes/{conceptVersion}': - get: - tags: - - concepts - summary: Concept notes by version - description: '' - operationId: getConceptNotesByID - produces: - - application/json - parameters: - - name: id - in: path - description: ID of concept to fetch - required: true - type: string - - name: conceptVersion - in: path - description: Concept version of concept to fetch - required: true - type: string - responses: - '200': - description: successful operation - schema: - type: object - properties: - definitionLg1: - type: string - definitionLg2: - type: string - scopeNoteLg1: - type: string - scopeNoteLg2: - type: string - editorialNoteLg1: - type: string - editorialNoteLg2: - type: string - changeNoteLg1: - type: string - changeNoteLg2: - type: string - /concepts/private/concept: - post: - tags: - - concepts - summary: Create new concept - description: Create new concept - operationId: setConcept - consumes: - - application/json - produces: - - text/plain - parameters: - - name: concept - in: body - description: Concept attributes - required: true - schema: - type: object - properties: - prefLabelLg1: - type: string - prefLabelLg2: - type: string - altLabelLg1: - type: string - altLabelLg2: - type: string - creator: - type: string - contributor: - type: string - disseminationStatus: - type: string - additionalMaterial: - type: string - valid: - type: string - format: dateTime - versionableNotes: - type: array - items: - type: object - properties: - noteType: - type: string - enum: - - scopeNoteLg1 - - scopeNoteLg2 - - definitionLg1 - - definitionLg2 - - editorialNoteLg1 - - editorialNoteLg2 - content: - type: string - datableNotes: - type: array - items: - type: object - properties: - noteType: - type: string - enum: - - changeNoteLg1 - - changeNoteLg2 - content: - type: string - links: - type: array - items: - type: object - properties: - typeOfLink: - type: string - enum: - - broader - - narrower - - references - - succeed - - related - ids: - type: array - items: - type: string - responses: - '204': - description: 'Concept created, returns concept ID' - schema: - type: string - '/concepts/private/concept/{id}': - put: - tags: - - concepts - summary: Modify concept - description: Modify new concept - operationId: modifyConcept - consumes: - - application/json - parameters: - - name: id - in: path - description: ID of concept to fetch - required: true - type: string - - name: concept - in: body - description: Concept attributes - required: true - schema: - type: object - properties: - prefLabelLg1: - type: string - prefLabelLg2: - type: string - altLabelLg1: - type: string - altLabelLg2: - type: string - creator: - type: string - contributor: - type: string - disseminationStatus: - type: string - additionalMaterial: - type: string - created: - type: string - format: dateTime - valid: - type: string - format: dateTime - versioning: - type: boolean - versionableNotes: - type: array - items: - type: object - properties: - noteType: - type: string - enum: - - scopeNoteLg1 - - scopeNoteLg2 - - definitionLg1 - - definitionLg2 - - editorialNoteLg1 - - editorialNoteLg2 - content: - type: string - datableNotes: - type: array - items: - type: object - properties: - noteType: - type: string - enum: - - changeNoteLg1 - - changeNoteLg2 - content: - type: string - links: - type: array - items: - type: object - properties: - typeOfLink: - type: string - enum: - - broader - - narrower - - references - - succeed - - related - ids: - type: array - items: - type: string - responses: - '204': - description: Concept modified - /concepts/private/concepts/validate: - put: - tags: - - concepts - description: Validate concepts - operationId: setConceptsValidation - consumes: - - application/json - parameters: - - name: concepts - in: body - description: Concepts ID to validate - required: true - schema: - type: array - items: - type: string - responses: - '204': - description: Concepts validated - '/concepts/concept/export/{id}': - get: - tags: - - concepts - description: Export concept - operationId: setConceptExport - produces: - - application/octet-stream - parameters: - - name: id - in: path - description: Concept ID to export - required: true - type: string - responses: - '204': - description: Concept exported - schema: - type: file - '/concepts/private/concept/send/{id}': - post: - tags: - - concepts - description: Send concept - operationId: setConceptSend - consumes: - - application/json - produces: - - text/plain - parameters: - - name: id - in: path - description: Concept ID to send - required: true - type: string - - name: concepts - in: body - description: Mail informations - required: true - schema: - type: object - properties: - sender: - type: string - recipient: - type: string - object: - type: string - message: - type: string - responses: - '204': - description: Concept sent - schema: - type: boolean - /collections: - get: - tags: - - collections - summary: List of collections - description: '' - operationId: getCollections - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - id: - type: string - label: - type: string - /concepts/collections/toValidate: - get: - tags: - - collections - summary: List of collections to validate - description: '' - operationId: getCollectionsToValidate - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: array - items: - type: object - properties: - id: - type: string - label: - type: string - '/concepts/collection/{id}': - get: - tags: - - collections - summary: Generals attributs of collection - description: '' - operationId: getCollectionByID - produces: - - application/json - parameters: - - name: id - in: path - description: ID of collection to fetch - required: true - type: string - responses: - '200': - description: successful operation - schema: - type: object - properties: - id: - type: string - prefLabelLg1: - type: string - prefLabelLg2: - type: string - created: - type: string - format: dateTime - modified: - type: string - format: dateTime - descriptionLg1: - type: string - descriptionLg2: - type: string - isValidated: - type: string - enum: - - Validée - - Provisoire - creator: - type: string - contributor: - type: string - '/concepts/collection/{id}/members': - get: - tags: - - collections - summary: Concepts members of collection - description: '' - operationId: getCollectionMembersByID - produces: - - application/json - parameters: - - name: id - in: path - description: ID of collection to fetch - required: true - type: string - responses: - '200': - description: successful operation - schema: - type: array - items: - properties: - id: - type: string - prefLabelLg1: - type: string - prefLabelLg2: - type: string - /concepts/private/collection: - post: - tags: - - collections - summary: Create new collection - description: Create new collection - operationId: setCollection - consumes: - - application/json - parameters: - - name: collection - in: body - description: Collection attributes - required: true - schema: - type: object - properties: - id: - type: string - prefLabelLg1: - type: string - prefLabelLg2: - type: string - descriptionLg1: - type: string - descriptionLg2: - type: string - creator: - type: string - contributor: - type: string - members: - type: array - items: - type: string - responses: - '204': - description: Collection created - '/concepts/private/collection/{id}': - put: - tags: - - collections - summary: Modify collection - description: Modify collection - operationId: modifyCollection - consumes: - - application/json - parameters: - - name: id - in: path - description: ID of collection to fetch - required: true - type: string - - name: collection - in: body - description: Collection attributes - required: true - schema: - type: object - properties: - prefLabelLg1: - type: string - prefLabelLg2: - type: string - descriptionLg1: - type: string - descriptionLg2: - type: string - creator: - type: string - contributor: - type: string - created: - type: string - format: dateTime - members: - type: array - items: - type: string - responses: - '204': - description: Collection modified - /concepts/private/collections/validate: - put: - tags: - - collections - description: Validate collections - operationId: setCollectionsValidation - consumes: - - application/json - parameters: - - name: collections - in: body - description: Collections ID to validate - required: true - schema: - type: array - items: - type: string - responses: - '204': - description: Collections validated - '/concepts/collection/export/{id}': - get: - tags: - - collections - description: Export collection - operationId: setCollectionExport - produces: - - application/octet-stream - parameters: - - name: id - in: path - description: Collection ID to export - required: true - type: string - responses: - '204': - description: Collection exported - schema: - type: file - '/concepts/private/collection/send/{id}': - post: - tags: - - collections - description: Send collection - operationId: setCollectionSend - consumes: - - application/json - produces: - - text/plain - parameters: - - name: id - in: path - description: Collection ID to send - required: true - type: string - - name: Mail - in: body - description: Mail informations - required: true - schema: - type: object - properties: - sender: - type: string - recipient: - type: string - object: - type: string - message: - type: string - responses: - '204': - description: Collection sent - schema: - type: boolean