L'import manuel élève par élève est fastidieux pour les établissements qui gèrent des centaines d'élèves. Un wizard d'import en 4 étapes (upload → mapping → preview → confirmation) permet de traiter un fichier complet en une seule opération, avec détection automatique du format (Pronote, École Directe) et validation avant import. L'import est traité de manière asynchrone via Messenger pour ne pas bloquer l'interface, avec suivi de progression en temps réel et réutilisation des mappings entre imports successifs.
107 lines
3.8 KiB
PHP
107 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Administration\Application\Service\Import;
|
|
|
|
use App\Administration\Application\Service\Import\ColumnMappingSuggester;
|
|
use App\Administration\Domain\Model\Import\KnownImportFormat;
|
|
use App\Administration\Domain\Model\Import\StudentImportField;
|
|
|
|
use function count;
|
|
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
use const SORT_REGULAR;
|
|
|
|
final class ColumnMappingSuggesterTest extends TestCase
|
|
{
|
|
private ColumnMappingSuggester $suggester;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->suggester = new ColumnMappingSuggester();
|
|
}
|
|
|
|
#[Test]
|
|
public function suggestPronoteMapping(): void
|
|
{
|
|
$columns = ['Élèves', 'Né(e) le', 'Sexe', 'Adresse E-mail', 'Classe de rattachement'];
|
|
|
|
$mapping = $this->suggester->suggerer($columns, KnownImportFormat::PRONOTE);
|
|
|
|
self::assertSame(StudentImportField::FULL_NAME, $mapping['Élèves']);
|
|
self::assertSame(StudentImportField::BIRTH_DATE, $mapping['Né(e) le']);
|
|
self::assertSame(StudentImportField::GENDER, $mapping['Sexe']);
|
|
self::assertSame(StudentImportField::EMAIL, $mapping['Adresse E-mail']);
|
|
self::assertSame(StudentImportField::CLASS_NAME, $mapping['Classe de rattachement']);
|
|
}
|
|
|
|
#[Test]
|
|
public function suggestEcoleDirecteMapping(): void
|
|
{
|
|
$columns = ['NOM', 'PRENOM', 'CLASSE', 'DATE_NAISSANCE', 'SEXE'];
|
|
|
|
$mapping = $this->suggester->suggerer($columns, KnownImportFormat::ECOLE_DIRECTE);
|
|
|
|
self::assertSame(StudentImportField::LAST_NAME, $mapping['NOM']);
|
|
self::assertSame(StudentImportField::FIRST_NAME, $mapping['PRENOM']);
|
|
self::assertSame(StudentImportField::CLASS_NAME, $mapping['CLASSE']);
|
|
self::assertSame(StudentImportField::BIRTH_DATE, $mapping['DATE_NAISSANCE']);
|
|
self::assertSame(StudentImportField::GENDER, $mapping['SEXE']);
|
|
}
|
|
|
|
#[Test]
|
|
public function suggestGenericMappingByKeywords(): void
|
|
{
|
|
$columns = ['Nom', 'Prénom', 'Classe', 'Email'];
|
|
|
|
$mapping = $this->suggester->suggerer($columns, KnownImportFormat::CUSTOM);
|
|
|
|
self::assertSame(StudentImportField::LAST_NAME, $mapping['Nom']);
|
|
self::assertSame(StudentImportField::FIRST_NAME, $mapping['Prénom']);
|
|
self::assertSame(StudentImportField::CLASS_NAME, $mapping['Classe']);
|
|
self::assertSame(StudentImportField::EMAIL, $mapping['Email']);
|
|
}
|
|
|
|
#[Test]
|
|
public function suggestDoesNotDuplicateFields(): void
|
|
{
|
|
$columns = ['Nom', 'Nom de famille', 'Prénom', 'Classe'];
|
|
|
|
$mapping = $this->suggester->suggerer($columns, KnownImportFormat::CUSTOM);
|
|
|
|
$mappedFields = array_values($mapping);
|
|
$uniqueFields = array_unique($mappedFields, SORT_REGULAR);
|
|
|
|
self::assertCount(count($uniqueFields), $mappedFields);
|
|
}
|
|
|
|
#[Test]
|
|
public function suggestHandlesUnknownColumns(): void
|
|
{
|
|
$columns = ['ColonneInconnue', 'AutreColonne', 'Nom', 'Classe'];
|
|
|
|
$mapping = $this->suggester->suggerer($columns, KnownImportFormat::CUSTOM);
|
|
|
|
self::assertArrayNotHasKey('ColonneInconnue', $mapping);
|
|
self::assertArrayNotHasKey('AutreColonne', $mapping);
|
|
self::assertArrayHasKey('Nom', $mapping);
|
|
self::assertArrayHasKey('Classe', $mapping);
|
|
}
|
|
|
|
#[Test]
|
|
public function suggestHandlesEnglishColumnNames(): void
|
|
{
|
|
$columns = ['Last Name', 'First Name', 'Class', 'Email'];
|
|
|
|
$mapping = $this->suggester->suggerer($columns, KnownImportFormat::CUSTOM);
|
|
|
|
self::assertSame(StudentImportField::LAST_NAME, $mapping['Last Name']);
|
|
self::assertSame(StudentImportField::FIRST_NAME, $mapping['First Name']);
|
|
self::assertSame(StudentImportField::CLASS_NAME, $mapping['Class']);
|
|
self::assertSame(StudentImportField::EMAIL, $mapping['Email']);
|
|
}
|
|
}
|