B: Fix cyclic block hierarchy
This commit is contained in:
parent
854d32aea1
commit
2cb7c44f3a
|
@ -123,7 +123,7 @@ class UpdateBlockSerializer(StrictSerializer):
|
|||
raise serializers.ValidationError({
|
||||
'parent': msg.parentNotInOSS()
|
||||
})
|
||||
if parent == attrs['target']:
|
||||
if attrs['target'].pk in _collect_ancestors(parent):
|
||||
raise serializers.ValidationError({
|
||||
'parent': msg.blockCyclicHierarchy()
|
||||
})
|
||||
|
|
|
@ -266,3 +266,36 @@ class TestOssBlocks(EndpointTester):
|
|||
|
||||
data['layout'] = self.layout_data
|
||||
self.executeOK(data=data)
|
||||
|
||||
|
||||
@decl_endpoint('/api/oss/{item}/update-block', method='patch')
|
||||
def test_update_block_cyclic_parent(self):
|
||||
self.populateData()
|
||||
# block1 -> block2
|
||||
# Try to set block1's parent to block2 (should fail, direct cycle)
|
||||
data = {
|
||||
'target': self.block1.pk,
|
||||
'item_data': {
|
||||
'title': self.block1.title,
|
||||
'description': self.block1.description,
|
||||
'parent': self.block2.pk
|
||||
},
|
||||
}
|
||||
self.executeBadData(data=data, item=self.owned_id)
|
||||
|
||||
# Create a deeper hierarchy: block1 -> block2 -> block3
|
||||
self.block3 = self.owned.create_block(title='3', parent=self.block2)
|
||||
# Try to set block1's parent to block3 (should fail, indirect cycle)
|
||||
data['item_data']['parent'] = self.block3.pk
|
||||
self.executeBadData(data=data, item=self.owned_id)
|
||||
|
||||
# Setting block2's parent to block1 (valid, as block1 is not a descendant)
|
||||
data = {
|
||||
'target': self.block2.pk,
|
||||
'item_data': {
|
||||
'title': self.block2.title,
|
||||
'description': self.block2.description,
|
||||
'parent': self.block1.pk
|
||||
},
|
||||
}
|
||||
self.executeOK(data=data, item=self.owned_id)
|
||||
|
|
|
@ -66,14 +66,18 @@ export function DlgEditBlock() {
|
|||
<Controller
|
||||
name='item_data.parent'
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
render={({ field }) => {
|
||||
const descendantNodeIDs = manager.oss.hierarchy.expandAllOutputs([target.nodeID]);
|
||||
descendantNodeIDs.push(target.nodeID);
|
||||
return (
|
||||
<SelectParent
|
||||
items={manager.oss.blocks.filter(block => block.id !== target.id)}
|
||||
items={manager.oss.blocks.filter(block => !descendantNodeIDs.includes(block.nodeID))}
|
||||
value={field.value ? manager.oss.blockByID.get(field.value) ?? null : null}
|
||||
placeholder='Родительский блок'
|
||||
onChange={value => field.onChange(value ? value.id : null)}
|
||||
/>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextArea
|
||||
|
|
Loading…
Reference in New Issue
Block a user