Paillasse/portail/tests/Feature/CoquilleApplicationTest.php

141 lines
6.1 KiB
PHP
Raw Permalink Normal View History

<?php
use App\Models\Classe;
use App\Models\Eleve;
use App\Models\FilConversation;
use App\Models\User;
use Illuminate\Support\Facades\Process;
test('la vitrine reste accessible sans être connecté', function () {
$this->get(route('accueil'))->assertOk()->assertSee('Syllabus');
});
test('un élève voit la barre latérale élève, jamais celle du prof', function () {
$eleve = Eleve::factory()->create();
$page = eleve($this, $eleve)->get(route('eleve'));
$page->assertOk()
->assertSee('Ma classe')
->assertSee('Mes devoirs')
->assertDontSee('Séances en direct')
->assertDontSee('Bibliothèque');
});
test('un prof voit la barre latérale prof, jamais celle des élèves', function () {
$prof = User::factory()->create();
$classe = Classe::factory()->create(['user_id' => $prof->id]);
$page = prof($this, $prof)->get(route('mes-classes.show', $classe));
$page->assertOk()
->assertSee('Séances en direct')
->assertSee('Bibliothèque')
->assertDontSee('Mes notes')
->assertDontSee('Mes cours');
});
test('un élève ne peut jamais atteindre le chat (ni le sien, ni celui des profs) via les routes prof', function () {
$classeA = Classe::factory()->create();
$eleveA = Eleve::factory()->create(['classe_id' => $classeA->id]);
$filA = FilConversation::create(['classe_id' => $classeA->id, 'eleve_id' => $eleveA->id]);
eleve($this, $eleveA)->getJson(route('chat.prof.index'))->assertStatus(401);
eleve($this, $eleveA)->getJson(route('chat.prof.etat', $filA))->assertStatus(401);
});
test("un prof ne peut pas lire ou écrire dans le fil de conversation d'une classe qui n'est pas la sienne", function () {
$classeA = Classe::factory()->create();
$eleveA = Eleve::factory()->create(['classe_id' => $classeA->id]);
$filA = FilConversation::create(['classe_id' => $classeA->id, 'eleve_id' => $eleveA->id]);
$autreProf = User::factory()->create();
prof($this, $autreProf)->getJson(route('chat.prof.etat', $filA))->assertStatus(403);
prof($this, $autreProf)->postJson(route('chat.prof.envoyer', $filA), ['contenu' => 'Bonjour'])->assertStatus(403);
expect($filA->messages()->count())->toBe(0);
});
test("deux élèves de classes différentes n'ont jamais le même fil de conversation et ne peuvent pas lire celui de l'autre", function () {
$classeA = Classe::factory()->create();
$eleveA = Eleve::factory()->create(['classe_id' => $classeA->id]);
$classeB = Classe::factory()->create();
$eleveB = Eleve::factory()->create(['classe_id' => $classeB->id]);
eleve($this, $eleveA)->postJson(route('chat.eleve.envoyer'), ['contenu' => 'Un message de A'])->assertCreated();
eleve($this, $eleveB)->postJson(route('chat.eleve.envoyer'), ['contenu' => 'Un message de B'])->assertCreated();
$reponseA = eleve($this, $eleveA)->getJson(route('chat.eleve.etat'))->json();
$reponseB = eleve($this, $eleveB)->getJson(route('chat.eleve.etat'))->json();
expect(collect($reponseA['messages'])->pluck('contenu')->all())->toBe(['Un message de A'])
->and(collect($reponseB['messages'])->pluck('contenu')->all())->toBe(['Un message de B']);
});
test('les scripts en ligne de la coquille (barre du haut, chat) sont du JavaScript valide, côté élève et côté prof', function () {
if (Process::run('node --version')->failed()) {
$this->markTestSkipped('Node absent');
}
$eleve = Eleve::factory()->create();
$prof = User::factory()->create();
$classe = Classe::factory()->create(['user_id' => $prof->id]);
$pages = [
fn () => eleve($this, $eleve)->get(route('eleve')),
fn () => prof($this, $prof)->get(route('mes-classes.show', $classe)),
];
$erreurs = [];
foreach ($pages as $i => $visite) {
preg_match_all('#<script(?![^>]*\bsrc=)[^>]*>(.*?)</script>#s', $visite()->getContent(), $scripts);
foreach ($scripts[1] as $j => $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[] = "page {$i} script {$j} : ".strtok($resultat->errorOutput(), "\n");
}
}
}
expect($erreurs)->toBe([]);
});
test('toutes les nouvelles pages de la coquille se chargent sans erreur', function () {
$prof = User::factory()->create();
$classe = Classe::factory()->create(['user_id' => $prof->id]);
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
$pagesEleve = ['ma-classe', 'emploi-du-temps', 'mes-devoirs', 'mes-cours', 'mes-notes', 'profil', 'parametres', 'aide.app'];
foreach ($pagesEleve as $route) {
eleve($this, $eleve)->get(route($route))->assertOk();
}
$pagesProf = ['seances-en-direct', 'bibliotheque.app', 'resultats', 'profil', 'parametres', 'aide.app', 'emploi-du-temps'];
foreach ($pagesProf as $route) {
prof($this, $prof)->get(route($route))->assertOk();
}
});
test('le compteur de messages non lus retombe à zéro une fois le fil ouvert, côté prof et côté élève', function () {
$prof = User::factory()->create();
$classe = Classe::factory()->create(['user_id' => $prof->id]);
$eleve = Eleve::factory()->create(['classe_id' => $classe->id]);
eleve($this, $eleve)->postJson(route('chat.eleve.envoyer'), ['contenu' => 'Un message'])->assertCreated();
$fil = FilConversation::where('eleve_id', $eleve->id)->first();
expect(prof($this, $prof)->getJson(route('chat.prof.index'))->json('fils.0.non_lus'))->toBe(1);
prof($this, $prof)->getJson(route('chat.prof.etat', $fil))->assertOk();
expect(prof($this, $prof)->getJson(route('chat.prof.index'))->json('fils.0.non_lus'))->toBe(0);
prof($this, $prof)->postJson(route('chat.prof.envoyer', $fil), ['contenu' => 'Une réponse'])->assertCreated();
expect(eleve($this, $eleve)->getJson(route('chat.eleve.etat'))->json('non_lus'))->toBe(1);
eleve($this, $eleve)->getJson(route('chat.eleve.etat').'?lu=1')->assertOk();
expect(eleve($this, $eleve)->getJson(route('chat.eleve.etat'))->json('non_lus'))->toBe(0);
});