11package io .mosip .kernel .masterdata .test .service ;
22
3+ import io .mosip .kernel .masterdata .dto .HolidayDto ;
34import io .mosip .kernel .masterdata .dto .HolidayIDDto ;
45import io .mosip .kernel .masterdata .dto .HolidayUpdateDto ;
56import io .mosip .kernel .masterdata .dto .getresponse .extn .HolidayExtnDto ;
67import io .mosip .kernel .masterdata .dto .request .SearchFilter ;
78import io .mosip .kernel .masterdata .dto .response .HolidaySearchDto ;
9+ import io .mosip .kernel .masterdata .entity .Holiday ;
810import io .mosip .kernel .masterdata .entity .Location ;
11+ import io .mosip .kernel .masterdata .repository .HolidayRepository ;
12+ import io .mosip .kernel .masterdata .repository .LocationRepository ;
913import io .mosip .kernel .masterdata .service .impl .HolidayServiceImpl ;
14+ import io .mosip .kernel .masterdata .utils .AuditUtil ;
1015import io .mosip .kernel .masterdata .validator .FilterTypeEnum ;
1116import org .junit .Before ;
1217import org .junit .Test ;
1318import org .junit .runner .RunWith ;
19+ import org .mockito .ArgumentCaptor ;
1420import org .mockito .InjectMocks ;
21+ import org .mockito .Mock ;
1522import org .mockito .junit .MockitoJUnitRunner ;
1623import org .springframework .boot .test .context .SpringBootTest ;
1724import org .springframework .test .util .ReflectionTestUtils ;
2229import java .util .*;
2330
2431import static org .junit .Assert .*;
32+ import static org .mockito .Mockito .*;
2533
2634@ SpringBootTest
2735@ RunWith (MockitoJUnitRunner .class )
@@ -30,9 +38,20 @@ public class HolidayServiceImplTest {
3038 @ InjectMocks
3139 HolidayServiceImpl holidayService ;
3240
41+ @ Mock
42+ private HolidayRepository holidayRepository ;
43+
44+ @ Mock
45+ private LocationRepository locationRepository ;
46+
47+ @ Mock
48+ private AuditUtil auditUtil ;
49+
50+
3351 private HolidayUpdateDto holidayUpdateDto ;
3452 private Location location ;
3553
54+
3655 @ Before
3756 public void setUp () {
3857 holidayUpdateDto = new HolidayUpdateDto ();
@@ -117,6 +136,106 @@ public void testSetMetaData_Success() {
117136 assertNotNull (locations );
118137 }
119138
139+ @ Test
140+ public void saveHoliday_reusesExistingHolidayId_whenSameDateAndLocationDifferentLanguage () {
141+ // GIVEN
142+ final int holidayId = 123 ;
143+ final String existingHolidayName = "Test Holiday" ;
144+ final String existingHolidayDesc = "Test Description" ;
145+ final String holidayName = "Test Holiday Clone" ;
146+ final String holidayDesc = "Test Description Clone" ;
147+ final LocalDate date = LocalDate .now ();
148+ final String locationCode = "10036" ;
149+ final String englishLanguageCode = "eng" ;
150+ final String arabicLanguageCode = "ara" ;
151+ final boolean activeStatus = true ;
152+ // mock audit call
153+ doNothing ().when (auditUtil ).auditRequest (anyString (), anyString (), anyString (), anyString ());
154+ // Existing location with code = "10036"
155+ final Location locEntity = new Location ();
156+ locEntity .setCode (locationCode );
157+ locEntity .setLangCode (englishLanguageCode );
158+ final List <Location > locationsResult = Collections .singletonList (locEntity );
159+ when (locationRepository .findByCode (locationCode )).thenReturn (locationsResult );
160+ // Existing holiday (any language, e.g. ENG) for same (date, locationCode) with holidayId = 123
161+ final Holiday existing = new Holiday ();
162+ existing .setHolidayId (holidayId );
163+ existing .setHolidayName (existingHolidayName );
164+ existing .setHolidayDesc (existingHolidayDesc );
165+ existing .setHolidayDate (date );
166+ existing .setLocationCode (locationCode );
167+ existing .setLangCode (englishLanguageCode );
168+ existing .setIsActive (activeStatus );
169+ // No existing ARABIC row (same date+locationCode+lang)
170+ when (holidayRepository .findFirstByHolidayByHolidayDateLocationCodeLangCode (
171+ date , locationCode , arabicLanguageCode
172+ )).thenReturn (Optional .empty ());
173+ // But an existing row exists for same (date, locationCode) in another language → reuse its holidayId
174+ when (holidayRepository .findFirstByHolidayDateAndLocationCode (
175+ date , locationCode
176+ )).thenReturn (Optional .of (existing ));
177+ // Avoid “empty table” branch if the service checks it
178+ when (holidayRepository .count ()).thenReturn (1L );
179+ // Capture entity passed to save(...)
180+ ArgumentCaptor <Holiday > captor = ArgumentCaptor .forClass (Holiday .class );
181+ when (holidayRepository .save (captor .capture ())).thenAnswer (inv -> {
182+ final Holiday h = captor .getValue ();
183+ final Holiday persisted = new Holiday ();
184+ persisted .setHolidayId (h .getHolidayId ());
185+ persisted .setHolidayDate (h .getHolidayDate ());
186+ persisted .setLocationCode (h .getLocationCode ());
187+ persisted .setLangCode (h .getLangCode ());
188+ persisted .setHolidayName (h .getHolidayName ());
189+ persisted .setHolidayDesc (h .getHolidayDesc ());
190+ persisted .setIsActive (h .getIsActive ());
191+ return persisted ;
192+ });
193+ when (holidayRepository .findHolidayByHolidayNameHolidayDateLocationCodeLangCode (
194+ holidayName ,
195+ date ,
196+ locationCode ,
197+ arabicLanguageCode
198+ )).thenReturn (null );
199+ // DTO to create for Arabic, same (date, locationCode)
200+ HolidayDto dto = new HolidayDto ();
201+ dto .setHolidayDate (date );
202+ dto .setLocationCode (locationCode );
203+ dto .setLangCode (arabicLanguageCode );
204+ dto .setHolidayName (holidayName );
205+ dto .setHolidayDesc (holidayDesc );
206+ // WHEN
207+ HolidayIDDto out = holidayService .saveHoliday (dto );
208+ // THEN — the new row must reuse holidayId = 123
209+ Holiday saved = captor .getValue ();
210+ assertNotNull (saved );
211+ assertEquals (holidayId , saved .getHolidayId ());
212+ assertEquals (arabicLanguageCode , saved .getLangCode ());
213+ assertEquals (date , saved .getHolidayDate ());
214+ assertEquals (locationCode , saved .getLocationCode ());
215+ assertEquals (activeStatus , saved .getIsActive ());
216+ assertEquals (holidayName , saved .getHolidayName ());
217+ assertEquals (holidayDesc , saved .getHolidayDesc ());
218+ assertNotNull (out );
219+ assertEquals (holidayId , out .getHolidayId ());
220+ assertEquals (arabicLanguageCode , out .getLangCode ());
221+ assertEquals (holidayName , out .getHolidayName ());
222+ // Should not request a new max id
223+ verify (holidayRepository , never ()).findMaxHolidayId ();
224+ // Verification of flow
225+ verify (holidayRepository ).count ();
226+ verify (locationRepository ).findByCode (locationCode );
227+ verify (holidayRepository ).findFirstByHolidayByHolidayDateLocationCodeLangCode (date , locationCode , arabicLanguageCode );
228+ verify (holidayRepository ).findFirstByHolidayDateAndLocationCode (date , locationCode );
229+ verify (holidayRepository ).findHolidayByHolidayNameHolidayDateLocationCodeLangCode (
230+ holidayName ,
231+ date ,
232+ locationCode ,
233+ arabicLanguageCode
234+ );
235+ verify (holidayRepository ).save (any (Holiday .class ));
236+ }
237+
238+
120239 private SearchFilter buildExpectedSearchFilter_Success () {
121240 SearchFilter filter = new SearchFilter ();
122241 filter .setColumnName ("locationCode" );
0 commit comments