withSession(['jeton_session_web' => $prof->demarreNouvelleSession()])->actingAs($prof, 'web');
}
test('un élève rejoint la classe avec son code ; le prof accepte ; l’élève voit son code une seule fois et peut se reconnecter', function () {
$classe = Classe::factory()->create();
$this->post(route('rejoindre.demander'), ['code' => strtolower($classe->code_classe), 'prenom' => 'Inès', 'nom' => 'Martin'])
->assertRedirect(route('rejoindre.attente'));
$this->get(route('rejoindre.attente'))->assertOk()->assertSee('Demande envoyée, Inès');
$this->getJson(route('rejoindre.etat'))->assertJson(['statut' => 'en_attente']);
$demande = DemandeInscription::sole();
commeProf($this, $classe->prof)->get(route('mes-classes.show', $classe))->assertSee('Inès Martin')->assertSee($classe->code_classe);
commeProf($this, $classe->prof)->post(route('mes-classes.demandes.accepter', [$classe, $demande]))->assertRedirect();
Auth::guard('web')->logout();
$this->getJson(route('rejoindre.etat'))->assertJson(['statut' => 'acceptee']);
$page = $this->get(route('rejoindre.bienvenue'))->assertOk()->assertSee('ines.m');
preg_match('#Code secret
]*>([A-Z0-9]{6})#', $page->getContent(), $m);
$code = $m[1];
expect(DemandeInscription::count())->toBe(0)
->and(Auth::guard('eleve')->user()?->identifiant)->toBe('ines.m');
// Une seule fois : un second affichage renvoie vers l'espace élève.
$this->get(route('rejoindre.bienvenue'))->assertRedirect(route('eleve'));
Auth::guard('eleve')->logout();
expect(Auth::guard('eleve')->attempt(['identifiant' => 'ines.m', 'password' => $code]))->toBeTrue();
});
test('un code faux ou une classe archivée sont refusés', function () {
$this->post(route('rejoindre.demander'), ['code' => 'ZZZZZZ', 'prenom' => 'Léo'])->assertSessionHasErrors('code');
$archivee = Classe::factory()->create();
$archivee->forceFill(['archivee_a' => now()])->save();
$this->post(route('rejoindre.demander'), ['code' => $archivee->code_classe, 'prenom' => 'Léo'])->assertSessionHasErrors('code');
expect(DemandeInscription::count())->toBe(0);
});
test('une demande refusée l’annonce à l’élève et disparaît', function () {
$classe = Classe::factory()->create();
$this->post(route('rejoindre.demander'), ['code' => $classe->code_classe, 'prenom' => 'Léo']);
commeProf($this, $classe->prof)->post(route('mes-classes.demandes.refuser', [$classe, DemandeInscription::sole()]));
Auth::guard('web')->logout();
$this->get(route('rejoindre.attente'))->assertOk()->assertSee('pas accepté');
expect(DemandeInscription::count())->toBe(0)->and(Eleve::count())->toBe(0);
});
test('seul le navigateur de l’élève voit son code, et seul le prof de la classe peut accepter', function () {
$classe = Classe::factory()->create();
$this->post(route('rejoindre.demander'), ['code' => $classe->code_classe, 'prenom' => 'Léo']);
$demande = DemandeInscription::sole();
commeProf($this, User::factory()->create())->post(route('mes-classes.demandes.accepter', [$classe, $demande]))->assertForbidden();
commeProf($this, $classe->prof)->post(route('mes-classes.demandes.accepter', [$classe, $demande]));
Auth::guard('web')->logout();
$this->flushSession();
$this->get(route('rejoindre.bienvenue'))->assertRedirect(route('rejoindre'));
expect(DemandeInscription::sole()->statut)->toBe(DemandeInscription::ACCEPTEE);
});
test('une demande non traitée depuis une heure est supprimée', function () {
$classe = Classe::factory()->create();
$ancienne = DemandeInscription::create(['classe_id' => $classe->id, 'prenom' => 'A', 'jeton_empreinte' => DemandeInscription::empreinte('a'), 'statut' => 'en_attente']);
$ancienne->forceFill(['created_at' => now()->subMinutes(61)])->save();
DemandeInscription::create(['classe_id' => $classe->id, 'prenom' => 'B', 'jeton_empreinte' => DemandeInscription::empreinte('b'), 'statut' => 'en_attente']);
$this->artisan('model:prune', ['--model' => [DemandeInscription::class]]);
expect(DemandeInscription::pluck('prenom')->all())->toBe(['B']);
});
test('le prof génère de nouvelles fiches pour les élèves cochés, et seulement eux', function () {
$classe = Classe::factory()->create();
[$a, $b] = Eleve::factory()->count(2)->create(['classe_id' => $classe->id]);
$ancienB = $b->code_secret;
commeProf($this, $classe->prof)->post(route('mes-classes.fiches', $classe), ['eleves' => [$a->id]])
->assertSessionHas('fiches', fn ($fiches) => count($fiches) === 1 && $fiches[0]['identifiant'] === $a->identifiant);
expect(Auth::guard('eleve')->attempt(['identifiant' => $a->identifiant, 'password' => '123456']))->toBeFalse()
->and($b->refresh()->code_secret)->toBe($ancienB);
});