Paillasse/portail/tests/Feature/PurgeRgpdTest.php

100 lines
4.1 KiB
PHP
Raw Permalink Normal View History

<?php
use App\Models\Classe;
use App\Models\Correction;
use App\Models\Eleve;
use App\Models\Lab;
use App\Models\LabSession;
use App\Models\LabSessionMachine;
use App\Models\Seance;
use App\Models\User;
/**
* Une classe complète : 2 élèves, une séance, une session de lab terminée
* avec une machine et une correction.
*/
function classeComplete(?int $archiveeIlYaJours): Classe
{
$classe = Classe::factory()->create();
if ($archiveeIlYaJours !== null) {
$classe->forceFill(['archivee_a' => now()->subDays($archiveeIlYaJours)])->save();
}
$eleves = Eleve::factory()->count(2)->create(['classe_id' => $classe->id]);
$lab = Lab::factory()->create();
$seance = Seance::create(['classe_id' => $classe->id, 'lab_id' => $lab->id, 'statut' => Seance::TERMINEE]);
$session = LabSession::create(['seance_id' => $seance->id, 'eleve_id' => $eleves[0]->id, 'lab_id' => $lab->id, 'etat' => LabSession::EXPIRE]);
$session->machines()->create(['nom' => 'pc-a', 'instance_id' => 'uuid-a']);
$session->corrections()->create(['reussi' => true, 'note' => 10, 'note_max' => 10, 'details' => []]);
return $classe;
}
test('la purge supprime une classe archivée depuis plus de 90 jours et toutes les données de ses élèves', function () {
$classe = classeComplete(91);
$prof = $classe->prof;
$this->artisan('classes:purger-archivees')->expectsOutput('1 classe(s) purgée(s).')->assertSuccessful();
expect(Classe::find($classe->id))->toBeNull()
->and(Eleve::where('classe_id', $classe->id)->count())->toBe(0)
->and(Seance::where('classe_id', $classe->id)->count())->toBe(0)
->and(LabSession::count())->toBe(0)
->and(LabSessionMachine::count())->toBe(0)
->and(Correction::count())->toBe(0)
// Le compte du prof n'est pas une donnée d'élève : il reste.
->and(User::find($prof->id))->not->toBeNull();
});
test('la purge épargne les classes archivées depuis moins de 90 jours et les classes en cours', function () {
$recente = classeComplete(89);
$enCours = classeComplete(null);
$this->artisan('classes:purger-archivees')->expectsOutput('0 classe(s) purgée(s).');
expect(Classe::find($recente->id))->not->toBeNull()
->and(Classe::find($enCours->id))->not->toBeNull()
->and(Eleve::count())->toBe(4)
->and(Correction::count())->toBe(2);
});
test('la purge ne touche qu’aux classes concernées', function () {
$aPurger = classeComplete(120);
$aGarder = classeComplete(null);
$this->artisan('classes:purger-archivees');
expect(Classe::pluck('id')->all())->toBe([$aGarder->id])
->and(Eleve::pluck('classe_id')->unique()->all())->toBe([$aGarder->id]);
});
test('un prof archive sa classe : plus de séance possible, date de suppression annoncée', function () {
$classe = classeComplete(null);
$prof = $classe->prof;
$jeton = $prof->demarreNouvelleSession();
$connecte = fn () => $this->withSession(['jeton_session_web' => $jeton])->actingAs($prof, 'web');
$connecte()->post(route('mes-classes.archiver', $classe))->assertRedirect(route('mes-classes.show', $classe));
$classe->refresh();
expect($classe->estArchivee())->toBeTrue()
->and($classe->supprimeeLe()->toDateString())->toBe(now()->addDays(90)->toDateString());
$connecte()->get(route('mes-classes.show', $classe))
->assertSee('Classe archivée')
->assertSee($classe->supprimeeLe()->timezone(config('app.fuseau_utilisateurs'))->format('d/m/Y'));
$connecte()->post(route('mes-classes.seances.store', $classe), ['lab_id' => Lab::first()->id])->assertSessionHasErrors('prevue_a');
expect(Seance::where('classe_id', $classe->id)->where('statut', '!=', Seance::TERMINEE)->count())->toBe(0);
});
test('un autre prof ne peut pas archiver la classe', function () {
$classe = classeComplete(null);
$intrus = User::factory()->create();
$jeton = $intrus->demarreNouvelleSession();
$this->withSession(['jeton_session_web' => $jeton])->actingAs($intrus, 'web')
->post(route('mes-classes.archiver', $classe))->assertForbidden();
expect($classe->refresh()->estArchivee())->toBeFalse();
});