package org.mte.numecoeval.referentiel.infrastructure.jpa;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mte.numecoeval.referentiel.domain.exception.ReferentielException;
import org.mte.numecoeval.referentiel.domain.model.Critere;
import org.mte.numecoeval.referentiel.domain.model.id.CritereId;
import org.mte.numecoeval.referentiel.infrastructure.jpa.adapter.CritereJpaAdapter;
import org.mte.numecoeval.referentiel.infrastructure.jpa.adapter.ImpactEquipementJpaAdapter;
import org.mte.numecoeval.referentiel.infrastructure.jpa.adapter.ImpactMessagerieJpaAdapter;
import org.mte.numecoeval.referentiel.infrastructure.jpa.adapter.ImpactReseauJpaAdapter;
import org.mte.numecoeval.referentiel.infrastructure.jpa.adapter.MixElectriqueJpaAdapter;
import org.mte.numecoeval.referentiel.infrastructure.jpa.entity.CritereEntity;
import org.mte.numecoeval.referentiel.infrastructure.jpa.repository.CritereRepository;
import org.mte.numecoeval.referentiel.infrastructure.mapper.CritereMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ContextConfiguration(classes = {CritereJpaAdapter.class})
@ExtendWith(SpringExtension.class)
class CritereJpaAdapterTest {
    @Autowired
    private CritereJpaAdapter critereJpaAdapter;

    @MockBean
    private CritereMapper critereMapper;

    @MockBean
    private CritereRepository critereRepository;

    @MockBean
    private ImpactEquipementJpaAdapter impactEquipementJpaAdapter;

    @MockBean
    private ImpactReseauJpaAdapter impactReseauJpaAdapter;

    @MockBean
    private MixElectriqueJpaAdapter mixElectriqueJpaAdapter;

    @MockBean
    private ImpactMessagerieJpaAdapter impactMessagerieJpaAdapter;

    /**
     * Method under test: {@link CritereJpaAdapter#save(Critere)}
     */
    @Test
    void testSave() throws ReferentielException {
        Critere critere = new Critere();
        critere.setDescription("The characteristics of someone or something");
        critere.setNomCritere("Nom Critere");
        critere.setUnite("Unite");
        assertNull(critereJpaAdapter.save(critere));
    }

    /**
     * Method under test: {@link CritereJpaAdapter#save(Critere)}
     */
    @Test
    void testSave2() throws ReferentielException {
        Critere critere = new Critere();
        critere.setDescription("The characteristics of someone or something");
        critere.setNomCritere("Nom Critere");
        critere.setUnite("Unite");

        Critere critere1 = new Critere();
        critere1.setDescription("The characteristics of someone or something");
        critere1.setNomCritere("Nom Critere");
        critere1.setUnite("Unite");

        Critere critere2 = new Critere();
        critere2.setDescription("The characteristics of someone or something");
        critere2.setNomCritere("Nom Critere");
        critere2.setUnite("Unite");
        Critere critere3 = mock(Critere.class);
        when(critere3.setDescription((String) any())).thenReturn(critere);
        when(critere3.setNomCritere((String) any())).thenReturn(critere1);
        when(critere3.setUnite((String) any())).thenReturn(critere2);
        critere3.setDescription("The characteristics of someone or something");
        critere3.setNomCritere("Nom Critere");
        critere3.setUnite("Unite");
        assertNull(critereJpaAdapter.save(critere3));
        verify(critere3).setDescription((String) any());
        verify(critere3).setNomCritere((String) any());
        verify(critere3).setUnite((String) any());
    }

    /**
     * Method under test: {@link CritereJpaAdapter#saveAll(Collection)}
     */
    @Test
    void testSaveAll() throws ReferentielException {
        when(critereMapper.toEntities((Collection<Critere>) any())).thenReturn(new ArrayList<>());
        when(critereRepository.saveAll((Iterable<CritereEntity>) any())).thenReturn(new ArrayList<>());
        critereJpaAdapter.saveAll(new ArrayList<>());
        verify(critereMapper).toEntities((Collection<Critere>) any());
        verify(critereRepository).saveAll((Iterable<CritereEntity>) any());
        assertTrue(critereJpaAdapter.getAll().isEmpty());
    }

    /**
     * Method under test: {@link CritereJpaAdapter#get(CritereId)}
     */
    @Test
    void testGet() throws ReferentielException {
        CritereId critereId = new CritereId();
        critereId.setNomCritere("Nom Critere");
        assertNull(critereJpaAdapter.get(critereId));
    }

    /**
     * Method under test: {@link CritereJpaAdapter#get(CritereId)}
     */
    @Test
    void testGet2() throws ReferentielException {
        CritereId critereId = new CritereId();
        critereId.setNomCritere("Nom Critere");
        CritereId critereId1 = mock(CritereId.class);
        when(critereId1.setNomCritere((String) any())).thenReturn(critereId);
        critereId1.setNomCritere("Nom Critere");
        assertNull(critereJpaAdapter.get(critereId1));
        verify(critereId1).setNomCritere((String) any());
    }

    /**
     * Method under test: {@link CritereJpaAdapter#purge()}
     */
    @Test
    void testPurge() {
        doNothing().when(impactReseauJpaAdapter).purge();
        doNothing().when(impactEquipementJpaAdapter).purge();
        doNothing().when(mixElectriqueJpaAdapter).purge();
        doNothing().when(impactMessagerieJpaAdapter).purge();
        doNothing().when(critereRepository).deleteAll();
        critereJpaAdapter.purge();

        // Purge des données filles
        verify(impactReseauJpaAdapter, times(0)).purge();
        verify(impactEquipementJpaAdapter, times(0)).purge();
        verify(mixElectriqueJpaAdapter, times(0)).purge();
        verify(impactMessagerieJpaAdapter, times(0)).purge();

        verify(critereRepository).deleteAll();
        assertTrue(critereJpaAdapter.getAll().isEmpty());
    }

    /**
     * Method under test: {@link CritereJpaAdapter#getAll()}
     */
    @Test
    void testGetAll() {
        ArrayList<Critere> critereList = new ArrayList<>();
        when(critereMapper.toDomains((List<CritereEntity>) any())).thenReturn(critereList);
        when(critereRepository.findAll()).thenReturn(new ArrayList<>());
        List<Critere> actualAll = critereJpaAdapter.getAll();
        assertSame(critereList, actualAll);
        assertTrue(actualAll.isEmpty());
        verify(critereMapper).toDomains((List<CritereEntity>) any());
        verify(critereRepository).findAll();
    }
}

