added possibility to specify non existing elements

This commit is contained in:
dashevchenko 2023-02-12 23:40:12 +02:00
parent 4a9c4cc614
commit f812e02920
2 changed files with 46 additions and 14 deletions

View File

@ -778,41 +778,68 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
JsonNode expectedSettings = mapper.readTree("{\"A\":10, \"B\":{\"C\":true, \"D\":\"stringValue\"}}");
Assert.assertEquals(expectedSettings, updatedSettings);
JsonNode patchedSettings = mapper.readTree("{\"B\":{\"C\":false, \"D\":\"stringValue2\"}}");
JsonNode patchedSettings = mapper.readTree("{\"A\":11, \"B\":{\"C\":false, \"D\":\"stringValue2\"}}");
doPut("/api/user/settings", patchedSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":10, \"B\":{\"C\":false, \"D\":\"stringValue2\"}}");
expectedSettings = mapper.readTree("{\"A\":11, \"B\":{\"C\":false, \"D\":\"stringValue2\"}}");
Assert.assertEquals(expectedSettings, updatedSettings);
patchedSettings = mapper.readTree("{\"B.D\": \"stringValue3\"}");
doPut("/api/user/settings", patchedSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":10, \"B\":{\"C\":false, \"D\": \"stringValue3\"}}");
expectedSettings = mapper.readTree("{\"A\":11, \"B\":{\"C\":false, \"D\": \"stringValue3\"}}");
Assert.assertEquals(expectedSettings, updatedSettings);
patchedSettings = mapper.readTree("{\"B.D\": {\"E\": 76, \"F\": 92}}");
doPut("/api/user/settings", patchedSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":10, \"B\":{\"C\":false, \"D\": {\"E\":76, \"F\": 92}}}");
expectedSettings = mapper.readTree("{\"A\":11, \"B\":{\"C\":false, \"D\": {\"E\":76, \"F\": 92}}}");
Assert.assertEquals(expectedSettings, updatedSettings);
patchedSettings = mapper.readTree("{\"B.D.E\": 100}");
doPut("/api/user/settings", patchedSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":10, \"B\":{\"C\":false, \"D\": {\"E\":100, \"F\": 92}}}");
expectedSettings = mapper.readTree("{\"A\":11, \"B\":{\"C\":false, \"D\": {\"E\":100, \"F\": 92}}}");
Assert.assertEquals(expectedSettings, updatedSettings);
}
@Test
public void testShouldNotUpdateUserSettingsWithNoExistingPath() throws Exception {
public void testShouldCreatePathIfNotExists() throws Exception {
loginCustomerUser();
JsonNode userSettings = mapper.readTree("{\"A\":5, \"B\":{\"C\":true, \"D\":\"stringValue\"}}");
JsonNode userSettings = mapper.readTree("{\"A\":5}");
JsonNode savedSettings = doPost("/api/user/settings", userSettings, JsonNode.class);
Assert.assertEquals(userSettings, savedSettings);
JsonNode newSettings = mapper.readTree("{\"A.E\":10}");
doPut("/api/user/settings", newSettings).andExpect(status().isBadRequest());
JsonNode newSettings = mapper.readTree("{\"B\":{\"C\": 10}}");
doPut("/api/user/settings", newSettings);
JsonNode updatedSettings = doGet("/api/user/settings", JsonNode.class);
JsonNode expectedSettings = mapper.readTree("{\"A\":5, \"B\":{\"C\": 10}}");
Assert.assertEquals(expectedSettings, updatedSettings);
newSettings = mapper.readTree("{\"B.K\":true}");
doPut("/api/user/settings", newSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":5, \"B\":{\"C\": 10, \"K\": true}}");
Assert.assertEquals(expectedSettings, updatedSettings);
newSettings = mapper.readTree("{\"B\":{}}");
doPut("/api/user/settings", newSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":5, \"B\":{}}");
Assert.assertEquals(expectedSettings, updatedSettings);
newSettings = mapper.readTree("{\"F.G\":\"string\"}");
doPut("/api/user/settings", newSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":5, \"B\":{}, \"F\":{\"G\": \"string\"}}");
Assert.assertEquals(expectedSettings, updatedSettings);
newSettings = mapper.readTree("{\"F\":{\"G\":\"string2\"}}");
doPut("/api/user/settings", newSettings);
updatedSettings = doGet("/api/user/settings", JsonNode.class);
expectedSettings = mapper.readTree("{\"A\":5, \"B\":{}, \"F\":{\"G\": \"string2\"}}");
Assert.assertEquals(expectedSettings, updatedSettings);
}
@Test

View File

@ -37,6 +37,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -135,7 +136,7 @@ public class UserSettingsServiceImpl extends AbstractCachedService<UserId, UserS
Iterator<String> fieldNames = updateNode.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
validatePathExists(dcOldSettings, fieldName);
createPathIfNotExists(dcOldSettings, "$."+ fieldName);
dcOldSettings = dcOldSettings.set("$." + fieldName, getValueByNodeType(updateNode.get(fieldName)));
}
try {
@ -145,11 +146,15 @@ public class UserSettingsServiceImpl extends AbstractCachedService<UserId, UserS
}
}
private static void validatePathExists(DocumentContext dcOldSettings, String fieldName) {
private static String createPathIfNotExists(DocumentContext dcOldSettings, String path) {
try {
dcOldSettings.read("$." + fieldName);
}catch (PathNotFoundException e) {
throw new DataValidationException("Json element with path " + fieldName + "was not found");
dcOldSettings.read(path);
return path;
} catch (PathNotFoundException e) {
String lastElement = path.substring(path.lastIndexOf(".") + 1);
String pathToLastElement = path.substring(0, path.lastIndexOf("."));
dcOldSettings.put(createPathIfNotExists(dcOldSettings, pathToLastElement), lastElement, new LinkedHashMap<String, Object>());
return path;
}
}