package tech.easyflow.admin.controller.skill;

import com.mybatisflex.core.query.QueryWrapper;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.lang.reflect.Method;
import java.util.Locale;

import static org.mockito.Answers.CALLS_REAL_METHODS;
import static org.mockito.Mockito.mock;

/**
 * Skill 列表轻量投影的权限字段回归测试。
 */
public class SkillControllerProjectionTenantTest {

    /**
     * 验证列表投影包含内部 tenant_id，以便资源权限派生时不会将合法记录误判为不可读。
     *
     * @throws Exception 反射调用失败时抛出
     */
    @Test
    public void descriptorProjectionShouldIncludeTenantId() throws Exception {
        SkillController controller = mock(SkillController.class, CALLS_REAL_METHODS);
        Method method = SkillController.class.getDeclaredMethod("descriptorQuery");
        method.setAccessible(true);

        QueryWrapper query = (QueryWrapper) method.invoke(controller);

        Assert.assertTrue(query.toSQL().toLowerCase(Locale.ROOT).contains("tenant_id"),
                "Skill descriptor projection 缺少 tenant_id: " + query.toSQL());
    }

    /**
     * 验证列表投影不会加载正文或发布快照等重字段。
     *
     * @throws Exception 反射调用失败时抛出
     */
    @Test
    public void descriptorProjectionShouldExcludeHeavyContent() throws Exception {
        SkillController controller = mock(SkillController.class, CALLS_REAL_METHODS);
        Method method = SkillController.class.getDeclaredMethod("descriptorQuery");
        method.setAccessible(true);

        String sql = ((QueryWrapper) method.invoke(controller)).toSQL().toLowerCase(Locale.ROOT);

        Assert.assertFalse(sql.contains("skill_content"), "列表投影不应加载 SKILL.md 正文: " + sql);
        Assert.assertFalse(sql.contains("published_snapshot_json"), "列表投影不应加载发布快照: " + sql);
    }
}
