Bug 6903 - Implement Query parameters - fields
[netconf.git] / restconf / sal-rest-connector / src / test / java / org / opendaylight / restconf / utils / parser / ParserFieldsParameterTest.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
9 package org.opendaylight.restconf.utils.parser;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15
16 import java.net.URI;
17 import java.text.SimpleDateFormat;
18 import java.util.List;
19 import java.util.Set;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.mockito.Mock;
23 import org.mockito.Mockito;
24 import org.mockito.MockitoAnnotations;
25 import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
26 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
27 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
28 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
29 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.common.QNameModule;
32 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36
37 /**
38  * Unit test for {@link ParserFieldsParameter}
39  */
40 public class ParserFieldsParameterTest {
41
42     @Mock
43     private InstanceIdentifierContext<ContainerSchemaNode> identifierContext;
44
45     // container jukebox
46     @Mock
47     private ContainerSchemaNode containerJukebox;
48     private QName jukeboxQName;
49
50     // container player
51     @Mock
52     private ContainerSchemaNode containerPlayer;
53     private QName playerQName;
54
55     // container library
56     @Mock
57     private ContainerSchemaNode containerLibrary;
58     private QName libraryQName;
59
60     // container augmented library
61     @Mock
62     private ContainerSchemaNode augmentedContainerLibrary;
63     private QName augmentedLibraryQName;
64
65     // list album
66     @Mock
67     private ListSchemaNode listAlbum;
68     private QName albumQName;
69
70     // leaf name
71     @Mock
72     private LeafSchemaNode leafName;
73     private QName nameQName;
74
75     @Before
76     public void setUp() throws Exception {
77         MockitoAnnotations.initMocks(this);
78         final SchemaContext schemaContext = TestRestconfUtils.loadSchemaContext("/jukebox");
79
80         final QNameModule qNameModule = QNameModule.create(URI.create("http://example.com/ns/example-jukebox"),
81                 new SimpleDateFormat("yyyy-MM-dd").parse("2015-04-04"));
82
83         jukeboxQName = QName.create(qNameModule, "jukebox");
84         playerQName = QName.create(qNameModule, "player");
85         libraryQName = QName.create(qNameModule, "library");
86         augmentedLibraryQName = QName.create(
87                 QNameModule.create(
88                         URI.create("http://example.com/ns/augmented-jukebox"),
89                         new SimpleDateFormat("yyyy-MM-dd").parse("2016-05-05")),
90                 "augmented-library");
91         albumQName = QName.create(qNameModule, "album");
92         nameQName = QName.create(qNameModule, "name");
93
94         Mockito.when(identifierContext.getSchemaContext()).thenReturn(schemaContext);
95         Mockito.when(containerJukebox.getQName()).thenReturn(jukeboxQName);
96         Mockito.when(identifierContext.getSchemaNode()).thenReturn(containerJukebox);
97
98         Mockito.when(containerLibrary.getQName()).thenReturn(libraryQName);
99         Mockito.when(containerJukebox.getDataChildByName(libraryQName)).thenReturn(containerLibrary);
100
101         Mockito.when(augmentedContainerLibrary.getQName()).thenReturn(augmentedLibraryQName);
102         Mockito.when(containerJukebox.getDataChildByName(augmentedLibraryQName)).thenReturn(augmentedContainerLibrary);
103
104         Mockito.when(containerPlayer.getQName()).thenReturn(playerQName);
105         Mockito.when(containerJukebox.getDataChildByName(playerQName)).thenReturn(containerPlayer);
106
107         Mockito.when(listAlbum.getQName()).thenReturn(albumQName);
108         Mockito.when(containerLibrary.getDataChildByName(albumQName)).thenReturn(listAlbum);
109
110         Mockito.when(leafName.getQName()).thenReturn(nameQName);
111         Mockito.when(listAlbum.getDataChildByName(nameQName)).thenReturn(leafName);
112     }
113
114     /**
115      * Test parse fields parameter containing only one child selected
116      */
117     @Test
118     public void parseFieldsParameterSimplePathTest() {
119         final String input = "library";
120         final List<Set<QName>> parsedFields = ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
121
122         assertNotNull(parsedFields);
123         assertEquals(1, parsedFields.size());
124         assertEquals(1, parsedFields.get(0).size());
125         assertTrue(parsedFields.get(0).contains(libraryQName));
126     }
127
128     /**
129      * Test parse fields parameter containing two child nodes selected
130      */
131     @Test
132     public void parseFieldsParameterDoublePathTest() {
133         final String input = "library;player";
134         final List<Set<QName>> parsedFields = ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
135
136         assertNotNull(parsedFields);
137         assertEquals(1, parsedFields.size());
138         assertEquals(2, parsedFields.get(0).size());
139         assertTrue(parsedFields.get(0).contains(libraryQName));
140         assertTrue(parsedFields.get(0).contains(playerQName));
141     }
142
143     /**
144      * Test parse fields parameter containing sub-children selected delimited by slash
145      */
146     @Test
147     public void parseFieldsParameterSubPathTest() {
148         final String input = "library/album/name";
149         final List<Set<QName>> parsedFields = ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
150
151         assertNotNull(parsedFields);
152         assertEquals(3, parsedFields.size());
153
154         assertEquals(1, parsedFields.get(0).size());
155         assertTrue(parsedFields.get(0).contains(libraryQName));
156
157         assertEquals(1, parsedFields.get(1).size());
158         assertTrue(parsedFields.get(1).contains(albumQName));
159
160         assertEquals(1, parsedFields.get(2).size());
161         assertTrue(parsedFields.get(2).contains(nameQName));
162     }
163
164     /**
165      * Test parse fields parameter containing sub-children selected delimited by parenthesis
166      */
167     @Test
168     public void parseFieldsParameterChildrenPathTest() {
169         final String input = "library(album(name))";
170         final List<Set<QName>> parsedFields = ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
171
172         assertNotNull(parsedFields);
173         assertEquals(3, parsedFields.size());
174
175         assertEquals(1, parsedFields.get(0).size());
176         assertTrue(parsedFields.get(0).contains(libraryQName));
177
178         assertEquals(1, parsedFields.get(1).size());
179         assertTrue(parsedFields.get(1).contains(albumQName));
180
181         assertEquals(1, parsedFields.get(2).size());
182         assertTrue(parsedFields.get(2).contains(nameQName));
183     }
184
185     /**
186      * Test parse fields parameter when augmentation with different namespace is used
187      */
188     @Test
189     public void parseFieldsParameterNamespaceTest() {
190         final String input = "augmented-jukebox:augmented-library";
191         final List<Set<QName>> parsedFields = ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
192
193         assertNotNull(parsedFields);
194         assertEquals(1, parsedFields.size());
195
196         assertEquals(1, parsedFields.get(0).size());
197         assertTrue(parsedFields.get(0).contains(augmentedLibraryQName));
198     }
199
200     /**
201      * Test parse fields parameter containing not expected character
202      */
203     @Test
204     public void parseFieldsParameterNotExpectedCharacterNegativeTest() {
205         final String input = "*";
206
207         try {
208             ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
209             fail("Test should fail due to not expected character used in parameter input value");
210         } catch (final RestconfDocumentedException e) {
211             // Bad request
212             assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
213             assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
214             assertEquals("Error status code is not correct", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
215         }
216     }
217
218     /**
219      * Test parse fields parameter with missing closing parenthesis
220      */
221     @Test
222     public void parseFieldsParameterMissingParenthesisNegativeTest() {
223         final String input = "library(";
224
225         try {
226             ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
227             fail("Test should fail due to missing closing parenthesis");
228         } catch (final RestconfDocumentedException e) {
229             // Bad request
230             assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
231             assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
232             assertEquals("Error status code is not correct", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
233         }
234     }
235
236     /**
237      * Test parse fields parameter when not existing child node selected
238      */
239     @Test
240     public void parseFieldsParameterMissingChildNodeNegativeTest() {
241         final String input = "library(not-existing)";
242
243         try {
244             ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
245             fail("Test should fail due to missing child node in parent node");
246         } catch (final RestconfDocumentedException e) {
247             // Bad request
248             assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
249             assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
250             assertEquals("Error status code is not correct", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
251         }
252     }
253
254     /**
255      * Test parse fields parameter with unexpected character after parenthesis
256      */
257     @Test
258     public void parseFieldsParameterAfterParenthesisNegativeTest() {
259         final String input = "library(album);";
260
261         try {
262             ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
263             fail("Test should fail due to unexpected character after parenthesis");
264         } catch (final RestconfDocumentedException e) {
265             // Bad request
266             assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
267             assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
268             assertEquals("Error status code is not correct", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
269         }
270     }
271
272     /**
273      * Test parse fields parameter with missing semicolon after parenthesis
274      */
275     @Test
276     public void parseFieldsParameterMissingSemicolonNegativeTest() {
277         final String input = "library(album)player";
278
279         try {
280             ParserFieldsParameter.parseFieldsParameter(identifierContext, input);
281             fail("Test should fail due to missing semicolon after parenthesis");
282         } catch (final RestconfDocumentedException e) {
283             // Bad request
284             assertEquals("Error type is not correct", ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
285             assertEquals("Error tag is not correct", ErrorTag.INVALID_VALUE, e.getErrors().get(0).getErrorTag());
286             assertEquals("Error status code is not correct", 400, e.getErrors().get(0).getErrorTag().getStatusCode());
287         }
288     }
289 }