'Utilisateur']); return Utilisateur::create([ 'Pseudo' => 'JeanTest', 'Email' => 'jean.test@example.com', 'MotDePasse' => Hash::make('motdepasse123'), 'ID_Role' => $role->ID_Role, 'Statut' => 'Actif', ]); } private function configurerGitea(): void { config([ 'services.gitea.url' => 'https://gitea.test', 'services.gitea.token' => 'fake-token', 'services.gitea.admin_token' => 'fake-admin-token', 'services.gitea.repo' => 'Groupe1/Ressources-relationnel', ]); } /** * Fakes par défaut : aucun compte existant, création de compte et de ticket OK. * * @param array $overrides */ private function fakesGitea(array $overrides = []): void { Http::fake($overrides + [ 'gitea.test/api/v1/admin/emails/search*' => Http::response([]), 'gitea.test/api/v1/admin/users' => Http::response(['id' => 42], 201), 'gitea.test/api/v1/repos/*/issues' => Http::response(['number' => 42], 201), ]); } public function test_le_formulaire_de_suggestion_exige_une_authentification(): void { $this->get('/suggestions/nouveau')->assertRedirect('/login'); } public function test_une_suggestion_valide_cree_un_ticket_gitea(): void { $this->configurerGitea(); $this->fakesGitea(); $response = $this->actingAs($this->utilisateur())->post('/suggestions', [ 'type' => 'Correction', 'titre' => 'Faute dans une ressource', 'description' => 'Il y a une faute à corriger sur la page des ressources.', ]); $response->assertRedirect(route('suggestions.create')); $response->assertSessionHas('success'); Http::assertSent(function ($request) { return str_contains($request->url(), '/api/v1/repos/Groupe1/Ressources-relationnel/issues') && $request['title'] === '[Correction] Faute dans une ressource' && str_contains($request['body'], 'JeanTest'); }); } public function test_le_premier_envoi_cree_un_compte_gitea_pour_l_utilisateur(): void { $this->configurerGitea(); $this->fakesGitea(); $utilisateur = $this->utilisateur(); $response = $this->actingAs($utilisateur)->post('/suggestions', [ 'type' => 'Ajout', 'titre' => 'Une nouvelle fonctionnalité', 'description' => 'Description suffisamment longue de la fonctionnalité.', ]); $usernameAttendu = 'jeantest-'.$utilisateur->ID_Utilisateur; $response->assertSessionHas('success'); // Les identifiants sont flashés une seule fois pour affichage $response->assertSessionHas('gitea_compte', fn ($compte) => $compte['username'] === $usernameAttendu && $compte['mot_de_passe'] !== null); $this->assertSame($usernameAttendu, $utilisateur->fresh()->GiteaUsername); // Le compte a été créé via l'API admin… Http::assertSent(fn ($request) => str_contains($request->url(), '/api/v1/admin/users') && $request['username'] === $usernameAttendu && $request['email'] === 'jean.test@example.com' && $request['must_change_password'] === true); // …et le ticket est ouvert au nom de l'utilisateur (en-tête Sudo) Http::assertSent(fn ($request) => str_contains($request->url(), '/issues') && $request->header('Sudo') === [$usernameAttendu]); } public function test_un_compte_gitea_existant_est_reutilise(): void { $this->configurerGitea(); $this->fakesGitea(); $utilisateur = $this->utilisateur(); $utilisateur->GiteaUsername = 'jean-deja-la'; $utilisateur->save(); $response = $this->actingAs($utilisateur)->post('/suggestions', [ 'type' => 'Modification', 'titre' => 'Changer un contenu', 'description' => 'Description suffisamment longue de la modification.', ]); $response->assertSessionHas('success'); $response->assertSessionMissing('gitea_compte'); // Aucune création de compte ne doit être tentée Http::assertNotSent(fn ($request) => str_contains($request->url(), '/api/v1/admin/users')); Http::assertSent(fn ($request) => str_contains($request->url(), '/issues') && $request->header('Sudo') === ['jean-deja-la']); } public function test_le_ticket_est_cree_meme_si_la_creation_du_compte_echoue(): void { $this->configurerGitea(); // Token sans droits admin : la création de compte est refusée $this->fakesGitea([ 'gitea.test/api/v1/admin/emails/search*' => Http::response('Forbidden', 403), 'gitea.test/api/v1/admin/users' => Http::response('Forbidden', 403), ]); $response = $this->actingAs($this->utilisateur())->post('/suggestions', [ 'type' => 'Correction', 'titre' => 'Un bug à corriger', 'description' => 'Description suffisamment longue du bug rencontré.', ]); // Repli : ticket créé avec le compte de service, sans en-tête Sudo $response->assertSessionHas('success'); $response->assertSessionMissing('gitea_compte'); Http::assertSent(fn ($request) => str_contains($request->url(), '/issues') && $request->header('Sudo') === []); } public function test_un_sudo_refuse_retombe_sur_le_compte_de_service(): void { $this->configurerGitea(); $this->fakesGitea([ // 1er appel (Sudo) refusé, 2e appel (compte de service) accepté 'gitea.test/api/v1/repos/*/issues' => Http::sequence() ->push('Not Found', 404) ->push(['number' => 43], 201), ]); $utilisateur = $this->utilisateur(); $utilisateur->GiteaUsername = 'jean-deja-la'; $utilisateur->save(); $response = $this->actingAs($utilisateur)->post('/suggestions', [ 'type' => 'Ajout', 'titre' => 'Encore une idée géniale', 'description' => 'Description suffisamment longue de cette idée géniale.', ]); $response->assertSessionHas('success'); } public function test_une_suggestion_invalide_est_rejetee(): void { Http::fake(); $response = $this->actingAs($this->utilisateur())->post('/suggestions', [ 'type' => 'Inconnu', 'titre' => 'x', 'description' => 'court', ]); $response->assertSessionHasErrors(['type', 'titre', 'description']); Http::assertNothingSent(); } public function test_un_echec_gitea_affiche_une_erreur(): void { $this->configurerGitea(); $this->fakesGitea([ 'gitea.test/api/v1/repos/*/issues' => Http::response(['message' => 'nope'], 500), ]); $response = $this->actingAs($this->utilisateur())->post('/suggestions', [ 'type' => 'Ajout', 'titre' => 'Nouvelle fonctionnalité utile', 'description' => 'Ce serait bien d\'ajouter un filtre par thème.', ]); $response->assertSessionHasErrors('gitea'); } }