package incheon.product.geoview2d.basemap.service.impl;

import incheon.product.geoview2d.basemap.mapper.BasemapMapper;
import incheon.product.geoview2d.basemap.vo.BasemapVO;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * BasemapServiceImpl 단위 테스트.
 * 배경지도 CRUD 위임 로직을 검증한다.
 */
@ExtendWith(MockitoExtension.class)
class BasemapServiceImplTest {

    @InjectMocks
    private BasemapServiceImpl basemapService;

    @Mock
    private BasemapMapper basemapMapper;

    @Nested
    @DisplayName("조회 메서드")
    class ReadMethods {

        @Test
        @DisplayName("getById는 mapper에 위임한다")
        void getById() {
            BasemapVO expected = new BasemapVO();
            when(basemapMapper.findById("base1")).thenReturn(expected);

            assertThat(basemapService.getById("base1")).isEqualTo(expected);
            verify(basemapMapper).findById("base1");
        }

        @Test
        @DisplayName("getActiveList는 mapper.findAll에 위임한다")
        void getActiveList() {
            List<BasemapVO> expected = List.of(new BasemapVO());
            when(basemapMapper.findAll()).thenReturn(expected);

            assertThat(basemapService.getActiveList()).isEqualTo(expected);
        }

        @Test
        @DisplayName("getList는 페이징 offset을 계산한다")
        void getListPaging() {
            when(basemapMapper.findAllWithPaging("kw", 10, 10)).thenReturn(List.of());

            basemapService.getList("kw", 2, 10);

            verify(basemapMapper).findAllWithPaging("kw", 10, 10);
        }

        @Test
        @DisplayName("getTotalCount는 mapper.count에 위임한다")
        void getTotalCount() {
            when(basemapMapper.count("test")).thenReturn(3);
            assertThat(basemapService.getTotalCount("test")).isEqualTo(3);
        }
    }

    @Nested
    @DisplayName("CUD 메서드")
    class CudMethods {

        @Test
        @DisplayName("create는 mapper.insert에 위임한다")
        void create() {
            BasemapVO vo = new BasemapVO();
            basemapService.create(vo);
            verify(basemapMapper).insert(vo);
        }

        @Test
        @DisplayName("update는 mapper.update에 위임한다")
        void update() {
            BasemapVO vo = new BasemapVO();
            basemapService.update(vo);
            verify(basemapMapper).update(vo);
        }

        @Test
        @DisplayName("delete는 mapper.delete에 위임한다")
        void delete() {
            basemapService.delete("base1");
            verify(basemapMapper).delete("base1");
        }
    }
}
