# Plan de Tests — Application Laravel (Unified)

> Plateforme multi-tenant de gestion d'événements, inscriptions, hébergements, votes et communications.
> Ce document liste tous les tests unitaires et E2E à implémenter progressivement.
> Cocher chaque test au fur et à mesure de l'implémentation.

---

## Légende

- `[ ]` À implémenter
- `[x]` Implémenté
- `[~]` Partiel / en cours

---

## 1. Tests Unitaires — Services (`tests/Unit/Services/`)

### ParticipantRegistrationService — `tests/Unit/Services/ParticipantRegistrationServiceTest.php`

- [x] `fill_congressiste_fields_avec_request_laravel`
- [x] `fill_congressiste_fields_avec_stdclass`
- [x] `fill_congressiste_fields_champs_vides_donnent_zero`
- [x] `fill_non_congressiste_nettoie_payment_fields`
- [x] `fill_non_congressiste_cree_sponsor_si_other_exposant`
- [x] `fill_non_congressiste_ne_duplique_pas_sponsor_existant`
- [x] `fill_non_congressiste_sans_other_exposant_ne_cree_pas_sponsor`
- [x] `genere_code_pre_inscription_format_correct`
- [x] `genere_codes_pre_inscription_incrementaux`
- [x] `genere_code_pre_inscription_incremente_compteur_event`
- [x] `genere_code_participation_format_correct`
- [x] `genere_codes_participation_incrementaux`
- [x] `genere_code_participation_incremente_compteur_event`
- [x] `process_attachments_stocke_fichiers`
- [x] `process_attachments_sans_fichier_ne_modifie_pas_participant`

### WorkshopPricingService — `tests/Unit/Services/WorkshopPricingServiceTest.php`

- [x] `process_workshops_parse_format_id_pipe_prix`
- [x] `process_workshops_cumule_prix_plusieurs_ateliers`
- [x] `process_workshops_supprime_ateliers_deselectionnees`
- [x] `process_workshops_detecte_atelier_adhesion2`
- [x] `process_workshops_retourne_is_fee_zero_sans_adhesion2`
- [x] `process_workshops_liste_vide_retourne_zero`
- [x] `process_workshops_ignore_entree_vide`
- [x] `tiered_pricing_sans_event_concerne_retourne_total_inchange`
- [x] `tiered_pricing_event_13jmfm_un_atelier_formation`
- [x] `tiered_pricing_event_13jmfm_deux_ateliers_formation`
- [x] `tiered_pricing_event_13jmfm_trois_ateliers_formation`
- [x] `tiered_pricing_ateliers_non_formation_non_affectes`
- [x] `sync_multi_use_workshop_introuvable_retourne_zero`
- [x] `sync_multi_use_workshop_non_multi_use_retourne_zero`
- [x] `sync_multi_use_sans_ligne_existante_retourne_zero`
- [x] `sync_multi_use_ajoute_lignes_manquantes`
- [x] `sync_multi_use_clamp_extra_qty_au_max`

### PaymentService — `tests/Unit/Services/PaymentServiceTest.php`

- [x] `fill_for_validation_self_payer_virement`
- [x] `fill_for_validation_self_payer_espece`
- [x] `fill_for_validation_sans_toggle_ne_copie_pas_groupe`
- [x] `fill_for_validation_bon_de_commande`
- [x] `fill_for_validation_prise_en_charge_utilise_other_organisme`
- [x] `fill_for_validation_prise_en_charge_fallback_organisme`
- [x] `fill_for_validation_adhesion_virement`
- [x] `fill_for_validation_adhesion_espece_nullifie_onhold_validated_by`
- [x] `fill_for_validation_adhesion_onhold_stocke_validated_by`
- [x] `fill_for_validation_nettoie_payment_fields_avant_remplissage`
- [x] `fill_for_revalidation_copie_champs_sans_condition`
- [x] `fill_for_revalidation_copie_champs_adhesion`

### MagicLinkService — `tests/Unit/Services/MagicLinkServiceTest.php`

- [x] `genere_token_de_6_caracteres`
- [x] `genere_token_uniquement_alphanum`
- [x] `genere_token_persiste_en_base`
- [x] `reutilise_token_existant_pour_meme_email`
- [x] `genere_tokens_differents_pour_emails_differents`
- [x] `resout_email_a_partir_du_token`
- [x] `retourne_null_pour_token_inconnu`
- [x] `token_genere_est_resolvable`

### AccessCodeService

- [x] `genere_codes_uniques_pour_election`
- [x] `valide_code_existant`
- [x] `refuse_code_deja_utilise`
- [x] `refuse_code_inconnu`

### VoteValidationService

- [x] `accepte_vote_avec_code_valide`
- [x] `refuse_double_vote`
- [x] `refuse_vote_election_fermee`
- [x] `agregat_resultats_correct`

### UserService

- [x] `cree_utilisateur_avec_metas`
- [x] `mise_a_jour_metas_utilisateur`
- [x] `envoi_credentials_par_email`

### SystemEmailLogService

- [x] `enregistre_email_envoye`
- [x] `marque_email_ouvert_via_tracking`
- [x] `marque_lien_clique_via_tracking`

---

## 2. Tests Unitaires — Modèles (`tests/Unit/Models/`)

### User

- [x] `relation_participants`
- [x] `relation_roles`
- [x] `scope_par_domaine`
- [x] `participant_pour_evenement_donne`

### Event

- [x] `relation_participants`
- [x] `relation_workshops`
- [x] `relation_hotels`
- [x] `relation_forms`
- [x] `evenement_ferme_si_flag_closed`
- [x] `evenement_visible_si_flag_visible`
- [x] `cache_invalide_apres_modification`

### Participant

- [x] `relation_user`
- [x] `relation_event`
- [x] `relation_workshops`
- [x] `relation_metas`
- [x] `est_valide`
- [x] `est_present`
- [x] `prix_total_calcule`

### Workshop

- [x] `relation_event`
- [x] `relation_participants`
- [x] `capacite_disponible`
- [x] `atelier_complet_si_capacite_atteinte`

### Form

- [x] `relation_fields_ordonnes`
- [x] `relation_responses`
- [x] `max_reponses_par_utilisateur_respecte`

### Campaign

- [x] `relation_recipients`
- [x] `relation_email_logs`
- [x] `relation_template`
- [x] `duplication_cree_nouvelle_campagne`

### Election

- [x] `relation_candidates`
- [x] `relation_votes`
- [x] `relation_access_codes`
- [x] `resultats_agrege_correctement`

### Reservation

- [x] `relation_hotel`
- [x] `relation_room_reservations`
- [x] `statut_checkin_tracke`
- [x] `voucher_genere`

---

## 3. Tests Feature — Authentification (`tests/Feature/Auth/`)

### Login — `tests/Feature/Backend/Auth/LoginTest.php`

- [x] `connexion_avec_email_password_valides`
- [x] `echec_avec_mauvais_password`
- [x] `echec_email_inconnu`
- [x] `email_requis`
- [x] `password_requis`
- [x] `format_email_invalide`
- [x] `connexion_met_a_jour_last_login_at`
- [x] `connexion_met_a_jour_last_login_ip`
- [x] `brute_force_bloque_apres_5_tentatives`
- [x] `logout_deauthentifie_utilisateur`
- [x] `redirection_apres_connexion_admin`
- [x] `redirection_apres_connexion_frontend`
- [x] `multi_domaine_redirige_correctement`

### Register

- [x] `inscription_avec_donnees_valides`
- [x] `echec_si_email_deja_utilise`
- [x] `validation_champs_requis`

### Magic Link

- [x] `envoi_lien_magique_par_email`
- [x] `connexion_via_lien_magique_valide`
- [x] `echec_lien_expire`
- [x] `echec_lien_deja_utilise`

### Autorisation par rôle

- [x] `admin_acces_backend`
- [x] `utilisateur_normal_bloque_backend`
- [x] `impersonation_admin_vers_user`
- [x] `arret_impersonation`
- [x] `permissions_spatie_respectees`

---

## 4. Tests Feature — Backend Admin (`tests/Feature/Backend/`)

### EventController — `tests/Feature/Backend/EventControllerTest.php`

- [x] `liste_events_retourne_200`
- [x] `liste_events_redirige_si_non_connecte`
- [x] `creation_event_persiste_en_base`
- [x] `creation_event_redirige_vers_edit`
- [x] `creation_event_echoue_sans_titre`
- [x] `creation_event_echoue_slug_duplique`
- [x] `modification_event_met_a_jour_en_base`
- [x] `modification_event_echoue_sans_bo_title`
- [x] `suppression_event_retire_de_la_base`
- [x] `suppression_redirige_vers_liste`
- [x] `duplication_cree_nouvel_event`
- [x] `duplication_met_is_active_a_zero`
- [x] `duplication_slug_unique_si_copie_existe`
- [x] `gestion_paiements_event`
- [x] `gestion_organismes_event`

### ParticipantController — `tests/Feature/Backend/ParticipantControllerTest.php`

- [x] `liste_participants_retourne_200`
- [x] `liste_participants_redirige_si_non_connecte`
- [x] `api_participants_retourne_json`
- [x] `api_participants_retourne_uniquement_ceux_de_levent`
- [x] `recherche_utilisateurs_retourne_json`
- [x] `suppression_participant_retire_de_la_base`
- [x] `suppression_participant_via_ajax_retourne_json`
- [x] `marquer_present_met_is_present_a_1`
- [x] `marquer_present_via_ajax_retourne_json`
- [x] `marquer_absent_met_is_present_a_0`
- [x] `invalider_participant_efface_le_code`
- [x] `invalider_participant_via_ajax_retourne_json`
- [x] `ajout_participant_manuel`
- [x] `validation_participant`
- [x] `reprise_participant`

### WorkshopController

- [x] `liste_ateliers_par_event`
- [x] `modification_atelier`
- [x] `toggle_presence_atelier`

### HebergementController

- [x] `liste_hebergements`
- [x] `ajout_hebergement`
- [x] `validation_hebergement`
- [x] `checkin_hebergement`
- [x] `uncheckin_hebergement`
- [x] `voucher_hebergement`
- [x] `reprise_hebergement`

### ReservationController

- [x] `liste_reservations`
- [x] `validation_reservation`
- [x] `invalidation_reservation`
- [x] `checkin_reservation`
- [x] `undo_checkin`
- [x] `voucher_reservation`

### FormController

- [x] `creation_formulaire`
- [x] `modification_formulaire`
- [x] `liste_reponses`
- [x] `modification_reponse`
- [x] `suppression_reponse`

### CampaignController

- [x] `creation_campagne`
- [x] `preview_campagne`
- [x] `envoi_campagne`
- [x] `duplication_campagne`
- [x] `export_campagne`
- [x] `gestion_recipients`

### SmsCampaignController

- [x] `estimation_sms`
- [x] `envoi_sms_campagne`
- [x] `duplication_sms_campagne`

### ElectionController

- [x] `creation_election`
- [x] `gestion_candidats`
- [x] `generation_codes_acces`
- [x] `reset_votes`

### AccountController

- [x] `creation_compte`
- [x] `liste_comptes`
- [x] `modification_compte`
- [x] `envoi_credentials`
- [x] `impersonation_depuis_compte`

### ImportController

- [x] `import_utilisateurs_csv`
- [x] `import_participants_csv`
- [x] `import_presences_csv`
- [x] `import_attestations_csv`
- [x] `import_hebergements_csv`
- [x] `import_ateliers_csv`
- [x] `import_sponsors_csv`
- [x] `erreur_fichier_invalide`
- [x] `erreur_colonnes_manquantes`

### BadgeTemplateController

- [x] `creation_template_badge`
- [x] `preview_badge`
- [x] `generation_massive_badges`

### AbstController

- [x] `soumission_abstract`
- [x] `review_abstract`
- [x] `acceptation_abstract`
- [x] `rejet_abstract`

---

## 5. Tests Feature — Frontend (`tests/Feature/Frontend/`)

### Flux d'inscription en plusieurs étapes

- [x] `etape1_informations_personnelles`
- [x] `etape2_choix_categorie`
- [x] `etape3_selection_ateliers`
- [x] `etape4_informations_complementaires`
- [x] `etape5_formulaire_dynamique`
- [x] `etape6_recapitulatif`
- [x] `etape7_paiement_ou_confirmation`
- [x] `reprise_inscription_existante`
- [x] `mise_a_jour_inscription_step1_a_7`

### Flux de réservation hôtel

- [x] `choix_evenement`
- [x] `choix_hotel`
- [x] `choix_details_chambre`
- [x] `ajout_accompagnants`
- [x] `contact_reservation`
- [x] `recapitulatif_reservation`
- [x] `confirmation_reservation`
- [x] `page_succes`

### Paiements Frontend

- [x] `initier_paiement_flouci`
- [x] `callback_succes_flouci`
- [x] `callback_echec_flouci`
- [x] `webhook_paiement_inscription`
- [x] `webhook_paiement_show`

### Formulaires dynamiques

- [x] `affichage_formulaire_public`
- [x] `soumission_formulaire_authentifie`
- [x] `soumission_formulaire_sans_auth_si_permis`
- [x] `limite_reponses_par_utilisateur`

### Abstracts Frontend

- [x] `soumission_abstract_frontend`
- [x] `affichage_abstract_soumis`

### Profil Utilisateur

- [x] `affichage_profil`
- [x] `modification_profil`
- [x] `tableau_de_bord_inscriptions`
- [x] `telechargement_attestation`

### Désinscription Newsletter

- [x] `desinscription_via_lien`
- [x] `confirmation_desinscription`

---

## 6. Tests API (`tests/Feature/Api/`)

### Elections API

- [x] `GET /api/elections/{slug}` — récupérer détails élection
- [x] `GET /api/elections/{slug}/results` — résultats en temps réel
- [x] `POST /api/elections/{slug}/vote` — voter avec code valide
- [x] `POST /api/elections/{slug}/vote` — refus code invalide
- [x] `POST /api/elections/{slug}/vote` — refus double vote

### KEA Registration API

- [x] `GET /api/31cnlci/test` — endpoint de test
- [x] `GET /api/31cnlci/hotels` — liste hôtels
- [x] `POST /api/31cnlci/register` — inscription KEA

### API interne (web routes)

- [x] `GET /api/v2/participants/{event}` — liste participants
- [x] `GET /api/v2/search-users/{id}` — recherche utilisateurs
- [x] `GET /api/room-reservations/{event}` — réservations chambres

---

## 7. Tests E2E — Laravel Dusk (`tests/Browser/`)

> Nécessite `php artisan dusk:install` et une configuration ChromeDriver.

### Flux Utilisateur Complet

- [ ] **RegistrationFlow** — Inscription complète (étapes 1 à 7) avec paiement simulé
- [ ] **ProfileUpdateFlow** — Mise à jour profil utilisateur
- [ ] **HotelReservationFlow** — Réservation hôtel complète (choix → confirmation)
- [ ] **AbstractSubmissionFlow** — Soumission et suivi d'un abstract
- [ ] **FormSubmissionFlow** — Remplissage et soumission formulaire dynamique
- [ ] **MagicLinkLoginFlow** — Connexion via lien magique (email → session)

### Flux Administrateur

- [ ] **AdminEventManagementFlow** — Créer/modifier/supprimer un événement
- [ ] **AdminParticipantValidationFlow** — Valider / marquer présent un participant
- [ ] **AdminCampaignSendFlow** — Créer et envoyer une campagne email
- [ ] **AdminBadgeGenerationFlow** — Générer badges en masse
- [ ] **AdminImportParticipantsFlow** — Importer participants via CSV
- [ ] **AdminElectionFlow** — Créer élection, codes, voter, voir résultats
- [ ] **AdminReservationCheckinFlow** — Check-in réservation hôtel

### Flux de Vote

- [ ] **VotingFlow** — Accéder à une élection, saisir code, voter, voir résultats

---

## 8. Priorité d'Implémentation Recommandée

### Phase 1 — Fondations (commencer ici)

1. `Unit/Services/ParticipantRegistrationServiceTest`
2. `Unit/Services/WorkshopPricingServiceTest`
3. `Unit/Services/PaymentServiceTest`
4. `Feature/Auth/LoginTest`
5. `Feature/Auth/MagicLinkTest`

### Phase 2 — Cœur métier

6. `Feature/Backend/EventControllerTest`
7. `Feature/Backend/ParticipantControllerTest`
8. `Feature/Frontend/RegistrationFlowTest` (étapes 1-7)
9. `Feature/Api/ElectionApiTest`

### Phase 3 — Fonctionnalités avancées

10. `Feature/Backend/ImportControllerTest`
11. `Feature/Backend/CampaignControllerTest`
12. `Feature/Frontend/ReservationFlowTest`
13. `Feature/Frontend/PaymentTest`

### Phase 4 — E2E (une fois les features stables)

14. `Browser/RegistrationFlow`
15. `Browser/AdminEventManagementFlow`
16. `Browser/VotingFlow`

---

## 9. Configuration de l'environnement de test

```bash
# Fichier .env.testing à créer
APP_ENV=testing
DB_CONNECTION=sqlite
DB_DATABASE=:memory:

# Ou avec MySQL dédié
DB_DATABASE=unified_test

# Lancer les tests
php artisan test
php artisan test --filter=ParticipantRegistrationServiceTest

# E2E avec Dusk
php artisan dusk
php artisan dusk --filter=RegistrationFlow
```

### Traits et helpers utiles

- `RefreshDatabase` — reset DB entre chaque test
- `WithFaker` — données factices
- `actingAs($user)` — simuler utilisateur connecté
- `actingAs($user, 'web')` — pour les routes web multi-domaine
- Factories à créer : `UserFactory`, `EventFactory`, `ParticipantFactory`, etc.

---

*Dernière mise à jour : 2026-05-05 — Phases 1, 2, 3, API et Frontend complètes (~280 tests)*
