liu
9 小时以前 da93fafc417b4f590b6ab639ccbbe67c14c8753c
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package cn.iocoder.yudao.module.mes.framework.qrcode;
 
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO;
import cn.iocoder.yudao.module.mes.framework.config.MesTraceConfigSnapshot;
import cn.iocoder.yudao.module.mes.framework.config.MesTraceUrlSource;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
 
import java.util.Map;
 
import static org.junit.jupiter.api.Assertions.*;
 
/**
 * 标签构建器的配置来源测试。
 * <p>
 * 构建器是静态工具类,配置来源通过 {@link MesTraceConfigProvider} 装配。这里重点验证
 * 「配置来源优先、配置文件兜底、两者皆无则拒绝导出」这条链路,以及标签可读文本与
 * 二维码内容取到的是同一个追溯网址。
 */
class MesProQrLabelBuilderTest {
 
    private static final String YAML_URL = "http://yaml.example.org/trace.html";
    private static final String DICT_URL = "http://1.95.78.124:9008/prod/trace.html";
 
    @AfterEach
    void resetStaticState() {
        // 构建器的配置是静态字段,不清干净会串味到其它测试
        MesProQrLabelBuilder.setTraceConfigProvider(null);
        MesProQrLabelBuilder.setTraceBaseUrl("");
        MesProQrLabelBuilder.setOperatorName("");
        MesProQrLabelBuilder.setImporterName("");
        MesProQrLabelBuilder.setImported(false);
        MesProQrLabelBuilder.setAllowPlainQrCode(false);
    }
 
    @Test
    void providerValueWinsOverConfiguredFile() {
        MesProQrLabelBuilder.setTraceBaseUrl(YAML_URL);
        MesProQrLabelBuilder.setOperatorName("生产经营者");
        useProvider(snapshot(DICT_URL, "生产经营者", "", false));
 
        assertEquals(DICT_URL, MesProQrLabelBuilder.resolveTraceUrl());
    }
 
    @Test
    void fallsBackToConfiguredFileWhenProviderAbsent() {
        MesProQrLabelBuilder.setTraceBaseUrl(YAML_URL);
 
        // 未装配配置来源(单测 / 非 Spring 上下文)时应回退配置文件
        assertEquals(YAML_URL, MesProQrLabelBuilder.resolveTraceUrl());
    }
 
    @Test
    void blankProviderValueDoesNotEraseConfiguredFile() {
        MesProQrLabelBuilder.setTraceBaseUrl(YAML_URL);
        useProvider(snapshot("", "生产经营者", "", false));
 
        // 配置来源只应「补充」,不应把兜底值抹成空
        assertEquals(YAML_URL, MesProQrLabelBuilder.resolveTraceUrl());
    }
 
    @Test
    void bagLabelPrintsSameUrlAsItsQrCode() {
        MesProQrLabelBuilder.setOperatorName("生产经营者");
        useProvider(snapshot(DICT_URL, "生产经营者", "", false));
 
        QrLabelInfo label = MesProQrLabelBuilder.buildBagCodeLabel(bagCode(), null, Map.of(), Map.of());
 
        // 可读文本与二维码内容必须是同一个网址,否则标签会自相矛盾
        assertEquals(DICT_URL, label.getKeyValues().get("追溯网址"));
        assertEquals(DICT_URL + "?code=12345678901234567890", label.getCode());
    }
 
    @Test
    void importedSceneLabelsImporterName() {
        useProvider(snapshot(DICT_URL, "生产经营者", "某进口商", true));
 
        QrLabelInfo label = MesProQrLabelBuilder.buildBagCodeLabel(bagCode(), null, Map.of(), Map.of());
 
        assertEquals("某进口商", label.getKeyValues().get("进口商名称"));
        assertNull(label.getKeyValues().get("生产经营者名称"));
    }
 
    @Test
    void rejectsExportWhenNeitherSourceHasUrl() {
        MesProQrLabelBuilder.setOperatorName("生产经营者");
        useProvider(snapshot("", "生产经营者", "", false));
 
        // 四要素缺失即拒绝导出:这是标签合规的最后一道闸门,绝不能静默降级
        assertThrows(ServiceException.class,
                () -> MesProQrLabelBuilder.buildBagCodeLabel(bagCode(), null, Map.of(), Map.of()));
    }
 
    @Test
    void providerCannotBypassElementValidation() {
        // 即使配置来源给了网址,生产经营者名称缺失仍须拒绝导出
        useProvider(snapshot(DICT_URL, "", "", false));
 
        assertThrows(ServiceException.class,
                () -> MesProQrLabelBuilder.buildBagCodeLabel(bagCode(), null, Map.of(), Map.of()));
    }
 
    private static void useProvider(MesTraceConfigSnapshot snapshot) {
        MesProQrLabelBuilder.setTraceConfigProvider(() -> snapshot);
    }
 
    private static MesTraceConfigSnapshot snapshot(String traceUrl, String operatorName,
                                                   String importerName, boolean imported) {
        return new MesTraceConfigSnapshot(traceUrl, MesTraceUrlSource.DICT, operatorName, importerName, imported);
    }
 
    private static MesProBagCodeDO bagCode() {
        return new MesProBagCodeDO().setCode("12345678901234567890").setItemName("新陆早78号");
    }
 
}