Skip to content

Commit d9d6903

Browse files
authored
Merge pull request #11748 from IQSS/11387-fix-inputLevel-api
11387 fix input level api
2 parents 3ec96b2 + 9cc6b8e commit d9d6903

File tree

7 files changed

+119
-13
lines changed

7 files changed

+119
-13
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Update Collection Input Level API Changed
2+
3+
- This endpoint will no longer delete the custom input levels previously modified for the given collection. In order to update a previously modified custom input level, it must be included in the JSON provided to the api.

doc/sphinx-guides/source/api/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ v6.8
1313
- For POST /api/files/{id}/metadata passing an empty string ("description":"") or array ("categories":[]) will no longer be ignored. Empty fields will now clear out the values in the file's metadata. To ignore the fields simply do not include them in the JSON string.
1414
- For PUT /api/datasets/{id}/editMetadata the query parameter "sourceInternalVersionNumber" has been removed and replaced with "sourceLastUpdateTime" to verify that the data being edited hasn't been modified and isn't stale.
1515
- For GET /api/dataverses/$dataverse-alias/links the Json response has changed breaking the backward compatibility of the API.
16+
- For PUT /api/dataverses/$dataverse-alias/inputLevels custom input levels that had been previously set will no longer be deleted. To delete input levels send an empty list (deletes all), then send the new/modified list.
1617
- For GET /api/externalTools and /api/externalTools/{id} the responses are now formatted as JSON (previously the toolParameters and allowedApiCalls were a JSON object and array (respectively) that were serialized as JSON strings) and any configured "requirements" are included.
1718

1819
v6.7

doc/sphinx-guides/source/api/native-api.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,8 @@ Update Collection Input Levels
11061106

11071107
Updates the dataset field type input levels in a collection.
11081108

1109-
Please note that this endpoint overwrites all the input levels of the collection page, so if you want to keep the existing ones, you will need to add them to the JSON request body.
1109+
Please note that this endpoint does not change previously updated input levels of the collection page, so if you want to add new levels or modify existing ones, you will need to include them in the JSON request body.
1110+
In order to delete input levels you must call this API with an empty list to delete all of the input levels, then call this API with the new list of input levels.
11101111

11111112
If one of the input levels corresponds to a dataset field type belonging to a metadata block that does not exist in the collection, the metadata block will be added to the collection.
11121113

src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AbstractWriteDataverseCommand.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ private void processInputLevels(CommandContext ctxt) {
105105
ctxt.fieldTypeInputLevels().deleteDataverseFieldTypeInputLevelFor(dataverse);
106106
} else {
107107
dataverse.addInputLevelsMetadataBlocksIfNotPresent(inputLevels);
108-
ctxt.fieldTypeInputLevels().deleteDataverseFieldTypeInputLevelFor(dataverse);
108+
//if levels not empty either create or update (handled by save - update when id not null create if null)
109109
inputLevels.forEach(inputLevel -> {
110+
DataverseFieldTypeInputLevel ftil = ctxt.fieldTypeInputLevels().findByDataverseIdDatasetFieldTypeId(dataverse.getId(), inputLevel.getDatasetFieldType().getId());
111+
if(ftil != null){
112+
inputLevel.setId(ftil.getId());
113+
}
110114
inputLevel.setDataverse(dataverse);
111-
ctxt.fieldTypeInputLevels().create(inputLevel);
115+
ctxt.fieldTypeInputLevels().save(inputLevel);
112116
});
113117
}
114118
}

src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,77 @@ public void testUpdateInputLevels() {
12551255
updateDataverseInputLevelsResponse.then().assertThat()
12561256
.body("message", equalTo("Error while updating dataverse input levels: Input level list cannot be null or empty"))
12571257
.statusCode(INTERNAL_SERVER_ERROR.getStatusCode());
1258+
1259+
//Add new types and see that previously changed ones remain as before... #11387
1260+
testInputLevelNames = new String[]{"subtitle", "relatedMaterial"};
1261+
1262+
testRequiredInputLevels = new boolean[] {false, false};
1263+
testIncludedInputLevels = new boolean[] {true, true};
1264+
boolean [] testDisplayOnCreate = new boolean[] {true, false};
1265+
updateDataverseInputLevelsResponse = UtilIT.updateDataverseInputLevels(dataverseAlias, testInputLevelNames, testRequiredInputLevels, testIncludedInputLevels, testDisplayOnCreate, apiToken);
1266+
updateDataverseInputLevelsResponse.prettyPrint();
1267+
int subtitleInputLevelIndex = -1;
1268+
int relatedMaterialInputLevelIndex = -1;
1269+
int i = 0;
1270+
1271+
while (updateDataverseInputLevelsResponse.then().extract().path(String.format("data.inputLevels[%d].datasetFieldTypeName", i)) != null){
1272+
actualInputLevelName = updateDataverseInputLevelsResponse.then().extract().path(String.format("data.inputLevels[%d].datasetFieldTypeName", i)).toString();
1273+
if (actualInputLevelName.equals("subtitle")){
1274+
subtitleInputLevelIndex = i;
1275+
}
1276+
if (actualInputLevelName.equals("relatedMaterial")){
1277+
relatedMaterialInputLevelIndex = i;
1278+
}
1279+
i++;
1280+
}
1281+
1282+
updateDataverseInputLevelsResponse.then().assertThat()
1283+
.body(String.format("data.inputLevels[%d].include", subtitleInputLevelIndex), equalTo(true))
1284+
.body(String.format("data.inputLevels[%d].required", subtitleInputLevelIndex), equalTo(false))
1285+
.body(String.format("data.inputLevels[%d].displayOnCreate", subtitleInputLevelIndex), equalTo(true))
1286+
.body(String.format("data.inputLevels[%d].include", relatedMaterialInputLevelIndex), equalTo(true))
1287+
.body(String.format("data.inputLevels[%d].required", relatedMaterialInputLevelIndex), equalTo(false))
1288+
.body(String.format("data.inputLevels[%d].displayOnCreate", relatedMaterialInputLevelIndex), equalTo(false))
1289+
.statusCode(OK.getStatusCode());
1290+
1291+
actualFieldTypeName1 = updateDataverseInputLevelsResponse.then().extract().path(String.format("data.inputLevels[%d].datasetFieldTypeName", subtitleInputLevelIndex));
1292+
actualFieldTypeName2 = updateDataverseInputLevelsResponse.then().extract().path(String.format("data.inputLevels[%d].datasetFieldTypeName", relatedMaterialInputLevelIndex));
1293+
assertNotEquals(actualFieldTypeName1, actualFieldTypeName2);
1294+
assertThat(testInputLevelNames, hasItemInArray(actualFieldTypeName1));
1295+
assertThat(testInputLevelNames, hasItemInArray(actualFieldTypeName2));
1296+
1297+
1298+
testInputLevelNames = new String[]{"subtitle", "otherReferences"};
1299+
testRequiredInputLevels = new boolean[] {false, false};
1300+
testIncludedInputLevels = new boolean[] {true, true};
1301+
testDisplayOnCreate = new boolean[] {false, true};
1302+
1303+
updateDataverseInputLevelsResponse = UtilIT.updateDataverseInputLevels(dataverseAlias, testInputLevelNames, testRequiredInputLevels, testIncludedInputLevels, testDisplayOnCreate, apiToken);
1304+
updateDataverseInputLevelsResponse.prettyPrint();
1305+
1306+
subtitleInputLevelIndex = 0;
1307+
i = 0;
1308+
1309+
while (updateDataverseInputLevelsResponse.then().extract().path(String.format("data.inputLevels[%d].datasetFieldTypeName", i)) != null) {
1310+
actualInputLevelName = updateDataverseInputLevelsResponse.then().extract().path(String.format("data.inputLevels[%d].datasetFieldTypeName", i)).toString();
1311+
if (actualInputLevelName.equals("subtitle")) {
1312+
subtitleInputLevelIndex = i;
1313+
}
1314+
i++;
1315+
}
1316+
1317+
//make sure subtitle got changed to false
1318+
updateDataverseInputLevelsResponse.then().assertThat()
1319+
.body(String.format("data.inputLevels[%d].displayOnCreate", subtitleInputLevelIndex), equalTo(false))
1320+
.statusCode(OK.getStatusCode());
1321+
1322+
//make superuser for cleanup
1323+
String username = UtilIT.getUsernameFromResponse(createUserResponse);
1324+
UtilIT.setSuperuserStatus(username, Boolean.TRUE);
1325+
Response deleteDataverse1Response = UtilIT.deleteDataverse(dataverseAlias, apiToken);
1326+
deleteDataverse1Response.prettyPrint();
1327+
assertEquals(200, deleteDataverse1Response.getStatusCode());
1328+
12581329
}
12591330

12601331
@Test
@@ -2256,12 +2327,17 @@ public void testUpdateInputLevelDisplayOnCreateOverride() {
22562327
.body("data.inputLevels[0].displayOnCreate", equalTo(true))
22572328
.body("data.inputLevels[0].datasetFieldTypeName", equalTo("notesText"));
22582329

2330+
22592331
updateResponse = UtilIT.updateDataverseInputLevelDisplayOnCreate(
22602332
dataverseAlias, "subtitle", true, apiToken);
2333+
2334+
String actualInputLevelName = updateResponse.then().extract().path("data.inputLevels[0].datasetFieldTypeName");
2335+
int subtitleInputLevelIndex = actualInputLevelName.equals("subtitle") ? 0 : 1;
2336+
updateResponse.prettyPrint();
22612337
updateResponse.then().assertThat()
22622338
.statusCode(OK.getStatusCode())
2263-
.body("data.inputLevels[0].displayOnCreate", equalTo(true))
2264-
.body("data.inputLevels[0].datasetFieldTypeName", equalTo("subtitle"));
2339+
.body(String.format("data.inputLevels[%d].displayOnCreate", subtitleInputLevelIndex), equalTo(true))
2340+
.body(String.format("data.inputLevels[%d].datasetFieldTypeName", subtitleInputLevelIndex), equalTo("subtitle"));
22652341

22662342
listMetadataBlocksResponse = UtilIT.listMetadataBlocks(dataverseAlias, true, true, apiToken);
22672343
listMetadataBlocksResponse.prettyPrint();
@@ -2274,14 +2350,15 @@ public void testUpdateInputLevelDisplayOnCreateOverride() {
22742350
.body("data[0].displayName", equalTo("Citation Metadata"))
22752351
.body("data.size()", equalTo(expectedOnlyDisplayedOnCreateNumberOfMetadataBlocks))
22762352
.body("data[0].fields.author.childFields.size()", is(4));
2277-
2278-
updateResponse = UtilIT.updateDataverseInputLevelDisplayOnCreate(
2279-
dataverseAlias, "subtitle", false, apiToken);
2353+
2354+
updateResponse = UtilIT.updateDataverseInputLevelDisplayOnCreate(dataverseAlias, "subtitle", false, apiToken);
2355+
actualInputLevelName = updateResponse.then().extract().path("data.inputLevels[0].datasetFieldTypeName");
2356+
int subtitleIndex = actualInputLevelName.equals("subtitle") ? 0 : 1;
22802357
updateResponse.then().assertThat()
2281-
.statusCode(OK.getStatusCode())
2282-
.body("data.inputLevels[0].displayOnCreate", equalTo(false))
2283-
.body("data.inputLevels[0].datasetFieldTypeName", equalTo("subtitle"));
2284-
2358+
.body(String.format("data.inputLevels[%d].displayOnCreate", subtitleIndex), equalTo(false))
2359+
.body(String.format("data.inputLevels[%d].datasetFieldTypeName", subtitleIndex), equalTo("subtitle"))
2360+
.statusCode(OK.getStatusCode());
2361+
22852362
}
22862363

22872364
@Test

src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4533,13 +4533,33 @@ public static Response updateDataverseInputLevels(String dataverseAlias, String[
45334533
.contentType(ContentType.JSON)
45344534
.put("/api/dataverses/" + dataverseAlias + "/inputLevels");
45354535
}
4536+
4537+
public static Response updateDataverseInputLevels(String dataverseAlias, String[] inputLevelNames, boolean[] requiredInputLevels, boolean[] includedInputLevels, boolean[] displayOnCreate, String apiToken) {
4538+
JsonArrayBuilder inputLevelsArrayBuilder = Json.createArrayBuilder();
4539+
for (int i = 0; i < inputLevelNames.length; i++) {
4540+
inputLevelsArrayBuilder.add(createInputLevelObject(inputLevelNames[i], requiredInputLevels[i], includedInputLevels[i], displayOnCreate[i]));
4541+
}
4542+
return given()
4543+
.header(API_TOKEN_HTTP_HEADER, apiToken)
4544+
.body(inputLevelsArrayBuilder.build().toString())
4545+
.contentType(ContentType.JSON)
4546+
.put("/api/dataverses/" + dataverseAlias + "/inputLevels");
4547+
}
45364548

45374549
private static JsonObjectBuilder createInputLevelObject(String name, boolean required, boolean include) {
45384550
return Json.createObjectBuilder()
45394551
.add("datasetFieldTypeName", name)
45404552
.add("required", required)
45414553
.add("include", include);
45424554
}
4555+
4556+
private static JsonObjectBuilder createInputLevelObject(String name, boolean required, boolean include, boolean displayOnCreate) {
4557+
return Json.createObjectBuilder()
4558+
.add("datasetFieldTypeName", name)
4559+
.add("required", required)
4560+
.add("include", include)
4561+
.add("displayOnCreate", displayOnCreate);
4562+
}
45434563

45444564
public static Response getOpenAPI(String accept, String format) {
45454565
Response response = given()

src/test/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDataverseCommandTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public void testCustomOptions() throws CommandException {
307307
i++;
308308
}
309309

310-
assertTrue( dftilsDeleted );
310+
// assertTrue( dftilsDeleted ); we no longer delete when adding new input levels to preserve previously created
311311
for ( DataverseFieldTypeInputLevel dftil : createdDftils ) {
312312
assertEquals( result, dftil.getDataverse() );
313313
}

0 commit comments

Comments
 (0)