2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.restconf.server.api;
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;
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;
38 @RunWith(MockitoJUnitRunner.StrictStubs.class)
39 public class ParamsTest {
41 * Test when not allowed parameter type is used.
44 public void checkParametersTypesNegativeTest() {
45 final var mockDatabind = DatabindContext.ofModel(mock(EffectiveModelContext.class));
47 assertInvalidIAE(EventStreamGetParams::of);
48 assertInvalidIAE(EventStreamGetParams::of, ContentParam.ALL);
50 assertParamsThrows("Unknown parameter in /data GET: insert", DataGetParams::of, "insert",
53 assertInvalidIAE(queryParams -> Insert.of(mockDatabind, queryParams));
54 assertInvalidIAE(queryParams -> Insert.of(mockDatabind, queryParams), ContentParam.ALL);
58 * Test of parsing default parameters from URI request.
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());
70 public void testInvalidValueReadDataParams() {
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");
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");
91 * Testing parsing of with-defaults parameter which value matches 'report-all-tagged' setting.
94 public void parseUriParametersWithDefaultAndTaggedTest() {
95 final var params = assertParams(DataGetParams::of, WithDefaultsParam.uriName,
97 assertEquals(WithDefaultsParam.REPORT_ALL_TAGGED, params.withDefaults());
101 * Testing parsing of with-defaults parameter which value matches 'report-all' setting.
104 public void parseUriParametersWithDefaultAndReportAllTest() {
105 final var params = assertParams(DataGetParams::of, WithDefaultsParam.uriName,
107 assertEquals(WithDefaultsParam.REPORT_ALL, params.withDefaults());
111 * Testing parsing of with-defaults parameter which value doesn't match report-all or report-all-tagged patterns
112 * - non-reporting setting.
115 public void parseUriParametersWithDefaultAndNonTaggedTest() {
116 final var params = assertParams(DataGetParams::of, WithDefaultsParam.uriName,
118 assertEquals(WithDefaultsParam.EXPLICIT, params.withDefaults());
122 * Test of parsing user defined parameters from URI request.
125 public void parseUriParametersUserDefinedTest() {
126 final QName containerChild = QName.create("ns", "container-child");
128 final var params = assertParams(DataGetParams::of, QueryParameters.of(
129 ContentParam.CONFIG, DepthParam.of(10), FieldsParam.forUriValue("container-child")));
131 assertEquals(ContentParam.CONFIG, params.content());
134 final var depth = params.depth();
135 assertNotNull(depth);
136 assertEquals(10, depth.value());
139 final var paramsFields = params.fields();
140 assertNotNull(paramsFields);
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);
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));
158 private static void assertInvalidIAE(final Function<QueryParameters, ?> paramsMethod,
159 final RestconfQueryParam<?> param) {
160 assertParamsThrows("Invalid parameter: " + param.paramName(), paramsMethod, param.paramName(),
164 private static void assertInvalidIAE(final Function<QueryParameters, ?> paramsMethod) {
165 assertParamsThrows("Invalid parameter: odl-unknown-param", paramsMethod, "odl-unknown-param", "odl-test-value");
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));
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());
179 private static <T> T assertParams(final Function<QueryParameters, T> paramsMethod, final QueryParameters params) {
180 return paramsMethod.apply(params);
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));