createToken('test', $abilities)->plainTextToken; } test('aucune requête sans jeton', function () { $this->getJson('/api/v1/labs')->assertUnauthorized(); }); test("un jeton sans l'ability catalogue:lire est refusé", function () { $jeton = jetonApi(User::factory()->create(), []); $this->withToken($jeton)->getJson('/api/v1/labs')->assertForbidden(); }); test('un jeton révoqué ne fonctionne plus', function () { $prof = User::factory()->create(); $jeton = jetonApi($prof); $prof->tokens()->delete(); $this->withToken($jeton)->getJson('/api/v1/labs')->assertUnauthorized(); }); test('liste et détail des labs', function () { $jeton = jetonApi(User::factory()->create()); Lab::factory()->create(['identifiant' => '08-deux-lan-routeur', 'titre' => 'Deux LAN et un routeur', 'competences' => ['routage-statique']]); $this->withToken($jeton)->getJson('/api/v1/labs') ->assertOk() ->assertJsonFragment(['identifiant' => '08-deux-lan-routeur']); $this->withToken($jeton)->getJson('/api/v1/labs/08-deux-lan-routeur') ->assertOk() ->assertJson(['data' => ['identifiant' => '08-deux-lan-routeur', 'titre' => 'Deux LAN et un routeur', 'competences' => ['routage-statique']]]); $this->withToken($jeton)->getJson('/api/v1/labs/inconnu')->assertNotFound(); }); test('la liste des quiz ne montre que la banque officielle (partagés, avec thème), jamais les questions', function () { $jeton = jetonApi(User::factory()->create()); $classe = Classe::factory()->create(); $officiel = Quiz::create(['classe_id' => $classe->id, 'titre' => 'Officiel', 'theme' => 'NET', 'partage' => true]); $officiel->questions()->create(['enonce' => 'Une question', 'type' => 'vrai_faux', 'ordre' => 0, 'reponse_vrai_faux' => true]); Quiz::create(['classe_id' => $classe->id, 'titre' => 'Partagé sans thème', 'theme' => null, 'partage' => true]); Quiz::create(['classe_id' => $classe->id, 'titre' => 'Privé', 'theme' => 'NET', 'partage' => false]); $reponse = $this->withToken($jeton)->getJson('/api/v1/quiz')->assertOk(); $titres = collect($reponse->json('data'))->pluck('titre'); expect($titres->all())->toBe(['Officiel']) ->and($reponse->json('data.0'))->not->toHaveKey('questions') ->and($reponse->json('data.0.questions_count'))->toBe(1); $this->withToken($jeton)->getJson("/api/v1/quiz/{$officiel->id}")->assertOk(); $prive = Quiz::where('titre', 'Privé')->first(); $this->withToken($jeton)->getJson("/api/v1/quiz/{$prive->id}")->assertNotFound(); }); test('liste et détail des cours : le contenu complet seulement sur le détail', function () { $jeton = jetonApi(User::factory()->create()); Cours::create(['identifiant' => '08-deux-lan-routeur', 'titre' => 'Deux LAN et un routeur', 'contenu_markdown' => '# Cours']); $this->withToken($jeton)->getJson('/api/v1/cours') ->assertOk() ->assertJsonMissing(['contenu_markdown' => '# Cours']); $this->withToken($jeton)->getJson('/api/v1/cours/08-deux-lan-routeur') ->assertOk() ->assertJson(['data' => ['contenu_markdown' => '# Cours']]); }); test('chaque réponse porte les en-têtes de limite de débit', function () { $jeton = jetonApi(User::factory()->create()); $this->withToken($jeton)->getJson('/api/v1/labs') ->assertHeader('X-RateLimit-Limit', 60); }); test('un prof crée un jeton, le voit en clair une seule fois, le révoque', function () { $prof = User::factory()->create(); $page = prof($this, $prof)->post(route('jetons-api.store'), ['nom' => 'Mon script'])->assertRedirect(); $page = prof($this, $prof)->get(route('jetons-api.index')); $page->assertOk()->assertSee('Mon script'); expect($prof->tokens()->count())->toBe(1); $jeton = $prof->tokens()->first(); prof($this, $prof)->get(route('jetons-api.index'))->assertDontSee($jeton->token); prof($this, $prof)->post(route('jetons-api.destroy', $jeton))->assertRedirect(); expect($prof->tokens()->count())->toBe(0); }); test("un prof ne peut pas révoquer le jeton d'un autre prof", function () { $prof = User::factory()->create(); $autreProf = User::factory()->create(); jetonApi($autreProf); $jeton = $autreProf->tokens()->first(); prof($this, $prof)->post(route('jetons-api.destroy', $jeton))->assertForbidden(); expect($autreProf->tokens()->count())->toBe(1); });