vendredi 25 septembre 2026

À propos

Contact

Tests

Tester wp_privacy_personal_data_exporters pour l’export RGPD

Une extension qui stocke des données personnelles doit déclarer un exportateur RGPD fonctionnel. Voici comment le vérifier automatiquement plutôt qu'à l'œil.

Par Clément Hadrot • 23 mars 2020 • 4 min de lecture • Aucun commentaire
Tester wp_privacy_personal_data_exporters pour l'export RGPD

Une extension de billetterie que nous maintenons stocke des numéros de téléphone et des préférences alimentaires liés à des commandes. Le jour où un client a exercé son droit d’accès RGPD, l’export généré par WordPress était vide. La fonction d’export existait bien dans le code, mais elle n’était jamais appelée : le filtre wp_privacy_personal_data_exporters pointait vers une méthode renommée lors d’un refactoring, sans qu’aucun test ne le détecte.

Ce genre de régression silencieuse justifie à elle seule d’écrire un test dédié à l’exportateur RGPD, séparé des tests fonctionnels classiques de l’extension.

Comprendre le contrat attendu par WordPress

Le cœur de WordPress construit la liste des exportateurs disponibles à partir du filtre wp_privacy_personal_data_exporters. Chaque entrée doit fournir un callback respectant une signature précise : recevoir un e-mail et un numéro de page, retourner un tableau avec les clés data, done. Chaque élément de data doit lui-même contenir group_id, group_label, item_id et data (un tableau de paires name/value).

add_filter('wp_privacy_personal_data_exporters', function ($exporters) {
    $exporters['billetterie-commandes'] = [
        'exporter_friendly_name' => __('Commandes de billetterie', 'billetterie'),
        'callback'               => 'billetterie_exporter_donnees',
    ];
    return $exporters;
});

Écrire le test d’intégration

Le test doit créer une commande réaliste rattachée à un e-mail connu, appeler le callback directement — sans passer par l’interface d’administration — puis vérifier la forme exacte du retour :

class Test_Export_RGPD_Billetterie extends WP_UnitTestCase {

    public function test_export_contient_les_champs_attendus(): void {
        $commande_id = $this->factory()->post->create([
            'post_type' => 'commande_billet',
        ]);
        update_post_meta($commande_id, '_email_client', 'julie@example.test');
        update_post_meta($commande_id, '_telephone', '0601020304');

        $resultat = billetterie_exporter_donnees('julie@example.test', 1);

        $this->assertArrayHasKey('data', $resultat);
        $this->assertArrayHasKey('done', $resultat);
        $this->assertTrue($resultat['done']);
        $this->assertNotEmpty($resultat['data']);

        $item = $resultat['data'][0];
        $this->assertSame('billetterie-commandes', $item['group_id']);
        $this->assertArrayHasKey('item_id', $item);
        $this->assertArrayHasKey('data', $item);
    }
}
L'essentiel à retenir : Déclarer un exportateur via le filtre officiel ; Vérifier la structure du tableau retourné ; Couvrir la pagination des gros volumes

Ce test aurait immédiatement échoué le jour du renommage de la méthode, avant même que le client ne s’en aperçoive.

Couvrir la pagination sur un gros volume

WordPress appelle l’exportateur page par page tant que done vaut false. Une extension qui traite mal la pagination — en renvoyant toujours la première page, par exemple — produit un export incomplet sans lever la moindre erreur visible. Il faut donc créer un volume de données dépassant la taille d’une page (souvent 500 lignes côté cœur, mais l’extension peut définir sa propre limite) et vérifier que plusieurs appels successifs couvrent bien l’ensemble sans doublon :

public function test_export_pagine_sans_doublon(): void {
    for ($i = 0; $i < 12; $i++) {
        $id = $this->factory()->post->create(['post_type' => 'commande_billet']);
        update_post_meta($id, '_email_client', 'gros-client@example.test');
    }

    $vus = [];
    $page = 1;
    do {
        $resultat = billetterie_exporter_donnees('gros-client@example.test', $page);
        foreach ($resultat['data'] as $item) {
            $vus[] = $item['item_id'];
        }
        $page++;
    } while (!$resultat['done']);

    $this->assertCount(12, array_unique($vus));
}

Vérifier aussi l’absence de données pour un e-mail inconnu

Un cas souvent oublié : que se passe-t-il quand l’e-mail demandé n’a jamais rien commandé ? L’exportateur doit renvoyer un tableau data vide et done à true, jamais une erreur PHP ni un null qui ferait planter l’outil natif de traitement des demandes RGPD :

  • Tester explicitement un e-mail sans aucune correspondance en base.
  • Vérifier que le type de retour reste un tableau bien formé, même vide.
  • S’assurer qu’aucune notice PHP n’est émise (utile depuis le passage à PHP 8, plus strict sur les accès aux tableaux).

Sur nos projets, l’exportateur RGPD est traité comme une fonctionnalité de production à part entière, avec sa propre suite de tests — pas comme une case à cocher ajoutée en fin de développement.

Pour aller plus loin

Un test unitaire ne remplace pas une vérification manuelle occasionnelle depuis Outils → Exporter les données personnelles dans l’administration, qui reste la meilleure façon de contrôler le rendu final du fichier envoyé à l’utilisateur. Mais automatiser la vérification du contrat de retour évite la régression la plus fréquente : un callback qui existe dans le code sans jamais être réellement branché au bon filtre. Ce point précis, une fois testé, élimine la classe d’incidents la plus embarrassante en matière de conformité — celle où l’on répond « nous exportons vos données » sans que ce soit vrai.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi