package tech.easyflow.skill.publish;

import org.junit.Test;
import org.mockito.MockedStatic;
import tech.easyflow.ai.publish.AiResourceLifecycleService;
import tech.easyflow.approval.enums.ApprovalActionType;
import tech.easyflow.approval.enums.ApprovalResourceType;
import tech.easyflow.common.entity.LoginAccount;
import tech.easyflow.common.satoken.util.SaTokenUtil;
import tech.easyflow.common.web.exceptions.BusinessException;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;

/**
 * {@link SkillPublishAppService} 发布说明契约测试。
 */
public class SkillPublishAppServiceTest {

    /**
     * 发布说明必须包含可见字符。
     */
    @Test
    public void rejectsBlankPublishReason() {
        SkillPublishAppService service = new SkillPublishAppService(mock(AiResourceLifecycleService.class));

        BusinessException exception = assertThrows(BusinessException.class,
                () -> service.submitPublishApproval(BigInteger.ONE, "  \n "));

        assertEquals("发布说明不能为空", exception.getMessage());
    }

    /**
     * 发布说明最长为 500 个字符。
     */
    @Test
    public void rejectsPublishReasonLongerThanLimit() {
        SkillPublishAppService service = new SkillPublishAppService(mock(AiResourceLifecycleService.class));

        BusinessException exception = assertThrows(BusinessException.class,
                () -> service.submitPublishApproval(BigInteger.ONE, "a".repeat(501)));

        assertEquals("发布说明不能超过 500 个字符", exception.getMessage());
    }

    /**
     * 提交发布时会规范化说明并透传登录身份。
     */
    @Test
    public void trimsAndForwardsPublishReason() {
        AiResourceLifecycleService lifecycleService = mock(AiResourceLifecycleService.class);
        SkillPublishAppService service = new SkillPublishAppService(lifecycleService);
        LoginAccount account = new LoginAccount();
        account.setId(BigInteger.valueOf(7));
        account.setTenantId(BigInteger.ONE);

        try (MockedStatic<SaTokenUtil> saToken = mockStatic(SaTokenUtil.class)) {
            saToken.when(SaTokenUtil::getLoginAccount).thenReturn(account);
            service.submitPublishApproval(BigInteger.valueOf(101), "  首次发布  ");
        }

        verify(lifecycleService).submitAction(
                ApprovalResourceType.SKILL.getCode(),
                BigInteger.valueOf(101),
                ApprovalActionType.PUBLISH.getCode(),
                BigInteger.valueOf(7),
                "首次发布");
    }
}
