<?php
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../src/db.php';
require_once __DIR__ . '/../src/antispam.php';
final class AntispamTest extends TestCase {
    public function testHoneypotRempliDetecte(): void {
        $this->assertTrue(est_spam(['site_web' => 'http://spam.com']));
        $this->assertFalse(est_spam(['site_web' => '']));
    }
    public function testRateLimitTroisParHeure(): void {
        $pdo = db_test();
        for ($i = 0; $i < 3; $i++) { $this->assertFalse(ip_bloquee($pdo, '1.2.3.4')); journaliser_envoi($pdo, '1.2.3.4', true); }
        $this->assertTrue(ip_bloquee($pdo, '1.2.3.4'));
        $this->assertFalse(ip_bloquee($pdo, '5.6.7.8'));
    }
    public function testDoublonMemeTelephoneMemeFiliere(): void {
        $pdo = db_test();
        require_once __DIR__ . '/../src/filieres.php'; require_once __DIR__ . '/../src/candidatures.php';
        enregistrer_candidature($pdo, ['nom'=>'A','prenoms'=>'B','date_naissance'=>'2007-01-01','lieu_naissance'=>'K',
            'sexe'=>'M','nationalite'=>'CI','telephone'=>'0101010101','ville'=>'K','tuteur_nom'=>'T',
            'tuteur_telephone'=>'02','bac_serie'=>'D','bac_annee'=>'2026','etablissement_origine'=>'L','filiere1'=>'INFO'], 2026);
        $this->assertTrue(est_doublon($pdo, '0101010101', 'INFO'));
        $this->assertFalse(est_doublon($pdo, '0101010101', 'GES'));
    }
    private function candidatureMin(string $telephone): array {
        return ['nom'=>'A','prenoms'=>'B','date_naissance'=>'2007-01-01','lieu_naissance'=>'K',
            'sexe'=>'M','nationalite'=>'CI','telephone'=>$telephone,'ville'=>'K','tuteur_nom'=>'T',
            'tuteur_telephone'=>'0203040506','bac_serie'=>'D','bac_annee'=>'2026',
            'etablissement_origine'=>'L','filiere1'=>'INFO'];
    }
    // Revue Task 7 — fix 1 : champ honeypot non-chaîne (ex. site_web[]=x) = signal de bot, sans erreur fatale
    public function testHoneypotTableauDetecteSansErreurFatale(): void {
        $this->assertTrue(est_spam(['site_web' => ['x']]));
        $this->assertFalse(est_spam([]));
    }
    // Revue Task 7 — fix 2 : détection de doublon insensible aux espaces dans le téléphone
    public function testDoublonInsensibleAuxEspacesTelephone(): void {
        require_once __DIR__ . '/../src/filieres.php'; require_once __DIR__ . '/../src/candidatures.php';
        $pdo = db_test(); // stocké avec espaces, vérifié sans
        enregistrer_candidature($pdo, $this->candidatureMin('01 02 03 04 05'), 2026);
        $this->assertTrue(est_doublon($pdo, '0102030405', 'INFO'));
        $pdo2 = db_test(); // stocké sans espaces, vérifié avec
        enregistrer_candidature($pdo2, $this->candidatureMin('0102030405'), 2026);
        $this->assertTrue(est_doublon($pdo2, '01 02 03 04 05', 'INFO'));
        $this->assertFalse(est_doublon($pdo, '0999999999', 'INFO'));
    }
    // Revue Task 7 — fix 3 : la fenêtre glissante d'1 h exclut les envois plus anciens
    public function testRateLimitFenetreGlissanteExclutEnvoisAnciens(): void {
        $pdo = db_test();
        $pdo->exec("INSERT INTO envois_log (ip, ok, created_at) VALUES ('x', 1, datetime('now','-2 hour'))");
        journaliser_envoi($pdo, 'x', true);
        journaliser_envoi($pdo, 'x', true);
        $this->assertFalse(ip_bloquee($pdo, 'x')); // 2 dans la fenêtre, l'envoi de -2 h ne compte pas
        journaliser_envoi($pdo, 'x', true);
        $this->assertTrue(ip_bloquee($pdo, 'x'));  // 3 dans la fenêtre
    }
}
