5 小时以前 9bad721754fe8bbe2e5f459d0706e0fefac569f3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package cn.iocoder.yudao.module.qcreport.engine;
 
import cn.iocoder.yudao.module.qcreport.dal.dataobject.version.ReportTemplateSchema;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
 
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
 
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
 
/**
 * {@link QualityReportEngine#hasCanvas} 的判据测试。
 * <p>
 * 这条判据同时守着两处:出报告弹窗要不要把这个模板摆出来({@code getSelectableTemplates}),
 * 以及出件前要不要直接拒绝({@code resolveVersion})。它必须与渲染器读画布的那一行
 * ({@code pages[0].frames[0].component})严格一致——放宽一点,用户就会拿到一张不报错的白纸 PDF。
 */
class QualityReportEngineTest {
 
    private static final ObjectMapper MAPPER = new ObjectMapper();
 
    private static final String CANVAS_DIR = "qcreport/canvas/";
 
    @Test
    @DisplayName("只有元数据的画布不算有内容:它是非空 Map,但渲染器取不到根组件,渲染出来是白纸")
    void metadataOnlyGrapesIsNotCanvas() {
        // GrapesJS 把「打开过设计器但一个组件都没放」的项目存成这个样子
        assertFalse(QualityReportEngine.hasCanvas(schema(Map.of("assets", List.of(), "styles", List.of()))));
        // 只多了 pages 但没有 frames 也不行
        assertFalse(QualityReportEngine.hasCanvas(schema(Map.of("pages", List.of()))));
        // 有 frame 但没有 component 同样不行
        assertFalse(QualityReportEngine.hasCanvas(schema(Map.of("pages",
                List.of(Map.of("frames", List.of(Map.of("id", "f1"))))))));
    }
 
    @Test
    @DisplayName("frame 上有根组件才算有内容")
    void frameComponentIsCanvas() {
        assertTrue(QualityReportEngine.hasCanvas(schema(Map.of("pages",
                List.of(Map.of("frames", List.of(Map.of("component",
                        Map.of("type", "wrapper", "components", List.of())))))))));
    }
 
    @Test
    @DisplayName("Schema 或 grapes 为 null 不算有内容,且不抛错")
    void nullSchemaOrGrapesIsNotCanvas() {
        assertFalse(QualityReportEngine.hasCanvas(null));
        assertFalse(QualityReportEngine.hasCanvas(new ReportTemplateSchema()));
        assertFalse(QualityReportEngine.hasCanvas(schema(null)));
    }
 
    @ParameterizedTest(name = "存量画布 {0} 有内容")
    @ValueSource(strings = {"canvas-t5-v1.0.json", "canvas-t3-v1.0.json", "canvas-t5-v1.1.json", "canvas-t5-v1.2.json"})
    @DisplayName("运行库里真正画了东西的版本,判据为真")
    void realStoredCanvasIsCanvas(String fileName) throws IOException {
        assertTrue(QualityReportEngine.hasCanvas(schema(realGrapes(fileName))), fileName);
    }
 
    @ParameterizedTest(name = "存量空画布 {0} 无内容")
    @ValueSource(strings = {"canvas-t1-v1.0.json", "canvas-t1-v1.1.json"})
    @DisplayName("运行库里「打开过但没放组件」的版本,判据为假(它就是白纸 PDF 的来源)")
    void realStoredEmptyCanvasIsNotCanvas(String fileName) throws IOException {
        assertFalse(QualityReportEngine.hasCanvas(schema(realGrapes(fileName))), fileName);
    }
 
    private static ReportTemplateSchema schema(Map<String, Object> grapes) {
        ReportTemplateSchema schema = new ReportTemplateSchema();
        schema.setGrapes(grapes);
        return schema;
    }
 
    @SuppressWarnings("unchecked")
    private static Map<String, Object> realGrapes(String fileName) throws IOException {
        String path = CANVAS_DIR + fileName;
        try (InputStream in = QualityReportEngineTest.class.getClassLoader().getResourceAsStream(path)) {
            if (in == null) {
                throw new IOException("找不到画布夹具:" + path);
            }
            Map<String, Object> full = MAPPER.readValue(new String(in.readAllBytes(), StandardCharsets.UTF_8),
                    new TypeReference<Map<String, Object>>() {
                    });
            Object grapes = full.get("grapes");
            return grapes instanceof Map<?, ?> ? (Map<String, Object>) grapes : null;
        }
    }
 
}