package co.yixiang.yshop.module.member.service.userlevelequityref;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;

import javax.annotation.Resource;

import co.yixiang.yshop.framework.test.core.ut.BaseDbUnitTest;

import co.yixiang.yshop.module.member.controller.admin.userlevelequityref.vo.*;
import co.yixiang.yshop.module.member.dal.dataobject.userlevelequityref.UserLevelEquityRefDO;
import co.yixiang.yshop.module.member.dal.mysql.userlevelequityref.UserLevelEquityRefMapper;
import co.yixiang.yshop.framework.common.pojo.PageResult;

import javax.annotation.Resource;

import org.springframework.context.annotation.Import;

import java.util.*;
import java.time.LocalDateTime;

import static cn.hutool.core.util.RandomUtil.*;
import static co.yixiang.yshop.module.member.enums.ErrorCodeConstants.*;
import static co.yixiang.yshop.framework.test.core.util.AssertUtils.*;
import static co.yixiang.yshop.framework.test.core.util.RandomUtils.*;
import static co.yixiang.yshop.framework.common.util.date.LocalDateTimeUtils.*;
import static co.yixiang.yshop.framework.common.util.object.ObjectUtils.*;
import static co.yixiang.yshop.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

/**
 * {@link UserLevelEquityRefServiceImpl} 的单元测试类
 *
 * @author admin
 */
@Import(UserLevelEquityRefServiceImpl.class)
public class UserLevelEquityRefServiceImplTest extends BaseDbUnitTest {

    @Resource
    private UserLevelEquityRefServiceImpl userLevelEquityRefService;

    @Resource
    private UserLevelEquityRefMapper userLevelEquityRefMapper;

    @Test
    public void testCreateUserLevelEquityRef_success() {
        // 准备参数
        UserLevelEquityRefCreateReqVO reqVO = randomPojo(UserLevelEquityRefCreateReqVO.class);

        // 调用
        Long userLevelEquityRefId = userLevelEquityRefService.createUserLevelEquityRef(reqVO);
        // 断言
        assertNotNull(userLevelEquityRefId);
        // 校验记录的属性是否正确
        UserLevelEquityRefDO userLevelEquityRef = userLevelEquityRefMapper.selectById(userLevelEquityRefId);
        assertPojoEquals(reqVO, userLevelEquityRef);
    }

    @Test
    public void testUpdateUserLevelEquityRef_success() {
        // mock 数据
        UserLevelEquityRefDO dbUserLevelEquityRef = randomPojo(UserLevelEquityRefDO.class);
        userLevelEquityRefMapper.insert(dbUserLevelEquityRef);// @Sql: 先插入出一条存在的数据
        // 准备参数
        UserLevelEquityRefUpdateReqVO reqVO = randomPojo(UserLevelEquityRefUpdateReqVO.class, o -> {
            o.setId(dbUserLevelEquityRef.getId()); // 设置更新的 ID
        });

        // 调用
        userLevelEquityRefService.updateUserLevelEquityRef(reqVO);
        // 校验是否更新正确
        UserLevelEquityRefDO userLevelEquityRef = userLevelEquityRefMapper.selectById(reqVO.getId()); // 获取最新的
        assertPojoEquals(reqVO, userLevelEquityRef);
    }

    @Test
    public void testUpdateUserLevelEquityRef_notExists() {
        // 准备参数
        UserLevelEquityRefUpdateReqVO reqVO = randomPojo(UserLevelEquityRefUpdateReqVO.class);

        // 调用, 并断言异常
        assertServiceException(() -> userLevelEquityRefService.updateUserLevelEquityRef(reqVO), USER_LEVEL_EQUITY_REF_NOT_EXISTS);
    }

    @Test
    public void testDeleteUserLevelEquityRef_success() {
        // mock 数据
        UserLevelEquityRefDO dbUserLevelEquityRef = randomPojo(UserLevelEquityRefDO.class);
        userLevelEquityRefMapper.insert(dbUserLevelEquityRef);// @Sql: 先插入出一条存在的数据
        // 准备参数
        Long id = dbUserLevelEquityRef.getId();

        // 调用
        userLevelEquityRefService.deleteUserLevelEquityRef(id);
        // 校验数据不存在了
        assertNull(userLevelEquityRefMapper.selectById(id));
    }

    @Test
    public void testDeleteUserLevelEquityRef_notExists() {
        // 准备参数
        Long id = randomLongId();

        // 调用, 并断言异常
        assertServiceException(() -> userLevelEquityRefService.deleteUserLevelEquityRef(id), USER_LEVEL_EQUITY_REF_NOT_EXISTS);
    }

    @Test
    @Disabled  // TODO 请修改 null 为需要的值，然后删除 @Disabled 注解
    public void testGetUserLevelEquityRefPage() {
        // mock 数据
        UserLevelEquityRefDO dbUserLevelEquityRef = randomPojo(UserLevelEquityRefDO.class, o -> { // 等会查询到
            o.setLevelId(null);
            o.setEquityId(null);
            o.setCreateTime(null);
        });
        userLevelEquityRefMapper.insert(dbUserLevelEquityRef);
        // 测试 levelId 不匹配
        userLevelEquityRefMapper.insert(cloneIgnoreId(dbUserLevelEquityRef, o -> o.setLevelId(null)));
        // 测试 equityId 不匹配
        userLevelEquityRefMapper.insert(cloneIgnoreId(dbUserLevelEquityRef, o -> o.setEquityId(null)));
        // 测试 createTime 不匹配
        userLevelEquityRefMapper.insert(cloneIgnoreId(dbUserLevelEquityRef, o -> o.setCreateTime(null)));
        // 准备参数
        UserLevelEquityRefPageReqVO reqVO = new UserLevelEquityRefPageReqVO();
        reqVO.setLevelId(null);
        reqVO.setEquityId(null);
        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));

        // 调用
        PageResult<UserLevelEquityRefDO> pageResult = userLevelEquityRefService.getUserLevelEquityRefPage(reqVO);
        // 断言
        assertEquals(1, pageResult.getTotal());
        assertEquals(1, pageResult.getList().size());
        assertPojoEquals(dbUserLevelEquityRef, pageResult.getList().get(0));
    }

    @Test
    @Disabled  // TODO 请修改 null 为需要的值，然后删除 @Disabled 注解
    public void testGetUserLevelEquityRefList() {
        // mock 数据
        UserLevelEquityRefDO dbUserLevelEquityRef = randomPojo(UserLevelEquityRefDO.class, o -> { // 等会查询到
            o.setLevelId(null);
            o.setEquityId(null);
            o.setCreateTime(null);
        });
        userLevelEquityRefMapper.insert(dbUserLevelEquityRef);
        // 测试 levelId 不匹配
        userLevelEquityRefMapper.insert(cloneIgnoreId(dbUserLevelEquityRef, o -> o.setLevelId(null)));
        // 测试 equityId 不匹配
        userLevelEquityRefMapper.insert(cloneIgnoreId(dbUserLevelEquityRef, o -> o.setEquityId(null)));
        // 测试 createTime 不匹配
        userLevelEquityRefMapper.insert(cloneIgnoreId(dbUserLevelEquityRef, o -> o.setCreateTime(null)));
        // 准备参数
        UserLevelEquityRefExportReqVO reqVO = new UserLevelEquityRefExportReqVO();
        reqVO.setLevelId(null);
        reqVO.setEquityId(null);
        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));

        // 调用
        List<UserLevelEquityRefDO> list = userLevelEquityRefService.getUserLevelEquityRefList(reqVO);
        // 断言
        assertEquals(1, list.size());
        assertPojoEquals(dbUserLevelEquityRef, list.get(0));
    }

}
