OpenApi add POST request to device root
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / databind / JsonResourceBodyTest.java
1 /*
2  * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.restconf.nb.rfc8040.databind;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11
12 import java.util.Map;
13 import org.junit.jupiter.api.Test;
14 import org.opendaylight.restconf.api.ErrorMessage;
15 import org.opendaylight.restconf.server.api.JsonResourceBody;
16 import org.opendaylight.yangtools.yang.common.ErrorTag;
17 import org.opendaylight.yangtools.yang.common.ErrorType;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
23 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
24
25 class JsonResourceBodyTest extends AbstractResourceBodyTest {
26     JsonResourceBodyTest() {
27         super(JsonResourceBody::new);
28     }
29
30     @Test
31     void moduleDataTest() throws Exception {
32         final var entryId = NodeIdentifierWithPredicates.of(LST11,
33             Map.of(KEYVALUE111, "value1", KEYVALUE112, "value2"));
34
35         assertEquals(ImmutableNodes.newContainerBuilder()
36             .withNodeIdentifier(CONT_NID)
37             .withChild(ImmutableNodes.newContainerBuilder()
38                 .withNodeIdentifier(CONT1_NID)
39                 .withChild(ImmutableNodes.newSystemMapBuilder()
40                     .withNodeIdentifier(new NodeIdentifier(LST11))
41                     .withChild(ImmutableNodes.newMapEntryBuilder()
42                         .withNodeIdentifier(entryId)
43                         .withChild(ImmutableNodes.leafNode(KEYVALUE111, "value1"))
44                         .withChild(ImmutableNodes.leafNode(KEYVALUE112, "value2"))
45                         .withChild(ImmutableNodes.leafNode(LF111, YangInstanceIdentifier.of(CONT_NID, CONT1_NID,
46                             new NodeIdentifier(LST11), entryId, LF112_NID)))
47                         .withChild(ImmutableNodes.leafNode(LF112_NID, "lf112 value"))
48                         .build())
49                     .build())
50                 .build())
51             .build(), parse("instance-identifier-module:cont", """
52                 {
53                   "instance-identifier-module:cont": {
54                     "cont1": {
55                       "augment-module:lst11": [
56                         {
57                           "keyvalue111":"value1",
58                           "keyvalue112":"value2",
59                           "augment-augment-module:lf111": "/instance-identifier-module:cont/cont1\
60                 /augment-module:lst11[keyvalue111=\\"value1\\"][keyvalue112=\\"value2\\"]/augment-augment-module:lf112",
61                           "augment-augment-module:lf112": "lf112 value"
62                         }
63                       ]
64                     }
65                   }
66                 }"""));
67
68     }
69
70     @Test
71     void moduleSubContainerDataPutTest() throws Exception {
72         assertEquals(ImmutableNodes.newContainerBuilder()
73             .withNodeIdentifier(CONT1_NID)
74             .withChild(ImmutableNodes.leafNode(LF11, YangInstanceIdentifier.of(CONT_NID, CONT1_NID,
75                 new NodeIdentifier(LFLST11), new NodeWithValue<>(LFLST11, "lflst11_1"))))
76             .build(), parse("instance-identifier-module:cont/cont1", """
77                 {
78                   "instance-identifier-module:cont1": {
79                     "augment-module-leaf-list:lf11" : "/instance-identifier-module:cont\
80                 /instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.=\\"lflst11_1\\"]"
81                   }
82                 }"""));
83     }
84
85     @Test
86     void testRangeViolation() {
87         assertRangeViolation(() -> parse("netconf786:foo", """
88             {
89               "netconf786:foo": {
90                 "bar": 100
91               }
92             }"""));
93     }
94
95     @Test
96     void testMismatchedInput() {
97         final var error = assertError(() -> parse("base:cont", """
98             {
99               "ietf-restconf:restconf-state" : {
100               }
101             }"""));
102         assertEquals(new ErrorMessage("""
103             Payload name ((urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring?revision=2017-01-26)restconf-state) is \
104             different from identifier name ((ns?revision=2016-02-28)cont)"""), error.message());
105         assertEquals(ErrorType.PROTOCOL, error.type());
106         assertEquals(ErrorTag.MALFORMED_MESSAGE, error.tag());
107     }
108
109     @Test
110     void testMissingKeys() {
111         final var error = assertError(() -> parse("nested-module:depth1-cont/depth2-list2=one,two", """
112                 {
113                   "depth2-list2" : {
114                     "depth3-lf1-key" : "one"
115                   }
116                 }"""));
117         assertEquals(new ErrorMessage("""
118             Error parsing input: List entry (urn:nested:module?revision=2014-06-03)depth2-list2 is missing leaf values \
119             for [depth3-lf2-key]"""), error.message());
120         assertEquals(ErrorType.PROTOCOL, error.type());
121         assertEquals(ErrorTag.MALFORMED_MESSAGE, error.tag());
122     }
123
124     @Test
125     void testJukeboxBand() throws Exception {
126         final var one = QName.create("urn:nested:module", "2014-06-03", "depth3-lf1-key");
127         final var two = QName.create("urn:nested:module", "2014-06-03", "depth3-lf2-key");
128
129         assertEquals(ImmutableNodes.newMapEntryBuilder()
130             .withNodeIdentifier(NodeIdentifierWithPredicates.of(
131                 QName.create("urn:nested:module", "2014-06-03", "depth2-list2"), Map.of(one, "one", two, "two")))
132             .withChild(ImmutableNodes.leafNode(one, "one"))
133             .withChild(ImmutableNodes.leafNode(two, "two"))
134             .build(), parse("nested-module:depth1-cont/depth2-list2=one,two", """
135             {
136               "depth2-list2" : {
137                 "depth3-lf1-key" : "one",
138                 "depth3-lf2-key" : "two"
139               }
140             }"""));
141     }
142
143     @Test
144     void testBinaryTypeError() {
145         final var error = assertError(() -> parse("netconf1268:foo", """
146             {
147               "netconf1268:foo": {
148                 "bar": "a"
149               }
150             }"""));
151         assertEquals(new ErrorMessage("Error parsing input: Last unit does not have enough valid bits"),
152             error.message());
153         assertEquals(ErrorType.PROTOCOL, error.type());
154         assertEquals(ErrorTag.MALFORMED_MESSAGE, error.tag());
155     }
156 }