Use DepthParameter in QueryParameters
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / ReadDataTransactionUtilTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.rests.utils;
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.assertNull;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertThrows;
16 import static org.junit.Assert.assertTrue;
17 import static org.mockito.Mockito.doReturn;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
20 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
21
22 import com.google.common.collect.ImmutableList;
23 import java.util.List;
24 import java.util.Optional;
25 import java.util.Set;
26 import javax.ws.rs.core.MultivaluedHashMap;
27 import javax.ws.rs.core.UriInfo;
28 import org.eclipse.jdt.annotation.NonNull;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.mockito.Mock;
34 import org.mockito.junit.MockitoJUnitRunner;
35 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
36 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
37 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
38 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
39 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
40 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
41 import org.opendaylight.restconf.common.errors.RestconfError;
42 import org.opendaylight.restconf.nb.rfc8040.ContentParameter;
43 import org.opendaylight.restconf.nb.rfc8040.DepthParameter;
44 import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParameter;
45 import org.opendaylight.restconf.nb.rfc8040.legacy.QueryParameters;
46 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
47 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
48 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
49 import org.opendaylight.yangtools.yang.common.ErrorTag;
50 import org.opendaylight.yangtools.yang.common.ErrorType;
51 import org.opendaylight.yangtools.yang.common.QName;
52 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
53 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
54 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
55 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
56 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
57 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
58 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
59 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
60 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
61 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
62 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
63 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
64
65 @RunWith(MockitoJUnitRunner.StrictStubs.class)
66 public class ReadDataTransactionUtilTest {
67
68     private static final TestData DATA = new TestData();
69     private static final NodeIdentifier NODE_IDENTIFIER =
70         new NodeIdentifier(QName.create("ns", "2016-02-28", "container"));
71
72     private RestconfStrategy mdsalStrategy;
73     private RestconfStrategy netconfStrategy;
74     @Mock
75     private NetconfDataTreeService netconfService;
76     @Mock
77     private InstanceIdentifierContext<ContainerSchemaNode> context;
78     @Mock
79     private DOMDataTreeReadTransaction read;
80     @Mock
81     private EffectiveModelContext schemaContext;
82     @Mock
83     private ContainerSchemaNode containerSchemaNode;
84     @Mock
85     private LeafSchemaNode containerChildNode;
86     private QName containerChildQName;
87
88     @Before
89     public void setUp() {
90         containerChildQName = QName.create("ns", "2016-02-28", "container-child");
91
92         when(context.getSchemaContext()).thenReturn(schemaContext);
93         when(context.getSchemaNode()).thenReturn(containerSchemaNode);
94         when(containerSchemaNode.getQName()).thenReturn(NODE_IDENTIFIER.getNodeType());
95         when(containerChildNode.getQName()).thenReturn(containerChildQName);
96         when(containerSchemaNode.dataChildByName(containerChildQName)).thenReturn(containerChildNode);
97
98         DOMDataBroker mockDataBroker = mock(DOMDataBroker.class);
99         doReturn(read).when(mockDataBroker).newReadOnlyTransaction();
100         mdsalStrategy = new MdsalRestconfStrategy(mockDataBroker);
101         netconfStrategy = new NetconfRestconfStrategy(netconfService);
102     }
103
104     @Test
105     public void readDataConfigTest() {
106         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
107                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
108         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
109         NormalizedNode normalizedNode = readData(ContentParameter.CONFIG, DATA.path, mdsalStrategy);
110         assertEquals(DATA.data3, normalizedNode);
111
112         normalizedNode = readData(ContentParameter.CONFIG, DATA.path, netconfStrategy);
113         assertEquals(DATA.data3, normalizedNode);
114     }
115
116     @Test
117     public void readAllHavingOnlyConfigTest() {
118         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
119                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
120         doReturn(immediateFluentFuture(Optional.empty())).when(read)
121                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
122         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
123         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).get(DATA.path);
124         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path, mdsalStrategy);
125         assertEquals(DATA.data3, normalizedNode);
126
127         normalizedNode = readData(ContentParameter.ALL, DATA.path, netconfStrategy);
128         assertEquals(DATA.data3, normalizedNode);
129     }
130
131     @Test
132     public void readAllHavingOnlyNonConfigTest() {
133         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(read)
134                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path2);
135         doReturn(immediateFluentFuture(Optional.empty())).when(read)
136                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path2);
137         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(netconfService).get(DATA.path2);
138         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(DATA.path2);
139         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path2, mdsalStrategy);
140         assertEquals(DATA.data2, normalizedNode);
141
142         normalizedNode = readData(ContentParameter.ALL, DATA.path2, netconfStrategy);
143         assertEquals(DATA.data2, normalizedNode);
144     }
145
146     @Test
147     public void readDataNonConfigTest() {
148         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(read)
149                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path2);
150         doReturn(immediateFluentFuture(Optional.of(DATA.data2))).when(netconfService).get(DATA.path2);
151         NormalizedNode normalizedNode = readData(ContentParameter.NONCONFIG, DATA.path2, mdsalStrategy);
152         assertEquals(DATA.data2, normalizedNode);
153
154         normalizedNode = readData(ContentParameter.NONCONFIG, DATA.path2, netconfStrategy);
155         assertEquals(DATA.data2, normalizedNode);
156     }
157
158     @Test
159     public void readContainerDataAllTest() {
160         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
161                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
162         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(read)
163                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
164         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
165         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(netconfService).get(DATA.path);
166         final ContainerNode checkingData = Builders
167                 .containerBuilder()
168                 .withNodeIdentifier(NODE_IDENTIFIER)
169                 .withChild(DATA.contentLeaf)
170                 .withChild(DATA.contentLeaf2)
171                 .build();
172         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path, mdsalStrategy);
173         assertEquals(checkingData, normalizedNode);
174
175         normalizedNode = readData(ContentParameter.ALL, DATA.path, netconfStrategy);
176         assertEquals(checkingData, normalizedNode);
177     }
178
179     @Test
180     public void readContainerDataConfigNoValueOfContentTest() {
181         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read)
182                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path);
183         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(read)
184                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path);
185         doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(netconfService).getConfig(DATA.path);
186         doReturn(immediateFluentFuture(Optional.of(DATA.data4))).when(netconfService).get(DATA.path);
187         final ContainerNode checkingData = Builders
188                 .containerBuilder()
189                 .withNodeIdentifier(NODE_IDENTIFIER)
190                 .withChild(DATA.contentLeaf)
191                 .withChild(DATA.contentLeaf2)
192                 .build();
193         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path, mdsalStrategy);
194         assertEquals(checkingData, normalizedNode);
195
196         normalizedNode = readData(ContentParameter.ALL, DATA.path, netconfStrategy);
197         assertEquals(checkingData, normalizedNode);
198     }
199
200     @Test
201     public void readListDataAllTest() {
202         doReturn(immediateFluentFuture(Optional.of(DATA.listData))).when(read)
203                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
204         doReturn(immediateFluentFuture(Optional.of(DATA.listData2))).when(read)
205                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
206         doReturn(immediateFluentFuture(Optional.of(DATA.listData))).when(netconfService).get(DATA.path3);
207         doReturn(immediateFluentFuture(Optional.of(DATA.listData2))).when(netconfService).getConfig(DATA.path3);
208         final MapNode checkingData = Builders
209                 .mapBuilder()
210                 .withNodeIdentifier(new NodeIdentifier(QName.create("ns", "2016-02-28", "list")))
211                 .withChild(DATA.checkData)
212                 .build();
213         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path3, mdsalStrategy);
214         assertEquals(checkingData, normalizedNode);
215
216         normalizedNode = readData(ContentParameter.ALL, DATA.path3, netconfStrategy);
217         assertEquals(checkingData, normalizedNode);
218     }
219
220     @Test
221     public void readOrderedListDataAllTest() {
222         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode1))).when(read)
223                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
224         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode2))).when(read)
225                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
226         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode1))).when(netconfService).get(DATA.path3);
227         doReturn(immediateFluentFuture(Optional.of(DATA.orderedMapNode2))).when(netconfService)
228                 .getConfig(DATA.path3);
229         final MapNode expectedData = Builders.orderedMapBuilder()
230                 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
231                 .withChild(DATA.checkData)
232                 .build();
233         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path3,
234                 mdsalStrategy);
235         assertEquals(expectedData, normalizedNode);
236
237         normalizedNode = readData(ContentParameter.ALL, DATA.path3, netconfStrategy);
238         assertEquals(expectedData, normalizedNode);
239     }
240
241     @Test
242     public void readUnkeyedListDataAllTest() {
243         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode1))).when(read)
244                 .read(LogicalDatastoreType.OPERATIONAL, DATA.path3);
245         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode2))).when(read)
246                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path3);
247         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode1))).when(netconfService).get(DATA.path3);
248         doReturn(immediateFluentFuture(Optional.of(DATA.unkeyedListNode2))).when(netconfService)
249                 .getConfig(DATA.path3);
250         final UnkeyedListNode expectedData = Builders.unkeyedListBuilder()
251                 .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
252                 .withChild(Builders.unkeyedListEntryBuilder()
253                         .withNodeIdentifier(new NodeIdentifier(DATA.listQname))
254                         .withChild(DATA.unkeyedListEntryNode1.body().iterator().next())
255                         .withChild(DATA.unkeyedListEntryNode2.body().iterator().next()).build()).build();
256         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.path3, mdsalStrategy);
257         assertEquals(expectedData, normalizedNode);
258
259         normalizedNode = readData(ContentParameter.ALL, DATA.path3, netconfStrategy);
260         assertEquals(expectedData, normalizedNode);
261     }
262
263     @Test
264     public void readLeafListDataAllTest() {
265         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode1))).when(read)
266                 .read(LogicalDatastoreType.OPERATIONAL, DATA.leafSetNodePath);
267         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode2))).when(read)
268                 .read(LogicalDatastoreType.CONFIGURATION, DATA.leafSetNodePath);
269         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode1))).when(netconfService)
270                 .get(DATA.leafSetNodePath);
271         doReturn(immediateFluentFuture(Optional.of(DATA.leafSetNode2))).when(netconfService)
272                 .getConfig(DATA.leafSetNodePath);
273         final LeafSetNode<String> expectedData = Builders.<String>leafSetBuilder()
274                 .withNodeIdentifier(new NodeIdentifier(DATA.leafListQname))
275                 .withValue(ImmutableList.<LeafSetEntryNode<String>>builder()
276                         .addAll(DATA.leafSetNode1.body())
277                         .addAll(DATA.leafSetNode2.body())
278                         .build())
279                 .build();
280         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath,
281                 mdsalStrategy);
282         assertEquals(expectedData, normalizedNode);
283
284         normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath, netconfStrategy);
285         assertEquals(expectedData, normalizedNode);
286     }
287
288     @Test
289     public void readOrderedLeafListDataAllTest() {
290         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode1))).when(read)
291                 .read(LogicalDatastoreType.OPERATIONAL, DATA.leafSetNodePath);
292         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode2))).when(read)
293                 .read(LogicalDatastoreType.CONFIGURATION, DATA.leafSetNodePath);
294         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode1))).when(netconfService)
295                 .get(DATA.leafSetNodePath);
296         doReturn(immediateFluentFuture(Optional.of(DATA.orderedLeafSetNode2))).when(netconfService)
297                 .getConfig(DATA.leafSetNodePath);
298         final LeafSetNode<String> expectedData = Builders.<String>orderedLeafSetBuilder()
299                 .withNodeIdentifier(new NodeIdentifier(DATA.leafListQname))
300                 .withValue(ImmutableList.<LeafSetEntryNode<String>>builder()
301                         .addAll(DATA.orderedLeafSetNode1.body())
302                         .addAll(DATA.orderedLeafSetNode2.body())
303                         .build())
304                 .build();
305         NormalizedNode normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath,
306                 mdsalStrategy);
307         assertEquals(expectedData, normalizedNode);
308
309         normalizedNode = readData(ContentParameter.ALL, DATA.leafSetNodePath, netconfStrategy);
310         assertEquals(expectedData, normalizedNode);
311     }
312
313     @Test
314     public void readDataWrongPathOrNoContentTest() {
315         doReturn(immediateFluentFuture(Optional.empty())).when(read)
316                 .read(LogicalDatastoreType.CONFIGURATION, DATA.path2);
317         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(DATA.path2);
318         NormalizedNode normalizedNode = readData(ContentParameter.CONFIG, DATA.path2, mdsalStrategy);
319         assertNull(normalizedNode);
320
321         normalizedNode = readData(ContentParameter.CONFIG, DATA.path2, netconfStrategy);
322         assertNull(normalizedNode);
323     }
324
325     /**
326      * Test of parsing default parameters from URI request.
327      */
328     @Test
329     public void parseUriParametersDefaultTest() {
330         final UriInfo uriInfo = mock(UriInfo.class);
331         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
332
333         // no parameters, default values should be used
334         when(uriInfo.getQueryParameters()).thenReturn(parameters);
335
336         final QueryParameters parsedParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
337
338         assertEquals(ContentParameter.ALL, parsedParameters.getContent());
339         assertNull(parsedParameters.getDepth());
340         assertNull(parsedParameters.getFields());
341     }
342
343     /**
344      * Test of parsing user defined parameters from URI request.
345      */
346     @Test
347     public void parseUriParametersUserDefinedTest() {
348         final UriInfo uriInfo = mock(UriInfo.class);
349         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
350
351         final String fields = containerChildQName.getLocalName();
352
353         parameters.put("content", List.of("config"));
354         parameters.put("depth", List.of("10"));
355         parameters.put("fields", List.of(fields));
356
357         when(uriInfo.getQueryParameters()).thenReturn(parameters);
358
359         final QueryParameters parsedParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
360
361         // content
362         assertEquals(ContentParameter.CONFIG, parsedParameters.getContent());
363
364         // depth
365         final DepthParameter depth = parsedParameters.getDepth();
366         assertNotNull(depth);
367         assertEquals(10, depth.value());
368
369         // fields
370         assertNotNull(parsedParameters.getFields());
371         assertEquals(1, parsedParameters.getFields().size());
372         assertEquals(1, parsedParameters.getFields().get(0).size());
373         assertEquals(containerChildQName, parsedParameters.getFields().get(0).iterator().next());
374     }
375
376     /**
377      * Negative test of parsing request URI parameters when content parameter has not allowed value.
378      */
379     @Test
380     public void parseUriParametersContentParameterNegativeTest() {
381         final UriInfo uriInfo = mock(UriInfo.class);
382         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
383
384         parameters.put("content", List.of("not-allowed-parameter-value"));
385         when(uriInfo.getQueryParameters()).thenReturn(parameters);
386
387         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
388             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
389         // Bad request
390         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
391         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
392     }
393
394     /**
395      * Negative test of parsing request URI parameters when depth parameter has not allowed value.
396      */
397     @Test
398     public void parseUriParametersDepthParameterNegativeTest() {
399         final UriInfo uriInfo = mock(UriInfo.class);
400         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
401
402         // inserted value is not allowed
403         parameters.put("depth", List.of("bounded"));
404         when(uriInfo.getQueryParameters()).thenReturn(parameters);
405
406         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
407             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
408         // Bad request
409         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
410         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
411     }
412
413     /**
414      * Negative test of parsing request URI parameters when depth parameter has not allowed value (less than minimum).
415      */
416     @Test
417     public void parseUriParametersDepthMinimalParameterNegativeTest() {
418         final UriInfo uriInfo = mock(UriInfo.class);
419         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
420
421         // inserted value is too low
422         parameters.put("depth", List.of("0"));
423         when(uriInfo.getQueryParameters()).thenReturn(parameters);
424
425         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
426             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
427         // Bad request
428         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
429         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
430     }
431
432     /**
433      * Negative test of parsing request URI parameters when depth parameter has not allowed value (more than maximum).
434      */
435     @Test
436     public void parseUriParametersDepthMaximalParameterNegativeTest() {
437         final UriInfo uriInfo = mock(UriInfo.class);
438         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
439
440         // inserted value is too high
441         parameters.put("depth", List.of("65536"));
442         when(uriInfo.getQueryParameters()).thenReturn(parameters);
443
444         RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
445             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
446         // Bad request
447         assertEquals("Error type is not correct", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
448         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
449     }
450
451     /**
452      * Testing parsing of with-defaults parameter which value doesn't match report-all or report-all-tagged patterns
453      * - non-reporting setting.
454      */
455     @Test
456     public void parseUriParametersWithDefaultAndNonTaggedTest() {
457         // preparation of input data
458         final UriInfo uriInfo = mock(UriInfo.class);
459         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
460         parameters.put("with-defaults", List.of("explicit"));
461         when(uriInfo.getQueryParameters()).thenReturn(parameters);
462
463         final QueryParameters writerParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
464         assertSame(WithDefaultsParameter.EXPLICIT, writerParameters.getWithDefault());
465         assertFalse(writerParameters.isTagged());
466     }
467
468     /**
469      * Testing parsing of with-defaults parameter which value which is not supported.
470      */
471     @Test
472     public void parseUriParametersWithDefaultInvalidTest() {
473         // preparation of input data
474         final UriInfo uriInfo = mock(UriInfo.class);
475         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
476         parameters.put("with-defaults", List.of("invalid"));
477         when(uriInfo.getQueryParameters()).thenReturn(parameters);
478
479         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
480             () -> ReadDataTransactionUtil.parseUriParameters(context, uriInfo));
481         final List<RestconfError> errors = ex.getErrors();
482         assertEquals(1, errors.size());
483         assertEquals(ErrorTag.INVALID_VALUE, errors.get(0).getErrorTag());
484     }
485
486     /**
487      * Testing parsing of with-defaults parameter which value matches 'report-all-tagged' setting - default value should
488      * be set to {@code null} and tagged flag should be set to {@code true}.
489      */
490     @Test
491     public void parseUriParametersWithDefaultAndTaggedTest() {
492         // preparation of input data
493         final UriInfo uriInfo = mock(UriInfo.class);
494         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
495         parameters.put("with-defaults", List.of("report-all-tagged"));
496         when(uriInfo.getQueryParameters()).thenReturn(parameters);
497
498         final QueryParameters writerParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
499         assertNull(writerParameters.getWithDefault());
500         assertTrue(writerParameters.isTagged());
501     }
502
503     /**
504      * Testing parsing of with-defaults parameter which value matches 'report-all' setting - default value should
505      * be set to {@code null} and tagged flag should be set to {@code false}.
506      */
507     @Test
508     public void parseUriParametersWithDefaultAndReportAllTest() {
509         // preparation of input data
510         final UriInfo uriInfo = mock(UriInfo.class);
511         final MultivaluedHashMap<String, String> parameters = new MultivaluedHashMap<>();
512         parameters.put("with-defaults", List.of("report-all"));
513         when(uriInfo.getQueryParameters()).thenReturn(parameters);
514
515         final QueryParameters writerParameters = ReadDataTransactionUtil.parseUriParameters(context, uriInfo);
516         assertNull(writerParameters.getWithDefault());
517         assertFalse(writerParameters.isTagged());
518     }
519
520     /**
521      * Test when parameter is present at most once.
522      */
523     @Test
524     public void checkParameterCountTest() {
525         ReadDataTransactionUtil.checkParameterCount(List.of("all"), ContentParameter.uriName());
526     }
527
528     /**
529      * Test when parameter is present more than once.
530      */
531     @Test
532     public void checkParameterCountNegativeTest() {
533         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
534             () -> ReadDataTransactionUtil.checkParameterCount(List.of("config", "nonconfig", "all"),
535                     ContentParameter.uriName()));
536         final List<RestconfError> errors = ex.getErrors();
537         assertEquals(1, errors.size());
538
539         final RestconfError error = errors.get(0);
540         assertEquals("Error type is not correct", ErrorType.PROTOCOL, error.getErrorType());
541         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, error.getErrorTag());
542     }
543
544
545     /**
546      * Test when all parameters are allowed.
547      */
548     @Test
549     public void checkParametersTypesTest() {
550         ReadDataTransactionUtil.checkParametersTypes(Set.of("content"),
551             Set.of(ContentParameter.uriName(), DepthParameter.uriName()));
552     }
553
554     /**
555      * Test when not allowed parameter type is used.
556      */
557     @Test
558     public void checkParametersTypesNegativeTest() {
559         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
560             () -> ReadDataTransactionUtil.checkParametersTypes(Set.of("not-allowed-parameter"),
561                 Set.of(ContentParameter.uriName(), DepthParameter.uriName())));
562         final List<RestconfError> errors = ex.getErrors();
563         assertEquals(1, errors.size());
564
565         final RestconfError error = errors.get(0);
566         assertEquals("Error type is not correct", ErrorType.PROTOCOL, error.getErrorType());
567         assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, error.getErrorTag());
568     }
569
570     /**
571      * Read specific type of data from data store via transaction.
572      *
573      * @param content        type of data to read (config, state, all)
574      * @param strategy       {@link RestconfStrategy} - wrapper for variables
575      * @return {@link NormalizedNode}
576      */
577     private @Nullable NormalizedNode readData(final @NonNull ContentParameter content,
578             final YangInstanceIdentifier path, final @NonNull RestconfStrategy strategy) {
579         return ReadDataTransactionUtil.readData(content, path, strategy, null, schemaContext);
580     }
581 }