3609c534ba673bd60cffbcd3e171197cd9095e8f
[netconf.git] / restconf / sal-rest-docgen / src / test / java / org / opendaylight / netconf / sal / rest / doc / impl / ApiDocGeneratorRFC8040Test.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.netconf.sal.rest.doc.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 com.fasterxml.jackson.databind.node.ObjectNode;
17 import com.google.common.collect.ImmutableList;
18 import java.util.List;
19 import org.junit.Test;
20 import org.opendaylight.netconf.sal.rest.doc.openapi.OpenApiObject;
21 import org.opendaylight.yangtools.yang.common.Revision;
22
23 public final class ApiDocGeneratorRFC8040Test extends AbstractApiDocTest {
24     private static final String NAME = "toaster2";
25     private static final String REVISION_DATE = "2009-11-20";
26     private static final String NAME_2 = "toaster";
27     private static final String REVISION_DATE_2 = "2009-11-20";
28     private static final String CHOICE_TEST_MODULE = "choice-test";
29     private static final String PROPERTIES = "properties";
30     private final ApiDocGeneratorRFC8040 generator = new ApiDocGeneratorRFC8040(SCHEMA_SERVICE);
31
32     /**
33      * Test that paths are generated according to the model.
34      */
35     @Test
36     public void testPaths() {
37         final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
38         final OpenApiObject doc = generator.getOpenApiDocSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
39
40         assertEquals(List.of("/rests/data",
41             "/rests/data/toaster2:toaster",
42             "/rests/data/toaster2:toaster/toasterSlot={slotId}",
43             "/rests/data/toaster2:toaster/toasterSlot={slotId}/toaster-augmented:slotInfo",
44             "/rests/data/toaster2:lst",
45             "/rests/data/toaster2:lst/cont1",
46             "/rests/data/toaster2:lst/cont1/cont11",
47             "/rests/data/toaster2:lst/cont1/lst11",
48             "/rests/data/toaster2:lst/lst1={key1},{key2}",
49             "/rests/operations/toaster2:make-toast",
50             "/rests/operations/toaster2:cancel-toast",
51             "/rests/operations/toaster2:restock-toaster"),
52             ImmutableList.copyOf(doc.getPaths().fieldNames()));
53     }
54
55     /**
56      * Test that generated configuration paths allow to use operations: get, put, patch, delete and post.
57      */
58     @Test
59     public void testConfigPaths() {
60         final List<String> configPaths = List.of("/rests/data/toaster2:lst",
61                 "/rests/data/toaster2:lst/cont1",
62                 "/rests/data/toaster2:lst/cont1/cont11",
63                 "/rests/data/toaster2:lst/cont1/lst11",
64                 "/rests/data/toaster2:lst/lst1={key1},{key2}");
65
66         final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
67         final OpenApiObject doc = generator.getOpenApiDocSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
68
69         for (final String path : configPaths) {
70             final JsonNode node = doc.getPaths().get(path);
71             assertFalse(node.path("get").isMissingNode());
72             assertFalse(node.path("put").isMissingNode());
73             assertFalse(node.path("delete").isMissingNode());
74             assertFalse(node.path("post").isMissingNode());
75             assertFalse(node.path("patch").isMissingNode());
76         }
77     }
78
79     /**
80      * Test that generated document contains the following definitions.
81      */
82     @Test
83     public void testDefinitions() {
84         final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
85         final OpenApiObject doc = generator.getOpenApiDocSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
86
87         final ObjectNode definitions = doc.getDefinitions();
88         assertNotNull(definitions);
89
90         final JsonNode configLstTop = definitions.get("toaster2_config_lst_TOP");
91         assertNotNull(configLstTop);
92         DocGenTestHelper.containsReferences(configLstTop, "lst", "#/components/schemas/toaster2_config_lst");
93
94         final JsonNode configLst = definitions.get("toaster2_config_lst");
95         assertNotNull(configLst);
96         DocGenTestHelper.containsReferences(configLst, "lst1", "#/components/schemas/toaster2_lst_config_lst1");
97         DocGenTestHelper.containsReferences(configLst, "cont1", "#/components/schemas/toaster2_lst_config_cont1");
98
99         final JsonNode configLst1Top = definitions.get("toaster2_lst_config_lst1_TOP");
100         assertNotNull(configLst1Top);
101         DocGenTestHelper.containsReferences(configLst1Top, "lst1", "#/components/schemas/toaster2_lst_config_lst1");
102
103         final JsonNode configLst1 = definitions.get("toaster2_lst_config_lst1");
104         assertNotNull(configLst1);
105
106         final JsonNode configCont1Top = definitions.get("toaster2_lst_config_cont1_TOP");
107         assertNotNull(configCont1Top);
108         DocGenTestHelper.containsReferences(configCont1Top, "cont1", "#/components/schemas/toaster2_lst_config_cont1");
109
110         final JsonNode configCont1 = definitions.get("toaster2_lst_config_cont1");
111         assertNotNull(configCont1);
112         DocGenTestHelper.containsReferences(configCont1, "cont11",
113             "#/components/schemas/toaster2_lst_cont1_config_cont11");
114         DocGenTestHelper.containsReferences(configCont1, "lst11",
115             "#/components/schemas/toaster2_lst_cont1_config_lst11");
116
117         final JsonNode configCont11Top = definitions.get("toaster2_lst_cont1_config_cont11_TOP");
118         assertNotNull(configCont11Top);
119         DocGenTestHelper.containsReferences(configCont11Top,
120             "cont11", "#/components/schemas/toaster2_lst_cont1_config_cont11");
121
122         final JsonNode configCont11 = definitions.get("toaster2_lst_cont1_config_cont11");
123         assertNotNull(configCont11);
124
125         final JsonNode configLst11Top = definitions.get("toaster2_lst_cont1_config_lst11_TOP");
126         assertNotNull(configLst11Top);
127         DocGenTestHelper.containsReferences(configLst11Top, "lst11",
128             "#/components/schemas/toaster2_lst_cont1_config_lst11");
129
130         final JsonNode configLst11 = definitions.get("toaster2_lst_cont1_config_lst11");
131         assertNotNull(configLst11);
132     }
133
134     /**
135      * Test that generated document contains RPC definition for "make-toast" with correct input.
136      */
137     @Test
138     public void testRPC() {
139         final var module = CONTEXT.findModule(NAME_2, Revision.of(REVISION_DATE_2)).orElseThrow();
140         final OpenApiObject doc = generator.getOpenApiDocSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
141         assertNotNull(doc);
142
143         final ObjectNode definitions = doc.getDefinitions();
144         final JsonNode inputTop = definitions.get("toaster_make-toast_input_TOP");
145         assertNotNull(inputTop);
146         final String testString = "{\"input\":{\"$ref\":\"#/components/schemas/toaster_make-toast_input\"}}";
147         assertEquals(testString, inputTop.get("properties").toString());
148         final JsonNode input = definitions.get("toaster_make-toast_input");
149         final JsonNode properties = input.get("properties");
150         assertTrue(properties.has("toasterDoneness"));
151         assertTrue(properties.has("toasterToastType"));
152     }
153
154     @Test
155     public void testChoice() {
156         final var module = CONTEXT.findModule(CHOICE_TEST_MODULE).orElseThrow();
157         final var doc = generator.getOpenApiDocSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
158         assertNotNull(doc);
159
160         final var definitions = doc.getDefinitions();
161         JsonNode firstContainer = definitions.get("choice-test_first-container");
162         assertEquals("default-value",
163                 firstContainer.get(PROPERTIES).get("leaf-default").get("default").asText());
164         assertFalse(firstContainer.get(PROPERTIES).has("leaf-non-default"));
165
166         JsonNode secondContainer = definitions.get("choice-test_second-container");
167         assertTrue(secondContainer.get(PROPERTIES).has("leaf-first-case"));
168         assertFalse(secondContainer.get(PROPERTIES).has("leaf-second-case"));
169     }
170 }