F: Implement create-block API
This commit is contained in:
parent
1f15a6a53c
commit
dbceac0a6d
|
@ -19,6 +19,7 @@ from apps.rsform.models import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from .Argument import Argument
|
from .Argument import Argument
|
||||||
|
from .Block import Block
|
||||||
from .Inheritance import Inheritance
|
from .Inheritance import Inheritance
|
||||||
from .Layout import Layout
|
from .Layout import Layout
|
||||||
from .Operation import Operation
|
from .Operation import Operation
|
||||||
|
@ -60,6 +61,10 @@ class OperationSchema:
|
||||||
''' Get QuerySet containing all operations of current OSS. '''
|
''' Get QuerySet containing all operations of current OSS. '''
|
||||||
return Operation.objects.filter(oss=self.model)
|
return Operation.objects.filter(oss=self.model)
|
||||||
|
|
||||||
|
def blocks(self) -> QuerySet[Block]:
|
||||||
|
''' Get QuerySet containing all blocks of current OSS. '''
|
||||||
|
return Block.objects.filter(oss=self.model)
|
||||||
|
|
||||||
def arguments(self) -> QuerySet[Argument]:
|
def arguments(self) -> QuerySet[Argument]:
|
||||||
''' Operation arguments. '''
|
''' Operation arguments. '''
|
||||||
return Argument.objects.filter(operation__oss=self.model)
|
return Argument.objects.filter(operation__oss=self.model)
|
||||||
|
@ -99,6 +104,12 @@ class OperationSchema:
|
||||||
self.save(update_fields=['time_update'])
|
self.save(update_fields=['time_update'])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def create_block(self, **kwargs) -> Block:
|
||||||
|
''' Insert new block. '''
|
||||||
|
result = Block.objects.create(oss=self.model, **kwargs)
|
||||||
|
self.save(update_fields=['time_update'])
|
||||||
|
return result
|
||||||
|
|
||||||
def delete_operation(self, target: int, keep_constituents: bool = False):
|
def delete_operation(self, target: int, keep_constituents: bool = False):
|
||||||
''' Delete operation. '''
|
''' Delete operation. '''
|
||||||
self.cache.ensure_loaded()
|
self.cache.ensure_loaded()
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
from .basics import LayoutSerializer, SubstitutionExSerializer
|
from .basics import LayoutSerializer, SubstitutionExSerializer
|
||||||
from .data_access import (
|
from .data_access import (
|
||||||
ArgumentSerializer,
|
ArgumentSerializer,
|
||||||
|
BlockCreateSerializer,
|
||||||
|
BlockSerializer,
|
||||||
OperationCreateSerializer,
|
OperationCreateSerializer,
|
||||||
OperationDeleteSerializer,
|
OperationDeleteSerializer,
|
||||||
OperationSchemaSerializer,
|
OperationSchemaSerializer,
|
||||||
|
@ -12,4 +14,9 @@ from .data_access import (
|
||||||
RelocateConstituentsSerializer,
|
RelocateConstituentsSerializer,
|
||||||
SetOperationInputSerializer
|
SetOperationInputSerializer
|
||||||
)
|
)
|
||||||
from .responses import ConstituentaReferenceResponse, NewOperationResponse, NewSchemaResponse
|
from .responses import (
|
||||||
|
ConstituentaReferenceResponse,
|
||||||
|
NewBlockResponse,
|
||||||
|
NewOperationResponse,
|
||||||
|
NewSchemaResponse
|
||||||
|
)
|
||||||
|
|
|
@ -11,7 +11,7 @@ from apps.rsform.models import Constituenta
|
||||||
from apps.rsform.serializers import SubstitutionSerializerBase
|
from apps.rsform.serializers import SubstitutionSerializerBase
|
||||||
from shared import messages as msg
|
from shared import messages as msg
|
||||||
|
|
||||||
from ..models import Argument, Inheritance, Operation, OperationSchema, OperationType
|
from ..models import Argument, Block, Inheritance, Operation, OperationSchema, OperationType
|
||||||
from .basics import LayoutSerializer, SubstitutionExSerializer
|
from .basics import LayoutSerializer, SubstitutionExSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,15 @@ class OperationSerializer(serializers.ModelSerializer):
|
||||||
read_only_fields = ('id', 'oss')
|
read_only_fields = ('id', 'oss')
|
||||||
|
|
||||||
|
|
||||||
|
class BlockSerializer(serializers.ModelSerializer):
|
||||||
|
''' Serializer: Block data. '''
|
||||||
|
class Meta:
|
||||||
|
''' serializer metadata. '''
|
||||||
|
model = Block
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = ('id', 'oss')
|
||||||
|
|
||||||
|
|
||||||
class ArgumentSerializer(serializers.ModelSerializer):
|
class ArgumentSerializer(serializers.ModelSerializer):
|
||||||
''' Serializer: Operation data. '''
|
''' Serializer: Operation data. '''
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -32,6 +41,49 @@ class ArgumentSerializer(serializers.ModelSerializer):
|
||||||
fields = ('operation', 'argument')
|
fields = ('operation', 'argument')
|
||||||
|
|
||||||
|
|
||||||
|
class BlockCreateSerializer(serializers.Serializer):
|
||||||
|
''' Serializer: Block creation. '''
|
||||||
|
class BlockCreateData(serializers.ModelSerializer):
|
||||||
|
''' Serializer: Block creation data. '''
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
''' serializer metadata. '''
|
||||||
|
model = Block
|
||||||
|
fields = 'title', 'description', 'parent'
|
||||||
|
|
||||||
|
layout = LayoutSerializer()
|
||||||
|
|
||||||
|
item_data = BlockCreateData()
|
||||||
|
width = serializers.FloatField()
|
||||||
|
height = serializers.FloatField()
|
||||||
|
position_x = serializers.FloatField()
|
||||||
|
position_y = serializers.FloatField()
|
||||||
|
children_operations = PKField(many=True, queryset=Operation.objects.all().only('oss_id'))
|
||||||
|
children_blocks = PKField(many=True, queryset=Block.objects.all().only('oss_id'))
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
oss = cast(LibraryItem, self.context['oss'])
|
||||||
|
if 'parent' in attrs['item_data'] and \
|
||||||
|
attrs['item_data']['parent'] is not None and \
|
||||||
|
attrs['item_data']['parent'].oss_id != oss.pk:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'parent': msg.parentNotInOSS()
|
||||||
|
})
|
||||||
|
|
||||||
|
for operation in attrs['children_operations']:
|
||||||
|
if operation.oss_id != oss.pk:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'children_operations': msg.childNotInOSS()
|
||||||
|
})
|
||||||
|
|
||||||
|
for block in attrs['children_blocks']:
|
||||||
|
if block.oss_id != oss.pk:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'children_blocks': msg.childNotInOSS()
|
||||||
|
})
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
class OperationCreateSerializer(serializers.Serializer):
|
class OperationCreateSerializer(serializers.Serializer):
|
||||||
''' Serializer: Operation creation. '''
|
''' Serializer: Operation creation. '''
|
||||||
class OperationCreateData(serializers.ModelSerializer):
|
class OperationCreateData(serializers.ModelSerializer):
|
||||||
|
@ -47,13 +99,31 @@ class OperationCreateSerializer(serializers.Serializer):
|
||||||
'description', 'result', 'parent'
|
'description', 'result', 'parent'
|
||||||
|
|
||||||
layout = LayoutSerializer()
|
layout = LayoutSerializer()
|
||||||
position_x = serializers.FloatField()
|
|
||||||
position_y = serializers.FloatField()
|
|
||||||
|
|
||||||
item_data = OperationCreateData()
|
item_data = OperationCreateData()
|
||||||
|
position_x = serializers.FloatField()
|
||||||
|
position_y = serializers.FloatField()
|
||||||
create_schema = serializers.BooleanField(default=False, required=False)
|
create_schema = serializers.BooleanField(default=False, required=False)
|
||||||
arguments = PKField(many=True, queryset=Operation.objects.all().only('pk'), required=False)
|
arguments = PKField(many=True, queryset=Operation.objects.all().only('pk'), required=False)
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
oss = cast(LibraryItem, self.context['oss'])
|
||||||
|
if 'parent' in attrs['item_data'] and \
|
||||||
|
attrs['item_data']['parent'] is not None and \
|
||||||
|
attrs['item_data']['parent'].oss_id != oss.pk:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'parent': msg.parentNotInOSS()
|
||||||
|
})
|
||||||
|
|
||||||
|
if 'arguments' not in attrs:
|
||||||
|
return attrs
|
||||||
|
for operation in attrs['arguments']:
|
||||||
|
if operation.oss_id != oss.pk:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'arguments': msg.operationNotInOSS(oss.title)
|
||||||
|
})
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
class OperationUpdateSerializer(serializers.Serializer):
|
class OperationUpdateSerializer(serializers.Serializer):
|
||||||
''' Serializer: Operation update. '''
|
''' Serializer: Operation update. '''
|
||||||
|
@ -74,10 +144,19 @@ class OperationUpdateSerializer(serializers.Serializer):
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
|
oss = cast(LibraryItem, self.context['oss'])
|
||||||
|
if 'parent' in attrs['item_data'] and attrs['item_data']['parent'].oss_id != oss.pk:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'parent': msg.parentNotInOSS()
|
||||||
|
})
|
||||||
|
|
||||||
if 'arguments' not in attrs:
|
if 'arguments' not in attrs:
|
||||||
|
if 'substitutions' in attrs:
|
||||||
|
raise serializers.ValidationError({
|
||||||
|
'arguments': msg.missingArguments()
|
||||||
|
})
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
oss = cast(LibraryItem, self.context['oss'])
|
|
||||||
for operation in attrs['arguments']:
|
for operation in attrs['arguments']:
|
||||||
if operation.oss_id != oss.pk:
|
if operation.oss_id != oss.pk:
|
||||||
raise serializers.ValidationError({
|
raise serializers.ValidationError({
|
||||||
|
@ -175,6 +254,9 @@ class OperationSchemaSerializer(serializers.ModelSerializer):
|
||||||
operations = serializers.ListField(
|
operations = serializers.ListField(
|
||||||
child=OperationSerializer()
|
child=OperationSerializer()
|
||||||
)
|
)
|
||||||
|
blocks = serializers.ListField(
|
||||||
|
child=BlockSerializer()
|
||||||
|
)
|
||||||
arguments = serializers.ListField(
|
arguments = serializers.ListField(
|
||||||
child=ArgumentSerializer()
|
child=ArgumentSerializer()
|
||||||
)
|
)
|
||||||
|
@ -194,12 +276,15 @@ class OperationSchemaSerializer(serializers.ModelSerializer):
|
||||||
oss = OperationSchema(instance)
|
oss = OperationSchema(instance)
|
||||||
result['layout'] = oss.layout().data
|
result['layout'] = oss.layout().data
|
||||||
result['operations'] = []
|
result['operations'] = []
|
||||||
|
result['blocks'] = []
|
||||||
|
result['arguments'] = []
|
||||||
|
result['substitutions'] = []
|
||||||
for operation in oss.operations().order_by('pk'):
|
for operation in oss.operations().order_by('pk'):
|
||||||
result['operations'].append(OperationSerializer(operation).data)
|
result['operations'].append(OperationSerializer(operation).data)
|
||||||
result['arguments'] = []
|
for block in oss.blocks().order_by('pk'):
|
||||||
|
result['blocks'].append(BlockSerializer(block).data)
|
||||||
for argument in oss.arguments().order_by('order'):
|
for argument in oss.arguments().order_by('order'):
|
||||||
result['arguments'].append(ArgumentSerializer(argument).data)
|
result['arguments'].append(ArgumentSerializer(argument).data)
|
||||||
result['substitutions'] = []
|
|
||||||
for substitution in oss.substitutions().values(
|
for substitution in oss.substitutions().values(
|
||||||
'operation',
|
'operation',
|
||||||
'original',
|
'original',
|
||||||
|
|
|
@ -3,7 +3,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from apps.library.serializers import LibraryItemSerializer
|
from apps.library.serializers import LibraryItemSerializer
|
||||||
|
|
||||||
from .data_access import OperationSchemaSerializer, OperationSerializer
|
from .data_access import BlockSerializer, OperationSchemaSerializer, OperationSerializer
|
||||||
|
|
||||||
|
|
||||||
class NewOperationResponse(serializers.Serializer):
|
class NewOperationResponse(serializers.Serializer):
|
||||||
|
@ -12,6 +12,12 @@ class NewOperationResponse(serializers.Serializer):
|
||||||
oss = OperationSchemaSerializer()
|
oss = OperationSchemaSerializer()
|
||||||
|
|
||||||
|
|
||||||
|
class NewBlockResponse(serializers.Serializer):
|
||||||
|
''' Serializer: Create block response. '''
|
||||||
|
new_block = BlockSerializer()
|
||||||
|
oss = OperationSchemaSerializer()
|
||||||
|
|
||||||
|
|
||||||
class NewSchemaResponse(serializers.Serializer):
|
class NewSchemaResponse(serializers.Serializer):
|
||||||
''' Serializer: Create RSForm for input operation response. '''
|
''' Serializer: Create RSForm for input operation response. '''
|
||||||
new_schema = LibraryItemSerializer()
|
new_schema = LibraryItemSerializer()
|
||||||
|
|
|
@ -8,6 +8,7 @@ from apps.oss.models import Argument, Operation, OperationSchema, OperationType
|
||||||
class TestArgument(TestCase):
|
class TestArgument(TestCase):
|
||||||
''' Testing Argument model. '''
|
''' Testing Argument model. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.oss = OperationSchema.create(alias='T1')
|
self.oss = OperationSchema.create(alias='T1')
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ from apps.rsform.models import Constituenta, RSForm
|
||||||
class TestInheritance(TestCase):
|
class TestInheritance(TestCase):
|
||||||
''' Testing Inheritance model. '''
|
''' Testing Inheritance model. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.oss = OperationSchema.create(alias='T1')
|
self.oss = OperationSchema.create(alias='T1')
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ from apps.rsform.models import RSForm
|
||||||
class TestOperation(TestCase):
|
class TestOperation(TestCase):
|
||||||
''' Testing Operation model. '''
|
''' Testing Operation model. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.oss = OperationSchema.create(alias='T1')
|
self.oss = OperationSchema.create(alias='T1')
|
||||||
self.operation = Operation.objects.create(
|
self.operation = Operation.objects.create(
|
||||||
|
|
|
@ -10,6 +10,7 @@ from apps.rsform.models import RSForm
|
||||||
class TestSynthesisSubstitution(TestCase):
|
class TestSynthesisSubstitution(TestCase):
|
||||||
''' Testing Synthesis Substitution model. '''
|
''' Testing Synthesis Substitution model. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.oss = OperationSchema.create(alias='T1')
|
self.oss = OperationSchema.create(alias='T1')
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ from shared.EndpointTester import EndpointTester, decl_endpoint
|
||||||
class TestChangeAttributes(EndpointTester):
|
class TestChangeAttributes(EndpointTester):
|
||||||
''' Testing LibraryItem view when OSS is associated with RSForms. '''
|
''' Testing LibraryItem view when OSS is associated with RSForms. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user3 = User.objects.create(
|
self.user3 = User.objects.create(
|
||||||
|
@ -70,6 +71,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
layout.data = self.layout_data
|
layout.data = self.layout_data
|
||||||
layout.save()
|
layout.save()
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}/set-owner', method='patch')
|
@decl_endpoint('/api/library/{item}/set-owner', method='patch')
|
||||||
def test_set_owner(self):
|
def test_set_owner(self):
|
||||||
data = {'user': self.user3.pk}
|
data = {'user': self.user3.pk}
|
||||||
|
@ -85,6 +87,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.assertEqual(self.ks2.model.owner, self.user2)
|
self.assertEqual(self.ks2.model.owner, self.user2)
|
||||||
self.assertEqual(self.ks3.model.owner, self.user3)
|
self.assertEqual(self.ks3.model.owner, self.user3)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}/set-location', method='patch')
|
@decl_endpoint('/api/library/{item}/set-location', method='patch')
|
||||||
def test_set_location(self):
|
def test_set_location(self):
|
||||||
data = {'location': '/U/temp'}
|
data = {'location': '/U/temp'}
|
||||||
|
@ -100,6 +103,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.assertNotEqual(self.ks2.model.location, data['location'])
|
self.assertNotEqual(self.ks2.model.location, data['location'])
|
||||||
self.assertEqual(self.ks3.model.location, data['location'])
|
self.assertEqual(self.ks3.model.location, data['location'])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}/set-access-policy', method='patch')
|
@decl_endpoint('/api/library/{item}/set-access-policy', method='patch')
|
||||||
def test_set_access_policy(self):
|
def test_set_access_policy(self):
|
||||||
data = {'access_policy': AccessPolicy.PROTECTED}
|
data = {'access_policy': AccessPolicy.PROTECTED}
|
||||||
|
@ -115,6 +119,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.assertNotEqual(self.ks2.model.access_policy, data['access_policy'])
|
self.assertNotEqual(self.ks2.model.access_policy, data['access_policy'])
|
||||||
self.assertEqual(self.ks3.model.access_policy, data['access_policy'])
|
self.assertEqual(self.ks3.model.access_policy, data['access_policy'])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}/set-editors', method='patch')
|
@decl_endpoint('/api/library/{item}/set-editors', method='patch')
|
||||||
def test_set_editors(self):
|
def test_set_editors(self):
|
||||||
Editor.set(self.owned.model.pk, [self.user2.pk])
|
Editor.set(self.owned.model.pk, [self.user2.pk])
|
||||||
|
@ -133,6 +138,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.assertEqual(list(self.ks2.model.getQ_editors()), [])
|
self.assertEqual(list(self.ks2.model.getQ_editors()), [])
|
||||||
self.assertEqual(set(self.ks3.model.getQ_editors()), set([self.user, self.user3]))
|
self.assertEqual(set(self.ks3.model.getQ_editors()), set([self.user, self.user3]))
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}', method='patch')
|
@decl_endpoint('/api/library/{item}', method='patch')
|
||||||
def test_sync_from_result(self):
|
def test_sync_from_result(self):
|
||||||
data = {'alias': 'KS111', 'title': 'New Title', 'description': 'New description'}
|
data = {'alias': 'KS111', 'title': 'New Title', 'description': 'New description'}
|
||||||
|
@ -145,6 +151,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.assertEqual(self.operation1.title, data['title'])
|
self.assertEqual(self.operation1.title, data['title'])
|
||||||
self.assertEqual(self.operation1.description, data['description'])
|
self.assertEqual(self.operation1.description, data['description'])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
||||||
def test_sync_from_operation(self):
|
def test_sync_from_operation(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -163,6 +170,7 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.assertEqual(self.ks3.model.title, data['item_data']['title'])
|
self.assertEqual(self.ks3.model.title, data['item_data']['title'])
|
||||||
self.assertEqual(self.ks3.model.description, data['item_data']['description'])
|
self.assertEqual(self.ks3.model.description, data['item_data']['description'])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}', method='delete')
|
@decl_endpoint('/api/library/{item}', method='delete')
|
||||||
def test_destroy_oss_consequence(self):
|
def test_destroy_oss_consequence(self):
|
||||||
response = self.executeNoContent(item=self.owned_id)
|
response = self.executeNoContent(item=self.owned_id)
|
||||||
|
|
|
@ -69,6 +69,7 @@ class TestChangeConstituents(EndpointTester):
|
||||||
layout.data = self.layout_data
|
layout.data = self.layout_data
|
||||||
layout.save()
|
layout.save()
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{item}/details', method='get')
|
@decl_endpoint('/api/rsforms/{item}/details', method='get')
|
||||||
def test_retrieve_inheritance(self):
|
def test_retrieve_inheritance(self):
|
||||||
response = self.executeOK(item=self.ks3.model.pk)
|
response = self.executeOK(item=self.ks3.model.pk)
|
||||||
|
@ -96,6 +97,7 @@ class TestChangeConstituents(EndpointTester):
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/create-cst', method='post')
|
@decl_endpoint('/api/rsforms/{schema}/create-cst', method='post')
|
||||||
def test_create_constituenta(self):
|
def test_create_constituenta(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -112,6 +114,7 @@ class TestChangeConstituents(EndpointTester):
|
||||||
self.assertEqual(inherited_cst.order, 2)
|
self.assertEqual(inherited_cst.order, 2)
|
||||||
self.assertEqual(inherited_cst.definition_formal, 'X1 = X2')
|
self.assertEqual(inherited_cst.definition_formal, 'X1 = X2')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/rename-cst', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/rename-cst', method='patch')
|
||||||
def test_rename_constituenta(self):
|
def test_rename_constituenta(self):
|
||||||
data = {'target': self.ks1X1.pk, 'alias': 'D21', 'cst_type': CstType.TERM}
|
data = {'target': self.ks1X1.pk, 'alias': 'D21', 'cst_type': CstType.TERM}
|
||||||
|
@ -123,6 +126,7 @@ class TestChangeConstituents(EndpointTester):
|
||||||
self.assertEqual(inherited_cst.alias, 'D2')
|
self.assertEqual(inherited_cst.alias, 'D2')
|
||||||
self.assertEqual(inherited_cst.cst_type, data['cst_type'])
|
self.assertEqual(inherited_cst.cst_type, data['cst_type'])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/update-cst', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/update-cst', method='patch')
|
||||||
def test_update_constituenta(self):
|
def test_update_constituenta(self):
|
||||||
d2 = self.ks3.insert_new('D2', cst_type=CstType.TERM, definition_raw='@{X1|sing,nomn}')
|
d2 = self.ks3.insert_new('D2', cst_type=CstType.TERM, definition_raw='@{X1|sing,nomn}')
|
||||||
|
@ -149,6 +153,7 @@ class TestChangeConstituents(EndpointTester):
|
||||||
self.assertEqual(inherited_cst.definition_formal, r'X1\X1')
|
self.assertEqual(inherited_cst.definition_formal, r'X1\X1')
|
||||||
self.assertEqual(inherited_cst.definition_raw, r'@{X2|sing,datv}')
|
self.assertEqual(inherited_cst.definition_raw, r'@{X2|sing,datv}')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
|
||||||
def test_delete_constituenta(self):
|
def test_delete_constituenta(self):
|
||||||
data = {'items': [self.ks2X1.pk]}
|
data = {'items': [self.ks2X1.pk]}
|
||||||
|
@ -160,6 +165,7 @@ class TestChangeConstituents(EndpointTester):
|
||||||
self.assertEqual(self.ks2D1.definition_formal, r'DEL\DEL')
|
self.assertEqual(self.ks2D1.definition_formal, r'DEL\DEL')
|
||||||
self.assertEqual(inherited_cst.definition_formal, r'DEL\DEL')
|
self.assertEqual(inherited_cst.definition_formal, r'DEL\DEL')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
|
||||||
def test_substitute(self):
|
def test_substitute(self):
|
||||||
d2 = self.ks3.insert_new('D2', cst_type=CstType.TERM, definition_formal=r'X1\X2\X3')
|
d2 = self.ks3.insert_new('D2', cst_type=CstType.TERM, definition_formal=r'X1\X2\X3')
|
||||||
|
|
|
@ -8,6 +8,7 @@ from shared.EndpointTester import EndpointTester, decl_endpoint
|
||||||
class TestChangeOperations(EndpointTester):
|
class TestChangeOperations(EndpointTester):
|
||||||
''' Testing Operations change propagation in OSS. '''
|
''' Testing Operations change propagation in OSS. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.owned = OperationSchema.create(
|
self.owned = OperationSchema.create(
|
||||||
|
@ -120,6 +121,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
layout.data = self.layout_data
|
layout.data = self.layout_data
|
||||||
layout.save()
|
layout.save()
|
||||||
|
|
||||||
|
|
||||||
def test_oss_setup(self):
|
def test_oss_setup(self):
|
||||||
self.assertEqual(self.ks1.constituents().count(), 3)
|
self.assertEqual(self.ks1.constituents().count(), 3)
|
||||||
self.assertEqual(self.ks2.constituents().count(), 3)
|
self.assertEqual(self.ks2.constituents().count(), 3)
|
||||||
|
@ -128,6 +130,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks5.constituents().count(), 8)
|
self.assertEqual(self.ks5.constituents().count(), 8)
|
||||||
self.assertEqual(self.ks4D1.definition_formal, 'S1 X1')
|
self.assertEqual(self.ks4D1.definition_formal, 'S1 X1')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
||||||
def test_delete_input_operation(self):
|
def test_delete_input_operation(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -148,6 +151,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
||||||
def test_set_input_null(self):
|
def test_set_input_null(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -171,6 +175,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
||||||
def test_set_input_change_schema(self):
|
def test_set_input_change_schema(self):
|
||||||
ks6 = RSForm.create(
|
ks6 = RSForm.create(
|
||||||
|
@ -206,6 +211,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}', method='delete')
|
@decl_endpoint('/api/library/{item}', method='delete')
|
||||||
def test_delete_schema(self):
|
def test_delete_schema(self):
|
||||||
self.executeNoContent(item=self.ks1.model.pk)
|
self.executeNoContent(item=self.ks1.model.pk)
|
||||||
|
@ -222,6 +228,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'DEL X2 X3 S1 DEL')
|
self.assertEqual(self.ks4D2.definition_formal, r'DEL X2 X3 S1 DEL')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
||||||
def test_delete_operation_and_constituents(self):
|
def test_delete_operation_and_constituents(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -243,6 +250,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'DEL X2 X3 S1 DEL')
|
self.assertEqual(self.ks4D2.definition_formal, r'DEL X2 X3 S1 DEL')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
||||||
def test_delete_operation_keep_constituents(self):
|
def test_delete_operation_keep_constituents(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -264,6 +272,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
||||||
def test_delete_operation_keep_schema(self):
|
def test_delete_operation_keep_schema(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -288,6 +297,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 D2 D3')
|
||||||
self.assertFalse(Constituenta.objects.filter(as_child__parent_id=self.ks1D1.pk).exists())
|
self.assertFalse(Constituenta.objects.filter(as_child__parent_id=self.ks1D1.pk).exists())
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
||||||
def test_change_substitutions(self):
|
def test_change_substitutions(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -298,6 +308,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
'description': 'Comment mod'
|
'description': 'Comment mod'
|
||||||
},
|
},
|
||||||
'layout': self.layout_data,
|
'layout': self.layout_data,
|
||||||
|
'arguments': [self.operation1.pk, self.operation2.pk],
|
||||||
'substitutions': [
|
'substitutions': [
|
||||||
{
|
{
|
||||||
'original': self.ks1X1.pk,
|
'original': self.ks1X1.pk,
|
||||||
|
@ -322,6 +333,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 D1 X3 S1 D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 D1 X3 S1 D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'D1 X2 X3 S1 D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'D1 X2 X3 S1 D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
||||||
def test_change_arguments(self):
|
def test_change_arguments(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -360,6 +372,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/execute-operation', method='post')
|
@decl_endpoint('/api/oss/{item}/execute-operation', method='post')
|
||||||
def test_execute_middle_operation(self):
|
def test_execute_middle_operation(self):
|
||||||
self.client.delete(f'/api/library/{self.ks4.model.pk}')
|
self.client.delete(f'/api/library/{self.ks4.model.pk}')
|
||||||
|
@ -378,6 +391,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertNotEqual(self.operation4.result, None)
|
self.assertNotEqual(self.operation4.result, None)
|
||||||
self.assertEqual(self.ks5.constituents().count(), 8)
|
self.assertEqual(self.ks5.constituents().count(), 8)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/relocate-constituents', method='post')
|
@decl_endpoint('/api/oss/relocate-constituents', method='post')
|
||||||
def test_relocate_constituents_up(self):
|
def test_relocate_constituents_up(self):
|
||||||
ks1_old_count = self.ks1.constituents().count()
|
ks1_old_count = self.ks1.constituents().count()
|
||||||
|
@ -407,6 +421,7 @@ class TestChangeOperations(EndpointTester):
|
||||||
self.assertEqual(self.ks1.constituents().count(), ks1_old_count + 1)
|
self.assertEqual(self.ks1.constituents().count(), ks1_old_count + 1)
|
||||||
self.assertEqual(self.ks4.constituents().count(), ks4_old_count + 1)
|
self.assertEqual(self.ks4.constituents().count(), ks4_old_count + 1)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/relocate-constituents', method='post')
|
@decl_endpoint('/api/oss/relocate-constituents', method='post')
|
||||||
def test_relocate_constituents_down(self):
|
def test_relocate_constituents_down(self):
|
||||||
ks1_old_count = self.ks1.constituents().count()
|
ks1_old_count = self.ks1.constituents().count()
|
||||||
|
|
|
@ -8,6 +8,7 @@ from shared.EndpointTester import EndpointTester, decl_endpoint
|
||||||
class TestChangeSubstitutions(EndpointTester):
|
class TestChangeSubstitutions(EndpointTester):
|
||||||
''' Testing Substitutions change propagation in OSS. '''
|
''' Testing Substitutions change propagation in OSS. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.owned = OperationSchema.create(
|
self.owned = OperationSchema.create(
|
||||||
|
@ -129,6 +130,7 @@ class TestChangeSubstitutions(EndpointTester):
|
||||||
self.assertEqual(self.ks5.constituents().count(), 8)
|
self.assertEqual(self.ks5.constituents().count(), 8)
|
||||||
self.assertEqual(self.ks4D1.definition_formal, 'S1 X1')
|
self.assertEqual(self.ks4D1.definition_formal, 'S1 X1')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
|
||||||
def test_substitute_original(self):
|
def test_substitute_original(self):
|
||||||
data = {'substitutions': [{
|
data = {'substitutions': [{
|
||||||
|
@ -151,6 +153,7 @@ class TestChangeSubstitutions(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'S1 X2 X3 S1 D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'S1 X2 X3 S1 D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X3 D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X3 D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
|
||||||
def test_substitute_substitution(self):
|
def test_substitute_substitution(self):
|
||||||
data = {
|
data = {
|
||||||
|
@ -175,6 +178,7 @@ class TestChangeSubstitutions(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 X2 D1')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 X2 D1')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X1 D1 D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X1 D1 D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
|
||||||
def test_delete_original(self):
|
def test_delete_original(self):
|
||||||
data = {'items': [self.ks1X1.pk, self.ks1D1.pk]}
|
data = {'items': [self.ks1X1.pk, self.ks1D1.pk]}
|
||||||
|
@ -189,6 +193,7 @@ class TestChangeSubstitutions(EndpointTester):
|
||||||
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 DEL')
|
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 DEL')
|
||||||
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
|
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
|
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
|
||||||
def test_delete_substitution(self):
|
def test_delete_substitution(self):
|
||||||
data = {'items': [self.ks2S1.pk, self.ks2X2.pk]}
|
data = {'items': [self.ks2S1.pk, self.ks2X2.pk]}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
''' Tests for REST API. '''
|
''' Tests for REST API. '''
|
||||||
|
from .t_blocks import *
|
||||||
from .t_operations import *
|
from .t_operations import *
|
||||||
from .t_oss import *
|
from .t_oss import *
|
||||||
|
|
167
rsconcept/backend/apps/oss/tests/s_views/t_blocks.py
Normal file
167
rsconcept/backend/apps/oss/tests/s_views/t_blocks.py
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
''' Testing API: Operation Schema - blocks manipulation. '''
|
||||||
|
from apps.library.models import AccessPolicy, Editor, LibraryItem, LibraryItemType
|
||||||
|
from apps.oss.models import Operation, OperationSchema, OperationType
|
||||||
|
from apps.rsform.models import Constituenta, RSForm
|
||||||
|
from shared.EndpointTester import EndpointTester, decl_endpoint
|
||||||
|
|
||||||
|
|
||||||
|
class TestOssBlocks(EndpointTester):
|
||||||
|
''' Testing OSS view - Blocks. '''
|
||||||
|
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.owned = OperationSchema.create(title='Test', alias='T1', owner=self.user)
|
||||||
|
self.owned_id = self.owned.model.pk
|
||||||
|
self.unowned = OperationSchema.create(title='Test2', alias='T2')
|
||||||
|
self.unowned_id = self.unowned.model.pk
|
||||||
|
self.invalid_id = self.unowned_id + 1337
|
||||||
|
|
||||||
|
|
||||||
|
def populateData(self):
|
||||||
|
self.unowned.create_block()
|
||||||
|
self.unowned.create_block()
|
||||||
|
self.unowned.create_block()
|
||||||
|
self.unowned.create_block()
|
||||||
|
|
||||||
|
self.block1 = self.owned.create_block(
|
||||||
|
title='1',
|
||||||
|
)
|
||||||
|
self.operation1 = self.owned.create_operation(
|
||||||
|
alias='1',
|
||||||
|
operation_type=OperationType.INPUT,
|
||||||
|
parent=self.block1,
|
||||||
|
)
|
||||||
|
self.operation2 = self.owned.create_operation(
|
||||||
|
alias='2',
|
||||||
|
operation_type=OperationType.INPUT,
|
||||||
|
)
|
||||||
|
self.operation3 = self.unowned.create_operation(
|
||||||
|
alias='3',
|
||||||
|
operation_type=OperationType.INPUT
|
||||||
|
)
|
||||||
|
self.block2 = self.owned.create_block(
|
||||||
|
title='2',
|
||||||
|
parent=self.block1
|
||||||
|
)
|
||||||
|
self.block3 = self.unowned.create_block(
|
||||||
|
title='3',
|
||||||
|
parent=self.block1
|
||||||
|
)
|
||||||
|
self.layout_data = {
|
||||||
|
'operations': [
|
||||||
|
{'id': self.operation1.pk, 'x': 0, 'y': 0},
|
||||||
|
{'id': self.operation2.pk, 'x': 0, 'y': 0},
|
||||||
|
],
|
||||||
|
'blocks': [
|
||||||
|
{'id': self.block1.pk, 'x': 0, 'y': 0, 'width': 0.5, 'height': 0.5},
|
||||||
|
{'id': self.block2.pk, 'x': 0, 'y': 0, 'width': 0.5, 'height': 0.5},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
layout = self.owned.layout()
|
||||||
|
layout.data = self.layout_data
|
||||||
|
layout.save()
|
||||||
|
|
||||||
|
|
||||||
|
@decl_endpoint('/api/oss/{item}/create-block', method='post')
|
||||||
|
def test_create_block(self):
|
||||||
|
self.populateData()
|
||||||
|
self.executeBadData(item=self.owned_id)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'item_data': {
|
||||||
|
'title': 'Test title',
|
||||||
|
'description': 'Тест кириллицы',
|
||||||
|
},
|
||||||
|
'layout': self.layout_data,
|
||||||
|
'position_x': 1337,
|
||||||
|
'position_y': 1337,
|
||||||
|
'width': 0.42,
|
||||||
|
'height': 0.42,
|
||||||
|
'children_operations': [],
|
||||||
|
'children_blocks': []
|
||||||
|
}
|
||||||
|
self.executeNotFound(data=data, item=self.invalid_id)
|
||||||
|
|
||||||
|
response = self.executeCreated(data=data, item=self.owned_id)
|
||||||
|
self.assertEqual(len(response.data['oss']['blocks']), 3)
|
||||||
|
new_block = response.data['new_block']
|
||||||
|
layout = response.data['oss']['layout']
|
||||||
|
item = [item for item in layout['blocks'] if item['id'] == new_block['id']][0]
|
||||||
|
self.assertEqual(new_block['title'], data['item_data']['title'])
|
||||||
|
self.assertEqual(new_block['description'], data['item_data']['description'])
|
||||||
|
self.assertEqual(new_block['parent'], None)
|
||||||
|
self.assertEqual(item['x'], data['position_x'])
|
||||||
|
self.assertEqual(item['y'], data['position_y'])
|
||||||
|
self.assertEqual(item['width'], data['width'])
|
||||||
|
self.assertEqual(item['height'], data['height'])
|
||||||
|
self.operation1.refresh_from_db()
|
||||||
|
|
||||||
|
self.executeForbidden(data=data, item=self.unowned_id)
|
||||||
|
self.toggle_admin(True)
|
||||||
|
self.executeCreated(data=data, item=self.unowned_id)
|
||||||
|
|
||||||
|
|
||||||
|
@decl_endpoint('/api/oss/{item}/create-block', method='post')
|
||||||
|
def test_create_block_parent(self):
|
||||||
|
self.populateData()
|
||||||
|
data = {
|
||||||
|
'item_data': {
|
||||||
|
'title': 'Test title',
|
||||||
|
'description': 'Тест кириллицы',
|
||||||
|
'parent': self.invalid_id
|
||||||
|
},
|
||||||
|
'layout': self.layout_data,
|
||||||
|
'position_x': 1337,
|
||||||
|
'position_y': 1337,
|
||||||
|
'width': 0.42,
|
||||||
|
'height': 0.42,
|
||||||
|
'children_operations': [],
|
||||||
|
'children_blocks': []
|
||||||
|
}
|
||||||
|
self.executeBadData(data=data, item=self.owned_id)
|
||||||
|
|
||||||
|
data['item_data']['parent'] = self.block3.pk
|
||||||
|
self.executeBadData(data=data)
|
||||||
|
|
||||||
|
data['item_data']['parent'] = self.block1.pk
|
||||||
|
response = self.executeCreated(data=data)
|
||||||
|
new_block = response.data['new_block']
|
||||||
|
self.assertEqual(new_block['parent'], self.block1.pk)
|
||||||
|
|
||||||
|
|
||||||
|
@decl_endpoint('/api/oss/{item}/create-block', method='post')
|
||||||
|
def test_create_block_children(self):
|
||||||
|
self.populateData()
|
||||||
|
data = {
|
||||||
|
'item_data': {
|
||||||
|
'title': 'Test title',
|
||||||
|
'description': 'Тест кириллицы',
|
||||||
|
},
|
||||||
|
'layout': self.layout_data,
|
||||||
|
'position_x': 1337,
|
||||||
|
'position_y': 1337,
|
||||||
|
'width': 0.42,
|
||||||
|
'height': 0.42,
|
||||||
|
'children_operations': [self.invalid_id],
|
||||||
|
'children_blocks': []
|
||||||
|
}
|
||||||
|
self.executeBadData(data=data, item=self.owned_id)
|
||||||
|
|
||||||
|
data['children_operations'] = [self.operation3.pk]
|
||||||
|
self.executeBadData(data=data)
|
||||||
|
|
||||||
|
data['children_operations'] = [self.block1.pk]
|
||||||
|
self.executeBadData(data=data)
|
||||||
|
|
||||||
|
data['children_operations'] = [self.operation1.pk]
|
||||||
|
data['children_blocks'] = [self.operation1.pk]
|
||||||
|
self.executeBadData(data=data)
|
||||||
|
|
||||||
|
data['children_blocks'] = [self.block1.pk]
|
||||||
|
response = self.executeCreated(data=data)
|
||||||
|
new_block = response.data['new_block']
|
||||||
|
self.operation1.refresh_from_db()
|
||||||
|
self.block1.refresh_from_db()
|
||||||
|
self.assertEqual(self.operation1.parent.pk, new_block['id'])
|
||||||
|
self.assertEqual(self.block1.parent.pk, new_block['id'])
|
|
@ -1,4 +1,4 @@
|
||||||
''' Testing API: Operation Schema. '''
|
''' Testing API: Operation Schema - operations manipulation. '''
|
||||||
from apps.library.models import AccessPolicy, Editor, LibraryItem, LibraryItemType
|
from apps.library.models import AccessPolicy, Editor, LibraryItem, LibraryItemType
|
||||||
from apps.oss.models import Operation, OperationSchema, OperationType
|
from apps.oss.models import Operation, OperationSchema, OperationType
|
||||||
from apps.rsform.models import Constituenta, RSForm
|
from apps.rsform.models import Constituenta, RSForm
|
||||||
|
@ -6,7 +6,8 @@ from shared.EndpointTester import EndpointTester, decl_endpoint
|
||||||
|
|
||||||
|
|
||||||
class TestOssOperations(EndpointTester):
|
class TestOssOperations(EndpointTester):
|
||||||
''' Testing OSS view - operations. '''
|
''' Testing OSS view - Operations. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
@ -14,9 +15,8 @@ class TestOssOperations(EndpointTester):
|
||||||
self.owned_id = self.owned.model.pk
|
self.owned_id = self.owned.model.pk
|
||||||
self.unowned = OperationSchema.create(title='Test2', alias='T2')
|
self.unowned = OperationSchema.create(title='Test2', alias='T2')
|
||||||
self.unowned_id = self.unowned.model.pk
|
self.unowned_id = self.unowned.model.pk
|
||||||
self.private = OperationSchema.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE)
|
self.invalid_id = self.unowned_id + 1337
|
||||||
self.private_id = self.private.model.pk
|
|
||||||
self.invalid_id = self.private.model.pk + 1337
|
|
||||||
|
|
||||||
def populateData(self):
|
def populateData(self):
|
||||||
self.ks1 = RSForm.create(
|
self.ks1 = RSForm.create(
|
||||||
|
@ -72,6 +72,7 @@ class TestOssOperations(EndpointTester):
|
||||||
'substitution': self.ks2X1
|
'substitution': self.ks2X1
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
||||||
def test_create_operation(self):
|
def test_create_operation(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -116,6 +117,38 @@ class TestOssOperations(EndpointTester):
|
||||||
self.toggle_admin(True)
|
self.toggle_admin(True)
|
||||||
self.executeCreated(data=data, item=self.unowned_id)
|
self.executeCreated(data=data, item=self.unowned_id)
|
||||||
|
|
||||||
|
|
||||||
|
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
||||||
|
def test_create_operation_parent(self):
|
||||||
|
self.populateData()
|
||||||
|
data = {
|
||||||
|
'item_data': {
|
||||||
|
'parent': self.invalid_id,
|
||||||
|
'alias': 'Test3',
|
||||||
|
'title': 'Test title',
|
||||||
|
'description': '',
|
||||||
|
'operation_type': OperationType.INPUT
|
||||||
|
|
||||||
|
},
|
||||||
|
'layout': self.layout_data,
|
||||||
|
'position_x': 1,
|
||||||
|
'position_y': 1
|
||||||
|
|
||||||
|
}
|
||||||
|
self.executeBadData(data=data, item=self.owned_id)
|
||||||
|
|
||||||
|
block_unowned = self.unowned.create_block(title='TestBlock1')
|
||||||
|
data['item_data']['parent'] = block_unowned.id
|
||||||
|
self.executeBadData(data=data, item=self.owned_id)
|
||||||
|
|
||||||
|
block_owned = self.owned.create_block(title='TestBlock2')
|
||||||
|
data['item_data']['parent'] = block_owned.id
|
||||||
|
response = self.executeCreated(data=data, item=self.owned_id)
|
||||||
|
self.assertEqual(len(response.data['oss']['operations']), 4)
|
||||||
|
new_operation = response.data['new_operation']
|
||||||
|
self.assertEqual(new_operation['parent'], block_owned.id)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
||||||
def test_create_operation_arguments(self):
|
def test_create_operation_arguments(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -136,6 +169,7 @@ class TestOssOperations(EndpointTester):
|
||||||
self.assertTrue(arguments.filter(operation__id=new_operation['id'], argument=self.operation1))
|
self.assertTrue(arguments.filter(operation__id=new_operation['id'], argument=self.operation1))
|
||||||
self.assertTrue(arguments.filter(operation__id=new_operation['id'], argument=self.operation3))
|
self.assertTrue(arguments.filter(operation__id=new_operation['id'], argument=self.operation3))
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
||||||
def test_create_operation_result(self):
|
def test_create_operation_result(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -154,10 +188,10 @@ class TestOssOperations(EndpointTester):
|
||||||
'position_y': 1
|
'position_y': 1
|
||||||
}
|
}
|
||||||
response = self.executeCreated(data=data, item=self.owned_id)
|
response = self.executeCreated(data=data, item=self.owned_id)
|
||||||
self.owned.refresh_from_db()
|
|
||||||
new_operation = response.data['new_operation']
|
new_operation = response.data['new_operation']
|
||||||
self.assertEqual(new_operation['result'], self.ks1.model.pk)
|
self.assertEqual(new_operation['result'], self.ks1.model.pk)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
@decl_endpoint('/api/oss/{item}/create-operation', method='post')
|
||||||
def test_create_operation_schema(self):
|
def test_create_operation_schema(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -189,6 +223,7 @@ class TestOssOperations(EndpointTester):
|
||||||
self.assertEqual(schema.location, self.owned.model.location)
|
self.assertEqual(schema.location, self.owned.model.location)
|
||||||
self.assertIn(self.user2, schema.getQ_editors())
|
self.assertIn(self.user2, schema.getQ_editors())
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
|
||||||
def test_delete_operation(self):
|
def test_delete_operation(self):
|
||||||
self.executeNotFound(item=self.invalid_id)
|
self.executeNotFound(item=self.invalid_id)
|
||||||
|
@ -214,6 +249,7 @@ class TestOssOperations(EndpointTester):
|
||||||
self.assertEqual(len(response.data['operations']), 2)
|
self.assertEqual(len(response.data['operations']), 2)
|
||||||
self.assertEqual(len(deleted_items), 0)
|
self.assertEqual(len(deleted_items), 0)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/create-input', method='patch')
|
@decl_endpoint('/api/oss/{item}/create-input', method='patch')
|
||||||
def test_create_input(self):
|
def test_create_input(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -249,6 +285,7 @@ class TestOssOperations(EndpointTester):
|
||||||
data['target'] = self.operation3.pk
|
data['target'] = self.operation3.pk
|
||||||
self.executeBadData(data=data)
|
self.executeBadData(data=data)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
||||||
def test_set_input_null(self):
|
def test_set_input_null(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -283,6 +320,7 @@ class TestOssOperations(EndpointTester):
|
||||||
self.assertEqual(self.operation1.title, self.ks1.model.title)
|
self.assertEqual(self.operation1.title, self.ks1.model.title)
|
||||||
self.assertEqual(self.operation1.description, self.ks1.model.description)
|
self.assertEqual(self.operation1.description, self.ks1.model.description)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
|
||||||
def test_set_input_change_schema(self):
|
def test_set_input_change_schema(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -317,6 +355,7 @@ class TestOssOperations(EndpointTester):
|
||||||
self.operation1.refresh_from_db()
|
self.operation1.refresh_from_db()
|
||||||
self.assertEqual(self.operation1.result, self.ks2.model)
|
self.assertEqual(self.operation1.result, self.ks2.model)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
||||||
def test_update_operation(self):
|
def test_update_operation(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -388,6 +427,7 @@ class TestOssOperations(EndpointTester):
|
||||||
self.assertEqual(self.operation1.result.title, data['item_data']['title'])
|
self.assertEqual(self.operation1.result.title, data['item_data']['title'])
|
||||||
self.assertEqual(self.operation1.result.description, data['item_data']['description'])
|
self.assertEqual(self.operation1.result.description, data['item_data']['description'])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
|
||||||
def test_update_operation_invalid_substitution(self):
|
def test_update_operation_invalid_substitution(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -416,6 +456,7 @@ class TestOssOperations(EndpointTester):
|
||||||
}
|
}
|
||||||
self.executeBadData(data=data, item=self.owned_id)
|
self.executeBadData(data=data, item=self.owned_id)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/execute-operation', method='post')
|
@decl_endpoint('/api/oss/{item}/execute-operation', method='post')
|
||||||
def test_execute_operation(self):
|
def test_execute_operation(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
|
|
@ -16,7 +16,8 @@ class TestOssViewset(EndpointTester):
|
||||||
self.unowned_id = self.unowned.model.pk
|
self.unowned_id = self.unowned.model.pk
|
||||||
self.private = OperationSchema.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE)
|
self.private = OperationSchema.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE)
|
||||||
self.private_id = self.private.model.pk
|
self.private_id = self.private.model.pk
|
||||||
self.invalid_id = self.private.model.pk + 1337
|
self.invalid_id = self.private_id + 1337
|
||||||
|
|
||||||
|
|
||||||
def populateData(self):
|
def populateData(self):
|
||||||
self.ks1 = RSForm.create(
|
self.ks1 = RSForm.create(
|
||||||
|
@ -68,6 +69,7 @@ class TestOssViewset(EndpointTester):
|
||||||
'substitution': self.ks2X1
|
'substitution': self.ks2X1
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/details', method='get')
|
@decl_endpoint('/api/oss/{item}/details', method='get')
|
||||||
def test_details(self):
|
def test_details(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -117,6 +119,7 @@ class TestOssViewset(EndpointTester):
|
||||||
self.executeOK(item=self.unowned_id)
|
self.executeOK(item=self.unowned_id)
|
||||||
self.executeForbidden(item=self.private_id)
|
self.executeForbidden(item=self.private_id)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/{item}/update-layout', method='patch')
|
@decl_endpoint('/api/oss/{item}/update-layout', method='patch')
|
||||||
def test_update_layout(self):
|
def test_update_layout(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
@ -143,6 +146,7 @@ class TestOssViewset(EndpointTester):
|
||||||
self.executeForbidden(data=data, item=self.unowned_id)
|
self.executeForbidden(data=data, item=self.unowned_id)
|
||||||
self.executeForbidden(data=data, item=self.private_id)
|
self.executeForbidden(data=data, item=self.private_id)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/oss/get-predecessor', method='post')
|
@decl_endpoint('/api/oss/get-predecessor', method='post')
|
||||||
def test_get_predecessor(self):
|
def test_get_predecessor(self):
|
||||||
self.populateData()
|
self.populateData()
|
||||||
|
|
|
@ -38,6 +38,7 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev
|
||||||
if self.action in [
|
if self.action in [
|
||||||
'update_layout',
|
'update_layout',
|
||||||
'create_operation',
|
'create_operation',
|
||||||
|
'create_block',
|
||||||
'delete_operation',
|
'delete_operation',
|
||||||
'create_input',
|
'create_input',
|
||||||
'set_input',
|
'set_input',
|
||||||
|
@ -104,7 +105,10 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev
|
||||||
@action(detail=True, methods=['post'], url_path='create-operation')
|
@action(detail=True, methods=['post'], url_path='create-operation')
|
||||||
def create_operation(self, request: Request, pk) -> HttpResponse:
|
def create_operation(self, request: Request, pk) -> HttpResponse:
|
||||||
''' Create new operation. '''
|
''' Create new operation. '''
|
||||||
serializer = s.OperationCreateSerializer(data=request.data)
|
serializer = s.OperationCreateSerializer(
|
||||||
|
data=request.data,
|
||||||
|
context={'oss': self.get_object()}
|
||||||
|
)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
oss = m.OperationSchema(self.get_object())
|
oss = m.OperationSchema(self.get_object())
|
||||||
|
@ -148,6 +152,57 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@extend_schema(
|
||||||
|
summary='create block',
|
||||||
|
tags=['OSS'],
|
||||||
|
request=s.BlockCreateSerializer(),
|
||||||
|
responses={
|
||||||
|
c.HTTP_201_CREATED: s.NewBlockResponse,
|
||||||
|
c.HTTP_400_BAD_REQUEST: None,
|
||||||
|
c.HTTP_403_FORBIDDEN: None,
|
||||||
|
c.HTTP_404_NOT_FOUND: None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@action(detail=True, methods=['post'], url_path='create-block')
|
||||||
|
def create_block(self, request: Request, pk) -> HttpResponse:
|
||||||
|
''' Create new block. '''
|
||||||
|
serializer = s.BlockCreateSerializer(
|
||||||
|
data=request.data,
|
||||||
|
context={'oss': self.get_object()}
|
||||||
|
)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
oss = m.OperationSchema(self.get_object())
|
||||||
|
layout = serializer.validated_data['layout']
|
||||||
|
children_blocks: list[m.Block] = serializer.validated_data['children_blocks']
|
||||||
|
children_operations: list[m.Operation] = serializer.validated_data['children_operations']
|
||||||
|
with transaction.atomic():
|
||||||
|
new_block = oss.create_block(**serializer.validated_data['item_data'])
|
||||||
|
layout['blocks'].append({
|
||||||
|
'id': new_block.pk,
|
||||||
|
'x': serializer.validated_data['position_x'],
|
||||||
|
'y': serializer.validated_data['position_y'],
|
||||||
|
'width': serializer.validated_data['width'],
|
||||||
|
'height': serializer.validated_data['height'],
|
||||||
|
})
|
||||||
|
oss.update_layout(layout)
|
||||||
|
if len(children_blocks) > 0:
|
||||||
|
for block in children_blocks:
|
||||||
|
block.parent = new_block
|
||||||
|
m.Block.objects.bulk_update(children_blocks, ['parent'])
|
||||||
|
if len(children_operations) > 0:
|
||||||
|
for operation in children_operations:
|
||||||
|
operation.parent = new_block
|
||||||
|
m.Operation.objects.bulk_update(children_operations, ['parent'])
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
status=c.HTTP_201_CREATED,
|
||||||
|
data={
|
||||||
|
'new_block': s.BlockSerializer(new_block).data,
|
||||||
|
'oss': s.OperationSchemaSerializer(oss.model).data
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
summary='delete operation',
|
summary='delete operation',
|
||||||
tags=['OSS'],
|
tags=['OSS'],
|
||||||
|
|
|
@ -9,6 +9,7 @@ from apps.rsform.models import Constituenta, CstType, RSForm
|
||||||
class TestConstituenta(TestCase):
|
class TestConstituenta(TestCase):
|
||||||
''' Testing Constituenta model. '''
|
''' Testing Constituenta model. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.schema1 = RSForm.create(title='Test1')
|
self.schema1 = RSForm.create(title='Test1')
|
||||||
self.schema2 = RSForm.create(title='Test2')
|
self.schema2 = RSForm.create(title='Test2')
|
||||||
|
@ -47,6 +48,7 @@ class TestConstituenta(TestCase):
|
||||||
self.assertEqual(cst.definition_resolved, '')
|
self.assertEqual(cst.definition_resolved, '')
|
||||||
self.assertEqual(cst.definition_raw, '')
|
self.assertEqual(cst.definition_raw, '')
|
||||||
|
|
||||||
|
|
||||||
def test_extract_references(self):
|
def test_extract_references(self):
|
||||||
cst = Constituenta.objects.create(
|
cst = Constituenta.objects.create(
|
||||||
alias='X1',
|
alias='X1',
|
||||||
|
@ -57,6 +59,7 @@ class TestConstituenta(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(cst.extract_references(), set(['X1', 'X2', 'X3', 'X4', 'X5']))
|
self.assertEqual(cst.extract_references(), set(['X1', 'X2', 'X3', 'X4', 'X5']))
|
||||||
|
|
||||||
|
|
||||||
def text_apply_mapping(self):
|
def text_apply_mapping(self):
|
||||||
cst = Constituenta.objects.create(
|
cst = Constituenta.objects.create(
|
||||||
alias='X1',
|
alias='X1',
|
||||||
|
|
|
@ -9,6 +9,7 @@ from shared.DBTester import DBTester
|
||||||
class TestRSForm(DBTester):
|
class TestRSForm(DBTester):
|
||||||
''' Testing RSForm wrapper. '''
|
''' Testing RSForm wrapper. '''
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user1 = User.objects.create(username='User1')
|
self.user1 = User.objects.create(username='User1')
|
||||||
|
@ -103,6 +104,7 @@ class TestRSForm(DBTester):
|
||||||
self.assertEqual(x2.schema, self.schema.model)
|
self.assertEqual(x2.schema, self.schema.model)
|
||||||
self.assertEqual(x1.order, 0)
|
self.assertEqual(x1.order, 0)
|
||||||
|
|
||||||
|
|
||||||
def test_create_cst(self):
|
def test_create_cst(self):
|
||||||
data = {
|
data = {
|
||||||
'alias': 'X3',
|
'alias': 'X3',
|
||||||
|
@ -194,6 +196,7 @@ class TestRSForm(DBTester):
|
||||||
self.assertEqual(d1.definition_raw, '@{DEL|sing}')
|
self.assertEqual(d1.definition_raw, '@{DEL|sing}')
|
||||||
self.assertEqual(d1.term_raw, '@{X2|plur}')
|
self.assertEqual(d1.term_raw, '@{X2|plur}')
|
||||||
|
|
||||||
|
|
||||||
def test_apply_mapping(self):
|
def test_apply_mapping(self):
|
||||||
x1 = self.schema.insert_new('X1')
|
x1 = self.schema.insert_new('X1')
|
||||||
x2 = self.schema.insert_new('X11')
|
x2 = self.schema.insert_new('X11')
|
||||||
|
|
|
@ -138,6 +138,7 @@ class TestRSFormViewset(EndpointTester):
|
||||||
self.assertEqual(response.data['typification'], 'LOGIC')
|
self.assertEqual(response.data['typification'], 'LOGIC')
|
||||||
self.assertEqual(response.data['valueClass'], 'value')
|
self.assertEqual(response.data['valueClass'], 'value')
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{item}/check-constituenta', method='post')
|
@decl_endpoint('/api/rsforms/{item}/check-constituenta', method='post')
|
||||||
def test_check_constituenta_error(self):
|
def test_check_constituenta_error(self):
|
||||||
self.owned.insert_new('X1')
|
self.owned.insert_new('X1')
|
||||||
|
@ -145,6 +146,7 @@ class TestRSFormViewset(EndpointTester):
|
||||||
response = self.executeOK(data=data, item=self.owned_id)
|
response = self.executeOK(data=data, item=self.owned_id)
|
||||||
self.assertEqual(response.data['parseResult'], False)
|
self.assertEqual(response.data['parseResult'], False)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{item}/resolve', method='post')
|
@decl_endpoint('/api/rsforms/{item}/resolve', method='post')
|
||||||
def test_resolve(self):
|
def test_resolve(self):
|
||||||
x1 = self.owned.insert_new(
|
x1 = self.owned.insert_new(
|
||||||
|
|
|
@ -7,6 +7,7 @@ from apps.rsform.graph import Graph
|
||||||
class TestGraph(unittest.TestCase):
|
class TestGraph(unittest.TestCase):
|
||||||
''' Test class for graph. '''
|
''' Test class for graph. '''
|
||||||
|
|
||||||
|
|
||||||
def test_construction(self):
|
def test_construction(self):
|
||||||
graph = Graph()
|
graph = Graph()
|
||||||
self.assertFalse(graph.contains(1))
|
self.assertFalse(graph.contains(1))
|
||||||
|
@ -26,6 +27,7 @@ class TestGraph(unittest.TestCase):
|
||||||
self.assertTrue(graph.has_edge(1, 3))
|
self.assertTrue(graph.has_edge(1, 3))
|
||||||
self.assertTrue(graph.has_edge(2, 1))
|
self.assertTrue(graph.has_edge(2, 1))
|
||||||
|
|
||||||
|
|
||||||
def test_remove_node(self):
|
def test_remove_node(self):
|
||||||
graph = Graph({
|
graph = Graph({
|
||||||
1: [2],
|
1: [2],
|
||||||
|
@ -39,6 +41,7 @@ class TestGraph(unittest.TestCase):
|
||||||
self.assertEqual(graph.outputs[1], [])
|
self.assertEqual(graph.outputs[1], [])
|
||||||
self.assertEqual(len(graph.outputs), 3)
|
self.assertEqual(len(graph.outputs), 3)
|
||||||
|
|
||||||
|
|
||||||
def test_remove_edge(self):
|
def test_remove_edge(self):
|
||||||
graph = Graph({
|
graph = Graph({
|
||||||
1: [2],
|
1: [2],
|
||||||
|
@ -53,6 +56,7 @@ class TestGraph(unittest.TestCase):
|
||||||
self.assertEqual(graph.outputs[1], [])
|
self.assertEqual(graph.outputs[1], [])
|
||||||
graph.remove_edge(1, 2)
|
graph.remove_edge(1, 2)
|
||||||
|
|
||||||
|
|
||||||
def test_expand_outputs(self):
|
def test_expand_outputs(self):
|
||||||
graph = Graph({
|
graph = Graph({
|
||||||
1: [2],
|
1: [2],
|
||||||
|
@ -67,6 +71,7 @@ class TestGraph(unittest.TestCase):
|
||||||
self.assertEqual(graph.expand_outputs([7]), [])
|
self.assertEqual(graph.expand_outputs([7]), [])
|
||||||
self.assertEqual(graph.expand_outputs([2, 5]), [3, 6, 1])
|
self.assertEqual(graph.expand_outputs([2, 5]), [3, 6, 1])
|
||||||
|
|
||||||
|
|
||||||
def test_expand_inputs(self):
|
def test_expand_inputs(self):
|
||||||
graph = Graph({
|
graph = Graph({
|
||||||
1: [2],
|
1: [2],
|
||||||
|
@ -101,6 +106,7 @@ class TestGraph(unittest.TestCase):
|
||||||
7: [6]
|
7: [6]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def test_topological_order(self):
|
def test_topological_order(self):
|
||||||
self.assertEqual(Graph().topological_order(), [])
|
self.assertEqual(Graph().topological_order(), [])
|
||||||
graph = Graph({
|
graph = Graph({
|
||||||
|
@ -122,6 +128,7 @@ class TestGraph(unittest.TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(graph.topological_order(), [5, 3, 2, 4, 1])
|
self.assertEqual(graph.topological_order(), [5, 3, 2, 4, 1])
|
||||||
|
|
||||||
|
|
||||||
def test_sort_stable(self):
|
def test_sort_stable(self):
|
||||||
graph = Graph({
|
graph = Graph({
|
||||||
1: [2],
|
1: [2],
|
||||||
|
|
|
@ -8,6 +8,7 @@ from apps.rsform.utils import apply_pattern, fix_old_references
|
||||||
class TestUtils(unittest.TestCase):
|
class TestUtils(unittest.TestCase):
|
||||||
''' Test various utility functions. '''
|
''' Test various utility functions. '''
|
||||||
|
|
||||||
|
|
||||||
def test_apply_mapping_patter(self):
|
def test_apply_mapping_patter(self):
|
||||||
mapping = {'X101': 'X20'}
|
mapping = {'X101': 'X20'}
|
||||||
pattern = re.compile(r'(X[0-9]+)')
|
pattern = re.compile(r'(X[0-9]+)')
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
import os
|
import os
|
||||||
|
import runpy
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# Build the module path from the test file
|
||||||
filepath = sys.argv[1]
|
filepath = sys.argv[1]
|
||||||
project_root = os.path.join(os.path.dirname(__file__))
|
project_root = os.path.dirname(__file__)
|
||||||
relpath = os.path.relpath(filepath, project_root)
|
relpath = os.path.relpath(filepath, project_root)
|
||||||
module_path = relpath.replace('/', '.').replace('\\', '.').rstrip('.py')
|
module_path = relpath.replace('/', '.').replace('\\', '.').removesuffix('.py')
|
||||||
|
|
||||||
os.system(f"python manage.py test {module_path}")
|
# Run manage.py in-process so breakpoints work
|
||||||
|
sys.argv = ["manage.py", "test", module_path]
|
||||||
|
runpy.run_path("manage.py", run_name="__main__")
|
||||||
|
|
|
@ -14,6 +14,18 @@ def operationNotInOSS(title: str):
|
||||||
return f'Операция не принадлежит ОСС: {title}'
|
return f'Операция не принадлежит ОСС: {title}'
|
||||||
|
|
||||||
|
|
||||||
|
def parentNotInOSS():
|
||||||
|
return f'Родительский блок не принадлежит ОСС'
|
||||||
|
|
||||||
|
|
||||||
|
def childNotInOSS():
|
||||||
|
return f'Дочерний элемент блок не принадлежит ОСС'
|
||||||
|
|
||||||
|
|
||||||
|
def missingArguments():
|
||||||
|
return 'Операция не содержит аргументов, при этом содержит отождествления'
|
||||||
|
|
||||||
|
|
||||||
def exteorFileCorrupted():
|
def exteorFileCorrupted():
|
||||||
return 'Файл Экстеор не соответствует ожидаемому формату. Попробуйте сохранить файл в новой версии'
|
return 'Файл Экстеор не соответствует ожидаемому формату. Попробуйте сохранить файл в новой версии'
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,7 @@ import { schemaCstSubstitute } from '@/features/rsform/backend/types';
|
||||||
|
|
||||||
import { errorMsg } from '@/utils/labels';
|
import { errorMsg } from '@/utils/labels';
|
||||||
|
|
||||||
/**
|
/** Represents {@link IOperation} type. */
|
||||||
* Represents {@link IOperation} type.
|
|
||||||
*/
|
|
||||||
export const OperationType = {
|
export const OperationType = {
|
||||||
INPUT: 'input',
|
INPUT: 'input',
|
||||||
SYNTHESIS: 'synthesis'
|
SYNTHESIS: 'synthesis'
|
||||||
|
@ -20,10 +18,13 @@ export type ICstSubstituteInfo = z.infer<typeof schemaCstSubstituteInfo>;
|
||||||
/** Represents {@link IOperation} data from server. */
|
/** Represents {@link IOperation} data from server. */
|
||||||
export type IOperationDTO = z.infer<typeof schemaOperation>;
|
export type IOperationDTO = z.infer<typeof schemaOperation>;
|
||||||
|
|
||||||
|
/** Represents {@link IOperation} data from server. */
|
||||||
|
export type IBlockDTO = z.infer<typeof schemaBlock>;
|
||||||
|
|
||||||
/** Represents backend data for {@link IOperationSchema}. */
|
/** Represents backend data for {@link IOperationSchema}. */
|
||||||
export type IOperationSchemaDTO = z.infer<typeof schemaOperationSchema>;
|
export type IOperationSchemaDTO = z.infer<typeof schemaOperationSchema>;
|
||||||
|
|
||||||
/** Represents {@link schemaOperation} layout. */
|
/** Represents {@link IOperationSchema} layout. */
|
||||||
export type IOssLayout = z.infer<typeof schemaOssLayout>;
|
export type IOssLayout = z.infer<typeof schemaOssLayout>;
|
||||||
|
|
||||||
/** Represents {@link IOperation} data, used in creation process. */
|
/** Represents {@link IOperation} data, used in creation process. */
|
||||||
|
@ -64,15 +65,21 @@ export const schemaOperation = z.strictObject({
|
||||||
id: z.number(),
|
id: z.number(),
|
||||||
operation_type: schemaOperationType,
|
operation_type: schemaOperationType,
|
||||||
oss: z.number(),
|
oss: z.number(),
|
||||||
|
|
||||||
alias: z.string(),
|
alias: z.string(),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
|
|
||||||
parent: z.number().nullable(),
|
parent: z.number().nullable(),
|
||||||
result: z.number().nullable()
|
result: z.number().nullable()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const schemaBlock = z.strictObject({
|
||||||
|
id: z.number(),
|
||||||
|
oss: z.number(),
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
parent: z.number().nullable()
|
||||||
|
});
|
||||||
|
|
||||||
export const schemaCstSubstituteInfo = schemaCstSubstitute.extend({
|
export const schemaCstSubstituteInfo = schemaCstSubstitute.extend({
|
||||||
operation: z.number(),
|
operation: z.number(),
|
||||||
original_alias: z.string(),
|
original_alias: z.string(),
|
||||||
|
@ -81,20 +88,29 @@ export const schemaCstSubstituteInfo = schemaCstSubstitute.extend({
|
||||||
substitution_term: z.string()
|
substitution_term: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemaPosition = z.strictObject({
|
export const schemaOperationPosition = z.strictObject({
|
||||||
id: z.number(),
|
id: z.number(),
|
||||||
x: z.number(),
|
x: z.number(),
|
||||||
y: z.number()
|
y: z.number()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const schemaBlockPosition = z.strictObject({
|
||||||
|
id: z.number(),
|
||||||
|
x: z.number(),
|
||||||
|
y: z.number(),
|
||||||
|
width: z.number(),
|
||||||
|
height: z.number()
|
||||||
|
});
|
||||||
|
|
||||||
export const schemaOssLayout = z.strictObject({
|
export const schemaOssLayout = z.strictObject({
|
||||||
operations: z.array(schemaPosition),
|
operations: z.array(schemaOperationPosition),
|
||||||
blocks: z.array(schemaPosition)
|
blocks: z.array(schemaBlockPosition)
|
||||||
});
|
});
|
||||||
|
|
||||||
export const schemaOperationSchema = schemaLibraryItem.extend({
|
export const schemaOperationSchema = schemaLibraryItem.extend({
|
||||||
editors: z.number().array(),
|
editors: z.number().array(),
|
||||||
operations: z.array(schemaOperation),
|
operations: z.array(schemaOperation),
|
||||||
|
blocks: z.array(schemaBlock),
|
||||||
layout: schemaOssLayout,
|
layout: schemaOssLayout,
|
||||||
arguments: z
|
arguments: z
|
||||||
.object({
|
.object({
|
||||||
|
|
Loading…
Reference in New Issue
Block a user