diff --git a/src/main/java/com/github/fge/jsonpatch/AddOperation.java b/src/main/java/com/github/fge/jsonpatch/AddOperation.java index 66d86cf5..759fe5de 100644 --- a/src/main/java/com/github/fge/jsonpatch/AddOperation.java +++ b/src/main/java/com/github/fge/jsonpatch/AddOperation.java @@ -22,11 +22,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.github.fge.jackson.jsonpointer.JsonPointer; -import com.github.fge.jackson.jsonpointer.ReferenceToken; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; @@ -83,23 +79,41 @@ public JsonNode apply(final JsonNode node) throws JsonPatchException { * Check the parent node: it must exist and be a container (ie an array * or an object) for the add operation to work. */ - final int lastSlashIndex = path.lastIndexOf('/'); - final String newNodeName = path.substring(lastSlashIndex + 1); - final String pathToParent = path.substring(0, lastSlashIndex); - final String jsonPath = JsonPathParser.tmfStringToJsonPath(pathToParent); + final String fullJsonPath = JsonPathParser.tmfStringToJsonPath(path); + final int lastDotIndex = fullJsonPath.lastIndexOf('.'); + final String newNodeName = fullJsonPath.substring(lastDotIndex + 1) + .replace("[", "").replace("]", ""); + final String pathToParent = fullJsonPath.substring(0, lastDotIndex); + final DocumentContext nodeContext = JsonPath.parse(node.deepCopy()); - final JsonNode parentNode = nodeContext.read(jsonPath); - if (parentNode == null) { + final JsonNode evaluatedJsonParents = nodeContext.read(pathToParent); + if (evaluatedJsonParents == null) { throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.noSuchParent")); } - if (!parentNode.isContainerNode()) { + if (!evaluatedJsonParents.isContainerNode()) { throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.parentNotContainer")); } - return parentNode.isArray() - ? addToArray(nodeContext, jsonPath, newNodeName) - : addToObject(nodeContext, jsonPath, newNodeName); + if (pathToParent.contains("[?(")) { // json filter result is always a list + for (int i = 0; i < evaluatedJsonParents.size(); i++) { + JsonNode parentNode = evaluatedJsonParents.get(i); + if (!parentNode.isContainerNode()) { + throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.parentNotContainer")); + } + DocumentContext containerContext = JsonPath.parse(parentNode); + if (parentNode.isArray()) { + addToArray(containerContext, "$", newNodeName); + } else { + addToObject(containerContext, "$", newNodeName); + } + } + return nodeContext.read("$"); + } else { + return evaluatedJsonParents.isArray() + ? addToArray(nodeContext, pathToParent, newNodeName) + : addToObject(nodeContext, pathToParent, newNodeName); + } } private JsonNode addToArray(final DocumentContext node, String jsonPath, String newNodeName) throws JsonPatchException { @@ -108,14 +122,7 @@ private JsonNode addToArray(final DocumentContext node, String jsonPath, String } final int size = node.read(jsonPath, JsonNode.class).size(); - final int index; - try { - index = Integer.parseInt(newNodeName); - } catch (NumberFormatException ignored) { - throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.notAnIndex")); - } - if (index < 0 || index > size) - throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.noSuchIndex")); + final int index = verifyAndGetArrayIndex(newNodeName, size); ArrayNode updatedArray = node.read(jsonPath, ArrayNode.class).insert(index, value); return "$".equals(jsonPath) ? updatedArray : node.set(jsonPath, updatedArray).read("$", JsonNode.class); @@ -126,4 +133,17 @@ private JsonNode addToObject(final DocumentContext node, String jsonPath, String .put(jsonPath, newNodeName, value) .read("$", JsonNode.class); } + + private int verifyAndGetArrayIndex(String stringIndex, int size) throws JsonPatchException { + int index; + try { + index = Integer.parseInt(stringIndex); + } catch (NumberFormatException ignored) { + throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.notAnIndex")); + } + if (index < 0 || index > size) { + throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.noSuchIndex")); + } + return index; + } } diff --git a/src/main/java/com/github/fge/jsonpatch/DualPathOperation.java b/src/main/java/com/github/fge/jsonpatch/DualPathOperation.java index d26f7b8c..41d4a49d 100644 --- a/src/main/java/com/github/fge/jsonpatch/DualPathOperation.java +++ b/src/main/java/com/github/fge/jsonpatch/DualPathOperation.java @@ -51,8 +51,8 @@ protected DualPathOperation(final String op, final String from, final String pat public final void serialize(final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeStringField("op", op); - jgen.writeStringField("path", path.toString()); - jgen.writeStringField("from", from.toString()); + jgen.writeStringField("path", path); + jgen.writeStringField("from", from); jgen.writeEndObject(); } diff --git a/src/main/java/com/github/fge/jsonpatch/JsonPatchOperation.java b/src/main/java/com/github/fge/jsonpatch/JsonPatchOperation.java index b0109ce2..de406eba 100644 --- a/src/main/java/com/github/fge/jsonpatch/JsonPatchOperation.java +++ b/src/main/java/com/github/fge/jsonpatch/JsonPatchOperation.java @@ -24,7 +24,6 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonSerializable; -import com.github.fge.jackson.jsonpointer.JsonPointer; import com.github.fge.msgsimple.bundle.MessageBundle; import com.github.fge.msgsimple.load.MessageBundles; import com.jayway.jsonpath.Configuration; diff --git a/src/main/java/com/github/fge/jsonpatch/JsonPathParser.java b/src/main/java/com/github/fge/jsonpatch/JsonPathParser.java index 00467216..4c6e2f7b 100644 --- a/src/main/java/com/github/fge/jsonpatch/JsonPathParser.java +++ b/src/main/java/com/github/fge/jsonpatch/JsonPathParser.java @@ -1,17 +1,49 @@ package com.github.fge.jsonpatch; +import static com.github.fge.jsonpatch.JsonPatchOperation.BUNDLE; + public class JsonPathParser { private static final String ARRAY_ELEMENT_REGEX = "\\.(\\d+)\\."; private static final String ARRAY_ELEMENT_LAST_REGEX = "\\.(\\d+)$"; - public static String tmfStringToJsonPath(String path) { + public static String tmfStringToJsonPath(String path) throws JsonPatchException { + if (!path.startsWith("/") && !path.isEmpty()) { + return "$." + path; + } if ("/".equals(path)) { return "$"; } - final String jsonPath = "$" + path.replace('/', '.') + final String[] pointerAndQuery = path + .replaceAll("(\\w)\\?", "$1#THIS_IS_SPLIT_PLACEHOLDER#") + .split("#THIS_IS_SPLIT_PLACEHOLDER#", -1); + if (pointerAndQuery.length > 2) { + throw new JsonPatchException(BUNDLE.getMessage("jsonPatch.invalidPathExpression")); + } + + final String jsonPath = "$" + pointerAndQuery[0].replace('/', '.') .replaceAll(ARRAY_ELEMENT_REGEX, ".[$1].") + .replaceAll(ARRAY_ELEMENT_REGEX, ".[$1].") // has to be repeated due to positive lookahead not working properly .replaceAll(ARRAY_ELEMENT_LAST_REGEX, ".[$1]"); - return jsonPath; + final String jsonPathWithQuery = addQueryIfApplicable(jsonPath, pointerAndQuery); + return jsonPathWithQuery; + } + + private static String addQueryIfApplicable(String jsonPath, String[] pointerAndQuery) { + if (pointerAndQuery.length == 2) { + String preparedFilter = pointerAndQuery[1] + .replaceAll("]", "] empty false") // add empty false to nested array expressions + .replaceAll("(\\w)=(\\w)", "$1==$2") // replace single equals with double + .replaceAll("==([\\w .]+)", "=='$1'") // surround strings with single quotes + .replaceFirst("\\w+", "@") // jsonpath expression should start with @ as the name of item + .replaceAll("([&|])\\w+", " $1$1 @"); // replace single | and & with doubles + String filterWithBooleansAndNumbers = preparedFilter + .replaceAll("@([\\w.]+)=='(true|false)'", "(@$1==$2 || @$1=='$2')") // prepare a statement for boolean and boolean as string + .replaceAll("@([\\w.]+)=='(\\d+)'", "(@$1==$2 || @$1=='$2')") // prepare a statement for an integer and integer as string + .replaceAll("@([\\w.]+)=='(\\d+\\.\\d+)'", "(@$1==$2 || @$1=='$2')"); // prepare a statement for float and float as string + return jsonPath.replaceFirst("(\\w+)", "$1[?(" + filterWithBooleansAndNumbers + ")]"); + } else { + return jsonPath; + } } } diff --git a/src/main/java/com/github/fge/jsonpatch/MoveOperation.java b/src/main/java/com/github/fge/jsonpatch/MoveOperation.java index 138214bc..df6850a9 100644 --- a/src/main/java/com/github/fge/jsonpatch/MoveOperation.java +++ b/src/main/java/com/github/fge/jsonpatch/MoveOperation.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import com.github.fge.jackson.jsonpointer.JsonPointer; import com.jayway.jsonpath.JsonPath; /** diff --git a/src/main/java/com/github/fge/jsonpatch/PathValueOperation.java b/src/main/java/com/github/fge/jsonpatch/PathValueOperation.java index acfa12ab..e3dab45b 100644 --- a/src/main/java/com/github/fge/jsonpatch/PathValueOperation.java +++ b/src/main/java/com/github/fge/jsonpatch/PathValueOperation.java @@ -25,7 +25,6 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -import com.github.fge.jackson.jsonpointer.JsonPointer; import java.io.IOException; diff --git a/src/main/java/com/github/fge/jsonpatch/ReplaceOperation.java b/src/main/java/com/github/fge/jsonpatch/ReplaceOperation.java index 274fab37..c31a8076 100644 --- a/src/main/java/com/github/fge/jsonpatch/ReplaceOperation.java +++ b/src/main/java/com/github/fge/jsonpatch/ReplaceOperation.java @@ -22,9 +22,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.github.fge.jackson.jsonpointer.JsonPointer; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; diff --git a/src/main/resources/com/github/fge/jsonpatch/messages.properties b/src/main/resources/com/github/fge/jsonpatch/messages.properties index 668240ca..7bee4508 100644 --- a/src/main/resources/com/github/fge/jsonpatch/messages.properties +++ b/src/main/resources/com/github/fge/jsonpatch/messages.properties @@ -27,4 +27,5 @@ jsonPatch.noSuchIndex=no such index in target array jsonPatch.noSuchPath=no such path in target JSON document jsonPatch.parentNotContainer=parent of path to add to is not a container jsonPatch.valueTestFailure=value differs from expectations +jsonPatch.invalidPathExpression=invalid path expression mergePatch.notContainer=value is neither an object or an array (found %s) diff --git a/src/test/java/com/github/fge/jsonpatch/JsonPathParserTest.java b/src/test/java/com/github/fge/jsonpatch/JsonPathParserTest.java new file mode 100644 index 00000000..48feab05 --- /dev/null +++ b/src/test/java/com/github/fge/jsonpatch/JsonPathParserTest.java @@ -0,0 +1,81 @@ +package com.github.fge.jsonpatch; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class JsonPathParserTest { + + @Test + public void shouldConvertQueryToJsonPath() throws JsonPatchException { + String jsonPointerWithQuery = "/productPrice/prodPriceAlteration?productPrice.name=Regular Price"; + String expected = "$.productPrice[?(@.name=='Regular Price')].prodPriceAlteration"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertArrayPathToJsonPath() throws JsonPatchException { + String jsonPointerWithQuery = "/2/1/-"; + String expected = "$.[2].[1].-"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertBooleans() throws JsonPatchException { + String jsonPointerWithQuery = "/orderItem/quantity?orderItem.productOffering.valid=true&orderItem.product.relatedParty.role=customer"; + String expected = "$.orderItem[?((@.productOffering.valid==true || @.productOffering.valid=='true') && @.product.relatedParty.role=='customer')].quantity"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertFloatingPoint() throws JsonPatchException { + String jsonPointerWithQuery = "/orderItem/quantity?orderItem.productOffering.price=1513.77&orderItem.product.relatedParty.role=customer"; + String expected = "$.orderItem[?((@.productOffering.price==1513.77 || @.productOffering.price=='1513.77') && @.product.relatedParty.role=='customer')].quantity"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertIntegers() throws JsonPatchException { + String jsonPointerWithQuery = "/orderItem/quantity?orderItem.productOffering.id=1513&orderItem.product.relatedParty.role=customer"; + String expected = "$.orderItem[?((@.productOffering.id==1513 || @.productOffering.id=='1513') && @.product.relatedParty.role=='customer')].quantity"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertManyConditions() throws JsonPatchException { + String jsonPointerWithQuery = "/orderItem/quantity?orderItem.product.relatedParty.role=customer&orderItem.product.relatedParty.name=Mary"; + String expected = "$.orderItem[?(@.product.relatedParty.role=='customer' && @.product.relatedParty.name=='Mary')].quantity"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertNestedArrayQuery() throws JsonPatchException { + String jsonPointerWithQuery = "/orderItem/quantity?orderItem.productOffering.id=1513&orderItem.product.relatedParty[?(@.role=='customer' && @.name=='Mary')]"; + String expected = "$.orderItem[?((@.productOffering.id==1513 || @.productOffering.id=='1513') && @.product.relatedParty[?(@.role=='customer' && @.name=='Mary')] empty false)].quantity"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertNestedArrayQueryWhichIsNotLastStatement() throws JsonPatchException { + String jsonPointerWithQuery = "/orderItem/quantity?orderItem.product.relatedParty[?(@.role=='customer' && @.name=='Mary')]&orderItem.productOffering.id=1513"; + String expected = "$.orderItem[?(@.product.relatedParty[?(@.role=='customer' && @.name=='Mary')] empty false && (@.productOffering.id==1513 || @.productOffering.id=='1513'))].quantity"; + String result = JsonPathParser.tmfStringToJsonPath(jsonPointerWithQuery); + assertEquals(result, expected); + } + + @Test + public void shouldConvertFilterQuery() throws JsonPatchException { + String filterQuery = "note[?(@.author=='John Doe')].date"; + String expected = "$.note[?(@.author=='John Doe')].date"; + String result = JsonPathParser.tmfStringToJsonPath(filterQuery); + assertEquals(result, expected); + } + +} \ No newline at end of file diff --git a/src/test/java/com/github/fge/jsonpatch/query/AddQueryOperationTest.java b/src/test/java/com/github/fge/jsonpatch/query/AddQueryOperationTest.java index 00c087b6..7ca4c0eb 100644 --- a/src/test/java/com/github/fge/jsonpatch/query/AddQueryOperationTest.java +++ b/src/test/java/com/github/fge/jsonpatch/query/AddQueryOperationTest.java @@ -3,10 +3,10 @@ import com.github.fge.jsonpatch.JsonPatchOperationTest; import java.io.IOException; -// TODO extend with JsonPatchOperationTest and uncomment constructor when this test needs to be active, couldn't ignore it otherway -public class AddQueryOperationTest extends Object { + +public class AddQueryOperationTest extends JsonPatchOperationTest { public AddQueryOperationTest() throws IOException { - //super("query/add"); + super("query/add"); } } diff --git a/src/test/java/com/github/fge/jsonpatch/query/FilterOperationTest.java b/src/test/java/com/github/fge/jsonpatch/query/FilterOperationTest.java new file mode 100644 index 00000000..42af19cb --- /dev/null +++ b/src/test/java/com/github/fge/jsonpatch/query/FilterOperationTest.java @@ -0,0 +1,12 @@ +package com.github.fge.jsonpatch.query; + +import com.github.fge.jsonpatch.JsonPatchOperationTest; + +import java.io.IOException; + +public class FilterOperationTest extends JsonPatchOperationTest { + + public FilterOperationTest() throws IOException { + super("query/filter"); + } +} diff --git a/src/test/java/com/github/fge/jsonpatch/query/IndividualEntityTest.java b/src/test/java/com/github/fge/jsonpatch/query/IndividualEntityTest.java new file mode 100644 index 00000000..7ee114bb --- /dev/null +++ b/src/test/java/com/github/fge/jsonpatch/query/IndividualEntityTest.java @@ -0,0 +1,12 @@ +package com.github.fge.jsonpatch.query; + +import com.github.fge.jsonpatch.JsonPatchOperationTest; + +import java.io.IOException; + +public class IndividualEntityTest extends JsonPatchOperationTest { + + public IndividualEntityTest() throws IOException { + super("query/individual"); + } +} diff --git a/src/test/java/com/github/fge/jsonpatch/query/RemoveQueryOperationTest.java b/src/test/java/com/github/fge/jsonpatch/query/RemoveQueryOperationTest.java index 078e1ee2..3c48ad80 100644 --- a/src/test/java/com/github/fge/jsonpatch/query/RemoveQueryOperationTest.java +++ b/src/test/java/com/github/fge/jsonpatch/query/RemoveQueryOperationTest.java @@ -4,10 +4,9 @@ import java.io.IOException; -// TODO extend with JsonPatchOperationTest and uncomment constructor when this test needs to be active, couldn't ignore it otherway -public class RemoveQueryOperationTest extends Object { +public class RemoveQueryOperationTest extends JsonPatchOperationTest { public RemoveQueryOperationTest() throws IOException { - //super("query/remove"); + super("query/remove"); } } diff --git a/src/test/java/com/github/fge/jsonpatch/query/ReplaceQueryOperationTest.java b/src/test/java/com/github/fge/jsonpatch/query/ReplaceQueryOperationTest.java index f960322e..8b8848bb 100644 --- a/src/test/java/com/github/fge/jsonpatch/query/ReplaceQueryOperationTest.java +++ b/src/test/java/com/github/fge/jsonpatch/query/ReplaceQueryOperationTest.java @@ -4,10 +4,9 @@ import java.io.IOException; -// TODO extend with JsonPatchOperationTest and uncomment constructor when this test needs to be active, couldn't ignore it otherway -public class ReplaceQueryOperationTest extends Object { +public class ReplaceQueryOperationTest extends JsonPatchOperationTest { public ReplaceQueryOperationTest() throws IOException { - //super("query/replace"); + super("query/replace"); } } diff --git a/src/test/resources/jsonpatch/query/add.json b/src/test/resources/jsonpatch/query/add.json index 43e70b64..a533f811 100644 --- a/src/test/resources/jsonpatch/query/add.json +++ b/src/test/resources/jsonpatch/query/add.json @@ -1,37 +1,531 @@ { "errors": [], "ops": [ + { + "op": { + "op": "add", + "path": "/note/text?note.verified=true", + "value": "Informed" + }, + "node": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe" + } + ] + }, + "expected": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "text": "Informed" + } + ] + } + }, + { + "op": { + "op": "add", + "path": "/note/text?note.verified=true|note.verified=false", + "value": "Informed" + }, + "node": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe" + } + ] + }, + "expected": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "text": "Informed" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "text": "Informed" + } + ] + } + }, + { + "op": { + "op": "add", + "path": "/note/text?note.verified=false", + "value": "Informed" + }, + "node": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "text": "Old informed" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe" + } + ] + }, + "expected": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "text": "Informed" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe" + } + ] + } + }, + { + "op": { + "op": "add", + "path": "/note/text?note.text=Old informed", + "value": "Informed predicate" + }, + "node": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "text": "Old informed" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe" + } + ] + }, + "expected": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "verified": false, + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "text": "Informed predicate" + }, + { + "verified": true, + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe" + } + ] + } + }, + { + "op": { + "op": "add", + "path": "/note/text?note.price=8.5", + "value": "Informed" + }, + "node": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "price": 16 + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "price": 8.5 + } + ] + }, + "expected": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "price": 16 + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "price": 8.5, + "text": "Informed" + } + ] + } + }, + { + "op": { + "op": "add", + "path": "/note/text?note.price>9", + "value": "Informed" + }, + "node": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "price": 16 + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "price": 8.5 + } + ] + }, + "expected": { + "id": "1", + "correlationId": "TT53482", + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "price": 16, + "text": "Informed" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "price": 8.5 + } + ] + } + }, { "description": "TMF630 - Example 1 - Adding an attribute to one of the components of an array", "op": { "op": "add", "path": "/note/text?note.author=John Doe", - "value":"Informed" + "value": "Informed" }, "node": { "id": "1", "correlationId": "TT53482", - "note": [{ - "date": "2013-07-24T09:55:30.0Z", - "author": "Arthur Evans" - }, + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans" + }, { "date": "2013-07-25T08:55:12.0Z", "author": "John Doe" - }] + } + ] }, "expected": { "id": "1", "correlationId": "TT53482", - "note": [{ - "date": "2013-07-24T09:55:30.0Z", - "author": "Arthur Evans" - }, + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans" + }, { "date": "2013-07-25T08:55:12.0Z", "author": "John Doe", "text": "Informed" - }] + } + ] + } + }, + { + "description": "Additional test 1", + "op": { + "op": "add", + "path": "/contactMedium/ThisHasBeenAdded?contactMedium.mediumType=phone", + "value": true + }, + "node": { + "aristocraticTitle": "Baron", + "boolean": true, + "deathDate": "2021-07-12T10:54:17Z", + "title": "Sir", + "contactMedium": [ + { + "mediumType": "phone", + "preferred": false, + "characteristic": { + "addressKeyType": "AA", + "addressKey": "AAAAA" + } + }, + { + "mediumType": "pager", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB" + } + }, + { + "mediumType": "facebook", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB", + "detail": { + "detailA": "A", + "detailB": "B" + } + } + } + ] + }, + "expected": { + "aristocraticTitle": "Baron", + "boolean": true, + "deathDate": "2021-07-12T10:54:17Z", + "title": "Sir", + "contactMedium": [ + { + "mediumType": "phone", + "preferred": false, + "characteristic": { + "addressKeyType": "AA", + "addressKey": "AAAAA" + }, + "ThisHasBeenAdded": true + }, + { + "mediumType": "pager", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB" + } + }, + { + "mediumType": "facebook", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB", + "detail": { + "detailA": "A", + "detailB": "B" + } + } + } + ] + } + }, + { + "description": "Additional test 2", + "op": { + "op": "add", + "path": "contactMedium[?(@.mediumType=='phone')].newProperty", + "value": { + "ThisHasBeenAdded": true + } + }, + "node": { + "aristocraticTitle": "Baron", + "boolean": true, + "deathDate": "2021-07-12T10:54:17Z", + "title": "Sir", + "contactMedium": [ + { + "mediumType": "phone", + "preferred": false, + "characteristic": { + "addressKeyType": "AA", + "addressKey": "AAAAA" + } + }, + { + "mediumType": "pager", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB" + } + }, + { + "mediumType": "facebook", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB", + "detail": { + "detailA": "A", + "detailB": "B" + } + } + } + ] + }, + "expected": { + "aristocraticTitle": "Baron", + "boolean": true, + "deathDate": "2021-07-12T10:54:17Z", + "title": "Sir", + "contactMedium": [ + { + "mediumType": "phone", + "preferred": false, + "characteristic": { + "addressKeyType": "AA", + "addressKey": "AAAAA" + }, + "newProperty": {"ThisHasBeenAdded": true} + }, + { + "mediumType": "pager", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB" + } + }, + { + "mediumType": "facebook", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB", + "detail": { + "detailA": "A", + "detailB": "B" + } + } + } + ] + } + }, + { + "description": "Additional test 2", + "op": { + "op": "add", + "path": "contactMedium[?(@.mediumType=='phone')].newProperty", + "value": { + "ThisHasBeenAdded": true + } + }, + "node": { + "aristocraticTitle": "Baron", + "boolean": true, + "deathDate": "2021-07-12T10:54:17Z", + "title": "Sir", + "contactMedium": [ + { + "mediumType": "phone", + "preferred": false, + "characteristic": { + "addressKeyType": "AA", + "addressKey": "AAAAA" + } + }, + { + "mediumType": "pager", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB" + } + }, + { + "mediumType": "facebook", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB", + "detail": { + "detailA": "A", + "detailB": "B" + } + } + } + ] + }, + "expected": { + "aristocraticTitle": "Baron", + "boolean": true, + "deathDate": "2021-07-12T10:54:17Z", + "title": "Sir", + "contactMedium": [ + { + "mediumType": "phone", + "preferred": false, + "characteristic": { + "addressKeyType": "AA", + "addressKey": "AAAAA" + }, + "newProperty": {"ThisHasBeenAdded": true} + }, + { + "mediumType": "pager", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB" + } + }, + { + "mediumType": "facebook", + "preferred": true, + "characteristic": { + "addressKeyType": "BB", + "addressKey": "BBBBBB", + "detail": { + "detailA": "A", + "detailB": "B" + } + } + } + ] } } ] diff --git a/src/test/resources/jsonpatch/query/filter.json b/src/test/resources/jsonpatch/query/filter.json new file mode 100644 index 00000000..2f230505 --- /dev/null +++ b/src/test/resources/jsonpatch/query/filter.json @@ -0,0 +1,173 @@ +{ + "errors": [], + "ops": [ + { + "op": { + "op": "add", + "path": "note[?(@.author=='John Doe')].text", + "value": "Informed" + }, + "node" : { + "id": "1", + "note": [{ + "date": "2013-07-25T06:55:12.0Z", + "author": "John Doe", + "status": "Edited" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "status": "Archived" + }] + }, + "expected": { + "id": "1", + "note": [{ + "date": "2013-07-25T06:55:12.0Z", + "author": "John Doe", + "status": "Edited", + "text": "Informed" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "status": "Archived", + "text": "Informed" + }] + } + }, + { + "op": { + "op": "add", + "path": "note[?(@.author=='John Doe' && @.status=='Edited')].text", + "value": "Informed" + }, + "node": { + "id": "1", + "note": [ + { + "date": "2013-07-25T06:55:12.0Z", + "author": "John Doe", + "status": "Edited" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "status": "Archived" + } + ] + }, + "expected": { + "id": "1", + "note": [ + { + "date": "2013-07-25T06:55:12.0Z", + "author": "John Doe", + "status": "Edited", + "text": "Informed" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "status": "Archived" + } + ] + } + }, + { + "op": { + "op": "remove", + "path": "note[?(@.author=='John Doe')].date", + "value": "{\"text\": \"Informed\"}" + }, + "node" : { + "id": "1", + "note": [{ + "date": "2013-07-25T06:55:12.0Z", + "author": "John Doe", + "status": "Edited" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "status": "Archived" + }] + }, + "expected": { + "id": "1", + "note": [{ + "author": "John Doe", + "status": "Edited" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "author": "John Doe", + "status": "Archived" + }] + } + }, + { + "op": { + "op": "remove", + "path": "note[?(@.author=='John Doe')]" + }, + "node" : { + "id": "1", + "note": [{ + "date": "2013-07-25T06:55:12.0Z", + "author": "John Doe", + "status": "Edited" + }, + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + }, + { + "date": "2013-07-25T08:55:12.0Z", + "author": "John Doe", + "status": "Archived" + }] + }, + "expected": { + "id": "1", + "note": [ + { + "date": "2013-07-24T09:55:30.0Z", + "author": "Arthur Evans", + "status": "Edited" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/jsonpatch/query/individual.json b/src/test/resources/jsonpatch/query/individual.json new file mode 100644 index 00000000..da7eb0a5 --- /dev/null +++ b/src/test/resources/jsonpatch/query/individual.json @@ -0,0 +1,645 @@ +{ + "errors": [], + "ops": [ + { + "op": { + "op": "add", + "path": "/contactMedium/wrapper?contactMedium.mediumType=qRXcJlpNjx", + "value": "12" + }, + "node": { + "aristocraticTitle": "Baron", + "contactMedium": [ + { + "mediumType": "qRXcJlpNjx", + "preferred": false, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + } + }, + { + "mediumType": "asfasdfgasdf", + "preferred": true, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + } + } + ], + "creditRating": [ + { + "creditAgencyName": "wrSavzqmHm", + "ratingScore": 66, + "validFor": { + "endDateTime": "2021-07-31T11:00:17Z", + "startDateTime": "2021-07-30T10:21:17Z" + } + } + ], + "disability": [ + { + "disabilityCode": "QgHhbBLahC", + "disabilityName": "ouqGwsvLEf", + "validFor": { + "endDateTime": "2021-08-03T04:29:17Z", + "startDateTime": "2021-07-28T00:27:17Z" + } + } + ], + "externalReference": [ + { + "externalReferenceType": "aIOPiNhbmo", + "name": "RIlMwNlVmu" + } + ], + "individualIdentification": [ + { + "identificationId": "DqReHbjoAZ", + "issuingDate": "2021-07-31T09:46:17Z", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "href": "OXMkUnCJZU", + "size": { + "amount": 744, + "units": "JCxEtmpdJp" + }, + "validFor": { + "endDateTime": "2021-08-01T23:24:17Z", + "startDateTime": "2021-07-28T01:50:17Z" + } + }, + "validFor": { + "endDateTime": "2021-08-03T23:35:17Z", + "startDateTime": "2021-07-30T06:43:17Z" + } + } + ], + "languageAbility": [ + { + "isFavouriteLanguage": false, + "languageCode": "ZcpsxgQNhM", + "writingProficiency": "zWYDbRYonQ", + "validFor": { + "endDateTime": "2021-08-02T05:17:17Z", + "startDateTime": "2021-07-28T22:04:17Z" + } + } + ], + "otherName": [ + { + "aristocraticTitle": "qpMBXqEnNP", + "title": "mlfshyAJHW", + "validFor": { + "endDateTime": "2021-08-01T06:06:17Z", + "startDateTime": "2021-07-29T14:22:17Z" + } + } + ], + "partyCharacteristic": [ + { + "name": "OKMcApMuEM", + "valueType": "sdraPevzAe", + "value": "HEIlNQxeHi" + } + ], + "relatedParty": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "href": "WRYrNaAtsf", + "name": "EYOufmlArK", + "role": "OtbxPWgead", + "@referredType": "idUvdppQWd" + } + ], + "skill": [ + { + "comment": "yfFsTAPwkJ", + "evaluatedLevel": "kahUzknbkv", + "skillCode": "UjeonFMegY", + "skillName": "NdjXHHuZze", + "validFor": { + "endDateTime": "2021-07-30T22:35:17Z", + "startDateTime": "2021-07-28T09:45:17Z" + } + } + ], + "status": "initialized", + "taxExemptionCertificate": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "size": { + "amount": 399, + "units": "nEbqvKVtps" + }, + "validFor": { + "endDateTime": "2021-08-01T15:27:17Z", + "startDateTime": "2021-07-27T16:20:17Z" + } + }, + "taxDefinition": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "name": "shnwvwDoob", + "taxType": "wjtBLFqKRt" + } + ], + "validFor": { + "endDateTime": "2021-08-01T12:01:17Z", + "startDateTime": "2021-07-30T05:23:17Z" + } + } + ] + }, + "expected": { + "aristocraticTitle": "Baron", + "contactMedium": [ + { + "mediumType": "qRXcJlpNjx", + "preferred": false, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + }, + "wrapper": "12" + }, + { + "mediumType": "asfasdfgasdf", + "preferred": true, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + } + } + ], + "creditRating": [ + { + "creditAgencyName": "wrSavzqmHm", + "ratingScore": 66, + "validFor": { + "endDateTime": "2021-07-31T11:00:17Z", + "startDateTime": "2021-07-30T10:21:17Z" + } + } + ], + "disability": [ + { + "disabilityCode": "QgHhbBLahC", + "disabilityName": "ouqGwsvLEf", + "validFor": { + "endDateTime": "2021-08-03T04:29:17Z", + "startDateTime": "2021-07-28T00:27:17Z" + } + } + ], + "externalReference": [ + { + "externalReferenceType": "aIOPiNhbmo", + "name": "RIlMwNlVmu" + } + ], + "individualIdentification": [ + { + "identificationId": "DqReHbjoAZ", + "issuingDate": "2021-07-31T09:46:17Z", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "href": "OXMkUnCJZU", + "size": { + "amount": 744, + "units": "JCxEtmpdJp" + }, + "validFor": { + "endDateTime": "2021-08-01T23:24:17Z", + "startDateTime": "2021-07-28T01:50:17Z" + } + }, + "validFor": { + "endDateTime": "2021-08-03T23:35:17Z", + "startDateTime": "2021-07-30T06:43:17Z" + } + } + ], + "languageAbility": [ + { + "isFavouriteLanguage": false, + "languageCode": "ZcpsxgQNhM", + "writingProficiency": "zWYDbRYonQ", + "validFor": { + "endDateTime": "2021-08-02T05:17:17Z", + "startDateTime": "2021-07-28T22:04:17Z" + } + } + ], + "otherName": [ + { + "aristocraticTitle": "qpMBXqEnNP", + "title": "mlfshyAJHW", + "validFor": { + "endDateTime": "2021-08-01T06:06:17Z", + "startDateTime": "2021-07-29T14:22:17Z" + } + } + ], + "partyCharacteristic": [ + { + "name": "OKMcApMuEM", + "valueType": "sdraPevzAe", + "value": "HEIlNQxeHi" + } + ], + "relatedParty": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "href": "WRYrNaAtsf", + "name": "EYOufmlArK", + "role": "OtbxPWgead", + "@referredType": "idUvdppQWd" + } + ], + "skill": [ + { + "comment": "yfFsTAPwkJ", + "evaluatedLevel": "kahUzknbkv", + "skillCode": "UjeonFMegY", + "skillName": "NdjXHHuZze", + "validFor": { + "endDateTime": "2021-07-30T22:35:17Z", + "startDateTime": "2021-07-28T09:45:17Z" + } + } + ], + "status": "initialized", + "taxExemptionCertificate": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "size": { + "amount": 399, + "units": "nEbqvKVtps" + }, + "validFor": { + "endDateTime": "2021-08-01T15:27:17Z", + "startDateTime": "2021-07-27T16:20:17Z" + } + }, + "taxDefinition": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "name": "shnwvwDoob", + "taxType": "wjtBLFqKRt" + } + ], + "validFor": { + "endDateTime": "2021-08-01T12:01:17Z", + "startDateTime": "2021-07-30T05:23:17Z" + } + } + ] + } + }, + { + "op": { + "op": "add", + "path": "/contactMedium/wrapper?contactMedium.preferred=false", + "value": {"inside": 12} + }, + "node": { + "aristocraticTitle": "Baron", + "contactMedium": [ + { + "mediumType": "qRXcJlpNjx", + "preferred": false, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + } + }, + { + "mediumType": "asfasdfgasdf", + "preferred": true, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + } + } + ], + "creditRating": [ + { + "creditAgencyName": "wrSavzqmHm", + "ratingScore": 66, + "validFor": { + "endDateTime": "2021-07-31T11:00:17Z", + "startDateTime": "2021-07-30T10:21:17Z" + } + } + ], + "disability": [ + { + "disabilityCode": "QgHhbBLahC", + "disabilityName": "ouqGwsvLEf", + "validFor": { + "endDateTime": "2021-08-03T04:29:17Z", + "startDateTime": "2021-07-28T00:27:17Z" + } + } + ], + "externalReference": [ + { + "externalReferenceType": "aIOPiNhbmo", + "name": "RIlMwNlVmu" + } + ], + "individualIdentification": [ + { + "identificationId": "DqReHbjoAZ", + "issuingDate": "2021-07-31T09:46:17Z", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "href": "OXMkUnCJZU", + "size": { + "amount": 744, + "units": "JCxEtmpdJp" + }, + "validFor": { + "endDateTime": "2021-08-01T23:24:17Z", + "startDateTime": "2021-07-28T01:50:17Z" + } + }, + "validFor": { + "endDateTime": "2021-08-03T23:35:17Z", + "startDateTime": "2021-07-30T06:43:17Z" + } + } + ], + "languageAbility": [ + { + "isFavouriteLanguage": false, + "languageCode": "ZcpsxgQNhM", + "writingProficiency": "zWYDbRYonQ", + "validFor": { + "endDateTime": "2021-08-02T05:17:17Z", + "startDateTime": "2021-07-28T22:04:17Z" + } + } + ], + "otherName": [ + { + "aristocraticTitle": "qpMBXqEnNP", + "title": "mlfshyAJHW", + "validFor": { + "endDateTime": "2021-08-01T06:06:17Z", + "startDateTime": "2021-07-29T14:22:17Z" + } + } + ], + "partyCharacteristic": [ + { + "name": "OKMcApMuEM", + "valueType": "sdraPevzAe", + "value": "HEIlNQxeHi" + } + ], + "relatedParty": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "href": "WRYrNaAtsf", + "name": "EYOufmlArK", + "role": "OtbxPWgead", + "@referredType": "idUvdppQWd" + } + ], + "skill": [ + { + "comment": "yfFsTAPwkJ", + "evaluatedLevel": "kahUzknbkv", + "skillCode": "UjeonFMegY", + "skillName": "NdjXHHuZze", + "validFor": { + "endDateTime": "2021-07-30T22:35:17Z", + "startDateTime": "2021-07-28T09:45:17Z" + } + } + ], + "status": "initialized", + "taxExemptionCertificate": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "size": { + "amount": 399, + "units": "nEbqvKVtps" + }, + "validFor": { + "endDateTime": "2021-08-01T15:27:17Z", + "startDateTime": "2021-07-27T16:20:17Z" + } + }, + "taxDefinition": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "name": "shnwvwDoob", + "taxType": "wjtBLFqKRt" + } + ], + "validFor": { + "endDateTime": "2021-08-01T12:01:17Z", + "startDateTime": "2021-07-30T05:23:17Z" + } + } + ] + }, + "expected": { + "aristocraticTitle": "Baron", + "contactMedium": [ + { + "mediumType": "qRXcJlpNjx", + "preferred": false, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + }, + "wrapper": {"inside": 12} + }, + { + "mediumType": "asfasdfgasdf", + "preferred": true, + "characteristic": { + "addressKeyType": "NAD", + "addressKey": "wunMHlcIQP", + "city": "kiNnXHrWwz" + }, + "validFor": { + "endDateTime": "2021-08-02T12:31:17Z", + "startDateTime": "2021-07-28T16:33:17Z" + } + } + ], + "creditRating": [ + { + "creditAgencyName": "wrSavzqmHm", + "ratingScore": 66, + "validFor": { + "endDateTime": "2021-07-31T11:00:17Z", + "startDateTime": "2021-07-30T10:21:17Z" + } + } + ], + "disability": [ + { + "disabilityCode": "QgHhbBLahC", + "disabilityName": "ouqGwsvLEf", + "validFor": { + "endDateTime": "2021-08-03T04:29:17Z", + "startDateTime": "2021-07-28T00:27:17Z" + } + } + ], + "externalReference": [ + { + "externalReferenceType": "aIOPiNhbmo", + "name": "RIlMwNlVmu" + } + ], + "individualIdentification": [ + { + "identificationId": "DqReHbjoAZ", + "issuingDate": "2021-07-31T09:46:17Z", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "href": "OXMkUnCJZU", + "size": { + "amount": 744, + "units": "JCxEtmpdJp" + }, + "validFor": { + "endDateTime": "2021-08-01T23:24:17Z", + "startDateTime": "2021-07-28T01:50:17Z" + } + }, + "validFor": { + "endDateTime": "2021-08-03T23:35:17Z", + "startDateTime": "2021-07-30T06:43:17Z" + } + } + ], + "languageAbility": [ + { + "isFavouriteLanguage": false, + "languageCode": "ZcpsxgQNhM", + "writingProficiency": "zWYDbRYonQ", + "validFor": { + "endDateTime": "2021-08-02T05:17:17Z", + "startDateTime": "2021-07-28T22:04:17Z" + } + } + ], + "otherName": [ + { + "aristocraticTitle": "qpMBXqEnNP", + "title": "mlfshyAJHW", + "validFor": { + "endDateTime": "2021-08-01T06:06:17Z", + "startDateTime": "2021-07-29T14:22:17Z" + } + } + ], + "partyCharacteristic": [ + { + "name": "OKMcApMuEM", + "valueType": "sdraPevzAe", + "value": "HEIlNQxeHi" + } + ], + "relatedParty": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "href": "WRYrNaAtsf", + "name": "EYOufmlArK", + "role": "OtbxPWgead", + "@referredType": "idUvdppQWd" + } + ], + "skill": [ + { + "comment": "yfFsTAPwkJ", + "evaluatedLevel": "kahUzknbkv", + "skillCode": "UjeonFMegY", + "skillName": "NdjXHHuZze", + "validFor": { + "endDateTime": "2021-07-30T22:35:17Z", + "startDateTime": "2021-07-28T09:45:17Z" + } + } + ], + "status": "initialized", + "taxExemptionCertificate": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "attachment": { + "id": "61bb19204b8a355d3bdb45a4", + "size": { + "amount": 399, + "units": "nEbqvKVtps" + }, + "validFor": { + "endDateTime": "2021-08-01T15:27:17Z", + "startDateTime": "2021-07-27T16:20:17Z" + } + }, + "taxDefinition": [ + { + "id": "61bb19204b8a355d3bdb45a4", + "name": "shnwvwDoob", + "taxType": "wjtBLFqKRt" + } + ], + "validFor": { + "endDateTime": "2021-08-01T12:01:17Z", + "startDateTime": "2021-07-30T05:23:17Z" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/jsonpatch/query/remove.json b/src/test/resources/jsonpatch/query/remove.json index 61ff64c6..72a4f5e5 100644 --- a/src/test/resources/jsonpatch/query/remove.json +++ b/src/test/resources/jsonpatch/query/remove.json @@ -1,4 +1,5 @@ { + "errors": [], "ops": [ { "description": "TMF630 - Example 2 - Removing one of the components of an Array Element (the whole structure)", @@ -48,7 +49,7 @@ "description": "TMF630 - Example 3 - Removing an attribute from one of the components of an array", "op": { "op": "remove", - "path": "/productPrice/prodPriceAlteration?prodPrice.name=Regular Price" + "path": "/productPrice/prodPriceAlteration?productPrice.name=Regular Price" }, "node": { "id": "4501", @@ -89,7 +90,7 @@ }, { "description": "TMF630 - Example 4 - Removing a complete complex structure component of an array", - "op": { "op": "remove", "path": "/productPrice? productPrice.name=Setup Price" }, + "op": { "op": "remove", "path": "/productPrice?productPrice.name=Setup Price" }, "node": { "id": "4501", "description": "This product .... ", diff --git a/src/test/resources/jsonpatch/query/replace.json b/src/test/resources/jsonpatch/query/replace.json index 25cd8e9c..339cd6f2 100644 --- a/src/test/resources/jsonpatch/query/replace.json +++ b/src/test/resources/jsonpatch/query/replace.json @@ -1,11 +1,12 @@ { + "errors": [], "ops": [ { "description": "TMF630 - Example 5 - Replacing an attribute from one of the components of an array", "op": { "op": "replace", "path": "/productOfferingPrice/price/amount?productOfferingPrice.name=Monthly Price", - "value": "25" + "value": 25 }, "node": { "id": "42", @@ -60,7 +61,7 @@ "op": "replace", "path": "/productOfferingPrice/price?productOfferingPrice.name=Setup Price", "value": { - "amount": "40", + "amount": 40, "units": "USD" } }, @@ -81,8 +82,8 @@ "name": "Setup Price", "priceType": "one time", "price": { - "amount": "40", - "units": "USD" + "amount": 30, + "units": "EUR" } } ] @@ -96,7 +97,7 @@ "name": "Monthly Price", "priceType": "recurring", "price": { - "amount": 25, + "amount": 12, "units": "EUR" } }, @@ -104,8 +105,8 @@ "name": "Setup Price", "priceType": "one time", "price": { - "amount": 30, - "units": "EUR" + "amount": 40, + "units": "USD" } } ] @@ -115,8 +116,8 @@ "description": "TMF630 - Example 7 - Replacing an attribute from one of the components of a complex array (resolving ambiguities)", "op": { "op": "replace", - "path": "/orderItem/quantity?orderItem.productOffering.id=1513&orderItem.product.relatedParty.role=customer&orderItem.product.relatedParty.name=Mary", - "value": "25" + "path": "/orderItem/quantity?orderItem.productOffering.id=1513&orderItem.product.relatedParty[?(@.role=='customer' && @.name=='Mary')]", + "value": 25 }, "node": { "id": "3774",