diff --git a/pom.xml b/pom.xml
index 73aa689..4640511 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,14 @@
microprofile-openapi-api
+
+
+ io.quarkus
+ quarkus-core
+ provided
+ true
+
+
org.junit.jupiter
@@ -60,6 +68,21 @@
org.apache.maven.plugins
maven-compiler-plugin
+
+
+
+ io.smallrye
+ jandex-maven-plugin
+ 3.1.0
+
+
+ make-index
+
+ jandex
+
+
+
+
diff --git a/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java b/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java
new file mode 100644
index 0000000..1ec3c49
--- /dev/null
+++ b/src/main/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTO.java
@@ -0,0 +1,119 @@
+package dev.lions.user.manager.dto.realm;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import dev.lions.user.manager.dto.base.BaseDTO;
+import jakarta.validation.constraints.NotBlank;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+import java.time.LocalDateTime;
+
+/**
+ * DTO pour assigner ou révoquer l'accès d'un utilisateur à un realm
+ * Permet de gérer les permissions multi-tenant
+ */
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Schema(description = "Attribution ou révocation d'accès à un realm")
+@RegisterForReflection
+public class RealmAssignmentDTO extends BaseDTO {
+
+ private static final long serialVersionUID = 1L;
+
+ @NotBlank(message = "L'ID utilisateur est obligatoire")
+ @Schema(description = "ID de l'utilisateur Keycloak", example = "f47ac10b-58cc-4372-a567-0e02b2c3d479", required = true)
+ private String userId;
+
+ @Schema(description = "Username de l'utilisateur", example = "jdupont")
+ private String username;
+
+ @Schema(description = "Email de l'utilisateur", example = "jdupont@example.com")
+ private String email;
+
+ @NotBlank(message = "Le nom du realm est obligatoire")
+ @Schema(description = "Nom du realm assigné", example = "btpxpress", required = true)
+ private String realmName;
+
+ @Schema(description = "Indique si l'utilisateur est super admin (peut gérer tous les realms)", example = "false")
+ private Boolean isSuperAdmin;
+
+ @Schema(description = "Date d'assignation", example = "2025-01-15T10:30:00")
+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
+ private LocalDateTime assignedAt;
+
+ @Schema(description = "Username de l'administrateur qui a fait l'assignation", example = "admin@lions.dev")
+ private String assignedBy;
+
+ @Schema(description = "Raison de l'assignation", example = "Nouveau gestionnaire du realm client")
+ private String raison;
+
+ @Schema(description = "Commentaires administratifs", example = "Accès temporaire pour support")
+ private String commentaires;
+
+ @Schema(description = "Indique si c'est une assignation temporaire", example = "false")
+ private Boolean temporaire;
+
+ @Schema(description = "Date d'expiration de l'assignation temporaire", example = "2025-12-31T23:59:59")
+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
+ private LocalDateTime dateExpiration;
+
+ @Schema(description = "Indique si l'assignation est active", example = "true")
+ private Boolean active;
+
+ /**
+ * Vérifie si l'assignation est temporaire
+ * @return true si temporaire
+ */
+ public boolean isTemporaire() {
+ return Boolean.TRUE.equals(temporaire);
+ }
+
+ /**
+ * Vérifie si l'assignation est active
+ * @return true si active
+ */
+ public boolean isActive() {
+ return Boolean.TRUE.equals(active);
+ }
+
+ /**
+ * Vérifie si l'assignation a expiré
+ * @return true si expirée
+ */
+ public boolean isExpired() {
+ if (!isTemporaire() || dateExpiration == null) {
+ return false;
+ }
+ return LocalDateTime.now().isAfter(dateExpiration);
+ }
+
+ /**
+ * Vérifie si l'utilisateur est super admin
+ * @return true si super admin
+ */
+ public boolean isSuperAdmin() {
+ return Boolean.TRUE.equals(isSuperAdmin);
+ }
+
+ /**
+ * Retourne un résumé de l'assignation
+ * @return résumé
+ */
+ public String getSummary() {
+ return String.format("Realm '%s' assigné à %s%s",
+ realmName,
+ username != null ? username : userId,
+ isTemporaire() ? " (temporaire)" : ""
+ );
+ }
+}
diff --git a/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java b/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java
index 90e1958..31bf580 100644
--- a/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java
+++ b/src/main/java/dev/lions/user/manager/dto/role/RoleDTO.java
@@ -12,6 +12,7 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import io.quarkus.runtime.annotations.RegisterForReflection;
import java.util.List;
import java.util.Map;
@@ -27,6 +28,7 @@ import java.util.Map;
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Rôle Keycloak (Realm ou Client)")
+@RegisterForReflection
public class RoleDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java b/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java
index 544fc34..520b01a 100644
--- a/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java
+++ b/src/main/java/dev/lions/user/manager/dto/user/UserDTO.java
@@ -14,6 +14,7 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.LocalDateTime;
import java.util.List;
@@ -30,6 +31,7 @@ import java.util.Map;
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Utilisateur Keycloak")
+@RegisterForReflection
public class UserDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java b/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java
index 150681b..d96661e 100644
--- a/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java
+++ b/src/main/java/dev/lions/user/manager/dto/user/UserSearchResultDTO.java
@@ -6,6 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import io.quarkus.runtime.annotations.RegisterForReflection;
import java.io.Serializable;
import java.util.List;
@@ -20,6 +21,7 @@ import java.util.List;
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Résultat paginé de recherche d'utilisateurs")
+@RegisterForReflection
public class UserSearchResultDTO implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java b/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java
index add7505..08c21df 100644
--- a/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java
+++ b/src/main/java/dev/lions/user/manager/enums/audit/TypeActionAudit.java
@@ -45,6 +45,11 @@ public enum TypeActionAudit {
REALM_SYNC("Synchronisation realm", "REALM", "SYNC"),
REALM_EXPORT("Export realm", "REALM", "EXPORT"),
REALM_IMPORT("Import realm", "REALM", "IMPORT"),
+ REALM_ASSIGN("Assignation realm", "REALM", "ASSIGN"),
+ REALM_REVOKE("Révocation realm", "REALM", "REVOKE"),
+ REALM_ACTIVATE("Activation assignation realm", "REALM", "ACTIVATE"),
+ REALM_DEACTIVATE("Désactivation assignation realm", "REALM", "DEACTIVATE"),
+ REALM_SET_SUPER_ADMIN("Définition super admin", "REALM", "SET_SUPER_ADMIN"),
// Actions Session
SESSION_CREATE("Création session", "SESSION", "CREATE"),
diff --git a/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java b/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java
new file mode 100644
index 0000000..527ad63
--- /dev/null
+++ b/src/main/java/dev/lions/user/manager/service/RealmAuthorizationService.java
@@ -0,0 +1,132 @@
+package dev.lions.user.manager.service;
+
+import dev.lions.user.manager.dto.realm.RealmAssignmentDTO;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Service de gestion des autorisations multi-tenant par realm
+ * Permet de contrôler quels utilisateurs peuvent administrer quels realms
+ */
+public interface RealmAuthorizationService {
+
+ /**
+ * Récupère toutes les assignations de realms
+ * @return liste de toutes les assignations
+ */
+ List getAllAssignments();
+
+ /**
+ * Récupère les assignations pour un utilisateur spécifique
+ * @param userId ID de l'utilisateur Keycloak
+ * @return liste des realms assignés à cet utilisateur
+ */
+ List getAssignmentsByUser(@NotBlank String userId);
+
+ /**
+ * Récupère les assignations pour un realm spécifique
+ * @param realmName nom du realm
+ * @return liste des utilisateurs ayant accès à ce realm
+ */
+ List getAssignmentsByRealm(@NotBlank String realmName);
+
+ /**
+ * Récupère une assignation spécifique
+ * @param assignmentId ID de l'assignation
+ * @return assignation ou Optional vide
+ */
+ Optional getAssignmentById(@NotBlank String assignmentId);
+
+ /**
+ * Vérifie si un utilisateur peut administrer un realm donné
+ * @param userId ID de l'utilisateur
+ * @param realmName nom du realm
+ * @return true si l'utilisateur peut administrer ce realm
+ */
+ boolean canManageRealm(@NotBlank String userId, @NotBlank String realmName);
+
+ /**
+ * Vérifie si un utilisateur est super admin (peut tout gérer)
+ * @param userId ID de l'utilisateur
+ * @return true si super admin
+ */
+ boolean isSuperAdmin(@NotBlank String userId);
+
+ /**
+ * Récupère la liste des realms qu'un utilisateur peut administrer
+ * @param userId ID de l'utilisateur
+ * @return liste des noms de realms, ou liste vide si super admin (peut tout gérer)
+ */
+ List getAuthorizedRealms(@NotBlank String userId);
+
+ /**
+ * Assigne un realm à un utilisateur
+ * @param assignment données de l'assignation
+ * @return assignation créée
+ */
+ RealmAssignmentDTO assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment);
+
+ /**
+ * Retire l'accès d'un utilisateur à un realm
+ * @param userId ID de l'utilisateur
+ * @param realmName nom du realm
+ */
+ void revokeRealmFromUser(@NotBlank String userId, @NotBlank String realmName);
+
+ /**
+ * Retire toutes les assignations d'un utilisateur
+ * @param userId ID de l'utilisateur
+ */
+ void revokeAllRealmsFromUser(@NotBlank String userId);
+
+ /**
+ * Retire toutes les assignations pour un realm
+ * @param realmName nom du realm
+ */
+ void revokeAllUsersFromRealm(@NotBlank String realmName);
+
+ /**
+ * Définit un utilisateur comme super admin
+ * @param userId ID de l'utilisateur
+ * @param superAdmin true pour définir comme super admin, false pour retirer
+ */
+ void setSuperAdmin(@NotBlank String userId, boolean superAdmin);
+
+ /**
+ * Désactive une assignation (sans la supprimer)
+ * @param assignmentId ID de l'assignation
+ */
+ void deactivateAssignment(@NotBlank String assignmentId);
+
+ /**
+ * Réactive une assignation
+ * @param assignmentId ID de l'assignation
+ */
+ void activateAssignment(@NotBlank String assignmentId);
+
+ /**
+ * Compte le nombre d'assignations pour un utilisateur
+ * @param userId ID de l'utilisateur
+ * @return nombre d'assignations actives
+ */
+ long countAssignmentsByUser(@NotBlank String userId);
+
+ /**
+ * Compte le nombre d'utilisateurs ayant accès à un realm
+ * @param realmName nom du realm
+ * @return nombre d'utilisateurs
+ */
+ long countUsersByRealm(@NotBlank String realmName);
+
+ /**
+ * Vérifie si une assignation existe
+ * @param userId ID de l'utilisateur
+ * @param realmName nom du realm
+ * @return true si l'assignation existe
+ */
+ boolean assignmentExists(@NotBlank String userId, @NotBlank String realmName);
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java b/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java
new file mode 100644
index 0000000..ee4f990
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/audit/AuditLogDTOTest.java
@@ -0,0 +1,119 @@
+package dev.lions.user.manager.dto.audit;
+
+import dev.lions.user.manager.enums.audit.TypeActionAudit;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour AuditLogDTO
+ */
+class AuditLogDTOTest {
+
+ @Test
+ void testBuilder() {
+ LocalDateTime now = LocalDateTime.now();
+ AuditLogDTO log = AuditLogDTO.builder()
+ .id("log-123")
+ .typeAction(TypeActionAudit.USER_CREATE)
+ .acteurUsername("admin")
+ .acteurUserId("admin-123")
+ .ressourceType("USER")
+ .ressourceId("user-123")
+ .ressourceName("testuser")
+ .realmName("test-realm")
+ .success(true)
+ .description("User created")
+ .dateAction(now)
+ .ipAddress("192.168.1.1")
+ .build();
+
+ assertNotNull(log);
+ assertEquals("log-123", log.getId());
+ assertEquals(TypeActionAudit.USER_CREATE, log.getTypeAction());
+ assertEquals("admin", log.getActeurUsername());
+ assertEquals("admin-123", log.getActeurUserId());
+ assertEquals("USER", log.getRessourceType());
+ assertEquals("user-123", log.getRessourceId());
+ assertEquals("testuser", log.getRessourceName());
+ assertEquals("test-realm", log.getRealmName());
+ assertTrue(log.isSuccessful());
+ assertEquals("User created", log.getDescription());
+ assertEquals(now, log.getDateAction());
+ assertEquals("192.168.1.1", log.getIpAddress());
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ AuditLogDTO log = new AuditLogDTO();
+
+ assertNotNull(log);
+ assertNull(log.getId());
+ assertNull(log.getTypeAction());
+ assertNull(log.getActeurUsername());
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ AuditLogDTO log = new AuditLogDTO();
+ LocalDateTime now = LocalDateTime.now();
+
+ log.setId("log-456");
+ log.setTypeAction(TypeActionAudit.USER_UPDATE);
+ log.setActeurUsername("user1");
+ log.setActeurUserId("user1-123");
+ log.setRessourceType("USER");
+ log.setRessourceId("user-456");
+ log.setRessourceName("user2");
+ log.setRealmName("realm2");
+ log.setSuccess(false);
+ log.setDescription("Update failed");
+ log.setDateAction(now);
+ log.setIpAddress("10.0.0.1");
+
+ assertEquals("log-456", log.getId());
+ assertEquals(TypeActionAudit.USER_UPDATE, log.getTypeAction());
+ assertEquals("user1", log.getActeurUsername());
+ assertEquals("user1-123", log.getActeurUserId());
+ assertEquals("USER", log.getRessourceType());
+ assertEquals("user-456", log.getRessourceId());
+ assertEquals("user2", log.getRessourceName());
+ assertEquals("realm2", log.getRealmName());
+ assertFalse(log.isSuccessful());
+ assertEquals("Update failed", log.getDescription());
+ assertEquals(now, log.getDateAction());
+ assertEquals("10.0.0.1", log.getIpAddress());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ LocalDateTime now = LocalDateTime.now();
+ AuditLogDTO log1 = AuditLogDTO.builder()
+ .id("log-123")
+ .typeAction(TypeActionAudit.USER_CREATE)
+ .dateAction(now)
+ .build();
+
+ AuditLogDTO log2 = AuditLogDTO.builder()
+ .id("log-123")
+ .typeAction(TypeActionAudit.USER_CREATE)
+ .dateAction(now)
+ .build();
+
+ assertEquals(log1, log2);
+ assertEquals(log1.hashCode(), log2.hashCode());
+ }
+
+ @Test
+ void testToString() {
+ AuditLogDTO log = AuditLogDTO.builder()
+ .id("log-123")
+ .typeAction(TypeActionAudit.USER_CREATE)
+ .build();
+
+ String toString = log.toString();
+ assertNotNull(toString);
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java b/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java
new file mode 100644
index 0000000..c8c1997
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/base/BaseDTOTest.java
@@ -0,0 +1,134 @@
+package dev.lions.user.manager.dto.base;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class BaseDTOTest {
+
+ // Concrete implementation for testing abstract class
+ static class TestDTO extends BaseDTO {
+ private static final long serialVersionUID = 1L;
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ TestDTO dto = new TestDTO();
+ LocalDateTime now = LocalDateTime.now();
+
+ dto.setId("uuid-123");
+ dto.setDateCreation(now);
+ dto.setDateModification(now);
+ dto.setCreeParUsername("admin");
+ dto.setModifieParUsername("superadmin");
+ dto.setVersion(1L);
+
+ assertEquals("uuid-123", dto.getId());
+ assertEquals(now, dto.getDateCreation());
+ assertEquals(now, dto.getDateModification());
+ assertEquals("admin", dto.getCreeParUsername());
+ assertEquals("superadmin", dto.getModifieParUsername());
+ assertEquals(1L, dto.getVersion());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ TestDTO dto1 = new TestDTO();
+ dto1.setId("uuid-123");
+ dto1.setVersion(1L);
+
+ TestDTO dto2 = new TestDTO();
+ dto2.setId("uuid-123");
+ dto2.setVersion(1L);
+
+ TestDTO dto3 = new TestDTO();
+ dto3.setId("uuid-456");
+ dto3.setVersion(2L);
+
+ assertEquals(dto1, dto2);
+ assertEquals(dto1.hashCode(), dto2.hashCode());
+ assertNotEquals(dto1, dto3);
+ }
+
+ @Test
+ void testToString() {
+ TestDTO dto = new TestDTO();
+ dto.setId("uuid-123");
+ dto.setCreeParUsername("admin");
+
+ String str = dto.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("uuid-123"));
+ assertTrue(str.contains("admin"));
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ TestDTO dto = new TestDTO();
+ assertNull(dto.getId());
+ assertNull(dto.getDateCreation());
+ assertNull(dto.getDateModification());
+ assertNull(dto.getCreeParUsername());
+ assertNull(dto.getModifieParUsername());
+ assertNull(dto.getVersion());
+ }
+
+ @Test
+ void testAllFields() {
+ LocalDateTime creationTime = LocalDateTime.of(2025, 1, 15, 10, 30);
+ LocalDateTime modificationTime = LocalDateTime.of(2025, 1, 15, 14, 20);
+
+ TestDTO dto = new TestDTO();
+ dto.setId("f47ac10b-58cc-4372-a567-0e02b2c3d479");
+ dto.setDateCreation(creationTime);
+ dto.setDateModification(modificationTime);
+ dto.setCreeParUsername("admin@lions.dev");
+ dto.setModifieParUsername("superadmin@lions.dev");
+ dto.setVersion(5L);
+
+ assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", dto.getId());
+ assertEquals(creationTime, dto.getDateCreation());
+ assertEquals(modificationTime, dto.getDateModification());
+ assertEquals("admin@lions.dev", dto.getCreeParUsername());
+ assertEquals("superadmin@lions.dev", dto.getModifieParUsername());
+ assertEquals(5L, dto.getVersion());
+ }
+
+ @Test
+ void testEqualsWithNull() {
+ TestDTO dto = new TestDTO();
+ dto.setId("uuid-123");
+
+ assertNotEquals(null, dto);
+ }
+
+ @Test
+ void testEqualsWithDifferentClass() {
+ TestDTO dto = new TestDTO();
+ dto.setId("uuid-123");
+
+ assertNotEquals("string", dto);
+ }
+
+ @Test
+ void testEqualsSameObject() {
+ TestDTO dto = new TestDTO();
+ dto.setId("uuid-123");
+
+ assertEquals(dto, dto);
+ }
+
+ @Test
+ void testHashCodeConsistency() {
+ TestDTO dto = new TestDTO();
+ dto.setId("uuid-123");
+ dto.setVersion(1L);
+
+ int hash1 = dto.hashCode();
+ int hash2 = dto.hashCode();
+
+ assertEquals(hash1, hash2);
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java b/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java
new file mode 100644
index 0000000..d085f72
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/realm/RealmAssignmentDTOTest.java
@@ -0,0 +1,184 @@
+package dev.lions.user.manager.dto.realm;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour RealmAssignmentDTO
+ */
+class RealmAssignmentDTOTest {
+
+ @Test
+ void testBuilder() {
+ LocalDateTime now = LocalDateTime.now();
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .id("assignment-1")
+ .userId("user-1")
+ .username("testuser")
+ .email("test@example.com")
+ .realmName("realm1")
+ .isSuperAdmin(false)
+ .active(true)
+ .temporaire(false)
+ .assignedAt(now)
+ .assignedBy("admin")
+ .raison("Test assignment")
+ .commentaires("Test comments")
+ .dateCreation(now)
+ .dateModification(now)
+ .dateExpiration(now.plusDays(30))
+ .build();
+
+ assertEquals("assignment-1", dto.getId());
+ assertEquals("user-1", dto.getUserId());
+ assertEquals("testuser", dto.getUsername());
+ assertEquals("test@example.com", dto.getEmail());
+ assertEquals("realm1", dto.getRealmName());
+ assertFalse(dto.isSuperAdmin());
+ assertTrue(dto.isActive());
+ assertFalse(dto.getTemporaire());
+ assertEquals(now, dto.getAssignedAt());
+ assertEquals("admin", dto.getAssignedBy());
+ assertEquals("Test assignment", dto.getRaison());
+ assertEquals("Test comments", dto.getCommentaires());
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ RealmAssignmentDTO dto = new RealmAssignmentDTO();
+ assertNotNull(dto);
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ RealmAssignmentDTO dto = new RealmAssignmentDTO();
+ LocalDateTime now = LocalDateTime.now();
+
+ dto.setId("assignment-1");
+ dto.setUserId("user-1");
+ dto.setUsername("testuser");
+ dto.setEmail("test@example.com");
+ dto.setRealmName("realm1");
+ dto.setIsSuperAdmin(true);
+ dto.setActive(true);
+ dto.setTemporaire(false);
+ dto.setAssignedAt(now);
+ dto.setAssignedBy("admin");
+ dto.setRaison("Test");
+ dto.setCommentaires("Comments");
+ dto.setDateCreation(now);
+ dto.setDateModification(now);
+ dto.setDateExpiration(now.plusDays(30));
+
+ assertEquals("assignment-1", dto.getId());
+ assertEquals("user-1", dto.getUserId());
+ assertEquals("testuser", dto.getUsername());
+ assertEquals("test@example.com", dto.getEmail());
+ assertEquals("realm1", dto.getRealmName());
+ assertTrue(dto.isSuperAdmin());
+ assertTrue(dto.isActive());
+ assertFalse(dto.getTemporaire());
+ assertEquals(now, dto.getAssignedAt());
+ assertEquals("admin", dto.getAssignedBy());
+ }
+
+ @Test
+ void testIsExpired_NotExpired() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne
+ .dateExpiration(LocalDateTime.now().plusDays(1))
+ .build();
+
+ assertFalse(dto.isExpired());
+ }
+
+ @Test
+ void testIsExpired_Expired() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .temporaire(true) // Doit être temporaire pour que isExpired() fonctionne
+ .dateExpiration(LocalDateTime.now().minusDays(1))
+ .build();
+
+ assertTrue(dto.isExpired());
+ }
+
+ @Test
+ void testIsExpired_NoExpiration() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .temporaire(true)
+ .dateExpiration(null)
+ .build();
+
+ assertFalse(dto.isExpired());
+ }
+
+ @Test
+ void testIsExpired_NotTemporary() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .temporaire(false) // Si pas temporaire, isExpired() retourne false
+ .dateExpiration(LocalDateTime.now().minusDays(1))
+ .build();
+
+ assertFalse(dto.isExpired());
+ }
+
+ @Test
+ void testIsTemporaire() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .temporaire(true)
+ .build();
+
+ assertTrue(dto.isTemporaire());
+ }
+
+ @Test
+ void testIsActive() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .active(true)
+ .build();
+
+ assertTrue(dto.isActive());
+ }
+
+ @Test
+ void testIsSuperAdmin() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .isSuperAdmin(true)
+ .build();
+
+ assertTrue(dto.isSuperAdmin());
+ }
+
+ @Test
+ void testGetSummary() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .realmName("test-realm")
+ .username("testuser")
+ .temporaire(true)
+ .build();
+
+ String summary = dto.getSummary();
+ assertNotNull(summary);
+ assertTrue(summary.contains("test-realm"));
+ assertTrue(summary.contains("testuser"));
+ assertTrue(summary.contains("temporaire"));
+ }
+
+ @Test
+ void testGetSummary_WithUserId() {
+ RealmAssignmentDTO dto = RealmAssignmentDTO.builder()
+ .realmName("test-realm")
+ .userId("user-123")
+ .temporaire(false)
+ .build();
+
+ String summary = dto.getSummary();
+ assertNotNull(summary);
+ assertTrue(summary.contains("test-realm"));
+ assertTrue(summary.contains("user-123"));
+ }
+}
+
diff --git a/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java b/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java
new file mode 100644
index 0000000..b016753
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/role/RoleAssignmentDTOTest.java
@@ -0,0 +1,147 @@
+package dev.lions.user.manager.dto.role;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour RoleAssignmentDTO
+ */
+class RoleAssignmentDTOTest {
+
+ @Test
+ void testBuilder() {
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .userId("user-123")
+ .realmName("test-realm")
+ .roleNames(Arrays.asList("admin", "user"))
+ .build();
+
+ assertNotNull(assignment);
+ assertEquals("user-123", assignment.getUserId());
+ assertEquals("test-realm", assignment.getRealmName());
+ assertEquals(2, assignment.getRoleNames().size());
+ assertTrue(assignment.getRoleNames().contains("admin"));
+ assertTrue(assignment.getRoleNames().contains("user"));
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ RoleAssignmentDTO assignment = new RoleAssignmentDTO();
+
+ assertNotNull(assignment);
+ assertNull(assignment.getUserId());
+ assertNull(assignment.getRealmName());
+ assertNull(assignment.getRoleNames());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ // Le constructeur AllArgsConstructor nécessite tous les champs
+ // On utilise plutôt le builder pour ce test
+ List roles = Arrays.asList("admin", "user");
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .userId("user-123")
+ .realmName("test-realm")
+ .roleNames(roles)
+ .build();
+
+ assertNotNull(assignment);
+ assertEquals("user-123", assignment.getUserId());
+ assertEquals("test-realm", assignment.getRealmName());
+ assertEquals(2, assignment.getRoleNames().size());
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ RoleAssignmentDTO assignment = new RoleAssignmentDTO();
+
+ assignment.setUserId("user-456");
+ assignment.setRealmName("realm2");
+ assignment.setRoleNames(Collections.singletonList("admin"));
+
+ assertEquals("user-456", assignment.getUserId());
+ assertEquals("realm2", assignment.getRealmName());
+ assertEquals(1, assignment.getRoleNames().size());
+ assertEquals("admin", assignment.getRoleNames().get(0));
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ RoleAssignmentDTO assignment1 = RoleAssignmentDTO.builder()
+ .userId("user-123")
+ .realmName("test-realm")
+ .roleNames(Arrays.asList("admin"))
+ .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE)
+ .build();
+
+ RoleAssignmentDTO assignment2 = RoleAssignmentDTO.builder()
+ .userId("user-123")
+ .realmName("test-realm")
+ .roleNames(Arrays.asList("admin"))
+ .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE)
+ .build();
+
+ assertEquals(assignment1, assignment2);
+ assertEquals(assignment1.hashCode(), assignment2.hashCode());
+ }
+
+ @Test
+ void testIsValidForClientRole() {
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .typeRole(dev.lions.user.manager.enums.role.TypeRole.CLIENT_ROLE)
+ .clientName("test-client")
+ .build();
+
+ assertTrue(assignment.isValidForClientRole());
+ }
+
+ @Test
+ void testIsValidForRealmRole() {
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .typeRole(dev.lions.user.manager.enums.role.TypeRole.REALM_ROLE)
+ .build();
+
+ assertTrue(assignment.isValidForRealmRole());
+ }
+
+ @Test
+ void testGetRoleCount() {
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .roleNames(Arrays.asList("admin", "user", "viewer"))
+ .build();
+
+ assertEquals(3, assignment.getRoleCount());
+ }
+
+ @Test
+ void testGetRoleCount_Empty() {
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .roleNames(Collections.emptyList())
+ .build();
+
+ assertEquals(0, assignment.getRoleCount());
+ }
+
+ @Test
+ void testGetRoleCount_Null() {
+ RoleAssignmentDTO assignment = new RoleAssignmentDTO();
+
+ assertEquals(0, assignment.getRoleCount());
+ }
+
+ @Test
+ void testToString() {
+ RoleAssignmentDTO assignment = RoleAssignmentDTO.builder()
+ .userId("user-123")
+ .realmName("test-realm")
+ .build();
+
+ String toString = assignment.toString();
+ assertNotNull(toString);
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java b/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java
new file mode 100644
index 0000000..482bcce
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/role/RoleDTOTest.java
@@ -0,0 +1,318 @@
+package dev.lions.user.manager.dto.role;
+
+import dev.lions.user.manager.enums.role.TypeRole;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class RoleDTOTest {
+
+ @Test
+ void testIsRealmRole_true() {
+ RoleDTO role = new RoleDTO();
+ role.setTypeRole(TypeRole.REALM_ROLE);
+ assertTrue(role.isRealmRole());
+ assertFalse(role.isClientRole());
+ }
+
+ @Test
+ void testIsRealmRole_false() {
+ RoleDTO role = new RoleDTO();
+ role.setTypeRole(TypeRole.CLIENT_ROLE);
+ assertFalse(role.isRealmRole());
+ }
+
+ @Test
+ void testIsRealmRole_null() {
+ RoleDTO role = new RoleDTO();
+ role.setTypeRole(null);
+ assertFalse(role.isRealmRole());
+ }
+
+ @Test
+ void testIsClientRole_true() {
+ RoleDTO role = new RoleDTO();
+ role.setTypeRole(TypeRole.CLIENT_ROLE);
+ assertTrue(role.isClientRole());
+ assertFalse(role.isRealmRole());
+ }
+
+ @Test
+ void testIsClientRole_false() {
+ RoleDTO role = new RoleDTO();
+ role.setTypeRole(TypeRole.REALM_ROLE);
+ assertFalse(role.isClientRole());
+ }
+
+ @Test
+ void testIsClientRole_null() {
+ RoleDTO role = new RoleDTO();
+ role.setTypeRole(null);
+ assertFalse(role.isClientRole());
+ }
+
+ @Test
+ void testIsComposite_withCompositeRoles() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(true);
+ role.setCompositeRoles(Arrays.asList("role1", "role2"));
+ assertTrue(role.isComposite());
+ }
+
+ @Test
+ void testIsComposite_withCompositeRealmRoles() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(true);
+ role.setCompositeRoles(null);
+ role.setCompositeRealmRoles(Collections.singletonList(new RoleDTO.RoleCompositeDTO()));
+ assertTrue(role.isComposite());
+ }
+
+ @Test
+ void testIsComposite_withCompositeClientRoles() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(true);
+ role.setCompositeRoles(null);
+ role.setCompositeRealmRoles(null);
+ Map> clientRoles = new HashMap<>();
+ clientRoles.put("client", Collections.singletonList(new RoleDTO.RoleCompositeDTO()));
+ role.setCompositeClientRoles(clientRoles);
+ assertTrue(role.isComposite());
+ }
+
+ @Test
+ void testIsComposite_falseWhenCompositeFalse() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(false);
+ role.setCompositeRoles(Arrays.asList("role1"));
+ assertFalse(role.isComposite());
+ }
+
+ @Test
+ void testIsComposite_falseWhenCompositeNull() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(null);
+ role.setCompositeRoles(Arrays.asList("role1"));
+ assertFalse(role.isComposite());
+ }
+
+ @Test
+ void testIsComposite_falseWhenNoRoles() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(true);
+ role.setCompositeRoles(null);
+ role.setCompositeRealmRoles(null);
+ role.setCompositeClientRoles(null);
+ assertFalse(role.isComposite());
+ }
+
+ @Test
+ void testIsComposite_falseWhenEmptyRoles() {
+ RoleDTO role = new RoleDTO();
+ role.setComposite(true);
+ role.setCompositeRoles(Collections.emptyList());
+ role.setCompositeRealmRoles(Collections.emptyList());
+ role.setCompositeClientRoles(Collections.emptyMap());
+ assertFalse(role.isComposite());
+ }
+
+ @Test
+ void testGetFullName_realmRole() {
+ RoleDTO role = new RoleDTO();
+ role.setName("admin");
+ role.setTypeRole(TypeRole.REALM_ROLE);
+ assertEquals("admin", role.getFullName());
+ }
+
+ @Test
+ void testGetFullName_clientRole() {
+ RoleDTO role = new RoleDTO();
+ role.setName("admin");
+ role.setTypeRole(TypeRole.CLIENT_ROLE);
+ role.setClientName("app");
+ assertEquals("app:admin", role.getFullName());
+ }
+
+ @Test
+ void testGetFullName_clientRoleNullClientName() {
+ RoleDTO role = new RoleDTO();
+ role.setName("admin");
+ role.setTypeRole(TypeRole.CLIENT_ROLE);
+ role.setClientName(null);
+ assertEquals("admin", role.getFullName());
+ }
+
+ @Test
+ void testGetFullName_nullTypeRole() {
+ RoleDTO role = new RoleDTO();
+ role.setName("admin");
+ role.setTypeRole(null);
+ assertEquals("admin", role.getFullName());
+ }
+
+ @Test
+ void testRoleCompositeDTO_builder() {
+ RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder()
+ .id("1")
+ .name("role")
+ .description("desc")
+ .typeRole(TypeRole.REALM_ROLE)
+ .clientName("client")
+ .build();
+
+ assertEquals("1", comp.getId());
+ assertEquals("role", comp.getName());
+ assertEquals("desc", comp.getDescription());
+ assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole());
+ assertEquals("client", comp.getClientName());
+ }
+
+ @Test
+ void testRoleCompositeDTO_settersGetters() {
+ RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO();
+ comp.setId("id");
+ comp.setName("name");
+ comp.setDescription("desc");
+ comp.setTypeRole(TypeRole.CLIENT_ROLE);
+ comp.setClientName("client");
+
+ assertEquals("id", comp.getId());
+ assertEquals("name", comp.getName());
+ assertEquals("desc", comp.getDescription());
+ assertEquals(TypeRole.CLIENT_ROLE, comp.getTypeRole());
+ assertEquals("client", comp.getClientName());
+ }
+
+ @Test
+ void testRoleCompositeDTO_allArgsConstructor() {
+ RoleDTO.RoleCompositeDTO comp = new RoleDTO.RoleCompositeDTO("id", "name", "desc", TypeRole.REALM_ROLE,
+ "client");
+ assertEquals("id", comp.getId());
+ assertEquals("name", comp.getName());
+ assertEquals("desc", comp.getDescription());
+ assertEquals(TypeRole.REALM_ROLE, comp.getTypeRole());
+ assertEquals("client", comp.getClientName());
+ }
+
+ @Test
+ void testRoleCompositeDTO_equalsAndHashCode() {
+ RoleDTO.RoleCompositeDTO comp1 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build();
+ RoleDTO.RoleCompositeDTO comp2 = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build();
+ RoleDTO.RoleCompositeDTO comp3 = RoleDTO.RoleCompositeDTO.builder().id("2").name("other").build();
+
+ assertEquals(comp1, comp2);
+ assertEquals(comp1.hashCode(), comp2.hashCode());
+ assertNotEquals(comp1, comp3);
+ }
+
+ @Test
+ void testRoleCompositeDTO_toString() {
+ RoleDTO.RoleCompositeDTO comp = RoleDTO.RoleCompositeDTO.builder().id("1").name("role").build();
+ String str = comp.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("role"));
+ }
+
+ @Test
+ void testBuilderAndAllFields() {
+ Map> attrs = new HashMap<>();
+ attrs.put("key", Collections.singletonList("value"));
+ Map> clientComposites = new HashMap<>();
+ clientComposites.put("client",
+ Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subclient").build()));
+
+ RoleDTO role = RoleDTO.builder()
+ .id("uuid-123")
+ .name("admin")
+ .description("Administrator role")
+ .typeRole(TypeRole.REALM_ROLE)
+ .composite(true)
+ .containerId("container")
+ .realmName("realm")
+ .clientName("client")
+ .clientId("clientId")
+ .compositeRoles(Arrays.asList("role1", "role2"))
+ .compositeRealmRoles(
+ Collections.singletonList(RoleDTO.RoleCompositeDTO.builder().name("subrealm").build()))
+ .compositeClientRoles(clientComposites)
+ .attributes(attrs)
+ .userCount(10)
+ .systemRole(false)
+ .deletable(true)
+ .build();
+
+ assertEquals("uuid-123", role.getId());
+ assertEquals("admin", role.getName());
+ assertEquals("Administrator role", role.getDescription());
+ assertEquals(TypeRole.REALM_ROLE, role.getTypeRole());
+ assertTrue(role.getComposite());
+ assertEquals("container", role.getContainerId());
+ assertEquals("realm", role.getRealmName());
+ assertEquals("client", role.getClientName());
+ assertEquals("clientId", role.getClientId());
+ assertEquals(2, role.getCompositeRoles().size());
+ assertEquals(1, role.getCompositeRealmRoles().size());
+ assertEquals(1, role.getCompositeClientRoles().size());
+ assertEquals(1, role.getAttributes().size());
+ assertEquals(10, role.getUserCount());
+ assertFalse(role.getSystemRole());
+ assertTrue(role.getDeletable());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ RoleDTO role1 = RoleDTO.builder().id("uuid-123").name("admin").build();
+ RoleDTO role2 = RoleDTO.builder().id("uuid-123").name("admin").build();
+ RoleDTO role3 = RoleDTO.builder().id("uuid-456").name("user").build();
+
+ assertEquals(role1, role2);
+ assertEquals(role1.hashCode(), role2.hashCode());
+ assertNotEquals(role1, role3);
+ }
+
+ @Test
+ void testToString() {
+ RoleDTO role = RoleDTO.builder().name("admin").description("Admin role").build();
+ String str = role.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("admin"));
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ RoleDTO role = new RoleDTO();
+ assertNull(role.getName());
+ assertNull(role.getDescription());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ Map> attrs = new HashMap<>();
+ Map> clientComposites = new HashMap<>();
+ List compositeRoles = Collections.emptyList();
+ List realmComposites = Collections.emptyList();
+
+ RoleDTO role = new RoleDTO(
+ "name", "desc", TypeRole.REALM_ROLE, true, "container", "realm",
+ "clientName", "clientId", compositeRoles, realmComposites, clientComposites,
+ attrs, 5, true, false);
+
+ assertEquals("name", role.getName());
+ assertEquals("desc", role.getDescription());
+ assertEquals(TypeRole.REALM_ROLE, role.getTypeRole());
+ assertTrue(role.getComposite());
+ assertEquals("container", role.getContainerId());
+ assertEquals("realm", role.getRealmName());
+ assertEquals("clientName", role.getClientName());
+ assertEquals("clientId", role.getClientId());
+ assertEquals(5, role.getUserCount());
+ assertTrue(role.getSystemRole());
+ assertFalse(role.getDeletable());
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java b/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java
new file mode 100644
index 0000000..c6bcaee
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/sync/HealthStatusDTOTest.java
@@ -0,0 +1,125 @@
+package dev.lions.user.manager.dto.sync;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class HealthStatusDTOTest {
+
+ @Test
+ void testBuilderAndAllFields() {
+ HealthStatusDTO dto = HealthStatusDTO.builder()
+ .timestamp(1699545600000L)
+ .keycloakAccessible(true)
+ .keycloakVersion("23.0.3")
+ .realmsAccessible(true)
+ .realmsCount(5)
+ .overallHealthy(true)
+ .errorMessage(null)
+ .build();
+
+ assertEquals(1699545600000L, dto.getTimestamp());
+ assertTrue(dto.isKeycloakAccessible());
+ assertEquals("23.0.3", dto.getKeycloakVersion());
+ assertTrue(dto.isRealmsAccessible());
+ assertEquals(5, dto.getRealmsCount());
+ assertTrue(dto.isOverallHealthy());
+ assertNull(dto.getErrorMessage());
+ }
+
+ @Test
+ void testBuilderWithError() {
+ HealthStatusDTO dto = HealthStatusDTO.builder()
+ .timestamp(System.currentTimeMillis())
+ .keycloakAccessible(false)
+ .realmsAccessible(false)
+ .overallHealthy(false)
+ .errorMessage("Connection refused")
+ .build();
+
+ assertFalse(dto.isKeycloakAccessible());
+ assertFalse(dto.isRealmsAccessible());
+ assertFalse(dto.isOverallHealthy());
+ assertEquals("Connection refused", dto.getErrorMessage());
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ HealthStatusDTO dto = new HealthStatusDTO();
+ dto.setTimestamp(12345L);
+ dto.setKeycloakAccessible(true);
+ dto.setKeycloakVersion("24.0.0");
+ dto.setRealmsAccessible(true);
+ dto.setRealmsCount(3);
+ dto.setOverallHealthy(true);
+ dto.setErrorMessage("warning");
+
+ assertEquals(12345L, dto.getTimestamp());
+ assertTrue(dto.isKeycloakAccessible());
+ assertEquals("24.0.0", dto.getKeycloakVersion());
+ assertTrue(dto.isRealmsAccessible());
+ assertEquals(3, dto.getRealmsCount());
+ assertTrue(dto.isOverallHealthy());
+ assertEquals("warning", dto.getErrorMessage());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ HealthStatusDTO dto1 = HealthStatusDTO.builder()
+ .timestamp(1000L)
+ .keycloakVersion("23.0.3")
+ .overallHealthy(true)
+ .build();
+ HealthStatusDTO dto2 = HealthStatusDTO.builder()
+ .timestamp(1000L)
+ .keycloakVersion("23.0.3")
+ .overallHealthy(true)
+ .build();
+ HealthStatusDTO dto3 = HealthStatusDTO.builder()
+ .timestamp(2000L)
+ .keycloakVersion("24.0.0")
+ .overallHealthy(false)
+ .build();
+
+ assertEquals(dto1, dto2);
+ assertEquals(dto1.hashCode(), dto2.hashCode());
+ assertNotEquals(dto1, dto3);
+ }
+
+ @Test
+ void testToString() {
+ HealthStatusDTO dto = HealthStatusDTO.builder()
+ .keycloakVersion("23.0.3")
+ .overallHealthy(true)
+ .build();
+ String str = dto.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("23.0.3"));
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ HealthStatusDTO dto = new HealthStatusDTO();
+ assertEquals(0L, dto.getTimestamp());
+ assertFalse(dto.isKeycloakAccessible());
+ assertNull(dto.getKeycloakVersion());
+ assertFalse(dto.isRealmsAccessible());
+ assertEquals(0, dto.getRealmsCount());
+ assertFalse(dto.isOverallHealthy());
+ assertNull(dto.getErrorMessage());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ HealthStatusDTO dto = new HealthStatusDTO(
+ 1000L, true, "23.0.3", true, 5, true, null);
+
+ assertEquals(1000L, dto.getTimestamp());
+ assertTrue(dto.isKeycloakAccessible());
+ assertEquals("23.0.3", dto.getKeycloakVersion());
+ assertTrue(dto.isRealmsAccessible());
+ assertEquals(5, dto.getRealmsCount());
+ assertTrue(dto.isOverallHealthy());
+ assertNull(dto.getErrorMessage());
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java b/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java
new file mode 100644
index 0000000..0be3a91
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/sync/SyncResultDTOTest.java
@@ -0,0 +1,127 @@
+package dev.lions.user.manager.dto.sync;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class SyncResultDTOTest {
+
+ @Test
+ void testGetDurationMs() {
+ SyncResultDTO dto = SyncResultDTO.builder()
+ .startTime(1000L)
+ .endTime(5000L)
+ .build();
+ assertEquals(4000L, dto.getDurationMs());
+ }
+
+ @Test
+ void testGetDurationMs_sameTime() {
+ SyncResultDTO dto = SyncResultDTO.builder()
+ .startTime(1000L)
+ .endTime(1000L)
+ .build();
+ assertEquals(0L, dto.getDurationMs());
+ }
+
+ @Test
+ void testBuilderAndAllFields() {
+ SyncResultDTO dto = SyncResultDTO.builder()
+ .realmName("btpxpress")
+ .usersCount(150)
+ .realmRolesCount(25)
+ .clientRolesCount(50)
+ .success(true)
+ .errorMessage(null)
+ .startTime(1699545600000L)
+ .endTime(1699545615000L)
+ .build();
+
+ assertEquals("btpxpress", dto.getRealmName());
+ assertEquals(150, dto.getUsersCount());
+ assertEquals(25, dto.getRealmRolesCount());
+ assertEquals(50, dto.getClientRolesCount());
+ assertTrue(dto.isSuccess());
+ assertNull(dto.getErrorMessage());
+ assertEquals(1699545600000L, dto.getStartTime());
+ assertEquals(1699545615000L, dto.getEndTime());
+ assertEquals(15000L, dto.getDurationMs());
+ }
+
+ @Test
+ void testBuilderWithError() {
+ SyncResultDTO dto = SyncResultDTO.builder()
+ .realmName("btpxpress")
+ .success(false)
+ .errorMessage("Connection failed")
+ .build();
+
+ assertEquals("btpxpress", dto.getRealmName());
+ assertFalse(dto.isSuccess());
+ assertEquals("Connection failed", dto.getErrorMessage());
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ SyncResultDTO dto = new SyncResultDTO();
+ dto.setRealmName("realm");
+ dto.setUsersCount(10);
+ dto.setRealmRolesCount(5);
+ dto.setClientRolesCount(3);
+ dto.setSuccess(true);
+ dto.setErrorMessage("error");
+ dto.setStartTime(100L);
+ dto.setEndTime(200L);
+
+ assertEquals("realm", dto.getRealmName());
+ assertEquals(10, dto.getUsersCount());
+ assertEquals(5, dto.getRealmRolesCount());
+ assertEquals(3, dto.getClientRolesCount());
+ assertTrue(dto.isSuccess());
+ assertEquals("error", dto.getErrorMessage());
+ assertEquals(100L, dto.getStartTime());
+ assertEquals(200L, dto.getEndTime());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ SyncResultDTO dto1 = SyncResultDTO.builder().realmName("realm").usersCount(10).build();
+ SyncResultDTO dto2 = SyncResultDTO.builder().realmName("realm").usersCount(10).build();
+ SyncResultDTO dto3 = SyncResultDTO.builder().realmName("other").usersCount(5).build();
+
+ assertEquals(dto1, dto2);
+ assertEquals(dto1.hashCode(), dto2.hashCode());
+ assertNotEquals(dto1, dto3);
+ }
+
+ @Test
+ void testToString() {
+ SyncResultDTO dto = SyncResultDTO.builder().realmName("realm").success(true).build();
+ String str = dto.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("realm"));
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ SyncResultDTO dto = new SyncResultDTO();
+ assertNull(dto.getRealmName());
+ assertEquals(0, dto.getUsersCount());
+ assertFalse(dto.isSuccess());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ SyncResultDTO dto = new SyncResultDTO(
+ "realm", 100, 20, 30, true, null, 1000L, 2000L);
+
+ assertEquals("realm", dto.getRealmName());
+ assertEquals(100, dto.getUsersCount());
+ assertEquals(20, dto.getRealmRolesCount());
+ assertEquals(30, dto.getClientRolesCount());
+ assertTrue(dto.isSuccess());
+ assertNull(dto.getErrorMessage());
+ assertEquals(1000L, dto.getStartTime());
+ assertEquals(2000L, dto.getEndTime());
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java b/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java
new file mode 100644
index 0000000..d421f21
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/user/UserDTOTest.java
@@ -0,0 +1,305 @@
+package dev.lions.user.manager.dto.user;
+
+import dev.lions.user.manager.enums.user.StatutUser;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class UserDTOTest {
+
+ @Test
+ void testGetNomComplet_withPrenomAndNom() {
+ UserDTO user = new UserDTO();
+ user.setPrenom("Jean");
+ user.setNom("Dupont");
+ user.setUsername("jdupont");
+ assertEquals("Jean Dupont", user.getNomComplet());
+ }
+
+ @Test
+ void testGetNomComplet_withNullPrenom() {
+ UserDTO user = new UserDTO();
+ user.setPrenom(null);
+ user.setNom("Dupont");
+ user.setUsername("jdupont");
+ assertEquals("jdupont", user.getNomComplet());
+ }
+
+ @Test
+ void testGetNomComplet_withNullNom() {
+ UserDTO user = new UserDTO();
+ user.setPrenom("Jean");
+ user.setNom(null);
+ user.setUsername("jdupont");
+ assertEquals("jdupont", user.getNomComplet());
+ }
+
+ @Test
+ void testGetNomComplet_withBothNull() {
+ UserDTO user = new UserDTO();
+ user.setPrenom(null);
+ user.setNom(null);
+ user.setUsername("jdupont");
+ assertEquals("jdupont", user.getNomComplet());
+ }
+
+ @Test
+ void testIsActif_true() {
+ UserDTO user = new UserDTO();
+ user.setStatut(StatutUser.ACTIF);
+ user.setEnabled(true);
+ assertTrue(user.isActif());
+ }
+
+ @Test
+ void testIsActif_falseWhenNotActif() {
+ UserDTO user = new UserDTO();
+ user.setStatut(StatutUser.INACTIF);
+ user.setEnabled(true);
+ assertFalse(user.isActif());
+ }
+
+ @Test
+ void testIsActif_falseWhenNotEnabled() {
+ UserDTO user = new UserDTO();
+ user.setStatut(StatutUser.ACTIF);
+ user.setEnabled(false);
+ assertFalse(user.isActif());
+ }
+
+ @Test
+ void testIsActif_falseWhenEnabledNull() {
+ UserDTO user = new UserDTO();
+ user.setStatut(StatutUser.ACTIF);
+ user.setEnabled(null);
+ assertFalse(user.isActif());
+ }
+
+ @Test
+ void testIsExpire_true() {
+ UserDTO user = new UserDTO();
+ user.setDateExpiration(LocalDateTime.now().minusDays(1));
+ assertTrue(user.isExpire());
+ }
+
+ @Test
+ void testIsExpire_false() {
+ UserDTO user = new UserDTO();
+ user.setDateExpiration(LocalDateTime.now().plusDays(1));
+ assertFalse(user.isExpire());
+ }
+
+ @Test
+ void testIsExpire_nullDate() {
+ UserDTO user = new UserDTO();
+ user.setDateExpiration(null);
+ assertFalse(user.isExpire());
+ }
+
+ @Test
+ void testHasRequiredActions_true() {
+ UserDTO user = new UserDTO();
+ user.setRequiredActions(Arrays.asList("UPDATE_PASSWORD", "VERIFY_EMAIL"));
+ assertTrue(user.hasRequiredActions());
+ }
+
+ @Test
+ void testHasRequiredActions_empty() {
+ UserDTO user = new UserDTO();
+ user.setRequiredActions(Collections.emptyList());
+ assertFalse(user.hasRequiredActions());
+ }
+
+ @Test
+ void testHasRequiredActions_null() {
+ UserDTO user = new UserDTO();
+ user.setRequiredActions(null);
+ assertFalse(user.hasRequiredActions());
+ }
+
+ @Test
+ void testBuilderAndAllFields() {
+ LocalDateTime now = LocalDateTime.now();
+ Map> clientRoles = new HashMap<>();
+ clientRoles.put("app", Arrays.asList("user", "admin"));
+ Map> attributes = new HashMap<>();
+ attributes.put("custom", Collections.singletonList("value"));
+
+ List fedIds = Collections.singletonList(
+ UserDTO.FederatedIdentityDTO.builder()
+ .identityProvider("google")
+ .userId("google-123")
+ .userName("user@gmail.com")
+ .build());
+
+ UserDTO user = UserDTO.builder()
+ .id("uuid-123")
+ .dateCreation(now)
+ .dateModification(now)
+ .creeParUsername("admin")
+ .modifieParUsername("admin")
+ .version(1L)
+ .username("jdupont")
+ .email("jean.dupont@lions.dev")
+ .emailVerified(true)
+ .prenom("Jean")
+ .nom("Dupont")
+ .statut(StatutUser.ACTIF)
+ .enabled(true)
+ .telephone("+225 07 12 34 56 78")
+ .organisation("Lions Dev")
+ .departement("IT")
+ .fonction("Developer")
+ .pays("Côte d'Ivoire")
+ .ville("Abidjan")
+ .langue("fr")
+ .timezone("Africa/Abidjan")
+ .realmName("btpxpress")
+ .realmRoles(Arrays.asList("user", "admin"))
+ .clientRoles(clientRoles)
+ .groups(Arrays.asList("group1", "group2"))
+ .derniereConnexion(now)
+ .dateExpiration(now.plusYears(1))
+ .dateVerrouillage(null)
+ .attributes(attributes)
+ .requiredActions(Collections.singletonList("UPDATE_PASSWORD"))
+ .federatedIdentityProvider("google")
+ .federatedIdentities(fedIds)
+ .temporaryPassword("temp123")
+ .temporaryPasswordFlag(true)
+ .activeSessions(2)
+ .failedLoginAttempts(0)
+ .raisonModification("Update")
+ .commentaires("Test user")
+ .build();
+
+ assertEquals("uuid-123", user.getId());
+ assertNotNull(user.getDateCreation());
+ assertNotNull(user.getDateModification());
+ assertEquals("admin", user.getCreeParUsername());
+ assertEquals("admin", user.getModifieParUsername());
+ assertEquals(1L, user.getVersion());
+ assertEquals("jdupont", user.getUsername());
+ assertEquals("jean.dupont@lions.dev", user.getEmail());
+ assertTrue(user.getEmailVerified());
+ assertEquals("Jean", user.getPrenom());
+ assertEquals("Dupont", user.getNom());
+ assertEquals(StatutUser.ACTIF, user.getStatut());
+ assertTrue(user.getEnabled());
+ assertEquals("+225 07 12 34 56 78", user.getTelephone());
+ assertEquals("Lions Dev", user.getOrganisation());
+ assertEquals("IT", user.getDepartement());
+ assertEquals("Developer", user.getFonction());
+ assertEquals("Côte d'Ivoire", user.getPays());
+ assertEquals("Abidjan", user.getVille());
+ assertEquals("fr", user.getLangue());
+ assertEquals("Africa/Abidjan", user.getTimezone());
+ assertEquals("btpxpress", user.getRealmName());
+ assertEquals(2, user.getRealmRoles().size());
+ assertEquals(1, user.getClientRoles().size());
+ assertEquals(2, user.getGroups().size());
+ assertNotNull(user.getDerniereConnexion());
+ assertNotNull(user.getDateExpiration());
+ assertNull(user.getDateVerrouillage());
+ assertEquals(1, user.getAttributes().size());
+ assertEquals(1, user.getRequiredActions().size());
+ assertEquals("google", user.getFederatedIdentityProvider());
+ assertEquals(1, user.getFederatedIdentities().size());
+ assertEquals("temp123", user.getTemporaryPassword());
+ assertTrue(user.getTemporaryPasswordFlag());
+ assertEquals(2, user.getActiveSessions());
+ assertEquals(0, user.getFailedLoginAttempts());
+ assertEquals("Update", user.getRaisonModification());
+ assertEquals("Test user", user.getCommentaires());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ UserDTO user1 = UserDTO.builder().id("uuid-123").username("jdupont").build();
+ UserDTO user2 = UserDTO.builder().id("uuid-123").username("jdupont").build();
+ UserDTO user3 = UserDTO.builder().id("uuid-456").username("other").build();
+
+ assertEquals(user1, user2);
+ assertEquals(user1.hashCode(), user2.hashCode());
+ assertNotEquals(user1, user3);
+ }
+
+ @Test
+ void testToString() {
+ UserDTO user = UserDTO.builder().username("jdupont").email("test@test.com").build();
+ String str = user.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("jdupont"));
+ assertTrue(str.contains("test@test.com"));
+ }
+
+ @Test
+ void testFederatedIdentityDTO() {
+ UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO();
+ fed.setIdentityProvider("google");
+ fed.setUserId("user-123");
+ fed.setUserName("user@gmail.com");
+
+ assertEquals("google", fed.getIdentityProvider());
+ assertEquals("user-123", fed.getUserId());
+ assertEquals("user@gmail.com", fed.getUserName());
+
+ // Test equals/hashCode/toString
+ UserDTO.FederatedIdentityDTO fed2 = UserDTO.FederatedIdentityDTO.builder()
+ .identityProvider("google")
+ .userId("user-123")
+ .userName("user@gmail.com")
+ .build();
+ assertEquals(fed, fed2);
+ assertEquals(fed.hashCode(), fed2.hashCode());
+ assertNotNull(fed.toString());
+ }
+
+ @Test
+ void testFederatedIdentityDTO_AllArgsConstructor() {
+ UserDTO.FederatedIdentityDTO fed = new UserDTO.FederatedIdentityDTO("google", "user-123", "user@gmail.com");
+ assertEquals("google", fed.getIdentityProvider());
+ assertEquals("user-123", fed.getUserId());
+ assertEquals("user@gmail.com", fed.getUserName());
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ UserDTO user = new UserDTO();
+ assertNull(user.getUsername());
+ assertNull(user.getEmail());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ LocalDateTime now = LocalDateTime.now();
+ Map> clientRoles = new HashMap<>();
+ Map> attributes = new HashMap<>();
+ List fedIds = Collections.emptyList();
+ List roles = Collections.emptyList();
+ List groups = Collections.emptyList();
+ List actions = Collections.emptyList();
+
+ UserDTO user = new UserDTO(
+ "username", "email@test.com", true, "Jean", "Dupont",
+ StatutUser.ACTIF, true, "phone", "org", "dept", "func",
+ "pays", "ville", "fr", "UTC", "realm", roles, clientRoles,
+ groups, now, now, now, attributes, actions, "google", fedIds,
+ "temppass", true, 1, 0, "reason", "comments");
+
+ assertEquals("username", user.getUsername());
+ assertEquals("email@test.com", user.getEmail());
+ assertTrue(user.getEmailVerified());
+ assertEquals("Jean", user.getPrenom());
+ assertEquals("Dupont", user.getNom());
+ assertEquals(StatutUser.ACTIF, user.getStatut());
+ assertTrue(user.getEnabled());
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java b/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java
new file mode 100644
index 0000000..de5253b
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/user/UserSearchCriteriaDTOTest.java
@@ -0,0 +1,145 @@
+package dev.lions.user.manager.dto.user;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour UserSearchCriteriaDTO
+ */
+class UserSearchCriteriaDTOTest {
+
+ @Test
+ void testBuilder() {
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .realmName("test-realm")
+ .username("testuser")
+ .email("test@example.com")
+ .enabled(true)
+ .page(0)
+ .pageSize(20)
+ .build();
+
+ assertNotNull(criteria);
+ assertEquals("test-realm", criteria.getRealmName());
+ assertEquals("testuser", criteria.getUsername());
+ assertEquals("test@example.com", criteria.getEmail());
+ assertTrue(criteria.getEnabled());
+ assertEquals(0, criteria.getPage());
+ assertEquals(20, criteria.getPageSize());
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
+
+ assertNotNull(criteria);
+ assertNull(criteria.getRealmName());
+ assertNull(criteria.getUsername());
+ assertNull(criteria.getEmail());
+ assertNull(criteria.getEnabled());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ // Le constructeur AllArgsConstructor nécessite tous les champs
+ // On utilise plutôt le builder pour ce test
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .realmName("test-realm")
+ .username("testuser")
+ .email("test@example.com")
+ .enabled(true)
+ .page(0)
+ .pageSize(20)
+ .build();
+
+ assertNotNull(criteria);
+ assertEquals("test-realm", criteria.getRealmName());
+ assertEquals("testuser", criteria.getUsername());
+ assertEquals("test@example.com", criteria.getEmail());
+ assertTrue(criteria.getEnabled());
+ assertEquals(0, criteria.getPage());
+ assertEquals(20, criteria.getPageSize());
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
+
+ criteria.setRealmName("realm1");
+ criteria.setUsername("user1");
+ criteria.setEmail("user1@example.com");
+ criteria.setEnabled(false);
+ criteria.setPage(1);
+ criteria.setPageSize(10);
+
+ assertEquals("realm1", criteria.getRealmName());
+ assertEquals("user1", criteria.getUsername());
+ assertEquals("user1@example.com", criteria.getEmail());
+ assertFalse(criteria.getEnabled());
+ assertEquals(1, criteria.getPage());
+ assertEquals(10, criteria.getPageSize());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ UserSearchCriteriaDTO criteria1 = UserSearchCriteriaDTO.builder()
+ .realmName("test-realm")
+ .username("testuser")
+ .build();
+
+ UserSearchCriteriaDTO criteria2 = UserSearchCriteriaDTO.builder()
+ .realmName("test-realm")
+ .username("testuser")
+ .build();
+
+ assertEquals(criteria1, criteria2);
+ assertEquals(criteria1.hashCode(), criteria2.hashCode());
+ }
+
+ @Test
+ void testToString() {
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .realmName("test-realm")
+ .username("testuser")
+ .build();
+
+ String toString = criteria.toString();
+ assertNotNull(toString);
+ assertTrue(toString.contains("test-realm") || toString.contains("testuser"));
+ }
+
+ @Test
+ void testHasFilters_WithFilters() {
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .username("testuser")
+ .enabled(true)
+ .build();
+
+ assertTrue(criteria.hasFilters());
+ }
+
+ @Test
+ void testHasFilters_NoFilters() {
+ UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
+
+ assertFalse(criteria.hasFilters());
+ }
+
+ @Test
+ void testGetOffset() {
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(2)
+ .pageSize(20)
+ .build();
+
+ assertEquals(40, criteria.getOffset());
+ }
+
+ @Test
+ void testGetOffset_Default() {
+ UserSearchCriteriaDTO criteria = new UserSearchCriteriaDTO();
+
+ assertEquals(0, criteria.getOffset());
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java b/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java
new file mode 100644
index 0000000..b68480c
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/dto/user/UserSearchResultDTOTest.java
@@ -0,0 +1,279 @@
+package dev.lions.user.manager.dto.user;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class UserSearchResultDTOTest {
+
+ @Test
+ void testOf_firstPage() {
+ List users = Arrays.asList(
+ UserDTO.builder().username("user1").build(),
+ UserDTO.builder().username("user2").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(0)
+ .pageSize(10)
+ .build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L);
+
+ assertEquals(2, result.getUsers().size());
+ assertEquals(25L, result.getTotalCount());
+ assertEquals(0, result.getCurrentPage());
+ assertEquals(10, result.getPageSize());
+ assertEquals(3, result.getTotalPages());
+ assertTrue(result.getHasNextPage());
+ assertFalse(result.getHasPreviousPage());
+ assertEquals(0, result.getFirstElement());
+ assertEquals(9, result.getLastElement());
+ assertFalse(result.getIsEmpty());
+ assertTrue(result.getIsFirstPage());
+ assertFalse(result.getIsLastPage());
+ assertEquals(criteria, result.getCriteria());
+ }
+
+ @Test
+ void testOf_middlePage() {
+ List users = Arrays.asList(
+ UserDTO.builder().username("user1").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(1)
+ .pageSize(10)
+ .build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L);
+
+ assertEquals(1, result.getCurrentPage());
+ assertTrue(result.getHasNextPage());
+ assertTrue(result.getHasPreviousPage());
+ assertFalse(result.getIsFirstPage());
+ assertFalse(result.getIsLastPage());
+ }
+
+ @Test
+ void testOf_lastPage() {
+ List users = Arrays.asList(
+ UserDTO.builder().username("user1").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(2)
+ .pageSize(10)
+ .build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 25L);
+
+ assertEquals(2, result.getCurrentPage());
+ assertFalse(result.getHasNextPage());
+ assertTrue(result.getHasPreviousPage());
+ assertFalse(result.getIsFirstPage());
+ assertTrue(result.getIsLastPage());
+ }
+
+ @Test
+ void testOf_emptyList() {
+ List users = Collections.emptyList();
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(0)
+ .pageSize(20)
+ .build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 0L);
+
+ assertTrue(result.getIsEmpty());
+ assertEquals(0, result.getTotalCount());
+ assertEquals(0, result.getTotalPages());
+ }
+
+ @Test
+ void testOf_nullList() {
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(0)
+ .pageSize(20)
+ .build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.of(null, criteria, 0L);
+
+ assertTrue(result.getIsEmpty());
+ }
+
+ @Test
+ void testOf_singlePage() {
+ List users = Arrays.asList(
+ UserDTO.builder().username("user1").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
+ .page(0)
+ .pageSize(10)
+ .build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.of(users, criteria, 5L);
+
+ assertEquals(1, result.getTotalPages());
+ assertFalse(result.getHasNextPage());
+ assertFalse(result.getHasPreviousPage());
+ assertTrue(result.getIsFirstPage());
+ assertTrue(result.getIsLastPage());
+ }
+
+ @Test
+ void testGetCurrentPageSize_withUsers() {
+ UserSearchResultDTO result = UserSearchResultDTO.builder()
+ .users(Arrays.asList(
+ UserDTO.builder().username("u1").build(),
+ UserDTO.builder().username("u2").build(),
+ UserDTO.builder().username("u3").build()))
+ .build();
+
+ assertEquals(3, result.getCurrentPageSize());
+ }
+
+ @Test
+ void testGetCurrentPageSize_emptyUsers() {
+ UserSearchResultDTO result = UserSearchResultDTO.builder()
+ .users(Collections.emptyList())
+ .build();
+
+ assertEquals(0, result.getCurrentPageSize());
+ }
+
+ @Test
+ void testGetCurrentPageSize_nullUsers() {
+ UserSearchResultDTO result = UserSearchResultDTO.builder()
+ .users(null)
+ .build();
+
+ assertEquals(0, result.getCurrentPageSize());
+ }
+
+ @Test
+ void testBuilderAndAllFields() {
+ List users = Collections.singletonList(UserDTO.builder().username("test").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().page(0).pageSize(20).build();
+
+ UserSearchResultDTO result = UserSearchResultDTO.builder()
+ .users(users)
+ .totalCount(100L)
+ .currentPage(0)
+ .pageSize(20)
+ .totalPages(5)
+ .hasNextPage(true)
+ .hasPreviousPage(false)
+ .firstElement(0)
+ .lastElement(19)
+ .isEmpty(false)
+ .isFirstPage(true)
+ .isLastPage(false)
+ .criteria(criteria)
+ .executionTimeMs(150L)
+ .build();
+
+ assertEquals(users, result.getUsers());
+ assertEquals(100L, result.getTotalCount());
+ assertEquals(0, result.getCurrentPage());
+ assertEquals(20, result.getPageSize());
+ assertEquals(5, result.getTotalPages());
+ assertTrue(result.getHasNextPage());
+ assertFalse(result.getHasPreviousPage());
+ assertEquals(0, result.getFirstElement());
+ assertEquals(19, result.getLastElement());
+ assertFalse(result.getIsEmpty());
+ assertTrue(result.getIsFirstPage());
+ assertFalse(result.getIsLastPage());
+ assertEquals(criteria, result.getCriteria());
+ assertEquals(150L, result.getExecutionTimeMs());
+ }
+
+ @Test
+ void testSettersAndGetters() {
+ UserSearchResultDTO result = new UserSearchResultDTO();
+ List users = Collections.singletonList(UserDTO.builder().username("test").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build();
+
+ result.setUsers(users);
+ result.setTotalCount(50L);
+ result.setCurrentPage(1);
+ result.setPageSize(10);
+ result.setTotalPages(5);
+ result.setHasNextPage(true);
+ result.setHasPreviousPage(true);
+ result.setFirstElement(10);
+ result.setLastElement(19);
+ result.setIsEmpty(false);
+ result.setIsFirstPage(false);
+ result.setIsLastPage(false);
+ result.setCriteria(criteria);
+ result.setExecutionTimeMs(200L);
+
+ assertEquals(users, result.getUsers());
+ assertEquals(50L, result.getTotalCount());
+ assertEquals(1, result.getCurrentPage());
+ assertEquals(10, result.getPageSize());
+ assertEquals(5, result.getTotalPages());
+ assertTrue(result.getHasNextPage());
+ assertTrue(result.getHasPreviousPage());
+ assertEquals(10, result.getFirstElement());
+ assertEquals(19, result.getLastElement());
+ assertFalse(result.getIsEmpty());
+ assertFalse(result.getIsFirstPage());
+ assertFalse(result.getIsLastPage());
+ assertEquals(criteria, result.getCriteria());
+ assertEquals(200L, result.getExecutionTimeMs());
+ }
+
+ @Test
+ void testEqualsAndHashCode() {
+ UserSearchResultDTO dto1 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build();
+ UserSearchResultDTO dto2 = UserSearchResultDTO.builder().totalCount(10L).currentPage(0).build();
+ UserSearchResultDTO dto3 = UserSearchResultDTO.builder().totalCount(20L).currentPage(1).build();
+
+ assertEquals(dto1, dto2);
+ assertEquals(dto1.hashCode(), dto2.hashCode());
+ assertNotEquals(dto1, dto3);
+ }
+
+ @Test
+ void testToString() {
+ UserSearchResultDTO result = UserSearchResultDTO.builder()
+ .totalCount(100L)
+ .currentPage(0)
+ .build();
+ String str = result.toString();
+ assertNotNull(str);
+ assertTrue(str.contains("100"));
+ }
+
+ @Test
+ void testNoArgsConstructor() {
+ UserSearchResultDTO result = new UserSearchResultDTO();
+ assertNull(result.getUsers());
+ assertNull(result.getTotalCount());
+ assertNull(result.getCurrentPage());
+ }
+
+ @Test
+ void testAllArgsConstructor() {
+ List users = Collections.singletonList(UserDTO.builder().username("test").build());
+ UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder().build();
+
+ UserSearchResultDTO result = new UserSearchResultDTO(
+ users, 100L, 0, 20, 5, true, false, 0, 19, false, true, false, criteria, 150L);
+
+ assertEquals(users, result.getUsers());
+ assertEquals(100L, result.getTotalCount());
+ assertEquals(0, result.getCurrentPage());
+ assertEquals(20, result.getPageSize());
+ assertEquals(5, result.getTotalPages());
+ assertTrue(result.getHasNextPage());
+ assertFalse(result.getHasPreviousPage());
+ assertEquals(0, result.getFirstElement());
+ assertEquals(19, result.getLastElement());
+ assertFalse(result.getIsEmpty());
+ assertTrue(result.getIsFirstPage());
+ assertFalse(result.getIsLastPage());
+ assertEquals(criteria, result.getCriteria());
+ assertEquals(150L, result.getExecutionTimeMs());
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java b/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java
new file mode 100644
index 0000000..ea615b2
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/enums/audit/TypeActionAuditTest.java
@@ -0,0 +1,59 @@
+package dev.lions.user.manager.enums.audit;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour TypeActionAudit
+ */
+class TypeActionAuditTest {
+
+ @Test
+ void testValues() {
+ TypeActionAudit[] values = TypeActionAudit.values();
+
+ assertNotNull(values);
+ assertTrue(values.length > 0);
+ }
+
+ @Test
+ void testValueOf() {
+ TypeActionAudit userCreate = TypeActionAudit.valueOf("USER_CREATE");
+ TypeActionAudit userUpdate = TypeActionAudit.valueOf("USER_UPDATE");
+ TypeActionAudit userDelete = TypeActionAudit.valueOf("USER_DELETE");
+ TypeActionAudit roleCreate = TypeActionAudit.valueOf("ROLE_CREATE");
+ TypeActionAudit roleUpdate = TypeActionAudit.valueOf("ROLE_UPDATE");
+ TypeActionAudit roleDelete = TypeActionAudit.valueOf("ROLE_DELETE");
+ TypeActionAudit roleAssign = TypeActionAudit.valueOf("ROLE_ASSIGN");
+ TypeActionAudit roleRevoke = TypeActionAudit.valueOf("ROLE_REVOKE");
+
+ assertEquals(TypeActionAudit.USER_CREATE, userCreate);
+ assertEquals(TypeActionAudit.USER_UPDATE, userUpdate);
+ assertEquals(TypeActionAudit.USER_DELETE, userDelete);
+ assertEquals(TypeActionAudit.ROLE_CREATE, roleCreate);
+ assertEquals(TypeActionAudit.ROLE_UPDATE, roleUpdate);
+ assertEquals(TypeActionAudit.ROLE_DELETE, roleDelete);
+ assertEquals(TypeActionAudit.ROLE_ASSIGN, roleAssign);
+ assertEquals(TypeActionAudit.ROLE_REVOKE, roleRevoke);
+ }
+
+ @Test
+ void testValueOf_Invalid() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ TypeActionAudit.valueOf("INVALID");
+ });
+ }
+
+ @Test
+ void testEnumValues() {
+ assertNotNull(TypeActionAudit.USER_CREATE);
+ assertNotNull(TypeActionAudit.USER_UPDATE);
+ assertNotNull(TypeActionAudit.USER_DELETE);
+ assertNotNull(TypeActionAudit.ROLE_CREATE);
+ assertNotNull(TypeActionAudit.ROLE_UPDATE);
+ assertNotNull(TypeActionAudit.ROLE_DELETE);
+ assertNotNull(TypeActionAudit.ROLE_ASSIGN);
+ assertNotNull(TypeActionAudit.ROLE_REVOKE);
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java b/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java
new file mode 100644
index 0000000..706497f
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/enums/role/TypeRoleTest.java
@@ -0,0 +1,41 @@
+package dev.lions.user.manager.enums.role;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour TypeRole
+ */
+class TypeRoleTest {
+
+ @Test
+ void testValues() {
+ TypeRole[] values = TypeRole.values();
+
+ assertNotNull(values);
+ assertTrue(values.length > 0);
+ }
+
+ @Test
+ void testValueOf() {
+ TypeRole realmRole = TypeRole.valueOf("REALM_ROLE");
+ TypeRole clientRole = TypeRole.valueOf("CLIENT_ROLE");
+
+ assertEquals(TypeRole.REALM_ROLE, realmRole);
+ assertEquals(TypeRole.CLIENT_ROLE, clientRole);
+ }
+
+ @Test
+ void testValueOf_Invalid() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ TypeRole.valueOf("INVALID");
+ });
+ }
+
+ @Test
+ void testEnumValues() {
+ assertNotNull(TypeRole.REALM_ROLE);
+ assertNotNull(TypeRole.CLIENT_ROLE);
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java b/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java
new file mode 100644
index 0000000..16e98ad
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/enums/user/StatutUserTest.java
@@ -0,0 +1,44 @@
+package dev.lions.user.manager.enums.user;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests unitaires pour StatutUser
+ */
+class StatutUserTest {
+
+ @Test
+ void testValues() {
+ StatutUser[] values = StatutUser.values();
+
+ assertNotNull(values);
+ assertTrue(values.length > 0);
+ }
+
+ @Test
+ void testValueOf() {
+ StatutUser actif = StatutUser.valueOf("ACTIF");
+ StatutUser inactif = StatutUser.valueOf("INACTIF");
+ StatutUser suspendu = StatutUser.valueOf("SUSPENDU");
+
+ assertEquals(StatutUser.ACTIF, actif);
+ assertEquals(StatutUser.INACTIF, inactif);
+ assertEquals(StatutUser.SUSPENDU, suspendu);
+ }
+
+ @Test
+ void testValueOf_Invalid() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ StatutUser.valueOf("INVALID");
+ });
+ }
+
+ @Test
+ void testEnumValues() {
+ assertNotNull(StatutUser.ACTIF);
+ assertNotNull(StatutUser.INACTIF);
+ assertNotNull(StatutUser.SUSPENDU);
+ }
+}
diff --git a/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java b/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java
new file mode 100644
index 0000000..282b798
--- /dev/null
+++ b/src/test/java/dev/lions/user/manager/validation/ValidationConstantsTest.java
@@ -0,0 +1,18 @@
+package dev.lions.user.manager.validation;
+
+import org.junit.jupiter.api.Test;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import static org.junit.jupiter.api.Assertions.*;
+
+class ValidationConstantsTest {
+
+ @Test
+ void testPrivateConstructor() throws Exception {
+ Constructor constructor = ValidationConstants.class.getDeclaredConstructor();
+ assertTrue(Modifier.isPrivate(constructor.getModifiers()));
+ constructor.setAccessible(true);
+ ValidationConstants instance = constructor.newInstance();
+ assertNotNull(instance);
+ }
+}