|
30 | 30 |
|
31 | 31 | import java.lang.reflect.InvocationTargetException; |
32 | 32 | import java.lang.reflect.Method; |
| 33 | +import java.util.ArrayList; |
33 | 34 | import java.util.Arrays; |
34 | 35 | import java.util.Collections; |
35 | 36 | import java.util.HashMap; |
| 37 | +import java.util.List; |
36 | 38 | import java.util.Map; |
| 39 | +import java.util.concurrent.atomic.AtomicReference; |
| 40 | +import java.util.function.Consumer; |
| 41 | +import java.util.function.Supplier; |
37 | 42 |
|
38 | 43 | import org.assertj.core.api.Assertions; |
39 | 44 | import org.junit.jupiter.api.BeforeEach; |
@@ -186,7 +191,102 @@ void testReplaceTaskCodeForConditionTaskParams_throwsOnInvalidJson() { |
186 | 191 | .hasMessageContaining("Failed to parse Condition task params"); |
187 | 192 | } |
188 | 193 |
|
189 | | - // Reflection Helper |
| 194 | + @Test |
| 195 | + void testReplaceInNodeList_withNullList() throws Exception { |
| 196 | + AtomicReference<List<Long>> stateRef = new AtomicReference<>(null); |
| 197 | + Supplier<List<Long>> getter = stateRef::get; |
| 198 | + Consumer<List<Long>> setter = stateRef::set; |
| 199 | + |
| 200 | + invokeReplaceInNodeList(getter, setter, Collections.emptyMap()); |
| 201 | + |
| 202 | + assertThat(stateRef.get()).isNull(); |
| 203 | + } |
| 204 | + |
| 205 | + @Test |
| 206 | + void testReplaceInNodeList_withEmptyList() throws Exception { |
| 207 | + AtomicReference<List<Long>> stateRef = new AtomicReference<>(new ArrayList<>()); |
| 208 | + Supplier<List<Long>> getter = stateRef::get; |
| 209 | + Consumer<List<Long>> setter = stateRef::set; |
| 210 | + |
| 211 | + invokeReplaceInNodeList(getter, setter, Collections.emptyMap()); |
| 212 | + |
| 213 | + assertThat(stateRef.get()).isEmpty(); |
| 214 | + } |
| 215 | + |
| 216 | + @Test |
| 217 | + void testReplaceInNodeList_replacesMappedCodes() throws Exception { |
| 218 | + AtomicReference<List<Long>> stateRef = new AtomicReference<>(new ArrayList<>(Arrays.asList(1L, 2L, 3L))); |
| 219 | + Supplier<List<Long>> getter = stateRef::get; |
| 220 | + Consumer<List<Long>> setter = stateRef::set; |
| 221 | + |
| 222 | + Map<Long, Long> codeMap = new HashMap<>(); |
| 223 | + codeMap.put(1L, 10L); |
| 224 | + codeMap.put(3L, 30L); |
| 225 | + |
| 226 | + invokeReplaceInNodeList(getter, setter, codeMap); |
| 227 | + |
| 228 | + assertThat(stateRef.get()).containsExactly(10L, 2L, 30L); |
| 229 | + } |
| 230 | + |
| 231 | + @Test |
| 232 | + void testReplaceInNodeList_preservesUnmappedAndNullElements() throws Exception { |
| 233 | + AtomicReference<List<Long>> stateRef = |
| 234 | + new AtomicReference<>(new ArrayList<>(Arrays.asList(null, 4L, 5L, null))); |
| 235 | + Supplier<List<Long>> getter = stateRef::get; |
| 236 | + Consumer<List<Long>> setter = stateRef::set; |
| 237 | + |
| 238 | + Map<Long, Long> codeMap = new HashMap<>(); |
| 239 | + codeMap.put(4L, 40L); |
| 240 | + |
| 241 | + invokeReplaceInNodeList(getter, setter, codeMap); |
| 242 | + |
| 243 | + assertThat(stateRef.get()).containsExactly((Long) null, 40L, 5L, (Long) null); |
| 244 | + } |
| 245 | + |
| 246 | + @Test |
| 247 | + void testReplaceInNodeList_noOpWhenCodeMapIsEmpty() throws Exception { |
| 248 | + AtomicReference<List<Long>> stateRef = new AtomicReference<>(new ArrayList<>(Arrays.asList(6L, 7L))); |
| 249 | + Supplier<List<Long>> getter = stateRef::get; |
| 250 | + Consumer<List<Long>> setter = stateRef::set; |
| 251 | + |
| 252 | + invokeReplaceInNodeList(getter, setter, Collections.emptyMap()); |
| 253 | + |
| 254 | + assertThat(stateRef.get()).containsExactly(6L, 7L); |
| 255 | + } |
| 256 | + |
| 257 | + @Test |
| 258 | + void testReplaceInNodeList_createsNewListInstance() throws Exception { |
| 259 | + List<Long> original = Arrays.asList(8L, 9L); |
| 260 | + AtomicReference<List<Long>> stateRef = new AtomicReference<>(new ArrayList<>(original)); |
| 261 | + Supplier<List<Long>> getter = stateRef::get; |
| 262 | + Consumer<List<Long>> setter = stateRef::set; |
| 263 | + |
| 264 | + invokeReplaceInNodeList(getter, setter, Collections.emptyMap()); |
| 265 | + |
| 266 | + assertThat(stateRef.get()).isNotSameAs(original); |
| 267 | + assertThat(stateRef.get()).isEqualTo(original); |
| 268 | + } |
| 269 | + |
| 270 | + // Reflection Helper to call private replaceInNodeList |
| 271 | + private void invokeReplaceInNodeList(Supplier<List<Long>> getter, |
| 272 | + Consumer<List<Long>> setter, |
| 273 | + Map<Long, Long> codeMap) throws Exception { |
| 274 | + Method method = WorkflowDefinitionServiceImpl.class |
| 275 | + .getDeclaredMethod("replaceInNodeList", Supplier.class, Consumer.class, Map.class); |
| 276 | + method.setAccessible(true); |
| 277 | + |
| 278 | + try { |
| 279 | + method.invoke(workflowDefinitionService, getter, setter, codeMap); |
| 280 | + } catch (java.lang.reflect.InvocationTargetException e) { |
| 281 | + Throwable cause = e.getCause(); |
| 282 | + if (cause instanceof RuntimeException) { |
| 283 | + throw (RuntimeException) cause; |
| 284 | + } |
| 285 | + throw new RuntimeException("Exception in private method", cause); |
| 286 | + } |
| 287 | + } |
| 288 | + |
| 289 | + // Reflection Helper to call private replaceTaskCodeForSwitchTaskParams and replaceTaskCodeForConditionTaskParams |
190 | 290 | private void invokePrivateMethod(String methodName, Object... args) throws Exception { |
191 | 291 | Class<?>[] argTypes = new Class[args.length]; |
192 | 292 | for (int i = 0; i < args.length; i++) { |
|
0 commit comments