feat: passe à l'API de recherche d’entreprises de api.gouv.fr
parent
6e4e630d68
commit
269ca6fbcc
|
@ -36,6 +36,7 @@ describe(`Navigation to income simulator using company name (${
|
|||
let pendingRequests = new Set()
|
||||
let responses = {}
|
||||
const hostnamesToRecord = [
|
||||
'recherche-entreprises.api.gouv.fr',
|
||||
'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
'geo.api.gouv.fr',
|
||||
]
|
||||
|
@ -64,8 +65,8 @@ describe(`Navigation to income simulator using company name (${
|
|||
it('should allow to retrieve company and show link corresponding to the legal status', function () {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
hostname: 'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
url: '/api/v1/search*',
|
||||
hostname: 'recherche-entreprises.api.gouv.fr',
|
||||
url: '/search?q=*',
|
||||
}).as('search')
|
||||
|
||||
cy.get('input[data-test-id="company-search-input"]').first().type('menoz')
|
||||
|
@ -93,8 +94,8 @@ describe(`Navigation to income simulator using company name (${
|
|||
it('should allow auto entrepreneur to access the corresponding income simulator', function () {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
hostname: 'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
url: '/api/v1/search*',
|
||||
hostname: 'recherche-entreprises.api.gouv.fr',
|
||||
url: '/search?q=*',
|
||||
}).as('search')
|
||||
|
||||
cy.get('input[data-test-id="company-search-input"]').type('jeremy rialland')
|
||||
|
|
|
@ -21,6 +21,7 @@ describe('Landing page', function () {
|
|||
let pendingRequests = new Set()
|
||||
let responses = {}
|
||||
const hostnamesToRecord = [
|
||||
'recherche-entreprises.api.gouv.fr',
|
||||
'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
'geo.api.gouv.fr',
|
||||
]
|
||||
|
@ -41,13 +42,13 @@ describe('Landing page', function () {
|
|||
|
||||
cy.get(searchInputPath).should('have.attr', 'placeholder')
|
||||
cy.get(searchInputPath).invoke('attr', 'type').should('equal', 'search')
|
||||
cy.get(searchInputPath).first().type('noima')
|
||||
cy.get(searchInputPath).first().type('menoz')
|
||||
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
hostname: 'api.recherche-entreprises.fabrique.social.gouv.fr',
|
||||
url: '/api/v1/search?*',
|
||||
hostname: 'recherche-entreprises.api.gouv.fr',
|
||||
url: '/search?q=*',
|
||||
},
|
||||
(req) => {
|
||||
req.responseTimeout = 10 * 1000
|
||||
|
@ -57,7 +58,7 @@ describe('Landing page', function () {
|
|||
|
||||
cy.wait('@search')
|
||||
|
||||
cy.get(searchResultsPath).children().should('have.length', 6)
|
||||
cy.get(searchResultsPath).children().should('have.length.at.least', 4)
|
||||
cy.get(searchResultsPath).children().first().click()
|
||||
|
||||
cy.url().should('include', '/pour-mon-entreprise')
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
[[headers]]
|
||||
for = "/*"
|
||||
[headers.values]
|
||||
Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self' 'unsafe-inline' mon-entreprise.zammad.com; connect-src 'self' *.incubateur.net raw.githubusercontent.com tm.urssaf.fr mon-entreprise.zammad.com api.recherche-entreprises.fabrique.social.gouv.fr geo.api.gouv.fr *.algolia.net *.algolianet.com polyfill.io jedonnemonavis.numerique.gouv.fr user-images.githubusercontent.com; form-action 'self' *.sibforms.com *.incubateur.net mon-entreprise.zammad.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' tm.urssaf.fr *.incubateur.net stonly.com code.jquery.com mon-entreprise.zammad.com polyfill.io; img-src 'self' data: mon-entreprise.urssaf.fr tm.urssaf.fr user-images.githubusercontent.com jedonnemonavis.numerique.gouv.fr; frame-src 'self' https://www.youtube-nocookie.com https://codesandbox.io https://place-des-entreprises.beta.gouv.fr https://reso-staging.osc-fr1.scalingo.io https://stackblitz.com"
|
||||
Content-Security-Policy = """\
|
||||
default-src 'self' mon-entreprise.fr; \
|
||||
style-src 'self' 'unsafe-inline' mon-entreprise.zammad.com; \
|
||||
connect-src 'self' *.incubateur.net raw.githubusercontent.com tm.urssaf.fr mon-entreprise.zammad.com recherche-entreprises.api.gouv.fr api.recherche-entreprises.fabrique.social.gouv.fr geo.api.gouv.fr *.algolia.net *.algolianet.com polyfill.io jedonnemonavis.numerique.gouv.fr user-images.githubusercontent.com; \
|
||||
form-action 'self' *.sibforms.com *.incubateur.net mon-entreprise.zammad.com; \
|
||||
script-src 'self' 'unsafe-inline' 'unsafe-eval' tm.urssaf.fr *.incubateur.net stonly.com code.jquery.com mon-entreprise.zammad.com polyfill.io; \
|
||||
img-src 'self' data: mon-entreprise.urssaf.fr tm.urssaf.fr user-images.githubusercontent.com jedonnemonavis.numerique.gouv.fr; \
|
||||
frame-src 'self' https://www.youtube-nocookie.com https://codesandbox.io https://place-des-entreprises.beta.gouv.fr https://reso-staging.osc-fr1.scalingo.io https://stackblitz.com \
|
||||
"""
|
||||
|
||||
[dev]
|
||||
autoLaunch = false
|
||||
|
@ -33,7 +41,7 @@ Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self
|
|||
|
||||
############
|
||||
# Redirects following architectural changes
|
||||
# DO NOT MOVE THIS SECTION ! ORDER MATTERS IN REDIRECTS !
|
||||
# DO NOT MOVE THIS SECTION ! ORDER MATTERS IN REDIRECTS !
|
||||
|
||||
# :SITE_<name> is a placeholder replaced before deploy (depends on the environment)
|
||||
|
||||
|
@ -80,7 +88,7 @@ Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self
|
|||
from=":SITE_FR/simulateurs/%C3%A9conomie-collaborative/*"
|
||||
to=":SITE_FR/assistants/%C3%A9conomie-collaborative/:splat"
|
||||
status = 301
|
||||
|
||||
|
||||
## Older changes
|
||||
|
||||
# FR | coronavirus -> simulateurs/chômage-partiel
|
||||
|
@ -163,7 +171,7 @@ Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self
|
|||
|
||||
####################
|
||||
# Redirect following huge refacto in modele-social
|
||||
# DO NOT MOVE THIS SECTION ! ORDER MATTERS IN REDIRECTS !
|
||||
# DO NOT MOVE THIS SECTION ! ORDER MATTERS IN REDIRECTS !
|
||||
##################""
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
import { CodeActivite } from '@/domain/CodeActivite'
|
||||
import { CodeCatégorieJuridique } from '@/domain/CodeCatégorieJuridique'
|
||||
import { IsoDate, parseIsoDateString } from '@/domain/Date'
|
||||
import { Entreprise } from '@/domain/Entreprise'
|
||||
import { EntreprisesRepository } from '@/domain/EntreprisesRepository'
|
||||
import { Établissement } from '@/domain/Établissement'
|
||||
import { Siren, Siret } from '@/domain/Siren'
|
||||
|
||||
/**
|
||||
* @see https://api.gouv.fr/documentation/api-recherche-entreprises
|
||||
*/
|
||||
export const RechercheEntreprisesGouvFr: EntreprisesRepository = {
|
||||
rechercheTexteLibre,
|
||||
}
|
||||
|
||||
const makeSearchUrl = (q: string, limit: number) =>
|
||||
`https://recherche-entreprises.api.gouv.fr/search?q=${q}&etat_administratif=A&per_page=${limit}`
|
||||
|
||||
async function rechercheTexteLibre(text: string, limit = 10) {
|
||||
const response = await fetch(makeSearchUrl(text, limit))
|
||||
|
||||
if (!response.ok) {
|
||||
return null
|
||||
}
|
||||
|
||||
const json = (await response.json()) as ApiResponse
|
||||
|
||||
return json.results.map(EntrepriseFromApiAdapter)
|
||||
}
|
||||
|
||||
interface ApiResponse {
|
||||
results: Array<EntrepriseApi>
|
||||
total_results: number
|
||||
page: number
|
||||
per_page: number
|
||||
total_pages: number
|
||||
}
|
||||
|
||||
interface EntrepriseApi {
|
||||
siren: Siren
|
||||
nom_complet: string
|
||||
nom_raison_sociale: string
|
||||
sigle: string
|
||||
date_creation: IsoDate
|
||||
nature_juridique: CodeCatégorieJuridique
|
||||
activite_principale: CodeActivite
|
||||
siege: EtablissementApi
|
||||
matching_etablissements: Array<EtablissementApi>
|
||||
nombre_etablissements: number
|
||||
nombre_etablissements_ouverts: number
|
||||
}
|
||||
|
||||
const EntrepriseFromApiAdapter = (api: EntrepriseApi): Entreprise => {
|
||||
const siège = ÉtablissementFromApiAdapter(api.siege)
|
||||
const établissement = api.matching_etablissements.length
|
||||
? ÉtablissementFromApiAdapter(api.matching_etablissements[0])
|
||||
: siège
|
||||
|
||||
return {
|
||||
nom: api.nom_complet,
|
||||
siren: api.siren,
|
||||
dateDeCréation: parseIsoDateString(api.date_creation),
|
||||
siège,
|
||||
établissement,
|
||||
activitéPrincipale: api.activite_principale,
|
||||
codeCatégorieJuridique: api.nature_juridique,
|
||||
}
|
||||
}
|
||||
|
||||
interface EtablissementApi {
|
||||
siret: Siret
|
||||
adresse: string
|
||||
commune: string
|
||||
libelle_commune: string
|
||||
activite_principale: CodeActivite
|
||||
est_siege: boolean
|
||||
nom_commercial: string
|
||||
}
|
||||
|
||||
const ÉtablissementFromApiAdapter = (api: EtablissementApi): Établissement => ({
|
||||
siret: api.siret,
|
||||
adresse: {
|
||||
complète: api.adresse,
|
||||
codeCommune: api.commune,
|
||||
},
|
||||
activitéPrincipale: api.activite_principale,
|
||||
})
|
|
@ -44,7 +44,6 @@ const établissementAdapter = (
|
|||
),
|
||||
adresse: {
|
||||
complète: fabriqueSocialEtablissement.address,
|
||||
codePostal: fabriqueSocialEtablissement.codePostalEtablissement,
|
||||
codeCommune: fabriqueSocialEtablissement.codeCommuneEtablissement,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -51,7 +51,7 @@ export default function EntrepriseSearchDetails({
|
|||
</>
|
||||
)}
|
||||
<br />
|
||||
<Trans>Établissement recherché:</Trans>{' '}
|
||||
<Trans>Établissement recherché :</Trans>{' '}
|
||||
<Strong>{établissement?.adresse.complète}</Strong>
|
||||
</CompanyContainer>
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createContext } from 'react'
|
||||
|
||||
import { FabriqueSocialEntreprisesRepository } from '@/api/RechercheEntreprise/fabrique-social'
|
||||
import { RechercheEntreprisesGouvFr } from '@/api/RechercheEntreprise/RechercheEntreprisesGouvFr'
|
||||
import { EntreprisesRepository } from '@/domain/EntreprisesRepository'
|
||||
|
||||
interface Repositories {
|
||||
|
@ -8,5 +8,5 @@ interface Repositories {
|
|||
}
|
||||
|
||||
export const RepositoriesContext = createContext<Repositories>({
|
||||
entreprises: FabriqueSocialEntreprisesRepository,
|
||||
entreprises: RechercheEntreprisesGouvFr,
|
||||
})
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export interface Adresse {
|
||||
complète?: string
|
||||
codePostal: string
|
||||
codeCommune: string
|
||||
}
|
||||
|
|
|
@ -4,6 +4,13 @@ export type PublicodeDate =
|
|||
`${number}${number}/${number}${number}/${number}${number}${number}${number}`
|
||||
export const publicodesStandardDateFormat = 'dd/MM/yyyy'
|
||||
|
||||
/**
|
||||
* @example 2024-12-31
|
||||
*/
|
||||
export type IsoDate =
|
||||
`${number}${number}${number}${number}-${number}${number}-${number}${number}`
|
||||
export const isoDateFormat = 'yyyy-MM-dd'
|
||||
|
||||
type DateToPublicodeDate = (d: Date) => PublicodeDate
|
||||
|
||||
export const toPublicodeDate = format(
|
||||
|
@ -16,3 +23,5 @@ export const parsePublicodesDateString = parse(
|
|||
new Date(),
|
||||
publicodesStandardDateFormat
|
||||
) as PublicodeDateToDate
|
||||
|
||||
export const parseIsoDateString = parse(new Date(), isoDateFormat)
|
||||
|
|
|
@ -86,7 +86,6 @@ Coût de création: Cost of creation
|
|||
Dividendes nets: Net dividends
|
||||
Documentation: Documentation
|
||||
Documentation des simulateurs: Simulator documentation
|
||||
"Domiciliée à l'adresse :": "Domiciled at address :"
|
||||
Donner votre avis: Give your opinion
|
||||
Décrivez votre projet ou votre problème en donnant quelques éléments de contexte. Notre partenaire Place des Entreprises identifiera, parmi l’ensemble des partenaires publics et parapublics, le conseiller compétent pour votre demande. Celui-ci vous contactera par téléphone sous 5 jours et vous accompagnera en fonction de votre situation.:
|
||||
Describe your project or problem and provide some background information. Our
|
||||
|
@ -285,6 +284,7 @@ Simulateurs: Simulators
|
|||
Simulateurs et Assistants: Simulators and Assistants
|
||||
Simulation en cours: Simulation in progress
|
||||
Situation personnelle: Personal situation
|
||||
"Siège :": "Headquarters:"
|
||||
Soit <2><0></0></2> avant impôts: Or <2><0></0></2> before tax
|
||||
Statistiques: Statistics
|
||||
Statut du conjoint: Spouse's status
|
||||
|
@ -1721,6 +1721,7 @@ warning:
|
|||
À quoi servent mes cotisations ?: What are my contributions used for?
|
||||
Échanger avec un conseiller: Talk to an advisor
|
||||
Échec: Failure
|
||||
"Établissement recherché :": "Establishment sought :"
|
||||
Étape complétée: Step completed
|
||||
Étape non complétée: Step not completed
|
||||
Étape {{ total }} sur {{ maxValue }}: Step {{ total }} on {{ maxValue }}
|
||||
|
|
|
@ -91,7 +91,6 @@ Coût de création: Coût de création
|
|||
Dividendes nets: Dividendes nets
|
||||
Documentation: Documentation
|
||||
Documentation des simulateurs: Documentation des simulateurs
|
||||
"Domiciliée à l'adresse :": "Domiciliée à l'adresse :"
|
||||
Donner votre avis: Donner votre avis
|
||||
Décrivez votre projet ou votre problème en donnant quelques éléments de contexte. Notre partenaire Place des Entreprises identifiera, parmi l’ensemble des partenaires publics et parapublics, le conseiller compétent pour votre demande. Celui-ci vous contactera par téléphone sous 5 jours et vous accompagnera en fonction de votre situation.:
|
||||
Décrivez votre projet ou votre problème en donnant quelques éléments de
|
||||
|
@ -299,6 +298,7 @@ Simulateurs: Simulateurs
|
|||
Simulateurs et Assistants: Simulateurs et Assistants
|
||||
Simulation en cours: Simulation en cours
|
||||
Situation personnelle: Situation personnelle
|
||||
"Siège :": "Siège :"
|
||||
Soit <2><0></0></2> avant impôts: Soit <2><0></0></2> avant impôts
|
||||
Statistiques: Statistiques
|
||||
Statut du conjoint: Statut du conjoint
|
||||
|
@ -1827,6 +1827,7 @@ warning:
|
|||
À quoi servent mes cotisations ?: À quoi servent mes cotisations ?
|
||||
Échanger avec un conseiller: Échanger avec un conseiller
|
||||
Échec: Échec
|
||||
"Établissement recherché :": "Établissement recherché :"
|
||||
Étape complétée: Étape complétée
|
||||
Étape non complétée: Étape non complétée
|
||||
Étape {{ total }} sur {{ maxValue }}: Étape {{ total }} sur {{ maxValue }}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { FabriqueSocialEntreprise } from '@/api/fabrique-social'
|
||||
import { FabriqueSocialEntreprise } from '@/api/RechercheEntreprise/fabrique-social'
|
||||
|
||||
export const fabriqueSocialWithSiege: FabriqueSocialEntreprise = {
|
||||
activitePrincipale: 'Agences immobilières',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { fabriqueSocialEntrepriseAdapter } from '@/api/fabrique-social'
|
||||
import { fabriqueSocialEntrepriseAdapter } from '@/api/RechercheEntreprise/fabrique-social'
|
||||
|
||||
import {
|
||||
fabriqueSocialWithoutSiege,
|
||||
|
@ -15,16 +15,16 @@ describe('Fabrique Social', () => {
|
|||
)
|
||||
|
||||
it('retourne le siren', () => {
|
||||
expect(entreprise.siren).to.equal('849074190')
|
||||
expect(entreprise.siren).toBe('849074190')
|
||||
})
|
||||
|
||||
it("a l'établissement demandé dans 'établissement'", () => {
|
||||
expect(entreprise.siège?.adresse.complète).to.equal(
|
||||
expect(entreprise.siège?.adresse.complète).toBe(
|
||||
'23 RUE DE MOGADOR 75009 PARIS 9'
|
||||
)
|
||||
})
|
||||
it("a le siège dans 'siège'", () => {
|
||||
expect(entreprise.établissement.adresse.complète).to.equal(
|
||||
expect(entreprise.établissement.adresse.complète).toBe(
|
||||
'4 RUE VOLTAIRE 44000 NANTES'
|
||||
)
|
||||
})
|
||||
|
@ -35,10 +35,10 @@ describe('Fabrique Social', () => {
|
|||
)
|
||||
|
||||
it("n'a pas de siège", () => {
|
||||
expect(entreprise.siège?.adresse.complète).to.equal(undefined)
|
||||
expect(entreprise.siège?.adresse.complète).toBe(undefined)
|
||||
})
|
||||
it('a l’établissement demandé', () => {
|
||||
expect(entreprise.établissement.adresse.complète).to.equal(
|
||||
expect(entreprise.établissement.adresse.complète).toBe(
|
||||
'4 RUE VOLTAIRE 44000 NANTES'
|
||||
)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue