Skip to content

Commit

Permalink
Merge pull request #51 from kbss-cvut/add-record-filtering-by-templates
Browse files Browse the repository at this point in the history
[kbss-cvut/record-manager-ui#168] Add filtering of records according …
  • Loading branch information
blcham committed Jun 6, 2024
2 parents 355669f + 1a1e84d commit a2a8a3f
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 47 deletions.
30 changes: 2 additions & 28 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,13 @@
<name>OFN Record Manager</name>
<packaging>jar</packaging>

<!-- The snapshot repositories are necessary only for JOPA 2.0.0-SNAPSHOT -->
<repositories>
<repository>
<id>central-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>17</jdk.version>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>

<cz.cvut.kbss.jopa.version>2.0.0-SNAPSHOT</cz.cvut.kbss.jopa.version>
<cz.cvut.kbss.jopa.version>2.0.0</cz.cvut.kbss.jopa.version>
<org.mockito.version>4.11.0</org.mockito.version>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>
Expand Down Expand Up @@ -101,7 +75,7 @@
<dependency>
<groupId>com.github.ledsoft</groupId>
<artifactId>jopa-spring-transaction</artifactId>
<version>0.3.0-SNAPSHOT</version>
<version>0.3.0</version>
</dependency>

<!-- Logging -->
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/cz/cvut/kbss/study/config/WebAppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import cz.cvut.kbss.jopa.sessions.UnitOfWorkImpl;
import cz.cvut.kbss.study.rest.servlet.DiagnosticsContextFilter;
import cz.cvut.kbss.study.util.Constants;
import cz.cvut.kbss.study.util.json.ManageableIgnoreMixin;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -46,8 +44,6 @@ public static ObjectMapper createJsonObjectMapper() {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Ignore UoW references injected into entities
objectMapper.addMixIn(UnitOfWorkImpl.class, ManageableIgnoreMixin.class);
// JSR 310 (Java 8 DateTime API)
objectMapper.registerModule(new JavaTimeModule());
// Serialize datetime as ISO strings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ private <T> Page<T> findRecords(RecordFilterParams filters, Pageable pageSpec, C
private void setQueryParameters(TypedQuery<?> query, Map<String, Object> queryParams) {
query.setParameter("type", typeUri)
.setParameter("hasPhase", URI.create(Vocabulary.s_p_has_phase))
.setParameter("hasFormTemplate", URI.create(Vocabulary.s_p_has_form_template))
.setParameter("hasInstitution",
URI.create(Vocabulary.s_p_was_treated_at))
.setParameter("hasKey", URI.create(Vocabulary.s_p_key))
Expand All @@ -256,6 +257,7 @@ private static String constructWhereClause(RecordFilterParams filters, Map<Strin
"?hasInstitution ?institution . " +
"?institution ?hasKey ?institutionKey ." +
"OPTIONAL { ?r ?hasPhase ?phase . } " +
"OPTIONAL { ?r ?hasFormTemplate ?formTemplate . } " +
"OPTIONAL { ?r ?hasLastModified ?lastModified . } " +
"BIND (COALESCE(?lastModified, ?created) AS ?date) ";
whereClause += mapParamsToQuery(filters, queryParams);
Expand All @@ -280,6 +282,11 @@ private static String mapParamsToQuery(RecordFilterParams filterParams, Map<Stri
queryParams.put("phases",
filterParams.getPhaseIds().stream().map(URI::create).collect(Collectors.toList()));
}
if (!filterParams.getFormTemplateIds().isEmpty()) {
filters.add("FILTER (?formTemplate in (?formTemplates))");
queryParams.put("formTemplates",
filterParams.getFormTemplateIds().stream().map(id -> new LangString(id, Constants.PU_LANGUAGE)).collect(Collectors.toList()));
}
return String.join(" ", filters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class RecordFilterParams {

private LocalDate maxModifiedDate = LocalDate.now();

private Set<String> formTemplateIds = Collections.emptySet();

private Set<String> phaseIds = Collections.emptySet();

public RecordFilterParams() {
Expand All @@ -28,11 +30,12 @@ public RecordFilterParams(String institutionKey) {

// This one mainly is for test data setup
public RecordFilterParams(String institutionKey, LocalDate minModifiedDate, LocalDate maxModifiedDate,
Set<String> phaseIds) {
Set<String> phaseIds, Set<String> formTemplateIds) {
this.institutionKey = institutionKey;
this.minModifiedDate = minModifiedDate;
this.maxModifiedDate = maxModifiedDate;
this.phaseIds = phaseIds;
this.formTemplateIds = formTemplateIds;
}

public Optional<String> getInstitutionKey() {
Expand All @@ -59,6 +62,14 @@ public void setMaxModifiedDate(LocalDate maxModifiedDate) {
this.maxModifiedDate = maxModifiedDate;
}

public Set<String> getFormTemplateIds() {
return formTemplateIds;
}

public void setFormTemplateIds(Set<String> formTemplateIds) {
this.formTemplateIds = formTemplateIds;
}

public Set<String> getPhaseIds() {
return phaseIds;
}
Expand All @@ -78,12 +89,13 @@ public boolean equals(Object o) {
return Objects.equals(institutionKey, that.institutionKey)
&& Objects.equals(minModifiedDate, that.minModifiedDate)
&& Objects.equals(maxModifiedDate, that.maxModifiedDate)
&& Objects.equals(formTemplateIds, that.formTemplateIds)
&& Objects.equals(phaseIds, that.phaseIds);
}

@Override
public int hashCode() {
return Objects.hash(institutionKey, minModifiedDate, maxModifiedDate, phaseIds);
return Objects.hash(institutionKey, minModifiedDate, maxModifiedDate, formTemplateIds, phaseIds);
}

@Override
Expand All @@ -92,6 +104,7 @@ public String toString() {
"institutionKey='" + institutionKey + '\'' +
", minModifiedDate=" + minModifiedDate +
", maxModifiedDate=" + maxModifiedDate +
", formTemplateIds=" + formTemplateIds +
", phaseIds=" + phaseIds +
'}';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cz.cvut.kbss.study.model.RecordPhase;
import cz.cvut.kbss.study.persistence.dao.util.RecordFilterParams;
import cz.cvut.kbss.study.rest.exception.BadRequestException;
import java.util.HashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.LinkedMultiValueMap;
Expand Down Expand Up @@ -30,6 +31,8 @@ public class RecordFilterMapper {

private static final String INSTITUTION_KEY_PARAM = "institution";

private static final String FORM_TEMPLATE_ID_PARAM = "formTemplate";

private static final String PHASE_ID_PARAM = "phase";

/**
Expand Down Expand Up @@ -69,6 +72,10 @@ public static RecordFilterParams constructRecordFilter(MultiValueMap<String, Str
getSingleValue(INSTITUTION_KEY_PARAM, params).ifPresent(result::setInstitutionKey);
result.setPhaseIds(params.getOrDefault(PHASE_ID_PARAM, Collections.emptyList()).stream()
.map(s -> RecordPhase.fromIriOrName(s).getIri()).collect(Collectors.toSet()));

result.setFormTemplateIds(
new HashSet<>(params.getOrDefault(FORM_TEMPLATE_ID_PARAM, Collections.emptyList()))
);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ void findAllFullReturnsRecordsMatchingSpecifiedDatePeriod() {
}).toList();

final Page<PatientRecord> result =
sut.findAllRecordsFull(new RecordFilterParams(null, minDate, maxDate, Collections.emptySet()),
sut.findAllRecordsFull(new RecordFilterParams(null, minDate, maxDate, Collections.emptySet(), Collections.emptySet()),
Pageable.unpaged());
assertFalse(result.isEmpty());
assertThat(result.getContent(), containsSameEntities(expected));
Expand Down Expand Up @@ -316,7 +316,7 @@ void findAllFullReturnsRecordsMatchingSpecifiedDatePeriodAndInstitution() {
}).toList();

final Page<PatientRecord> result =
sut.findAllRecordsFull(new RecordFilterParams(institution.getKey(), minDate, maxDate, Collections.emptySet()),
sut.findAllRecordsFull(new RecordFilterParams(institution.getKey(), minDate, maxDate, Collections.emptySet(), Collections.emptySet()),
Pageable.unpaged());
assertFalse(result.isEmpty());
assertThat(result.getContent(), containsSameEntities(expected));
Expand All @@ -327,7 +327,7 @@ void findAllFullReturnsRecordsMatchingSpecifiedPhase() {
final User author = generateAuthorWithInstitution();
final List<PatientRecord> allRecords = generateRecordsForAuthor(author, 5);
transactional(() -> allRecords.forEach(r -> {
r.setPhase(RecordPhase.values()[Generator.randomInt(RecordPhase.values().length)]);
r.setPhase(RecordPhase.values()[Generator.randomInt(0, RecordPhase.values().length)]);
persistRecordWithIdentification(r);
}));
final RecordPhase phase = allRecords.get(Generator.randomIndex(allRecords)).getPhase();
Expand All @@ -339,6 +339,28 @@ void findAllFullReturnsRecordsMatchingSpecifiedPhase() {
result.forEach(res -> assertEquals(phase, res.getPhase()));
}

@Test
void findAllFullReturnsRecordsMatchingSpecifiedFormTemplate() {
String[] formTemplates = new String[]{
"http://example.org/form-template-1",
"http://example.org/form-template-2"
};
final User author = generateAuthorWithInstitution();
final List<PatientRecord> allRecords = generateRecordsForAuthor(author, 5);
transactional(() -> allRecords.forEach(r -> {
r.setFormTemplate(formTemplates[Generator.randomInt(0, formTemplates.length)]);
persistRecordWithIdentification(r);
}));
final String formTemplate = allRecords.get(Generator.randomIndex(allRecords)).getFormTemplate();
final RecordFilterParams filterParams = new RecordFilterParams();
filterParams.setFormTemplateIds(Set.of(formTemplate));

final Page<PatientRecord> result = sut.findAllRecordsFull(filterParams, Pageable.unpaged());
assertFalse(result.isEmpty());
result.forEach(res -> assertEquals(formTemplate, res.getFormTemplate()));
}


@Test
void findAllFullReturnsRecordsMatchingSpecifiedPage() {
final User author = generateAuthorWithInstitution();
Expand Down Expand Up @@ -408,7 +430,7 @@ void findAllRecordsReturnsPageWithMatchingRecords() {
final int pageSize = 3;

final Page<PatientRecordDto> result =
sut.findAllRecords(new RecordFilterParams(null, minDate, maxDate, Collections.emptySet()),
sut.findAllRecords(new RecordFilterParams(null, minDate, maxDate, Collections.emptySet(), Collections.emptySet()),
PageRequest.of(0, pageSize, Sort.Direction.ASC, RecordSort.SORT_DATE_PROPERTY));
assertEquals(Math.min(pageSize, allMatching.size()), result.getNumberOfElements());
assertEquals(allMatching.size(), result.getTotalElements());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void exportRecordsParsesProvidedDateBoundsAndPassesThemToService() throws Except
});
assertThat(result, containsSameEntities(records));
verify(patientRecordServiceMock).findAllFull(
new RecordFilterParams(null, minDate, maxDate, Collections.emptySet()), Pageable.unpaged());
new RecordFilterParams(null, minDate, maxDate, Collections.emptySet(), Collections.emptySet()), Pageable.unpaged());
}

@Test
Expand Down Expand Up @@ -298,7 +298,7 @@ void exportRecordsExportsRecordsForProvidedInstitutionForSpecifiedPeriod() throw
});
assertThat(result, containsSameEntities(records));
verify(patientRecordServiceMock).findAllFull(
new RecordFilterParams(user.getInstitution().getKey(), minDate, maxDate, Collections.emptySet()),
new RecordFilterParams(user.getInstitution().getKey(), minDate, maxDate, Collections.emptySet(), Collections.emptySet()),
Pageable.unpaged());
}

Expand Down Expand Up @@ -369,7 +369,7 @@ void getRecordsResolvesPagingConfigurationFromRequestParameters() throws Excepti
});
assertThat(result, containsSameEntities(records));
verify(patientRecordServiceMock).findAllFull(
new RecordFilterParams(null, minDate, maxDate, Collections.emptySet()),
new RecordFilterParams(null, minDate, maxDate, Collections.emptySet(), Collections.emptySet()),
PageRequest.of(page, pageSize, Sort.Direction.DESC, RecordSort.SORT_DATE_PROPERTY));
}

Expand Down Expand Up @@ -417,7 +417,7 @@ void exportRecordsPublishesPagingEvent() throws Exception {
});
assertThat(result, containsSameEntities(records));
verify(patientRecordServiceMock).findAllFull(
new RecordFilterParams(null, minDate, maxDate, Collections.emptySet()), PageRequest.of(0, 50));
new RecordFilterParams(null, minDate, maxDate, Collections.emptySet(), Collections.emptySet()), PageRequest.of(0, 50));
final ArgumentCaptor<PaginatedResultRetrievedEvent> captor =
ArgumentCaptor.forClass(PaginatedResultRetrievedEvent.class);
verify(eventPublisherMock).publishEvent(captor.capture());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,27 @@ static Stream<Arguments> testValues() {
Arguments.of(new LinkedMultiValueMap<>(Map.of(
"minDate", List.of(LocalDate.now().minusYears(1).toString())
)), new RecordFilterParams(null, LocalDate.now().minusYears(1), LocalDate.now(),
Collections.emptySet())),
Collections.emptySet(), Collections.emptySet())),
Arguments.of(new LinkedMultiValueMap<>(Map.of(
"minDate", List.of(LocalDate.now().minusYears(1).toString()),
"maxDate", List.of(LocalDate.now().minusDays(1).toString())
)), new RecordFilterParams(null, LocalDate.now().minusYears(1), LocalDate.now().minusDays(1),
Collections.emptySet())),
Collections.emptySet(), Collections.emptySet())),
Arguments.of(new LinkedMultiValueMap<>(Map.of(
"institution", List.of("1111111")
)), new RecordFilterParams("1111111", LocalDate.EPOCH, LocalDate.now(), Collections.emptySet())),
)), new RecordFilterParams("1111111", LocalDate.EPOCH, LocalDate.now(), Collections.emptySet(), Collections.emptySet())),
Arguments.of(new LinkedMultiValueMap<>(Map.of(
"institution", List.of("1111111"),
"phase", List.of(RecordPhase.open.getIri(), RecordPhase.completed.name())
)), new RecordFilterParams("1111111", LocalDate.EPOCH, LocalDate.now(),
Set.of(RecordPhase.open.getIri(), RecordPhase.completed.getIri()))),
Set.of(RecordPhase.open.getIri(), RecordPhase.completed.getIri()), Collections.emptySet())),
Arguments.of(new LinkedMultiValueMap<>(Map.of(
"minDate", List.of(LocalDate.now().minusYears(1).toString()),
"maxDate", List.of(LocalDate.now().minusDays(1).toString()),
"institution", List.of("1111111"),
"phase", List.of(RecordPhase.published.name())
)), new RecordFilterParams("1111111", LocalDate.now().minusYears(1), LocalDate.now().minusDays(1),
Set.of(RecordPhase.published.getIri())))
Set.of(RecordPhase.published.getIri()), Collections.emptySet()))
);
}
}

0 comments on commit a2a8a3f

Please sign in to comment.