2 * Copyright (c) 2016 Cisco Systems, Inc. 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.nb.rfc8040.utils.parser;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
12 import static org.junit.Assert.assertTrue;
14 import com.google.common.collect.Iterables;
15 import com.google.common.collect.Sets;
16 import java.io.FileNotFoundException;
17 import java.util.Iterator;
18 import java.util.LinkedHashMap;
20 import java.util.Map.Entry;
22 import org.junit.AfterClass;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
26 import org.opendaylight.restconf.common.errors.RestconfError;
27 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
28 import org.opendaylight.yangtools.yang.common.ErrorType;
29 import org.opendaylight.yangtools.yang.common.QName;
30 import org.opendaylight.yangtools.yang.common.Revision;
31 import org.opendaylight.yangtools.yang.common.Uint8;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
38 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
39 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
42 * Unit tests for {@link YangInstanceIdentifierDeserializer}.
44 public class YangInstanceIdentifierDeserializerTest {
46 private static EffectiveModelContext SCHEMA_CONTEXT;
49 public static void beforeClass() throws FileNotFoundException {
51 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/restconf/parser/deserializer"));
55 public static void afterClass() {
56 SCHEMA_CONTEXT = null;
60 * Test of deserialization <code>String</code> URI with container to
61 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
64 public void deserializeContainerTest() {
65 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
66 .create(SCHEMA_CONTEXT, "deserializer-test:contA");
68 assertEquals("Result does not contains expected number of path arguments", 1, Iterables.size(result));
69 assertEquals("Not expected path argument",
70 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
71 result.iterator().next());
75 * Test of deserialization <code>String</code> URI with container containing leaf to
76 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
79 public void deserializeContainerWithLeafTest() {
80 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
81 .create(SCHEMA_CONTEXT, "deserializer-test:contA/leaf-A");
83 assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
85 final Iterator<PathArgument> iterator = result.iterator();
86 assertEquals("Not expected path argument",
87 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
89 assertEquals("Not expected path argument",
90 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "leaf-A")),
95 * Test of deserialization <code>String</code> URI with container containing list with leaf list to
96 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
99 public void deserializeContainerWithListWithLeafListTest() {
100 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
101 .create(SCHEMA_CONTEXT, "deserializer-test:contA/list-A=100/leaf-list-AA=instance");
103 assertEquals("Result does not contains expected number of path arguments", 5, Iterables.size(result));
105 final Iterator<PathArgument> iterator = result.iterator();
108 assertEquals("Not expected path argument",
109 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
113 final QName list = QName.create("deserializer:test", "2016-06-06", "list-A");
114 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
115 assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(
116 list, QName.create(list, "list-key"), 100).toString(), iterator.next().toString());
119 final QName leafList = QName.create("deserializer:test", "2016-06-06", "leaf-list-AA");
120 assertEquals("Not expected path argument", NodeIdentifier.create(leafList), iterator.next());
121 assertEquals("Not expected path argument", new NodeWithValue<>(leafList, "instance"), iterator.next());
125 * Test of deserialization <code>String</code> URI with container containing list with Action to
126 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
129 public void deserializeContainerWithListWithActionTest() {
130 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
131 "example-actions:interfaces/interface=eth0/reset");
132 assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));
134 final Iterator<PathArgument> iterator = result.iterator();
137 assertEquals("Not expected path argument",
138 NodeIdentifier.create(QName.create("https://example.com/ns/example-actions", "2016-07-07", "interfaces")),
142 final QName list = QName.create("https://example.com/ns/example-actions", "2016-07-07", "interface");
143 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
144 assertEquals("Not expected path argument",
145 NodeIdentifierWithPredicates.of(list, QName.create(list, "name"), "eth0"), iterator.next());
148 final QName action = QName.create("https://example.com/ns/example-actions", "2016-07-07", "reset");
149 assertEquals("Not expected path argument", NodeIdentifier.create(action),
154 * Test of deserialization <code>String</code> URI containing list with no keys to
155 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
158 public void deserializeListWithNoKeysTest() {
159 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
160 "deserializer-test:list-no-key");
162 assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
164 final Iterator<PathArgument> iterator = result.iterator();
165 final QName list = QName.create("deserializer:test", "2016-06-06", "list-no-key");
167 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
168 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
172 * Test of deserialization <code>String</code> URI containing list with one key to
173 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
176 public void deserializeListWithOneKeyTest() {
177 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
178 "deserializer-test:list-one-key=value");
180 assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
182 final Iterator<PathArgument> iterator = result.iterator();
183 final QName list = QName.create("deserializer:test", "2016-06-06", "list-one-key");
185 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
186 assertEquals("Not expected path argument",
187 NodeIdentifierWithPredicates.of(list, QName.create(list, "name"), "value"), iterator.next());
191 * Test of deserialization <code>String</code> URI containing list with multiple keys to
192 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
195 public void deserializeListWithMultipleKeysTest() {
196 final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
197 final Map<QName, Object> values = new LinkedHashMap<>();
198 values.put(QName.create(list, "name"), "value");
199 values.put(QName.create(list, "number"), 100);
200 values.put(QName.create(list, "enabled"), false);
202 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
203 "deserializer-test:list-multiple-keys=value,100,false");
205 assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
207 final Iterator<PathArgument> iterator = result.iterator();
209 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
210 assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(list, values).toString(),
211 iterator.next().toString());
215 * Test of deserialization <code>String</code> URI containing leaf list to
216 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
219 public void deserializeLeafListTest() {
220 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
221 "deserializer-test:leaf-list-0=true");
223 assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
225 final Iterator<PathArgument> iterator = result.iterator();
226 final QName leafList = QName.create("deserializer:test", "2016-06-06", "leaf-list-0");
228 assertEquals("Not expected path argument", new NodeIdentifier(leafList), iterator.next());
229 assertEquals("Not expected path argument",
230 new NodeWithValue<>(leafList, true).toString(), iterator.next().toString());
234 * Test when empty <code>String</code> is supplied as an input. Test is expected to return empty result.
237 public void deserializeEmptyDataTest() {
238 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "");
239 assertTrue("Empty result expected", Iterables.isEmpty(result));
243 * Test of deserialization <code>String</code> URI with identifiers separated by multiple slashes to
244 * {@code Iterable<YangInstanceIdentifier.PathArgument>}.
247 public void deserializeMultipleSlashesTest() {
248 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
249 .create(SCHEMA_CONTEXT, "deserializer-test:contA////list-A=40//list-key");
251 assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));
253 final Iterator<PathArgument> iterator = result.iterator();
256 assertEquals("Not expected path argument",
257 NodeIdentifier.create(QName.create("deserializer:test", "2016-06-06", "contA")),
261 final QName list = QName.create("deserializer:test", "2016-06-06", "list-A");
262 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
263 assertEquals("Not expected path argument",
264 NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 40).toString(),
265 iterator.next().toString());
268 assertEquals("Not expected path argument",
269 new NodeIdentifier(QName.create("deserializer:test", "2016-06-06", "list-key")), iterator.next());
273 * Negative test when supplied <code>SchemaContext</code> is null. Test is expected to fail with
274 * <code>NullPointerException</code>.
277 public void deserializeNullSchemaContextNegativeTest() {
278 assertThrows(NullPointerException.class,
279 () -> YangInstanceIdentifierDeserializer.create(null, "deserializer-test:contA"));
283 * Negative test when supplied <code>String</code> data to deserialize is null. Test is expected to fail with
284 * <code>NullPointerException</code>.
287 public void nullDataNegativeNegativeTest() {
288 assertThrows(NullPointerException.class,
289 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, null));
293 * Negative test when identifier is not followed by slash or equals. Test is expected to fail with
294 * <code>RestconfDocumentedException</code>.
297 public void deserializeBadCharMissingSlashOrEqualNegativeTest() {
298 assertThrows(RestconfDocumentedException.class,
299 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:cont*leaf-A"));
303 * Negative test of validating identifier when there is a slash after container without next identifier. Test
304 * is expected to fail with <code>RestconfDocumentedException</code>.
307 public void validArgIdentifierContainerEndsWithSlashNegativeTest() {
308 assertThrows(RestconfDocumentedException.class,
309 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA/"));
313 * Negative test of validating identifier when there are multiple slashes after container without next identifier.
314 * Test is expected to fail with <code>RestconfDocumentedException</code>.
317 public void validArgIdentifierContainerEndsWithMultipleSlashesNegativeTest() {
318 assertThrows(RestconfDocumentedException.class,
319 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA///"));
323 * Negative test of validating identifier when there is a slash after list key values without next identifier. Test
324 * is expected to fail with <code>RestconfDocumentedException</code>.
327 public void validArgIdentifierListEndsWithSlashLNegativeTest() {
328 assertThrows(RestconfDocumentedException.class,
329 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-one-key=value/"));
333 * Negative test of validating identifier when there are multiple slashes after list key values without next
334 * identifier. Test is expected to fail with <code>RestconfDocumentedException</code>.
337 public void validArgIdentifierListEndsWithSlashesNegativeTest() {
338 assertThrows(RestconfDocumentedException.class,
339 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-one-key=value//"));
343 * Negative test of creating <code>QName</code> when identifier is empty (example: '/'). Test is expected to fail
344 * with <code>RestconfDocumentedException</code>.
347 public void prepareQnameEmptyIdentifierNegativeTest() {
348 assertThrows(RestconfDocumentedException.class,
349 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "/"));
353 * Negative test of creating <code>QName</code> when in identifier there is another sign than colon or equals.
354 * Test is expected to fail with <code>RestconfDocumentedException</code>.
357 public void prepareQnameBuildPathNegativeTest() {
358 assertThrows(RestconfDocumentedException.class,
359 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test*contA"));
363 * Negative test of creating <code>QName</code> when it is not possible to find module for specified prefix. Test is
364 * expected to fail with <code>RestconfDocumentedException</code>.
367 public void prepareQnameNotExistingPrefixNegativeTest() {
368 assertThrows(RestconfDocumentedException.class,
369 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "not-existing:contA"));
373 * Negative test of creating <code>QName</code> when after prefix and colon there is not parsable identifier as
374 * local name. Test is expected to fail with <code>RestconfDocumentedException</code>.
377 public void prepareQnameNotValidPrefixAndLocalNameNegativeTest() {
378 assertThrows(RestconfDocumentedException.class, () ->
379 YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:*not-parsable-identifier"));
383 * Negative test of creating <code>QName</code> when data ends after prefix and colon. Test is expected to fail
384 * with <code>StringIndexOutOfBoundsException</code>.
387 public void prepareQnameErrorParsingNegativeTest() {
388 assertThrows(StringIndexOutOfBoundsException.class,
389 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:"));
393 * Negative test of creating <code>QName</code> when after identifier and colon there is node name of unknown
394 * node in current container. Test is expected to fail with <code>RestconfDocumentedException</code> and error
395 * type, error tag and error status code are compared to expected values.
398 public void prepareQnameNotValidContainerNameNegativeTest() {
399 RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
400 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:contA/leafB"));
401 assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
402 assertEquals("Not expected error tag", RestconfError.ErrorTag.DATA_MISSING,
403 ex.getErrors().get(0).getErrorTag());
407 * Negative test of creating <code>QName</code> when after identifier and equals there is node name of unknown
408 * node in current list. Test is expected to fail with <code>RestconfDocumentedException</code> and error
409 * type, error tag and error status code are compared to expected values.
412 public void prepareQnameNotValidListNameNegativeTest() {
413 RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
414 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
415 "deserializer-test:list-no-key/disabled=false"));
416 assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
417 assertEquals("Not expected error tag", RestconfError.ErrorTag.DATA_MISSING,
418 ex.getErrors().get(0).getErrorTag());
422 * Negative test of getting next identifier when current node is keyed entry. Test is expected to
423 * fail with <code>RestconfDocumentedException</code>.
426 public void prepareIdentifierNotKeyedEntryNegativeTest() {
427 assertThrows(RestconfDocumentedException.class,
428 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:list-one-key"));
432 * Negative test when there is a comma also after the last key. Test is expected to fail with
433 * <code>RestconfDocumentedException</code>.
436 public void deserializeKeysEndsWithComaNegativeTest() {
437 assertThrows(RestconfDocumentedException.class, () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
438 "deserializer-test:list-multiple-keys=value,100,false,"));
442 * Positive when not all keys of list are encoded. The missing keys should be considered to has empty
443 * <code>String</code> values. Also value of next leaf must not be considered to be missing key value.
446 public void notAllListKeysEncodedPositiveTest() {
447 final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
448 final Map<QName, Object> values = new LinkedHashMap<>();
449 values.put(QName.create(list, "name"), ":foo");
450 values.put(QName.create(list, "number"), "");
451 values.put(QName.create(list, "enabled"), "");
453 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(
454 SCHEMA_CONTEXT, "deserializer-test:list-multiple-keys=%3Afoo,,/string-value");
456 assertEquals("Result does not contains expected number of path arguments", 3, Iterables.size(result));
458 final Iterator<PathArgument> iterator = result.iterator();
461 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
462 assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(list, values).toString(),
463 iterator.next().toString());
466 assertEquals("Not expected path argument",
467 new NodeIdentifier(QName.create("deserializer:test", "2016-06-06", "string-value")), iterator.next());
471 * Negative test when not all keys of list are encoded and it is not possible to consider missing keys to be empty.
472 * Test is expected to fail with <code>RestconfDocumentedException</code> and error type, error tag and error
473 * status code are compared to expected values.
476 public void notAllListKeysEncodedNegativeTest() {
477 RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
478 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
479 "deserializer-test:list-multiple-keys=%3Afoo/string-value"));
480 assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
481 assertEquals("Not expected error tag", RestconfError.ErrorTag.MISSING_ATTRIBUTE,
482 ex.getErrors().get(0).getErrorTag());
483 assertEquals("Not expected error status code", 400, ex.getErrors().get(0).getErrorTag().getStatusCode());
487 * Test URI with list where key value starts with, ends with or contains percent encoded characters.The encoded
488 * value should be complete also with not percent-encoded parts.
491 public void percentEncodedKeyEndsWithNoPercentEncodedChars() {
492 final String URI = "deserializer-test:list-multiple-keys=%3Afoo,1,true";
493 final YangInstanceIdentifier result = YangInstanceIdentifier.create(
494 YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, URI));
496 final Iterator<Entry<QName, Object>> resultListKeys =
497 ((NodeIdentifierWithPredicates)result.getLastPathArgument()).entrySet().iterator();
499 assertEquals(":foo", resultListKeys.next().getValue());
500 assertEquals(Uint8.ONE, resultListKeys.next().getValue());
501 assertEquals(true, resultListKeys.next().getValue());
505 * Positive test when all keys of list can be considered to be empty <code>String</code>.
508 public void deserializeAllKeysEmptyTest() {
509 final QName list = QName.create("deserializer:test", "2016-06-06", "list-multiple-keys");
510 final Map<QName, Object> values = new LinkedHashMap<>();
511 values.put(QName.create(list, "name"), "");
512 values.put(QName.create(list, "number"), "");
513 values.put(QName.create(list, "enabled"), "");
515 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer
516 .create(SCHEMA_CONTEXT, "deserializer-test:list-multiple-keys=,,");
518 assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
520 final Iterator<PathArgument> iterator = result.iterator();
522 assertEquals("Not expected path argument", NodeIdentifier.create(list), iterator.next());
523 assertEquals("Not expected path argument", NodeIdentifierWithPredicates.of(list, values).toString(),
524 iterator.next().toString());
528 * Negative test of deserialization when for leaf list there is no specified instance value.
529 * <code>RestconfDocumentedException</code> is expected and error type, error tag and error status code are
530 * compared to expected values.
533 public void leafListMissingKeyNegativeTest() {
534 RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
535 () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT, "deserializer-test:leaf-list-0="));
536 assertEquals("Not expected error type", ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
537 assertEquals("Not expected error tag", RestconfError.ErrorTag.MISSING_ATTRIBUTE,
538 ex.getErrors().get(0).getErrorTag());
539 assertEquals("Not expected error status code", 400, ex.getErrors().get(0).getErrorTag().getStatusCode());
543 * Positive test of deserialization when parts of input URI <code>String</code> are defined in another module.
546 public void deserializePartInOtherModuleTest() {
547 final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
548 "deserializer-test-included:augmented-list=100/augmented-leaf");
550 assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));
552 final Iterator<PathArgument> iterator = result.iterator();
553 final QName list = QName.create("deserializer:test:included", "2016-06-06", "augmented-list");
554 final QName child = QName.create("deserializer:test", "2016-06-06", "augmented-leaf");
557 assertEquals("Not expected path argument",
558 NodeIdentifier.create(list),
561 assertEquals("Not expected path argument",
562 NodeIdentifierWithPredicates.of(list, QName.create(list, "list-key"), 100).toString(),
563 iterator.next().toString());
566 assertEquals("Not expected path argument", new AugmentationIdentifier(Sets.newHashSet(child)), iterator.next());
567 assertEquals("Not expected path argument", NodeIdentifier.create(child), iterator.next());
571 * Deserialization of path that contains list entry with key which value is described by leaflef to identityref.
574 public void deserializePathWithIdentityrefKeyValueTest() {
575 final Iterable<PathArgument> pathArgs = YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
576 "refs/list-with-identityref=deserializer-test%3Aderived-identity/foo");
577 assertEquals(4, Iterables.size(pathArgs));
578 final Iterator<PathArgument> pathArgsIterator = pathArgs.iterator();
580 assertEquals("refs", pathArgsIterator.next().getNodeType().getLocalName());
581 assertEquals("list-with-identityref", pathArgsIterator.next().getNodeType().getLocalName());
583 final PathArgument listEntryArg = pathArgsIterator.next();
584 assertTrue(listEntryArg instanceof NodeIdentifierWithPredicates);
585 assertEquals("list-with-identityref", listEntryArg.getNodeType().getLocalName());
586 final Set<QName> keys = ((NodeIdentifierWithPredicates) listEntryArg).keySet();
587 assertEquals(1, keys.size());
588 assertEquals("id", keys.iterator().next().getLocalName());
589 final Object keyValue = ((NodeIdentifierWithPredicates) listEntryArg).values().iterator().next();
590 assertEquals(QName.create("deserializer:test", "derived-identity", Revision.of("2016-06-06")), keyValue);
592 assertEquals("foo", pathArgsIterator.next().getNodeType().getLocalName());
596 * Identityref key value is not encoded correctly - ':' character must be encoded as '%3A'.
599 public void deserializePathWithInvalidIdentityrefKeyValueTest() {
600 assertThrows(RestconfDocumentedException.class, () -> YangInstanceIdentifierDeserializer.create(SCHEMA_CONTEXT,
601 "refs/list-with-identityref=deserializer-test:derived-identity/foo"));