Rework body formatting wiring
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / server / api / ParamsTest.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.server.api;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertThrows;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.withSettings;
17
18 import java.util.Set;
19 import java.util.function.Function;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.junit.MockitoJUnitRunner;
23 import org.opendaylight.restconf.api.QueryParameters;
24 import org.opendaylight.restconf.api.query.ContentParam;
25 import org.opendaylight.restconf.api.query.DepthParam;
26 import org.opendaylight.restconf.api.query.FieldsParam;
27 import org.opendaylight.restconf.api.query.RestconfQueryParam;
28 import org.opendaylight.restconf.api.query.WithDefaultsParam;
29 import org.opendaylight.restconf.nb.rfc8040.Insert;
30 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.data.util.DataSchemaContext;
33 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
35 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
37
38 @RunWith(MockitoJUnitRunner.StrictStubs.class)
39 public class ParamsTest {
40     /**
41      * Test when not allowed parameter type is used.
42      */
43     @Test
44     public void checkParametersTypesNegativeTest() {
45         final var mockDatabind = DatabindContext.ofModel(mock(EffectiveModelContext.class));
46
47         assertInvalidIAE(EventStreamGetParams::of);
48         assertInvalidIAE(EventStreamGetParams::of, ContentParam.ALL);
49
50         assertParamsThrows("Unknown parameter in /data GET: insert", DataGetParams::of, "insert",
51             "odl-test-value");
52
53         assertInvalidIAE(queryParams -> Insert.of(mockDatabind, queryParams));
54         assertInvalidIAE(queryParams -> Insert.of(mockDatabind, queryParams), ContentParam.ALL);
55     }
56
57     /**
58      * Test of parsing default parameters from URI request.
59      */
60     @Test
61     public void parseUriParametersDefaultTest() {
62         // no parameters, default values should be used
63         final var params = assertParams(DataGetParams::of, QueryParameters.of());
64         assertEquals(ContentParam.ALL, params.content());
65         assertNull(params.depth());
66         assertNull(params.fields());
67     }
68
69     @Test
70     public void testInvalidValueReadDataParams() {
71         assertParamsThrows(
72             "Invalid content value: Value can be 'all', 'config' or 'nonconfig', not 'odl-invalid-value'",
73             DataGetParams::of, ContentParam.uriName, "odl-invalid-value");
74         assertParamsThrows("""
75             The depth parameter must be "unbounded" or an integer between 1 and 65535. "odl-invalid-value" is not a \
76             valid integer""", DataGetParams::of, DepthParam.uriName, "odl-invalid-value");
77         assertParamsThrows("Invalid with-defaults value: \"odl-invalid-value\" is not a valid name",
78             DataGetParams::of, WithDefaultsParam.uriName, "odl-invalid-value");
79
80         // inserted value is too high
81         assertParamsThrows("""
82             The depth parameter must be "unbounded" or an integer between 1 and 65535. 65536 is not between 1 and 65535\
83             """, DataGetParams::of, DepthParam.uriName, "65536");
84         // inserted value is too low
85         assertParamsThrows("""
86             The depth parameter must be "unbounded" or an integer between 1 and 65535. 0 is not between 1 and 65535""",
87             DataGetParams::of, DepthParam.uriName, "0");
88     }
89
90     /**
91      * Testing parsing of with-defaults parameter which value matches 'report-all-tagged' setting.
92      */
93     @Test
94     public void parseUriParametersWithDefaultAndTaggedTest() {
95         final var params = assertParams(DataGetParams::of, WithDefaultsParam.uriName,
96             "report-all-tagged");
97         assertEquals(WithDefaultsParam.REPORT_ALL_TAGGED, params.withDefaults());
98     }
99
100     /**
101      * Testing parsing of with-defaults parameter which value matches 'report-all' setting.
102      */
103     @Test
104     public void parseUriParametersWithDefaultAndReportAllTest() {
105         final var params = assertParams(DataGetParams::of, WithDefaultsParam.uriName,
106             "report-all");
107         assertEquals(WithDefaultsParam.REPORT_ALL, params.withDefaults());
108     }
109
110     /**
111      * Testing parsing of with-defaults parameter which value doesn't match report-all or report-all-tagged patterns
112      * - non-reporting setting.
113      */
114     @Test
115     public void parseUriParametersWithDefaultAndNonTaggedTest() {
116         final var params = assertParams(DataGetParams::of, WithDefaultsParam.uriName,
117             "explicit");
118         assertEquals(WithDefaultsParam.EXPLICIT, params.withDefaults());
119     }
120
121     /**
122      * Test of parsing user defined parameters from URI request.
123      */
124     @Test
125     public void parseUriParametersUserDefinedTest() {
126         final QName containerChild = QName.create("ns", "container-child");
127
128         final var params = assertParams(DataGetParams::of, QueryParameters.of(
129             ContentParam.CONFIG, DepthParam.of(10), FieldsParam.forUriValue("container-child")));
130         // content
131         assertEquals(ContentParam.CONFIG, params.content());
132
133         // depth
134         final var depth = params.depth();
135         assertNotNull(depth);
136         assertEquals(10, depth.value());
137
138         // fields
139         final var paramsFields = params.fields();
140         assertNotNull(paramsFields);
141
142         // fields for write filtering
143         final var containerSchema = mock(ContainerSchemaNode.class,
144             withSettings().extraInterfaces(ContainerEffectiveStatement.class));
145         final var containerQName = QName.create(containerChild, "container");
146         doReturn(containerQName).when(containerSchema).getQName();
147         final var containerChildSchema = mock(LeafSchemaNode.class);
148         doReturn(containerChild).when(containerChildSchema).getQName();
149         doReturn(containerChildSchema).when(containerSchema).dataChildByName(containerChild);
150
151         final var fields = MdsalRestconfStrategy.translateFieldsParam(mock(EffectiveModelContext.class),
152             DataSchemaContext.of(containerSchema), paramsFields);
153         assertNotNull(fields);
154         assertEquals(1, fields.size());
155         assertEquals(Set.of(containerChild), fields.get(0));
156     }
157
158     private static void assertInvalidIAE(final Function<QueryParameters, ?> paramsMethod,
159             final RestconfQueryParam<?> param) {
160         assertParamsThrows("Invalid parameter: " + param.paramName(), paramsMethod, param.paramName(),
161             "odl-test-value");
162     }
163
164     private static void assertInvalidIAE(final Function<QueryParameters, ?> paramsMethod) {
165         assertParamsThrows("Invalid parameter: odl-unknown-param", paramsMethod, "odl-unknown-param", "odl-test-value");
166     }
167
168     private static void assertParamsThrows(final String expectedMessage,
169             final Function<QueryParameters, ?> paramsMethod, final String name, final String value) {
170         assertParamsThrows(expectedMessage, paramsMethod, QueryParameters.of(name, value));
171     }
172
173     private static void assertParamsThrows(final String expectedMessage,
174             final Function<QueryParameters, ?> paramsMethod, final QueryParameters params) {
175         final var ex = assertThrows(IllegalArgumentException.class, () -> assertParams(paramsMethod, params));
176         assertEquals(expectedMessage, ex.getMessage());
177     }
178
179     private static <T> T assertParams(final Function<QueryParameters, T> paramsMethod, final QueryParameters params) {
180         return paramsMethod.apply(params);
181     }
182
183     private static <T> T assertParams(final Function<QueryParameters, T> paramsMethod, final String name,
184             final String value) {
185         return assertParams(paramsMethod, QueryParameters.of(name, value));
186     }
187 }