package com.ruoyi.web.modules.news.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.util.Collections;
import org.junit.jupiter.api.DisplayName;
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 com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.diagnosis.domain.BizMedicalResource;
import com.ruoyi.web.modules.diagnosis.mapper.BizMedicalResourceMapper;
import com.ruoyi.web.modules.diagnosis.support.MedicalResourceRules;
import com.ruoyi.web.modules.farming.domain.BizTechResource;
import com.ruoyi.web.modules.farming.mapper.BizTechResourceMapper;
import com.ruoyi.web.modules.farming.support.TechResourceRules;
import com.ruoyi.web.modules.news.LivestockResourceTestSamples;
import com.ruoyi.web.modules.news.domain.LivestockResourceQuery;
import com.ruoyi.web.modules.news.mapper.LivestockResourceMapper;
import com.ruoyi.web.modules.news.service.impl.LivestockResourceServiceImpl;
import com.ruoyi.web.modules.news.support.LivestockResourceRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("畜牧资源 Service")
class LivestockResourceServiceImplTest
{
    @Mock
    private LivestockResourceMapper livestockResourceMapper;

    @Mock
    private BizMedicalResourceMapper bizMedicalResourceMapper;

    @Mock
    private BizTechResourceMapper bizTechResourceMapper;

    @InjectMocks
    private LivestockResourceServiceImpl livestockResourceService;

    @Test
    @DisplayName("按 type 查询并映射列表项")
    void selectList_mapsVo()
    {
        when(livestockResourceMapper.selectLivestockResourceList(any(LivestockResourceQuery.class)))
                .thenReturn(Collections.singletonList(LivestockResourceTestSamples.sampleRow()));
        assertEquals(1, livestockResourceService.selectLivestockResourceList(LivestockResourceTestSamples.listQuery()).size());
    }

    @Test
    @DisplayName("无数据返回空列表")
    void selectList_empty()
    {
        when(livestockResourceMapper.selectLivestockResourceList(any(LivestockResourceQuery.class)))
                .thenReturn(Collections.emptyList());
        assertTrue(livestockResourceService.selectLivestockResourceList(LivestockResourceTestSamples.listQuery()).isEmpty());
    }

    @Test
    @DisplayName("详情 type=1 返回医疗实体")
    void detailMedical()
    {
        BizMedicalResource row = LivestockResourceTestSamples.sampleMedicalDetail();
        when(bizMedicalResourceMapper.selectBizMedicalResourceById(11L)).thenReturn(row);
        Object result = livestockResourceService.selectLivestockResourceById(11L, LivestockResourceRules.SOURCE_MEDICAL);
        assertSame(row, result);
    }

    @Test
    @DisplayName("详情 type=2 返回科技实体")
    void detailTech()
    {
        BizTechResource row = LivestockResourceTestSamples.sampleTechDetail();
        when(bizTechResourceMapper.selectBizTechResourceById(22L)).thenReturn(row);
        Object result = livestockResourceService.selectLivestockResourceById(22L, LivestockResourceRules.SOURCE_TECH);
        assertSame(row, result);
    }

    @Test
    @DisplayName("详情不存在")
    void detailNotFound()
    {
        when(bizTechResourceMapper.selectBizTechResourceById(9L)).thenReturn(null);
        ServiceException ex = assertThrows(ServiceException.class,
                () -> livestockResourceService.selectLivestockResourceById(9L, LivestockResourceRules.SOURCE_TECH));
        assertEquals(LivestockResourceRules.NOT_FOUND_MSG, ex.getMessage());
    }

    @Test
    @DisplayName("详情未发布不可见")
    void detailNotPublished()
    {
        BizTechResource row = LivestockResourceTestSamples.sampleTechDetail();
        row.setPublishStatus(TechResourceRules.PUBLISH_STATUS_DRAFT);
        when(bizTechResourceMapper.selectBizTechResourceById(22L)).thenReturn(row);
        assertThrows(ServiceException.class,
                () -> livestockResourceService.selectLivestockResourceById(22L, LivestockResourceRules.SOURCE_TECH));
    }
}
