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('#]*\bsrc=)[^>]*>(.*?)#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); });