- }
-
- static def createDataNodeTree(String... xpaths) {
- def dataNodeBuilder = new DataNodeBuilder().withXpath(xpaths[0])
- if (xpaths.length > 1) {
- def xPathsDescendant = Arrays.copyOfRange(xpaths, 1, xpaths.length)
- def childDataNode = createDataNodeTree(xPathsDescendant)
- dataNodeBuilder.withChildDataNodes(ImmutableSet.of(childDataNode))
- }
- dataNodeBuilder.build()
- }
-
- def getFragmentByXpath(dataspaceName, anchorName, xpath) {
- def dataspace = dataspaceRepository.getByName(dataspaceName)
- def anchor = anchorRepository.getByDataspaceAndName(dataspace, anchorName)
- return fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspace, anchor, xpath).orElseThrow()
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Get data node by xpath without descendants.'() {
- when: 'data node is requested'
- def result = objectUnderTest.getDataNode(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES,
- inputXPath, OMIT_DESCENDANTS)
- then: 'data node is returned with no descendants'
- assert result.getXpath() == XPATH_DATA_NODE_WITH_LEAVES
- and: 'expected leaves'
- assert result.getChildDataNodes().size() == 0
- assertLeavesMaps(result.getLeaves(), expectedLeavesByXpathMap[XPATH_DATA_NODE_WITH_LEAVES])
- where: 'the following data is used'
- scenario | inputXPath
- 'some xpath' | '/parent-100'
- 'root xpath' | '/'
- 'empty xpath' | ''
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Get data node by xpath with all descendants.'() {
- when: 'data node is requested with all descendants'
- def result = objectUnderTest.getDataNode(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES,
- inputXPath, INCLUDE_ALL_DESCENDANTS)
- def mappedResult = treeToFlatMapByXpath(new HashMap<>(), result)
- then: 'data node is returned with all the descendants populated'
- assert mappedResult.size() == 4
- assert result.getChildDataNodes().size() == 2
- assert mappedResult.get('/parent-100/child-001').getChildDataNodes().size() == 0
- assert mappedResult.get('/parent-100/child-002').getChildDataNodes().size() == 1
- and: 'extracted leaves maps are matching expected'
- mappedResult.forEach(
- (xPath, dataNode) -> assertLeavesMaps(dataNode.getLeaves(), expectedLeavesByXpathMap[xPath]))
- where: 'the following data is used'
- scenario | inputXPath
- 'some xpath' | '/parent-100'
- 'root xpath' | '/'
- 'empty xpath' | ''
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Get data node error scenario: #scenario.'() {
- when: 'attempt to get data node with #scenario'
- objectUnderTest.getDataNode(dataspaceName, anchorName, xpath, OMIT_DESCENDANTS)
- then: 'a #expectedException is thrown'
- thrown(expectedException)
- where: 'the following data is used'
- scenario | dataspaceName | anchorName | xpath || expectedException
- 'non-existing dataspace' | 'NO DATASPACE' | 'not relevant' | 'not relevant' || DataspaceNotFoundException
- 'non-existing anchor' | DATASPACE_NAME | 'NO ANCHOR' | 'not relevant' || AnchorNotFoundException
- 'non-existing xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | 'NO XPATH' || DataNodeNotFoundException
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Update data node leaves.'() {
- when: 'update is performed for leaves'
- objectUnderTest.updateDataLeaves(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES,
- "/parent-200/child-201", ['leaf-value': 'new'])
- then: 'leaves are updated for selected data node'
- def updatedFragment = fragmentRepository.getOne(UPDATE_DATA_NODE_FRAGMENT_ID)
- def updatedLeaves = getLeavesMap(updatedFragment)
- assert updatedLeaves.size() == 1
- assert updatedLeaves.'leaf-value' == 'new'
- and: 'existing child entry remains as is'
- def childFragment = updatedFragment.getChildFragments().iterator().next()
- def childLeaves = getLeavesMap(childFragment)
- assert childFragment.getId() == UPDATE_DATA_NODE_SUB_FRAGMENT_ID
- assert childLeaves.'leaf-value' == 'original'
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Update data leaves error scenario: #scenario.'() {
- when: 'attempt to update data node for #scenario'
- objectUnderTest.updateDataLeaves(dataspaceName, anchorName, xpath, ['leaf-name': 'leaf-value'])
- then: 'a #expectedException is thrown'
- thrown(expectedException)
- where: 'the following data is used'
- scenario | dataspaceName | anchorName | xpath || expectedException
- 'non-existing dataspace' | 'NO DATASPACE' | 'not relevant' | 'not relevant' || DataspaceNotFoundException
- 'non-existing anchor' | DATASPACE_NAME | 'NO ANCHOR' | 'not relevant' || AnchorNotFoundException
- 'non-existing xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | 'NON-EXISTING XPATH' || DataNodeNotFoundException
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Replace data node tree with descendants removal.'() {
- given: 'data node object with leaves updated, no children'
- def submittedDataNode = buildDataNode("/parent-200/child-201", ['leaf-value': 'new'], [])
- when: 'replace data node tree is performed'
- objectUnderTest.replaceDataNodeTree(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNode)
- then: 'leaves have been updated for selected data node'
- def updatedFragment = fragmentRepository.getOne(UPDATE_DATA_NODE_FRAGMENT_ID)
- def updatedLeaves = getLeavesMap(updatedFragment)
- assert updatedLeaves.size() == 1
- assert updatedLeaves.'leaf-value' == 'new'
- and: 'updated entry has no children'
- updatedFragment.getChildFragments().isEmpty()
- and: 'previously attached child entry is removed from database'
- fragmentRepository.findById(UPDATE_DATA_NODE_SUB_FRAGMENT_ID).isEmpty()
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Replace data node tree with descendants.'() {
- given: 'data node object with leaves updated, having child with old content'
- def submittedDataNode = buildDataNode("/parent-200/child-201", ['leaf-value': 'new'], [
- buildDataNode("/parent-200/child-201/grand-child", ['leaf-value': 'original'], [])
- ])
- when: 'update is performed including descendants'
- objectUnderTest.replaceDataNodeTree(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNode)
- then: 'leaves have been updated for selected data node'
- def updatedFragment = fragmentRepository.getOne(UPDATE_DATA_NODE_FRAGMENT_ID)
- def updatedLeaves = getLeavesMap(updatedFragment)
- assert updatedLeaves.size() == 1
- assert updatedLeaves.'leaf-value' == 'new'
- and: 'previously attached child entry is removed from database'
- fragmentRepository.findById(UPDATE_DATA_NODE_SUB_FRAGMENT_ID).isEmpty()
- and: 'new child entry with same content is created'
- def childFragment = updatedFragment.getChildFragments().iterator().next()
- def childLeaves = getLeavesMap(childFragment)
- assert childFragment.getId() != UPDATE_DATA_NODE_SUB_FRAGMENT_ID
- assert childLeaves.'leaf-value' == 'original'
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Replace data node tree error scenario: #scenario.'() {