Fix YANG patch request for augmented element
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / jersey / providers / patch / XmlPatchBodyReaderTest.java
index fd3a9b0a52793306345e0cb637672f31ce0dbe3e..439683b18ed1739329fbd79efc3b42507eb9568a 100644 (file)
@@ -5,34 +5,34 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.junit.Assert.assertThrows;
 
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import javax.ws.rs.core.MediaType;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
-import org.opendaylight.restconf.common.patch.PatchContext;
-import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.jersey.providers.test.AbstractBodyReaderTest;
 import org.opendaylight.restconf.nb.rfc8040.jersey.providers.test.XmlBodyReaderTest;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.common.ErrorTag;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
 public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
+    private static EffectiveModelContext schemaContext;
 
-    private final XmlToPatchBodyReader xmlToPatchBodyReader;
-    private static SchemaContext schemaContext;
+    private final XmlPatchBodyReader xmlToPatchBodyReader;
 
     public XmlPatchBodyReaderTest() throws Exception {
-        super();
-        xmlToPatchBodyReader = new XmlToPatchBodyReader();
+        super(schemaContext);
+        xmlToPatchBodyReader = new XmlPatchBodyReader(schemaContextHandler, mountPointService);
     }
 
     @Override
@@ -43,19 +43,13 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
     @BeforeClass
     public static void initialization() {
         schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
-        when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mock(DOMMountPointService.class));
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
     }
 
     @Test
     public void moduleDataTest() throws Exception {
-        final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
-        final InputStream inputStream = XmlBodyReaderTest.class
-                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml");
-        final PatchContext returnValue = xmlToPatchBodyReader
-                .readFrom(null, null, null, mediaType, null, inputStream);
-        checkPatchContext(returnValue);
+        mockBodyReader("instance-identifier-patch-module:patch-cont/my-list1=leaf1", xmlToPatchBodyReader, false);
+        checkPatchContext(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null,
+            XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml")));
     }
 
     /**
@@ -63,16 +57,12 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
      */
     @Test
     public void moduleDataValueMissingNegativeTest() throws Exception {
-        final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
-        final InputStream inputStream = XmlBodyReaderTest.class
-                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueMissing.xml");
-        try {
-            xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
-            fail("Test should return error 400 due to missing value node when attempt to invoke create operation");
-        } catch (final RestconfDocumentedException e) {
-            assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
-        }
+        mockBodyReader("instance-identifier-patch-module:patch-cont/my-list1=leaf1", xmlToPatchBodyReader, false);
+        final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream(
+            "/instanceidentifier/xml/xmlPATCHdataValueMissing.xml");
+        final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
+            () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
+        assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
     }
 
     /**
@@ -81,31 +71,22 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
      */
     @Test
     public void moduleDataNotValueNotSupportedNegativeTest() throws Exception {
-        final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
-        final InputStream inputStream = XmlBodyReaderTest.class
-                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml");
-        try {
-            xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
-            fail("Test should return error 400 due to present value node when attempt to invoke delete operation");
-        } catch (final RestconfDocumentedException e) {
-            assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
-        }
+        mockBodyReader("instance-identifier-patch-module:patch-cont/my-list1=leaf1", xmlToPatchBodyReader, false);
+        final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream(
+            "/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml");
+        final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
+            () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
+        assertEquals(ErrorTag.MALFORMED_MESSAGE, ex.getErrors().get(0).getErrorTag());
     }
 
-
     /**
      * Test of Yang Patch with absolute target path.
      */
     @Test
     public void moduleDataAbsoluteTargetPathTest() throws Exception {
-        final String uri = "";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
-        final InputStream inputStream = XmlBodyReaderTest.class
-                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml");
-        final PatchContext returnValue = xmlToPatchBodyReader
-                .readFrom(null, null, null, mediaType, null, inputStream);
-        checkPatchContext(returnValue);
+        mockBodyReader("", xmlToPatchBodyReader, false);
+        checkPatchContext(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null,
+            XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml")));
     }
 
     /**
@@ -113,13 +94,10 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
      */
     @Test
     public void modulePatchCompleteTargetInURITest() throws Exception {
-        final String uri = "instance-identifier-patch-module:patch-cont";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
-        final InputStream inputStream = XmlBodyReaderTest.class
-                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml");
-        final PatchContext returnValue = xmlToPatchBodyReader
-                .readFrom(null, null, null, mediaType, null, inputStream);
-        checkPatchContext(returnValue);
+        mockBodyReader("instance-identifier-patch-module:patch-cont", xmlToPatchBodyReader, false);
+        checkPatchContext(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null,
+            XmlBodyReaderTest.class.getResourceAsStream(
+                "/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml")));
     }
 
     /**
@@ -127,13 +105,10 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
      */
     @Test
     public void moduleDataMergeOperationOnListTest() throws Exception {
-        final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
-        final InputStream inputStream = XmlBodyReaderTest.class
-                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml");
-        final PatchContext returnValue = xmlToPatchBodyReader
-                .readFrom(null, null, null, mediaType, null, inputStream);
-        checkPatchContext(returnValue);
+        mockBodyReader("instance-identifier-patch-module:patch-cont/my-list1=leaf1", xmlToPatchBodyReader, false);
+        final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream(
+            "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml");
+        checkPatchContext(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
     }
 
     /**
@@ -141,12 +116,52 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
      */
     @Test
     public void moduleDataMergeOperationOnContainerTest() throws Exception {
-        final String uri = "instance-identifier-patch-module:patch-cont";
-        mockBodyReader(uri, xmlToPatchBodyReader, false);
+        mockBodyReader("instance-identifier-patch-module:patch-cont", xmlToPatchBodyReader, false);
         final InputStream inputStream = XmlBodyReaderTest.class
                 .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml");
-        final PatchContext returnValue = xmlToPatchBodyReader
-                .readFrom(null, null, null, mediaType, null, inputStream);
+        checkPatchContext(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
+    }
+
+    /**
+     * Test of Yang Patch on the top-level container with empty URI for data root.
+     */
+    @Test
+    public void modulePatchTargetTopLevelContainerWithEmptyURITest() throws Exception {
+        mockBodyReader("", xmlToPatchBodyReader, false);
+        final InputStream inputStream = XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xmlPATCHTargetTopLevelContainerWithEmptyURI.xml");
+        checkPatchContext(xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream));
+    }
+
+    /**
+     * Test of Yang Patch on the top augmented element.
+     */
+    @Test
+    public void moduleTargetTopLevelAugmentedContainerTest() throws Exception {
+        mockBodyReader("", xmlToPatchBodyReader, false);
+        final var inputStream = new ByteArrayInputStream((
+            "<yang-patch xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-patch\">\n"
+                + "    <patch-id>test-patch</patch-id>\n"
+                + "    <comment>This test patch for augmented element</comment>\n"
+                + "    <edit>\n"
+                + "        <edit-id>edit1</edit-id>\n"
+                + "        <operation>replace</operation>\n"
+                + "        <target>/test-m:container-root/test-m:container-lvl1/test-m-aug:container-aug</target>\n"
+                + "        <value>\n"
+                + "            <container-aug xmlns=\"test-ns-aug\">\n"
+                + "                <leaf-aug>data</leaf-aug>\n"
+                + "            </container-aug>\n"
+                + "        </value>\n"
+                + "    </edit>\n"
+                + "</yang-patch>").getBytes(StandardCharsets.UTF_8));
+        final var expectedData = Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(CONT_AUG_QNAME))
+                .withChild(ImmutableNodes.leafNode(LEAF_AUG_QNAME, "data"))
+                .build();
+        final var returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
         checkPatchContext(returnValue);
+        final var data = returnValue.getData().get(0).getNode();
+        assertEquals(CONT_AUG_QNAME, data.getIdentifier().getNodeType());
+        assertEquals(expectedData, data);
     }
 }