package jnpf.onlinedev.util; import jnpf.onlinedev.model.FormDisplaySchema; import org.junit.jupiter.api.Test; import java.util.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; class FormDisplayValueServiceTest { @Test void approvalDateControlsOverrideMainAndChildFormTimeFormats() { OnlineSwapDataUtils platform = mock(OnlineSwapDataUtils.class); doAnswer(call -> { List fields = call.getArgument(1); assertEquals("yyyy-MM-dd", fields.get(0).getFormat()); assertEquals("yyyy-MM-dd", fields.get(1).getFormat()); assertEquals("yyyy-MM-dd", fields.get(2).getConfig().getChildren().get(0).getFormat()); return call.getArgument(0); }).when(platform).getSwapInfoStrict(anyList(), anyList(), eq("form")); new FormDisplayValueService(platform).convert("form", """ {"fields":[ {"__vModel__":"date","format":"yyyy/MM/dd HH:mm:ss","__config__":{"jnpfKey":"datePicker"}}, {"__vModel__":"created","__config__":{"jnpfKey":"createTime"}}, {"__vModel__":"rows","__config__":{"jnpfKey":"table","children":[ {"__vModel__":"modified","__config__":{"jnpfKey":"modifyTime"}}]}}]} """, Map.of()); verify(platform).getSwapInfoStrict(anyList(), anyList(), eq("form")); } @Test void publishedOrganizeControlResolvesBothChildRowsAndKeepsNullCopies() throws Exception { String configuration; try (var resource = getClass().getResourceAsStream("/qianpiye/distribution-form.json")) { configuration = new String(Objects.requireNonNull(resource).readAllBytes(), java.nio.charset.StandardCharsets.UTF_8); } var schema = FormDisplaySchema.parse(configuration); assertTrue(schema.get(0).isSupported()); assertTrue(schema.get(0).isReference()); assertEquals("fenfa_bumen_mingxi.bumen_id", schema.get(0).getPath()); OnlineSwapDataUtils platform = mock(OnlineSwapDataUtils.class, CALLS_REAL_METHODS); OnlineExecutor executor = mock(OnlineExecutor.class); org.springframework.test.util.ReflectionTestUtils.setField(platform, "executor", executor); doAnswer(call -> { Map cache = call.getArgument(0); cache.put("__orgTree_map", Map.of("org-a", "质量部", "org-b", "生产部")); return null; }).when(executor).executorRedis(anyMap(), anyList(), anyString(), anyBoolean(), anyList(), nullable(Map.class)); Map first = new LinkedHashMap<>(); first.put("bumen_id", "org-a"); first.put("fenshu", null); Map raw = Map.of("fenfa_bumen_mingxi", List.of(first, Map.of("bumen_id", "org-b", "fenshu", 10))); try (var ignored = mockStatic(jnpf.database.util.DynamicDataSourceUtil.class)) { Map display = new FormDisplayValueService(platform).convert("form", configuration, raw); List> rows = (List>) display.get("fenfa_bumen_mingxi"); assertEquals("质量部", rows.get(0).get("bumen_id")); assertEquals("生产部", rows.get(1).get("bumen_id")); assertNull(rows.get(0).get("fenshu")); assertEquals("10", String.valueOf(rows.get(1).get("fenshu"))); assertEquals("org-a", first.get("bumen_id")); } } @Test void discoversNewFieldsInsideLayoutsAndIdentifiesUnsupportedControls() { List fields = FormDisplaySchema.parse("{\"fields\":[" + "{\"__vModel__\":\"layout\",\"__config__\":{\"jnpfKey\":\"row\",\"children\":[" + "{\"__vModel__\":\"brand_new\",\"__config__\":{\"jnpfKey\":\"depSelect\"}}," + "{\"__vModel__\":\"image\",\"__config__\":{\"jnpfKey\":\"uploadImg\"}}," + "{\"__vModel__\":\"biz_sign\",\"__config__\":{}}]}}]}"); assertEquals(2, fields.size()); assertEquals("brand_new", fields.get(0).getPath()); assertTrue(fields.get(0).isSupported()); assertFalse(fields.get(1).isSupported()); } @Test void convertsDynamicDepartmentThroughPlatformWithoutMutatingRawData() { OnlineSwapDataUtils platform = mock(OnlineSwapDataUtils.class); doAnswer(call -> { List> rows = call.getArgument(0); rows.get(0).put("new_department", "质量部"); return rows; }).when(platform).getSwapInfoStrict(anyList(), anyList(), eq("form-2")); Map raw = Map.of("new_department", "12345"); Map display = new FormDisplayValueService(platform).convert("form-2", "{\"fields\":[{\"__vModel__\":\"new_department\",\"__config__\":{\"jnpfKey\":\"depSelect\"}}]}", raw); assertEquals("质量部", display.get("new_department")); assertEquals("12345", raw.get("new_department")); } @Test void realPlatformConversionResolvesMultiDepartmentsAndStaticOptions() throws Exception { OnlineSwapDataUtils platform = mock(OnlineSwapDataUtils.class, CALLS_REAL_METHODS); java.lang.reflect.Method convert = OnlineSwapDataUtils.class.getDeclaredMethod("writeRedisAndList", Map.class, List.class, String.class, boolean.class, List.class, boolean.class, Map.class, boolean.class); convert.setAccessible(true); List fields = jnpf.util.JsonUtil.getJsonToList( "[{\"__vModel__\":\"departments\",\"multiple\":true,\"__config__\":{\"jnpfKey\":\"organizeSelect\"}}," + "{\"__vModel__\":\"category\",\"props\":{\"label\":\"label\",\"value\":\"value\"}," + "\"__config__\":{\"jnpfKey\":\"select\",\"dataType\":\"static\",\"relationTable\":\"\",\"templateJson\":[]}}]", jnpf.model.visualjson.FieLdsModel.class); Map cache = new HashMap<>(); cache.put("__orgTree_map", Map.of("12345", "质量部", "67890", "生产部")); cache.put("form-category-static", Map.of("a", "技术文件")); Map row = new LinkedHashMap<>(); row.put("departments", "[\"12345\",\"67890\"]"); row.put("category", "a"); convert.invoke(platform, cache, fields, "form", false, List.of(row), false, null, true); assertEquals("质量部;生产部", row.get("departments")); assertEquals("技术文件", row.get("category")); } @Test void strictLookupRejectsPartialMultiSelectionInsteadOfDroppingMissingIds() throws Exception { java.lang.reflect.Method check = OnlineSwapDataUtils.class.getDeclaredMethod("requireDisplayMappings", Map.class, Object.class); check.setAccessible(true); check.invoke(null, Map.of("a", "质量部", "b", "生产部"), "[\"a\",\"b\"]"); java.lang.reflect.InvocationTargetException error = assertThrows(java.lang.reflect.InvocationTargetException.class, () -> check.invoke(null, Map.of("a", "质量部"), "[\"a\",\"deleted\"]")); assertInstanceOf(jnpf.exception.DataException.class, error.getCause()); } }