Files
Starseed/frontend/shared/utils/__tests__/httpExternal.test.ts
T
tristan 912280d24e
Auto Tag Develop / tag (push) Successful in 7s
feat(front) : util httpExternal + autocomplete adresse BAN (ERP-66) (#52)
## ERP-66 — Utilitaires adresse/téléphone + autocomplétion BAN

### feat
- **httpExternal** : client dédié aux API publiques externes (URL absolue, sans cookie de session, timeout). Seul point d'entrée autorisé pour un `$fetch` externe (règle frontend n°4).
- **useAddressAutocomplete** : implémentation BAN (api-adresse.data.gouv.fr) — recherche ville (`type=municipality`) et adresse, mapping GeoJSON, throw en cas d'erreur/timeout (mode dégradé côté composant). La recherche d'adresse n'impose **pas** `type=housenumber` (sinon 0 résultat tant qu'aucun numéro n'est saisi) — spec-front mise à jour.
- Tests Vitest : httpExternal, useAddressAutocomplete, cas limites `formatPhoneFR`.

### fix
- **ClientAddressBlock** : la rue courante est toujours réinjectée dans les options de `MalioInputAutocomplete` (computed, miroir de `cityOptions`). Corrige le champ Adresse qui se vidait après validation / à l'édition d'une adresse existante (valeur pourtant persistée). Test de montage ajouté.
- **useClientReferentials** : libellé des sites = numéro de département (2 premiers chiffres du code postal, déjà exposé par `/sites`) au lieu du nom.

### Vérifs
- ESLint  · Vitest 196/196 
- Changements 100% frontend (+ doc spec).

Reviewed-on: #52
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
2026-06-03 14:02:14 +00:00

57 lines
1.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { httpExternal } from '../httpExternal'
// On mocke ofetch : httpExternal s'appuie sur $fetch sans jamais toucher le
// reseau pendant les tests. vi.mock est hoiste par Vitest au-dessus des imports.
const mockFetch = vi.hoisted(() => vi.fn())
vi.mock('ofetch', () => ({ $fetch: mockFetch }))
describe('httpExternal', () => {
beforeEach(() => {
mockFetch.mockReset()
})
it('retourne le JSON parse renvoye par $fetch', async () => {
mockFetch.mockResolvedValueOnce({ ok: true })
const res = await httpExternal<{ ok: boolean }>('https://example.test/api')
expect(res).toEqual({ ok: true })
})
it('transmet la query, coupe le cookie (credentials omit) et pose un timeout par defaut', async () => {
mockFetch.mockResolvedValueOnce([])
await httpExternal('https://example.test/search', {
query: { q: '80000', type: 'municipality' },
})
expect(mockFetch).toHaveBeenCalledWith(
'https://example.test/search',
expect.objectContaining({
query: { q: '80000', type: 'municipality' },
credentials: 'omit',
retry: 0,
timeout: 5000,
}),
)
})
it('permet de surcharger le timeout', async () => {
mockFetch.mockResolvedValueOnce(null)
await httpExternal('https://example.test', { timeoutMs: 1000 })
expect(mockFetch).toHaveBeenCalledWith(
'https://example.test',
expect.objectContaining({ timeout: 1000 }),
)
})
it('propage l\'erreur reseau / timeout (throw)', async () => {
mockFetch.mockRejectedValueOnce(new Error('network down'))
await expect(httpExternal('https://example.test')).rejects.toThrow('network down')
})
})