Add unit test for request parameters
[netconf.git] / restconf / restconf-openapi / src / test / java / org / opendaylight / restconf / openapi / impl / OpenApiGeneratorRFC8040Test.java
1 /*
2  * Copyright (c) 2021 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.openapi.impl;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14
15 import com.fasterxml.jackson.databind.JsonNode;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import org.junit.Test;
20 import org.opendaylight.restconf.openapi.AbstractOpenApiTest;
21 import org.opendaylight.restconf.openapi.DocGenTestHelper;
22 import org.opendaylight.restconf.openapi.model.OpenApiObject;
23 import org.opendaylight.restconf.openapi.model.Path;
24 import org.opendaylight.restconf.openapi.model.Schema;
25 import org.opendaylight.yangtools.yang.common.Revision;
26
27 public final class OpenApiGeneratorRFC8040Test extends AbstractOpenApiTest {
28     private static final String NAME = "toaster2";
29     private static final String REVISION_DATE = "2009-11-20";
30     private static final String NAME_2 = "toaster";
31     private static final String REVISION_DATE_2 = "2009-11-20";
32     private static final String CHOICE_TEST_MODULE = "choice-test";
33     private static final String RECURSIVE_TEST_MODULE = "recursive";
34
35     private final OpenApiGeneratorRFC8040 generator = new OpenApiGeneratorRFC8040(SCHEMA_SERVICE);
36
37     /**
38      * Test that paths are generated according to the model.
39      */
40     @Test
41     public void testPaths() {
42         final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
43         final OpenApiObject doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
44
45         assertEquals(Set.of("/rests/data",
46             "/rests/data/toaster2:toaster",
47             "/rests/data/toaster2:toaster/toasterSlot={slotId}",
48             "/rests/data/toaster2:toaster/toasterSlot={slotId}/toaster-augmented:slotInfo",
49             "/rests/data/toaster2:lst",
50             "/rests/data/toaster2:lst/cont1",
51             "/rests/data/toaster2:lst/cont1/cont11",
52             "/rests/data/toaster2:lst/cont1/lst11",
53             "/rests/data/toaster2:lst/lst1={key1},{key2}",
54             "/rests/operations/toaster2:make-toast",
55             "/rests/operations/toaster2:cancel-toast",
56             "/rests/operations/toaster2:restock-toaster"),
57             doc.getPaths().keySet());
58     }
59
60     /**
61      * Test that generated configuration paths allow to use operations: get, put, patch, delete and post.
62      */
63     @Test
64     public void testConfigPaths() {
65         final List<String> configPaths = List.of("/rests/data/toaster2:lst",
66                 "/rests/data/toaster2:lst/cont1",
67                 "/rests/data/toaster2:lst/cont1/cont11",
68                 "/rests/data/toaster2:lst/cont1/lst11",
69                 "/rests/data/toaster2:lst/lst1={key1},{key2}");
70
71         final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
72         final OpenApiObject doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
73
74         for (final String path : configPaths) {
75             final Path node = doc.getPaths().get(path);
76             assertNotNull(node.getGet());
77             assertNotNull(node.getPut());
78             assertNotNull(node.getDelete());
79             assertNotNull(node.getPost());
80             assertNotNull(node.getPatch());
81         }
82     }
83
84     /**
85      * Test that generated document contains the following schemas.
86      */
87     @Test
88     public void testSchemas() {
89         final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
90         final OpenApiObject doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
91
92         final Map<String, Schema> schemas = doc.getComponents().getSchemas();
93         assertNotNull(schemas);
94
95         final Schema configLstTop = schemas.get("toaster2_config_lst_TOP");
96         assertNotNull(configLstTop);
97         DocGenTestHelper.containsReferences(configLstTop, "lst", "#/components/schemas/toaster2_config_lst");
98
99         final Schema configLst = schemas.get("toaster2_config_lst");
100         assertNotNull(configLst);
101         DocGenTestHelper.containsReferences(configLst, "lst1", "#/components/schemas/toaster2_lst_config_lst1");
102         DocGenTestHelper.containsReferences(configLst, "cont1", "#/components/schemas/toaster2_lst_config_cont1");
103
104         final Schema configLst1Top = schemas.get("toaster2_lst_config_lst1_TOP");
105         assertNotNull(configLst1Top);
106         DocGenTestHelper.containsReferences(configLst1Top, "lst1", "#/components/schemas/toaster2_lst_config_lst1");
107
108         final Schema configLst1 = schemas.get("toaster2_lst_config_lst1");
109         assertNotNull(configLst1);
110
111         final Schema configCont1Top = schemas.get("toaster2_lst_config_cont1_TOP");
112         assertNotNull(configCont1Top);
113         DocGenTestHelper.containsReferences(configCont1Top, "cont1", "#/components/schemas/toaster2_lst_config_cont1");
114
115         final Schema configCont1 = schemas.get("toaster2_lst_config_cont1");
116         assertNotNull(configCont1);
117         DocGenTestHelper.containsReferences(configCont1, "cont11",
118                 "#/components/schemas/toaster2_lst_cont1_config_cont11");
119         DocGenTestHelper.containsReferences(configCont1, "lst11",
120                 "#/components/schemas/toaster2_lst_cont1_config_lst11");
121
122         final Schema configCont11Top = schemas.get("toaster2_lst_cont1_config_cont11_TOP");
123         assertNotNull(configCont11Top);
124         DocGenTestHelper.containsReferences(configCont11Top,
125                 "cont11", "#/components/schemas/toaster2_lst_cont1_config_cont11");
126
127         final Schema configCont11 = schemas.get("toaster2_lst_cont1_config_cont11");
128         assertNotNull(configCont11);
129
130         final Schema configLst11Top = schemas.get("toaster2_lst_cont1_config_lst11_TOP");
131         assertNotNull(configLst11Top);
132         DocGenTestHelper.containsReferences(configLst11Top, "lst11",
133                 "#/components/schemas/toaster2_lst_cont1_config_lst11");
134
135         final Schema configLst11 = schemas.get("toaster2_lst_cont1_config_lst11");
136         assertNotNull(configLst11);
137     }
138
139     /**
140      * Test that generated document contains RPC schemas for "make-toast" with correct input.
141      */
142     @Test
143     public void testRPC() {
144         final var module = CONTEXT.findModule(NAME_2, Revision.of(REVISION_DATE_2)).orElseThrow();
145         final OpenApiObject doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
146         assertNotNull(doc);
147
148         final Map<String, Schema> schemas = doc.getComponents().getSchemas();
149         final Schema inputTop = schemas.get("toaster_make-toast_input_TOP");
150         assertNotNull(inputTop);
151         final String testString = "{\"input\":{\"$ref\":\"#/components/schemas/toaster_make-toast_input\"}}";
152         assertEquals(testString, inputTop.getProperties().toString());
153         final Schema input = schemas.get("toaster_make-toast_input");
154         final JsonNode properties = input.getProperties();
155         assertTrue(properties.has("toasterDoneness"));
156         assertTrue(properties.has("toasterToastType"));
157     }
158
159     @Test
160     public void testChoice() {
161         final var module = CONTEXT.findModule(CHOICE_TEST_MODULE).orElseThrow();
162         final var doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
163         assertNotNull(doc);
164
165         final var schemas = doc.getComponents().getSchemas();
166         final Schema firstContainer = schemas.get("choice-test_first-container");
167         assertEquals("default-value",
168                 firstContainer.getProperties().get("leaf-default").get("default").asText());
169         assertFalse(firstContainer.getProperties().has("leaf-non-default"));
170
171         final Schema secondContainer = schemas.get("choice-test_second-container");
172         assertTrue(secondContainer.getProperties().has("leaf-first-case"));
173         assertFalse(secondContainer.getProperties().has("leaf-second-case"));
174     }
175
176     /**
177      * Test that checks for correct amount of parameters in requests.
178      */
179     @Test
180     public void testRecursiveParameters() {
181         final var configPaths = Map.of("/rests/data/recursive:container-root", 0,
182             "/rests/data/recursive:container-root/root-list={name}", 1,
183             "/rests/data/recursive:container-root/root-list={name}/nested-list={name1}", 2,
184             "/rests/data/recursive:container-root/root-list={name}/nested-list={name1}/super-nested-list={name2}", 3);
185
186         final var module = CONTEXT.findModule(RECURSIVE_TEST_MODULE, Revision.of("2023-05-22")).orElseThrow();
187         final var doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
188         assertNotNull(doc);
189
190         final var paths = doc.getPaths();
191         assertEquals(5, paths.size());
192
193         for (final var expectedPath : configPaths.entrySet()) {
194             assertTrue(paths.containsKey(expectedPath.getKey()));
195             final int expectedSize = expectedPath.getValue();
196
197             final var path = paths.get(expectedPath.getKey());
198
199             final var get = path.getGet();
200             assertFalse(get.isMissingNode());
201             assertEquals(expectedSize + 1, get.get("parameters").size());
202
203             final var put = path.getPut();
204             assertFalse(put.isMissingNode());
205             assertEquals(expectedSize, put.get("parameters").size());
206
207             final var delete = path.getDelete();
208             assertFalse(delete.isMissingNode());
209             assertEquals(expectedSize, delete.get("parameters").size());
210
211             final var post = path.getPost();
212             assertFalse(post.isMissingNode());
213             assertEquals(expectedSize, post.get("parameters").size());
214
215             final var patch = path.getPatch();
216             assertFalse(patch.isMissingNode());
217             assertEquals(expectedSize, patch.get("parameters").size());
218         }
219     }
220 }