SkillServiceTest.java 4.15 KB
package com.xly.service;

import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

/** skill 文件加载:5 个技能齐全、首行为用途、正文非空、模糊名可命中。 */
class SkillServiceTest {

    private final SkillService skills = new SkillService(null); // jdbc 未装配 → 按表不存在 → classpath 模式

    @Test
    void allFiveSkillsLoadFromClasspath() {
        List<SkillService.Skill> all = skills.all();
        assertEquals(5, all.size());
        for (String name : new String[]{"查询数据", "新建报价", "新建单据", "修改记录", "单据状态操作"}) {
            SkillService.Skill s = skills.find(name);
            assertNotNull(s, name + " 必须存在");
            assertTrue(s.brief().length() > 4, "首行=一句话用途");
            assertTrue(s.body().contains("【技能:"), "正文为技能全文");
        }
    }

    @Test
    void fuzzyNameMatches() {
        assertEquals("新建报价", skills.find("新建报价单").name(), "「新建报价单」→ 新建报价");
        assertEquals("修改记录", skills.find("修改").name());
        assertNull(skills.find("不存在的技能"));
    }

    @Test
    void indexHasOneLinePerSkill() {
        String idx = skills.indexLines();
        assertEquals(5, idx.strip().split("\n").length);
        assertTrue(idx.contains("- 新建报价:"));
    }

    // ---------------- DB 全权模式(表存在开关) ----------------

    private org.springframework.jdbc.core.JdbcTemplate jdbcWithTable(boolean exists) {
        org.springframework.jdbc.core.JdbcTemplate jdbc =
                org.mockito.Mockito.mock(org.springframework.jdbc.core.JdbcTemplate.class);
        org.mockito.Mockito.when(jdbc.queryForObject(
                        org.mockito.ArgumentMatchers.contains("information_schema"),
                        org.mockito.ArgumentMatchers.eq(Integer.class)))
                .thenReturn(exists ? 1 : 0);
        return jdbc;
    }

    @Test
    void tableExistsMeansDbOnlyEvenIfEmpty() {
        org.springframework.jdbc.core.JdbcTemplate jdbc = jdbcWithTable(true);
        org.mockito.Mockito.when(jdbc.queryForList(org.mockito.ArgumentMatchers.startsWith("SELECT sName")))
                .thenReturn(java.util.List.of());
        SkillService s = new SkillService(jdbc);
        assertTrue(s.all().isEmpty(), "空表 = 用户要的无技能场景,绝不回读 war 包");
        assertTrue(s.indexLines().isBlank());
        assertNull(s.find("新建报价"));
    }

    @Test
    void tableExistsLoadsCustomSkillsFromDb() {
        org.springframework.jdbc.core.JdbcTemplate jdbc = jdbcWithTable(true);
        org.mockito.Mockito.when(jdbc.queryForList(org.mockito.ArgumentMatchers.startsWith("SELECT sName")))
                .thenReturn(java.util.List.of(java.util.Map.of(
                        "sName", "自定义流程", "sBrief", "用户自定义", "sBody", "【技能:自定义流程】1. 步骤")));
        SkillService s = new SkillService(jdbc);
        assertEquals(1, s.all().size(), "DB 有 1 行 = 只读这 1 行,不合并 war 包");
        assertEquals("自定义流程", s.find("自定义").name());
    }

    @Test
    void dbFailureDegradesToNoSkillsNotClasspath() {
        org.springframework.jdbc.core.JdbcTemplate jdbc =
                org.mockito.Mockito.mock(org.springframework.jdbc.core.JdbcTemplate.class);
        org.mockito.Mockito.when(jdbc.queryForObject(
                        org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.eq(Integer.class)))
                .thenThrow(new RuntimeException("db down"));
        SkillService s = new SkillService(jdbc);
        assertTrue(s.all().isEmpty(), "DB 故障按无技能降级,绝不回落 war 包");
    }

    @Test
    void tableAbsentFallsBackToClasspath() {
        SkillService s = new SkillService(jdbcWithTable(false));
        assertEquals(5, s.all().size(), "表不存在 → 读 war 包内置技能");
    }
}