Files
crm_ecosplay/tests/js/entreprise-search.test.js
Serreau Jovann a29e1d93f8 test: couverture JS 100% lignes + 100% fonctions (115 tests)
app.js : 100% lignes, 100% fonctions, 99.5% statements
- 3 tests prefill branches (fetch error, missing fields, hosting no fetch)

entreprise-search.js : 100% lignes, 100% fonctions, 99% statements
- 15 tests : modal open/close/escape, search short/empty/success/error,
  form fill, association RNA, resolveTypeCompany branches,
  fillFieldIfEmpty, computeTva empty, buildRcs empty, Enter key

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:21:56 +02:00

392 lines
17 KiB
JavaScript

import { describe, it, expect, beforeEach, vi } from 'vitest'
import { initEntrepriseSearch } from '../../assets/modules/entreprise-search.js'
describe('entreprise-search.js', () => {
beforeEach(() => {
document.body.innerHTML = ''
vi.restoreAllMocks()
})
it('does nothing without modal or openBtn', () => {
document.body.innerHTML = '<div></div>'
initEntrepriseSearch()
expect(true).toBe(true)
})
it('opens modal on openBtn click', () => {
document.body.innerHTML = `
<div id="modal-entreprise" class="hidden"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
initEntrepriseSearch()
document.getElementById('btn-search-entreprise').click()
expect(document.getElementById('modal-entreprise').classList.contains('hidden')).toBe(false)
})
it('closes modal on closeBtn click', () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
initEntrepriseSearch()
document.getElementById('modal-close').click()
expect(document.getElementById('modal-entreprise').classList.contains('hidden')).toBe(true)
})
it('closes modal on overlay click', () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
initEntrepriseSearch()
document.getElementById('modal-overlay').click()
expect(document.getElementById('modal-entreprise').classList.contains('hidden')).toBe(true)
})
it('closes modal on Escape key', () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
initEntrepriseSearch()
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))
expect(document.getElementById('modal-entreprise').classList.contains('hidden')).toBe(true)
})
it('does not search when query is too short', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="a">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
globalThis.fetch = vi.fn()
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
expect(globalThis.fetch).not.toHaveBeenCalled()
})
it('shows no results message', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="zzzzz">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
globalThis.fetch = vi.fn(() => Promise.resolve({ json: () => Promise.resolve({ results: [], total_results: 0 }) }))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
expect(document.getElementById('search-entreprise-status').textContent).toContain('Aucun resultat')
})
it('shows results and fills form on click', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="acme">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
<input id="raisonSociale">
<input id="siret">
<input id="rcs">
<input id="numTva">
<input id="ape">
<input id="address">
<input id="zipCode">
<input id="city">
<input id="geoLat">
<input id="geoLong">
<input id="typeCompany">
<input id="rna">
<input id="firstName">
<input id="lastName">
`
globalThis.fetch = vi.fn(() => Promise.resolve({
json: () => Promise.resolve({
results: [{
nom_raison_sociale: 'ACME SA',
nom_complet: 'ACME SA COMPLETE',
siren: '123456789',
etat_administratif: 'A',
activite_principale: '6201Z',
nature_juridique: '5710',
siege: {
siret: '12345678901234',
numero_voie: '42',
type_voie: 'rue',
libelle_voie: 'de la Paix',
code_postal: '75001',
libelle_commune: 'Paris',
geo_adresse: '42 rue de la Paix 75001 Paris',
latitude: '48.8',
longitude: '2.3',
},
dirigeants: [{ nom: 'DUPONT', prenoms: 'Jean Pierre' }],
complements: { identifiant_association: '' },
}],
total_results: 1,
})
}))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
const status = document.getElementById('search-entreprise-status')
expect(status.textContent).toContain('1 resultat(s)')
const results = document.getElementById('search-entreprise-results')
expect(results.innerHTML).toContain('ACME SA')
expect(results.innerHTML).toContain('Actif')
// Click to fill form
results.querySelector('div').click()
expect(document.getElementById('raisonSociale').value).toBe('ACME SA')
expect(document.getElementById('siret').value).toBe('12345678901234')
expect(document.getElementById('numTva').value).toContain('FR')
expect(document.getElementById('ape').value).toBe('6201Z')
expect(document.getElementById('address').value).toBe('42 rue de la Paix')
expect(document.getElementById('zipCode').value).toBe('75001')
expect(document.getElementById('city').value).toBe('Paris')
expect(document.getElementById('typeCompany').value).toBe('sas')
expect(document.getElementById('firstName').value).toBe('Jean')
expect(document.getElementById('lastName').value).toBe('Dupont')
})
it('handles association type with RNA', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="asso">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
<input id="raisonSociale">
<input id="typeCompany">
<input id="rna">
`
globalThis.fetch = vi.fn(() => Promise.resolve({
json: () => Promise.resolve({
results: [{
nom_complet: 'Asso Test',
siren: '999888777',
etat_administratif: 'C',
nature_juridique: '9220',
siege: {},
complements: { identifiant_association: 'W123456789' },
}],
total_results: 1,
})
}))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
const results = document.getElementById('search-entreprise-results')
expect(results.innerHTML).toContain('Association')
expect(results.innerHTML).toContain('Ferme')
expect(results.innerHTML).toContain('W123456789')
results.querySelector('div').click()
expect(document.getElementById('rna').value).toBe('W123456789')
expect(document.getElementById('typeCompany').value).toBe('association')
})
it('handles fetch error', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="fail">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
globalThis.fetch = vi.fn(() => Promise.reject(new Error('Network fail')))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
expect(document.getElementById('search-entreprise-status').textContent).toContain('Erreur')
})
it('Enter key triggers search', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="test">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
`
globalThis.fetch = vi.fn(() => Promise.resolve({ json: () => Promise.resolve({ results: [], total_results: 0 }) }))
initEntrepriseSearch()
document.getElementById('search-entreprise-input').dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true }))
await new Promise(r => setTimeout(r, 100))
expect(globalThis.fetch).toHaveBeenCalled()
})
it('covers resolveTypeCompany branches', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="multi">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
<input id="typeCompany">
`
const types = [
{ code: '1000', expected: 'auto-entrepreneur' },
{ code: '5400', expected: 'sarl' },
{ code: '5599', expected: 'sarl' }, // 55xx matches sarl before sa check
{ code: '5200', expected: 'eurl' },
{ code: '6500', expected: 'sci' },
{ code: '9999', expected: '' },
]
for (const { code, expected } of types) {
globalThis.fetch = vi.fn(() => Promise.resolve({
json: () => Promise.resolve({
results: [{ nom_complet: 'Test', siren: '111', nature_juridique: code, siege: {} }],
total_results: 1,
})
}))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
const results = document.getElementById('search-entreprise-results')
results.querySelector('div').click()
const typeVal = document.getElementById('typeCompany').value
if (expected) {
expect(typeVal).toBe(expected)
}
document.getElementById('typeCompany').value = ''
}
})
it('fillFieldIfEmpty does not overwrite existing value', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="pre">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
<input id="firstName" value="Existing">
<input id="lastName">
`
globalThis.fetch = vi.fn(() => Promise.resolve({
json: () => Promise.resolve({
results: [{ nom_complet: 'Test', siren: '111', siege: {}, dirigeants: [{ nom: 'NEW', prenoms: 'Name' }] }],
total_results: 1,
})
}))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
document.getElementById('search-entreprise-results').querySelector('div').click()
expect(document.getElementById('firstName').value).toBe('Existing')
expect(document.getElementById('lastName').value).toBe('New')
})
it('computeTva returns empty for falsy siren', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="no-siren">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
<input id="numTva">
`
globalThis.fetch = vi.fn(() => Promise.resolve({
json: () => Promise.resolve({
results: [{ nom_complet: 'No Siren', siege: {} }],
total_results: 1,
})
}))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
document.getElementById('search-entreprise-results').querySelector('div').click()
expect(document.getElementById('numTva').value).toBe('')
})
it('buildRcs returns empty when no siren or city', async () => {
document.body.innerHTML = `
<div id="modal-entreprise"></div>
<div id="modal-overlay"></div>
<button id="modal-close"></button>
<button id="btn-search-entreprise"></button>
<input id="search-entreprise-input" value="norcs">
<button id="search-entreprise-btn"></button>
<div id="search-entreprise-results"></div>
<div id="search-entreprise-status" class="hidden"></div>
<input id="rcs">
`
globalThis.fetch = vi.fn(() => Promise.resolve({
json: () => Promise.resolve({
results: [{ nom_complet: 'No RCS', siege: {} }],
total_results: 1,
})
}))
initEntrepriseSearch()
document.getElementById('search-entreprise-btn').click()
await new Promise(r => setTimeout(r, 100))
document.getElementById('search-entreprise-results').querySelector('div').click()
expect(document.getElementById('rcs').value).toBe('')
})
})