Skip to content

Commit 4b03bde

Browse files
authored
DT-950: Handle NPE in delete study API (#2421)
1 parent 9d2dece commit 4b03bde

File tree

2 files changed

+131
-8
lines changed

2 files changed

+131
-8
lines changed

src/main/java/org/broadinstitute/consent/http/resources/StudyResource.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public Response deleteStudyById(@Auth AuthUser authUser, @PathParam("studyId") I
148148
throw new NotFoundException("Study not found");
149149
}
150150

151-
boolean deletable = study.getDatasets()
151+
boolean deletable = (study.getDatasets() == null || study.getDatasets().isEmpty()) || study.getDatasets()
152152
.stream()
153153
.allMatch(Dataset::getDeletable);
154154
if (!deletable) {
@@ -157,13 +157,15 @@ public Response deleteStudyById(@Auth AuthUser authUser, @PathParam("studyId") I
157157
Set<Integer> studyDatasetIds = study.getDatasetIds();
158158
datasetService.deleteStudy(study, user);
159159
// Remove from ES index
160-
studyDatasetIds.forEach(id -> {
161-
try {
162-
elasticSearchService.deleteIndex(id);
163-
} catch (IOException e) {
164-
logException(e);
165-
}
166-
});
160+
if (studyDatasetIds != null) {
161+
studyDatasetIds.forEach(id -> {
162+
try {
163+
elasticSearchService.deleteIndex(id);
164+
} catch (IOException e) {
165+
logException(e);
166+
}
167+
});
168+
}
167169
return Response.ok().build();
168170
} catch (Exception e) {
169171
return createExceptionResponse(e);

src/test/java/org/broadinstitute/consent/http/resources/StudyResourceTest.java

+121
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44
import static org.mockito.ArgumentMatchers.any;
5+
import static org.mockito.Mockito.atLeastOnce;
6+
import static org.mockito.Mockito.never;
7+
import static org.mockito.Mockito.verify;
58
import static org.mockito.Mockito.when;
69

710
import com.google.api.client.http.HttpStatusCodes;
811
import com.google.gson.Gson;
912
import jakarta.ws.rs.NotFoundException;
1013
import jakarta.ws.rs.core.Response;
14+
import java.io.IOException;
1115
import java.util.List;
1216
import java.util.Objects;
1317
import java.util.Set;
@@ -209,6 +213,123 @@ void testUpdateStudyByRegistration() {
209213
assertEquals(HttpStatusCodes.STATUS_CODE_OK, response.getStatus());
210214
}
211215

216+
@Test
217+
void testDeleteStudyById() throws Exception {
218+
Study study = createMockStudy();
219+
study.getDatasets().forEach(d -> d.setDeletable(true));
220+
when(datasetService.getStudyWithDatasetsById(any())).thenReturn(study);
221+
User admin = new User();
222+
admin.setAdminRole();
223+
admin.setUserId(study.getCreateUserId());
224+
when(userService.findUserByEmail(any())).thenReturn(admin);
225+
initResource();
226+
227+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
228+
assertEquals(HttpStatusCodes.STATUS_CODE_OK, response.getStatus());
229+
verify(elasticSearchService, atLeastOnce()).deleteIndex(any());
230+
}
231+
}
232+
233+
@Test
234+
void testDeleteStudyByIdNotFound() throws Exception {
235+
Study study = createMockStudy();
236+
initResource();
237+
238+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
239+
assertEquals(HttpStatusCodes.STATUS_CODE_NOT_FOUND, response.getStatus());
240+
verify(elasticSearchService, never()).deleteIndex(any());
241+
}
242+
}
243+
244+
@Test
245+
void testDeleteStudyByIdNonCreatorNonAdmin() throws Exception {
246+
Study study = createMockStudy();
247+
study.getDatasets().forEach(d -> d.setDeletable(true));
248+
when(datasetService.getStudyWithDatasetsById(any())).thenReturn(study);
249+
User chair = new User();
250+
chair.setChairpersonRole();
251+
chair.setUserId(study.getCreateUserId() + 1);
252+
when(userService.findUserByEmail(any())).thenReturn(chair);
253+
initResource();
254+
255+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
256+
assertEquals(HttpStatusCodes.STATUS_CODE_NOT_FOUND, response.getStatus());
257+
verify(elasticSearchService, never()).deleteIndex(any());
258+
}
259+
}
260+
261+
@Test
262+
void testDeleteStudyByIdNotDeletable() throws Exception {
263+
Study study = createMockStudy();
264+
study.getDatasets().forEach(d -> d.setDeletable(false));
265+
when(datasetService.getStudyWithDatasetsById(any())).thenReturn(study);
266+
User admin = new User();
267+
admin.setAdminRole();
268+
admin.setUserId(study.getCreateUserId());
269+
when(userService.findUserByEmail(any())).thenReturn(admin);
270+
initResource();
271+
272+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
273+
assertEquals(HttpStatusCodes.STATUS_CODE_BAD_REQUEST, response.getStatus());
274+
verify(elasticSearchService, never()).deleteIndex(any());
275+
}
276+
}
277+
278+
@Test
279+
void testDeleteStudyByIdNullDatasets() throws Exception {
280+
Study study = new Study();
281+
study.setStudyId(1);
282+
when(datasetService.getStudyWithDatasetsById(any())).thenReturn(study);
283+
User admin = new User();
284+
admin.setAdminRole();
285+
admin.setUserId(study.getCreateUserId());
286+
when(userService.findUserByEmail(any())).thenReturn(admin);
287+
initResource();
288+
289+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
290+
assertEquals(HttpStatusCodes.STATUS_CODE_OK, response.getStatus());
291+
verify(elasticSearchService, never()).deleteIndex(any());
292+
}
293+
}
294+
295+
296+
@Test
297+
void testDeleteStudyByIdNoDatasets() throws Exception {
298+
Study study = createMockStudy();
299+
study.setDatasetIds(Set.of());
300+
study.getDatasets().clear();
301+
when(datasetService.getStudyWithDatasetsById(any())).thenReturn(study);
302+
User admin = new User();
303+
admin.setAdminRole();
304+
admin.setUserId(study.getCreateUserId());
305+
when(userService.findUserByEmail(any())).thenReturn(admin);
306+
initResource();
307+
308+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
309+
assertEquals(HttpStatusCodes.STATUS_CODE_OK, response.getStatus());
310+
verify(elasticSearchService, never()).deleteIndex(any());
311+
}
312+
}
313+
314+
@Test
315+
void testDeleteStudyByIdElasticSearchFailure() throws Exception {
316+
Study study = createMockStudy();
317+
study.getDatasets().forEach(d -> d.setDeletable(true));
318+
when(datasetService.getStudyWithDatasetsById(any())).thenReturn(study);
319+
User admin = new User();
320+
admin.setAdminRole();
321+
admin.setUserId(study.getCreateUserId());
322+
when(userService.findUserByEmail(any())).thenReturn(admin);
323+
when(elasticSearchService.deleteIndex(any())).thenThrow(new IOException());
324+
initResource();
325+
326+
try (Response response = resource.deleteStudyById(authUser, study.getStudyId())) {
327+
assertEquals(HttpStatusCodes.STATUS_CODE_OK, response.getStatus());
328+
verify(elasticSearchService, atLeastOnce()).deleteIndex(any());
329+
}
330+
}
331+
332+
212333
/*
213334
* Study mock
214335
*/

0 commit comments

Comments
 (0)