From 43678c8ae9d74f257d0c861e78decef85dcfb24e Mon Sep 17 00:00:00 2001 From: dahoud <41957584+DahoudG@users.noreply.github.com> Date: Sat, 11 Apr 2026 02:00:07 +0000 Subject: [PATCH] =?UTF-8?q?fix(api):=201.0.4=20=E2=80=94=20OrganisationSum?= =?UTF-8?q?maryResponse=20record=E2=86=92@Data=20(compat=20JSF/EL),=20vers?= =?UTF-8?q?ion=20bump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- parent-pom.xml | 3 +- pom.xml | 2 +- .../server/api/dto/common/ErrorResponse.java | 11 +- .../response/ConversationResponse.java | 38 +- .../response/MessageResponse.java | 46 ++- .../response/CotisationSummaryResponse.java | 49 +-- .../MembreDashboardSyntheseResponse.java | 69 ++-- .../dto/membre/CompteAdherentResponse.java | 94 ++--- .../response/MembreSummaryResponse.java | 101 ++--- .../response/OrganisationSummaryResponse.java | 32 +- .../response/IntentionStatutResponse.java | 29 +- .../response/PaiementSummaryResponse.java | 27 +- .../request/CreateTypeReferenceRequest.java | 14 +- .../request/UpdateTypeReferenceRequest.java | 8 +- .../response/TypeReferenceResponse.java | 15 + .../api/dto/common/ErrorResponseTest.java | 32 ++ .../response/CotisationResponseTest.java | 22 ++ .../membre/response/MembreResponseTest.java | 344 ++++++++++++++++++ .../CreateTypeReferenceRequestTest.java | 4 + .../UpdateTypeReferenceRequestTest.java | 54 ++- .../response/TypeReferenceResponseTest.java | 141 +++++++ 21 files changed, 897 insertions(+), 238 deletions(-) create mode 100644 src/test/java/dev/lions/unionflow/server/api/dto/common/ErrorResponseTest.java create mode 100644 src/test/java/dev/lions/unionflow/server/api/dto/membre/response/MembreResponseTest.java create mode 100644 src/test/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponseTest.java diff --git a/parent-pom.xml b/parent-pom.xml index 253ba82..13504ef 100644 --- a/parent-pom.xml +++ b/parent-pom.xml @@ -6,7 +6,7 @@ dev.lions.unionflow unionflow-parent - 1.0.0 + 1.0.4 pom UnionFlow - Parent @@ -60,6 +60,7 @@ unionflow-server-api ${project.version} + diff --git a/pom.xml b/pom.xml index 94a84f0..313d648 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ dev.lions.unionflow unionflow-parent - 1.0.0 + 1.0.4 parent-pom.xml diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/common/ErrorResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/common/ErrorResponse.java index 6ea5870..c30bbec 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/common/ErrorResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/common/ErrorResponse.java @@ -1,13 +1,22 @@ package dev.lions.unionflow.server.api.dto.common; import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; /** * DTO d'erreur unifié retourné par tous les endpoints REST. * Remplace les ErrorResponse locales dupliquées dans chaque Resource. */ @JsonInclude(JsonInclude.Include.NON_NULL) -public record ErrorResponse(String message, String error) { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ErrorResponse { + + private String message; + private String error; /** Constructeur pratique avec message uniquement (cas le plus courant). */ public static ErrorResponse of(String message) { diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/ConversationResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/ConversationResponse.java index 96fb6a1..9903787 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/ConversationResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/ConversationResponse.java @@ -1,7 +1,10 @@ package dev.lions.unionflow.server.api.dto.communication.response; import dev.lions.unionflow.server.api.enums.communication.ConversationType; +import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import java.time.LocalDateTime; import java.util.List; @@ -14,20 +17,23 @@ import java.util.UUID; * @version 1.0 * @since 2026-03-16 */ +@Data +@NoArgsConstructor +@AllArgsConstructor @Builder -public record ConversationResponse( - UUID id, - String name, - String description, - ConversationType type, - List participantIds, - UUID organisationId, - MessageResponse lastMessage, - int unreadCount, - boolean isMuted, - boolean isPinned, - boolean isArchived, - LocalDateTime createdAt, - LocalDateTime updatedAt, - String avatarUrl -) {} +public class ConversationResponse { + private UUID id; + private String name; + private String description; + private ConversationType type; + private List participantIds; + private UUID organisationId; + private MessageResponse lastMessage; + private int unreadCount; + private boolean muted; + private boolean pinned; + private boolean archived; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + private String avatarUrl; +} diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/MessageResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/MessageResponse.java index 1e7215f..784a174 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/MessageResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/communication/response/MessageResponse.java @@ -3,7 +3,10 @@ package dev.lions.unionflow.server.api.dto.communication.response; import dev.lions.unionflow.server.api.enums.communication.MessagePriority; import dev.lions.unionflow.server.api.enums.communication.MessageStatus; import dev.lions.unionflow.server.api.enums.communication.MessageType; +import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import java.time.LocalDateTime; import java.util.List; @@ -16,24 +19,27 @@ import java.util.UUID; * @version 1.0 * @since 2026-03-16 */ +@Data +@NoArgsConstructor +@AllArgsConstructor @Builder -public record MessageResponse( - UUID id, - UUID conversationId, - UUID senderId, - String senderName, - String senderAvatar, - String content, - MessageType type, - MessageStatus status, - MessagePriority priority, - List recipientIds, - List recipientRoles, - UUID organisationId, - LocalDateTime createdAt, - LocalDateTime readAt, - List attachments, - boolean isEdited, - LocalDateTime editedAt, - boolean isDeleted -) {} +public class MessageResponse { + private UUID id; + private UUID conversationId; + private UUID senderId; + private String senderName; + private String senderAvatar; + private String content; + private MessageType type; + private MessageStatus status; + private MessagePriority priority; + private List recipientIds; + private List recipientRoles; + private UUID organisationId; + private LocalDateTime createdAt; + private LocalDateTime readAt; + private List attachments; + private boolean edited; + private LocalDateTime editedAt; + private boolean deleted; +} diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationSummaryResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationSummaryResponse.java index 36d2db9..74c1926 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationSummaryResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationSummaryResponse.java @@ -1,5 +1,9 @@ package dev.lions.unionflow.server.api.dto.cotisation.response; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.math.BigDecimal; import java.time.LocalDate; import java.util.UUID; @@ -7,29 +11,32 @@ import java.util.UUID; /** * Réponse simplifiée pour les listes de cotisations. * - * @param id Identifiant unique. - * @param numeroReference Référence unique. - * @param nomMembre Nom du membre. - * @param montantDu Montant total dû. - * @param montantPaye Montant déjà réglé. - * @param statut Statut actuel (code). - * @param statutLibelle Libellé du statut pour l'UI. - * @param dateEcheance Date limite. - * @param annee Année concernée. - * @param actif Indique si l'entité est active. * @author UnionFlow Team * @version 1.0 * @since 2026-02-22 */ -public record CotisationSummaryResponse( - UUID id, - String numeroReference, - String nomMembre, - BigDecimal montantDu, - BigDecimal montantPaye, - String statut, - String statutLibelle, - LocalDate dateEcheance, - Integer annee, - Boolean actif) { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CotisationSummaryResponse { + /** Identifiant unique. */ + private UUID id; + /** Référence unique. */ + private String numeroReference; + /** Nom du membre. */ + private String nomMembre; + /** Montant total dû. */ + private BigDecimal montantDu; + /** Montant déjà réglé. */ + private BigDecimal montantPaye; + /** Statut actuel (code). */ + private String statut; + /** Libellé du statut pour l'UI. */ + private String statutLibelle; + /** Date limite. */ + private LocalDate dateEcheance; + /** Année concernée. */ + private Integer annee; + /** Indique si l'entité est active. */ + private Boolean actif; } diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/dashboard/MembreDashboardSyntheseResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/dashboard/MembreDashboardSyntheseResponse.java index bbf364a..0ee8898 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/dashboard/MembreDashboardSyntheseResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/dashboard/MembreDashboardSyntheseResponse.java @@ -1,5 +1,9 @@ package dev.lions.unionflow.server.api.dto.dashboard; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; @@ -10,39 +14,42 @@ import java.time.LocalDate; * @author UnionFlow Team * @version 1.0 */ -public record MembreDashboardSyntheseResponse( - String prenom, - String nom, - LocalDate dateInscription, +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MembreDashboardSyntheseResponse implements Serializable { - // Cotisations - BigDecimal mesCotisationsPaiement, - /** Total des cotisations payées sur l'année en cours (pour affichage dashboard). */ - BigDecimal totalCotisationsPayeesAnnee, - /** Total des cotisations payées tout temps (pour la carte « Contribution Totale »). */ - BigDecimal totalCotisationsPayeesToutTemps, - /** Nombre de cotisations PAYÉES (pour la carte « Cotisations »). */ - Integer nombreCotisationsPayees, - String statutCotisations, - /** Taux de cotisation en % (0-100). Calculé sur l'année courante ou toutes années si pas de cotisation 2026. */ - Integer tauxCotisationsPerso, - /** Nombre TOTAL de cotisations (toutes années, tous statuts) — pour calcul du taux d'engagement. */ - Integer nombreCotisationsTotal, + private String prenom; + private String nom; + private LocalDate dateInscription; - // Epargne - BigDecimal monSoldeEpargne, - BigDecimal evolutionEpargneNombre, - String evolutionEpargne, - Integer objectifEpargne, + // Cotisations + private BigDecimal mesCotisationsPaiement; + /** Total des cotisations payées sur l'année en cours (pour affichage dashboard). */ + private BigDecimal totalCotisationsPayeesAnnee; + /** Total des cotisations payées tout temps (pour la carte « Contribution Totale »). */ + private BigDecimal totalCotisationsPayeesToutTemps; + /** Nombre de cotisations PAYÉES (pour la carte « Cotisations »). */ + private Integer nombreCotisationsPayees; + private String statutCotisations; + /** Taux de cotisation en % (0-100). Calculé sur l'année courante ou toutes années si pas de cotisation 2026. */ + private Integer tauxCotisationsPerso; + /** Nombre TOTAL de cotisations (toutes années, tous statuts) — pour calcul du taux d'engagement. */ + private Integer nombreCotisationsTotal; - // Evenements - Integer mesEvenementsInscrits, - Integer evenementsAVenir, - Integer tauxParticipationPerso, + // Epargne + private BigDecimal monSoldeEpargne; + private BigDecimal evolutionEpargneNombre; + private String evolutionEpargne; + private Integer objectifEpargne; - // Aides - Integer mesDemandesAide, - Integer aidesEnCours, - Integer tauxAidesApprouvees) implements Serializable { + // Evenements + private Integer mesEvenementsInscrits; + private Integer evenementsAVenir; + private Integer tauxParticipationPerso; + + // Aides + private Integer mesDemandesAide; + private Integer aidesEnCours; + private Integer tauxAidesApprouvees; } - diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/membre/CompteAdherentResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/membre/CompteAdherentResponse.java index 25d887d..6188b63 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/membre/CompteAdherentResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/membre/CompteAdherentResponse.java @@ -1,5 +1,9 @@ package dev.lions.unionflow.server.api.dto.membre; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; @@ -18,57 +22,55 @@ import java.time.LocalDate; *
  • Capacité d'emprunt estimée (3× l'épargne — règle mutuelle classique)
  • * * - * @param numeroMembre Numéro unique du membre sur la plateforme (ex: MUF-2026-001) - * @param nomComplet Nom et prénom du membre - * @param organisationNom Nom de l'organisation principale (ou null si aucune) - * @param dateAdhesion Date d'inscription sur la plateforme - * @param statutCompte Statut actuel du compte (ACTIF, SUSPENDU, etc.) - * - * @param soldeCotisations Total des cotisations payées (toutes années confondues) - * @param soldeEpargne Solde disponible sur l'ensemble des comptes épargne actifs - * @param soldeBloque Montant bloqué (garantie de prêt) - * @param soldeTotalDisponible soldeCotisations + soldeEpargne - soldeBloque - * @param encoursCreditTotal Montant total des prêts en cours (0 si fonctionnalité non encore activée) - * @param capaciteEmprunt Capacité d'emprunt estimée (3 × soldeEpargne selon règle mutuelle standard) - * - * @param nombreCotisationsPayees Nombre de cotisations payées (historique complet) - * @param nombreCotisationsTotal Nombre total de cotisations (payées + en attente + retard) - * @param nombreCotisationsEnRetard Nombre de cotisations en retard - * @param tauxEngagement Taux de paiement global en % (0-100) - * - * @param nombreComptesEpargne Nombre de comptes épargne actifs - * @param dateCalcul Date/heure du calcul (pour information client) - * * @author UnionFlow Team * @version 1.0 */ -public record CompteAdherentResponse( +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CompteAdherentResponse implements Serializable { - // ── Identité ────────────────────────────────────────────────────────── - String numeroMembre, - String nomComplet, - String organisationNom, - LocalDate dateAdhesion, - String statutCompte, + // ── Identité ────────────────────────────────────────────────────────── + /** Numéro unique du membre sur la plateforme (ex: MUF-2026-001) */ + private String numeroMembre; + /** Nom et prénom du membre */ + private String nomComplet; + /** Nom de l'organisation principale (ou null si aucune) */ + private String organisationNom; + /** Date d'inscription sur la plateforme */ + private LocalDate dateAdhesion; + /** Statut actuel du compte (ACTIF, SUSPENDU, etc.) */ + private String statutCompte; - // ── Soldes ──────────────────────────────────────────────────────────── - BigDecimal soldeCotisations, - BigDecimal soldeEpargne, - BigDecimal soldeBloque, - BigDecimal soldeTotalDisponible, - BigDecimal encoursCreditTotal, - BigDecimal capaciteEmprunt, + // ── Soldes ──────────────────────────────────────────────────────────── + /** Total des cotisations payées (toutes années confondues) */ + private BigDecimal soldeCotisations; + /** Solde disponible sur l'ensemble des comptes épargne actifs */ + private BigDecimal soldeEpargne; + /** Montant bloqué (garantie de prêt) */ + private BigDecimal soldeBloque; + /** soldeCotisations + soldeEpargne - soldeBloque */ + private BigDecimal soldeTotalDisponible; + /** Montant total des prêts en cours (0 si fonctionnalité non encore activée) */ + private BigDecimal encoursCreditTotal; + /** Capacité d'emprunt estimée (3 × soldeEpargne selon règle mutuelle standard) */ + private BigDecimal capaciteEmprunt; - // ── Cotisations ─────────────────────────────────────────────────────── - Integer nombreCotisationsPayees, - Integer nombreCotisationsTotal, - Integer nombreCotisationsEnRetard, - Integer tauxEngagement, + // ── Cotisations ─────────────────────────────────────────────────────── + /** Nombre de cotisations payées (historique complet) */ + private Integer nombreCotisationsPayees; + /** Nombre total de cotisations (payées + en attente + retard) */ + private Integer nombreCotisationsTotal; + /** Nombre de cotisations en retard */ + private Integer nombreCotisationsEnRetard; + /** Taux de paiement global en % (0-100) */ + private Integer tauxEngagement; - // ── Épargne ─────────────────────────────────────────────────────────── - Integer nombreComptesEpargne, + // ── Épargne ─────────────────────────────────────────────────────────── + /** Nombre de comptes épargne actifs */ + private Integer nombreComptesEpargne; - // ── Méta ────────────────────────────────────────────────────────────── - LocalDate dateCalcul - -) implements Serializable {} + // ── Méta ────────────────────────────────────────────────────────────── + /** Date/heure du calcul (pour information client) */ + private LocalDate dateCalcul; +} diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/membre/response/MembreSummaryResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/membre/response/MembreSummaryResponse.java index 1afc5df..bdaa08b 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/membre/response/MembreSummaryResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/membre/response/MembreSummaryResponse.java @@ -1,5 +1,9 @@ package dev.lions.unionflow.server.api.dto.membre.response; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.time.LocalDate; import java.util.List; import java.util.UUID; @@ -7,81 +11,56 @@ import java.util.UUID; /** * DTO de réponse résumé pour Membre (listes et optimisations). * - *

    Ce record expose des méthodes calculées pour la compatibilité JSF EL : - * {@link #nomComplet()}, {@link #statut()}, {@link #typeMembre()}, etc. + *

    Classe JavaBean pour compatibilité JSF EL (EL cherche getXxx()). + * Expose également des propriétés calculées (nomComplet, statut, typeMembre, etc.) */ -public record MembreSummaryResponse( - UUID id, - String numeroMembre, - String prenom, - String nom, - String email, - String telephone, - String profession, - String statutCompte, - String statutCompteLibelle, - String statutCompteSeverity, - Boolean actif, - List roles, - UUID organisationId, - String organisationNom, - LocalDate dateAdhesion) { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MembreSummaryResponse { - // ── Getters JavaBean pour compatibilité JSF EL (EL cherche getXxx()) ────── - - public UUID getId() { return id; } - public String getNumeroMembre() { return numeroMembre; } - public String getPrenom() { return prenom; } - public String getNom() { return nom; } - public String getEmail() { return email; } - public String getTelephone() { return telephone; } - public String getProfession() { return profession; } - public String getStatutCompte() { return statutCompte; } - public String getStatutCompteLibelle() { return statutCompteLibelle; } - public String getStatutCompteSeverity() { return statutCompteSeverity; } - public Boolean getActif() { return actif; } - public boolean isActif() { return Boolean.TRUE.equals(actif); } - public List getRoles() { return roles; } - public UUID getOrganisationId() { return organisationId; } - public String getOrganisationNom() { return organisationNom; } - public LocalDate getDateAdhesion() { return dateAdhesion; } - - // Getters JavaBean pour les propriétés calculées - public String getNomComplet() { return nomComplet(); } - public String getStatut() { return statut(); } - public String getStatutLibelle() { return statutLibelle(); } - public String getStatutSeverity() { return statutSeverity(); } - public String getStatutIcon() { return statutIcon(); } - public String getTypeMembre() { return typeMembre(); } - public String getTypeSeverity() { return typeSeverity(); } - public String getTypeIcon() { return typeIcon(); } + private UUID id; + private String numeroMembre; + private String prenom; + private String nom; + private String email; + private String telephone; + private String profession; + private String statutCompte; + private String statutCompteLibelle; + private String statutCompteSeverity; + private Boolean actif; + private List roles; + private UUID organisationId; + private String organisationNom; + private LocalDate dateAdhesion; // ── Propriétés calculées pour la compatibilité JSF EL ────────────────── /** Prénom + Nom concaténés. */ - public String nomComplet() { + public String getNomComplet() { String p = prenom != null ? prenom.trim() : ""; String n = nom != null ? nom.trim() : ""; return (p + " " + n).trim(); } - /** Alias de {@link #statutCompte()} pour #{membre.statut}. */ - public String statut() { + /** Alias de {@link #getStatutCompte()} pour #{membre.statut}. */ + public String getStatut() { return statutCompte; } - /** Alias de {@link #statutCompteLibelle()} pour #{membre.statutLibelle}. */ - public String statutLibelle() { + /** Alias de {@link #getStatutCompteLibelle()} pour #{membre.statutLibelle}. */ + public String getStatutLibelle() { return statutCompteLibelle; } - /** Alias de {@link #statutCompteSeverity()} pour #{membre.statutSeverity}. */ - public String statutSeverity() { + /** Alias de {@link #getStatutCompteSeverity()} pour #{membre.statutSeverity}. */ + public String getStatutSeverity() { return statutCompteSeverity; } - /** Icône PrimeIcons calculée depuis {@link #statutCompte()}. */ - public String statutIcon() { + /** Icône PrimeIcons calculée depuis {@link #getStatutCompte()}. */ + public String getStatutIcon() { if (statutCompte == null) return "pi pi-question-circle"; return switch (statutCompte) { case "ACTIF" -> "pi pi-check-circle"; @@ -92,8 +71,8 @@ public record MembreSummaryResponse( }; } - /** Libellé du rôle principal calculé depuis {@link #roles()}. */ - public String typeMembre() { + /** Libellé du rôle principal calculé depuis {@link #getRoles()}. */ + public String getTypeMembre() { if (roles == null || roles.isEmpty()) return "Membre"; if (roles.contains("PRESIDENT")) return "Président"; if (roles.contains("VICE_PRESIDENT")) return "Vice-Président"; @@ -104,8 +83,8 @@ public record MembreSummaryResponse( return "Membre"; } - /** Severity PrimeUI calculée depuis {@link #roles()}. */ - public String typeSeverity() { + /** Severity PrimeUI calculée depuis {@link #getRoles()}. */ + public String getTypeSeverity() { if (roles == null || roles.isEmpty()) return "secondary"; if (roles.contains("PRESIDENT")) return "primary"; if (roles.contains("VICE_PRESIDENT")) return "primary"; @@ -116,8 +95,8 @@ public record MembreSummaryResponse( return "secondary"; } - /** Icône PrimeIcons calculée depuis {@link #roles()}. */ - public String typeIcon() { + /** Icône PrimeIcons calculée depuis {@link #getRoles()}. */ + public String getTypeIcon() { if (roles == null || roles.isEmpty()) return "pi pi-user"; if (roles.contains("PRESIDENT")) return "pi pi-star"; if (roles.contains("VICE_PRESIDENT")) return "pi pi-star"; diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/organisation/response/OrganisationSummaryResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/organisation/response/OrganisationSummaryResponse.java index 7aa3353..711f201 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/organisation/response/OrganisationSummaryResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/organisation/response/OrganisationSummaryResponse.java @@ -1,23 +1,31 @@ package dev.lions.unionflow.server.api.dto.organisation.response; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.util.UUID; /** * Résumé d'une organisation pour les listes. + * Classe JavaBean (pas un record) pour compatibilité JSF/EL (getNom() requis). * * @author UnionFlow Team - * @version 3.0 + * @version 3.1 * @since 2026-02-22 */ -public record OrganisationSummaryResponse( - UUID id, - String nom, - String nomCourt, - String typeOrganisation, - String typeOrganisationLibelle, - String statut, - String statutLibelle, - String statutSeverity, - Integer nombreMembres, - Boolean actif) { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OrganisationSummaryResponse { + private UUID id; + private String nom; + private String nomCourt; + private String typeOrganisation; + private String typeOrganisationLibelle; + private String statut; + private String statutLibelle; + private String statutSeverity; + private Integer nombreMembres; + private Boolean actif; } diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/IntentionStatutResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/IntentionStatutResponse.java index 91c3c2e..0ec38de 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/IntentionStatutResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/IntentionStatutResponse.java @@ -1,24 +1,31 @@ package dev.lions.unionflow.server.api.dto.paiement.response; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.math.BigDecimal; import java.util.UUID; -import lombok.Builder; /** * Réponse du polling de statut d'une IntentionPaiement Wave. * Utilisée par le web pour savoir si le paiement est confirmé. */ +@Data +@NoArgsConstructor +@AllArgsConstructor @Builder -public record IntentionStatutResponse( - UUID intentionId, +public class IntentionStatutResponse { + private UUID intentionId; /** INITIEE | EN_COURS | COMPLETEE | EXPIREE | ECHOUEE */ - String statut, + private String statut; /** URL à encoder en QR code (wave_launch_url Wave Checkout) */ - String waveLaunchUrl, - String waveCheckoutSessionId, + private String waveLaunchUrl; + private String waveCheckoutSessionId; /** ID de transaction Wave (TCN...) — disponible quand COMPLETEE */ - String waveTransactionId, - BigDecimal montant, - String referenceCotisation, - String message -) {} + private String waveTransactionId; + private BigDecimal montant; + private String referenceCotisation; + private String message; +} diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/PaiementSummaryResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/PaiementSummaryResponse.java index e0a38ba..e95a1fd 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/PaiementSummaryResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/paiement/response/PaiementSummaryResponse.java @@ -1,5 +1,9 @@ package dev.lions.unionflow.server.api.dto.paiement.response; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.UUID; @@ -11,14 +15,17 @@ import java.util.UUID; * @author UnionFlow Team * @version 3.0 */ -public record PaiementSummaryResponse( - UUID id, - String numeroReference, - BigDecimal montant, - String codeDevise, - String methodePaiementLibelle, - String statutPaiement, - String statutPaiementLibelle, - String statutPaiementSeverity, - LocalDateTime datePaiement) { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PaiementSummaryResponse { + private UUID id; + private String numeroReference; + private BigDecimal montant; + private String codeDevise; + private String methodePaiementLibelle; + private String statutPaiement; + private String statutPaiementLibelle; + private String statutPaiementSeverity; + private LocalDateTime datePaiement; } diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequest.java b/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequest.java index ebfad22..b8ad671 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequest.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequest.java @@ -52,5 +52,17 @@ public record CreateTypeReferenceRequest( Boolean estSysteme, /** UUID de l'organisation (null = global). */ - UUID organisationId) { + UUID organisationId, + + /** + * Catégorie fonctionnelle (ex: FINANCIER_SOLIDAIRE). + * Obligatoire pour domaine=TYPE_ORGANISATION. + */ + @Size(max = 50) String categorie, + + /** + * Modules métier CSV (ex: "MEMBRES,COTISATIONS,TONTINE,FINANCE"). + * Obligatoire pour domaine=TYPE_ORGANISATION. + */ + String modulesRequis) { } diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequest.java b/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequest.java index 1472f60..d06dd37 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequest.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequest.java @@ -41,5 +41,11 @@ public record UpdateTypeReferenceRequest( Boolean estDefaut, /** Nouvel état actif/inactif (optionnel). */ - Boolean actif) { + Boolean actif, + + /** Nouvelle catégorie fonctionnelle (optionnel). */ + @Size(max = 50) String categorie, + + /** Nouveaux modules requis CSV (optionnel). */ + String modulesRequis) { } diff --git a/src/main/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponse.java b/src/main/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponse.java index a418096..607b00a 100644 --- a/src/main/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponse.java +++ b/src/main/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponse.java @@ -60,4 +60,19 @@ public class TypeReferenceResponse extends BaseResponse { /** UUID de l'organisation (null = global). */ private UUID organisationId; + + /** + * Catégorie fonctionnelle du type d'organisation. + * Valeurs: ASSOCIATIF, FINANCIER_SOLIDAIRE, RELIGIEUX, PROFESSIONNEL, RESEAU_FEDERATION. + * Uniquement pertinent pour domaine=TYPE_ORGANISATION. + */ + private String categorie; + + /** + * Modules métier activés pour ce type d'organisation (CSV). + * Exemple: "MEMBRES,COTISATIONS,TONTINE,FINANCE" + * Utilisé pour initialiser Organisation.modulesActifs à la création. + * Uniquement pertinent pour domaine=TYPE_ORGANISATION. + */ + private String modulesRequis; } diff --git a/src/test/java/dev/lions/unionflow/server/api/dto/common/ErrorResponseTest.java b/src/test/java/dev/lions/unionflow/server/api/dto/common/ErrorResponseTest.java new file mode 100644 index 0000000..13e9e07 --- /dev/null +++ b/src/test/java/dev/lions/unionflow/server/api/dto/common/ErrorResponseTest.java @@ -0,0 +1,32 @@ +package dev.lions.unionflow.server.api.dto.common; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class ErrorResponseTest { + + @Test + void testOf_messageUniquement() { + ErrorResponse response = ErrorResponse.of("Une erreur est survenue"); + + assertThat(response.message()).isEqualTo("Une erreur est survenue"); + assertThat(response.error()).isNull(); + } + + @Test + void testOfError_errorUniquement() { + ErrorResponse response = ErrorResponse.ofError("NOT_FOUND"); + + assertThat(response.message()).isNull(); + assertThat(response.error()).isEqualTo("NOT_FOUND"); + } + + @Test + void testConstructeurComplet() { + ErrorResponse response = new ErrorResponse("Message d'erreur", "VALIDATION_ERROR"); + + assertThat(response.message()).isEqualTo("Message d'erreur"); + assertThat(response.error()).isEqualTo("VALIDATION_ERROR"); + } +} diff --git a/src/test/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationResponseTest.java b/src/test/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationResponseTest.java index 7d8c441..aa0e8d4 100644 --- a/src/test/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationResponseTest.java +++ b/src/test/java/dev/lions/unionflow/server/api/dto/cotisation/response/CotisationResponseTest.java @@ -228,6 +228,28 @@ class CotisationResponseTest { } } + @Nested + @DisplayName("Alias getMethodePaiementLibelle") + class AliasMethodePaiement { + + @Test + @DisplayName("getMethodePaiementLibelle retourne modePaiementLibelle") + void getMethodePaiementLibelle_retourneModePaiementLibelle() { + CotisationResponse r = CotisationResponse.builder() + .modePaiementLibelle("Wave Money") + .build(); + + assertThat(r.getMethodePaiementLibelle()).isEqualTo("Wave Money"); + } + + @Test + @DisplayName("getMethodePaiementLibelle retourne null si non renseigné") + void getMethodePaiementLibelle_null() { + CotisationResponse r = CotisationResponse.builder().build(); + assertThat(r.getMethodePaiementLibelle()).isNull(); + } + } + @Nested @DisplayName("Builder complet") class BuilderComplet { diff --git a/src/test/java/dev/lions/unionflow/server/api/dto/membre/response/MembreResponseTest.java b/src/test/java/dev/lions/unionflow/server/api/dto/membre/response/MembreResponseTest.java new file mode 100644 index 0000000..54a0319 --- /dev/null +++ b/src/test/java/dev/lions/unionflow/server/api/dto/membre/response/MembreResponseTest.java @@ -0,0 +1,344 @@ +package dev.lions.unionflow.server.api.dto.membre.response; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +@DisplayName("Tests MembreResponse") +class MembreResponseTest { + + @Nested + @DisplayName("Builder et getters de base") + class BuilderGetters { + + @Test + @DisplayName("builder remplit tous les champs") + void builder_tousLesChamps() { + UUID id = UUID.randomUUID(); + UUID keycloakId = UUID.randomUUID(); + UUID orgId = UUID.randomUUID(); + LocalDate dateNaissance = LocalDate.of(1990, 5, 15); + LocalDate dateAdhesion = LocalDate.of(2024, 1, 10); + + MembreResponse m = MembreResponse.builder() + .numeroMembre("M-001") + .keycloakId(keycloakId) + .prenom("Jean") + .nom("Dupont") + .nomComplet("Jean Dupont") + .email("jean.dupont@example.com") + .telephone("+225001122334") + .telephoneWave("+225001122334") + .dateNaissance(dateNaissance) + .age(35) + .profession("Ingénieur") + .photoUrl("https://example.com/photo.jpg") + .statutMatrimonial("MARIE") + .statutMatrimonialLibelle("Marié") + .nationalite("Ivoirienne") + .typeIdentite("CNI") + .typeIdentiteLibelle("Carte Nationale d'Identité") + .numeroIdentite("CI12345") + .niveauVigilanceKyc("STANDARD") + .statutKyc("VERIFIE") + .dateVerificationIdentite(LocalDate.of(2024, 2, 1)) + .statutCompte("ACTIF") + .statutCompteLibelle("Actif") + .statutCompteSeverity("success") + .roles(Arrays.asList("MEMBRE")) + .organisationId(orgId) + .organisationNom("Club Lions Abidjan") + .dateAdhesion(dateAdhesion) + .adresse("123 Rue de la Paix") + .ville("Abidjan") + .codePostal("00225") + .notes("Membre actif") + .nombreEvenementsParticipes(5) + .motDePasseTemporaire("TempPass123!") + .build(); + m.setId(id); + + assertThat(m.getId()).isEqualTo(id); + assertThat(m.getNumeroMembre()).isEqualTo("M-001"); + assertThat(m.getKeycloakId()).isEqualTo(keycloakId); + assertThat(m.getPrenom()).isEqualTo("Jean"); + assertThat(m.getNom()).isEqualTo("Dupont"); + assertThat(m.getNomComplet()).isEqualTo("Jean Dupont"); + assertThat(m.getEmail()).isEqualTo("jean.dupont@example.com"); + assertThat(m.getTelephone()).isEqualTo("+225001122334"); + assertThat(m.getTelephoneWave()).isEqualTo("+225001122334"); + assertThat(m.getDateNaissance()).isEqualTo(dateNaissance); + assertThat(m.getAge()).isEqualTo(35); + assertThat(m.getProfession()).isEqualTo("Ingénieur"); + assertThat(m.getPhotoUrl()).isEqualTo("https://example.com/photo.jpg"); + assertThat(m.getStatutMatrimonial()).isEqualTo("MARIE"); + assertThat(m.getStatutMatrimonialLibelle()).isEqualTo("Marié"); + assertThat(m.getNationalite()).isEqualTo("Ivoirienne"); + assertThat(m.getTypeIdentite()).isEqualTo("CNI"); + assertThat(m.getTypeIdentiteLibelle()).isEqualTo("Carte Nationale d'Identité"); + assertThat(m.getNumeroIdentite()).isEqualTo("CI12345"); + assertThat(m.getNiveauVigilanceKyc()).isEqualTo("STANDARD"); + assertThat(m.getStatutKyc()).isEqualTo("VERIFIE"); + assertThat(m.getDateVerificationIdentite()).isEqualTo(LocalDate.of(2024, 2, 1)); + assertThat(m.getStatutCompte()).isEqualTo("ACTIF"); + assertThat(m.getStatutCompteLibelle()).isEqualTo("Actif"); + assertThat(m.getStatutCompteSeverity()).isEqualTo("success"); + assertThat(m.getRoles()).containsExactly("MEMBRE"); + assertThat(m.getOrganisationId()).isEqualTo(orgId); + assertThat(m.getOrganisationNom()).isEqualTo("Club Lions Abidjan"); + assertThat(m.getDateAdhesion()).isEqualTo(dateAdhesion); + assertThat(m.getAdresse()).isEqualTo("123 Rue de la Paix"); + assertThat(m.getVille()).isEqualTo("Abidjan"); + assertThat(m.getCodePostal()).isEqualTo("00225"); + assertThat(m.getNotes()).isEqualTo("Membre actif"); + assertThat(m.getNombreEvenementsParticipes()).isEqualTo(5); + assertThat(m.getMotDePasseTemporaire()).isEqualTo("TempPass123!"); + } + + @Test + @DisplayName("constructeur vide produit un objet non null") + void constructeurVide() { + MembreResponse m = new MembreResponse(); + assertThat(m).isNotNull(); + assertThat(m.getPrenom()).isNull(); + assertThat(m.getNom()).isNull(); + } + + @Test + @DisplayName("setters mettent à jour les champs") + void setters_mettentAJour() { + MembreResponse m = new MembreResponse(); + m.setPrenom("Marie"); + m.setNom("Martin"); + m.setEmail("marie.martin@example.com"); + m.setStatutCompte("INACTIF"); + m.setStatutCompteSeverity("secondary"); + m.setDateAdhesion(LocalDate.of(2023, 6, 1)); + + assertThat(m.getPrenom()).isEqualTo("Marie"); + assertThat(m.getNom()).isEqualTo("Martin"); + assertThat(m.getEmail()).isEqualTo("marie.martin@example.com"); + } + } + + @Nested + @DisplayName("getInitiales") + class GetInitiales { + + @Test + @DisplayName("retourne initiales quand prénom et nom sont renseignés") + void initiales_prenomNomPresents() { + MembreResponse m = MembreResponse.builder().prenom("Jean").nom("Dupont").build(); + assertThat(m.getInitiales()).isEqualTo("JD"); + } + + @Test + @DisplayName("retourne initiale du prénom uniquement si nom null") + void initiales_nomNull() { + MembreResponse m = MembreResponse.builder().prenom("Jean").nom(null).build(); + assertThat(m.getInitiales()).isEqualTo("J"); + } + + @Test + @DisplayName("retourne initiale du nom uniquement si prénom null") + void initiales_prenomNull() { + MembreResponse m = MembreResponse.builder().prenom(null).nom("Dupont").build(); + assertThat(m.getInitiales()).isEqualTo("D"); + } + + @Test + @DisplayName("retourne chaîne vide si prénom et nom vides") + void initiales_prenomNomVides() { + MembreResponse m = MembreResponse.builder().prenom("").nom("").build(); + assertThat(m.getInitiales()).isEmpty(); + } + + @Test + @DisplayName("retourne chaîne vide si prénom et nom null") + void initiales_prenomNomNull() { + MembreResponse m = new MembreResponse(); + assertThat(m.getInitiales()).isEmpty(); + } + } + + @Nested + @DisplayName("getDateAdhesionFormatee") + class GetDateAdhesionFormatee { + + @Test + @DisplayName("retourne null quand dateAdhesion est null") + void dateAdhesion_null() { + MembreResponse m = new MembreResponse(); + assertThat(m.getDateAdhesionFormatee()).isNull(); + } + + @Test + @DisplayName("retourne date formatée dd/MM/yyyy") + void dateAdhesion_formatee() { + MembreResponse m = MembreResponse.builder().dateAdhesion(LocalDate.of(2024, 3, 15)).build(); + assertThat(m.getDateAdhesionFormatee()).isEqualTo("15/03/2024"); + } + } + + @Nested + @DisplayName("getStatut et getStatutSeverity") + class AliasStatut { + + @Test + @DisplayName("getStatut retourne statutCompte") + void getStatut() { + MembreResponse m = MembreResponse.builder().statutCompte("ACTIF").build(); + assertThat(m.getStatut()).isEqualTo("ACTIF"); + } + + @Test + @DisplayName("getStatutSeverity retourne statutCompteSeverity") + void getStatutSeverity() { + MembreResponse m = MembreResponse.builder().statutCompteSeverity("warning").build(); + assertThat(m.getStatutSeverity()).isEqualTo("warning"); + } + } + + @Nested + @DisplayName("getTypeMembre") + class GetTypeMembre { + + @Test + @DisplayName("retourne Membre quand roles null") + void typeMembre_rolesNull() { + MembreResponse m = new MembreResponse(); + assertThat(m.getTypeMembre()).isEqualTo("Membre"); + } + + @Test + @DisplayName("retourne Membre quand roles vide") + void typeMembre_rolesVide() { + MembreResponse m = MembreResponse.builder().roles(Collections.emptyList()).build(); + assertThat(m.getTypeMembre()).isEqualTo("Membre"); + } + + @Test + @DisplayName("retourne Président quand rôle PRESIDENT") + void typeMembre_president() { + MembreResponse m = MembreResponse.builder().roles(List.of("PRESIDENT")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Président"); + } + + @Test + @DisplayName("retourne Vice-Président quand rôle VICE_PRESIDENT") + void typeMembre_vicePresident() { + MembreResponse m = MembreResponse.builder().roles(List.of("VICE_PRESIDENT")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Vice-Président"); + } + + @Test + @DisplayName("retourne Secrétaire quand rôle SECRETAIRE") + void typeMembre_secretaire() { + MembreResponse m = MembreResponse.builder().roles(List.of("SECRETAIRE")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Secrétaire"); + } + + @Test + @DisplayName("retourne Trésorier quand rôle TRESORIER") + void typeMembre_tresorier() { + MembreResponse m = MembreResponse.builder().roles(List.of("TRESORIER")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Trésorier"); + } + + @Test + @DisplayName("retourne Administrateur quand rôle ADMIN_ORGANISATION") + void typeMembre_adminOrganisation() { + MembreResponse m = MembreResponse.builder().roles(List.of("ADMIN_ORGANISATION")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Administrateur"); + } + + @Test + @DisplayName("retourne Modérateur quand rôle MODERATEUR") + void typeMembre_moderateur() { + MembreResponse m = MembreResponse.builder().roles(List.of("MODERATEUR")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Modérateur"); + } + + @Test + @DisplayName("retourne Membre pour rôle inconnu") + void typeMembre_roleInconnu() { + MembreResponse m = MembreResponse.builder().roles(List.of("AUTRE_ROLE")).build(); + assertThat(m.getTypeMembre()).isEqualTo("Membre"); + } + } + + @Nested + @DisplayName("getTypeSeverity") + class GetTypeSeverity { + + @Test + @DisplayName("retourne secondary quand roles null") + void typeSeverity_rolesNull() { + MembreResponse m = new MembreResponse(); + assertThat(m.getTypeSeverity()).isEqualTo("secondary"); + } + + @Test + @DisplayName("retourne secondary quand roles vide") + void typeSeverity_rolesVide() { + MembreResponse m = MembreResponse.builder().roles(Collections.emptyList()).build(); + assertThat(m.getTypeSeverity()).isEqualTo("secondary"); + } + + @Test + @DisplayName("retourne primary pour PRESIDENT") + void typeSeverity_president() { + MembreResponse m = MembreResponse.builder().roles(List.of("PRESIDENT")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("primary"); + } + + @Test + @DisplayName("retourne primary pour VICE_PRESIDENT") + void typeSeverity_vicePresident() { + MembreResponse m = MembreResponse.builder().roles(List.of("VICE_PRESIDENT")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("primary"); + } + + @Test + @DisplayName("retourne info pour SECRETAIRE") + void typeSeverity_secretaire() { + MembreResponse m = MembreResponse.builder().roles(List.of("SECRETAIRE")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("info"); + } + + @Test + @DisplayName("retourne warning pour TRESORIER") + void typeSeverity_tresorier() { + MembreResponse m = MembreResponse.builder().roles(List.of("TRESORIER")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("warning"); + } + + @Test + @DisplayName("retourne danger pour ADMIN_ORGANISATION") + void typeSeverity_adminOrganisation() { + MembreResponse m = MembreResponse.builder().roles(List.of("ADMIN_ORGANISATION")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("danger"); + } + + @Test + @DisplayName("retourne warning pour MODERATEUR") + void typeSeverity_moderateur() { + MembreResponse m = MembreResponse.builder().roles(List.of("MODERATEUR")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("warning"); + } + + @Test + @DisplayName("retourne secondary pour rôle inconnu") + void typeSeverity_roleInconnu() { + MembreResponse m = MembreResponse.builder().roles(List.of("INCONNU")).build(); + assertThat(m.getTypeSeverity()).isEqualTo("secondary"); + } + } +} diff --git a/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequestTest.java b/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequestTest.java index 63327a7..ca557c7 100644 --- a/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequestTest.java +++ b/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/CreateTypeReferenceRequestTest.java @@ -37,6 +37,8 @@ class CreateTypeReferenceRequestTest { .estDefaut(true) .estSysteme(true) .organisationId(organisationId) + .categorie("FINANCIER_SOLIDAIRE") + .modulesRequis("MEMBRES,COTISATIONS,TONTINE,FINANCE") .build(); assertThat(request).isNotNull(); @@ -51,6 +53,8 @@ class CreateTypeReferenceRequestTest { assertThat(request.estDefaut()).isTrue(); assertThat(request.estSysteme()).isTrue(); assertThat(request.organisationId()).isEqualTo(organisationId); + assertThat(request.categorie()).isEqualTo("FINANCIER_SOLIDAIRE"); + assertThat(request.modulesRequis()).isEqualTo("MEMBRES,COTISATIONS,TONTINE,FINANCE"); } @Test diff --git a/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequestTest.java b/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequestTest.java index c4f6f29..0a0cbfa 100644 --- a/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequestTest.java +++ b/src/test/java/dev/lions/unionflow/server/api/dto/reference/request/UpdateTypeReferenceRequestTest.java @@ -31,7 +31,9 @@ class UpdateTypeReferenceRequestTest { "warning", 5, true, - false + false, + "FINANCIER_SOLIDAIRE", + "MEMBRES,COTISATIONS,TONTINE" ); assertThat(request).isNotNull(); @@ -44,6 +46,8 @@ class UpdateTypeReferenceRequestTest { assertThat(request.ordreAffichage()).isEqualTo(5); assertThat(request.estDefaut()).isTrue(); assertThat(request.actif()).isFalse(); + assertThat(request.categorie()).isEqualTo("FINANCIER_SOLIDAIRE"); + assertThat(request.modulesRequis()).isEqualTo("MEMBRES,COTISATIONS,TONTINE"); } @Test @@ -57,11 +61,15 @@ class UpdateTypeReferenceRequestTest { null, null, null, + null, + null, null ); assertThat(request).isNotNull(); assertThat(request.libelle()).isEqualTo("Libellé mis à jour"); + assertThat(request.categorie()).isNull(); + assertThat(request.modulesRequis()).isNull(); } @Test @@ -76,6 +84,8 @@ class UpdateTypeReferenceRequestTest { null, null, null, + null, + null, null ); @@ -97,6 +107,8 @@ class UpdateTypeReferenceRequestTest { null, null, null, + null, + null, null ); @@ -106,6 +118,29 @@ class UpdateTypeReferenceRequestTest { assertThat(violations).anyMatch(v -> v.getPropertyPath().toString().equals("libelle")); } + @Test + void testValidation_CategorieTooLong() { + String longCategorie = "A".repeat(51); + UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest( + null, + null, + null, + null, + null, + null, + null, + null, + null, + longCategorie, + null + ); + + Set> violations = validator.validate(request); + + assertThat(violations).isNotEmpty(); + assertThat(violations).anyMatch(v -> v.getPropertyPath().toString().equals("categorie")); + } + @Test void testValidation_ValidFields() { UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest( @@ -117,7 +152,9 @@ class UpdateTypeReferenceRequestTest { "success", 1, false, - true + true, + "ASSOCIATIF", + "MEMBRES,COTISATIONS" ); Set> violations = validator.validate(request); @@ -136,7 +173,9 @@ class UpdateTypeReferenceRequestTest { null, null, null, - true + true, + "ASSOCIATIF", + "MEMBRES" ); UpdateTypeReferenceRequest request2 = new UpdateTypeReferenceRequest( @@ -148,7 +187,9 @@ class UpdateTypeReferenceRequestTest { null, null, null, - true + true, + "ASSOCIATIF", + "MEMBRES" ); assertThat(request1).isEqualTo(request2); @@ -166,7 +207,9 @@ class UpdateTypeReferenceRequestTest { null, null, null, - true + true, + "FINANCIER_SOLIDAIRE", + "MEMBRES,TONTINE" ); String toString = request.toString(); @@ -174,5 +217,6 @@ class UpdateTypeReferenceRequestTest { assertThat(toString).isNotNull(); assertThat(toString).contains("UpdateTypeReferenceRequest"); assertThat(toString).contains("CODE_UPDATE"); + assertThat(toString).contains("FINANCIER_SOLIDAIRE"); } } diff --git a/src/test/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponseTest.java b/src/test/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponseTest.java new file mode 100644 index 0000000..a7d3625 --- /dev/null +++ b/src/test/java/dev/lions/unionflow/server/api/dto/reference/response/TypeReferenceResponseTest.java @@ -0,0 +1,141 @@ +package dev.lions.unionflow.server.api.dto.reference.response; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDateTime; +import java.util.UUID; +import org.junit.jupiter.api.Test; + +class TypeReferenceResponseTest { + + @Test + void testBuilder_AllFields() { + UUID id = UUID.randomUUID(); + UUID orgId = UUID.randomUUID(); + LocalDateTime now = LocalDateTime.now(); + + TypeReferenceResponse response = TypeReferenceResponse.builder() + .domaine("TYPE_ORGANISATION") + .code("TONTINE") + .libelle("Tontine") + .description("Organisation de type tontine") + .icone("pi-money-bill") + .couleur("#F59E0B") + .severity("warning") + .ordreAffichage(1) + .estDefaut(false) + .estSysteme(true) + .organisationId(orgId) + .categorie("FINANCIER_SOLIDAIRE") + .modulesRequis("MEMBRES,COTISATIONS,TONTINE,FINANCE") + .build(); + + response.setId(id); + response.setDateCreation(now); + response.setDateModification(now); + response.setCreePar("admin@test.com"); + response.setModifiePar("admin@test.com"); + response.setVersion(1L); + response.setActif(true); + + assertThat(response.getDomaine()).isEqualTo("TYPE_ORGANISATION"); + assertThat(response.getCode()).isEqualTo("TONTINE"); + assertThat(response.getLibelle()).isEqualTo("Tontine"); + assertThat(response.getDescription()).isEqualTo("Organisation de type tontine"); + assertThat(response.getIcone()).isEqualTo("pi-money-bill"); + assertThat(response.getCouleur()).isEqualTo("#F59E0B"); + assertThat(response.getSeverity()).isEqualTo("warning"); + assertThat(response.getOrdreAffichage()).isEqualTo(1); + assertThat(response.getEstDefaut()).isFalse(); + assertThat(response.getEstSysteme()).isTrue(); + assertThat(response.getOrganisationId()).isEqualTo(orgId); + assertThat(response.getCategorie()).isEqualTo("FINANCIER_SOLIDAIRE"); + assertThat(response.getModulesRequis()).isEqualTo("MEMBRES,COTISATIONS,TONTINE,FINANCE"); + assertThat(response.getId()).isEqualTo(id); + assertThat(response.getDateCreation()).isEqualTo(now); + assertThat(response.getDateModification()).isEqualTo(now); + assertThat(response.getCreePar()).isEqualTo("admin@test.com"); + assertThat(response.getModifiePar()).isEqualTo("admin@test.com"); + assertThat(response.getVersion()).isEqualTo(1L); + assertThat(response.getActif()).isTrue(); + } + + @Test + void testNoArgsConstructor() { + TypeReferenceResponse response = new TypeReferenceResponse(); + + assertThat(response).isNotNull(); + assertThat(response.getDomaine()).isNull(); + assertThat(response.getCode()).isNull(); + assertThat(response.getCategorie()).isNull(); + assertThat(response.getModulesRequis()).isNull(); + } + + @Test + void testAllArgsConstructor() { + UUID orgId = UUID.randomUUID(); + + TypeReferenceResponse response = new TypeReferenceResponse( + "TYPE_ORGANISATION", + "MUTUELLE", + "Mutuelle d'épargne", + "Description mutuelle", + "pi-wallet", + "#6366F1", + "info", + 2, + true, + false, + orgId, + "FINANCIER_SOLIDAIRE", + "MEMBRES,EPARGNE,CREDIT" + ); + + assertThat(response.getDomaine()).isEqualTo("TYPE_ORGANISATION"); + assertThat(response.getCode()).isEqualTo("MUTUELLE"); + assertThat(response.getLibelle()).isEqualTo("Mutuelle d'épargne"); + assertThat(response.getCategorie()).isEqualTo("FINANCIER_SOLIDAIRE"); + assertThat(response.getModulesRequis()).isEqualTo("MEMBRES,EPARGNE,CREDIT"); + assertThat(response.getEstDefaut()).isTrue(); + assertThat(response.getEstSysteme()).isFalse(); + assertThat(response.getOrganisationId()).isEqualTo(orgId); + } + + @Test + void testSetters() { + TypeReferenceResponse response = new TypeReferenceResponse(); + + response.setDomaine("STATUT_MEMBRE"); + response.setCode("ACTIF"); + response.setLibelle("Membre Actif"); + response.setDescription("Description"); + response.setIcone("pi-user"); + response.setCouleur("#22C55E"); + response.setSeverity("success"); + response.setOrdreAffichage(1); + response.setEstDefaut(true); + response.setEstSysteme(false); + response.setOrganisationId(null); + response.setCategorie("ASSOCIATIF"); + response.setModulesRequis("MEMBRES,COTISATIONS"); + + assertThat(response.getDomaine()).isEqualTo("STATUT_MEMBRE"); + assertThat(response.getCode()).isEqualTo("ACTIF"); + assertThat(response.getCategorie()).isEqualTo("ASSOCIATIF"); + assertThat(response.getModulesRequis()).isEqualTo("MEMBRES,COTISATIONS"); + } + + @Test + void testEqualsAndHashCode() { + UUID id = UUID.randomUUID(); + + TypeReferenceResponse r1 = TypeReferenceResponse.builder().build(); + r1.setId(id); + + TypeReferenceResponse r2 = TypeReferenceResponse.builder().build(); + r2.setId(id); + + assertThat(r1).isEqualTo(r2); + assertThat(r1.hashCode()).isEqualTo(r2.hashCode()); + } +}