44import jakarta .json .JsonObject ;
55import jakarta .persistence .EntityManager ;
66import jakarta .persistence .TypedQuery ;
7+ import org .junit .jupiter .api .AfterEach ;
78import org .junit .jupiter .api .BeforeAll ;
89import org .junit .jupiter .api .Nested ;
910import org .junit .jupiter .api .Test ;
1617
1718import java .util .Collections ;
1819import java .util .List ;
20+ import java .util .Map ;
1921import java .util .Set ;
2022
2123import static org .junit .jupiter .api .Assertions .assertDoesNotThrow ;
2224import static org .junit .jupiter .api .Assertions .assertEquals ;
2325import static org .junit .jupiter .api .Assertions .assertThrows ;
26+ import static org .mockito .ArgumentMatchers .any ;
27+ import static org .mockito .Mockito .clearInvocations ;
2428import static org .mockito .Mockito .mock ;
29+ import static org .mockito .Mockito .never ;
30+ import static org .mockito .Mockito .verify ;
2531import static org .mockito .Mockito .when ;
2632
2733class SettingsServiceBeanTest {
@@ -315,4 +321,85 @@ void testConvertJsonToSettings_complexJsonValue() {
315321
316322
317323 }
324+
325+ @ Nested
326+ class ReplaceAllSettingsTest {
327+
328+ static TypedQuery <Setting > typedQuery = mock (TypedQuery .class );
329+ static EntityManager em = mock (EntityManager .class );
330+ static SettingsServiceBean settingsServiceBean = new SettingsServiceBean ();
331+
332+ @ BeforeAll
333+ static void setup () {
334+ settingsServiceBean .em = em ;
335+
336+ when (em .createNamedQuery (
337+ ArgumentMatchers .eq ("Setting.findAll" ),
338+ ArgumentMatchers .eq (Setting .class )))
339+ .thenReturn (typedQuery );
340+ }
341+
342+ @ AfterEach
343+ void reset () {
344+ // After each test, we need to clear the invocations for test isolation.
345+ clearInvocations (em );
346+ }
347+
348+ @ Test
349+ void testReplaceAllSettings_null () {
350+ // When/Then
351+ NullPointerException exception = assertThrows (NullPointerException .class ,
352+ () -> settingsServiceBean .replaceAllSettings (null ));
353+ assertEquals ("The list of new settings cannot be null (it may be empty)." , exception .getMessage ());
354+ }
355+
356+ @ Test
357+ void testReplaceAllSettings_updateDeleteCreate () {
358+ // Given
359+ Setting existingSetting1 = new Setting (":Key1" , "Value1" );
360+ Setting existingSetting2 = new Setting (":Key2" , "Value2" );
361+ Setting newSetting1 = new Setting (":Key1" , "UpdatedValue1" );
362+ Setting newSetting3 = new Setting (":Key3" , "Value3" );
363+
364+ when (typedQuery .getResultList ()).thenReturn (List .of (existingSetting1 , existingSetting2 ));
365+
366+ // When
367+ Map <Setting , SettingsServiceBean .Op > result = settingsServiceBean .replaceAllSettings (Set .of (newSetting1 , newSetting3 ));
368+
369+ // Then
370+ assertEquals (3 , result .size ());
371+ assertEquals (SettingsServiceBean .Op .UPDATED , result .get (existingSetting1 ));
372+ assertEquals (SettingsServiceBean .Op .DELETED , result .get (existingSetting2 ));
373+ assertEquals (SettingsServiceBean .Op .CREATED , result .get (newSetting3 ));
374+ // We cannot track the em.merge() call in this unit-test, as this happens in ORM code, beyond our reach.
375+ // Thus check the update to the ORM-tracked entity happened.
376+ assertEquals ("UpdatedValue1" , existingSetting1 .getContent ());
377+
378+ // Verify interactions
379+ verify (em ).remove (existingSetting2 );
380+ verify (em ).persist (newSetting3 );
381+ verify (em ).flush (); // verify persistence is enforced
382+ }
383+
384+ @ Test
385+ void testReplaceAllSettings_noChanges () {
386+ // Given
387+ Setting existingSetting = new Setting (":Key1" , "Value1" );
388+ Setting newSetting = new Setting (":Key1" , "Value1" );
389+
390+ when (typedQuery .getResultList ()).thenReturn (List .of (existingSetting ));
391+
392+ // When
393+ Map <Setting , SettingsServiceBean .Op > result = settingsServiceBean .replaceAllSettings (Set .of (newSetting ));
394+
395+ // Then
396+ assertEquals (1 , result .size ());
397+ assertEquals (SettingsServiceBean .Op .UNCHANGED , result .get (existingSetting ));
398+
399+ // Verify no interactions causing change
400+ verify (em , never ()).persist (any (Setting .class ));
401+ verify (em , never ()).remove (any (Setting .class ));
402+ verify (em , never ()).merge (any (Setting .class ));
403+ }
404+ }
318405}
0 commit comments