+
+
Dans les cours et les labs du catalogue.
+
+
+
+ @if (! $disponible)
+
+ La recherche n'est pas disponible pour le moment.
+
+ @elseif ($texte !== '' && empty($resultats))
+
Rien trouvé pour « {{ $texte }} ».
+ @elseif (! empty($resultats))
+
+ @endif
+
+@endsection
diff --git a/portail/routes/web.php b/portail/routes/web.php
index b7010b0..0814570 100644
--- a/portail/routes/web.php
+++ b/portail/routes/web.php
@@ -29,6 +29,7 @@ use App\Http\Controllers\QuizController;
use App\Http\Controllers\QuizEleveController;
use App\Http\Controllers\RaccourciController;
use App\Http\Controllers\RapportCspController;
+use App\Http\Controllers\RechercheController;
use App\Http\Controllers\RejoindreClasseController;
use App\Http\Controllers\ResultatsController;
use App\Http\Controllers\SeanceController;
@@ -122,6 +123,7 @@ Route::middleware(['auth:eleve,web', 'session.unique:eleve', 'session.unique:web
Route::post('/raccourcis/{raccourci}/supprimer', [RaccourciController::class, 'destroy'])->name('raccourcis.destroy');
Route::get('/emploi-du-temps', [EmploiDuTempsController::class, 'show'])->name('emploi-du-temps');
Route::get('/mes-cours/{cours:identifiant}', [MesCoursController::class, 'montrer'])->name('mes-cours.show');
+ Route::get('/recherche', [RechercheController::class, 'chercher'])->middleware('throttle:30,1')->name('recherche');
});
// --- Espace élève (protégé, session unique) ---
diff --git a/portail/tests/Feature/RechercheTest.php b/portail/tests/Feature/RechercheTest.php
new file mode 100644
index 0000000..04b1209
--- /dev/null
+++ b/portail/tests/Feature/RechercheTest.php
@@ -0,0 +1,69 @@
+create();
+
+ eleve($this, $eleve)->get(route('recherche', ['q' => 'routage']))
+ ->assertOk()
+ ->assertSee('pas disponible');
+});
+
+test('un prof et un élève peuvent tous les deux utiliser la recherche', function () {
+ $eleve = Eleve::factory()->create();
+ eleve($this, $eleve)->get(route('recherche'))->assertOk();
+
+ $classe = Classe::factory()->create();
+ commeProf($this, $classe->prof)->get(route('recherche'))->assertOk();
+});
+
+test('un résultat de type cours renvoie vers la page du cours, avec l’extrait surligné', function () {
+ config(['elasticsearch.hote' => '127.0.0.1']);
+ Cours::create(['identifiant' => '08-deux-lan-routeur', 'titre' => 'Deux LAN et un routeur', 'contenu_markdown' => 'Le routage statique...']);
+
+ Http::fake([
+ '*/_search' => Http::response([
+ 'hits' => ['hits' => [
+ [
+ '_source' => ['type' => 'cours', 'identifiant' => '08-deux-lan-routeur', 'titre' => 'Deux LAN et un routeur', 'contenu' => 'Le routage statique...'],
+ 'highlight' => ['contenu' => ['Le