100 lines
4.1 KiB
PHP
100 lines
4.1 KiB
PHP
|
|
<?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();
|
|||
|
|
});
|