feat: ajout du suivi des suggestions avec intégration Gitea
CI - Intégration continue / quality-and-tests (push) Successful in 3m15s
CD - Déploiement continu / deploy (push) Successful in 3m10s

This commit is contained in:
Azmog
2026-07-08 09:59:05 +02:00
parent 507d77246c
commit 2984b9f410
9 changed files with 646 additions and 31 deletions
+138 -7
View File
@@ -3,6 +3,7 @@
namespace Tests\Feature;
use App\Models\Role;
use App\Models\Suggestion;
use App\Models\Utilisateur;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
@@ -13,19 +14,30 @@ class SuggestionTest extends TestCase
{
use RefreshDatabase;
private function utilisateur(): Utilisateur
private function utilisateur(string $pseudo = 'JeanTest', string $email = 'jean.test@example.com'): Utilisateur
{
$role = Role::create(['Nom' => 'Utilisateur']);
$role = Role::firstOrCreate(['Nom' => 'Utilisateur']);
return Utilisateur::create([
'Pseudo' => 'JeanTest',
'Email' => 'jean.test@example.com',
'Pseudo' => $pseudo,
'Email' => $email,
'MotDePasse' => Hash::make('motdepasse123'),
'ID_Role' => $role->ID_Role,
'Statut' => 'Actif',
]);
}
private function suggestion(Utilisateur $utilisateur, ?int $numero = 42): Suggestion
{
return Suggestion::create([
'ID_Utilisateur' => $utilisateur->ID_Utilisateur,
'Type' => 'Correction',
'Titre' => 'Faute dans une ressource',
'Description' => 'Il y a une faute à corriger sur la page des ressources.',
'GiteaIssueNumber' => $numero,
]);
}
private function configurerGitea(): void
{
config([
@@ -38,22 +50,26 @@ class SuggestionTest extends TestCase
public function test_le_formulaire_de_suggestion_exige_une_authentification(): void
{
$this->get('/suggestions/nouveau')->assertRedirect('/login');
$this->get('/suggestions')->assertRedirect('/login');
}
public function test_une_suggestion_valide_cree_un_ticket_gitea(): void
public function test_une_suggestion_valide_cree_un_ticket_gitea_et_est_conservee(): void
{
$this->configurerGitea();
Http::fake([
'*/api/v1/repos/*/issues' => Http::response(['number' => 42], 201),
]);
$response = $this->actingAs($this->utilisateur())->post('/suggestions', [
$utilisateur = $this->utilisateur();
$response = $this->actingAs($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'));
// L'utilisateur arrive sur la page de suivi de ses suggestions
$response->assertRedirect(route('suggestions.index'));
$response->assertSessionHas('success');
Http::assertSent(function ($request) {
@@ -61,6 +77,118 @@ class SuggestionTest extends TestCase
&& $request['title'] === '[Correction] Faute dans une ressource'
&& str_contains($request['body'], 'JeanTest');
});
// La suggestion est liée au ticket pour permettre le suivi
$this->assertDatabaseHas('suggestions', [
'ID_Utilisateur' => $utilisateur->ID_Utilisateur,
'Titre' => 'Faute dans une ressource',
'GiteaIssueNumber' => 42,
]);
}
public function test_la_liste_affiche_l_etat_du_ticket_et_les_nouvelles_reponses(): void
{
$this->configurerGitea();
Http::fake([
'gitea.test/api/v1/repos/*/issues/42' => Http::response([
'number' => 42, 'state' => 'open', 'comments' => 2, 'title' => '[Correction] Faute',
]),
]);
$utilisateur = $this->utilisateur();
$this->suggestion($utilisateur);
$response = $this->actingAs($utilisateur)->get('/suggestions');
$response->assertOk()
->assertSee('Faute dans une ressource')
->assertSee('En cours')
->assertSee('2 nouvelles réponses');
}
public function test_la_liste_ne_montre_pas_les_suggestions_des_autres(): void
{
$this->configurerGitea();
Http::fake();
$autre = $this->utilisateur('AutreUser', 'autre@example.com');
$this->suggestion($autre);
$moi = $this->utilisateur('Moi', 'moi@example.com');
$this->actingAs($moi)->get('/suggestions')
->assertOk()
->assertDontSee('Faute dans une ressource');
}
public function test_le_detail_affiche_les_reponses_du_ticket_et_les_marque_comme_vues(): void
{
$this->configurerGitea();
Http::fake([
'gitea.test/api/v1/repos/*/issues/42/comments' => Http::response([
[
'user' => ['username' => 'sam-depardieu'],
'body' => 'Merci, correction prévue dans la v1.1 !',
'created_at' => '2026-07-08T10:00:00Z',
],
]),
'gitea.test/api/v1/repos/*/issues/42' => Http::response([
'number' => 42, 'state' => 'open', 'comments' => 1, 'title' => '[Correction] Faute',
]),
]);
$utilisateur = $this->utilisateur();
$suggestion = $this->suggestion($utilisateur);
$response = $this->actingAs($utilisateur)->get('/suggestions/'.$suggestion->ID_Suggestion);
$response->assertOk()
->assertSee('sam-depardieu')
->assertSee('Merci, correction prévue dans la v1.1 !');
// Les réponses consultées ne comptent plus comme « nouvelles »
$this->assertSame(1, $suggestion->fresh()->CommentairesVus);
}
public function test_le_detail_d_une_suggestion_d_un_autre_est_interdit(): void
{
$this->configurerGitea();
Http::fake();
$autre = $this->utilisateur('AutreUser', 'autre@example.com');
$suggestion = $this->suggestion($autre);
$moi = $this->utilisateur('Moi', 'moi@example.com');
$this->actingAs($moi)->get('/suggestions/'.$suggestion->ID_Suggestion)
->assertForbidden();
}
public function test_l_utilisateur_peut_repondre_sur_le_ticket(): void
{
$this->configurerGitea();
Http::fake([
'gitea.test/api/v1/repos/*/issues/42/comments' => Http::response(['id' => 7], 201),
]);
$utilisateur = $this->utilisateur();
$suggestion = $this->suggestion($utilisateur);
$response = $this->actingAs($utilisateur)
->post('/suggestions/'.$suggestion->ID_Suggestion.'/repondre', [
'message' => 'Précision : la faute est dans le deuxième paragraphe.',
]);
$response->assertRedirect(route('suggestions.show', $suggestion));
$response->assertSessionHas('success');
// Le commentaire est publié sur le ticket Gitea, signé du pseudo
Http::assertSent(function ($request) {
return $request->method() === 'POST'
&& str_contains($request->url(), '/issues/42/comments')
&& str_contains($request['body'], 'JeanTest')
&& str_contains($request['body'], 'deuxième paragraphe');
});
}
public function test_une_suggestion_invalide_est_rejetee(): void
@@ -91,5 +219,8 @@ class SuggestionTest extends TestCase
]);
$response->assertSessionHasErrors('gitea');
// Rien n'est conservé si le ticket n'a pas pu être créé
$this->assertDatabaseCount('suggestions', 0);
}
}