Skip to content

Commit d821ac3

Browse files
committed
WFPREV-437 Update spatial added badge when spatial file is added to activity
1 parent d18edad commit d821ac3

File tree

3 files changed

+95
-9
lines changed

3 files changed

+95
-9
lines changed

client/wfprev-war/src/main/angular/src/app/components/edit-project/activities/activities.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { CommonModule } from '@angular/common';
2-
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
2+
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
33
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
44
import { MomentDateAdapter } from '@angular/material-moment-adapter';
55
import { MatCheckboxModule } from '@angular/material/checkbox';
@@ -57,7 +57,7 @@ export const CUSTOM_DATE_FORMATS = {
5757
],
5858
})
5959

60-
export class ActivitiesComponent implements OnChanges, OnInit, CanComponentDeactivate{
60+
export class ActivitiesComponent implements OnChanges, CanComponentDeactivate{
6161
@Input() fiscalGuid: string = '';
6262
@Output() boundariesUpdated = new EventEmitter<void>();
6363

@@ -90,8 +90,6 @@ export class ActivitiesComponent implements OnChanges, OnInit, CanComponentDeact
9090
public cd: ChangeDetectorRef
9191
) {}
9292

93-
ngOnInit(): void {
94-
}
9593
ngOnChanges(changes: SimpleChanges): void {
9694
if (changes['fiscalGuid'] && changes['fiscalGuid'].currentValue) {
9795
// Clear previous state before loading new fiscal data
@@ -735,5 +733,7 @@ export class ActivitiesComponent implements OnChanges, OnInit, CanComponentDeact
735733

736734
onFilesChanged() {
737735
this.boundariesUpdated.emit(); // Notify ProjectFiscalsComponent
736+
this.getActivities();
738737
}
738+
739739
}

server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ActivityBoundaryController.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc;
55
import ca.bc.gov.nrs.wfprev.common.controllers.CommonController;
66
import ca.bc.gov.nrs.wfprev.data.models.ActivityBoundaryModel;
7+
import ca.bc.gov.nrs.wfprev.data.models.ActivityModel;
78
import ca.bc.gov.nrs.wfprev.services.ActivityBoundaryService;
9+
import ca.bc.gov.nrs.wfprev.services.ActivityService;
810
import ca.bc.gov.nrs.wfprev.services.CoordinatesService;
911
import io.swagger.v3.oas.annotations.Operation;
1012
import io.swagger.v3.oas.annotations.Parameter;
@@ -37,13 +39,15 @@
3739
@Slf4j
3840
@RequestMapping(value = "/projects/{projectGuid}/projectFiscals/{projectPlanFiscalGuid}/activities/{activityGuid}/activityBoundary")
3941
public class ActivityBoundaryController extends CommonController {
42+
private final ActivityService activityService;
4043
private final ActivityBoundaryService activityBoundaryService;
4144
private final CoordinatesService coordinatesService;
4245

43-
public ActivityBoundaryController(ActivityBoundaryService activityBoundaryService, CoordinatesService coordinatesService) {
46+
public ActivityBoundaryController(ActivityBoundaryService activityBoundaryService, CoordinatesService coordinatesService, ActivityService activityService) {
4447
super(ActivityBoundaryController.class.getName());
4548
this.activityBoundaryService = activityBoundaryService;
4649
this.coordinatesService = coordinatesService;
50+
this.activityService = activityService;
4751
}
4852

4953
@GetMapping
@@ -142,6 +146,11 @@ public ResponseEntity<ActivityBoundaryModel> createActivityBoundary(
142146
projectGuid, projectPlanFiscalGuid, activityGuid, resource);
143147
coordinatesService.updateProjectCoordinates(projectGuid);
144148

149+
// Update activity spatial indicator
150+
ActivityModel activity = activityService.getActivity(projectGuid, projectPlanFiscalGuid, activityGuid);
151+
activity.setIsSpatialAddedInd(true);
152+
activityService.updateActivity(projectGuid, projectPlanFiscalGuid, activity);
153+
145154
return ResponseEntity.status(201).body(newResource);
146155
} catch (DataIntegrityViolationException e) {
147156
log.error(" ### DataIntegrityViolationException while creating Activity Boundary", e);
@@ -182,6 +191,11 @@ public ResponseEntity<ActivityBoundaryModel> updateActivityBoundary(
182191
projectGuid, projectPlanFiscalGuid, activityGuid, resource);
183192
coordinatesService.updateProjectCoordinates(projectGuid);
184193

194+
// Update activity spatial indicator
195+
ActivityModel activity = activityService.getActivity(projectGuid, projectPlanFiscalGuid, activityGuid);
196+
activity.setIsSpatialAddedInd(true);
197+
activityService.updateActivity(projectGuid, projectPlanFiscalGuid, activity);
198+
185199
return updatedResource == null ? notFound() : ok(updatedResource);
186200
} catch (DataIntegrityViolationException e) {
187201
log.error(" ### DataIntegrityViolationException while updating Activity Boundary", e);
@@ -219,6 +233,13 @@ public ResponseEntity<Void> deleteActivityBoundary(
219233
try {
220234
activityBoundaryService.deleteActivityBoundary(projectGuid, projectPlanFiscalGuid, activityGuid, id);
221235
coordinatesService.updateProjectCoordinates(projectGuid);
236+
237+
// Update activity spatial indicator
238+
ActivityModel activity = activityService.getActivity(projectGuid, projectPlanFiscalGuid, activityGuid);
239+
CollectionModel<ActivityBoundaryModel> boundaries = activityBoundaryService.getAllActivityBoundaries(projectGuid, projectPlanFiscalGuid, activityGuid);
240+
activity.setIsSpatialAddedInd(!boundaries.getContent().isEmpty());
241+
activityService.updateActivity(projectGuid, projectPlanFiscalGuid, activity);
242+
222243
return ResponseEntity.noContent().build();
223244
} catch (EntityNotFoundException e) {
224245
log.warn(" ### Activity Boundary for deletion not found: {}", id, e);

server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ActivityBoundaryControllerTest.java

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import ca.bc.gov.nrs.wfprev.controllers.ActivityBoundaryController;
44
import ca.bc.gov.nrs.wfprev.data.models.ActivityBoundaryModel;
5+
import ca.bc.gov.nrs.wfprev.data.models.ActivityModel;
56
import ca.bc.gov.nrs.wfprev.services.ActivityBoundaryService;
7+
import ca.bc.gov.nrs.wfprev.services.ActivityService;
68
import ca.bc.gov.nrs.wfprev.services.CoordinatesService;
79
import com.nimbusds.jose.shaded.gson.Gson;
810
import com.nimbusds.jose.shaded.gson.GsonBuilder;
@@ -17,6 +19,7 @@
1719
import org.locationtech.jts.geom.LinearRing;
1820
import org.locationtech.jts.geom.MultiPolygon;
1921
import org.locationtech.jts.geom.Polygon;
22+
import org.mockito.ArgumentCaptor;
2023
import org.springframework.beans.factory.annotation.Autowired;
2124
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
2225
import org.springframework.boot.test.mock.mockito.MockBean;
@@ -35,8 +38,11 @@
3538
import java.util.List;
3639
import java.util.UUID;
3740

41+
import static org.junit.jupiter.api.Assertions.assertFalse;
42+
import static org.junit.jupiter.api.Assertions.assertTrue;
3843
import static org.mockito.ArgumentMatchers.any;
3944
import static org.mockito.ArgumentMatchers.anyString;
45+
import static org.mockito.ArgumentMatchers.argThat;
4046
import static org.mockito.ArgumentMatchers.eq;
4147
import static org.mockito.Mockito.doNothing;
4248
import static org.mockito.Mockito.verify;
@@ -59,6 +65,9 @@ class ActivityBoundaryControllerTest {
5965
@MockBean
6066
private CoordinatesService coordinatesService;
6167

68+
@MockBean
69+
private ActivityService activityService;
70+
6271
@Autowired
6372
private MockMvc mockMvc;
6473

@@ -200,10 +209,15 @@ void testGetActivityBoundary_EntityNotFoundException() throws Exception {
200209
@WithMockUser
201210
void testCreateActivityBoundary_Success() throws Exception {
202211
ActivityBoundaryModel requestModel = buildActivityBoundaryRequestModel();
212+
ActivityModel activity = new ActivityModel();
213+
activity.setActivityGuid(requestModel.getActivityGuid());
203214

204215
when(activityBoundaryService.createActivityBoundary(anyString(), anyString(), anyString(), any(ActivityBoundaryModel.class)))
205216
.thenReturn(requestModel);
206217

218+
when(activityService.getActivity(anyString(), anyString(), anyString()))
219+
.thenReturn(activity);
220+
207221
String requestJson = activityBoundaryJson.formatted(
208222
requestModel.getActivityBoundaryGuid(),
209223
requestModel.getActivityGuid(),
@@ -218,8 +232,17 @@ void testCreateActivityBoundary_Success() throws Exception {
218232
.content(requestJson))
219233
.andExpect(status().isCreated())
220234
.andExpect(jsonPath("$.activityBoundaryGuid").value(requestModel.getActivityBoundaryGuid()));
221-
}
222235

236+
// Verify calls to activityService
237+
verify(activityService).getActivity(anyString(), anyString(), anyString());
238+
239+
verify(activityService).updateActivity(
240+
anyString(),
241+
anyString(),
242+
argThat(updatedActivity ->
243+
updatedActivity.getIsSpatialAddedInd() != null && updatedActivity.getIsSpatialAddedInd())
244+
);
245+
}
223246
@Test
224247
@WithMockUser
225248
void testCreateActivityBoundary_DataIntegrityViolationException() throws Exception {
@@ -293,9 +316,14 @@ void testCreateActivityBoundary_IllegalArgumentException() throws Exception {
293316
@WithMockUser
294317
void testUpdateActivityBoundary_Success() throws Exception {
295318
ActivityBoundaryModel requestModel = buildActivityBoundaryRequestModel();
319+
ActivityModel activity = new ActivityModel();
320+
activity.setActivityGuid(requestModel.getActivityGuid());
321+
activity.setIsSpatialAddedInd(false);
296322

297323
when(activityBoundaryService.updateActivityBoundary(anyString(), anyString(), anyString(), any(ActivityBoundaryModel.class)))
298324
.thenReturn(requestModel);
325+
when(activityService.getActivity(anyString(), anyString(), anyString()))
326+
.thenReturn(activity);
299327

300328
String requestJson = activityBoundaryJson.formatted(
301329
requestModel.getActivityBoundaryGuid(),
@@ -311,6 +339,13 @@ void testUpdateActivityBoundary_Success() throws Exception {
311339
.content(requestJson))
312340
.andExpect(status().isOk())
313341
.andExpect(jsonPath("$.activityBoundaryGuid").value(requestModel.getActivityBoundaryGuid()));
342+
343+
// Verify spatial indicator update
344+
verify(activityService).getActivity(anyString(), anyString(), anyString());
345+
ArgumentCaptor<ActivityModel> activityCaptor = ArgumentCaptor.forClass(ActivityModel.class);
346+
verify(activityService).updateActivity(anyString(), anyString(), activityCaptor.capture());
347+
348+
assertTrue(activityCaptor.getValue().getIsSpatialAddedInd(), "isSpatialAddedInd should be true after update");
314349
}
315350

316351
@Test
@@ -410,14 +445,44 @@ void testUpdateActivityBoundary_DataIntegrityViolationException() throws Excepti
410445
@WithMockUser
411446
void testDeleteActivityBoundary_Success() throws Exception {
412447
UUID boundaryId = UUID.randomUUID();
413-
doNothing().when(activityBoundaryService).deleteActivityBoundary(anyString(), anyString(), anyString(), anyString());
448+
UUID projectId = UUID.randomUUID();
449+
UUID fiscalId = UUID.randomUUID();
450+
UUID activityId = UUID.randomUUID();
451+
452+
ActivityModel updatedActivity = new ActivityModel();
453+
updatedActivity.setIsSpatialAddedInd(false);
454+
455+
when(activityService.updateActivity(eq(projectId.toString()), eq(fiscalId.toString()), any(ActivityModel.class)))
456+
.thenReturn(updatedActivity);
457+
458+
doNothing().when(activityBoundaryService).deleteActivityBoundary(
459+
eq(projectId.toString()), eq(fiscalId.toString()), eq(activityId.toString()), eq(boundaryId.toString()));
460+
461+
when(activityService.getActivity(eq(projectId.toString()), eq(fiscalId.toString()), eq(activityId.toString())))
462+
.thenReturn(new ActivityModel());
463+
464+
when(activityBoundaryService.getAllActivityBoundaries(eq(projectId.toString()), eq(fiscalId.toString()), eq(activityId.toString())))
465+
.thenReturn(CollectionModel.empty());
466+
467+
doNothing().when(coordinatesService).updateProjectCoordinates(eq(projectId.toString()));
468+
469+
when(activityService.updateActivity(eq(projectId.toString()), eq(fiscalId.toString()), any(ActivityModel.class)))
470+
.thenReturn(updatedActivity);
414471

415472
mockMvc.perform(delete("/projects/{projectId}/projectFiscals/{projectFiscalId}/activities/{activityId}/activityBoundary/{id}",
416-
UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), boundaryId)
473+
projectId, fiscalId, activityId, boundaryId)
417474
.header(HttpHeaders.AUTHORIZATION, "Bearer test-token"))
418475
.andExpect(status().isNoContent());
419476

420-
verify(activityBoundaryService).deleteActivityBoundary(anyString(), anyString(), anyString(), eq(boundaryId.toString()));
477+
verify(activityBoundaryService).deleteActivityBoundary(eq(projectId.toString()), eq(fiscalId.toString()), eq(activityId.toString()), eq(boundaryId.toString()));
478+
verify(coordinatesService).updateProjectCoordinates(eq(projectId.toString()));
479+
verify(activityService).getActivity(eq(projectId.toString()), eq(fiscalId.toString()), eq(activityId.toString()));
480+
verify(activityBoundaryService).getAllActivityBoundaries(eq(projectId.toString()), eq(fiscalId.toString()), eq(activityId.toString()));
481+
482+
ArgumentCaptor<ActivityModel> activityCaptor = ArgumentCaptor.forClass(ActivityModel.class);
483+
verify(activityService).updateActivity(eq(projectId.toString()), eq(fiscalId.toString()), activityCaptor.capture());
484+
485+
assertFalse(activityCaptor.getValue().getIsSpatialAddedInd(), "isSpatialAddedInd should be false after deleting last boundary");
421486
}
422487

423488
ActivityBoundaryModel buildActivityBoundaryRequestModel() {

0 commit comments

Comments
 (0)