@proconnect-gouv/proconnect.identite 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,12 @@
1
1
  //
2
2
 
3
3
  import { IdentityVectorSchema } from "#src/types";
4
+ import {
5
+ api_entreprise_mock_client,
6
+ api_insee_mock_client,
7
+ api_registre_national_entreprises_mock_client,
8
+ context,
9
+ } from "#testing";
4
10
  import {
5
11
  AmberleyVailFranceConnectUserInfo,
6
12
  LiElJonsonFranceConnectUserInfo,
@@ -32,19 +38,14 @@ import { processCertificationDirigeantFactory } from "./process-certification-di
32
38
 
33
39
  //
34
40
 
41
+ const processCertificationDirigeant =
42
+ processCertificationDirigeantFactory(context);
43
+
35
44
  describe("processCertificationDirigeantFactory", () => {
36
45
  it("should recognize a user as executive of a auto-entrepreneur", async () => {
37
- const processCertificationDirigeant = processCertificationDirigeantFactory({
38
- ApiEntrepriseClient: {
39
- findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
40
- },
41
- RegistreNationalEntreprisesApiClient: {
42
- findPouvoirsBySiren: () => Promise.reject(new Error("💣")),
43
- },
44
- InseeApiClient: {
45
- findBySiren: () => Promise.resolve(LiElJonsonEstablishment),
46
- },
47
- });
46
+ api_insee_mock_client.findBySiren.mock.mockImplementationOnce(() =>
47
+ Promise.resolve(LiElJonsonEstablishment),
48
+ );
48
49
 
49
50
  const certificationDirigeantResult = await processCertificationDirigeant(
50
51
  rogal_dorn_org_info,
@@ -70,18 +71,9 @@ describe("processCertificationDirigeantFactory", () => {
70
71
  });
71
72
 
72
73
  it("should recognize a foreign user as executive of a auto-entrepreneur", async () => {
73
- const processCertificationDirigeant = processCertificationDirigeantFactory({
74
- ApiEntrepriseClient: {
75
- findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
76
- },
77
- RegistreNationalEntreprisesApiClient: {
78
- findPouvoirsBySiren: () => Promise.reject(new Error("💣")),
79
- },
80
- InseeApiClient: {
81
- findBySiren: () => Promise.resolve(RogalDornEstablishment),
82
- },
83
- });
84
-
74
+ api_insee_mock_client.findBySiren.mock.mockImplementationOnce(() =>
75
+ Promise.resolve(RogalDornEstablishment),
76
+ );
85
77
  const certificationDirigeantResult = await processCertificationDirigeant(
86
78
  rogal_dorn_org_info,
87
79
  RogalDornFranceConnectUserInfo,
@@ -106,17 +98,9 @@ describe("processCertificationDirigeantFactory", () => {
106
98
  });
107
99
 
108
100
  it("should not match another mandataire", async () => {
109
- const processCertificationDirigeant = processCertificationDirigeantFactory({
110
- ApiEntrepriseClient: {
111
- findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
112
- },
113
- RegistreNationalEntreprisesApiClient: {
114
- findPouvoirsBySiren: () => Promise.reject(new Error("💣")),
115
- },
116
- InseeApiClient: {
117
- findBySiren: () => Promise.resolve(LiElJonsonEstablishment),
118
- },
119
- });
101
+ api_insee_mock_client.findBySiren.mock.mockImplementationOnce(() =>
102
+ Promise.resolve(LiElJonsonEstablishment),
103
+ );
120
104
 
121
105
  const certificationDirigeantResult = await processCertificationDirigeant(
122
106
  rogal_dorn_org_info,
@@ -136,18 +120,9 @@ describe("processCertificationDirigeantFactory", () => {
136
120
  });
137
121
 
138
122
  it("should match Rogal Dorn among the executive of Papillon in RNE", async () => {
139
- const processCertificationDirigeant = processCertificationDirigeantFactory({
140
- ApiEntrepriseClient: {
141
- findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
142
- },
143
- RegistreNationalEntreprisesApiClient: {
144
- findPouvoirsBySiren: () =>
145
- Promise.resolve([UlysseTosiPouvoir, RogalDornPouvoir]),
146
- },
147
- InseeApiClient: {
148
- findBySiren: () => Promise.reject(new Error("💣")),
149
- },
150
- });
123
+ api_registre_national_entreprises_mock_client.findPouvoirsBySiren.mock.mockImplementationOnce(
124
+ () => Promise.resolve([UlysseTosiPouvoir, RogalDornPouvoir]),
125
+ );
151
126
 
152
127
  const certificationDirigeantResult = await processCertificationDirigeant(
153
128
  papillon_org_info,
@@ -173,18 +148,9 @@ describe("processCertificationDirigeantFactory", () => {
173
148
  });
174
149
 
175
150
  it("should match Amberley Vail among the executive of Papillon in RNE", async () => {
176
- const processCertificationDirigeant = processCertificationDirigeantFactory({
177
- ApiEntrepriseClient: {
178
- findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
179
- },
180
- RegistreNationalEntreprisesApiClient: {
181
- findPouvoirsBySiren: () =>
182
- Promise.resolve([UlysseTosiPouvoir, AmberleyVailPouvoir]),
183
- },
184
- InseeApiClient: {
185
- findBySiren: () => Promise.reject(new Error("💣")),
186
- },
187
- });
151
+ api_registre_national_entreprises_mock_client.findPouvoirsBySiren.mock.mockImplementationOnce(
152
+ () => Promise.resolve([UlysseTosiPouvoir, AmberleyVailPouvoir]),
153
+ );
188
154
 
189
155
  const certificationDirigeantResult = await processCertificationDirigeant(
190
156
  papillon_org_info,
@@ -210,18 +176,9 @@ describe("processCertificationDirigeantFactory", () => {
210
176
  });
211
177
 
212
178
  it("should match Rogal Dorn among the executive of Papillon in Infogreffe", async () => {
213
- const processCertificationDirigeant = processCertificationDirigeantFactory({
214
- ApiEntrepriseClient: {
215
- findMandatairesSociauxBySiren: () =>
216
- Promise.resolve([UlysseToriMandataire, RogalDornMandataire]),
217
- },
218
- RegistreNationalEntreprisesApiClient: {
219
- findPouvoirsBySiren: () => Promise.reject(new Error("💣")),
220
- },
221
- InseeApiClient: {
222
- findBySiren: () => Promise.reject(new Error("💣")),
223
- },
224
- });
179
+ api_entreprise_mock_client.findMandatairesSociauxBySiren.mock.mockImplementationOnce(
180
+ () => Promise.resolve([UlysseToriMandataire, RogalDornMandataire]),
181
+ );
225
182
 
226
183
  const certificationDirigeantResult = await processCertificationDirigeant(
227
184
  papillon_org_info,
@@ -248,17 +205,9 @@ describe("processCertificationDirigeantFactory", () => {
248
205
  });
249
206
 
250
207
  it("❎ fail with no mandataires", async () => {
251
- const processCertificationDirigeant = processCertificationDirigeantFactory({
252
- ApiEntrepriseClient: {
253
- findMandatairesSociauxBySiren: () => Promise.reject(new Error("💣")),
254
- },
255
- RegistreNationalEntreprisesApiClient: {
256
- findPouvoirsBySiren: () => Promise.resolve([]),
257
- },
258
- InseeApiClient: {
259
- findBySiren: () => Promise.reject(new Error("💣")),
260
- },
261
- });
208
+ api_registre_national_entreprises_mock_client.findPouvoirsBySiren.mock.mockImplementationOnce(
209
+ () => Promise.resolve([]),
210
+ );
262
211
 
263
212
  const certificationDirigeantResult = await processCertificationDirigeant(
264
213
  papillon_org_info,
@@ -1,5 +1,6 @@
1
1
  //
2
2
 
3
+ import type { Context } from "#src/connectors";
3
4
  import { isOrganizationCoveredByCertificationDirigeant } from "#src/services/organization";
4
5
  import {
5
6
  NullIdentityVector,
@@ -7,9 +8,6 @@ import {
7
8
  type IdentityVector,
8
9
  type Organization,
9
10
  } from "#src/types";
10
- import type { ApiEntrepriseClient } from "@proconnect-gouv/proconnect.api_entreprise/api";
11
- import type { ApiInseeClient } from "@proconnect-gouv/proconnect.insee/api";
12
- import type { FindPouvoirsBySirenHandler } from "@proconnect-gouv/proconnect.registre_national_entreprises/api";
13
11
  import { match } from "ts-pattern";
14
12
  import z from "zod/v4";
15
13
  import * as ApiEntreprise from "./adapters/api_entreprise.js";
@@ -20,17 +18,6 @@ import { certificationScore } from "./certification-score.js";
20
18
 
21
19
  //
22
20
 
23
- type ProcessCertificationDirigeantConfig = {
24
- ApiEntrepriseClient: Pick<
25
- ApiEntrepriseClient,
26
- "findMandatairesSociauxBySiren"
27
- >;
28
- InseeApiClient: ApiInseeClient;
29
- RegistreNationalEntreprisesApiClient: {
30
- findPouvoirsBySiren: FindPouvoirsBySirenHandler;
31
- };
32
- };
33
-
34
21
  export const CertificationDirigeantDataSource = z.enum([
35
22
  "api.insee.fr/api-sirene/private",
36
23
  "entreprise.api.gouv.fr/v3/infogreffe/rcs/unites_legales/{siren}/mandataires_sociaux",
@@ -59,15 +46,11 @@ export function getCertificationDirigeantDataSourceLabels(
59
46
  //
60
47
 
61
48
  async function getMandatairesSociaux(
62
- {
63
- RegistreNationalEntreprisesApiClient,
64
- ApiEntrepriseClient,
65
- }: ProcessCertificationDirigeantConfig,
49
+ { client: { api_entreprise, rne } }: Context,
66
50
  siren: string,
67
51
  ) {
68
52
  try {
69
- const pouvoirs =
70
- await RegistreNationalEntreprisesApiClient.findPouvoirsBySiren(siren);
53
+ const pouvoirs = await rne.findPouvoirsBySiren(siren);
71
54
  const dirigeants = pouvoirs.map(RNE.toIdentityVector);
72
55
 
73
56
  return {
@@ -80,7 +63,7 @@ async function getMandatairesSociaux(
80
63
  } catch (error) {
81
64
  console.error(error);
82
65
  const mandataires =
83
- await ApiEntrepriseClient.findMandatairesSociauxBySiren(siren);
66
+ await api_entreprise.findMandatairesSociauxBySiren(siren);
84
67
  const dirigeants = mandataires.map(ApiEntreprise.toIdentityVector);
85
68
 
86
69
  return {
@@ -126,10 +109,10 @@ function match_identity_to_dirigeant(
126
109
  }));
127
110
  }
128
111
 
129
- export function processCertificationDirigeantFactory(
130
- config: ProcessCertificationDirigeantConfig,
131
- ) {
132
- const { InseeApiClient } = config;
112
+ export function processCertificationDirigeantFactory(context: Context) {
113
+ const {
114
+ client: { insee },
115
+ } = context;
133
116
 
134
117
  return async function processCertificationDirigeant(
135
118
  organization: Organization,
@@ -163,7 +146,8 @@ export function processCertificationDirigeantFactory(
163
146
 
164
147
  const { dirigeants, source } = await match(preferredDataSource)
165
148
  .with("api.insee.fr/api-sirene/private", async () => ({
166
- dirigeants: await InseeApiClient.findBySiren(siren)
149
+ dirigeants: await insee
150
+ .findBySiren(siren)
167
151
  .then(INSEE.toIdentityVector)
168
152
  .then((vector) => [vector]),
169
153
  source:
@@ -172,7 +156,7 @@ export function processCertificationDirigeantFactory(
172
156
  ],
173
157
  }))
174
158
  .with("registre-national-entreprises.inpi.fr/api", () =>
175
- getMandatairesSociaux(config, siren),
159
+ getMandatairesSociaux(context, siren),
176
160
  )
177
161
  .exhaustive();
178
162
 
package/testing/index.ts CHANGED
@@ -1,18 +1,27 @@
1
1
  //
2
2
 
3
3
  import { PGlite } from "@electric-sql/pglite";
4
+ import type { FindMandatairesSociauxBySirenHandler } from "@proconnect-gouv/proconnect.api_entreprise/api/infogreffe";
5
+ import type {
6
+ FindBySirenHandler,
7
+ FindBySiretHandler,
8
+ } from "@proconnect-gouv/proconnect.api_entreprise/api/insee";
9
+ import type { FindPouvoirsBySirenHandler } from "@proconnect-gouv/proconnect.registre_national_entreprises/api";
4
10
  import { noop } from "lodash-es";
5
11
  import { runner } from "node-pg-migrate";
12
+ import { mock } from "node:test";
6
13
  import { join } from "path";
14
+ import type { Pool } from "pg";
15
+ import type { FindUniteLegaleBySirenHandler } from "../../insee/src/api/find-by-siren.js";
16
+ import type { FindUniteLegaleBySiretHandler } from "../../insee/src/api/find-by-siret.js";
7
17
  import { createContext } from "../src/connectors/index.js";
8
18
 
9
19
  //
10
20
 
11
21
  export const pg = new PGlite();
12
- export const context = createContext(pg as any);
13
22
 
14
- export function migrate() {
15
- return runner({
23
+ export async function migrate() {
24
+ await runner({
16
25
  dbClient: pg as any,
17
26
  dir: join(import.meta.dirname, "../../../migrations"),
18
27
  direction: "up",
@@ -31,3 +40,34 @@ export async function emptyDatabase() {
31
40
  await pg.sql`delete from email_domains;`;
32
41
  await pg.sql`ALTER SEQUENCE email_domains_id_seq RESTART WITH 1`;
33
42
  }
43
+
44
+ //
45
+
46
+ const should_not_been_called = () => Promise.reject(new Error("💣"));
47
+
48
+ export const api_entreprise_mock_client = {
49
+ findBySiren: mock.fn<FindBySirenHandler>(should_not_been_called),
50
+ findBySiret: mock.fn<FindBySiretHandler>(should_not_been_called),
51
+ findMandatairesSociauxBySiren: mock.fn<FindMandatairesSociauxBySirenHandler>(
52
+ should_not_been_called,
53
+ ),
54
+ };
55
+
56
+ export const api_insee_mock_client = {
57
+ findBySiret: mock.fn<FindUniteLegaleBySiretHandler>(should_not_been_called),
58
+ findBySiren: mock.fn<FindUniteLegaleBySirenHandler>(should_not_been_called),
59
+ };
60
+
61
+ export const api_registre_national_entreprises_mock_client = {
62
+ findPouvoirsBySiren: mock.fn<FindPouvoirsBySirenHandler>(
63
+ should_not_been_called,
64
+ ),
65
+ };
66
+
67
+ export const context = createContext({
68
+ api_entreprise_client: api_entreprise_mock_client,
69
+ api_insee_client: api_insee_mock_client,
70
+ api_registre_national_entreprises_client:
71
+ api_registre_national_entreprises_mock_client,
72
+ pg: pg as Pool & PGlite,
73
+ });
package/tsconfig.json CHANGED
@@ -12,10 +12,11 @@
12
12
  },
13
13
  "extends": "@proconnect-gouv/proconnect.devtools.typescript/base/tsconfig.json",
14
14
  "references": [
15
- { "path": "../annuaire_entreprises/tsconfig.lib.json" },
16
- { "path": "../core/tsconfig.lib.json" },
17
- { "path": "../entreprise/tsconfig.lib.json" },
18
- { "path": "../insee/tsconfig.lib.json" }
15
+ { "path": "../annuaire_entreprises" },
16
+ { "path": "../core" },
17
+ { "path": "../entreprise" },
18
+ { "path": "../insee" },
19
+ { "path": "../registre_national_entreprises" }
19
20
  ],
20
21
  "include": ["./src/**/*", "./src/**/*.json", "testing"]
21
22
  }