fix: Correction des boutons d'action dans organisation/liste.xhtml et corrections diverses

- Alignement des boutons d'action avec membre/liste.xhtml (icônes seulement, style rounded)
- Remplacement findByIdOptional par find[Entity]ById dans tous les repositories
- Correction des erreurs de compilation UUID vs Long
- Correction du test MembreServiceAdvancedSearchTest (suppression assignation roles String)
- Ajout de méthodes find[Entity]ById dans tous les repositories
- Mise à jour des services pour utiliser les nouvelles méthodes de repository
- Correction des appels order() vers Sort.by() dans les repositories
- Suppression des tests obsolètes dans unionflow-server-api
This commit is contained in:
dahoud
2025-11-30 16:18:38 +00:00
parent 950392e63f
commit e92acf44e6
51 changed files with 349 additions and 1687 deletions

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{cotisationsBean}"/>
<ui:define name="title">Gestion des Cotisations - UnionFlow</ui:define> <ui:define name="title">Gestion des Cotisations - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{evenementsBean}"/>
<ui:define name="title">Bilan des Événements - UnionFlow</ui:define> <ui:define name="title">Bilan des Événements - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{evenementsBean}"/>
<ui:define name="title">Création d'Événement - UnionFlow</ui:define> <ui:define name="title">Création d'Événement - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">
@@ -61,7 +62,7 @@
<ui:param name="label" value="Type d'événement *" /> <ui:param name="label" value="Type d'événement *" />
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.typeEvenement}" /> <ui:param name="value" value="#{evenementsBean.nouvelEvenement.typeEvenement}" />
<ui:param name="required" value="true" /> <ui:param name="required" value="true" />
<ui:define name="items"> <ui:param name="items">
<f:selectItem itemLabel="Sélectionner un type" itemValue="" /> <f:selectItem itemLabel="Sélectionner un type" itemValue="" />
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" /> <f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
<f:selectItem itemLabel="Formation" itemValue="FORMATION" /> <f:selectItem itemLabel="Formation" itemValue="FORMATION" />
@@ -72,7 +73,7 @@
<f:selectItem itemLabel="Atelier" itemValue="ATELIER" /> <f:selectItem itemLabel="Atelier" itemValue="ATELIER" />
<f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" /> <f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" />
<f:selectItem itemLabel="Autre" itemValue="AUTRE" /> <f:selectItem itemLabel="Autre" itemValue="AUTRE" />
</ui:define> </ui:param>
</ui:include> </ui:include>
</div> </div>
@@ -81,12 +82,12 @@
<ui:param name="id" value="priorite" /> <ui:param name="id" value="priorite" />
<ui:param name="label" value="Priorité" /> <ui:param name="label" value="Priorité" />
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.priorite}" /> <ui:param name="value" value="#{evenementsBean.nouvelEvenement.priorite}" />
<ui:define name="items"> <ui:param name="items">
<f:selectItem itemLabel="Normale" itemValue="NORMALE" /> <f:selectItem itemLabel="Normale" itemValue="NORMALE" />
<f:selectItem itemLabel="Haute" itemValue="HAUTE" /> <f:selectItem itemLabel="Haute" itemValue="HAUTE" />
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" /> <f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
<f:selectItem itemLabel="Basse" itemValue="BASSE" /> <f:selectItem itemLabel="Basse" itemValue="BASSE" />
</ui:define> </ui:param>
</ui:include> </ui:include>
</div> </div>
</div> </div>

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{evenementsBean}"/>
<ui:define name="title">Gestion des Événements - UnionFlow</ui:define> <ui:define name="title">Gestion des Événements - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">
@@ -283,7 +284,7 @@
<ui:param name="label" value="Type d'événement *" /> <ui:param name="label" value="Type d'événement *" />
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.typeEvenement}" /> <ui:param name="value" value="#{evenementsBean.nouvelEvenement.typeEvenement}" />
<ui:param name="required" value="true" /> <ui:param name="required" value="true" />
<ui:define name="items"> <ui:param name="items">
<f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" /> <f:selectItem itemLabel="Assemblée Générale" itemValue="ASSEMBLEE_GENERALE" />
<f:selectItem itemLabel="Formation" itemValue="FORMATION" /> <f:selectItem itemLabel="Formation" itemValue="FORMATION" />
<f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" /> <f:selectItem itemLabel="Activité Sociale" itemValue="ACTIVITE_SOCIALE" />
@@ -293,7 +294,7 @@
<f:selectItem itemLabel="Atelier" itemValue="ATELIER" /> <f:selectItem itemLabel="Atelier" itemValue="ATELIER" />
<f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" /> <f:selectItem itemLabel="Cérémonie" itemValue="CEREMONIE" />
<f:selectItem itemLabel="Autre" itemValue="AUTRE" /> <f:selectItem itemLabel="Autre" itemValue="AUTRE" />
</ui:define> </ui:param>
</ui:include> </ui:include>
</div> </div>
@@ -302,12 +303,12 @@
<ui:param name="id" value="priorite" /> <ui:param name="id" value="priorite" />
<ui:param name="label" value="Priorité" /> <ui:param name="label" value="Priorité" />
<ui:param name="value" value="#{evenementsBean.nouvelEvenement.priorite}" /> <ui:param name="value" value="#{evenementsBean.nouvelEvenement.priorite}" />
<ui:define name="items"> <ui:param name="items">
<f:selectItem itemLabel="Critique" itemValue="CRITIQUE" /> <f:selectItem itemLabel="Critique" itemValue="CRITIQUE" />
<f:selectItem itemLabel="Haute" itemValue="HAUTE" /> <f:selectItem itemLabel="Haute" itemValue="HAUTE" />
<f:selectItem itemLabel="Normale" itemValue="NORMALE" /> <f:selectItem itemLabel="Normale" itemValue="NORMALE" />
<f:selectItem itemLabel="Basse" itemValue="BASSE" /> <f:selectItem itemLabel="Basse" itemValue="BASSE" />
</ui:define> </ui:param>
</ui:include> </ui:include>
</div> </div>
@@ -485,14 +486,14 @@
<ui:param name="id" value="statutModif" /> <ui:param name="id" value="statutModif" />
<ui:param name="label" value="Statut" /> <ui:param name="label" value="Statut" />
<ui:param name="value" value="#{evenementsBean.evenementSelectionne.statut}" /> <ui:param name="value" value="#{evenementsBean.evenementSelectionne.statut}" />
<ui:define name="items"> <ui:param name="items">
<f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" /> <f:selectItem itemLabel="Planifié" itemValue="PLANIFIE" />
<f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" /> <f:selectItem itemLabel="Confirmé" itemValue="CONFIRME" />
<f:selectItem itemLabel="En cours" itemValue="EN_COURS" /> <f:selectItem itemLabel="En cours" itemValue="EN_COURS" />
<f:selectItem itemLabel="Terminé" itemValue="TERMINE" /> <f:selectItem itemLabel="Terminé" itemValue="TERMINE" />
<f:selectItem itemLabel="Annulé" itemValue="ANNULE" /> <f:selectItem itemLabel="Annulé" itemValue="ANNULE" />
<f:selectItem itemLabel="Reporté" itemValue="REPORTE" /> <f:selectItem itemLabel="Reporté" itemValue="REPORTE" />
</ui:define> </ui:param>
</ui:include> </ui:include>
</div> </div>

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{evenementsBean}"/>
<ui:define name="title">Logistique des Événements - UnionFlow</ui:define> <ui:define name="title">Logistique des Événements - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{evenementsBean}"/>
<ui:define name="title">Planification des Événements - UnionFlow</ui:define> <ui:define name="title">Planification des Événements - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{evenementsBean}"/>
<ui:define name="title">Réservations d'Événements - UnionFlow</ui:define> <ui:define name="title">Réservations d'Événements - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{membreInscriptionBean}"/>
<ui:define name="title">Inscription Membre - UnionFlow</ui:define> <ui:define name="title">Inscription Membre - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -7,6 +7,7 @@
xmlns:uf="http://xmlns.jcp.org/jsf/composite/components" xmlns:uf="http://xmlns.jcp.org/jsf/composite/components"
template="/templates/main-template.xhtml"> template="/templates/main-template.xhtml">
<ui:param name="page" value="#{membreListeBean}"/>
<ui:define name="title">Liste des Membres - UnionFlow</ui:define> <ui:define name="title">Liste des Membres - UnionFlow</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui"> xmlns:p="http://primefaces.org/ui">
<ui:composition template="/templates/main-template.xhtml"> <ui:composition template="/templates/main-template.xhtml">
<ui:param name="page" value="#{organisationDetailBean}"/>
<ui:define name="title">Détail de l'Organisation</ui:define> <ui:define name="title">Détail de l'Organisation</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -7,6 +7,7 @@
xmlns:uf="http://xmlns.jcp.org/jsf/composite/components"> xmlns:uf="http://xmlns.jcp.org/jsf/composite/components">
<ui:composition template="/templates/main-template.xhtml"> <ui:composition template="/templates/main-template.xhtml">
<ui:param name="page" value="#{organisationsBean}"/>
<ui:define name="title">Gestion des Organisations</ui:define> <ui:define name="title">Gestion des Organisations</ui:define>
<ui:define name="content"> <ui:define name="content">
@@ -167,29 +168,40 @@
</p:column> </p:column>
<!-- Actions (DRY/WOU: Composite Components) --> <!-- Actions (DRY/WOU: Composite Components) -->
<p:column headerText="Actions" style="width: 320px;"> <p:column headerText="Actions" style="width:200px">
<!-- DRY/WOU: Composite Component action-button-view --> <div class="flex gap-1">
<uf:action-button-view itemId="#{org.id}" <!-- DRY/WOU: Composite Component action-button-view -->
detailPage="/pages/secure/organisation/detail.xhtml" <uf:action-button-view itemId="#{org.id.toString()}"
styleClass="mr-2"/> detailPage="/pages/secure/organisation/detail.xhtml"
iconOnly="true"/>
<!-- DRY/WOU: Composite Component action-button-edit --> <!-- DRY/WOU: button-icon pour Modifier -->
<uf:action-button-edit actionListener="#{organisationsBean.setOrganisationSelectionnee(org)}" <p:commandButton icon="pi pi-pencil"
update=":formModifier" actionListener="#{organisationsBean.setOrganisationSelectionnee(org)}"
dialogWidget="dlgModifier" oncomplete="PF('dlgModifier').show();"
styleClass="mr-2"/> update=":formModifier"
styleClass="ui-button-rounded ui-button-warning"
<!-- DRY/WOU: Composite Component action-button-toggle --> title="Modifier"/>
<uf:action-button-toggle actionListener="#{organisationsBean.basculerStatutOrganisation(org)}" <!-- DRY/WOU: button-icon pour Activer/Désactiver -->
update=":formOrganisations:dtOrganisations :formOrganisations:messages" <p:commandButton icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-ban' : 'pi pi-check'}"
isActive="#{org.statut == organisationsBean.statutActive}" actionListener="#{organisationsBean.basculerStatutOrganisation(org)}"
confirmMessage="Êtes-vous sûr de vouloir changer le statut de cette organisation ?" update=":formOrganisations:dtOrganisations :formOrganisations:messages"
styleClass="mr-2"/> styleClass="ui-button-rounded #{org.statut == organisationsBean.statutActive ? 'ui-button-secondary' : 'ui-button-success'}"
title="#{org.statut == organisationsBean.statutActive ? 'Désactiver' : 'Activer'}">
<!-- DRY/WOU: Composite Component action-button-delete --> <p:confirm header="Confirmation"
<uf:action-button-delete actionListener="#{organisationsBean.supprimerOrganisation(org)}" message="Êtes-vous sûr de vouloir changer le statut de cette organisation ?"
update=":formOrganisations:dtOrganisations :formOrganisations:messages" icon="pi pi-exclamation-triangle"/>
confirmMessage="Êtes-vous sûr de vouloir supprimer cette organisation ? Cette action est irréversible."/> </p:commandButton>
<!-- DRY/WOU: button-icon pour Supprimer -->
<p:commandButton icon="pi pi-trash"
actionListener="#{organisationsBean.supprimerOrganisation(org)}"
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
styleClass="ui-button-rounded ui-button-danger"
title="Supprimer">
<p:confirm header="Confirmation"
message="Êtes-vous sûr de vouloir supprimer cette organisation ? Cette action est irréversible."
icon="pi pi-exclamation-triangle"/>
</p:commandButton>
</div>
</p:column> </p:column>
</p:dataTable> </p:dataTable>
</ui:define> </ui:define>
@@ -227,12 +239,10 @@
<ui:decorate template="/templates/components/buttons/button-form-submit.xhtml"> <ui:decorate template="/templates/components/buttons/button-form-submit.xhtml">
<ui:param name="value" value="Enregistrer" /> <ui:param name="value" value="Enregistrer" />
<ui:param name="icon" value="pi pi-check" /> <ui:param name="icon" value="pi pi-check" />
<ui:param name="action" value="#{organisationsBean.modifierOrganisation}" />
<ui:param name="update" value=":formOrganisations:dtOrganisations :formOrganisations:messages" /> <ui:param name="update" value=":formOrganisations:dtOrganisations :formOrganisations:messages" />
<ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgModifier').hide();" /> <ui:param name="oncomplete" value="if(!args.validationFailed) PF('dlgModifier').hide();" />
<ui:param name="severity" value="success" /> <ui:param name="severity" value="success" />
<ui:define name="action">
#{organisationsBean.modifierOrganisation}
</ui:define>
</ui:decorate> </ui:decorate>
</ui:define> </ui:define>
</ui:decorate> </ui:decorate>

View File

@@ -6,6 +6,7 @@
xmlns:p="http://primefaces.org/ui"> xmlns:p="http://primefaces.org/ui">
<ui:composition template="/templates/main-template.xhtml"> <ui:composition template="/templates/main-template.xhtml">
<ui:param name="page" value="#{organisationsBean}"/>
<ui:define name="title">Nouvelle Organisation</ui:define> <ui:define name="title">Nouvelle Organisation</ui:define>
<ui:define name="content"> <ui:define name="content">

View File

@@ -0,0 +1,33 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<!--
Composant bouton de soumission de formulaire réutilisable (WOU/DRY)
Usage: <ui:decorate template="/templates/components/buttons/button-form-submit.xhtml">
<ui:param name="value" value="Enregistrer" />
<ui:param name="icon" value="pi pi-check" />
<ui:param name="action" value="#{bean.method}" />
<ui:param name="update" value="componentId" />
<ui:param name="oncomplete" value="javascript" />
<ui:param name="severity" value="success|primary|info|warning|danger" />
<ui:param name="disabled" value="false" />
<ui:param name="styleClass" value="" />
</ui:decorate>
-->
<ui:fragment rendered="#{empty rendered or rendered}">
<p:commandButton
value="#{value}"
icon="#{icon}"
action="#{action}"
update="#{update}"
oncomplete="#{oncomplete}"
disabled="#{not empty disabled and disabled}"
styleClass="ui-button-#{empty severity ? 'primary' : severity} #{not empty styleClass ? styleClass : ''}"
title="#{title}" />
</ui:fragment>
</ui:composition>

View File

@@ -26,19 +26,15 @@
disabled="#{not empty readonly and readonly}" disabled="#{not empty readonly and readonly}"
styleClass="w-full"> styleClass="w-full">
<f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" rendered="#{not empty required and required}" /> <f:selectItem itemLabel="Sélectionner..." itemValue="" noSelectionOption="true" rendered="#{not empty required and required}" />
<!-- Support pour ui:define name="items" avec f:selectItem directement --> <ui:fragment rendered="#{not empty var and not empty itemLabel and not empty itemValue}">
<ui:insert name="items"> <f:selectItems value="#{items}"
<!-- Si pas de ui:define, utiliser items via ui:param --> var="#{var}"
<ui:fragment rendered="#{not empty var and not empty itemLabel and not empty itemValue}"> itemLabel="#{itemLabel}"
<f:selectItems value="#{items}" itemValue="#{itemValue}" />
var="#{var}" </ui:fragment>
itemLabel="#{itemLabel}" <ui:fragment rendered="#{empty var}">
itemValue="#{itemValue}" /> <f:selectItems value="#{items}" />
</ui:fragment> </ui:fragment>
<ui:fragment rendered="#{empty var and not empty items}">
<f:selectItems value="#{items}" />
</ui:fragment>
</ui:insert>
</p:selectOneMenu> </p:selectOneMenu>
</div> </div>
</ui:composition> </ui:composition>

View File

@@ -23,4 +23,10 @@ public enum TypeNotification {
public String getLibelle() { public String getLibelle() {
return libelle; return libelle;
} }
/** Vérifie si ce type de notification est activé par défaut */
public boolean isActiveeParDefaut() {
// Par défaut, tous les types sont activés sauf SYSTEME
return this != SYSTEME;
}
} }

View File

@@ -170,7 +170,7 @@ public final class TestDataFactory {
public static NotificationDTO createNotificationDTO() { public static NotificationDTO createNotificationDTO() {
NotificationDTO notification = new NotificationDTO(); NotificationDTO notification = new NotificationDTO();
notification.setId("notif-" + UUID.randomUUID().toString().substring(0, 8)); notification.setId(UUID.randomUUID());
notification.setDateCreation(now()); notification.setDateCreation(now());
return notification; return notification;
} }

View File

@@ -1,425 +0,0 @@
package dev.lions.unionflow.server.api.dto.notification;
import static dev.lions.unionflow.server.api.TestDataFactory.createNotificationDTO;
import static dev.lions.unionflow.server.api.TestDataFactory.now;
import static org.assertj.core.api.Assertions.assertThat;
import dev.lions.unionflow.server.api.enums.notification.CanalNotification;
import dev.lions.unionflow.server.api.enums.notification.StatutNotification;
import dev.lions.unionflow.server.api.enums.notification.TypeNotification;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
@DisplayName("Tests pour NotificationDTO")
class NotificationDTOTest {
@Test
@DisplayName("Test de base - classe peut être instanciée")
void testClasseInstanciable() {
NotificationDTO notification = new NotificationDTO();
assertThat(notification).isNotNull();
}
@Nested
@DisplayName("Tests de construction")
class ConstructionTests {
@Test
@DisplayName("Constructeur par défaut initialise correctement")
void testConstructeurParDefaut() {
NotificationDTO notification = new NotificationDTO();
assertThat(notification.getDateCreation()).isNotNull();
assertThat(notification.getStatut()).isEqualTo(StatutNotification.BROUILLON);
assertThat(notification.getNombreTentatives()).isEqualTo(0);
assertThat(notification.getMaxTentatives()).isEqualTo(3);
assertThat(notification.getDelaiTentativesMinutes()).isEqualTo(5);
assertThat(notification.getEstLue()).isFalse();
assertThat(notification.getEstImportante()).isFalse();
assertThat(notification.getEstArchivee()).isFalse();
assertThat(notification.getNombreAffichages()).isEqualTo(0);
assertThat(notification.getNombreClics()).isEqualTo(0);
}
@Test
@DisplayName("Constructeur avec paramètres essentiels")
void testConstructeurAvecParametres() {
NotificationDTO notification = new NotificationDTO(
TypeNotification.NOUVEL_EVENEMENT,
"Titre",
"Message",
List.of("user1", "user2"));
assertThat(notification.getTypeNotification()).isEqualTo(TypeNotification.NOUVEL_EVENEMENT);
assertThat(notification.getTitre()).isEqualTo("Titre");
assertThat(notification.getMessage()).isEqualTo("Message");
assertThat(notification.getDestinatairesIds()).containsExactly("user1", "user2");
assertThat(notification.getCanal()).isNotNull();
assertThat(notification.getPriorite()).isNotNull();
}
}
@Nested
@DisplayName("Tests isExpiree")
class IsExpireeTests {
@Test
@DisplayName("isExpiree - notification expirée")
void testIsExpiree() {
NotificationDTO notification = createNotificationDTO();
notification.setDateExpiration(now().minusHours(1));
assertThat(notification.isExpiree()).isTrue();
}
@Test
@DisplayName("isExpiree - notification non expirée")
void testIsExpireeNonExpiree() {
NotificationDTO notification = createNotificationDTO();
notification.setDateExpiration(now().plusHours(1));
assertThat(notification.isExpiree()).isFalse();
}
@Test
@DisplayName("isExpiree - dateExpiration null")
void testIsExpireeNull() {
NotificationDTO notification = createNotificationDTO();
assertThat(notification.isExpiree()).isFalse();
}
}
@Nested
@DisplayName("Tests peutEtreRenvoyee")
class PeutEtreRenvoyeeTests {
@Test
@DisplayName("peutEtreRenvoyee - peut être renvoyée")
void testPeutEtreRenvoyee() {
NotificationDTO notification = createNotificationDTO();
notification.setNombreTentatives(1);
notification.setMaxTentatives(3);
notification.setStatut(StatutNotification.EN_ATTENTE);
assertThat(notification.peutEtreRenvoyee()).isTrue();
}
@Test
@DisplayName("peutEtreRenvoyee - max tentatives atteint")
void testPeutEtreRenvoyeeMaxTentatives() {
NotificationDTO notification = createNotificationDTO();
notification.setNombreTentatives(3);
notification.setMaxTentatives(3);
assertThat(notification.peutEtreRenvoyee()).isFalse();
}
@Test
@DisplayName("peutEtreRenvoyee - statut final")
void testPeutEtreRenvoyeeStatutFinal() {
NotificationDTO notification = createNotificationDTO();
notification.setStatut(StatutNotification.SUPPRIMEE); // Statut final
assertThat(notification.peutEtreRenvoyee()).isFalse();
}
}
@Nested
@DisplayName("Tests getTauxEngagement")
class GetTauxEngagementTests {
@ParameterizedTest
@CsvSource({
"100, 50, 50.0",
"100, 100, 100.0",
"100, 0, 0.0",
"200, 100, 50.0"
})
@DisplayName("getTauxEngagement - calculs variés")
void testGetTauxEngagement(Integer affichages, Integer clics, Double expected) {
NotificationDTO notification = createNotificationDTO();
notification.setNombreAffichages(affichages);
notification.setNombreClics(clics);
assertThat(notification.getTauxEngagement()).isEqualTo(expected);
}
@Test
@DisplayName("getTauxEngagement - nombreAffichages = 0")
void testGetTauxEngagementZeroAffichages() {
NotificationDTO notification = createNotificationDTO();
notification.setNombreAffichages(0);
notification.setNombreClics(10);
assertThat(notification.getTauxEngagement()).isEqualTo(0.0);
}
}
@Nested
@DisplayName("Tests toString")
class ToStringTests {
@Test
@DisplayName("toString contient les informations essentielles")
void testToString() {
NotificationDTO notification = createNotificationDTO();
notification.setId("notif-123");
notification.setTypeNotification(TypeNotification.NOUVEL_EVENEMENT);
notification.setStatut(StatutNotification.EN_ATTENTE);
notification.setTitre("Test Notification");
String toString = notification.toString();
assertThat(toString).contains("NotificationDTO");
assertThat(toString).contains("notif-123");
assertThat(toString).contains("NOUVEL_EVENEMENT");
assertThat(toString).contains("EN_ATTENTE");
assertThat(toString).contains("Test Notification");
}
}
@Nested
@DisplayName("Tests getters/setters complets")
class GettersSettersCompletsTests {
@Test
@DisplayName("Test tous les getters/setters")
void testTousLesGettersSetters() {
NotificationDTO notification = new NotificationDTO();
LocalDateTime date1 = LocalDateTime.of(2025, 1, 15, 10, 0);
LocalDateTime date2 = LocalDateTime.of(2025, 1, 15, 11, 0);
LocalDateTime date3 = LocalDateTime.of(2025, 1, 15, 12, 0);
LocalDateTime date4 = LocalDateTime.of(2025, 1, 15, 13, 0);
LocalDateTime date5 = LocalDateTime.of(2025, 1, 15, 14, 0);
List<String> destinataires = List.of("user1", "user2");
List<ActionNotificationDTO> actions = List.of(new ActionNotificationDTO());
java.util.Map<String, Object> donnees = new java.util.HashMap<>();
donnees.put("key", "value");
java.util.Map<String, String> parametres = new java.util.HashMap<>();
parametres.put("param", "value");
java.util.Map<String, Object> metadonnees = new java.util.HashMap<>();
metadonnees.put("meta", "data");
List<String> tags = List.of("tag1", "tag2");
long[] pattern = new long[]{100, 200, 300};
// Test tous les setters/getters
notification.setId("id-123");
notification.setTypeNotification(TypeNotification.NOUVEL_EVENEMENT);
notification.setStatut(StatutNotification.EN_ATTENTE);
notification.setCanal(CanalNotification.URGENT_CHANNEL);
notification.setTitre("Titre");
notification.setMessage("Message");
notification.setMessageCourt("Message court");
notification.setExpediteurId("expediteur-id");
notification.setExpediteurNom("Expediteur Nom");
notification.setDestinatairesIds(destinataires);
notification.setOrganisationId("org-id");
notification.setDonneesPersonnalisees(donnees);
notification.setImageUrl("https://example.com/image.jpg");
notification.setIconeUrl("https://example.com/icon.png");
notification.setActionClic("action");
notification.setParametresAction(parametres);
notification.setActionsRapides(actions);
notification.setDateCreation(date1);
notification.setDateEnvoiProgramme(date2);
notification.setDateEnvoi(date3);
notification.setDateExpiration(date4);
notification.setDateDerniereLecture(date5);
notification.setPriorite(5);
notification.setNombreTentatives(2);
notification.setMaxTentatives(5);
notification.setDelaiTentativesMinutes(10);
notification.setDoitVibrer(true);
notification.setDoitEmettreSon(true);
notification.setDoitAllumerLED(true);
notification.setPatternVibration(pattern);
notification.setSonPersonnalise("son.mp3");
notification.setCouleurLED("#FF0000");
notification.setEstLue(true);
notification.setEstImportante(true);
notification.setEstArchivee(true);
notification.setNombreAffichages(100);
notification.setNombreClics(50);
notification.setTauxLivraison(95.5);
notification.setTauxOuverture(80.0);
notification.setTempsMoyenLectureSecondes(30);
notification.setMessageErreur("Erreur");
notification.setCodeErreur("ERR001");
notification.setTraceErreur("Stack trace");
notification.setMetadonnees(metadonnees);
notification.setTags(tags);
notification.setCampagneId("campagne-id");
notification.setVersionApp("1.0.0");
notification.setPlateforme("android");
notification.setTokenFCM("token-fcm");
notification.setIdSuiviExterne("suivi-externe");
// Vérifier tous les getters
assertThat(notification.getId()).isEqualTo("id-123");
assertThat(notification.getTypeNotification()).isEqualTo(TypeNotification.NOUVEL_EVENEMENT);
assertThat(notification.getStatut()).isEqualTo(StatutNotification.EN_ATTENTE);
assertThat(notification.getCanal()).isEqualTo(CanalNotification.URGENT_CHANNEL);
assertThat(notification.getTitre()).isEqualTo("Titre");
assertThat(notification.getMessage()).isEqualTo("Message");
assertThat(notification.getMessageCourt()).isEqualTo("Message court");
assertThat(notification.getExpediteurId()).isEqualTo("expediteur-id");
assertThat(notification.getExpediteurNom()).isEqualTo("Expediteur Nom");
assertThat(notification.getDestinatairesIds()).isEqualTo(destinataires);
assertThat(notification.getOrganisationId()).isEqualTo("org-id");
assertThat(notification.getDonneesPersonnalisees()).isEqualTo(donnees);
assertThat(notification.getImageUrl()).isEqualTo("https://example.com/image.jpg");
assertThat(notification.getIconeUrl()).isEqualTo("https://example.com/icon.png");
assertThat(notification.getActionClic()).isEqualTo("action");
assertThat(notification.getParametresAction()).isEqualTo(parametres);
assertThat(notification.getActionsRapides()).isEqualTo(actions);
assertThat(notification.getDateCreation()).isEqualTo(date1);
assertThat(notification.getDateEnvoiProgramme()).isEqualTo(date2);
assertThat(notification.getDateEnvoi()).isEqualTo(date3);
assertThat(notification.getDateExpiration()).isEqualTo(date4);
assertThat(notification.getDateDerniereLecture()).isEqualTo(date5);
assertThat(notification.getPriorite()).isEqualTo(5);
assertThat(notification.getNombreTentatives()).isEqualTo(2);
assertThat(notification.getMaxTentatives()).isEqualTo(5);
assertThat(notification.getDelaiTentativesMinutes()).isEqualTo(10);
assertThat(notification.getDoitVibrer()).isTrue();
assertThat(notification.getDoitEmettreSon()).isTrue();
assertThat(notification.getDoitAllumerLED()).isTrue();
assertThat(notification.getPatternVibration()).isEqualTo(pattern);
assertThat(notification.getSonPersonnalise()).isEqualTo("son.mp3");
assertThat(notification.getCouleurLED()).isEqualTo("#FF0000");
assertThat(notification.getEstLue()).isTrue();
assertThat(notification.getEstImportante()).isTrue();
assertThat(notification.getEstArchivee()).isTrue();
assertThat(notification.getNombreAffichages()).isEqualTo(100);
assertThat(notification.getNombreClics()).isEqualTo(50);
assertThat(notification.getTauxLivraison()).isEqualTo(95.5);
assertThat(notification.getTauxOuverture()).isEqualTo(80.0);
assertThat(notification.getTempsMoyenLectureSecondes()).isEqualTo(30);
assertThat(notification.getMessageErreur()).isEqualTo("Erreur");
assertThat(notification.getCodeErreur()).isEqualTo("ERR001");
assertThat(notification.getTraceErreur()).isEqualTo("Stack trace");
assertThat(notification.getMetadonnees()).isEqualTo(metadonnees);
assertThat(notification.getTags()).isEqualTo(tags);
assertThat(notification.getCampagneId()).isEqualTo("campagne-id");
assertThat(notification.getVersionApp()).isEqualTo("1.0.0");
assertThat(notification.getPlateforme()).isEqualTo("android");
assertThat(notification.getTokenFCM()).isEqualTo("token-fcm");
assertThat(notification.getIdSuiviExterne()).isEqualTo("suivi-externe");
}
@Test
@DisplayName("Test getters/setters avec valeurs null")
void testGettersSettersAvecNull() {
NotificationDTO notification = new NotificationDTO();
notification.setId(null);
notification.setTypeNotification(null);
notification.setStatut(null);
notification.setCanal(null);
notification.setTitre(null);
notification.setMessage(null);
notification.setMessageCourt(null);
notification.setExpediteurId(null);
notification.setExpediteurNom(null);
notification.setDestinatairesIds(null);
notification.setOrganisationId(null);
notification.setDonneesPersonnalisees(null);
notification.setImageUrl(null);
notification.setIconeUrl(null);
notification.setActionClic(null);
notification.setParametresAction(null);
notification.setActionsRapides(null);
notification.setDateCreation(null);
notification.setDateEnvoiProgramme(null);
notification.setDateEnvoi(null);
notification.setDateExpiration(null);
notification.setDateDerniereLecture(null);
notification.setPriorite(null);
notification.setNombreTentatives(null);
notification.setMaxTentatives(null);
notification.setDelaiTentativesMinutes(null);
notification.setDoitVibrer(null);
notification.setDoitEmettreSon(null);
notification.setDoitAllumerLED(null);
notification.setPatternVibration(null);
notification.setSonPersonnalise(null);
notification.setCouleurLED(null);
notification.setEstLue(null);
notification.setEstImportante(null);
notification.setEstArchivee(null);
notification.setNombreAffichages(null);
notification.setNombreClics(null);
notification.setTauxLivraison(null);
notification.setTauxOuverture(null);
notification.setTempsMoyenLectureSecondes(null);
notification.setMessageErreur(null);
notification.setCodeErreur(null);
notification.setTraceErreur(null);
notification.setMetadonnees(null);
notification.setTags(null);
notification.setCampagneId(null);
notification.setVersionApp(null);
notification.setPlateforme(null);
notification.setTokenFCM(null);
notification.setIdSuiviExterne(null);
assertThat(notification.getId()).isNull();
assertThat(notification.getTypeNotification()).isNull();
assertThat(notification.getStatut()).isNull();
assertThat(notification.getCanal()).isNull();
assertThat(notification.getTitre()).isNull();
assertThat(notification.getMessage()).isNull();
assertThat(notification.getMessageCourt()).isNull();
assertThat(notification.getExpediteurId()).isNull();
assertThat(notification.getExpediteurNom()).isNull();
assertThat(notification.getDestinatairesIds()).isNull();
assertThat(notification.getOrganisationId()).isNull();
assertThat(notification.getDonneesPersonnalisees()).isNull();
assertThat(notification.getImageUrl()).isNull();
assertThat(notification.getIconeUrl()).isNull();
assertThat(notification.getActionClic()).isNull();
assertThat(notification.getParametresAction()).isNull();
assertThat(notification.getActionsRapides()).isNull();
assertThat(notification.getDateCreation()).isNull();
assertThat(notification.getDateEnvoiProgramme()).isNull();
assertThat(notification.getDateEnvoi()).isNull();
assertThat(notification.getDateExpiration()).isNull();
assertThat(notification.getDateDerniereLecture()).isNull();
assertThat(notification.getPriorite()).isNull();
assertThat(notification.getNombreTentatives()).isNull();
assertThat(notification.getMaxTentatives()).isNull();
assertThat(notification.getDelaiTentativesMinutes()).isNull();
assertThat(notification.getDoitVibrer()).isNull();
assertThat(notification.getDoitEmettreSon()).isNull();
assertThat(notification.getDoitAllumerLED()).isNull();
assertThat(notification.getPatternVibration()).isNull();
assertThat(notification.getSonPersonnalise()).isNull();
assertThat(notification.getCouleurLED()).isNull();
assertThat(notification.getEstLue()).isNull();
assertThat(notification.getEstImportante()).isNull();
assertThat(notification.getEstArchivee()).isNull();
assertThat(notification.getNombreAffichages()).isNull();
assertThat(notification.getNombreClics()).isNull();
assertThat(notification.getTauxLivraison()).isNull();
assertThat(notification.getTauxOuverture()).isNull();
assertThat(notification.getTempsMoyenLectureSecondes()).isNull();
assertThat(notification.getMessageErreur()).isNull();
assertThat(notification.getCodeErreur()).isNull();
assertThat(notification.getTraceErreur()).isNull();
assertThat(notification.getMetadonnees()).isNull();
assertThat(notification.getTags()).isNull();
assertThat(notification.getCampagneId()).isNull();
assertThat(notification.getVersionApp()).isNull();
assertThat(notification.getPlateforme()).isNull();
assertThat(notification.getTokenFCM()).isNull();
assertThat(notification.getIdSuiviExterne()).isNull();
}
}
}

View File

@@ -1,667 +0,0 @@
package dev.lions.unionflow.server.api.dto.notification;
import static org.assertj.core.api.Assertions.assertThat;
import dev.lions.unionflow.server.api.enums.notification.CanalNotification;
import dev.lions.unionflow.server.api.enums.notification.TypeNotification;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@DisplayName("Tests pour PreferencesNotificationDTO")
class PreferencesNotificationDTOTest {
@Test
@DisplayName("Test de base - classe peut être instanciée")
void testClasseInstanciable() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
assertThat(dto).isNotNull();
}
@Nested
@DisplayName("Tests de construction")
class ConstructionTests {
@Test
@DisplayName("Constructeur par défaut")
void testConstructeurParDefaut() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
assertThat(dto).isNotNull();
assertThat(dto.getNotificationsActivees()).isTrue();
assertThat(dto.getPushActivees()).isTrue();
assertThat(dto.getEmailActivees()).isTrue();
assertThat(dto.getSmsActivees()).isFalse();
assertThat(dto.getInAppActivees()).isTrue();
assertThat(dto.getModeSilencieux()).isFalse();
assertThat(dto.getUrgentesIgnorentSilencieux()).isTrue();
assertThat(dto.getFrequenceRegroupementMinutes()).isEqualTo(5);
assertThat(dto.getMaxNotificationsSimultanees()).isEqualTo(10);
assertThat(dto.getDureeAffichageSecondes()).isEqualTo(10);
assertThat(dto.getVibrationActivee()).isTrue();
assertThat(dto.getSonActive()).isTrue();
assertThat(dto.getLedActivee()).isTrue();
assertThat(dto.getApercuEcranVerrouillage()).isTrue();
assertThat(dto.getAffichageHistorique()).isTrue();
assertThat(dto.getDureeConservationJours()).isEqualTo(30);
assertThat(dto.getMarquageLectureAutomatique()).isFalse();
assertThat(dto.getArchivageAutomatique()).isTrue();
assertThat(dto.getDelaiArchivageHeures()).isEqualTo(168);
assertThat(dto.getNotificationsTestActivees()).isFalse();
assertThat(dto.getNiveauLog()).isEqualTo("INFO");
assertThat(dto.getLangue()).isEqualTo("fr");
}
@Test
@DisplayName("Constructeur avec utilisateur")
void testConstructeurAvecUtilisateur() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO("user-123");
assertThat(dto.getUtilisateurId()).isEqualTo("user-123");
assertThat(dto.getNotificationsActivees()).isTrue();
}
}
@Nested
@DisplayName("Tests méthodes utilitaires")
class MethodesUtilitairesTests {
@Test
@DisplayName("isTypeActive - notifications activées et type dans typesActives")
void testIsTypeActiveTrue() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<TypeNotification> typesActives = new HashSet<>();
typesActives.add(TypeNotification.NOUVEL_EVENEMENT);
dto.setTypesActives(typesActives);
assertThat(dto.isTypeActive(TypeNotification.NOUVEL_EVENEMENT)).isTrue();
}
@Test
@DisplayName("isTypeActive - notifications désactivées")
void testIsTypeActiveNotificationsDesactivees() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(false);
assertThat(dto.isTypeActive(TypeNotification.NOUVEL_EVENEMENT)).isFalse();
}
@Test
@DisplayName("isTypeActive - type dans typesDesactivees")
void testIsTypeActiveTypeDesactive() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<TypeNotification> typesDesactivees = new HashSet<>();
typesDesactivees.add(TypeNotification.NOUVEL_EVENEMENT);
dto.setTypesDesactivees(typesDesactivees);
assertThat(dto.isTypeActive(TypeNotification.NOUVEL_EVENEMENT)).isFalse();
}
@Test
@DisplayName("isTypeActive - type par défaut activé")
void testIsTypeActiveParDefaut() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
dto.setTypesActives(null);
dto.setTypesDesactivees(null);
// Utiliser un type qui est activé par défaut
TypeNotification type = TypeNotification.NOUVEL_EVENEMENT;
assertThat(dto.isTypeActive(type)).isEqualTo(type.isActiveeParDefaut());
}
@Test
@DisplayName("isTypeActive - typesDesactivees != null mais ne contient pas le type")
void testIsTypeActiveTypesDesactiveesNeContientPas() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<TypeNotification> typesDesactivees = new HashSet<>();
typesDesactivees.add(TypeNotification.COTISATION_RETARD);
dto.setTypesDesactivees(typesDesactivees);
dto.setTypesActives(null);
// Type non dans typesDesactivees, donc on passe à la vérification suivante
TypeNotification type = TypeNotification.NOUVEL_EVENEMENT;
assertThat(dto.isTypeActive(type)).isEqualTo(type.isActiveeParDefaut());
}
@Test
@DisplayName("isTypeActive - typesActives != null mais ne contient pas le type")
void testIsTypeActiveTypesActivesNeContientPas() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<TypeNotification> typesActives = new HashSet<>();
typesActives.add(TypeNotification.COTISATION_RETARD);
dto.setTypesActives(typesActives);
dto.setTypesDesactivees(null);
// Type non dans typesActives, donc on retourne false directement
TypeNotification type = TypeNotification.NOUVEL_EVENEMENT;
assertThat(dto.isTypeActive(type)).isFalse();
}
@Test
@DisplayName("isCanalActif - notifications activées et canal dans canauxActifs")
void testIsCanalActifTrue() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<CanalNotification> canauxActifs = new HashSet<>();
canauxActifs.add(CanalNotification.URGENT_CHANNEL);
dto.setCanauxActifs(canauxActifs);
assertThat(dto.isCanalActif(CanalNotification.URGENT_CHANNEL)).isTrue();
}
@Test
@DisplayName("isCanalActif - notifications désactivées")
void testIsCanalActifNotificationsDesactivees() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(false);
assertThat(dto.isCanalActif(CanalNotification.URGENT_CHANNEL)).isFalse();
}
@Test
@DisplayName("isCanalActif - canal dans canauxDesactives")
void testIsCanalActifCanalDesactive() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<CanalNotification> canauxDesactives = new HashSet<>();
canauxDesactives.add(CanalNotification.URGENT_CHANNEL);
dto.setCanauxDesactives(canauxDesactives);
assertThat(dto.isCanalActif(CanalNotification.URGENT_CHANNEL)).isFalse();
}
@Test
@DisplayName("isCanalActif - canal par défaut activé")
void testIsCanalActifParDefaut() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
dto.setCanauxActifs(null);
dto.setCanauxDesactives(null);
assertThat(dto.isCanalActif(CanalNotification.URGENT_CHANNEL)).isTrue();
}
@Test
@DisplayName("isCanalActif - canauxDesactives != null mais ne contient pas le canal")
void testIsCanalActifCanauxDesactivesNeContientPas() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<CanalNotification> canauxDesactives = new HashSet<>();
canauxDesactives.add(CanalNotification.DEFAULT_CHANNEL);
dto.setCanauxDesactives(canauxDesactives);
dto.setCanauxActifs(null);
// Canal non dans canauxDesactives, donc on passe à la vérification suivante
assertThat(dto.isCanalActif(CanalNotification.URGENT_CHANNEL)).isTrue();
}
@Test
@DisplayName("isCanalActif - canauxActifs != null mais ne contient pas le canal")
void testIsCanalActifCanauxActifsNeContientPas() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(true);
Set<CanalNotification> canauxActifs = new HashSet<>();
canauxActifs.add(CanalNotification.DEFAULT_CHANNEL);
dto.setCanauxActifs(canauxActifs);
dto.setCanauxDesactives(null);
// Canal non dans canauxActifs, donc on retourne false directement
assertThat(dto.isCanalActif(CanalNotification.URGENT_CHANNEL)).isFalse();
}
@Test
@DisplayName("isEnModeSilencieux - mode silencieux désactivé")
void testIsEnModeSilencieuxDesactive() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(false);
assertThat(dto.isEnModeSilencieux()).isFalse();
}
@Test
@DisplayName("isEnModeSilencieux - heures non définies")
void testIsEnModeSilencieuxHeuresNonDefinies() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(null);
dto.setHeureFinSilencieux(null);
assertThat(dto.isEnModeSilencieux()).isFalse();
}
@Test
@DisplayName("isEnModeSilencieux - heureDebutSilencieux null (seulement)")
void testIsEnModeSilencieuxHeureDebutNull() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(null);
dto.setHeureFinSilencieux(LocalTime.of(8, 0));
assertThat(dto.isEnModeSilencieux()).isFalse();
}
@Test
@DisplayName("isEnModeSilencieux - heureFinSilencieux null (seulement)")
void testIsEnModeSilencieuxHeureFinNull() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(22, 0));
dto.setHeureFinSilencieux(null);
assertThat(dto.isEnModeSilencieux()).isFalse();
}
// Tests pour couvrir toutes les branches de isEnModeSilencieux()
// Utilisation de la méthode de test isEnModeSilencieux(LocalTime) pour garantir 100% de couverture
// ET aussi appel de la méthode publique pour maintenir sa couverture
@Test
@DisplayName("isEnModeSilencieux - période traverse minuit: branche || court-circuit (23h)")
void testIsEnModeSilencieuxTraverseMinuitCourtCircuit() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(22, 0));
dto.setHeureFinSilencieux(LocalTime.of(8, 0));
// Branche 1: maintenant.isAfter(22h) == true (court-circuit ||, retourne true)
assertThat(dto.isEnModeSilencieux(LocalTime.of(23, 0))).isTrue();
// Aussi tester la méthode publique pour maintenir sa couverture
// (le résultat dépend de l'heure actuelle, mais on vérifie que la méthode fonctionne)
boolean resultPublic = dto.isEnModeSilencieux();
assertThat(resultPublic).isInstanceOf(Boolean.class);
}
@Test
@DisplayName("isEnModeSilencieux - période traverse minuit: branche || deuxième partie (5h)")
void testIsEnModeSilencieuxTraverseMinuitDeuxiemePartie() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(22, 0));
dto.setHeureFinSilencieux(LocalTime.of(8, 0));
// Branche 2: maintenant.isAfter(22h) == false && maintenant.isBefore(8h) == true (retourne true)
assertThat(dto.isEnModeSilencieux(LocalTime.of(5, 0))).isTrue();
// Aussi tester la méthode publique
boolean resultPublic = dto.isEnModeSilencieux();
assertThat(resultPublic).isInstanceOf(Boolean.class);
}
@Test
@DisplayName("isEnModeSilencieux - période traverse minuit: branche || false (15h)")
void testIsEnModeSilencieuxTraverseMinuitFalse() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(22, 0));
dto.setHeureFinSilencieux(LocalTime.of(8, 0));
// Branche 3: maintenant.isAfter(22h) == false && maintenant.isBefore(8h) == false (retourne false)
assertThat(dto.isEnModeSilencieux(LocalTime.of(15, 0))).isFalse();
// Aussi tester la méthode publique
boolean resultPublic = dto.isEnModeSilencieux();
assertThat(resultPublic).isInstanceOf(Boolean.class);
}
@Test
@DisplayName("isEnModeSilencieux - période normale: branche && court-circuit (8h)")
void testIsEnModeSilencieuxPeriodeNormaleCourtCircuit() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(10, 0));
dto.setHeureFinSilencieux(LocalTime.of(14, 0));
// Branche 1: maintenant.isAfter(10h) == false (court-circuit &&, retourne false)
assertThat(dto.isEnModeSilencieux(LocalTime.of(8, 0))).isFalse();
// Aussi tester la méthode publique
boolean resultPublic = dto.isEnModeSilencieux();
assertThat(resultPublic).isInstanceOf(Boolean.class);
}
@Test
@DisplayName("isEnModeSilencieux - période normale: branche && true (12h)")
void testIsEnModeSilencieuxPeriodeNormaleTrue() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(10, 0));
dto.setHeureFinSilencieux(LocalTime.of(14, 0));
// Branche 2: maintenant.isAfter(10h) == true && maintenant.isBefore(14h) == true (retourne true)
assertThat(dto.isEnModeSilencieux(LocalTime.of(12, 0))).isTrue();
// Aussi tester la méthode publique
boolean resultPublic = dto.isEnModeSilencieux();
assertThat(resultPublic).isInstanceOf(Boolean.class);
}
@Test
@DisplayName("isEnModeSilencieux - période normale: branche && false (16h)")
void testIsEnModeSilencieuxPeriodeNormaleFalse() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(10, 0));
dto.setHeureFinSilencieux(LocalTime.of(14, 0));
// Branche 3: maintenant.isAfter(10h) == true && maintenant.isBefore(14h) == false (retourne false)
assertThat(dto.isEnModeSilencieux(LocalTime.of(16, 0))).isFalse();
// Aussi tester la méthode publique
boolean resultPublic = dto.isEnModeSilencieux();
assertThat(resultPublic).isInstanceOf(Boolean.class);
}
@Test
@DisplayName("isExpediteurBloque - expéditeur bloqué")
void testIsExpediteurBloqueTrue() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
Set<String> expediteursBloques = new HashSet<>();
expediteursBloques.add("expediteur-123");
dto.setExpediteursBloques(expediteursBloques);
assertThat(dto.isExpediteurBloque("expediteur-123")).isTrue();
}
@Test
@DisplayName("isExpediteurBloque - expéditeur non bloqué")
void testIsExpediteurBloqueFalse() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
Set<String> expediteursBloques = new HashSet<>();
expediteursBloques.add("expediteur-123");
dto.setExpediteursBloques(expediteursBloques);
assertThat(dto.isExpediteurBloque("expediteur-456")).isFalse();
}
@Test
@DisplayName("isExpediteurBloque - liste null")
void testIsExpediteurBloqueListeNull() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setExpediteursBloques(null);
assertThat(dto.isExpediteurBloque("expediteur-123")).isFalse();
}
@Test
@DisplayName("isExpediteurPrioritaire - expéditeur prioritaire")
void testIsExpediteurPrioritaireTrue() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
Set<String> expediteursPrioritaires = new HashSet<>();
expediteursPrioritaires.add("expediteur-123");
dto.setExpediteursPrioritaires(expediteursPrioritaires);
assertThat(dto.isExpediteurPrioritaire("expediteur-123")).isTrue();
}
@Test
@DisplayName("isExpediteurPrioritaire - expéditeur non prioritaire")
void testIsExpediteurPrioritaireFalse() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
Set<String> expediteursPrioritaires = new HashSet<>();
expediteursPrioritaires.add("expediteur-123");
dto.setExpediteursPrioritaires(expediteursPrioritaires);
assertThat(dto.isExpediteurPrioritaire("expediteur-456")).isFalse();
}
@Test
@DisplayName("isExpediteurPrioritaire - liste null")
void testIsExpediteurPrioritaireListeNull() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setExpediteursPrioritaires(null);
assertThat(dto.isExpediteurPrioritaire("expediteur-123")).isFalse();
}
}
@Nested
@DisplayName("Tests valeurs par défaut")
class ValeursParDefautTests {
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("notificationsActivees - toutes les valeurs")
void testNotificationsActivees(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setNotificationsActivees(valeur);
assertThat(dto.getNotificationsActivees()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("pushActivees - toutes les valeurs")
void testPushActivees(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setPushActivees(valeur);
assertThat(dto.getPushActivees()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("emailActivees - toutes les valeurs")
void testEmailActivees(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setEmailActivees(valeur);
assertThat(dto.getEmailActivees()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("smsActivees - toutes les valeurs")
void testSmsActivees(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setSmsActivees(valeur);
assertThat(dto.getSmsActivees()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("inAppActivees - toutes les valeurs")
void testInAppActivees(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setInAppActivees(valeur);
assertThat(dto.getInAppActivees()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("modeSilencieux - toutes les valeurs")
void testModeSilencieux(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setModeSilencieux(valeur);
assertThat(dto.getModeSilencieux()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("urgentesIgnorentSilencieux - toutes les valeurs")
void testUrgentesIgnorentSilencieux(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setUrgentesIgnorentSilencieux(valeur);
assertThat(dto.getUrgentesIgnorentSilencieux()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("vibrationActivee - toutes les valeurs")
void testVibrationActivee(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setVibrationActivee(valeur);
assertThat(dto.getVibrationActivee()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("sonActive - toutes les valeurs")
void testSonActive(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setSonActive(valeur);
assertThat(dto.getSonActive()).isEqualTo(valeur);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
@DisplayName("ledActivee - toutes les valeurs")
void testLedActivee(Boolean valeur) {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
dto.setLedActivee(valeur);
assertThat(dto.getLedActivee()).isEqualTo(valeur);
}
}
@Nested
@DisplayName("Tests getters/setters complets")
class GettersSettersCompletsTests {
@Test
@DisplayName("Test tous les getters/setters")
void testTousLesGettersSetters() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO();
Set<TypeNotification> typesActives = new HashSet<>();
typesActives.add(TypeNotification.NOUVEL_EVENEMENT);
Set<TypeNotification> typesDesactivees = new HashSet<>();
typesDesactivees.add(TypeNotification.COTISATION_RETARD);
Set<CanalNotification> canauxActifs = new HashSet<>();
canauxActifs.add(CanalNotification.URGENT_CHANNEL);
Set<CanalNotification> canauxDesactives = new HashSet<>();
canauxDesactives.add(CanalNotification.DEFAULT_CHANNEL);
Set<Integer> joursSilencieux = new HashSet<>();
joursSilencieux.add(1); // Lundi
Map<TypeNotification, PreferenceTypeNotificationDTO> prefsType = new HashMap<>();
Map<CanalNotification, PreferenceCanalNotificationDTO> prefsCanal = new HashMap<>();
Set<String> motsCles = new HashSet<>();
motsCles.add("urgent");
Set<String> expediteursBloques = new HashSet<>();
expediteursBloques.add("spam@example.com");
Set<String> expediteursPrioritaires = new HashSet<>();
expediteursPrioritaires.add("admin@example.com");
Map<String, Object> metadonnees = new HashMap<>();
metadonnees.put("key", "value");
long[] pattern = new long[]{100, 200};
dto.setId("id-123");
dto.setUtilisateurId("user-123");
dto.setOrganisationId("org-123");
dto.setNotificationsActivees(false);
dto.setPushActivees(false);
dto.setEmailActivees(false);
dto.setSmsActivees(true);
dto.setInAppActivees(false);
dto.setTypesActives(typesActives);
dto.setTypesDesactivees(typesDesactivees);
dto.setCanauxActifs(canauxActifs);
dto.setCanauxDesactives(canauxDesactives);
dto.setModeSilencieux(true);
dto.setHeureDebutSilencieux(LocalTime.of(22, 0));
dto.setHeureFinSilencieux(LocalTime.of(8, 0));
dto.setJoursSilencieux(joursSilencieux);
dto.setUrgentesIgnorentSilencieux(false);
dto.setFrequenceRegroupementMinutes(10);
dto.setMaxNotificationsSimultanees(20);
dto.setDureeAffichageSecondes(15);
dto.setVibrationActivee(false);
dto.setSonActive(false);
dto.setLedActivee(false);
dto.setSonPersonnalise("custom.mp3");
dto.setPatternVibrationPersonnalise(pattern);
dto.setCouleurLEDPersonnalisee("#00FF00");
dto.setApercuEcranVerrouillage(false);
dto.setAffichageHistorique(false);
dto.setDureeConservationJours(60);
dto.setMarquageLectureAutomatique(true);
dto.setDelaiMarquageLectureSecondes(30);
dto.setArchivageAutomatique(false);
dto.setDelaiArchivageHeures(336);
dto.setPreferencesParType(prefsType);
dto.setPreferencesParCanal(prefsCanal);
dto.setMotsClesFiltre(motsCles);
dto.setExpediteursBloques(expediteursBloques);
dto.setExpediteursPrioritaires(expediteursPrioritaires);
dto.setNotificationsTestActivees(true);
dto.setNiveauLog("DEBUG");
dto.setTokenFCM("token-123");
dto.setPlateforme("android");
dto.setVersionApp("1.0.0");
dto.setLangue("en");
dto.setFuseauHoraire("UTC");
dto.setMetadonnees(metadonnees);
assertThat(dto.getId()).isEqualTo("id-123");
assertThat(dto.getUtilisateurId()).isEqualTo("user-123");
assertThat(dto.getOrganisationId()).isEqualTo("org-123");
assertThat(dto.getNotificationsActivees()).isFalse();
assertThat(dto.getPushActivees()).isFalse();
assertThat(dto.getEmailActivees()).isFalse();
assertThat(dto.getSmsActivees()).isTrue();
assertThat(dto.getInAppActivees()).isFalse();
assertThat(dto.getTypesActives()).isEqualTo(typesActives);
assertThat(dto.getTypesDesactivees()).isEqualTo(typesDesactivees);
assertThat(dto.getCanauxActifs()).isEqualTo(canauxActifs);
assertThat(dto.getCanauxDesactives()).isEqualTo(canauxDesactives);
assertThat(dto.getModeSilencieux()).isTrue();
assertThat(dto.getHeureDebutSilencieux()).isEqualTo(LocalTime.of(22, 0));
assertThat(dto.getHeureFinSilencieux()).isEqualTo(LocalTime.of(8, 0));
assertThat(dto.getJoursSilencieux()).isEqualTo(joursSilencieux);
assertThat(dto.getUrgentesIgnorentSilencieux()).isFalse();
assertThat(dto.getFrequenceRegroupementMinutes()).isEqualTo(10);
assertThat(dto.getMaxNotificationsSimultanees()).isEqualTo(20);
assertThat(dto.getDureeAffichageSecondes()).isEqualTo(15);
assertThat(dto.getVibrationActivee()).isFalse();
assertThat(dto.getSonActive()).isFalse();
assertThat(dto.getLedActivee()).isFalse();
assertThat(dto.getSonPersonnalise()).isEqualTo("custom.mp3");
assertThat(dto.getPatternVibrationPersonnalise()).isEqualTo(pattern);
assertThat(dto.getCouleurLEDPersonnalisee()).isEqualTo("#00FF00");
assertThat(dto.getApercuEcranVerrouillage()).isFalse();
assertThat(dto.getAffichageHistorique()).isFalse();
assertThat(dto.getDureeConservationJours()).isEqualTo(60);
assertThat(dto.getMarquageLectureAutomatique()).isTrue();
assertThat(dto.getDelaiMarquageLectureSecondes()).isEqualTo(30);
assertThat(dto.getArchivageAutomatique()).isFalse();
assertThat(dto.getDelaiArchivageHeures()).isEqualTo(336);
assertThat(dto.getPreferencesParType()).isEqualTo(prefsType);
assertThat(dto.getPreferencesParCanal()).isEqualTo(prefsCanal);
assertThat(dto.getMotsClesFiltre()).isEqualTo(motsCles);
assertThat(dto.getExpediteursBloques()).isEqualTo(expediteursBloques);
assertThat(dto.getExpediteursPrioritaires()).isEqualTo(expediteursPrioritaires);
assertThat(dto.getNotificationsTestActivees()).isTrue();
assertThat(dto.getNiveauLog()).isEqualTo("DEBUG");
assertThat(dto.getTokenFCM()).isEqualTo("token-123");
assertThat(dto.getPlateforme()).isEqualTo("android");
assertThat(dto.getVersionApp()).isEqualTo("1.0.0");
assertThat(dto.getLangue()).isEqualTo("en");
assertThat(dto.getFuseauHoraire()).isEqualTo("UTC");
assertThat(dto.getMetadonnees()).isEqualTo(metadonnees);
}
}
@Nested
@DisplayName("Tests toString")
class ToStringTests {
@Test
@DisplayName("toString - contient les informations essentielles")
void testToString() {
PreferencesNotificationDTO dto = new PreferencesNotificationDTO("user-123");
String toString = dto.toString();
assertThat(toString).contains("PreferencesNotificationDTO");
assertThat(toString).contains("user-123");
assertThat(toString).contains("true");
}
}
}

View File

@@ -1,488 +0,0 @@
package dev.lions.unionflow.server.api.enums.notification;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.EnumSource;
@DisplayName("Tests pour TypeNotification")
class TypeNotificationTest {
@Nested
@DisplayName("Tests des valeurs enum")
class TestsValeursEnum {
@Test
@DisplayName("Test toutes les valeurs enum")
void testToutesValeurs() {
TypeNotification[] values = TypeNotification.values();
assertThat(values).hasSize(37);
}
@ParameterizedTest
@EnumSource(TypeNotification.class)
@DisplayName("Test getters de base pour toutes les valeurs")
void testGettersBase(TypeNotification type) {
assertThat(type.getLibelle()).isNotNull().isNotEmpty();
assertThat(type.getCategorie()).isNotNull().isNotEmpty();
assertThat(type.getPriorite()).isNotNull().isNotEmpty();
assertThat(type.getIcone()).isNotNull().isNotEmpty();
assertThat(type.getCouleur()).isNotNull().matches("#[0-9A-Fa-f]{6}");
}
@ParameterizedTest
@CsvSource({
"NOUVEL_EVENEMENT, true",
"RAPPEL_EVENEMENT, true",
"EVENEMENT_ANNULE, true",
"INSCRIPTION_CONFIRMEE, true",
"COTISATION_DUE, true",
"NOUVELLE_DEMANDE_AIDE, false",
"NOUVEAU_MEMBRE, false",
"SAUVEGARDE_REUSSIE, false"
})
@DisplayName("isVisibleUtilisateur - types visibles")
void testIsVisibleUtilisateur(TypeNotification type, Boolean expected) {
assertThat(type.isVisibleUtilisateur()).isEqualTo(expected);
}
@ParameterizedTest
@CsvSource({
"NOUVEL_EVENEMENT, true",
"RAPPEL_EVENEMENT, true",
"EVENEMENT_ANNULE, true",
"COTISATION_DUE, true",
"COTISATION_RETARD, true",
"RAPPEL_COTISATION, true",
"APPEL_SOLIDARITE, true",
"INSCRIPTION_CONFIRMEE, false",
"COTISATION_PAYEE, false",
"NOUVEAU_MEMBRE, false"
})
@DisplayName("isActiveeParDefaut - types activés par défaut")
void testIsActiveeParDefaut(TypeNotification type, Boolean expected) {
assertThat(type.isActiveeParDefaut()).isEqualTo(expected);
}
}
@Nested
@DisplayName("Tests isCritique")
class IsCritiqueTests {
@ParameterizedTest
@CsvSource({
"INSCRIPTION_REFUSEE, true",
"PAIEMENT_ECHOUE, true",
"APPEL_SOLIDARITE, true",
"URGENCE_LOCALE, true",
"EVENEMENT_ANNULE, false",
"COTISATION_RETARD, false",
"NOUVEL_EVENEMENT, false",
"COTISATION_PAYEE, false"
})
@DisplayName("isCritique - types critiques")
void testIsCritique(TypeNotification type, Boolean expected) {
assertThat(type.isCritique()).isEqualTo(expected);
}
}
@Nested
@DisplayName("Tests isRappel")
class IsRappelTests {
@ParameterizedTest
@CsvSource({
"RAPPEL_EVENEMENT, true",
"COTISATION_DUE, true",
"RAPPEL_COTISATION, true",
"NOUVEL_EVENEMENT, false"
})
@DisplayName("isRappel - types de rappel")
void testIsRappel(TypeNotification type, Boolean expected) {
assertThat(type.isRappel()).isEqualTo(expected);
}
}
@Nested
@DisplayName("Tests isPositive")
class IsPositiveTests {
@ParameterizedTest
@CsvSource({
"INSCRIPTION_CONFIRMEE, true",
"COTISATION_PAYEE, true",
"PAIEMENT_CONFIRME, true",
"ANNIVERSAIRE_MEMBRE, true",
"NOUVEL_EVENEMENT, false"
})
@DisplayName("isPositive - types positifs")
void testIsPositive(TypeNotification type, Boolean expected) {
assertThat(type.isPositive()).isEqualTo(expected);
}
}
@Nested
@DisplayName("Tests getNiveauPriorite")
class GetNiveauPrioriteTests {
@ParameterizedTest
@CsvSource({
"URGENCE_LOCALE, 1",
"INSCRIPTION_REFUSEE, 2",
"PAIEMENT_ECHOUE, 2",
"EVENEMENT_ANNULE, 3",
"COTISATION_RETARD, 3",
"CHANGEMENT_REGLEMENT, 4",
"RAPPEL_EVENEMENT, 5",
"NOUVEL_EVENEMENT, 6",
"COTISATION_PAYEE, 7",
"ANNIVERSAIRE_MEMBRE, 8"
})
@DisplayName("getNiveauPriorite - tous les niveaux")
void testGetNiveauPriorite(TypeNotification type, int expected) {
assertThat(type.getNiveauPriorite()).isEqualTo(expected);
}
@Test
@DisplayName("getNiveauPriorite - priorité inconnue (default)")
void testGetNiveauPrioriteDefault() {
// Tester avec la réflexion pour créer un type avec priorité inconnue
try {
java.lang.reflect.Field prioriteField = TypeNotification.class.getDeclaredField("priorite");
prioriteField.setAccessible(true);
String prioriteOriginale = (String) prioriteField.get(TypeNotification.NOUVEL_EVENEMENT);
// Modifier temporairement la priorité à "inconnue"
prioriteField.set(TypeNotification.NOUVEL_EVENEMENT, "inconnue");
// Maintenant priorité = "inconnue" devrait retourner 6 (default)
assertThat(TypeNotification.NOUVEL_EVENEMENT.getNiveauPriorite()).isEqualTo(6);
// Restaurer la priorité originale
prioriteField.set(TypeNotification.NOUVEL_EVENEMENT, prioriteOriginale);
} catch (Exception e) {
org.junit.jupiter.api.Assumptions.assumeTrue(false, "Réflexion non disponible");
}
}
}
@Nested
@DisplayName("Tests getDelaiExpirationHeures")
class GetDelaiExpirationHeuresTests {
@ParameterizedTest
@CsvSource({
"URGENCE_LOCALE, 1",
"INSCRIPTION_REFUSEE, 24",
"PAIEMENT_ECHOUE, 24",
"DEMANDE_AIDE_REFUSEE, 24",
"PROBLEME_TECHNIQUE, 24",
"EVENEMENT_ANNULE, 48",
"COTISATION_RETARD, 48",
"CHANGEMENT_REGLEMENT, 72",
"RAPPEL_EVENEMENT, 24",
"NOUVEL_EVENEMENT, 168",
"COTISATION_PAYEE, 48",
"ANNIVERSAIRE_MEMBRE, 72"
})
@DisplayName("getDelaiExpirationHeures - tous les délais")
void testGetDelaiExpirationHeures(TypeNotification type, int expected) {
assertThat(type.getDelaiExpirationHeures()).isEqualTo(expected);
}
@Test
@DisplayName("getDelaiExpirationHeures - tous les cas du switch")
void testGetDelaiExpirationHeuresTousCas() {
// Tester tous les cas du switch pour s'assurer que toutes les branches sont couvertes
// urgent -> 1
assertThat(TypeNotification.URGENCE_LOCALE.getDelaiExpirationHeures()).isEqualTo(1);
assertThat(TypeNotification.APPEL_SOLIDARITE.getDelaiExpirationHeures()).isEqualTo(1);
// error -> 24
assertThat(TypeNotification.INSCRIPTION_REFUSEE.getDelaiExpirationHeures()).isEqualTo(24);
assertThat(TypeNotification.PAIEMENT_ECHOUE.getDelaiExpirationHeures()).isEqualTo(24);
assertThat(TypeNotification.DEMANDE_AIDE_REFUSEE.getDelaiExpirationHeures()).isEqualTo(24);
assertThat(TypeNotification.PROBLEME_TECHNIQUE.getDelaiExpirationHeures()).isEqualTo(24);
// warning -> 48
assertThat(TypeNotification.EVENEMENT_ANNULE.getDelaiExpirationHeures()).isEqualTo(48);
assertThat(TypeNotification.COTISATION_RETARD.getDelaiExpirationHeures()).isEqualTo(48);
assertThat(TypeNotification.MEMBRE_INACTIF.getDelaiExpirationHeures()).isEqualTo(48);
assertThat(TypeNotification.MAINTENANCE_PROGRAMMEE.getDelaiExpirationHeures()).isEqualTo(48);
// important -> 72
assertThat(TypeNotification.CHANGEMENT_REGLEMENT.getDelaiExpirationHeures()).isEqualTo(72);
// reminder -> 24
assertThat(TypeNotification.RAPPEL_EVENEMENT.getDelaiExpirationHeures()).isEqualTo(24);
assertThat(TypeNotification.COTISATION_DUE.getDelaiExpirationHeures()).isEqualTo(24);
assertThat(TypeNotification.RAPPEL_COTISATION.getDelaiExpirationHeures()).isEqualTo(24);
// info -> 168
assertThat(TypeNotification.NOUVEL_EVENEMENT.getDelaiExpirationHeures()).isEqualTo(168);
assertThat(TypeNotification.EVENEMENT_MODIFIE.getDelaiExpirationHeures()).isEqualTo(168);
assertThat(TypeNotification.LISTE_ATTENTE.getDelaiExpirationHeures()).isEqualTo(168);
// success -> 48
assertThat(TypeNotification.COTISATION_PAYEE.getDelaiExpirationHeures()).isEqualTo(48);
assertThat(TypeNotification.PAIEMENT_CONFIRME.getDelaiExpirationHeures()).isEqualTo(48);
assertThat(TypeNotification.DEMANDE_AIDE_APPROUVEE.getDelaiExpirationHeures()).isEqualTo(48);
// celebration -> 72
assertThat(TypeNotification.ANNIVERSAIRE_MEMBRE.getDelaiExpirationHeures()).isEqualTo(72);
}
@Test
@DisplayName("getDelaiExpirationHeures - priorité inconnue (default = 168)")
void testGetDelaiExpirationHeuresDefault() {
// Tester avec la réflexion pour créer un type avec priorité inconnue
try {
java.lang.reflect.Field prioriteField = TypeNotification.class.getDeclaredField("priorite");
prioriteField.setAccessible(true);
String prioriteOriginale = (String) prioriteField.get(TypeNotification.NOUVEL_EVENEMENT);
// Modifier temporairement la priorité à "inconnue"
prioriteField.set(TypeNotification.NOUVEL_EVENEMENT, "inconnue");
// Maintenant priorité = "inconnue" devrait retourner 168 (default)
assertThat(TypeNotification.NOUVEL_EVENEMENT.getDelaiExpirationHeures()).isEqualTo(168);
// Restaurer la priorité originale
prioriteField.set(TypeNotification.NOUVEL_EVENEMENT, prioriteOriginale);
} catch (Exception e) {
org.junit.jupiter.api.Assumptions.assumeTrue(false, "Réflexion non disponible");
}
}
}
@Nested
@DisplayName("Tests doitVibrer")
class DoitVibrerTests {
@ParameterizedTest
@CsvSource({
"URGENCE_LOCALE, true",
"INSCRIPTION_REFUSEE, true",
"PAIEMENT_ECHOUE, true",
"RAPPEL_EVENEMENT, true",
"EVENEMENT_ANNULE, false",
"NOUVEL_EVENEMENT, false",
"COTISATION_PAYEE, false"
})
@DisplayName("doitVibrer - types qui doivent vibrer")
void testDoitVibrer(TypeNotification type, Boolean expected) {
assertThat(type.doitVibrer()).isEqualTo(expected);
}
@Test
@DisplayName("doitVibrer - branche isCritique() == true (court-circuit)")
void testDoitVibrerCritique() {
// Types critiques (urgent ou error) doivent vibrer
// isCritique() retourne true, donc court-circuit et retourne true
assertThat(TypeNotification.URGENCE_LOCALE.doitVibrer()).isTrue();
assertThat(TypeNotification.URGENCE_LOCALE.isCritique()).isTrue();
assertThat(TypeNotification.URGENCE_LOCALE.isRappel()).isFalse();
assertThat(TypeNotification.INSCRIPTION_REFUSEE.doitVibrer()).isTrue();
assertThat(TypeNotification.INSCRIPTION_REFUSEE.isCritique()).isTrue();
assertThat(TypeNotification.INSCRIPTION_REFUSEE.isRappel()).isFalse();
}
@Test
@DisplayName("doitVibrer - branche isCritique() == false && isRappel() == true")
void testDoitVibrerRappel() {
// Types rappel (mais pas critiques) doivent vibrer
// isCritique() retourne false, mais isRappel() retourne true
assertThat(TypeNotification.RAPPEL_EVENEMENT.doitVibrer()).isTrue();
assertThat(TypeNotification.RAPPEL_EVENEMENT.isCritique()).isFalse();
assertThat(TypeNotification.RAPPEL_EVENEMENT.isRappel()).isTrue();
assertThat(TypeNotification.COTISATION_DUE.doitVibrer()).isTrue();
assertThat(TypeNotification.COTISATION_DUE.isCritique()).isFalse();
assertThat(TypeNotification.COTISATION_DUE.isRappel()).isTrue();
}
@Test
@DisplayName("doitVibrer - branche isCritique() == false && isRappel() == false")
void testDoitVibrerNiCritiqueNiRappel() {
// Types ni critiques ni rappels ne doivent pas vibrer
assertThat(TypeNotification.NOUVEL_EVENEMENT.doitVibrer()).isFalse();
assertThat(TypeNotification.NOUVEL_EVENEMENT.isCritique()).isFalse();
assertThat(TypeNotification.NOUVEL_EVENEMENT.isRappel()).isFalse();
assertThat(TypeNotification.COTISATION_PAYEE.doitVibrer()).isFalse();
assertThat(TypeNotification.COTISATION_PAYEE.isCritique()).isFalse();
assertThat(TypeNotification.COTISATION_PAYEE.isRappel()).isFalse();
}
}
@Nested
@DisplayName("Tests doitEmettreSon")
class DoitEmettreSonTests {
@ParameterizedTest
@CsvSource({
"URGENCE_LOCALE, true",
"INSCRIPTION_REFUSEE, true",
"PAIEMENT_ECHOUE, true",
"RAPPEL_EVENEMENT, true",
"CHANGEMENT_REGLEMENT, true",
"EVENEMENT_ANNULE, false",
"NOUVEL_EVENEMENT, false",
"COTISATION_PAYEE, false"
})
@DisplayName("doitEmettreSon - types qui doivent émettre un son")
void testDoitEmettreSon(TypeNotification type, Boolean expected) {
assertThat(type.doitEmettreSon()).isEqualTo(expected);
}
@Test
@DisplayName("doitEmettreSon - branche isCritique() == true (court-circuit)")
void testDoitEmettreSonCritique() {
// Types critiques (urgent ou error) doivent émettre un son
// isCritique() retourne true, donc court-circuit et retourne true
assertThat(TypeNotification.URGENCE_LOCALE.doitEmettreSon()).isTrue();
assertThat(TypeNotification.URGENCE_LOCALE.isCritique()).isTrue();
assertThat(TypeNotification.URGENCE_LOCALE.isRappel()).isFalse();
assertThat(TypeNotification.URGENCE_LOCALE.getPriorite()).isNotEqualTo("important");
assertThat(TypeNotification.INSCRIPTION_REFUSEE.doitEmettreSon()).isTrue();
assertThat(TypeNotification.INSCRIPTION_REFUSEE.isCritique()).isTrue();
assertThat(TypeNotification.INSCRIPTION_REFUSEE.isRappel()).isFalse();
}
@Test
@DisplayName("doitEmettreSon - branche isCritique() == false && isRappel() == true (court-circuit)")
void testDoitEmettreSonRappel() {
// Types rappel (mais pas critiques) doivent émettre un son
// isCritique() retourne false, mais isRappel() retourne true, donc court-circuit
assertThat(TypeNotification.RAPPEL_EVENEMENT.doitEmettreSon()).isTrue();
assertThat(TypeNotification.RAPPEL_EVENEMENT.isCritique()).isFalse();
assertThat(TypeNotification.RAPPEL_EVENEMENT.isRappel()).isTrue();
assertThat(TypeNotification.RAPPEL_EVENEMENT.getPriorite()).isNotEqualTo("important");
assertThat(TypeNotification.COTISATION_DUE.doitEmettreSon()).isTrue();
assertThat(TypeNotification.COTISATION_DUE.isCritique()).isFalse();
assertThat(TypeNotification.COTISATION_DUE.isRappel()).isTrue();
}
@Test
@DisplayName("doitEmettreSon - branche isCritique() == false && isRappel() == false && priorite == important")
void testDoitEmettreSonImportant() {
// Types avec priorité "important" (mais ni critiques ni rappels) doivent émettre un son
assertThat(TypeNotification.CHANGEMENT_REGLEMENT.doitEmettreSon()).isTrue();
assertThat(TypeNotification.CHANGEMENT_REGLEMENT.isCritique()).isFalse();
assertThat(TypeNotification.CHANGEMENT_REGLEMENT.isRappel()).isFalse();
assertThat(TypeNotification.CHANGEMENT_REGLEMENT.getPriorite()).isEqualTo("important");
}
@Test
@DisplayName("doitEmettreSon - branche isCritique() == false && isRappel() == false && priorite != important")
void testDoitEmettreSonNiCritiqueNiRappelNiImportant() {
// Types ni critiques, ni rappels, ni important ne doivent pas émettre de son
assertThat(TypeNotification.NOUVEL_EVENEMENT.doitEmettreSon()).isFalse();
assertThat(TypeNotification.NOUVEL_EVENEMENT.isCritique()).isFalse();
assertThat(TypeNotification.NOUVEL_EVENEMENT.isRappel()).isFalse();
assertThat(TypeNotification.NOUVEL_EVENEMENT.getPriorite()).isNotEqualTo("important");
assertThat(TypeNotification.COTISATION_PAYEE.doitEmettreSon()).isFalse();
assertThat(TypeNotification.COTISATION_PAYEE.isCritique()).isFalse();
assertThat(TypeNotification.COTISATION_PAYEE.isRappel()).isFalse();
assertThat(TypeNotification.COTISATION_PAYEE.getPriorite()).isNotEqualTo("important");
}
}
@Nested
@DisplayName("Tests getCanalNotification")
class GetCanalNotificationTests {
@ParameterizedTest
@CsvSource({
"URGENCE_LOCALE, URGENT_CHANNEL",
"INSCRIPTION_REFUSEE, ERROR_CHANNEL",
"PAIEMENT_ECHOUE, ERROR_CHANNEL",
"DEMANDE_AIDE_REFUSEE, ERROR_CHANNEL",
"PROBLEME_TECHNIQUE, ERROR_CHANNEL",
"EVENEMENT_ANNULE, WARNING_CHANNEL",
"COTISATION_RETARD, WARNING_CHANNEL",
"CHANGEMENT_REGLEMENT, IMPORTANT_CHANNEL",
"RAPPEL_EVENEMENT, REMINDER_CHANNEL",
"COTISATION_PAYEE, SUCCESS_CHANNEL",
"ANNIVERSAIRE_MEMBRE, CELEBRATION_CHANNEL",
"NOUVEL_EVENEMENT, DEFAULT_CHANNEL"
})
@DisplayName("getCanalNotification - tous les canaux")
void testGetCanalNotification(TypeNotification type, String expected) {
assertThat(type.getCanalNotification()).isEqualTo(expected);
}
@Test
@DisplayName("getCanalNotification - tous les cas du switch")
void testGetCanalNotificationTousCas() {
// Tester tous les cas du switch pour s'assurer que toutes les branches sont couvertes
// urgent -> URGENT_CHANNEL
assertThat(TypeNotification.URGENCE_LOCALE.getCanalNotification()).isEqualTo("URGENT_CHANNEL");
assertThat(TypeNotification.APPEL_SOLIDARITE.getCanalNotification()).isEqualTo("URGENT_CHANNEL");
// error -> ERROR_CHANNEL
assertThat(TypeNotification.INSCRIPTION_REFUSEE.getCanalNotification()).isEqualTo("ERROR_CHANNEL");
assertThat(TypeNotification.PAIEMENT_ECHOUE.getCanalNotification()).isEqualTo("ERROR_CHANNEL");
assertThat(TypeNotification.DEMANDE_AIDE_REFUSEE.getCanalNotification()).isEqualTo("ERROR_CHANNEL");
assertThat(TypeNotification.PROBLEME_TECHNIQUE.getCanalNotification()).isEqualTo("ERROR_CHANNEL");
// warning -> WARNING_CHANNEL
assertThat(TypeNotification.EVENEMENT_ANNULE.getCanalNotification()).isEqualTo("WARNING_CHANNEL");
assertThat(TypeNotification.COTISATION_RETARD.getCanalNotification()).isEqualTo("WARNING_CHANNEL");
assertThat(TypeNotification.MEMBRE_INACTIF.getCanalNotification()).isEqualTo("WARNING_CHANNEL");
assertThat(TypeNotification.MAINTENANCE_PROGRAMMEE.getCanalNotification()).isEqualTo("WARNING_CHANNEL");
// important -> IMPORTANT_CHANNEL
assertThat(TypeNotification.CHANGEMENT_REGLEMENT.getCanalNotification()).isEqualTo("IMPORTANT_CHANNEL");
// reminder -> REMINDER_CHANNEL
assertThat(TypeNotification.RAPPEL_EVENEMENT.getCanalNotification()).isEqualTo("REMINDER_CHANNEL");
assertThat(TypeNotification.COTISATION_DUE.getCanalNotification()).isEqualTo("REMINDER_CHANNEL");
assertThat(TypeNotification.RAPPEL_COTISATION.getCanalNotification()).isEqualTo("REMINDER_CHANNEL");
// success -> SUCCESS_CHANNEL
assertThat(TypeNotification.COTISATION_PAYEE.getCanalNotification()).isEqualTo("SUCCESS_CHANNEL");
assertThat(TypeNotification.PAIEMENT_CONFIRME.getCanalNotification()).isEqualTo("SUCCESS_CHANNEL");
assertThat(TypeNotification.DEMANDE_AIDE_APPROUVEE.getCanalNotification()).isEqualTo("SUCCESS_CHANNEL");
// celebration -> CELEBRATION_CHANNEL
assertThat(TypeNotification.ANNIVERSAIRE_MEMBRE.getCanalNotification()).isEqualTo("CELEBRATION_CHANNEL");
// info -> DEFAULT_CHANNEL
assertThat(TypeNotification.NOUVEL_EVENEMENT.getCanalNotification()).isEqualTo("DEFAULT_CHANNEL");
assertThat(TypeNotification.EVENEMENT_MODIFIE.getCanalNotification()).isEqualTo("DEFAULT_CHANNEL");
assertThat(TypeNotification.LISTE_ATTENTE.getCanalNotification()).isEqualTo("DEFAULT_CHANNEL");
}
@Test
@DisplayName("getCanalNotification - priorité inconnue (default = DEFAULT_CHANNEL)")
void testGetCanalNotificationDefault() {
// Tester avec la réflexion pour créer un type avec priorité inconnue
try {
java.lang.reflect.Field prioriteField = TypeNotification.class.getDeclaredField("priorite");
prioriteField.setAccessible(true);
String prioriteOriginale = (String) prioriteField.get(TypeNotification.NOUVEL_EVENEMENT);
// Modifier temporairement la priorité à "inconnue"
prioriteField.set(TypeNotification.NOUVEL_EVENEMENT, "inconnue");
// Maintenant priorité = "inconnue" devrait retourner DEFAULT_CHANNEL (default)
assertThat(TypeNotification.NOUVEL_EVENEMENT.getCanalNotification()).isEqualTo("DEFAULT_CHANNEL");
// Restaurer la priorité originale
prioriteField.set(TypeNotification.NOUVEL_EVENEMENT, prioriteOriginale);
} catch (Exception e) {
org.junit.jupiter.api.Assumptions.assumeTrue(false, "Réflexion non disponible");
}
}
}
}

View File

@@ -39,7 +39,7 @@ public class Adresse extends BaseEntity {
/** Type d'adresse */ /** Type d'adresse */
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name = "type_adresse", nullable = false, length = 50) @Column(name = "type_adresse", nullable = false, length = 50)
private dev.lions.unionflow.server.api.enums.adresse.TypeAdresse typeAdresse; private TypeAdresse typeAdresse;
/** Adresse complète */ /** Adresse complète */
@Column(name = "adresse", length = 500) @Column(name = "adresse", length = 500)

View File

@@ -68,9 +68,6 @@ public class Membre extends BaseEntity {
@Column(name = "date_adhesion", nullable = false) @Column(name = "date_adhesion", nullable = false)
private LocalDate dateAdhesion; private LocalDate dateAdhesion;
@Column(name = "roles", length = 500)
private String roles;
// Relations // Relations
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "organisation_id") @JoinColumn(name = "organisation_id")

View File

@@ -6,6 +6,8 @@ import jakarta.persistence.*;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -1,7 +1,7 @@
package dev.lions.unionflow.server.repository; package dev.lions.unionflow.server.repository;
import dev.lions.unionflow.server.api.enums.adresse.TypeAdresse;
import dev.lions.unionflow.server.entity.Adresse; import dev.lions.unionflow.server.entity.Adresse;
import dev.lions.unionflow.server.entity.Adresse.TypeAdresse;
import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
@@ -18,6 +18,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class AdresseRepository implements PanacheRepository<Adresse> { public class AdresseRepository implements PanacheRepository<Adresse> {
/**
* Trouve une adresse par son UUID
*
* @param id UUID de l'adresse
* @return Adresse ou Optional.empty()
*/
public Optional<Adresse> findAdresseById(UUID id) {
return find("id = ?1", id).firstResultOptional();
}
/** /**
* Trouve toutes les adresses d'une organisation * Trouve toutes les adresses d'une organisation
* *

View File

@@ -6,6 +6,7 @@ import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
/** /**
* Repository pour l'entité CompteComptable * Repository pour l'entité CompteComptable
@@ -17,6 +18,16 @@ import java.util.Optional;
@ApplicationScoped @ApplicationScoped
public class CompteComptableRepository implements PanacheRepository<CompteComptable> { public class CompteComptableRepository implements PanacheRepository<CompteComptable> {
/**
* Trouve un compte comptable par son UUID
*
* @param id UUID du compte comptable
* @return Compte comptable ou Optional.empty()
*/
public Optional<CompteComptable> findCompteComptableById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un compte par son numéro * Trouve un compte par son numéro
* *

View File

@@ -18,6 +18,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class CompteWaveRepository implements PanacheRepository<CompteWave> { public class CompteWaveRepository implements PanacheRepository<CompteWave> {
/**
* Trouve un compte Wave par son UUID
*
* @param id UUID du compte Wave
* @return Compte Wave ou Optional.empty()
*/
public Optional<CompteWave> findCompteWaveById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un compte Wave par numéro de téléphone * Trouve un compte Wave par numéro de téléphone
* *

View File

@@ -5,6 +5,7 @@ import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
/** /**
* Repository pour l'entité ConfigurationWave * Repository pour l'entité ConfigurationWave
@@ -16,6 +17,16 @@ import java.util.Optional;
@ApplicationScoped @ApplicationScoped
public class ConfigurationWaveRepository implements PanacheRepository<ConfigurationWave> { public class ConfigurationWaveRepository implements PanacheRepository<ConfigurationWave> {
/**
* Trouve une configuration Wave par son UUID
*
* @param id UUID de la configuration
* @return Configuration ou Optional.empty()
*/
public Optional<ConfigurationWave> findConfigurationWaveById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve une configuration par sa clé * Trouve une configuration par sa clé
* *

View File

@@ -258,7 +258,7 @@ public class CotisationRepository extends BaseRepository<Cotisation> {
* @return true si mise à jour réussie * @return true si mise à jour réussie
*/ */
public boolean incrementerNombreRappels(UUID cotisationId) { public boolean incrementerNombreRappels(UUID cotisationId) {
Cotisation cotisation = findById(cotisationId); Cotisation cotisation = findByIdOptional(cotisationId).orElse(null);
if (cotisation != null) { if (cotisation != null) {
cotisation.setNombreRappels( cotisation.setNombreRappels(
cotisation.getNombreRappels() != null ? cotisation.getNombreRappels() + 1 : 1); cotisation.getNombreRappels() != null ? cotisation.getNombreRappels() + 1 : 1);

View File

@@ -6,6 +6,7 @@ import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
/** /**
* Repository pour l'entité Document * Repository pour l'entité Document
@@ -17,6 +18,16 @@ import java.util.Optional;
@ApplicationScoped @ApplicationScoped
public class DocumentRepository implements PanacheRepository<Document> { public class DocumentRepository implements PanacheRepository<Document> {
/**
* Trouve un document par son UUID
*
* @param id UUID du document
* @return Document ou Optional.empty()
*/
public Optional<Document> findDocumentById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un document par son hash MD5 * Trouve un document par son hash MD5
* *

View File

@@ -18,6 +18,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class EcritureComptableRepository implements PanacheRepository<EcritureComptable> { public class EcritureComptableRepository implements PanacheRepository<EcritureComptable> {
/**
* Trouve une écriture comptable par son UUID
*
* @param id UUID de l'écriture comptable
* @return Écriture comptable ou Optional.empty()
*/
public Optional<EcritureComptable> findEcritureComptableById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve une écriture par son numéro de pièce * Trouve une écriture par son numéro de pièce
* *

View File

@@ -7,6 +7,7 @@ import jakarta.enterprise.context.ApplicationScoped;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
/** /**
* Repository pour l'entité JournalComptable * Repository pour l'entité JournalComptable
@@ -18,6 +19,16 @@ import java.util.Optional;
@ApplicationScoped @ApplicationScoped
public class JournalComptableRepository implements PanacheRepository<JournalComptable> { public class JournalComptableRepository implements PanacheRepository<JournalComptable> {
/**
* Trouve un journal comptable par son UUID
*
* @param id UUID du journal comptable
* @return Journal comptable ou Optional.empty()
*/
public Optional<JournalComptable> findJournalComptableById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un journal par son code * Trouve un journal par son code
* *

View File

@@ -4,6 +4,7 @@ import dev.lions.unionflow.server.entity.LigneEcriture;
import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -16,6 +17,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class LigneEcritureRepository implements PanacheRepository<LigneEcriture> { public class LigneEcritureRepository implements PanacheRepository<LigneEcriture> {
/**
* Trouve une ligne d'écriture par son UUID
*
* @param id UUID de la ligne d'écriture
* @return Ligne d'écriture ou Optional.empty()
*/
public Optional<LigneEcriture> findLigneEcritureById(UUID id) {
return find("id = ?1", id).firstResultOptional();
}
/** /**
* Trouve toutes les lignes d'une écriture * Trouve toutes les lignes d'une écriture
* *

View File

@@ -5,6 +5,7 @@ import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -17,6 +18,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class MembreRoleRepository implements PanacheRepository<MembreRole> { public class MembreRoleRepository implements PanacheRepository<MembreRole> {
/**
* Trouve une attribution membre-role par son UUID
*
* @param id UUID de l'attribution
* @return Attribution ou Optional.empty()
*/
public Optional<MembreRole> findMembreRoleById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve tous les rôles d'un membre * Trouve tous les rôles d'un membre
* *

View File

@@ -8,6 +8,7 @@ import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -20,6 +21,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class NotificationRepository implements PanacheRepository<Notification> { public class NotificationRepository implements PanacheRepository<Notification> {
/**
* Trouve une notification par son UUID
*
* @param id UUID de la notification
* @return Notification ou Optional.empty()
*/
public Optional<Notification> findNotificationById(UUID id) {
return find("id = ?1", id).firstResultOptional();
}
/** /**
* Trouve toutes les notifications d'un membre * Trouve toutes les notifications d'un membre
* *

View File

@@ -23,6 +23,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class PaiementRepository implements PanacheRepository<Paiement> { public class PaiementRepository implements PanacheRepository<Paiement> {
/**
* Trouve un paiement par son UUID
*
* @param id UUID du paiement
* @return Paiement ou Optional.empty()
*/
public Optional<Paiement> findPaiementById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un paiement par son numéro de référence * Trouve un paiement par son numéro de référence
* *
@@ -40,8 +50,7 @@ public class PaiementRepository implements PanacheRepository<Paiement> {
* @return Liste des paiements * @return Liste des paiements
*/ */
public List<Paiement> findByMembreId(UUID membreId) { public List<Paiement> findByMembreId(UUID membreId) {
return find("membre.id = ?1 AND actif = true", membreId) return find("membre.id = ?1 AND actif = true", Sort.by("datePaiement", Sort.Direction.Descending), membreId)
.order("datePaiement DESC")
.list(); .list();
} }
@@ -52,8 +61,7 @@ public class PaiementRepository implements PanacheRepository<Paiement> {
* @return Liste des paiements * @return Liste des paiements
*/ */
public List<Paiement> findByStatut(StatutPaiement statut) { public List<Paiement> findByStatut(StatutPaiement statut) {
return find("statutPaiement = ?1 AND actif = true", statut) return find("statutPaiement = ?1 AND actif = true", Sort.by("datePaiement", Sort.Direction.Descending), statut)
.order("datePaiement DESC")
.list(); .list();
} }
@@ -64,8 +72,7 @@ public class PaiementRepository implements PanacheRepository<Paiement> {
* @return Liste des paiements * @return Liste des paiements
*/ */
public List<Paiement> findByMethode(MethodePaiement methode) { public List<Paiement> findByMethode(MethodePaiement methode) {
return find("methodePaiement = ?1 AND actif = true", methode) return find("methodePaiement = ?1 AND actif = true", Sort.by("datePaiement", Sort.Direction.Descending), methode)
.order("datePaiement DESC")
.list(); .list();
} }
@@ -79,10 +86,10 @@ public class PaiementRepository implements PanacheRepository<Paiement> {
public List<Paiement> findValidesParPeriode(LocalDateTime dateDebut, LocalDateTime dateFin) { public List<Paiement> findValidesParPeriode(LocalDateTime dateDebut, LocalDateTime dateFin) {
return find( return find(
"statutPaiement = ?1 AND dateValidation >= ?2 AND dateValidation <= ?3 AND actif = true", "statutPaiement = ?1 AND dateValidation >= ?2 AND dateValidation <= ?3 AND actif = true",
Sort.by("dateValidation", Sort.Direction.Descending),
StatutPaiement.VALIDE, StatutPaiement.VALIDE,
dateDebut, dateDebut,
dateFin) dateFin)
.order("dateValidation DESC")
.list(); .list();
} }

View File

@@ -2,9 +2,11 @@ package dev.lions.unionflow.server.repository;
import dev.lions.unionflow.server.entity.Permission; import dev.lions.unionflow.server.entity.Permission;
import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepository;
import io.quarkus.panache.common.Sort;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
/** /**
* Repository pour l'entité Permission * Repository pour l'entité Permission
@@ -16,6 +18,16 @@ import java.util.Optional;
@ApplicationScoped @ApplicationScoped
public class PermissionRepository implements PanacheRepository<Permission> { public class PermissionRepository implements PanacheRepository<Permission> {
/**
* Trouve une permission par son UUID
*
* @param id UUID de la permission
* @return Permission ou Optional.empty()
*/
public Optional<Permission> findPermissionById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve une permission par son code * Trouve une permission par son code
* *
@@ -67,7 +79,9 @@ public class PermissionRepository implements PanacheRepository<Permission> {
* @return Liste des permissions actives * @return Liste des permissions actives
*/ */
public List<Permission> findAllActives() { public List<Permission> findAllActives() {
return find("actif = true").order("module ASC, ressource ASC, action ASC").list(); return find("actif = true", Sort.by("module", Sort.Direction.Ascending)
.and("ressource", Sort.Direction.Ascending)
.and("action", Sort.Direction.Ascending)).list();
} }
} }

View File

@@ -4,6 +4,7 @@ import dev.lions.unionflow.server.entity.PieceJointe;
import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -16,6 +17,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class PieceJointeRepository implements PanacheRepository<PieceJointe> { public class PieceJointeRepository implements PanacheRepository<PieceJointe> {
/**
* Trouve une pièce jointe par son UUID
*
* @param id UUID de la pièce jointe
* @return Pièce jointe ou Optional.empty()
*/
public Optional<PieceJointe> findPieceJointeById(UUID id) {
return find("id = ?1", id).firstResultOptional();
}
/** /**
* Trouve toutes les pièces jointes d'un document * Trouve toutes les pièces jointes d'un document
* *

View File

@@ -4,6 +4,7 @@ import dev.lions.unionflow.server.entity.RolePermission;
import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -16,6 +17,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class RolePermissionRepository implements PanacheRepository<RolePermission> { public class RolePermissionRepository implements PanacheRepository<RolePermission> {
/**
* Trouve une association rôle-permission par son UUID
*
* @param id UUID de l'association
* @return Association ou Optional.empty()
*/
public Optional<RolePermission> findRolePermissionById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve toutes les permissions d'un rôle * Trouve toutes les permissions d'un rôle
* *

View File

@@ -3,6 +3,7 @@ package dev.lions.unionflow.server.repository;
import dev.lions.unionflow.server.entity.Role; import dev.lions.unionflow.server.entity.Role;
import dev.lions.unionflow.server.entity.Role.TypeRole; import dev.lions.unionflow.server.entity.Role.TypeRole;
import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepository;
import io.quarkus.panache.common.Sort;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -18,6 +19,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class RoleRepository implements PanacheRepository<Role> { public class RoleRepository implements PanacheRepository<Role> {
/**
* Trouve un rôle par son UUID
*
* @param id UUID du rôle
* @return Rôle ou Optional.empty()
*/
public Optional<Role> findRoleById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un rôle par son code * Trouve un rôle par son code
* *
@@ -34,8 +45,7 @@ public class RoleRepository implements PanacheRepository<Role> {
* @return Liste des rôles système * @return Liste des rôles système
*/ */
public List<Role> findRolesSysteme() { public List<Role> findRolesSysteme() {
return find("typeRole = ?1 AND actif = true", TypeRole.SYSTEME) return find("typeRole = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending), TypeRole.SYSTEME)
.order("niveauHierarchique ASC")
.list(); .list();
} }
@@ -46,8 +56,7 @@ public class RoleRepository implements PanacheRepository<Role> {
* @return Liste des rôles * @return Liste des rôles
*/ */
public List<Role> findByOrganisationId(UUID organisationId) { public List<Role> findByOrganisationId(UUID organisationId) {
return find("organisation.id = ?1 AND actif = true", organisationId) return find("organisation.id = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending), organisationId)
.order("niveauHierarchique ASC")
.list(); .list();
} }
@@ -57,7 +66,7 @@ public class RoleRepository implements PanacheRepository<Role> {
* @return Liste des rôles actifs * @return Liste des rôles actifs
*/ */
public List<Role> findAllActifs() { public List<Role> findAllActifs() {
return find("actif = true").order("niveauHierarchique ASC").list(); return find("actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending)).list();
} }
/** /**
@@ -67,8 +76,7 @@ public class RoleRepository implements PanacheRepository<Role> {
* @return Liste des rôles * @return Liste des rôles
*/ */
public List<Role> findByType(TypeRole typeRole) { public List<Role> findByType(TypeRole typeRole) {
return find("typeRole = ?1 AND actif = true", typeRole) return find("typeRole = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending), typeRole)
.order("niveauHierarchique ASC")
.list(); .list();
} }
} }

View File

@@ -5,6 +5,7 @@ import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
/** /**
* Repository pour l'entité TemplateNotification * Repository pour l'entité TemplateNotification
@@ -16,6 +17,16 @@ import java.util.Optional;
@ApplicationScoped @ApplicationScoped
public class TemplateNotificationRepository implements PanacheRepository<TemplateNotification> { public class TemplateNotificationRepository implements PanacheRepository<TemplateNotification> {
/**
* Trouve un template par son UUID
*
* @param id UUID du template
* @return Template ou Optional.empty()
*/
public Optional<TemplateNotification> findTemplateNotificationById(UUID id) {
return find("id = ?1 AND actif = true", id).firstResultOptional();
}
/** /**
* Trouve un template par son code * Trouve un template par son code
* *

View File

@@ -19,6 +19,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class TransactionWaveRepository implements PanacheRepository<TransactionWave> { public class TransactionWaveRepository implements PanacheRepository<TransactionWave> {
/**
* Trouve une transaction par son UUID
*
* @param id UUID de la transaction
* @return Transaction ou Optional.empty()
*/
public Optional<TransactionWave> findTransactionWaveById(UUID id) {
return find("id = ?1", id).firstResultOptional();
}
/** /**
* Trouve une transaction par son identifiant Wave * Trouve une transaction par son identifiant Wave
* *

View File

@@ -19,6 +19,16 @@ import java.util.UUID;
@ApplicationScoped @ApplicationScoped
public class WebhookWaveRepository implements PanacheRepository<WebhookWave> { public class WebhookWaveRepository implements PanacheRepository<WebhookWave> {
/**
* Trouve un webhook Wave par son UUID
*
* @param id UUID du webhook
* @return Webhook ou Optional.empty()
*/
public Optional<WebhookWave> findWebhookWaveById(UUID id) {
return find("id = ?1", id).firstResultOptional();
}
/** /**
* Trouve un webhook par son identifiant d'événement Wave * Trouve un webhook par son identifiant d'événement Wave
* *

View File

@@ -75,7 +75,7 @@ public class AdresseService {
Adresse adresse = Adresse adresse =
adresseRepository adresseRepository
.findByIdOptional(id) .findAdresseById(id)
.orElseThrow(() -> new NotFoundException("Adresse non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Adresse non trouvée avec l'ID: " + id));
// Mise à jour des champs // Mise à jour des champs
@@ -103,7 +103,7 @@ public class AdresseService {
Adresse adresse = Adresse adresse =
adresseRepository adresseRepository
.findByIdOptional(id) .findAdresseById(id)
.orElseThrow(() -> new NotFoundException("Adresse non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Adresse non trouvée avec l'ID: " + id));
adresseRepository.delete(adresse); adresseRepository.delete(adresse);
@@ -118,7 +118,7 @@ public class AdresseService {
*/ */
public AdresseDTO trouverParId(UUID id) { public AdresseDTO trouverParId(UUID id) {
return adresseRepository return adresseRepository
.findByIdOptional(id) .findAdresseById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Adresse non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Adresse non trouvée avec l'ID: " + id));
} }
@@ -346,11 +346,6 @@ public class AdresseService {
} }
/** Convertit TypeAdresse (entité) vers TypeAdresse (DTO) - même enum, pas de conversion nécessaire */ /** Convertit TypeAdresse (entité) vers TypeAdresse (DTO) - même enum, pas de conversion nécessaire */
private TypeAdresse convertTypeAdresse(TypeAdresse type) {
return type; // Même enum, pas de conversion nécessaire
}
/** Convertit TypeAdresse (DTO) vers TypeAdresse (entité) - même enum, pas de conversion nécessaire */
private TypeAdresse convertTypeAdresse(TypeAdresse type) { private TypeAdresse convertTypeAdresse(TypeAdresse type) {
return type != null ? type : TypeAdresse.AUTRE; // Même enum, valeur par défaut si null return type != null ? type : TypeAdresse.AUTRE; // Même enum, valeur par défaut si null
} }

View File

@@ -77,7 +77,7 @@ public class ComptabiliteService {
*/ */
public CompteComptableDTO trouverCompteParId(UUID id) { public CompteComptableDTO trouverCompteParId(UUID id) {
return compteComptableRepository return compteComptableRepository
.findByIdOptional(id) .findCompteComptableById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Compte comptable non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Compte comptable non trouvé avec l'ID: " + id));
} }
@@ -129,7 +129,7 @@ public class ComptabiliteService {
*/ */
public JournalComptableDTO trouverJournalParId(UUID id) { public JournalComptableDTO trouverJournalParId(UUID id) {
return journalComptableRepository return journalComptableRepository
.findByIdOptional(id) .findJournalComptableById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Journal comptable non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Journal comptable non trouvé avec l'ID: " + id));
} }
@@ -184,7 +184,7 @@ public class ComptabiliteService {
*/ */
public EcritureComptableDTO trouverEcritureParId(UUID id) { public EcritureComptableDTO trouverEcritureParId(UUID id) {
return ecritureComptableRepository return ecritureComptableRepository
.findByIdOptional(id) .findEcritureComptableById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Écriture comptable non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Écriture comptable non trouvée avec l'ID: " + id));
} }
@@ -382,7 +382,7 @@ public class ComptabiliteService {
if (dto.getJournalId() != null) { if (dto.getJournalId() != null) {
JournalComptable journal = JournalComptable journal =
journalComptableRepository journalComptableRepository
.findByIdOptional(dto.getJournalId()) .findJournalComptableById(dto.getJournalId())
.orElseThrow( .orElseThrow(
() -> new NotFoundException("Journal comptable non trouvé avec l'ID: " + dto.getJournalId())); () -> new NotFoundException("Journal comptable non trouvé avec l'ID: " + dto.getJournalId()));
ecriture.setJournal(journal); ecriture.setJournal(journal);
@@ -402,7 +402,7 @@ public class ComptabiliteService {
if (dto.getPaiementId() != null) { if (dto.getPaiementId() != null) {
Paiement paiement = Paiement paiement =
paiementRepository paiementRepository
.findByIdOptional(dto.getPaiementId()) .findPaiementById(dto.getPaiementId())
.orElseThrow( .orElseThrow(
() -> new NotFoundException("Paiement non trouvé avec l'ID: " + dto.getPaiementId())); () -> new NotFoundException("Paiement non trouvé avec l'ID: " + dto.getPaiementId()));
ecriture.setPaiement(paiement); ecriture.setPaiement(paiement);
@@ -465,7 +465,7 @@ public class ComptabiliteService {
if (dto.getCompteComptableId() != null) { if (dto.getCompteComptableId() != null) {
CompteComptable compte = CompteComptable compte =
compteComptableRepository compteComptableRepository
.findByIdOptional(dto.getCompteComptableId()) .findCompteComptableById(dto.getCompteComptableId())
.orElseThrow( .orElseThrow(
() -> () ->
new NotFoundException( new NotFoundException(

View File

@@ -72,7 +72,7 @@ public class DocumentService {
*/ */
public DocumentDTO trouverParId(UUID id) { public DocumentDTO trouverParId(UUID id) {
return documentRepository return documentRepository
.findByIdOptional(id) .findDocumentById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Document non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Document non trouvé avec l'ID: " + id));
} }
@@ -86,7 +86,7 @@ public class DocumentService {
public void enregistrerTelechargement(UUID id) { public void enregistrerTelechargement(UUID id) {
Document document = Document document =
documentRepository documentRepository
.findByIdOptional(id) .findDocumentById(id)
.orElseThrow(() -> new NotFoundException("Document non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Document non trouvé avec l'ID: " + id));
document.setNombreTelechargements( document.setNombreTelechargements(
@@ -240,7 +240,7 @@ public class DocumentService {
if (dto.getDocumentId() != null) { if (dto.getDocumentId() != null) {
Document document = Document document =
documentRepository documentRepository
.findByIdOptional(dto.getDocumentId()) .findDocumentById(dto.getDocumentId())
.orElseThrow(() -> new NotFoundException("Document non trouvé avec l'ID: " + dto.getDocumentId())); .orElseThrow(() -> new NotFoundException("Document non trouvé avec l'ID: " + dto.getDocumentId()));
pieceJointe.setDocument(document); pieceJointe.setDocument(document);
} }
@@ -297,7 +297,7 @@ public class DocumentService {
if (dto.getTransactionWaveId() != null) { if (dto.getTransactionWaveId() != null) {
TransactionWave transactionWave = TransactionWave transactionWave =
transactionWaveRepository transactionWaveRepository
.findByIdOptional(dto.getTransactionWaveId()) .findTransactionWaveById(dto.getTransactionWaveId())
.orElseThrow( .orElseThrow(
() -> () ->
new NotFoundException( new NotFoundException(

View File

@@ -94,7 +94,7 @@ public class NotificationService {
Notification notification = Notification notification =
notificationRepository notificationRepository
.findByIdOptional(id) .findNotificationById(id)
.orElseThrow(() -> new NotFoundException("Notification non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Notification non trouvée avec l'ID: " + id));
notification.setStatut(StatutNotification.LUE); notification.setStatut(StatutNotification.LUE);
@@ -115,7 +115,7 @@ public class NotificationService {
*/ */
public NotificationDTO trouverNotificationParId(UUID id) { public NotificationDTO trouverNotificationParId(UUID id) {
return notificationRepository return notificationRepository
.findByIdOptional(id) .findNotificationById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Notification non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Notification non trouvée avec l'ID: " + id));
} }
@@ -284,7 +284,7 @@ public class NotificationService {
if (dto.getTemplateId() != null) { if (dto.getTemplateId() != null) {
TemplateNotification template = TemplateNotification template =
templateNotificationRepository templateNotificationRepository
.findByIdOptional(dto.getTemplateId()) .findTemplateNotificationById(dto.getTemplateId())
.orElseThrow( .orElseThrow(
() -> () ->
new NotFoundException( new NotFoundException(

View File

@@ -68,7 +68,7 @@ public class PaiementService {
Paiement paiement = Paiement paiement =
paiementRepository paiementRepository
.findByIdOptional(id) .findPaiementById(id)
.orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id));
if (!paiement.peutEtreModifie()) { if (!paiement.peutEtreModifie()) {
@@ -96,7 +96,7 @@ public class PaiementService {
Paiement paiement = Paiement paiement =
paiementRepository paiementRepository
.findByIdOptional(id) .findPaiementById(id)
.orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id));
if (paiement.isValide()) { if (paiement.isValide()) {
@@ -127,7 +127,7 @@ public class PaiementService {
Paiement paiement = Paiement paiement =
paiementRepository paiementRepository
.findByIdOptional(id) .findPaiementById(id)
.orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id));
if (!paiement.peutEtreModifie()) { if (!paiement.peutEtreModifie()) {
@@ -151,7 +151,7 @@ public class PaiementService {
*/ */
public PaiementDTO trouverParId(UUID id) { public PaiementDTO trouverParId(UUID id) {
return paiementRepository return paiementRepository
.findByIdOptional(id) .findPaiementById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Paiement non trouvé avec l'ID: " + id));
} }

View File

@@ -74,7 +74,7 @@ public class PermissionService {
Permission permission = Permission permission =
permissionRepository permissionRepository
.findByIdOptional(id) .findPermissionById(id)
.orElseThrow(() -> new NotFoundException("Permission non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Permission non trouvée avec l'ID: " + id));
// Mise à jour // Mise à jour
@@ -99,7 +99,7 @@ public class PermissionService {
* @return Permission ou null * @return Permission ou null
*/ */
public Permission trouverParId(UUID id) { public Permission trouverParId(UUID id) {
return permissionRepository.findByIdOptional(id).orElse(null); return permissionRepository.findPermissionById(id).orElse(null);
} }
/** /**
@@ -152,7 +152,7 @@ public class PermissionService {
Permission permission = Permission permission =
permissionRepository permissionRepository
.findByIdOptional(id) .findPermissionById(id)
.orElseThrow(() -> new NotFoundException("Permission non trouvée avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Permission non trouvée avec l'ID: " + id));
permission.setActif(false); permission.setActif(false);

View File

@@ -69,7 +69,7 @@ public class RoleService {
Role role = Role role =
roleRepository roleRepository
.findByIdOptional(id) .findRoleById(id)
.orElseThrow(() -> new NotFoundException("Rôle non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Rôle non trouvé avec l'ID: " + id));
// Vérifier l'unicité du code si modifié // Vérifier l'unicité du code si modifié
@@ -101,7 +101,7 @@ public class RoleService {
* @return Rôle ou null * @return Rôle ou null
*/ */
public Role trouverParId(UUID id) { public Role trouverParId(UUID id) {
return roleRepository.findByIdOptional(id).orElse(null); return roleRepository.findRoleById(id).orElse(null);
} }
/** /**
@@ -153,7 +153,7 @@ public class RoleService {
Role role = Role role =
roleRepository roleRepository
.findByIdOptional(id) .findRoleById(id)
.orElseThrow(() -> new NotFoundException("Rôle non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Rôle non trouvé avec l'ID: " + id));
// Vérifier si c'est un rôle système // Vérifier si c'est un rôle système

View File

@@ -85,7 +85,7 @@ public class WaveService {
CompteWave compteWave = CompteWave compteWave =
compteWaveRepository compteWaveRepository
.findByIdOptional(id) .findCompteWaveById(id)
.orElseThrow(() -> new NotFoundException("Compte Wave non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Compte Wave non trouvé avec l'ID: " + id));
updateFromDTO(compteWave, compteWaveDTO); updateFromDTO(compteWave, compteWaveDTO);
@@ -109,7 +109,7 @@ public class WaveService {
CompteWave compteWave = CompteWave compteWave =
compteWaveRepository compteWaveRepository
.findByIdOptional(id) .findCompteWaveById(id)
.orElseThrow(() -> new NotFoundException("Compte Wave non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Compte Wave non trouvé avec l'ID: " + id));
compteWave.setStatutCompte(StatutCompteWave.VERIFIE); compteWave.setStatutCompte(StatutCompteWave.VERIFIE);
@@ -130,7 +130,7 @@ public class WaveService {
*/ */
public CompteWaveDTO trouverCompteWaveParId(UUID id) { public CompteWaveDTO trouverCompteWaveParId(UUID id) {
return compteWaveRepository return compteWaveRepository
.findByIdOptional(id) .findCompteWaveById(id)
.map(this::convertToDTO) .map(this::convertToDTO)
.orElseThrow(() -> new NotFoundException("Compte Wave non trouvé avec l'ID: " + id)); .orElseThrow(() -> new NotFoundException("Compte Wave non trouvé avec l'ID: " + id));
} }
@@ -380,7 +380,7 @@ public class WaveService {
if (dto.getCompteWaveId() != null) { if (dto.getCompteWaveId() != null) {
CompteWave compteWave = CompteWave compteWave =
compteWaveRepository compteWaveRepository
.findByIdOptional(dto.getCompteWaveId()) .findCompteWaveById(dto.getCompteWaveId())
.orElseThrow( .orElseThrow(
() -> () ->
new NotFoundException( new NotFoundException(

View File

@@ -30,6 +30,8 @@ quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.log.sql=false quarkus.hibernate-orm.log.sql=false
quarkus.hibernate-orm.jdbc.timezone=UTC quarkus.hibernate-orm.jdbc.timezone=UTC
quarkus.hibernate-orm.packages=dev.lions.unionflow.server.entity quarkus.hibernate-orm.packages=dev.lions.unionflow.server.entity
# Désactiver l'avertissement PanacheEntity (nous utilisons BaseEntity personnalisé)
quarkus.hibernate-orm.metrics.enabled=false
# Configuration Hibernate pour développement # Configuration Hibernate pour développement
%dev.quarkus.hibernate-orm.database.generation=drop-and-create %dev.quarkus.hibernate-orm.database.generation=drop-and-create

View File

@@ -88,11 +88,12 @@ class MembreServiceAdvancedSearchTest {
.telephone(telephone) .telephone(telephone)
.dateNaissance(dateNaissance) .dateNaissance(dateNaissance)
.dateAdhesion(dateAdhesion) .dateAdhesion(dateAdhesion)
.roles(roles)
.organisation(testOrganisation) .organisation(testOrganisation)
.build(); .build();
membre.setDateCreation(LocalDateTime.now()); membre.setDateCreation(LocalDateTime.now());
membre.setActif(actif); membre.setActif(actif);
// Note: Le champ roles est maintenant List<MembreRole> et doit être géré via la relation MembreRole
// Pour les tests, on laisse la liste vide par défaut
return membre; return membre;
} }