diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java index 525a5e5b5..2113a0398 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java @@ -84,6 +84,7 @@ public class ExperimentProcessor implements Processor { private static final String NAME = "Experiment"; private static final String MISSING_OBS_UNIT_ID_ERROR = "Experimental entities are missing ObsUnitIDs"; + private static final String PREEXISTING_EXPERIMENT_TITLE = "Experiment Title already exists"; private static final String MULTIPLE_EXP_TITLES = "File contains more than one Experiment Title"; private static final String MIDNIGHT = "T00:00:00-00:00"; private static final String TIMESTAMP_PREFIX = "TS:"; @@ -1174,9 +1175,14 @@ private void fetchOrCreateLocationPIO(ExperimentObservation importRow) { } private PendingImportObject fetchOrCreateTrialPIO(Program program, User user, boolean commit, ExperimentObservation importRow, Supplier expNextVal) throws UnprocessableEntityException { - PendingImportObject pio; + PendingImportObject trialPio; if (trialByNameNoScope.containsKey(importRow.getExpTitle())) { - pio = trialByNameNoScope.get(importRow.getExpTitle()); + PendingImportObject envPio; + trialPio = trialByNameNoScope.get(importRow.getExpTitle()); + envPio = this.studyByNameNoScope.get(importRow.getEnv()); + if (trialPio!=null && ImportObjectState.EXISTING==trialPio.getState() && (StringUtils.isBlank( importRow.getObsUnitID() )) && (envPio!=null && ImportObjectState.EXISTING==envPio.getState() ) ){ + throw new UnprocessableEntityException(PREEXISTING_EXPERIMENT_TITLE); + } } else if (!trialByNameNoScope.isEmpty()) { throw new UnprocessableEntityException(MULTIPLE_EXP_TITLES); } else { @@ -1186,10 +1192,10 @@ private PendingImportObject fetchOrCreateTrialPIO(Program program, U expSeqValue = expNextVal.get().toString(); } BrAPITrial newTrial = importRow.constructBrAPITrial(program, user, commit, BRAPI_REFERENCE_SOURCE, id, expSeqValue); - pio = new PendingImportObject<>(ImportObjectState.NEW, newTrial, id); - this.trialByNameNoScope.put(importRow.getExpTitle(), pio); + trialPio = new PendingImportObject<>(ImportObjectState.NEW, newTrial, id); + this.trialByNameNoScope.put(importRow.getExpTitle(), trialPio); } - return pio; + return trialPio; } private void updateObservationDependencyValues(Program program) { diff --git a/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java b/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java index b3bcb0da1..7a797a815 100644 --- a/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java +++ b/src/test/java/org/breedinginsight/brapps/importer/ExperimentFileImportTest.java @@ -216,7 +216,7 @@ public void importNewExpNewLocNoObsSuccess() { @Test @SneakyThrows - public void importNewExpMultiNewEnvNoObsSuccess() { + public void importNewExpMultiNewEnvSuccess() { Program program = createProgram("New Exp and Multi New Env", "MULENV", "MULENV", BRAPI_REFERENCE_SOURCE, createGermplasm(1), null); Map firstEnv = new HashMap<>(); firstEnv.put(Columns.GERMPLASM_GID, "1"); @@ -282,15 +282,15 @@ public void importNewExpMultiNewEnvNoObsSuccess() { @Test @SneakyThrows - public void importNewEnvExistingExpNoObsSuccess() { - Program program = createProgram("New Env Existing Exp", "NEWENV", "NEWENV", BRAPI_REFERENCE_SOURCE, createGermplasm(1), null); + public void importExistingExpAndEnvErrorMessage() { + Program program = createProgram("New Env Existing Exp", "DUPENV", "DUPENV", BRAPI_REFERENCE_SOURCE, createGermplasm(1), null); Map newExp = new HashMap<>(); newExp.put(Columns.GERMPLASM_GID, "1"); newExp.put(Columns.TEST_CHECK, "T"); newExp.put(Columns.EXP_TITLE, "Test Exp"); newExp.put(Columns.EXP_UNIT, "Plot"); newExp.put(Columns.EXP_TYPE, "Phenotyping"); - newExp.put(Columns.ENV, "New Env"); + newExp.put(Columns.ENV, "Existing Env"); newExp.put(Columns.ENV_LOCATION, "Location A"); newExp.put(Columns.ENV_YEAR, "2023"); newExp.put(Columns.EXP_UNIT_ID, "a-1"); @@ -301,6 +301,38 @@ public void importNewEnvExistingExpNoObsSuccess() { JsonObject expResult = importTestUtils.uploadAndFetch(importTestUtils.writeExperimentDataToFile(List.of(newExp), null), null, true, client, program, mappingId); + Map dupExp = new HashMap<>(); + dupExp.put(Columns.GERMPLASM_GID, "1"); + dupExp.put(Columns.TEST_CHECK, "T"); + dupExp.put(Columns.EXP_TITLE, "Test Exp"); + dupExp.put(Columns.EXP_UNIT, "Plot"); + dupExp.put(Columns.EXP_TYPE, "Phenotyping"); + dupExp.put(Columns.ENV, "Existing Env"); + dupExp.put(Columns.ENV_LOCATION, "Location A"); + dupExp.put(Columns.ENV_YEAR, "2023"); + dupExp.put(Columns.EXP_UNIT_ID, "a-1"); + dupExp.put(Columns.REP_NUM, "1"); + dupExp.put(Columns.BLOCK_NUM, "1"); + dupExp.put(Columns.ROW, "1"); + dupExp.put(Columns.COLUMN, "1"); + + Flowable> call = importTestUtils.uploadDataFile(importTestUtils.writeExperimentDataToFile(List.of(dupExp), null), null, false, client, program, mappingId); + HttpResponse response = call.blockingFirst(); + assertEquals(HttpStatus.ACCEPTED, response.getStatus()); + + String importId = JsonParser.parseString(response.body()).getAsJsonObject().getAsJsonObject("result").get("importId").getAsString(); + + HttpResponse upload = importTestUtils.getUploadedFile(importId, client, program, mappingId); + JsonObject result = JsonParser.parseString(upload.body()).getAsJsonObject().getAsJsonObject("result"); + assertEquals(422, result.getAsJsonObject("progress").get("statuscode").getAsInt(), "Returned data: " + result); + assertTrue(result.getAsJsonObject("progress").get("message").getAsString().startsWith("Experiment Title already exists")); + } + + @Test + @SneakyThrows + public void importNewEnvNoObsSuccess() { + Program program = createProgram("New Env", "NEWENV", "NEWENV", BRAPI_REFERENCE_SOURCE, createGermplasm(1), null); + Map newEnv = new HashMap<>(); newEnv.put(Columns.GERMPLASM_GID, "1"); newEnv.put(Columns.TEST_CHECK, "T"); @@ -322,13 +354,14 @@ public void importNewEnvExistingExpNoObsSuccess() { assertEquals(1, previewRows.size()); JsonObject row = previewRows.get(0).getAsJsonObject(); - assertEquals("EXISTING", row.getAsJsonObject("trial").get("state").getAsString()); - assertEquals("EXISTING", row.getAsJsonObject("location").get("state").getAsString()); + assertEquals("NEW", row.getAsJsonObject("trial").get("state").getAsString()); + assertEquals("NEW", row.getAsJsonObject("location").get("state").getAsString()); assertEquals("NEW", row.getAsJsonObject("study").get("state").getAsString()); assertEquals("NEW", row.getAsJsonObject("observationUnit").get("state").getAsString()); assertRowSaved(newEnv, program, null); } + @ParameterizedTest @ValueSource(booleans = {true, false}) @SneakyThrows @@ -566,45 +599,46 @@ public void verifyFailureImportNewExpWithInvalidObs(boolean commit) { uploadAndVerifyFailure(program, importTestUtils.writeExperimentDataToFile(List.of(newExp), traits), traits.get(0).getObservationVariableName(), commit); } - @ParameterizedTest - @ValueSource(booleans = {true, false}) - @SneakyThrows - public void verifyFailureNewOuExistingEnv(boolean commit) { - Program program = createProgram("New OU Exising Env "+(commit ? "C" : "P"), "FLOU"+(commit ? "C" : "P"), "FLOU"+(commit ? "C" : "P"), BRAPI_REFERENCE_SOURCE, createGermplasm(1), null); - Map newExp = new HashMap<>(); - newExp.put(Columns.GERMPLASM_GID, "1"); - newExp.put(Columns.TEST_CHECK, "T"); - newExp.put(Columns.EXP_TITLE, "Test Exp"); - newExp.put(Columns.EXP_UNIT, "Plot"); - newExp.put(Columns.EXP_TYPE, "Phenotyping"); - newExp.put(Columns.ENV, "New Env"); - newExp.put(Columns.ENV_LOCATION, "Location A"); - newExp.put(Columns.ENV_YEAR, "2023"); - newExp.put(Columns.EXP_UNIT_ID, "a-1"); - newExp.put(Columns.REP_NUM, "1"); - newExp.put(Columns.BLOCK_NUM, "1"); - newExp.put(Columns.ROW, "1"); - newExp.put(Columns.COLUMN, "1"); - - importTestUtils.uploadAndFetch(importTestUtils.writeExperimentDataToFile(List.of(newExp), null), null, true, client, program, mappingId); - - Map newOU = new HashMap<>(newExp); - newOU.put(Columns.EXP_UNIT_ID, "a-2"); - newOU.put(Columns.ROW, "1"); - newOU.put(Columns.COLUMN, "2"); - - Flowable> call = importTestUtils.uploadDataFile(importTestUtils.writeExperimentDataToFile(List.of(newOU), null), null, commit, client, program, mappingId); - HttpResponse response = call.blockingFirst(); - assertEquals(HttpStatus.ACCEPTED, response.getStatus()); - - String importId = JsonParser.parseString(response.body()).getAsJsonObject().getAsJsonObject("result").get("importId").getAsString(); - - HttpResponse upload = importTestUtils.getUploadedFile(importId, client, program, mappingId); - JsonObject result = JsonParser.parseString(upload.body()).getAsJsonObject().getAsJsonObject("result"); - assertEquals(422, result.getAsJsonObject("progress").get("statuscode").getAsInt(), "Returned data: " + result); - - assertTrue(result.getAsJsonObject("progress").get("message").getAsString().startsWith("Experimental entities are missing ObsUnitIDs")); - } + // NO Longer needed, but may be needed in the future. +// @ParameterizedTest +// @ValueSource(booleans = {true, false}) +// @SneakyThrows +// public void verifyFailureNewOuExistingEnv(boolean commit) { +// Program program = createProgram("New OU Exising Env "+(commit ? "C" : "P"), "FLOU"+(commit ? "C" : "P"), "FLOU"+(commit ? "C" : "P"), BRAPI_REFERENCE_SOURCE, createGermplasm(1), null); +// Map newExp = new HashMap<>(); +// newExp.put(Columns.GERMPLASM_GID, "1"); +// newExp.put(Columns.TEST_CHECK, "T"); +// newExp.put(Columns.EXP_TITLE, "Test Exp"); +// newExp.put(Columns.EXP_UNIT, "Plot"); +// newExp.put(Columns.EXP_TYPE, "Phenotyping"); +// newExp.put(Columns.ENV, "New Env"); +// newExp.put(Columns.ENV_LOCATION, "Location A"); +// newExp.put(Columns.ENV_YEAR, "2023"); +// newExp.put(Columns.EXP_UNIT_ID, "a-1"); +// newExp.put(Columns.REP_NUM, "1"); +// newExp.put(Columns.BLOCK_NUM, "1"); +// newExp.put(Columns.ROW, "1"); +// newExp.put(Columns.COLUMN, "1"); +// +// importTestUtils.uploadAndFetch(importTestUtils.writeExperimentDataToFile(List.of(newExp), null), null, true, client, program, mappingId); +// +// Map newOU = new HashMap<>(newExp); +// newOU.put(Columns.EXP_UNIT_ID, "a-2"); +// newOU.put(Columns.ROW, "1"); +// newOU.put(Columns.COLUMN, "2"); +// +// Flowable> call = importTestUtils.uploadDataFile(importTestUtils.writeExperimentDataToFile(List.of(newOU), null), null, commit, client, program, mappingId); +// HttpResponse response = call.blockingFirst(); +// assertEquals(HttpStatus.ACCEPTED, response.getStatus()); +// +// String importId = JsonParser.parseString(response.body()).getAsJsonObject().getAsJsonObject("result").get("importId").getAsString(); +// +// HttpResponse upload = importTestUtils.getUploadedFile(importId, client, program, mappingId); +// JsonObject result = JsonParser.parseString(upload.body()).getAsJsonObject().getAsJsonObject("result"); +// assertEquals(422, result.getAsJsonObject("progress").get("statuscode").getAsInt(), "Returned data: " + result); +// +// assertTrue(result.getAsJsonObject("progress").get("message").getAsString().startsWith("Experimental entities are missing ObsUnitIDs")); +// } @Test @SneakyThrows