116 lines
5.8 KiB
PHP
116 lines
5.8 KiB
PHP
|
|
<?php
|
|||
|
|
|
|||
|
|
use App\Models\Classe;
|
|||
|
|
use App\Models\Devoir;
|
|||
|
|
use App\Models\Eleve;
|
|||
|
|
use App\Models\RenduDevoir;
|
|||
|
|
use Illuminate\Support\Facades\Process;
|
|||
|
|
|
|||
|
|
test('un prof crée un devoir, un élève le rend, le prof le note', function () {
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
|
|||
|
|
|
|||
|
|
commeProf($this, $classe->prof)->post(route('mes-classes.devoirs.store', $classe), [
|
|||
|
|
'titre' => 'Plan d’adressage',
|
|||
|
|
'consigne' => 'Découpe 192.168.1.0/24 en 4 sous-réseaux.',
|
|||
|
|
'echeance' => now()->addDays(3)->format('Y-m-d\TH:i'),
|
|||
|
|
])->assertRedirect();
|
|||
|
|
|
|||
|
|
$devoir = Devoir::where('titre', 'Plan d’adressage')->first();
|
|||
|
|
expect($devoir)->not->toBeNull()->and($devoir->classe_id)->toBe($classe->id);
|
|||
|
|
|
|||
|
|
eleve($this, $eleve)->get(route('devoirs.eleve.show', $devoir))->assertOk()->assertSee('Découpe 192.168.1.0/24');
|
|||
|
|
|
|||
|
|
eleve($this, $eleve)->post(route('devoirs.eleve.rendre', $devoir), ['reponse' => 'Voici mon découpage : /26 x4.'])
|
|||
|
|
->assertRedirect();
|
|||
|
|
|
|||
|
|
$rendu = RenduDevoir::where('devoir_id', $devoir->id)->where('eleve_id', $eleve->id)->first();
|
|||
|
|
expect($rendu)->not->toBeNull()->and($rendu->reponse)->toBe('Voici mon découpage : /26 x4.')->and($rendu->note)->toBeNull();
|
|||
|
|
|
|||
|
|
commeProf($this, $classe->prof)->get(route('mes-classes.devoirs.show', [$classe, $devoir]))
|
|||
|
|
->assertSee($eleve->nomAffiche())
|
|||
|
|
->assertSee('Voici mon découpage');
|
|||
|
|
|
|||
|
|
commeProf($this, $classe->prof)->post(route('mes-classes.devoirs.noter', [$classe, $devoir, $rendu]), ['note' => 15])
|
|||
|
|
->assertRedirect();
|
|||
|
|
expect($rendu->refresh()->note)->toBe(15);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('un élève peut modifier son rendu avant l’échéance, un seul rendu par devoir en base', function () {
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
|
|||
|
|
$devoir = Devoir::create(['classe_id' => $classe->id, 'titre' => 'Test', 'consigne' => 'Test', 'echeance' => now()->addDay()]);
|
|||
|
|
|
|||
|
|
eleve($this, $eleve)->post(route('devoirs.eleve.rendre', $devoir), ['reponse' => 'Premier essai'])->assertRedirect();
|
|||
|
|
eleve($this, $eleve)->post(route('devoirs.eleve.rendre', $devoir), ['reponse' => 'Version corrigée'])->assertRedirect();
|
|||
|
|
|
|||
|
|
expect(RenduDevoir::where('devoir_id', $devoir->id)->count())->toBe(1);
|
|||
|
|
expect(RenduDevoir::first()->reponse)->toBe('Version corrigée');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('un élève ne peut plus rendre après l’échéance', function () {
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
|
|||
|
|
$devoir = Devoir::create(['classe_id' => $classe->id, 'titre' => 'Test', 'consigne' => 'Test', 'echeance' => now()->subHour()]);
|
|||
|
|
|
|||
|
|
eleve($this, $eleve)->post(route('devoirs.eleve.rendre', $devoir), ['reponse' => 'Trop tard'])->assertStatus(409);
|
|||
|
|
expect(RenduDevoir::count())->toBe(0);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('un élève d’une autre classe ne peut pas voir ni rendre ce devoir', function () {
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$devoir = Devoir::create(['classe_id' => $classe->id, 'titre' => 'Test', 'consigne' => 'Test', 'echeance' => now()->addDay()]);
|
|||
|
|
$autreEleve = Eleve::factory()->create();
|
|||
|
|
|
|||
|
|
eleve($this, $autreEleve)->get(route('devoirs.eleve.show', $devoir))->assertForbidden();
|
|||
|
|
eleve($this, $autreEleve)->post(route('devoirs.eleve.rendre', $devoir), ['reponse' => 'Intrus'])->assertForbidden();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('un prof d’une autre classe ne peut pas voir ni noter les rendus', function () {
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
|
|||
|
|
$devoir = Devoir::create(['classe_id' => $classe->id, 'titre' => 'Test', 'consigne' => 'Test', 'echeance' => now()->addDay()]);
|
|||
|
|
$rendu = RenduDevoir::create(['devoir_id' => $devoir->id, 'eleve_id' => $eleve->id, 'reponse' => 'x', 'rendu_a' => now()]);
|
|||
|
|
$autreClasse = Classe::factory()->create();
|
|||
|
|
|
|||
|
|
commeProf($this, $autreClasse->prof)->get(route('mes-classes.devoirs.show', [$classe, $devoir]))->assertForbidden();
|
|||
|
|
commeProf($this, $autreClasse->prof)->post(route('mes-classes.devoirs.noter', [$classe, $devoir, $rendu]), ['note' => 20])->assertForbidden();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('archiver puis purger une classe supprime aussi ses devoirs et rendus', function () {
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
|
|||
|
|
$devoir = Devoir::create(['classe_id' => $classe->id, 'titre' => 'Test', 'consigne' => 'Test', 'echeance' => now()->addDay()]);
|
|||
|
|
RenduDevoir::create(['devoir_id' => $devoir->id, 'eleve_id' => $eleve->id, 'reponse' => 'x', 'rendu_a' => now()]);
|
|||
|
|
|
|||
|
|
$classe->forceFill(['archivee_a' => now()->subDays(91)])->save();
|
|||
|
|
$this->artisan('classes:purger-archivees');
|
|||
|
|
|
|||
|
|
expect(Devoir::count())->toBe(0)->and(RenduDevoir::count())->toBe(0);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('les scripts en ligne de la page de notation d’un devoir sont du JavaScript valide', function () {
|
|||
|
|
if (Process::run('node --version')->failed()) {
|
|||
|
|
$this->markTestSkipped('Node absent');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$classe = Classe::factory()->create();
|
|||
|
|
$devoir = Devoir::create(['classe_id' => $classe->id, 'titre' => 'Test', 'consigne' => 'Test', 'echeance' => now()->addDay()]);
|
|||
|
|
|
|||
|
|
$html = commeProf($this, $classe->prof)->get(route('mes-classes.devoirs.show', [$classe, $devoir]))->getContent();
|
|||
|
|
preg_match_all('#<script(?![^>]*\bsrc=)[^>]*>(.*?)</script>#s', $html, $scripts);
|
|||
|
|
|
|||
|
|
$erreurs = [];
|
|||
|
|
foreach ($scripts[1] as $i => $code) {
|
|||
|
|
$fichier = tempnam(sys_get_temp_dir(), 'js').'.js';
|
|||
|
|
file_put_contents($fichier, $code);
|
|||
|
|
$resultat = Process::run(['node', '--check', $fichier]);
|
|||
|
|
unlink($fichier);
|
|||
|
|
if ($resultat->failed()) {
|
|||
|
|
$erreurs[] = "script {$i} : ".strtok($resultat->errorOutput(), "\n");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
expect($erreurs)->toBe([]);
|
|||
|
|
});
|