# Vérifier qu’un formulaire scolaire respecte un quota d’inscriptions par classe

> Écrire des tests d'intégration qui valident le blocage automatique dès qu'un quota d'inscriptions par classe est atteint, pour un client du secteur éducatif.

- Auteur : WordPress Développement
- Publié le : 2020-08-31
- Mis à jour le : 2020-08-31
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/quota-inscriptions-par-classe-tests-integration/

## L’essentiel

- Compteur d'inscriptions par classe en temps réel
- Blocage testé au niveau du serveur, pas du JavaScript
- Interface d'administration hors périmètre

Un quota qui se contrôle uniquement côté navigateur ne protège rien : un utilisateur qui désactive JavaScript, ou qui envoie directement une requête au point de terminaison REST, contourne n'importe quelle limite affichée dans un formulaire. Sur un module d'inscription scolaire, cette règle de quota par classe doit donc être vérifiée côté serveur, et testée comme telle.

Ce billet montre comment écrire des tests d'intégration qui simulent des inscriptions successives jusqu'à atteindre la limite fixée par l'établissement, puis vérifient que la trentième et unième tentative échoue proprement. L'interface d'administration qui permet de modifier ce quota n'entre pas dans le périmètre de ce billet.

## Où placer le contrôle de quota dans le code

La logique de blocage doit vivre dans une fonction unique, appelée systématiquement avant toute création d'inscription, qu'elle soit déclenchée par le formulaire public ou par un import en masse depuis l'administration. Centraliser ce contrôle évite qu'une nouvelle voie d'inscription, ajoutée plus tard, oublie de vérifier le quota.

```
function ecole_inscription_est_possible( $classe_id ) {
    $inscrits = get_posts( array(
        'post_type'   => 'inscription',
        'meta_key'    => 'classe_id',
        'meta_value'  => $classe_id,
        'post_status' => 'publish',
        'numberposts' => -1,
    ) );

    $quota = (int) get_post_meta( $classe_id, 'quota_places', true );

    return count( $inscrits ) < $quota;
}
```

## Simuler des inscriptions jusqu'au quota

Le test d'intégration crée d'abord une classe avec un quota volontairement faible, pour ne pas avoir à générer des dizaines d'inscriptions inutiles, puis remplit ce quota une inscription à la fois.

> L'essentiel à retenir : Compteur d'inscriptions par classe en temps réel ; Blocage testé au niveau du serveur, pas du JavaScript ; Interface d'administration hors périmètre

```
class Test_Quota_Inscriptions extends WP_UnitTestCase {

    public function test_inscription_refusee_au_dela_du_quota() {
        $classe_id = $this->factory->post->create( array(
            'post_type'  => 'classe',
            'meta_input' => array( 'quota_places' => 2 ),
        ) );

        $this->creer_inscription( $classe_id );
        $this->creer_inscription( $classe_id );

        $this->assertFalse( ecole_inscription_est_possible( $classe_id ) );
    }

    private function creer_inscription( $classe_id ) {
        return $this->factory->post->create( array(
            'post_type'  => 'inscription',
            'meta_input' => array( 'classe_id' => $classe_id ),
        ) );
    }
}
```

Un point mérite l'attention : le compteur doit s'appuyer sur le statut réel des inscriptions. Une inscription encore en brouillon, ou annulée, ne doit pas consommer une place du quota, ce qui suppose de filtrer sur `post_status => 'publish'` et pas sur l'ensemble des enregistrements.

## Tester les scénarios de concurrence

Deux familles inscrivent leur enfant à la même seconde sur la dernière place disponible : ce scénario de concurrence est le plus difficile à couvrir, et le plus révélateur d'un bug de quota mal conçu.

- Deux appels simultanés au point de terminaison REST d'inscription
- Vérification qu'une seule des deux inscriptions aboutit
- Vérification que la seconde reçoit un message d'erreur clair, pas une erreur serveur générique

### Verrouiller la création au niveau de la base

Sans verrou explicite, deux requêtes peuvent lire le même compteur avant qu'aucune des deux n'ait encore écrit sa propre inscription, et toutes deux passent le contrôle. Une transaction de base de données, ou à défaut un verrou applicatif via `wp_cache_add` avec une expiration courte, referme cette fenêtre de concurrence.

## Vérifier le message renvoyé au formulaire

Un quota atteint ne doit jamais se traduire par une erreur technique brute affichée à une famille. Le test vérifie que la réponse REST retourne un code d'erreur explicite et un message compréhensible.

```
public function test_message_erreur_quota_atteint() {
    $classe_id = $this->factory->post->create( array(
        'post_type'  => 'classe',
        'meta_input' => array( 'quota_places' => 0 ),
    ) );

    $reponse = ecole_inscrire( $classe_id, array( 'nom_enfant' => 'Test' ) );

    $this->assertWPError( $reponse );
    $this->assertSame( 'quota_atteint', $reponse->get_error_code() );
}
```

1. Créer une classe au quota déjà atteint
2. Tenter une inscription supplémentaire
3. Vérifier le code d'erreur et le message renvoyés à la famille

> Sur ce type de module, on a pris l'habitude de tester d'abord le scénario de concurrence : c'est celui qui révèle le plus vite un quota mal verrouillé, bien avant qu'un parent n'appelle l'établissement pour signaler le problème.

## En résumé

Un quota d'inscriptions par classe ne vaut que par son contrôle serveur, jamais par sa seule traduction visuelle dans le formulaire. Des tests d'intégration qui remplissent le quota, testent la concurrence et vérifient le message d'erreur couvrent l'essentiel des situations rencontrées sur ce type de module scolaire.
