Skip to content

Commit

Permalink
[kbss-cvut/record-manager-ui#38] Allow providing phase to set on all …
Browse files Browse the repository at this point in the history
…imported records.
  • Loading branch information
ledsoft committed Dec 19, 2023
1 parent 58e584e commit ee9872d
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 5 deletions.
16 changes: 16 additions & 0 deletions src/main/java/cz/cvut/kbss/study/model/RecordPhase.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,20 @@ public enum RecordPhase {
public String getIri() {
return iri;
}

/**
* Returns {@link RecordPhase} with the specified IRI.
*
* @param iri record phase identifier
* @return matching {@code RecordPhase}
* @throws IllegalArgumentException When no matching phase is found
*/
public static RecordPhase fromString(String iri) {
for (RecordPhase p : values()) {
if (p.getIri().equals(iri)) {
return p;
}
}
throw new IllegalArgumentException("Unknown record phase identifier '" + iri + "'.");
}
}
16 changes: 12 additions & 4 deletions src/main/java/cz/cvut/kbss/study/rest/PatientRecordController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import cz.cvut.kbss.study.exception.NotFoundException;
import cz.cvut.kbss.study.model.Institution;
import cz.cvut.kbss.study.model.PatientRecord;
import cz.cvut.kbss.study.model.RecordPhase;
import cz.cvut.kbss.study.rest.exception.BadRequestException;
import cz.cvut.kbss.study.rest.util.RecordFilterMapper;
import cz.cvut.kbss.study.rest.util.RestUtils;
Expand Down Expand Up @@ -96,10 +97,17 @@ public ResponseEntity<Void> createRecord(@RequestBody PatientRecord record) {
}

@PostMapping(value = "/import", consumes = MediaType.APPLICATION_JSON_VALUE)
public RecordImportResult importRecords(@RequestBody List<PatientRecord> records) {
final RecordImportResult result = recordService.importRecords(records);
LOG.trace("Records imported with result: {}.", result);
return result;
public RecordImportResult importRecords(@RequestBody List<PatientRecord> records,
@RequestParam(name = "phase", required = false) String phaseIri) {
final RecordImportResult importResult;
if (phaseIri != null) {
final RecordPhase targetPhase = RecordPhase.fromString(phaseIri);
importResult = recordService.importRecords(records, targetPhase);
} else {
importResult = recordService.importRecords(records);
}
LOG.trace("Records imported with result: {}.", importResult);
return importResult;
}

@PutMapping(value = "/{key}", consumes = MediaType.APPLICATION_JSON_VALUE)
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/cz/cvut/kbss/study/service/PatientRecordService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import cz.cvut.kbss.study.dto.RecordImportResult;
import cz.cvut.kbss.study.model.Institution;
import cz.cvut.kbss.study.model.PatientRecord;
import cz.cvut.kbss.study.model.RecordPhase;
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.persistence.dao.util.RecordFilterParams;

Expand Down Expand Up @@ -59,9 +60,24 @@ public interface PatientRecordService extends BaseService<PatientRecord> {
* The current user is set as the author of the records. Only records whose identifiers do not already exist in the
* repository are imported. Existing records are skipped and the returned object contains a note that the record
* already exists.
* <p>
* This method, in contrast to {@link #importRecords(List, RecordPhase)}, preserves the phase of the imported
* records.
*
* @param records Records to import
* @return Instance representing the import result
*/
RecordImportResult importRecords(List<PatientRecord> records);

/**
* Imports the specified records and sets them all to the specified phase.
* <p>
* The current user is set as the author of the records. Only records whose identifiers do not already exist in the
* repository are imported. Existing records are skipped and the returned object contains a note that the record
* already exists.
*
* @param records Records to import
* @return Instance representing the import result
*/
RecordImportResult importRecords(List<PatientRecord> records, RecordPhase targetPhase);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import cz.cvut.kbss.study.dto.RecordImportResult;
import cz.cvut.kbss.study.model.Institution;
import cz.cvut.kbss.study.model.PatientRecord;
import cz.cvut.kbss.study.model.RecordPhase;
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.persistence.dao.OwlKeySupportingDao;
import cz.cvut.kbss.study.persistence.dao.PatientRecordDao;
Expand Down Expand Up @@ -103,4 +104,13 @@ public RecordImportResult importRecords(List<PatientRecord> records) {
});
return result;
}

@Transactional
@Override
public RecordImportResult importRecords(List<PatientRecord> records, RecordPhase targetPhase) {
Objects.requireNonNull(records);
LOG.debug("Importing records to target phase '{}'.", targetPhase);
records.forEach(r -> r.setPhase(targetPhase));
return importRecords(records);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ public static PatientRecord generatePatientRecord(User author) {
rec.setLocalName("RandomRecord" + randomInt());
rec.setUri(generateUri());
rec.setInstitution(author.getInstitution());
rec.setPhase(RecordPhase.values()[Generator.randomInt(0, RecordPhase.values().length)]);
return rec;
}

Expand Down
26 changes: 26 additions & 0 deletions src/test/java/cz/cvut/kbss/study/model/RecordPhaseTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cz.cvut.kbss.study.model;

import cz.cvut.kbss.study.environment.generator.Generator;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class RecordPhaseTest {

@Test
void fromStringReturnsMatchingRecordPhase() {
for (RecordPhase p : RecordPhase.values()) {
assertEquals(p, RecordPhase.fromString(p.getIri()));
}
}

@Test
void fromStringThrowsIllegalArgumentForUnknownPhaseIri() {
assertThrows(IllegalArgumentException.class, () -> RecordPhase.fromString(Generator.generateUri().toString()));
}

@Test
void fromStringThrowsIllegalArgumentForNullArgument() {
assertThrows(IllegalArgumentException.class, () -> RecordPhase.fromString(null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import cz.cvut.kbss.study.environment.util.Environment;
import cz.cvut.kbss.study.model.Institution;
import cz.cvut.kbss.study.model.PatientRecord;
import cz.cvut.kbss.study.model.RecordPhase;
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.persistence.dao.util.RecordFilterParams;
import cz.cvut.kbss.study.service.InstitutionService;
Expand All @@ -30,19 +31,21 @@

import static cz.cvut.kbss.study.environment.util.ContainsSameEntities.containsSameEntities;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.anyOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(MockitoExtension.class)
public class PatientRecordControllerTest extends BaseControllerTestRunner {
Expand Down Expand Up @@ -315,4 +318,18 @@ void importRecordsImportsSpecifiedRecordsAndReturnsImportResult() throws Excepti
verify(patientRecordServiceMock).importRecords(captor.capture());
assertEquals(records.size(), captor.getValue().size());
}

@Test
void importRecordsImportsSpecifiedRecordsWithSpecifiedPhaseAndReturnsImportResult() throws Exception {
final List<PatientRecord> records =
List.of(Generator.generatePatientRecord(user), Generator.generatePatientRecord(user));
final RecordImportResult importResult = new RecordImportResult(records.size());
importResult.setImportedCount(records.size());
final RecordPhase targetPhase = RecordPhase.values()[Generator.randomInt(0, RecordPhase.values().length)];
when(patientRecordServiceMock.importRecords(anyList(), any(RecordPhase.class))).thenReturn(importResult);

mockMvc.perform(post("/records/import").content(toJson(records)).contentType(MediaType.APPLICATION_JSON)
.param("phase", targetPhase.getIri())).andExpect(status().isOk());
verify(patientRecordServiceMock).importRecords(anyList(), eq(targetPhase));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import cz.cvut.kbss.study.environment.generator.Generator;
import cz.cvut.kbss.study.environment.util.Environment;
import cz.cvut.kbss.study.model.PatientRecord;
import cz.cvut.kbss.study.model.RecordPhase;
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.persistence.dao.PatientRecordDao;
import cz.cvut.kbss.study.service.security.SecurityUtils;
Expand Down Expand Up @@ -100,4 +101,23 @@ void importRecordsSkipsImportingRecordsThatAlreadyExist() {
assertEquals(1, result.getErrors().size());
toImport.forEach(r -> verify(recordDao).exists(r.getUri()));
}

@Test
void importRecordsWithPhaseSetsSpecifiedPhaseToAllRecords() {
final List<PatientRecord> toImport =
List.of(Generator.generatePatientRecord(user), Generator.generatePatientRecord(user));
final User originalAuthor = Generator.generateUser(Generator.generateInstitution());
final RecordPhase targetPhase = RecordPhase.values()[Generator.randomInt(0, RecordPhase.values().length)];
toImport.forEach(r -> {
// Simulate that the records existed in another deployment from which they are imported
r.setKey(IdentificationUtils.generateKey());
r.setDateCreated(new Date(System.currentTimeMillis() - 10000L));
r.setAuthor(originalAuthor);
});

sut.importRecords(toImport, targetPhase);
final ArgumentCaptor<PatientRecord> captor = ArgumentCaptor.forClass(PatientRecord.class);
verify(recordDao, times(toImport.size())).persist(captor.capture());
captor.getAllValues().forEach(r -> assertEquals(targetPhase, r.getPhase()));
}
}

0 comments on commit ee9872d

Please sign in to comment.