Files
Ressources-relationnel/tests/Feature/SuggestionTest.php
T
Azmog 2984b9f410
CI - Intégration continue / quality-and-tests (push) Successful in 3m15s
CD - Déploiement continu / deploy (push) Successful in 3m10s
feat: ajout du suivi des suggestions avec intégration Gitea
2026-07-08 09:59:05 +02:00

227 lines
7.8 KiB
PHP

<?php
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;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class SuggestionTest extends TestCase
{
use RefreshDatabase;
private function utilisateur(string $pseudo = 'JeanTest', string $email = 'jean.test@example.com'): Utilisateur
{
$role = Role::firstOrCreate(['Nom' => 'Utilisateur']);
return Utilisateur::create([
'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([
'services.gitea.url' => 'https://gitea.test',
'services.gitea.token' => 'fake-token',
'services.gitea.repo' => 'Groupe1/Ressources-relationnel',
]);
}
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_et_est_conservee(): void
{
$this->configurerGitea();
Http::fake([
'*/api/v1/repos/*/issues' => Http::response(['number' => 42], 201),
]);
$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.',
]);
// L'utilisateur arrive sur la page de suivi de ses suggestions
$response->assertRedirect(route('suggestions.index'));
$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');
});
// 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
{
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();
Http::fake([
'*/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');
// Rien n'est conservé si le ticket n'a pas pu être créé
$this->assertDatabaseCount('suggestions', 0);
}
}