22
33import ca .bc .gov .nrs .wfprev .controllers .ActivityBoundaryController ;
44import ca .bc .gov .nrs .wfprev .data .models .ActivityBoundaryModel ;
5+ import ca .bc .gov .nrs .wfprev .data .models .ActivityModel ;
56import ca .bc .gov .nrs .wfprev .services .ActivityBoundaryService ;
7+ import ca .bc .gov .nrs .wfprev .services .ActivityService ;
68import ca .bc .gov .nrs .wfprev .services .CoordinatesService ;
79import com .nimbusds .jose .shaded .gson .Gson ;
810import com .nimbusds .jose .shaded .gson .GsonBuilder ;
1719import org .locationtech .jts .geom .LinearRing ;
1820import org .locationtech .jts .geom .MultiPolygon ;
1921import org .locationtech .jts .geom .Polygon ;
22+ import org .mockito .ArgumentCaptor ;
2023import org .springframework .beans .factory .annotation .Autowired ;
2124import org .springframework .boot .test .autoconfigure .web .servlet .WebMvcTest ;
2225import org .springframework .boot .test .mock .mockito .MockBean ;
3538import java .util .List ;
3639import java .util .UUID ;
3740
41+ import static org .junit .jupiter .api .Assertions .assertFalse ;
42+ import static org .junit .jupiter .api .Assertions .assertTrue ;
3843import static org .mockito .ArgumentMatchers .any ;
3944import static org .mockito .ArgumentMatchers .anyString ;
45+ import static org .mockito .ArgumentMatchers .argThat ;
4046import static org .mockito .ArgumentMatchers .eq ;
4147import static org .mockito .Mockito .doNothing ;
4248import static org .mockito .Mockito .verify ;
4349import static org .mockito .Mockito .when ;
50+ import static org .mockito .Mockito .never ;
4451import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .delete ;
4552import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
4653import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .post ;
@@ -59,6 +66,9 @@ class ActivityBoundaryControllerTest {
5966 @ MockBean
6067 private CoordinatesService coordinatesService ;
6168
69+ @ MockBean
70+ private ActivityService activityService ;
71+
6272 @ Autowired
6373 private MockMvc mockMvc ;
6474
@@ -200,10 +210,15 @@ void testGetActivityBoundary_EntityNotFoundException() throws Exception {
200210 @ WithMockUser
201211 void testCreateActivityBoundary_Success () throws Exception {
202212 ActivityBoundaryModel requestModel = buildActivityBoundaryRequestModel ();
213+ ActivityModel activity = new ActivityModel ();
214+ activity .setActivityGuid (requestModel .getActivityGuid ());
203215
204216 when (activityBoundaryService .createActivityBoundary (anyString (), anyString (), anyString (), any (ActivityBoundaryModel .class )))
205217 .thenReturn (requestModel );
206218
219+ when (activityService .getActivity (anyString (), anyString (), anyString ()))
220+ .thenReturn (activity );
221+
207222 String requestJson = activityBoundaryJson .formatted (
208223 requestModel .getActivityBoundaryGuid (),
209224 requestModel .getActivityGuid (),
@@ -218,8 +233,17 @@ void testCreateActivityBoundary_Success() throws Exception {
218233 .content (requestJson ))
219234 .andExpect (status ().isCreated ())
220235 .andExpect (jsonPath ("$.activityBoundaryGuid" ).value (requestModel .getActivityBoundaryGuid ()));
221- }
222236
237+ // Verify calls to activityService
238+ verify (activityService ).getActivity (anyString (), anyString (), anyString ());
239+
240+ verify (activityService ).updateActivity (
241+ anyString (),
242+ anyString (),
243+ argThat (updatedActivity ->
244+ updatedActivity .getIsSpatialAddedInd () != null && updatedActivity .getIsSpatialAddedInd ())
245+ );
246+ }
223247 @ Test
224248 @ WithMockUser
225249 void testCreateActivityBoundary_DataIntegrityViolationException () throws Exception {
@@ -243,6 +267,35 @@ void testCreateActivityBoundary_DataIntegrityViolationException() throws Excepti
243267 .andExpect (status ().isBadRequest ());
244268 }
245269
270+ @ Test
271+ @ WithMockUser
272+ void testCreateActivityBoundary_NoActivityFound () throws Exception {
273+ ActivityBoundaryModel requestModel = buildActivityBoundaryRequestModel ();
274+
275+ when (activityBoundaryService .createActivityBoundary (anyString (), anyString (), anyString (), any (ActivityBoundaryModel .class )))
276+ .thenReturn (requestModel );
277+
278+ when (activityService .getActivity (anyString (), anyString (), anyString ()))
279+ .thenReturn (null );
280+
281+ String requestJson = activityBoundaryJson .formatted (
282+ requestModel .getActivityBoundaryGuid (),
283+ requestModel .getActivityGuid (),
284+ requestModel .getSystemStartTimestamp ().getTime (),
285+ requestModel .getSystemEndTimestamp ().getTime () + 1000 ,
286+ requestModel .getCollectionDate ().getTime ()
287+ );
288+
289+ mockMvc .perform (post ("/projects/{projectId}/projectFiscals/{projectFiscalId}/activities/{activityId}/activityBoundary" ,
290+ UUID .randomUUID (), UUID .randomUUID (), UUID .randomUUID ())
291+ .contentType (MediaType .APPLICATION_JSON )
292+ .content (requestJson ))
293+ .andExpect (status ().isCreated ());
294+
295+ verify (activityService ).getActivity (anyString (), anyString (), anyString ());
296+ verify (activityService , org .mockito .Mockito .never ()).updateActivity (anyString (), anyString (), any (ActivityModel .class ));
297+ }
298+
246299 @ Test
247300 @ WithMockUser
248301 void testCreateActivityBoundary_Exception () throws Exception {
@@ -293,9 +346,14 @@ void testCreateActivityBoundary_IllegalArgumentException() throws Exception {
293346 @ WithMockUser
294347 void testUpdateActivityBoundary_Success () throws Exception {
295348 ActivityBoundaryModel requestModel = buildActivityBoundaryRequestModel ();
349+ ActivityModel activity = new ActivityModel ();
350+ activity .setActivityGuid (requestModel .getActivityGuid ());
351+ activity .setIsSpatialAddedInd (false );
296352
297353 when (activityBoundaryService .updateActivityBoundary (anyString (), anyString (), anyString (), any (ActivityBoundaryModel .class )))
298354 .thenReturn (requestModel );
355+ when (activityService .getActivity (anyString (), anyString (), anyString ()))
356+ .thenReturn (activity );
299357
300358 String requestJson = activityBoundaryJson .formatted (
301359 requestModel .getActivityBoundaryGuid (),
@@ -311,6 +369,42 @@ void testUpdateActivityBoundary_Success() throws Exception {
311369 .content (requestJson ))
312370 .andExpect (status ().isOk ())
313371 .andExpect (jsonPath ("$.activityBoundaryGuid" ).value (requestModel .getActivityBoundaryGuid ()));
372+
373+ // Verify spatial indicator update
374+ verify (activityService ).getActivity (anyString (), anyString (), anyString ());
375+ ArgumentCaptor <ActivityModel > activityCaptor = ArgumentCaptor .forClass (ActivityModel .class );
376+ verify (activityService ).updateActivity (anyString (), anyString (), activityCaptor .capture ());
377+
378+ assertTrue (activityCaptor .getValue ().getIsSpatialAddedInd (), "isSpatialAddedInd should be true after update" );
379+ }
380+
381+ @ Test
382+ @ WithMockUser
383+ void testUpdateActivityBoundary_NoActivityFound () throws Exception {
384+ ActivityBoundaryModel requestModel = buildActivityBoundaryRequestModel ();
385+
386+ when (activityBoundaryService .updateActivityBoundary (anyString (), anyString (), anyString (), any (ActivityBoundaryModel .class )))
387+ .thenReturn (requestModel );
388+
389+ when (activityService .getActivity (anyString (), anyString (), anyString ()))
390+ .thenReturn (null );
391+
392+ String requestJson = activityBoundaryJson .formatted (
393+ requestModel .getActivityBoundaryGuid (),
394+ requestModel .getActivityGuid (),
395+ requestModel .getSystemStartTimestamp ().getTime (),
396+ requestModel .getSystemEndTimestamp ().getTime () + 1000 ,
397+ requestModel .getCollectionDate ().getTime ()
398+ );
399+
400+ mockMvc .perform (put ("/projects/{projectId}/projectFiscals/{projectFiscalId}/activities/{activityId}/activityBoundary/{id}" ,
401+ UUID .randomUUID (), UUID .randomUUID (), UUID .randomUUID (), requestModel .getActivityBoundaryGuid ())
402+ .contentType (MediaType .APPLICATION_JSON )
403+ .content (requestJson ))
404+ .andExpect (status ().isOk ());
405+
406+ verify (activityService ).getActivity (anyString (), anyString (), anyString ());
407+ verify (activityService , never ()).updateActivity (anyString (), anyString (), any (ActivityModel .class ));
314408 }
315409
316410 @ Test
@@ -410,14 +504,69 @@ void testUpdateActivityBoundary_DataIntegrityViolationException() throws Excepti
410504 @ WithMockUser
411505 void testDeleteActivityBoundary_Success () throws Exception {
412506 UUID boundaryId = UUID .randomUUID ();
413- doNothing ().when (activityBoundaryService ).deleteActivityBoundary (anyString (), anyString (), anyString (), anyString ());
507+ UUID projectId = UUID .randomUUID ();
508+ UUID fiscalId = UUID .randomUUID ();
509+ UUID activityId = UUID .randomUUID ();
510+
511+ ActivityModel updatedActivity = new ActivityModel ();
512+ updatedActivity .setIsSpatialAddedInd (false );
513+
514+ when (activityService .updateActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), any (ActivityModel .class )))
515+ .thenReturn (updatedActivity );
516+
517+ doNothing ().when (activityBoundaryService ).deleteActivityBoundary (
518+ eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()), eq (boundaryId .toString ()));
519+
520+ when (activityService .getActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ())))
521+ .thenReturn (new ActivityModel ());
522+
523+ when (activityBoundaryService .getAllActivityBoundaries (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ())))
524+ .thenReturn (CollectionModel .empty ());
525+
526+ doNothing ().when (coordinatesService ).updateProjectCoordinates (eq (projectId .toString ()));
527+
528+ when (activityService .updateActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), any (ActivityModel .class )))
529+ .thenReturn (updatedActivity );
530+
531+ mockMvc .perform (delete ("/projects/{projectId}/projectFiscals/{projectFiscalId}/activities/{activityId}/activityBoundary/{id}" ,
532+ projectId , fiscalId , activityId , boundaryId )
533+ .header (HttpHeaders .AUTHORIZATION , "Bearer test-token" ))
534+ .andExpect (status ().isNoContent ());
535+
536+ verify (activityBoundaryService ).deleteActivityBoundary (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()), eq (boundaryId .toString ()));
537+ verify (coordinatesService ).updateProjectCoordinates (eq (projectId .toString ()));
538+ verify (activityService ).getActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()));
539+ verify (activityBoundaryService ).getAllActivityBoundaries (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()));
540+
541+ ArgumentCaptor <ActivityModel > activityCaptor = ArgumentCaptor .forClass (ActivityModel .class );
542+ verify (activityService ).updateActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), activityCaptor .capture ());
543+
544+ assertFalse (activityCaptor .getValue ().getIsSpatialAddedInd (), "isSpatialAddedInd should be false after deleting last boundary" );
545+ }
546+
547+ @ Test
548+ @ WithMockUser
549+ void testDeleteActivityBoundary_NoActivityFound () throws Exception {
550+ UUID boundaryId = UUID .randomUUID ();
551+ UUID projectId = UUID .randomUUID ();
552+ UUID fiscalId = UUID .randomUUID ();
553+ UUID activityId = UUID .randomUUID ();
554+
555+ doNothing ().when (activityBoundaryService ).deleteActivityBoundary (
556+ eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()), eq (boundaryId .toString ()));
557+ doNothing ().when (coordinatesService ).updateProjectCoordinates (eq (projectId .toString ()));
558+ when (activityService .getActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ())))
559+ .thenReturn (null );
414560
415561 mockMvc .perform (delete ("/projects/{projectId}/projectFiscals/{projectFiscalId}/activities/{activityId}/activityBoundary/{id}" ,
416- UUID . randomUUID (), UUID . randomUUID (), UUID . randomUUID () , boundaryId )
562+ projectId , fiscalId , activityId , boundaryId )
417563 .header (HttpHeaders .AUTHORIZATION , "Bearer test-token" ))
418564 .andExpect (status ().isNoContent ());
419565
420- verify (activityBoundaryService ).deleteActivityBoundary (anyString (), anyString (), anyString (), eq (boundaryId .toString ()));
566+ verify (activityBoundaryService ).deleteActivityBoundary (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()), eq (boundaryId .toString ()));
567+ verify (coordinatesService ).updateProjectCoordinates (eq (projectId .toString ()));
568+ verify (activityService ).getActivity (eq (projectId .toString ()), eq (fiscalId .toString ()), eq (activityId .toString ()));
569+ verify (activityService , org .mockito .Mockito .never ()).updateActivity (anyString (), anyString (), any (ActivityModel .class ));
421570 }
422571
423572 ActivityBoundaryModel buildActivityBoundaryRequestModel () {
0 commit comments