package dev.lions.unionflow.server.service; import dev.lions.unionflow.server.client.RoleServiceClient; import dev.lions.unionflow.server.client.UserServiceClient; import dev.lions.user.manager.dto.role.RoleDTO; import dev.lions.user.manager.dto.user.UserDTO; import dev.lions.user.manager.dto.user.UserSearchResultDTO; import io.quarkus.test.InjectMock; import io.quarkus.test.junit.QuarkusTest; import jakarta.inject.Inject; import org.eclipse.microprofile.rest.client.inject.RestClient; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import java.util.List; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @QuarkusTest class AdminUserServiceTest { @Inject AdminUserService adminUserService; @InjectMock @RestClient UserServiceClient userServiceClient; @InjectMock @RestClient RoleServiceClient roleServiceClient; @Test @DisplayName("searchUsers appelle le client rest UserService") void searchUsers_callsClient() { UserSearchResultDTO mockResult = new UserSearchResultDTO(); Mockito.when(userServiceClient.searchUsers(any())).thenReturn(mockResult); UserSearchResultDTO result = adminUserService.searchUsers(0, 10, "test"); assertThat(result).isNotNull(); Mockito.verify(userServiceClient).searchUsers(any()); } @Test @DisplayName("getUserById retourne l'utilisateur via le client") void getUserById_returnsUser() { String userId = UUID.randomUUID().toString(); UserDTO mockUser = new UserDTO(); mockUser.setId(userId); mockUser.setUsername("testuser"); Mockito.when(userServiceClient.getUserById(eq(userId), any())).thenReturn(mockUser); UserDTO result = adminUserService.getUserById(userId); assertThat(result).isNotNull(); assertThat(result.getUsername()).isEqualTo("testuser"); } @Test @DisplayName("createUser appelle le client pour la création") void createUser_callsClient() { UserDTO user = new UserDTO(); user.setUsername("newuser"); Mockito.when(userServiceClient.createUser(any(), any())).thenReturn(user); UserDTO result = adminUserService.createUser(user); assertThat(result).isNotNull(); assertThat(result.getUsername()).isEqualTo("newuser"); } // ========================================================================= // getRealmRoles // ========================================================================= @Test @DisplayName("getRealmRoles retourne la liste des rôles") void getRealmRoles_returnsRoles() { RoleDTO role = new RoleDTO(); role.setName("admin"); Mockito.when(roleServiceClient.getRealmRoles("unionflow")).thenReturn(List.of(role)); List result = adminUserService.getRealmRoles(); assertThat(result).hasSize(1); assertThat(result.get(0).getName()).isEqualTo("admin"); } @Test @DisplayName("getRealmRoles retourne liste vide si le client lève une exception") void getRealmRoles_exceptionRetourneListeVide() { Mockito.when(roleServiceClient.getRealmRoles(any())) .thenThrow(new RuntimeException("Service unavailable")); List result = adminUserService.getRealmRoles(); assertThat(result).isEmpty(); } // ========================================================================= // getUserRoles // ========================================================================= @Test @DisplayName("getUserRoles retourne les rôles de l'utilisateur") void getUserRoles_returnsUserRoles() { String userId = UUID.randomUUID().toString(); RoleDTO role = new RoleDTO(); role.setName("membre"); Mockito.when(roleServiceClient.getUserRealmRoles(eq(userId), any())).thenReturn(List.of(role)); List result = adminUserService.getUserRoles(userId); assertThat(result).hasSize(1); assertThat(result.get(0).getName()).isEqualTo("membre"); } @Test @DisplayName("getUserRoles retourne liste vide si le client lève une exception") void getUserRoles_exceptionRetourneListeVide() { String userId = UUID.randomUUID().toString(); Mockito.when(roleServiceClient.getUserRealmRoles(eq(userId), any())) .thenThrow(new RuntimeException("Keycloak down")); List result = adminUserService.getUserRoles(userId); assertThat(result).isEmpty(); } // ========================================================================= // updateUser // ========================================================================= @Test @DisplayName("updateUser appelle le client REST avec userId et realm") void updateUser_callsClient() { String userId = UUID.randomUUID().toString(); UserDTO user = new UserDTO(); user.setUsername("updated-user"); Mockito.when(userServiceClient.updateUser(eq(userId), any(), any())).thenReturn(user); UserDTO result = adminUserService.updateUser(userId, user); assertThat(result).isNotNull(); assertThat(result.getUsername()).isEqualTo("updated-user"); Mockito.verify(userServiceClient).updateUser(eq(userId), any(), eq("unionflow")); } // ========================================================================= // updateUserEnabled // ========================================================================= @Test @DisplayName("updateUserEnabled active l'utilisateur et appelle updateUser") void updateUserEnabled_activerUtilisateur() { String userId = UUID.randomUUID().toString(); UserDTO existing = new UserDTO(); existing.setId(userId); existing.setUsername("testuser"); existing.setEnabled(false); UserDTO updated = new UserDTO(); updated.setId(userId); updated.setEnabled(true); Mockito.when(userServiceClient.getUserById(eq(userId), any())).thenReturn(existing); Mockito.when(userServiceClient.updateUser(eq(userId), any(), any())).thenReturn(updated); UserDTO result = adminUserService.updateUserEnabled(userId, true); assertThat(result).isNotNull(); Mockito.verify(userServiceClient).updateUser(eq(userId), any(), eq("unionflow")); } @Test @DisplayName("updateUserEnabled lance IllegalArgumentException si l'utilisateur est null") void updateUserEnabled_utilisateurNonTrouve_lancerException() { String userId = UUID.randomUUID().toString(); Mockito.when(userServiceClient.getUserById(eq(userId), any())).thenReturn(null); assertThatThrownBy(() -> adminUserService.updateUserEnabled(userId, true)) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("Utilisateur non trouvé"); } // ========================================================================= // setUserRoles // ========================================================================= @Test @DisplayName("setUserRoles assigne les nouveaux rôles et révoque les retirés") void setUserRoles_assigneEtRevoque() { String userId = UUID.randomUUID().toString(); RoleDTO existingRole = new RoleDTO(); existingRole.setName("membre"); // L'utilisateur a actuellement "membre", on veut lui assigner "admin" Mockito.when(roleServiceClient.getUserRealmRoles(eq(userId), any())) .thenReturn(List.of(existingRole)); // assign "admin", revoke "membre" adminUserService.setUserRoles(userId, List.of("admin")); Mockito.verify(roleServiceClient).assignRealmRoles(eq(userId), eq("unionflow"), any()); Mockito.verify(roleServiceClient).revokeRealmRoles(eq(userId), eq("unionflow"), any()); } @Test @DisplayName("setUserRoles sans changement — ni assign ni revoke appelé") void setUserRoles_sansChangement_aucunAppel() { String userId = UUID.randomUUID().toString(); RoleDTO existingRole = new RoleDTO(); existingRole.setName("admin"); // L'utilisateur a déjà "admin", on veut "admin" → rien à faire Mockito.when(roleServiceClient.getUserRealmRoles(eq(userId), any())) .thenReturn(List.of(existingRole)); adminUserService.setUserRoles(userId, List.of("admin")); Mockito.verify(roleServiceClient, Mockito.never()).assignRealmRoles(any(), any(), any()); Mockito.verify(roleServiceClient, Mockito.never()).revokeRealmRoles(any(), any(), any()); } @Test @DisplayName("setUserRoles avec liste cible vide — tous les rôles existants révoqués") void setUserRoles_listeCibleNull_tousRevoque() { String userId = UUID.randomUUID().toString(); RoleDTO existingRole = new RoleDTO(); existingRole.setName("membre"); Mockito.when(roleServiceClient.getUserRealmRoles(eq(userId), any())) .thenReturn(List.of(existingRole)); adminUserService.setUserRoles(userId, new java.util.ArrayList<>()); // rien à assigner, "membre" à révoquer Mockito.verify(roleServiceClient, Mockito.never()).assignRealmRoles(any(), any(), any()); Mockito.verify(roleServiceClient).revokeRealmRoles(eq(userId), eq("unionflow"), any()); } @Test @DisplayName("setUserRoles null targetRoleNames — couvre branche null L107") void setUserRoles_targetRolesNull_revoqueTous() { String userId = UUID.randomUUID().toString(); RoleDTO existingRole = new RoleDTO(); existingRole.setName("admin"); Mockito.when(roleServiceClient.getUserRealmRoles(eq(userId), any())) .thenReturn(List.of(existingRole)); // null → toAssign = List.of(), toRevoke = currentNames − List.of() = currentNames adminUserService.setUserRoles(userId, null); Mockito.verify(roleServiceClient, Mockito.never()).assignRealmRoles(any(), any(), any()); Mockito.verify(roleServiceClient).revokeRealmRoles(eq(userId), eq("unionflow"), any()); } }