Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kbss-cvut/record-manager-ui#168] Add filtering of records according … #51

Merged
merged 2 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()))
);
}
}
Loading