Files
unionflow-server-impl-quarkus/src/test/java/dev/lions/unionflow/server/resource/PaiementResourceTest.java
2026-03-28 14:21:30 +00:00

460 lines
16 KiB
Java

package dev.lions.unionflow.server.resource;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import dev.lions.unionflow.server.api.dto.paiement.response.PaiementGatewayResponse;
import dev.lions.unionflow.server.api.dto.paiement.response.PaiementResponse;
import dev.lions.unionflow.server.api.dto.paiement.response.PaiementSummaryResponse;
import dev.lions.unionflow.server.service.PaiementService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import jakarta.ws.rs.NotFoundException;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
/**
* Tests d'intégration REST pour PaiementResource.
*
* @author UnionFlow Team
* @version 2.0
* @since 2026-03-21
*/
@QuarkusTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class PaiementResourceTest {
private static final String BASE_PATH = "/api/paiements";
private static final String PAIEMENT_ID = "00000000-0000-0000-0000-000000000010";
private static final String MEMBRE_ID = "00000000-0000-0000-0000-000000000020";
@InjectMock
PaiementService paiementService;
// -------------------------------------------------------------------------
// GET /api/paiements/{id}
// -------------------------------------------------------------------------
@Test
@Order(1)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void trouverParId_found_returns200() {
PaiementResponse response = PaiementResponse.builder()
.numeroReference("PAY-001")
.build();
when(paiementService.trouverParId(any(UUID.class))).thenReturn(response);
given()
.pathParam("id", PAIEMENT_ID)
.when()
.get(BASE_PATH + "/{id}")
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.body("$", notNullValue());
}
@Test
@Order(2)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void trouverParId_notFound_returns404() {
when(paiementService.trouverParId(any(UUID.class)))
.thenThrow(new NotFoundException("Paiement non trouvé"));
given()
.pathParam("id", UUID.randomUUID())
.when()
.get(BASE_PATH + "/{id}")
.then()
.statusCode(404);
}
// -------------------------------------------------------------------------
// GET /api/paiements/reference/{numeroReference}
// -------------------------------------------------------------------------
@Test
@Order(3)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void trouverParNumeroReference_found_returns200() {
PaiementResponse response = PaiementResponse.builder()
.numeroReference("PAY-REF-001")
.build();
when(paiementService.trouverParNumeroReference(anyString())).thenReturn(response);
given()
.pathParam("numeroReference", "PAY-REF-001")
.when()
.get(BASE_PATH + "/reference/{numeroReference}")
.then()
.statusCode(200)
.contentType(ContentType.JSON);
}
@Test
@Order(4)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void trouverParNumeroReference_notFound_returns404() {
when(paiementService.trouverParNumeroReference(anyString()))
.thenThrow(new NotFoundException("Référence non trouvée"));
given()
.pathParam("numeroReference", "PAY-INEXISTANT-99999")
.when()
.get(BASE_PATH + "/reference/{numeroReference}")
.then()
.statusCode(404);
}
// -------------------------------------------------------------------------
// GET /api/paiements/membre/{membreId}
// -------------------------------------------------------------------------
@Test
@Order(5)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void listerParMembre_returns200() {
when(paiementService.listerParMembre(any(UUID.class)))
.thenReturn(Collections.emptyList());
given()
.pathParam("membreId", MEMBRE_ID)
.when()
.get(BASE_PATH + "/membre/{membreId}")
.then()
.statusCode(200)
.body("$", notNullValue());
}
// -------------------------------------------------------------------------
// GET /api/paiements/mes-paiements/historique
// -------------------------------------------------------------------------
@Test
@Order(6)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void getMonHistoriquePaiements_returns200() {
List<PaiementSummaryResponse> history = Collections.emptyList();
when(paiementService.getMonHistoriquePaiements(anyInt())).thenReturn(history);
given()
.queryParam("limit", 5)
.when()
.get(BASE_PATH + "/mes-paiements/historique")
.then()
.statusCode(200)
.body("$", notNullValue());
}
@Test
@Order(7)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void getMonHistoriquePaiements_defaultLimit_returns200() {
when(paiementService.getMonHistoriquePaiements(anyInt())).thenReturn(Collections.emptyList());
given()
.when()
.get(BASE_PATH + "/mes-paiements/historique")
.then()
.statusCode(200);
}
// -------------------------------------------------------------------------
// POST /api/paiements
// -------------------------------------------------------------------------
@Test
@Order(8)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void creerPaiement_success_returns201() {
PaiementResponse response = PaiementResponse.builder()
.numeroReference("PAY-NEW-001")
.build();
when(paiementService.creerPaiement(any())).thenReturn(response);
String body = String.format("""
{
"membreId": "%s",
"montant": 10000,
"numeroReference": "PAY-NEW-001",
"methodePaiement": "ESPECES",
"codeDevise": "XOF"
}
""", MEMBRE_ID);
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH)
.then()
.statusCode(anyOf(equalTo(201), equalTo(400)));
}
@Test
@Order(9)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void creerPaiement_serverError_returns500() {
when(paiementService.creerPaiement(any()))
.thenThrow(new RuntimeException("db error"));
String body = String.format("""
{"membreId": "%s", "montant": 10000, "numeroReference": "PAY-ERR", "methodePaiement": "ESPECES", "codeDevise": "XOF"}
""", MEMBRE_ID);
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH)
.then()
.statusCode(anyOf(equalTo(500), equalTo(400)));
}
// -------------------------------------------------------------------------
// POST /api/paiements/{id}/valider
// -------------------------------------------------------------------------
@Test
@Order(10)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void validerPaiement_success_returns200() {
PaiementResponse response = PaiementResponse.builder()
.numeroReference("PAY-001")
.build();
when(paiementService.validerPaiement(any(UUID.class))).thenReturn(response);
given()
.pathParam("id", PAIEMENT_ID)
.contentType(ContentType.JSON)
.when()
.post(BASE_PATH + "/{id}/valider")
.then()
.statusCode(200)
.contentType(ContentType.JSON);
}
@Test
@Order(11)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void validerPaiement_notFound_returns404() {
when(paiementService.validerPaiement(any(UUID.class)))
.thenThrow(new NotFoundException("Paiement non trouvé"));
given()
.pathParam("id", UUID.randomUUID())
.contentType(ContentType.JSON)
.when()
.post(BASE_PATH + "/{id}/valider")
.then()
.statusCode(404);
}
// -------------------------------------------------------------------------
// POST /api/paiements/{id}/annuler
// -------------------------------------------------------------------------
@Test
@Order(12)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void annulerPaiement_success_returns200() {
PaiementResponse response = PaiementResponse.builder()
.numeroReference("PAY-001")
.build();
when(paiementService.annulerPaiement(any(UUID.class))).thenReturn(response);
given()
.pathParam("id", PAIEMENT_ID)
.contentType(ContentType.JSON)
.when()
.post(BASE_PATH + "/{id}/annuler")
.then()
.statusCode(200)
.contentType(ContentType.JSON);
}
@Test
@Order(13)
@TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
void annulerPaiement_notFound_returns404() {
when(paiementService.annulerPaiement(any(UUID.class)))
.thenThrow(new NotFoundException("Paiement non trouvé"));
given()
.pathParam("id", UUID.randomUUID())
.contentType(ContentType.JSON)
.when()
.post(BASE_PATH + "/{id}/annuler")
.then()
.statusCode(404);
}
// -------------------------------------------------------------------------
// POST /api/paiements/initier-paiement-en-ligne
// -------------------------------------------------------------------------
@Test
@Order(14)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void initierPaiementEnLigne_success_returns201() {
PaiementGatewayResponse response = PaiementGatewayResponse.builder()
.transactionId(UUID.randomUUID())
.redirectUrl("https://wave.example.com/pay/TXN-001")
.build();
when(paiementService.initierPaiementEnLigne(any())).thenReturn(response);
String body = String.format("""
{
"cotisationId": "%s",
"methodePaiement": "WAVE",
"numeroTelephone": "771234567"
}
""", UUID.randomUUID());
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH + "/initier-paiement-en-ligne")
.then()
.statusCode(anyOf(equalTo(201), equalTo(400)));
}
@Test
@Order(15)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void initierPaiementEnLigne_serverError_returns500() {
when(paiementService.initierPaiementEnLigne(any()))
.thenThrow(new RuntimeException("gateway error"));
String body = String.format("""
{"cotisationId": "%s", "methodePaiement": "WAVE", "numeroTelephone": "771234567"}
""", UUID.randomUUID());
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH + "/initier-paiement-en-ligne")
.then()
.statusCode(anyOf(equalTo(500), equalTo(400)));
}
// -------------------------------------------------------------------------
// POST /api/paiements/initier-depot-epargne-en-ligne
// -------------------------------------------------------------------------
@Test
@Order(16)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void initierDepotEpargneEnLigne_success_returns201() {
PaiementGatewayResponse response = PaiementGatewayResponse.builder()
.transactionId(UUID.randomUUID())
.redirectUrl("https://wave.example.com/pay/DEPOT-001")
.build();
when(paiementService.initierDepotEpargneEnLigne(any())).thenReturn(response);
String body = String.format("""
{
"compteId": "%s",
"montant": 10000,
"numeroTelephone": "771234567"
}
""", UUID.randomUUID());
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH + "/initier-depot-epargne-en-ligne")
.then()
.statusCode(anyOf(equalTo(201), equalTo(400)));
}
@Test
@Order(17)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void initierDepotEpargneEnLigne_serverError_returns500() {
when(paiementService.initierDepotEpargneEnLigne(any()))
.thenThrow(new RuntimeException("epargne error"));
String body = String.format("""
{"compteId": "%s", "montant": 10000, "numeroTelephone": "771234567"}
""", UUID.randomUUID());
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH + "/initier-depot-epargne-en-ligne")
.then()
.statusCode(anyOf(equalTo(500), equalTo(400)));
}
// -------------------------------------------------------------------------
// POST /api/paiements/declarer-paiement-manuel
// -------------------------------------------------------------------------
@Test
@Order(18)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void declarerPaiementManuel_success_returns201() {
PaiementResponse response = PaiementResponse.builder()
.numeroReference("MANUEL-001")
.build();
when(paiementService.declarerPaiementManuel(any())).thenReturn(response);
String body = String.format("""
{
"cotisationId": "%s",
"methodePaiement": "ESPECES",
"montant": 5000,
"dateDeclaration": "2026-03-21",
"commentaire": "Paiement remis en main propre"
}
""", UUID.randomUUID());
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH + "/declarer-paiement-manuel")
.then()
.statusCode(201)
.contentType(ContentType.JSON);
}
@Test
@Order(19)
@TestSecurity(user = "membre@unionflow.com", roles = {"MEMBRE"})
void declarerPaiementManuel_serverError_returns500() {
when(paiementService.declarerPaiementManuel(any()))
.thenThrow(new RuntimeException("declaration error"));
String body = String.format("""
{"cotisationId": "%s", "methodePaiement": "ESPECES", "montant": 5000}
""", UUID.randomUUID());
given()
.contentType(ContentType.JSON)
.body(body)
.when()
.post(BASE_PATH + "/declarer-paiement-manuel")
.then()
.statusCode(500);
}
}