package cn.novalon.manage.sys.core.service.impl;

import cn.novalon.manage.sys.core.domain.SysDictData;
import cn.novalon.manage.sys.core.repository.ISysDictDataRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import java.time.LocalDateTime;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class SysDictDataServiceTest {

    @Mock
    private ISysDictDataRepository repository;

    private SysDictDataService dictDataService;
    private SysDictData testDictData;

    @BeforeEach
    void setUp() {
        dictDataService = new SysDictDataService(repository);
        
        testDictData = new SysDictData();
        testDictData.setId(1L);
        testDictData.setDictTypeId(1L);
        testDictData.setDictLabel("正常");
        testDictData.setDictValue("1");
        testDictData.setDictSort(1);
        testDictData.setDictType("sys_status");
        testDictData.setStatus("0");
        testDictData.setCreatedAt(LocalDateTime.now());
    }

    @Test
    void testFindAll() {
        when(repository.findByDeletedAtIsNull()).thenReturn(Flux.just(testDictData));
        
        Flux<SysDictData> result = dictDataService.findAll();
        
        StepVerifier.create(result)
                .expectNext(testDictData)
                .verifyComplete();
        
        verify(repository).findByDeletedAtIsNull();
    }

    @Test
    void testFindByDictType() {
        when(repository.findByDictTypeAndDeletedAtIsNull("sys_status")).thenReturn(Flux.just(testDictData));
        
        Flux<SysDictData> result = dictDataService.findByDictType("sys_status");
        
        StepVerifier.create(result)
                .expectNext(testDictData)
                .verifyComplete();
        
        verify(repository).findByDictTypeAndDeletedAtIsNull("sys_status");
    }

    @Test
    void testFindByDictTypeAndStatus() {
        when(repository.findByDictTypeAndStatusAndDeletedAtIsNull("sys_status", "0")).thenReturn(Flux.just(testDictData));
        
        Flux<SysDictData> result = dictDataService.findByDictTypeAndStatus("sys_status", "0");
        
        StepVerifier.create(result)
                .expectNext(testDictData)
                .verifyComplete();
        
        verify(repository).findByDictTypeAndStatusAndDeletedAtIsNull("sys_status", "0");
    }

    @Test
    void testFindById() {
        when(repository.findById(1L)).thenReturn(Mono.just(testDictData));
        
        Mono<SysDictData> result = dictDataService.findById(1L);
        
        StepVerifier.create(result)
                .expectNext(testDictData)
                .verifyComplete();
        
        verify(repository).findById(1L);
    }

    @Test
    void testSave() {
        when(repository.save(any(SysDictData.class))).thenReturn(Mono.just(testDictData));
        
        Mono<SysDictData> result = dictDataService.save(testDictData);
        
        StepVerifier.create(result)
                .expectNext(testDictData)
                .verifyComplete();
        
        verify(repository).save(any(SysDictData.class));
    }

    @Test
    void testDeleteById() {
        when(repository.deleteByIdAndDeletedAtIsNull(1L)).thenReturn(Mono.empty());
        
        Mono<Void> result = dictDataService.deleteById(1L);
        
        StepVerifier.create(result)
                .verifyComplete();
        
        verify(repository).deleteByIdAndDeletedAtIsNull(1L);
    }
}