+ def 'Cps Path querys with all descendants including descendants that are list entries: #scenario.'() {
+ when: 'a query is executed to get a data node by the given cps path'
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, INCLUDE_ALL_DESCENDANTS)
+ then: 'correct number of datanodes are returned'
+ assert countDataNodesInTree(result) == expectedNumberOfDataNodes
+ where:
+ scenario | cpsPath || expectedNumberOfDataNodes
+ 'absolute path all list entries' | '/bookstore/categories' || 24
+ 'absolute path 1 list entry by key' | '/bookstore/categories[@code="3"]' || 5
+ 'absolute path 1 list entry by name' | '/bookstore/categories[@name="Comedy"]' || 5
+ 'relative path all list entries' | '//categories' || 24
+ 'relative path 1 list entry by key' | '//categories[@code="3"]' || 5
+ 'relative path 1 list entry by leaf' | '//categories[@name="Comedy"]' || 5
+ 'incomplete absolute path' | '/categories' || 0
+ 'incomplete absolute 1 list entry' | '/categories[@code="3"]' || 0
+ }
+
+ def 'Cps Path query contains #wildcard.'() {
+ when: 'a query is executed with a wildcard in the given cps path'
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, INCLUDE_ALL_DESCENDANTS)
+ then: 'no results are returned, as Cps Path query does not interpret wildcard characters'
+ assert result.isEmpty()
+ where:
+ wildcard | cpsPath
+ ' sql wildcard in parent path list index' | '/bookstore/categories[@code="%"]/books'
+ 'regex wildcard in parent path list index' | '/bookstore/categories[@code=".*"]/books'
+ ' sql wildcard in leaf-condition' | '/bookstore/categories[@code="1"]/books[@title="%"]'
+ 'regex wildcard in leaf-condition' | '/bookstore/categories[@code="1"]/books[@title=".*"]'
+ ' sql wildcard in text-condition' | '/bookstore/categories[@code="1"]/books/title[text()="%"]'
+ 'regex wildcard in text-condition' | '/bookstore/categories[@code="1"]/books/title[text()=".*"]'
+ ' sql wildcard in contains-condition' | '/bookstore/categories[@code="1"]/books[contains(@title, "%")]'
+ 'regex wildcard in contains-condition' | '/bookstore/categories[@code="1"]/books[contains(@title, ".*")]'
+ }
+
+ def 'Cps Path query can return a data node containing [@ in xpath #scenario.'() {
+ given: 'a book with special characters [@ and ] in title'
+ cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, "/bookstore/categories[@code='1']", '{"books": [ {"title":"[@hello=world]"} ] }', OffsetDateTime.now())
+ when: 'a query is executed'
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS)
+ then: 'the node is returned'
+ assert result.size() == 1
+ cleanup: 'the new datanode'
+ cpsDataService.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, "/bookstore/categories[@code='1']/books[@title='[@hello=world]']", OffsetDateTime.now())
+ where:
+ scenario || cpsPath
+ 'leaf-condition' || "/bookstore/categories[@code='1']/books[@title='[@hello=world]']"
+ 'text-condition' || "/bookstore/categories[@code='1']/books/title[text()='[@hello=world]']"
+ 'contains-condition' || "/bookstore/categories[@code='1']/books[contains(@title, '[@hello=world]')]"
+ }
+
+ def 'Cps Path get and query can handle apostrophe inside #quotes.'() {
+ given: 'a book with special characters in title'
+ cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, "/bookstore/categories[@code='1']",
+ '{"books": [ {"title":"I\'m escaping"} ] }', OffsetDateTime.now())
+ when: 'a query is executed'
+ def result = objectUnderTest.queryDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, OMIT_DESCENDANTS)
+ then: 'the node is returned'
+ assert result.size() == 1
+ assert result[0].xpath == "/bookstore/categories[@code='1']/books[@title='I''m escaping']"
+ cleanup: 'the new datanode'
+ cpsDataService.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, "/bookstore/categories[@code='1']/books[@title='I''m escaping']", OffsetDateTime.now())
+ where:
+ quotes || cpsPath
+ 'single quotes' || "/bookstore/categories[@code='1']/books[@title='I''m escaping']"
+ 'double quotes' || '/bookstore/categories[@code="1"]/books[@title="I\'m escaping"]'
+ 'text-condition' || "/bookstore/categories[@code='1']/books/title[text()='I''m escaping']"
+ 'contains-condition' || "/bookstore/categories[@code='1']/books[contains(@title, 'I''m escaping')]"
+ }