lodash#transform JavaScript Examples

The following examples show how to use lodash#transform. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Mappers.js    From sampo-ui with MIT License 6 votes vote down vote up
makeObjectList = (objects) => {
  // const time = process.hrtime()
  const objList = transform(objects, function (result, obj) {
    if (!obj.id) {
      return null
    }
    // let orig = obj;
    obj = makeObject(obj)
    // obj = reviseObject(obj, orig);
    mergeValueToList(result, obj)
  })
  // const diff = process.hrtime(time)
  // console.log(`makeObjectList took ${(diff[0] * NS_PER_SEC + diff[1]) * MS_PER_NS} milliseconds`)
  return objList
  // return self.postProcess(objList);
}
Example #2
Source File: index.js    From datapass with GNU Affero General Public License v3.0 6 votes vote down vote up
getChangelogV1 = (diff) =>
  chain(diff)
    // { intitule: ['a', 'b'], contacts: [[{'name': 'c', email: 'd'}], [{'name': 'e', email: 'd'}]] }
    .omit(['updated_at'])
    .transform(flattenDiffTransformer, {})
    // { intitule: ['a', 'b'], contacts.0.name: ['c', 'e'] }
    .transform(changelogFormatTransformer, [])
    // ['changement d’intitule de "a" en "b"', 'changement du nom du DPD de "c" en "d"']
    .value()
Example #3
Source File: index.js    From datapass with GNU Affero General Public License v3.0 6 votes vote down vote up
flattenDiffTransformerV2Factory =
  (keyPrefix = null) =>
  (accumulatorObject, objectValue, objectKey) => {
    const key = [keyPrefix, objectKey].filter((e) => e).join('.');

    if (isArray(objectValue)) {
      accumulatorObject[key] = objectValue;
    }

    // { scope: { nom: [false, true] } }
    if (isObject(objectValue)) {
      transform(
        objectValue,
        flattenDiffTransformerV2Factory(key),
        accumulatorObject
      );
    }

    return accumulatorObject;
  }
Example #4
Source File: difference.js    From iceberg-editor with GNU General Public License v2.0 6 votes vote down vote up
difference = ( object, base ) => {
	/* eslint-disable no-shadow */
	function changes( object, base ) {
		return transform( object, function( result, value, key ) {
			if ( ! isEqual( value, base[ key ] ) ) {
				result[ key ] =
					isObject( value ) && isObject( base[ key ] )
						? changes( value, base[ key ] )
						: value;
			}
		} );
	}
	return changes( object, base );
}
Example #5
Source File: index.js    From datapass with GNU Affero General Public License v3.0 5 votes vote down vote up
getChangelogV2 = (diff) =>
  chain(diff)
    // { intitule: ['a', 'b'], team_members: { "_t": "a", "0": { 'name': ['c','e'], email: ['d'] } } }
    .transform(flattenDiffTransformerV2Factory(), {})
    // { intitule: ['a', 'b'], team_members.0.name: ['c', 'e'] , team_members.0.email: ['d'] }
    .transform(changelogFormatTransformer, [])
    // ['changement d’intitule de "a" en "b"', ...]
    .value()
Example #6
Source File: index.test.js    From datapass with GNU Affero General Public License v3.0 4 votes vote down vote up
describe('utils', () => {
  describe('getErrorMessages', () => {
    it('should return proper error message for error from nginx', () => {
      const errorObject = {
        response: {
          data: '<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body bgcolor="white">\r\n<center><h1>502 Bad Gateway</h1></center>\r\n<hr><center>nginx/1.10.3 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n',
          status: 502,
          statusText: 'Bad Gateway',
        },
      };

      expect(getErrorMessages(errorObject)).toEqual([
        'Une erreur est survenue. Le code de l’erreur est 502 (Bad Gateway). Merci de réessayer ultérieurement. Vous pouvez également nous signaler cette erreur par mail à [email protected].',
      ]);
    });

    it('should return proper error message for 422 error from backend', () => {
      const errorObject = {
        response: {
          data: {
            description: [
              'Vous devez renseigner la description de la démarche avant de continuer',
            ],
            contacts: [
              'Vous devez renseigner un prénom pour le contact technique avant de continuer',
              'Vous devez renseigner un nom pour le contact technique avant de continuer',
            ],
          },
          status: 422,
          statusText: 'Unprocessable Entity',
        },
      };

      expect(getErrorMessages(errorObject)).toEqual([
        'Vous devez renseigner la description de la démarche avant de continuer',
        'Vous devez renseigner un prénom pour le contact technique avant de continuer',
        'Vous devez renseigner un nom pour le contact technique avant de continuer',
      ]);
    });

    it('should return proper message for network error', () => {
      const errorObject = {
        message: 'Network Error',
      };

      expect(getErrorMessages(errorObject)).toEqual([
        'Une erreur de connexion au serveur est survenue. Merci de vérifier que vous êtes bien connecté à internet. Si vous utilisez un réseau d’entreprise, merci de signaler cette erreur à l’administrateur de votre réseau informatique. Si le problème persiste, vous pouvez nous contacter par mail à [email protected].',
      ]);
    });

    it('should return proper error message for copying error from backend', () => {
      const errorObject = {
        response: {
          data: {
            message:
              'La validation a échoué : Copied from enrollment n’est pas disponible',
          },
          status: 422,
          statusText: 'Unprocessable Entity',
        },
      };

      expect(getErrorMessages(errorObject)).toEqual([
        'La validation a échoué : Copied from enrollment n’est pas disponible',
      ]);
    });

    it('should return proper error message for 403 error from backend', () => {
      const errorObject = {
        response: {
          data: {
            message: 'Vous n’êtes pas autorisé à modifier cette ressource',
          },
          status: 403,
          statusText: 'Forbidden',
        },
      };

      expect(getErrorMessages(errorObject)).toEqual([
        'Vous n’êtes pas autorisé à modifier cette ressource',
      ]);
    });

    it('should return proper error message for 401 error from backend', () => {
      const errorObject = {
        response: {
          data: {
            message:
              'Vous devez vous connecter ou vous inscrire pour continuer.',
          },
          status: 401,
          statusText: 'Unauthorized',
        },
      };

      expect(getErrorMessages(errorObject)).toEqual([
        'Vous devez vous connecter ou vous inscrire pour continuer.',
      ]);
    });
  });

  describe('isValidNAFCode', () => {
    it('should return true for COMMUNE D HEM', () => {
      expect(isValidNAFCode('api_particulier', '84.11Z')).toBe(true);
    });
    it('should return true for ASSISTANCE PUBLIQUE HOPITAUX DE PARIS', () => {
      expect(isValidNAFCode('api_particulier', '86.10Z')).toBe(true);
    });
    it('should return false for RED NEEDLES', () => {
      expect(isValidNAFCode('api_particulier', '62.02A')).toBe(false);
    });
    it('should return true if provider does not filter on NAF code', () => {
      expect(isValidNAFCode('dgfip', '62.02A')).toBe(true);
    });
    it('should return true for Commune de bresse vallons', () => {
      expect(isValidNAFCode('hubee_portail', '84.11Z')).toBe(true);
    });
    it('should return false for Cpam de loire atlantique (cpam)', () => {
      expect(isValidNAFCode('hubee_portail', '84.30A')).toBe(false);
    });
  });

  describe('getChangelog', () => {
    const diff = {
      data_retention_period: [12, 11],
      fondement_juridique_url: [
        null,
        'https://www.legifrance.gouv.fr/loda/id/JORFTEXT000037611479/',
      ],
      fondement_juridique_title: [
        'Convention d\'accès à "Mon compte partenaire" - Ville de Hem / CAF du Nord - Contrat de service pris en application de la convention d\'accès à "Mon Compte Partenaire" (mode gestion déléguée) signés le 11 mai 2017.',
        'Convention d\'accès à "Mon compte partenaire" - Ville de Hem / CAF du Nord - Contrat de service pris en application de la convention d\'accès à "Mon Compte Partenaire" (mode gestion déléguée) signés le 11 mai 2017',
      ],
      updated_at: ['2019-05-13T16:35:19.742Z', '2019-05-14T09:30:54.304Z'],
      contacts: [
        [
          {
            email: '[email protected]',
            heading: 'Délégué à la protection des données',
            id: 'dpo',
            nom: 'Raphaël Dubigny2',
            phone_number: '0123456789',
          },
          {
            email: '[email protected]',
            heading: 'Responsable de traitement',
            id: 'responsable_traitement',
            nom: 'Raphaël Dubigny',
            phone_number: '0123456789',
          },
          {
            email: '[email protected]',
            heading: 'Responsable technique',
            id: 'responsable_technique',
            nom: 'Raphaël Dubigny',
            phone_number: '0123456789',
          },
        ],
        [
          {
            email: '[email protected]',
            heading: 'Délégué à la protection des données',
            id: 'dpo',
            nom: 'Raphaël Dubigny',
            phone_number: '0123456789',
          },
          {
            email: '[email protected]',
            heading: 'Responsable de traitement',
            id: 'responsable_traitement',
            nom: 'Raphaël Dubigny',
            phone_number: '0123456789',
          },
          {
            email: '[email protected]',
            heading: 'Responsable technique',
            id: 'responsable_technique',
            nom: 'Raphaël Dubigny',
            phone_number: '0123456789',
          },
        ],
      ],
      scopes: [
        {
          birthcountry: true,
          birthdate: false,
          birthplace: true,
          email: true,
          family_name: true,
          gender: false,
          given_name: true,
          openid: true,
          deprecated_scope: null,
        },
        {
          birthcountry: false,
          birthdate: true,
          birthplace: true,
          email: true,
          family_name: true,
          gender: false,
          given_name: true,
          openid: true,
          preferred_username: true,
        },
      ],
      additional_content: [
        {
          has_alternative_authentication_methods: true,
        },
        {
          eidas_level: '1',
          has_alternative_authentication_methods: true,
        },
      ],
    };

    const changelog = [
      'Changement de la durée de conservation des données de "12" en "11"',
      'Changement de l’url du cadre juridique de "null" en "https://www.legifrance.gouv.fr/loda/id/JORFTEXT000037611479/"',
      'Changement de la référence du cadre juridique de \n\nConvention d\'accès à "Mon compte ' +
        'partenaire" - Ville de Hem / CAF du Nord - Contrat de service pris en application de la ' +
        'convention d\'accès à "Mon Compte Partenaire" (mode gestion déléguée) signés le 11 mai ' +
        '2017.\n\n en \n\nConvention d\'accès à "Mon compte partenaire" - Ville de Hem / CAF du Nord - ' +
        'Contrat de service pris en application de la convention d\'accès à "Mon Compte ' +
        'Partenaire" (mode gestion déléguée) signés le 11 mai 2017\n\n',
      'Changement du nom du contact 1 de "Raphaël Dubigny2" en "Raphaël Dubigny"',
      'Changement du périmètre de données "birthcountry" de "coché" en "décoché"',
      'Changement du périmètre de données "birthdate" de "décoché" en "coché"',
      'Changement du périmètre de données "preferred_username" de "décoché" en "coché"',
      'Changement du champ "additional_content.eidas_level" de "non renseigné" en "1"',
    ];

    it('should return changelog for simple string field', () => {
      expect(getChangelog(diff)[0]).toEqual(changelog[0]);
    });
    it('should return changelog for simple string field with initial null value', () => {
      expect(getChangelog(diff)[1]).toEqual(changelog[1]);
    });
    it('should return changelog for several simple field', () => {
      expect(getChangelog(diff)[2]).toEqual(changelog[2]);
    });
    it('should return changelog for contact field', () => {
      expect(getChangelog(diff)[3]).toEqual(changelog[3]);
    });
    it('should return changelog for scopes', () => {
      expect(getChangelog(diff)).toEqual(changelog);
    });

    it('should return empty changelog for modified', () => {
      const diff = {
        updated_at: ['2021-12-28T15:51:35.552Z', '2021-12-28T15:51:35.565Z'],
      };
      const changelog = [];
      expect(getChangelog(diff)).toEqual(changelog);
    });
  });

  describe('flattenDiffTransformerV2Factory', () => {
    it('should return flattened diff', () => {
      const diff = { intitule: ['a', 'b'] };
      expect(transform(diff, flattenDiffTransformerV2Factory(), {})).toEqual({
        intitule: ['a', 'b'],
      });
    });
    it('should return flattened diff', () => {
      const diff = { _v: '2' };
      expect(transform(diff, flattenDiffTransformerV2Factory(), {})).toEqual(
        {}
      );
    });
    it('should return flattened diff', () => {
      const diff = { scope: { nom: [false, true], prenom: { a: ['a', 'b'] } } };
      expect(transform(diff, flattenDiffTransformerV2Factory(), {})).toEqual({
        'scope.nom': [false, true],
        'scope.prenom.a': ['a', 'b'],
      });
    });
    it('should return flattened diff', () => {
      const diff = {
        team_members: { _t: 'a', 3: { prenom: { a: ['a', 'b'] } } },
      };
      expect(transform(diff, flattenDiffTransformerV2Factory(), {})).toEqual({
        'team_members.3.prenom.a': ['a', 'b'],
      });
    });
  });

  describe('getChangelog v2', () => {
    it('should return changelog for simple string field', () => {
      const diff = {
        _v: '2',
        data_retention_period: [12, 11],
      };
      expect(getChangelog(diff)).toEqual([
        'Changement de la durée de conservation des données de "12" en "11"',
      ]);
    });

    it('should return changelog for simple string field with initial null value', () => {
      const diff = {
        _v: '2',
        fondement_juridique_url: [
          'https://www.legifrance.gouv.fr/loda/id/JORFTEXT000037611479/',
        ],
      };
      expect(getChangelog(diff)).toEqual([
        'Changement de l’url du cadre juridique de "non renseigné" en "https://www.legifrance.gouv.fr/loda/id/JORFTEXT000037611479/"',
      ]);
    });
    it('should return changelog for several simple field', () => {
      const diff = {
        _v: '2',
        fondement_juridique_title: [
          'Convention d\'accès à "Mon compte partenaire" - Ville de Hem / CAF du Nord - Contrat de service pris en application de la convention d\'accès à "Mon Compte Partenaire" (mode gestion déléguée) signés le 11 mai 2017.',
          'Convention d\'accès à "Mon compte partenaire" - Ville de Hem / CAF du Nord - Contrat de service pris en application de la convention d\'accès à "Mon Compte Partenaire" (mode gestion déléguée) signés le 11 mai 2017',
        ],
      };
      expect(getChangelog(diff)).toEqual([
        'Changement de la référence du cadre juridique de \n\nConvention d\'accès à "Mon compte ' +
          'partenaire" - Ville de Hem / CAF du Nord - Contrat de service pris en application de la ' +
          'convention d\'accès à "Mon Compte Partenaire" (mode gestion déléguée) signés le 11 mai ' +
          '2017.\n\n en \n\nConvention d\'accès à "Mon compte partenaire" - Ville de Hem / CAF du Nord - ' +
          'Contrat de service pris en application de la convention d\'accès à "Mon Compte ' +
          'Partenaire" (mode gestion déléguée) signés le 11 mai 2017\n\n',
      ]);
    });
    it('should return changelog for contact field', () => {
      const diff = {
        _v: '2',
        team_members: {
          0: {
            family_name: ['Dubigny', 'Dubigny2'],
          },
        },
      };
      expect(getChangelog(diff)).toEqual([
        'Changement du nom du demandeur de "Dubigny" en "Dubigny2"',
      ]);
    });
    it('should return changelog for adding team_member or document', () => {
      const diff = {
        _v: '2',
        team_members: {
          1: {
            job: ['Chef'],
            email: ['[email protected]'],
            user_id: [417269330],
            given_name: ['Administrator'],
            family_name: ['Test'],
            phone_number: ['0000000000'],
          },
          _t: 'a',
        },
        documents: {
          0: {
            id: [195],
            type: ['Document::LegalBasis'],
            attachment: [
              'A06_-_Mode_d_emploi_-_avance_imme_diate_de_cre_dit_d_impo_t.pdf',
            ],
            attachable_id: [1058510802],
            attachable_type: ['Enrollment'],
          },
        },
      };
      expect(getChangelog(diff)).toEqual([
        'Changement du poste du deuxième contact de "non renseigné" en "Chef"',
        'Changement de l’email du deuxième contact de "non renseigné" en "[email protected]"',
        'Changement du champ "team_members.1.user_id" de "non renseigné" en "417269330"',
        'Changement du prénom du deuxième contact de "non renseigné" en "Administrator"',
        'Changement du nom du deuxième contact de "non renseigné" en "Test"',
        'Changement du numéro de téléphone du deuxième contact de "non renseigné" en "0000000000"',
        'Changement du champ "documents.0.id" de "non renseigné" en "195"',
        'Changement du champ "documents.0.type" de "non renseigné" en "Document::LegalBasis"',
        'Changement du champ "documents.0.attachment" de "non renseigné" en "A06_-_Mode_d_emploi_-_avance_imme_diate_de_cre_dit_d_impo_t.pdf"',
        'Changement du champ "documents.0.attachable_id" de "non renseigné" en "1058510802"',
        'Changement du champ "documents.0.attachable_type" de "non renseigné" en "Enrollment"',
      ]);
    });
    it('should return changelog for scopes', () => {
      const diff = {
        _v: '2',
        scopes: {
          birthcountry: [true, false],
          birthdate: [false, true],
        },
        additional_content: {
          eidas_level: ['1'],
        },
      };
      expect(getChangelog(diff)).toEqual([
        'Changement du périmètre de données "birthcountry" de "coché" en "décoché"',
        'Changement du périmètre de données "birthdate" de "décoché" en "coché"',
        'Changement du champ "additional_content.eidas_level" de "non renseigné" en "1"',
      ]);
    });
  });

  describe('hashToQueryParams', () => {
    it('should return a query params string', () => {
      expect(hashToQueryParams({ a: 1, b: true, c: false, d: [] })).toBe(
        '?a=1&b=true'
      );
    });

    it('should return a query params string with one argument', () => {
      expect(hashToQueryParams({ a: 1 })).toBe('?a=1');
    });

    it('should return an empty query params string', () => {
      expect(hashToQueryParams({})).toBe('');
    });

    it('should return an empty query params string', () => {
      expect(hashToQueryParams(null)).toBe('');
    });

    it('should return an serialized json object', () => {
      expect(hashToQueryParams({ o: [{ id: 'a', value: 'b' }] })).toBe(
        '?o=%5B%7B%22id%22%3A%22a%22%2C%22value%22%3A%22b%22%7D%5D'
      );
    });

    it('should return an serialized json object', () => {
      const state = { demarche: 'ccas' };

      expect(hashToQueryParams(state)).toBe('?demarche=ccas');
    });

    it('should override value when new value is null', () => {
      expect(hashToQueryParams({ a: 0, b: 2 }, 'a=1')).toBe('?b=2');
    });
  });

  describe('collectionWithKeyToObject', () => {
    it('should return empty object for empty array', () => {
      expect(collectionWithKeyToObject([])).toStrictEqual({});
    });

    it('should return empty object for undefined', () => {
      expect(collectionWithKeyToObject(undefined)).toStrictEqual({});
    });

    it('should turn collection with key into object', () => {
      const collectionWithKey = [
        { id: 'a', attr1: 'a1', attr2: 'a2' },
        { id: 'b', attr1: 'b1', attr2: 'b2' },
      ];
      expect(collectionWithKeyToObject(collectionWithKey)).toStrictEqual({
        a: { attr1: 'a1', attr2: 'a2' },
        b: { attr1: 'b1', attr2: 'b2' },
      });
    });
  });

  describe('getStateFromUrlParams', () => {
    let location = null;

    beforeEach(() => {
      location = global.window.location;
      delete global.window.location;
      global.window = Object.create(window);
      global.window.location = {
        protocol: 'http:',
        hostname: 'localhost',
      };
    });

    afterEach(() => {
      global.window.location = location;
      location = null;
    });

    it('should return a hash from filtered enrollment list url', () => {
      global.window.location.search =
        '?page=0' +
        '&sorted=%5B%7B"id"%3A"updated_at"%2C"desc"%3Atrue%7D%5D' +
        '&filtered=%5B%7B"id"%3A"nom_raison_sociale"%2C"value"%3A"te"%7D%2C%7B"id"%3A"user.email"%2C"value"%3A"france"%7D%2C%7B"id"%3A"target_api"%2C"value"%3A%5B"franceconnect"%5D%7D%2C%7B"id"%3A"status"%2C"value"%3A%5B""%5D%7D%5D';

      const expectedResult = {
        page: 0,
        sorted: [{ id: 'updated_at', desc: true }],
        filtered: [
          { id: 'nom_raison_sociale', value: 'te' },
          { id: 'user.email', value: 'france' },
          { id: 'target_api', value: ['franceconnect'] },
          { id: 'status', value: [''] },
        ],
      };

      expect(
        getStateFromUrlParams({ page: 0, sorted: [], filtered: [] })
      ).toEqual(expectedResult);
    });

    it('should ignore null value', () => {
      global.window.location.search = '?a=&b&d=1';

      const expectedResult = { a: '', b: '', c: '' };

      expect(getStateFromUrlParams({ a: '', b: '', c: '' })).toEqual(
        expectedResult
      );
    });

    it('should process boolean value', () => {
      global.window.location.search = '?a=true&b=false';

      const expectedResult = { a: true, b: false, c: false };

      expect(getStateFromUrlParams({ a: false, b: true, c: false })).toEqual(
        expectedResult
      );
    });

    it('should return a hash from preset enrollment demarche form url', () => {
      global.window.location.search = '?demarche=ccas';

      const expectedResult = { demarche: 'ccas' };

      expect(
        getStateFromUrlParams({
          demarche: '',
        })
      ).toEqual(expectedResult);
    });

    it('should process nested array value', () => {
      global.window.location.search =
        '?filtered=%5B%7B%22id%22%3A%22target_api%22%2C%22value%22%3A%5B%22api_particulier%22%2C%22api_entreprise%22%5D%7D%2C%7B%22id%22%3A%22nom_raison_sociale%22%2C%22value%22%3A%22a%22%7D%5D';

      const expectedResult = {
        filtered: [
          {
            id: 'target_api',
            value: ['api_particulier', 'api_entreprise'],
          },
          { id: 'nom_raison_sociale', value: 'a' },
        ],
      };

      expect(getStateFromUrlParams({ filtered: [] })).toEqual(expectedResult);
    });

    it('should be the inverse fonction of hashToQueryParams', () => {
      const hash = {
        filtered: [
          {
            id: 'target_api',
            value: ['api_particulier', 'api_entreprise'],
          },
          { id: 'nom_raison_sociale', value: 'a' },
        ],
      };

      global.window.location.search = hashToQueryParams(hash);

      expect(getStateFromUrlParams({ filtered: [] })).toEqual(hash);
    });
  });

  describe('findModifiedFields', () => {
    it('should return null when only empty field are modified', () => {
      expect(
        findModifiedFields(
          {
            fondement_juridique_title: '',
          },
          {
            fondement_juridique_title:
              'Article L114-6 du code du service national',
          }
        )
      ).toStrictEqual([]);
    });

    it('should return an array with modified field(s)', () => {
      const demarcheState = {
        intitule:
          'Calcul de la tarification pour la facturation des services périscolaires, restauration scolaire et des accueils de loisirs.',
        description: 'description',
        scopes: {
          cnaf_quotient_familial: false,
          dgfip_declarant1_nom: false,
        },
      };
      const enrollmentState = {
        acl: {
          update: true,
          submit: true,
        },
        status: 'pending',
        target_api: 'api_particulier',
        intitule: 'Mon intitulé',
        scopes: {
          dgfip_declarant1_nom: false,
          cnaf_quotient_familial: false,
        },
        team_members: [
          {
            type: 'demandeur',
            tmp_id: 'tmp_31',
            email: '[email protected]',
          },
          {
            type: 'responsable_technique',
            tmp_id: 'tmp_34',
          },
        ],
      };
      expect(findModifiedFields(demarcheState, enrollmentState)).toStrictEqual([
        'intitule',
      ]);
    });
  });

  describe('findModifiedScopes', () => {
    it('should return an object containing modified scopes', () => {
      const demarcheState = {
        scopes: {
          dgfip_declarant1_nom: true,
          cnaf_quotient_familial: true,
        },
      };
      const enrollmentState = {
        scopes: {
          dgfip_declarant1_nom: true,
          cnaf_quotient_familial: false,
          entreprise: false,
        },
      };
      expect(findModifiedScopes(demarcheState, enrollmentState)).toStrictEqual({
        cnaf_quotient_familial: false,
        entreprise: false,
      });
    });
  });

  /*
   * duplicated from : api-auth/test/security.test.js
   */
  describe('isEmailValid', () => {
    it('should return false for undefined value', () => {
      expect(isEmailValid(undefined)).toStrictEqual(false);
    });

    it('should return false for empty string', () => {
      expect(isEmailValid('')).toStrictEqual(false);
    });

    it('should return false if no @ is present', () => {
      expect(isEmailValid('test')).toStrictEqual(false);
    });

    it('should return false if no domain is present', () => {
      expect(isEmailValid('test@')).toStrictEqual(false);
    });

    it('should return false if two @ are present', () => {
      expect(isEmailValid('test@test@test')).toStrictEqual(false);
    });

    it('should return false if domains contain other than letters, numbers, hyphens (-) and periods (.)', () => {
      expect(isEmailValid('test@test_test')).toStrictEqual(false);
    });

    it('should return false if local part is longer than 63 characters', () => {
      expect(
        isEmailValid(
          '1234567890123456789012345678901234567890123456789012345678901234@test'
        )
      ).toStrictEqual(false);
    });

    it('should return false if total length is longer than 254 characters', () => {
      expect(
        isEmailValid(
          'test@1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
        )
      ).toStrictEqual(false);
    });

    // this test cases have been taken from
    // https://stackoverflow.com/questions/46155/how-to-validate-an-email-address-in-javascript/32686261#32686261
    const validEmailAddresses = [
      '[email protected]',
      '[email protected]',
      '[email protected]',
      '[email protected]',
      "#!$%&'*+-/=?^_`{}|[email protected]",
      '"()[]:,;\\"!#$%&\'*+-/=?^_`{}| ~.a"@example.org',
      '" "@example.org', // space between the quotes
      'üñîçøðé@example.com', // Unicode characters in local part
      'Pelé@example.com', // Latin
    ];

    validEmailAddresses.forEach((validEmailAddress) => {
      it('should return true for valid email address', () => {
        expect(isEmailValid(validEmailAddress)).toStrictEqual(true);
      });
    });
  });

  describe('isValidPhoneNumber', () => {
    it('should return false for empty phone number', () => {
      expect(isValidPhoneNumber()).toStrictEqual(false);
    });
    it('should return false for non string value', () => {
      expect(isValidPhoneNumber([])).toStrictEqual(false);
    });
    it('should return true for valid phone number no spaces', () => {
      expect(isValidPhoneNumber('0123456789')).toStrictEqual(true);
    });
    it('should return true for valid phone number with spaces', () => {
      expect(isValidPhoneNumber('01 23 45 67 89')).toStrictEqual(true);
    });
    it('should return true for valid phone number with country indicator', () => {
      expect(isValidPhoneNumber('+33 1 23 45 67 89')).toStrictEqual(true);
    });
  });

  describe('isIndividualEmailAddress', () => {
    it('should return false for empty phone number', () => {
      expect(isIndividualEmailAddress()).toStrictEqual(false);
    });
    it('should return false for non string value', () => {
      expect(isIndividualEmailAddress([])).toStrictEqual(false);
    });
    it('should return true for individual email address', () => {
      expect(
        isIndividualEmailAddress('[email protected]')
      ).toStrictEqual(true);
    });
    [
      '[email protected]',
      '[email protected]',
    ].forEach((email) => {
      it(`should return true for ${email}`, () => {
        expect(isIndividualEmailAddress(email)).toStrictEqual(false);
      });
    });
    groupEmailAddresses.forEach((email) => {
      it(`should return false for ${email}`, () => {
        expect(isIndividualEmailAddress(email)).toStrictEqual(false);
      });
    });
  });

  describe('isValidMobilePhoneNumber', () => {
    it('should return false for empty phone number', () => {
      expect(isValidMobilePhoneNumber()).toStrictEqual(false);
    });
    it('should return false for non string value', () => {
      expect(isValidMobilePhoneNumber([])).toStrictEqual(false);
    });
    it('should return false for valid phone number no spaces', () => {
      expect(isValidMobilePhoneNumber('0123456789')).toStrictEqual(false);
    });
    it('should return false for valid phone number with spaces', () => {
      expect(isValidMobilePhoneNumber('01 23 45 67 89')).toStrictEqual(false);
    });
    it('should return false for valid phone number with country indicator', () => {
      expect(isValidMobilePhoneNumber('+33 1 73 45 67 89')).toStrictEqual(
        false
      );
    });
    it('should return true for valid mobile phone number no spaces 06', () => {
      expect(isValidMobilePhoneNumber('0623456789')).toStrictEqual(true);
    });
    it('should return true for valid mobile phone number no spaces 07', () => {
      expect(isValidMobilePhoneNumber('0623456789')).toStrictEqual(true);
    });
    it('should return true for valid mobile phone number with spaces 06', () => {
      expect(isValidMobilePhoneNumber('06 23 45 67 89')).toStrictEqual(true);
    });
    it('should return true for valid mobile phone number with country indicator 07', () => {
      expect(isValidMobilePhoneNumber('+33 7 23 45 67 89')).toStrictEqual(true);
    });
  });

  describe('stackLowUseAndUnpublishedApi', () => {
    it('should return anonymised count by api collection', () => {
      const enrollment_by_target_api = [
        {
          name: 'published_1',
          count: 5,
        },
        {
          name: 'not_published',
          count: 4,
        },
        {
          name: 'published_2',
          count: 3,
        },
        {
          name: 'published_3',
          count: 2,
        },
        {
          name: 'not_published',
          count: 1,
        },
        {
          name: 'published_4',
          count: 1,
        },
      ];

      const publishedApis = [
        'published_1',
        'published_2',
        'published_3',
        'published_4',
      ];

      expect(
        stackLowUseAndUnpublishedApi(publishedApis, enrollment_by_target_api, 3)
      ).toStrictEqual([
        {
          name: 'published_1',
          count: 5,
        },
        {
          name: 'published_2',
          count: 3,
        },
        {
          name: 'published_3',
          count: 2,
        },
        {
          name: 'others',
          count: 6,
        },
      ]);
    });
  });

  describe('dataProviderParametersToContactInfo', () => {
    it('should return stacked contact info', () => {
      const parameters = [
        { label: 'API 1', email: '[email protected]' },
        { label: 'API 2', email: '[email protected]' },
        { label: 'API 3', email: '[email protected]' },
        { label: 'API 4', email: null },
      ];

      const expected = [
        { label: 'API 1, API 3', email: '[email protected]' },
        { label: 'API 2', email: '[email protected]' },
      ];

      const result = dataProviderParametersToContactInfo(parameters);

      expect(result).toStrictEqual(expected);
    });

    it('should manage data provider with many api', () => {
      const parameters = [
        { label: 'API 1 (Bac à sable)', email: '[email protected]' },
        { label: 'API 1 (Production)', email: '[email protected]' },
        { label: 'API 1 (FC) (Bac à sable)', email: '[email protected]' },
        { label: 'API 1 (FC) (Production)', email: '[email protected]' },
        { label: 'API 2 (Bac à sable)', email: '[email protected]' },
        { label: 'API 2 (Production)', email: '[email protected]' },
        { label: 'API 3 (Bac à sable)', email: '[email protected]' },
        { label: 'API 3 (Production)', email: '[email protected]' },
        { label: 'API 4 (Bac à sable)', email: '[email protected]' },
        { label: 'API 4 (Production)', email: '[email protected]' },
        { label: 'API 5 (Bac à sable)', email: '[email protected]' },
        { label: 'API 5 (Production)', email: '[email protected]' },
        { label: 'API 6 (Bac à sable)', email: '[email protected]' },
        { label: 'API 6 (Production)', email: '[email protected]' },
      ];

      const expected = [
        { label: 'API 1, API 2, API 3, API 4, etc.', email: '[email protected]' },
      ];

      const result = dataProviderParametersToContactInfo(parameters);

      expect(result).toStrictEqual(expected);
    });
  });

  describe('getScopesFromEnrollments', () => {
    it('should return scopes', () => {
      const enrollments = [
        {
          id: 1058510684,
          scopes: {
            scope1: true,
            scope2: false,
          },
        },
        {
          id: 1058510632,
          scopes: {
            scope3: true,
          },
        },
        {
          id: 1058510631,
          scopes: {
            scope1: true,
          },
        },
      ];

      const result = getScopesFromEnrollments(enrollments);

      expect(result).toStrictEqual(['scope1', 'scope3']);
    });
  });
});