package dev.lions.unionflow.server.resource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import dev.lions.unionflow.server.api.dto.common.PagedResponse;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationResponse;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.service.KeycloakService;
import dev.lions.unionflow.server.service.OrganisationService;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import jakarta.inject.Inject;
import jakarta.ws.rs.core.Response;
import java.security.Principal;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
/**
* Tests CDI directs pour {@link OrganisationResource} couvrant les branches
* inaccessibles via HTTP standard (principal null).
*
*
* - L75 : {@code listerMesOrganisations()} — principal null → email null → liste vide
* - L172 : {@code listerOrganisations()} — ADMIN_ORGANISATION + principal null → chemin global
*
*/
@QuarkusTest
@DisplayName("OrganisationResource — branches de couverture manquantes")
class OrganisationResourceMissingBranchesTest {
@Inject
OrganisationResource organisationResource;
@InjectMock
OrganisationService organisationService;
@InjectMock
KeycloakService keycloakService;
@InjectMock
SecurityIdentity securityIdentity;
// =========================================================================
// listerMesOrganisations L75 : principal null → email null → liste vide
// =========================================================================
@Test
@TestSecurity(user = "membre@test.com", roles = {"MEMBRE"})
@DisplayName("listerMesOrganisations — principal null → email null → liste vide (couvre L75)")
void listerMesOrganisations_principalNull_retourneListeVide() {
when(securityIdentity.getPrincipal()).thenReturn(null);
Response response = organisationResource.listerMesOrganisations();
assertThat(response.getStatus()).isEqualTo(200);
@SuppressWarnings("unchecked")
List body = (List) response.getEntity();
assertThat(body).isEmpty();
}
// =========================================================================
// listerOrganisations L172 : ADMIN_ORGANISATION + principal null → chemin global (else)
// =========================================================================
@Test
@TestSecurity(user = "orgadmin@test.com", roles = {"ADMIN_ORGANISATION"})
@DisplayName("listerOrganisations — ADMIN_ORGANISATION + principal null → chemin global (couvre L172)")
void listerOrganisations_adminOrg_principalNull_cheminGlobal() {
when(securityIdentity.getRoles()).thenReturn(Set.of("ADMIN_ORGANISATION"));
when(securityIdentity.getPrincipal()).thenReturn(null);
when(organisationService.listerOrganisationsActives(anyInt(), anyInt())).thenReturn(List.of());
when(organisationService.compterOrganisationsActives()).thenReturn(0L);
PagedResponse result = organisationResource.listerOrganisations(
0, 20, null);
assertThat(result).isNotNull();
}
// =========================================================================
// listerOrganisations L175-180 : ADMIN_ORGANISATION + principal non-null + recherche non-vide
// → filtre appliqué sur les organisations (lambda getNom/getNomCourt)
// =========================================================================
@Test
@TestSecurity(user = "orgadmin@test.com", roles = {"ADMIN_ORGANISATION"})
@DisplayName("listerOrganisations — ADMIN_ORGANISATION + recherche → filtre lambda getNom (couvre L175-180)")
void listerOrganisations_adminOrg_avecRecherche_filtreParNom() {
Principal principal = () -> "orgadmin@test.com";
when(securityIdentity.getRoles()).thenReturn(Set.of("ADMIN_ORGANISATION"));
when(securityIdentity.getPrincipal()).thenReturn(principal);
// Organisation dont le nom contient "test" — passera le filtre
Organisation org1 = new Organisation();
org1.setId(UUID.randomUUID());
org1.setNom("Organisation Test");
org1.setNomCourt(null);
// Organisation dont nomCourt contient "test" — passera le filtre via nomCourt
Organisation org2 = new Organisation();
org2.setId(UUID.randomUUID());
org2.setNom(null);
org2.setNomCourt("Org Test Court");
// Organisation qui ne correspond pas
Organisation org3 = new Organisation();
org3.setId(UUID.randomUUID());
org3.setNom("Autre Association");
org3.setNomCourt("AA");
when(organisationService.listerOrganisationsPourUtilisateur("orgadmin@test.com"))
.thenReturn(List.of(org1, org2, org3));
when(organisationService.convertToSummaryResponse(any(Organisation.class)))
.thenReturn(new OrganisationSummaryResponse(null, null, null, null, null, null, null, null, null, null, null, null));
// recherche = "test" → filtre les organisations dont nom ou nomCourt contient "test"
PagedResponse result = organisationResource.listerOrganisations(
0, 20, "test");
assertThat(result).isNotNull();
// org1 et org2 correspondent, org3 non → 2 résultats
assertThat(result.getData()).hasSize(2);
}
@Test
@TestSecurity(user = "orgadmin@test.com", roles = {"ADMIN_ORGANISATION"})
@DisplayName("listerOrganisations — ADMIN_ORGANISATION + recherche → filtre lambda avec nom null et nomCourt null")
void listerOrganisations_adminOrg_avecRecherche_nomEtNomCourtNull_filtre() {
Principal principal = () -> "orgadmin@test.com";
when(securityIdentity.getRoles()).thenReturn(Set.of("ADMIN_ORGANISATION"));
when(securityIdentity.getPrincipal()).thenReturn(principal);
// Organisation avec nom=null et nomCourt=null — ne passera pas le filtre
Organisation org = new Organisation();
org.setId(UUID.randomUUID());
org.setNom(null);
org.setNomCourt(null);
when(organisationService.listerOrganisationsPourUtilisateur("orgadmin@test.com"))
.thenReturn(List.of(org));
// recherche non vide → filtre → nom null && nomCourt null → aucun résultat
PagedResponse result = organisationResource.listerOrganisations(
0, 20, "quelquechose");
assertThat(result).isNotNull();
assertThat(result.getData()).isEmpty();
}
// =========================================================================
// listerOrganisations L170 : ADMIN_ORGANISATION + ADMIN → onlyOrgAdmin=false
// =========================================================================
@Test
@TestSecurity(user = "admin@test.com", roles = {"ADMIN_ORGANISATION", "ADMIN"})
@DisplayName("listerOrganisations — ADMIN_ORGANISATION + ADMIN → onlyOrgAdmin=false, chemin global (couvre L170)")
void listerOrganisations_adminOrgPlusAdmin_onlyOrgAdminFalse() {
when(securityIdentity.getRoles()).thenReturn(Set.of("ADMIN_ORGANISATION", "ADMIN"));
when(organisationService.listerOrganisationsActives(anyInt(), anyInt())).thenReturn(List.of());
when(organisationService.compterOrganisationsActives()).thenReturn(0L);
PagedResponse result = organisationResource.listerOrganisations(
0, 20, null);
assertThat(result).isNotNull();
}
// =========================================================================
// listerOrganisations L171 : ADMIN_ORGANISATION + SUPER_ADMIN → onlyOrgAdmin=false
// =========================================================================
@Test
@TestSecurity(user = "superadmin@test.com", roles = {"ADMIN_ORGANISATION", "SUPER_ADMIN"})
@DisplayName("listerOrganisations — ADMIN_ORGANISATION + SUPER_ADMIN → onlyOrgAdmin=false (couvre L171)")
void listerOrganisations_adminOrgPlusSuperAdmin_onlyOrgAdminFalse() {
when(securityIdentity.getRoles()).thenReturn(Set.of("ADMIN_ORGANISATION", "SUPER_ADMIN"));
when(organisationService.listerOrganisationsActives(anyInt(), anyInt())).thenReturn(List.of());
when(organisationService.compterOrganisationsActives()).thenReturn(0L);
PagedResponse result = organisationResource.listerOrganisations(
0, 20, null);
assertThat(result).isNotNull();
}
// =========================================================================
// listerOrganisations L188 : onlyOrgAdmin=false + recherche non-null mais blank
// → !recherche.trim().isEmpty()=false → else branch
// =========================================================================
@Test
@TestSecurity(user = "membre@test.com", roles = {"MEMBRE"})
@DisplayName("listerOrganisations — MEMBRE + recherche blank → else if isEmpty()=true → else (couvre L188)")
void listerOrganisations_membre_rechercheBlank_elseElse() {
when(securityIdentity.getRoles()).thenReturn(Set.of("MEMBRE"));
when(organisationService.listerOrganisationsActives(anyInt(), anyInt())).thenReturn(List.of());
when(organisationService.compterOrganisationsActives()).thenReturn(0L);
// recherche non-null mais blank → trim().isEmpty()=true → condition false → else
PagedResponse result = organisationResource.listerOrganisations(
0, 20, " ");
assertThat(result).isNotNull();
}
// =========================================================================
// Error cases
// =========================================================================
@Test
@TestSecurity(user = "membre@test.com", roles = {"MEMBRE"})
@DisplayName("listerMesOrganisations — service lève exception → exception propagée")
void listerMesOrganisations_serviceException_propagee() {
Principal principal = () -> "membre@test.com";
when(securityIdentity.getPrincipal()).thenReturn(principal);
when(organisationService.listerOrganisationsPourUtilisateur(anyString()))
.thenThrow(new RuntimeException("Erreur base de données"));
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
() -> organisationResource.listerMesOrganisations());
}
@Test
@TestSecurity(user = "superadmin@test.com", roles = {"SUPER_ADMIN"})
@DisplayName("listerOrganisations — SUPER_ADMIN + service retourne liste vide → résultat non null")
void listerOrganisations_superAdmin_listeVide_retourneResultatNonNull() {
when(securityIdentity.getRoles()).thenReturn(Set.of("SUPER_ADMIN"));
when(organisationService.listerOrganisationsActives(anyInt(), anyInt())).thenReturn(List.of());
when(organisationService.compterOrganisationsActives()).thenReturn(0L);
PagedResponse result = organisationResource.listerOrganisations(
0, 20, null);
assertThat(result).isNotNull();
assertThat(result.getData()).isEmpty();
}
@Test
@TestSecurity(user = "orgadmin@test.com", roles = {"ADMIN_ORGANISATION"})
@DisplayName("listerOrganisations — ADMIN_ORGANISATION + service lève exception → exception propagée")
void listerOrganisations_adminOrg_serviceException_propagee() {
when(securityIdentity.getRoles()).thenReturn(Set.of("ADMIN_ORGANISATION"));
Principal principal = () -> "orgadmin@test.com";
when(securityIdentity.getPrincipal()).thenReturn(principal);
when(organisationService.listerOrganisationsPourUtilisateur(anyString()))
.thenThrow(new RuntimeException("Accès base de données impossible"));
org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
() -> organisationResource.listerOrganisations(0, 20, null));
}
}