Skip to content

Commit

Permalink
#266 - Change validation information
Browse files Browse the repository at this point in the history
- add skipValidation parameter to get query and get template
  • Loading branch information
michael-82 committed Mar 21, 2024
1 parent 6c01c8f commit 2ca7f48
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,15 @@ public List<QueryListEntry> getQueryListForUser(

@GetMapping("/{id}")
public ResponseEntity<Object> getQuery(@PathVariable("id") Long queryId,
@RequestParam(value = "skipValidation", required = false, defaultValue = "false") boolean skipValidation,
Authentication authentication) throws JsonProcessingException {
if (!hasAccess(queryId, authentication)) {
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
}
var query = queryHandlerService.getQuery(queryId);
var annotatedQuery = Query.builder()
.id(query.id())
.content(structuredQueryValidation.annotateStructuredQuery(query.content()))
.content(structuredQueryValidation.annotateStructuredQuery(query.content(), skipValidation))
.label(query.label())
.comment(query.comment())
.build();
Expand Down Expand Up @@ -398,7 +399,7 @@ public ResponseEntity<Object> getQueryContent(
@PostMapping("/validate")
public ResponseEntity<StructuredQuery> validateStructuredQuery(
@Valid @RequestBody StructuredQuery query) {
return new ResponseEntity<>(structuredQueryValidation.annotateStructuredQuery(query), HttpStatus.OK);
return new ResponseEntity<>(structuredQueryValidation.annotateStructuredQuery(query, false), HttpStatus.OK);
}

private boolean hasAccess(Long queryId, Authentication authentication) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ public ResponseEntity<Object> storeQueryTemplate(@Valid @RequestBody QueryTempla

@GetMapping(path = "/{queryId}")
public ResponseEntity<Object> getQueryTemplate(@PathVariable(value = "queryId") Long queryId,
@RequestParam(value = "skipValidation", required = false, defaultValue = "false") boolean skipValidation,
Principal principal) {

try {
var query = queryHandlerService.getQueryTemplate(queryId, principal.getName());
var queryTemplate = queryHandlerService.convertTemplatePersistenceToApi(query);
var queryTemplateWithInvalidCritiera = QueryTemplate.builder()
.id(queryTemplate.id())
.content(structuredQueryValidation.annotateStructuredQuery(queryTemplate.content()))
.content(structuredQueryValidation.annotateStructuredQuery(queryTemplate.content(), skipValidation))
.label(queryTemplate.label())
.comment(queryTemplate.comment())
.lastModified(queryTemplate.lastModified())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ public StructuredQueryValidation(TerminologyService terminologyService) {
* iterations may contain checking for availability of values and units of the term codes as well.
*
* @param structuredQuery the structured query to check
* @param skipValidation if set to true, the issues list will always be empty
* @return the structuredQuery with issue annotation
*/
public StructuredQuery annotateStructuredQuery(StructuredQuery structuredQuery) {
public StructuredQuery annotateStructuredQuery(StructuredQuery structuredQuery, boolean skipValidation) {
var mutableStructuredQuery = MutableStructuredQuery.createMutableStructuredQuery(structuredQuery);

for (List<MutableCriterion> inclusionCriteria : mutableStructuredQuery.getInclusionCriteria()) {
annotateCriteria(inclusionCriteria);
annotateCriteria(inclusionCriteria, skipValidation);
}

for (List<MutableCriterion> exclusionCriteria : mutableStructuredQuery.getExclusionCriteria()) {
annotateCriteria(exclusionCriteria);
annotateCriteria(exclusionCriteria, skipValidation);
}

return StructuredQuery.createImmutableStructuredQuery(mutableStructuredQuery);
Expand Down Expand Up @@ -75,8 +76,12 @@ public boolean isValid(StructuredQuery structuredQuery) {
return true;
}

private void annotateCriteria(List<MutableCriterion> criteria) {
private void annotateCriteria(List<MutableCriterion> criteria, boolean skipValidation) {
for (MutableCriterion criterion : criteria) {
if (skipValidation) {
criterion.setValidationIssues(List.of());
continue;

Check warning on line 83 in src/main/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidation.java#L82-L83

Added lines #L82 - L83 were not covered by tests
}
if (criterion.getContext() == null) {
criterion.setValidationIssues(List.of(ValidationIssue.TERMCODE_CONTEXT_COMBINATION_INVALID));
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public void testRunQueryEndpoint_SucceedsOnValidStructuredQueryWith201() throws
var annotatedQuery = createValidAnnotatedStructuredQuery(false);

doReturn(Mono.just(1L)).when(queryHandlerService).runQuery(any(StructuredQuery.class), eq("test"));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

var mvcResult = mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY)).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -156,7 +156,7 @@ public void testRunQueryEndpoint_FailsOnDownstreamServiceError() throws Exceptio
var dispatchError = new QueryDispatchException("something went wrong");

doReturn(Mono.error(dispatchError)).when(queryHandlerService).runQuery(any(StructuredQuery.class), eq("test"));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

var mvcResult = mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY)).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -175,7 +175,7 @@ public void testRunQueryEndpoint_FailsOnSoftQuotaExceeded() throws Exception {
var annotatedQuery = createValidAnnotatedStructuredQuery(false);

doReturn((long)quotaSoftCreateAmount + 1).when(queryHandlerService).getAmountOfQueriesByUserAndInterval(any(String.class), any(Integer.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

var mvcResult = mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY)).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -193,7 +193,7 @@ public void testValidateQueryEndpoint_SucceedsOnValidQuery() throws Exception {
StructuredQuery testQuery = createValidStructuredQuery();
var annotatedQuery = createValidAnnotatedStructuredQuery(false);

doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY + "/validate")).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -209,7 +209,7 @@ public void testValidateQueryEndpoint_SucceedsDespiteInvalidCriteriaWith200() th
StructuredQuery testQuery = createValidStructuredQuery();
var annotatedQuery = createValidAnnotatedStructuredQuery(true);

doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY + "/validate")).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -231,7 +231,7 @@ public void testRunQueryEndpoint_FailsOnBeingBlacklistedWith403() throws Excepti
Optional<UserBlacklist> userBlacklistOptional = Optional.of(userBlacklistEntry);
doReturn(userBlacklistOptional).when(userBlacklistRepository).findByUserId(any(String.class));
doReturn(Mono.just(1L)).when(queryHandlerService).runQuery(any(StructuredQuery.class), eq("test"));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

var mvcResult = mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY)).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -251,7 +251,7 @@ public void testRunQueryEndpoint_FailsOnExceedingHardLimitWith403() throws Excep

doReturn((long)quotaHardCreateAmount).when(queryHandlerService).getAmountOfQueriesByUserAndInterval(any(String.class), eq(quotaHardCreateIntervalMinutes));
doReturn(Mono.just(1L)).when(queryHandlerService).runQuery(any(StructuredQuery.class), eq("test"));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

var mvcResult = mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY)).with(csrf())
.contentType(APPLICATION_JSON)
Expand All @@ -273,7 +273,7 @@ public void testRunQueryEndpoint_SucceedsOnExceedingHardlimitAsPowerUserWith201(
doReturn((long)quotaHardCreateAmount).when(queryHandlerService).getAmountOfQueriesByUserAndInterval(any(String.class), eq(quotaHardCreateIntervalMinutes));
doReturn((long)(quotaSoftCreateAmount - 1)).when(queryHandlerService).getAmountOfQueriesByUserAndInterval(any(String.class), eq(quotaSoftCreateIntervalMinutes));
doReturn(Mono.just(1L)).when(queryHandlerService).runQuery(any(StructuredQuery.class), eq("test"));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

var mvcResult = mockMvc.perform(post(URI.create(PATH_API + PATH_QUERY)).with(csrf())
.contentType(APPLICATION_JSON)
Expand Down Expand Up @@ -360,7 +360,7 @@ public void testGetQuery_succeeds() throws Exception {
var annotatedQuery = createValidAnnotatedStructuredQuery(false);
doReturn("test").when(queryHandlerService).getAuthorId(any(Long.class));
doReturn(createValidApiQuery(queryId)).when(queryHandlerService).getQuery(any(Long.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(get(URI.create(PATH_API + PATH_QUERY + "/" + queryId)).with(csrf()))
.andExpect(status().isOk())
Expand All @@ -374,7 +374,7 @@ public void testGetQuery_failsOnWrongAuthorWith403() throws Exception {
var annotatedQuery = createValidAnnotatedStructuredQuery(false);
doReturn("some-other-user").when(queryHandlerService).getAuthorId(any(Long.class));
doReturn(createValidApiQuery(queryId)).when(queryHandlerService).getQuery(any(Long.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(get(URI.create(PATH_API + PATH_QUERY + "/" + queryId)).with(csrf()))
.andExpect(status().isForbidden());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void testGetQueryTemplate_succeeds() throws Exception {

doReturn(createValidPersistenceQueryTemplateToGet(queryTemplateId)).when(queryHandlerService).getQueryTemplate(any(Long.class), any(String.class));
doReturn(createValidApiQueryTemplateToGet(queryTemplateId)).when(queryHandlerService).convertTemplatePersistenceToApi(any(de.numcodex.feasibility_gui_backend.query.persistence.QueryTemplate.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(get(URI.create(PATH_API + PATH_QUERY + PATH_TEMPLATE + "/" + queryTemplateId)).with(csrf()))
.andExpect(status().isOk())
Expand All @@ -141,7 +141,7 @@ public void testGetQueryTemplate_failsOnNotFound() throws Exception {

doThrow(QueryTemplateException.class).when(queryHandlerService).getQueryTemplate(any(Long.class), any(String.class));
doReturn(createValidApiQueryTemplateToGet(queryTemplateId)).when(queryHandlerService).convertTemplatePersistenceToApi(any(de.numcodex.feasibility_gui_backend.query.persistence.QueryTemplate.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(get(URI.create(PATH_API + PATH_QUERY + PATH_TEMPLATE + "/" + queryTemplateId)).with(csrf()))
.andExpect(status().isNotFound());
Expand All @@ -155,7 +155,7 @@ public void testGetQueryTemplate_failsOnJsonError() throws Exception {

doReturn(createValidPersistenceQueryTemplateToGet(queryTemplateId)).when(queryHandlerService).getQueryTemplate(any(Long.class), any(String.class));
doThrow(JsonProcessingException.class).when(queryHandlerService).convertTemplatePersistenceToApi(any(de.numcodex.feasibility_gui_backend.query.persistence.QueryTemplate.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class));
doReturn(annotatedQuery).when(structuredQueryValidation).annotateStructuredQuery(any(StructuredQuery.class), any(Boolean.class));

mockMvc.perform(get(URI.create(PATH_API + PATH_QUERY + PATH_TEMPLATE + "/" + queryTemplateId)).with(csrf()))
.andExpect(status().isInternalServerError());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void isValid_falseOnMissingContext() {
void annotateStructuredQuery_emptyIssuesOnValidCriteria(boolean withExclusionCriteria) {
doReturn(true).when(terminologyService).isExistingTermCode(any(String.class), any(String.class), isNull());

var annotatedStructuredQuery = structuredQueryValidation.annotateStructuredQuery(createValidStructuredQuery(withExclusionCriteria));
var annotatedStructuredQuery = structuredQueryValidation.annotateStructuredQuery(createValidStructuredQuery(withExclusionCriteria), false);

assertTrue(annotatedStructuredQuery.inclusionCriteria().get(0).get(0).validationIssues().isEmpty());
}
Expand All @@ -77,14 +77,14 @@ void annotateStructuredQuery_emptyIssuesOnValidCriteria(boolean withExclusionCri
void annotateStructuredQuery_nonEmptyIssuesOnInvalidCriteria(boolean withExclusionCriteria) {
doReturn(false).when(terminologyService).isExistingTermCode(any(String.class), any(String.class), isNull());

var annotatedStructuredQuery = structuredQueryValidation.annotateStructuredQuery(createValidStructuredQuery(withExclusionCriteria));
var annotatedStructuredQuery = structuredQueryValidation.annotateStructuredQuery(createValidStructuredQuery(withExclusionCriteria), false);

assertFalse(annotatedStructuredQuery.inclusionCriteria().get(0).get(0).validationIssues().isEmpty());
}

@Test
void annotateStructuredQuery_nonEmptyIssuesOnMissingContext() {
var annotatedStructuredQuery = structuredQueryValidation.annotateStructuredQuery(createStructuredQueryWithoutContext());
var annotatedStructuredQuery = structuredQueryValidation.annotateStructuredQuery(createStructuredQueryWithoutContext(), false);

assertFalse(annotatedStructuredQuery.inclusionCriteria().get(0).get(0).validationIssues().isEmpty());
}
Expand Down

0 comments on commit 2ca7f48

Please sign in to comment.