From 12eef17b75d4ec51091d8b4b4196443ae16a95d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gregor=20Jer=C5=A1e?= Date: Mon, 18 Mar 2024 13:46:56 +0100 Subject: [PATCH] Remove descriptor and descriptor_schema from Entity --- docs/CHANGELOG.rst | 2 + .../example/processes/template_py_process.py | 4 +- resolwe/flow/filters.py | 7 ++- resolwe/flow/management/commands/register.py | 14 ------ .../0023_remove_entity_descriptor_and_more.py | 29 +++++++++++ resolwe/flow/migrations/triggers_entity.sql | 9 +--- resolwe/flow/models/collection.py | 48 +++++++++---------- resolwe/flow/models/data.py | 1 - resolwe/flow/models/process.py | 9 +--- resolwe/flow/serializers/collection.py | 2 +- resolwe/flow/serializers/process.py | 1 - resolwe/flow/tests/test_api.py | 31 +++--------- resolwe/flow/tests/test_filtering.py | 23 ++------- resolwe/flow/tests/test_manager.py | 1 - resolwe/flow/tests/test_models.py | 3 -- resolwe/flow/tests/test_validation.py | 30 +----------- resolwe/flow/views/entity.py | 5 +- resolwe/observers/tests.py | 1 - .../process/tests/processes/python_test.py | 17 ------- resolwe/process/tests/test_python_process.py | 35 -------------- resolwe/rest/tests.py | 1 - 21 files changed, 77 insertions(+), 196 deletions(-) create mode 100644 resolwe/flow/migrations/0023_remove_entity_descriptor_and_more.py diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 897924039..3717b76c3 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -13,6 +13,8 @@ Unreleased Changed ------- - **BACKWARD INCOMPATIBLE:** Make move between collections a background job +- **BACKWARD INCOMPATIBLE:** Remove ``descriptor_schema`` and ``descriptor`` + field from the ``Entity`` model - Require ``Jinja >= 3.1.3`` to address security vulnerability https://deps.dev/advisory/osv/GHSA-h5c8-rqwp-cp95 - Do not add ``descriptor_schema`` to automatically created entities diff --git a/docs/example/example/processes/template_py_process.py b/docs/example/example/processes/template_py_process.py index e3289267a..e11cff607 100644 --- a/docs/example/example/processes/template_py_process.py +++ b/docs/example/example/processes/template_py_process.py @@ -62,11 +62,9 @@ class YourProcessName(Process): # type sample. See # https://resolwe.readthedocs.io/en/latest/proc.html#entity for # more details. - # Fields descriptor_schema, input and always_create are optional. + # Field always_create is optional. entity = { "type": "sample", # name of your entity - # Use a descriptor schema slug if it differs from "type". - "descriptor_schema": "descriptor-schema-of-entity", "input": "name of input that has the entity", # If you want to create entity in all cases "always_create": True, diff --git a/resolwe/flow/filters.py b/resolwe/flow/filters.py index 22c16b459..0104f9bad 100644 --- a/resolwe/flow/filters.py +++ b/resolwe/flow/filters.py @@ -303,7 +303,6 @@ class Meta(BaseResolweFilter.Meta): **BaseResolweFilter.Meta.fields, **{ "description": TEXT_LOOKUPS[:], - "descriptor_schema": ["exact"], }, } @@ -331,6 +330,12 @@ class Meta(BaseCollectionFilter.Meta): """Filter configuration.""" model = Collection + fields = { + **BaseCollectionFilter.Meta.fields, + **{ + "descriptor_schema": ["exact"], + }, + } def count_entities(self, queryset: QuerySet, name: str, value: str): """Filter by the number of associated entities.""" diff --git a/resolwe/flow/management/commands/register.py b/resolwe/flow/management/commands/register.py index 7856c65ec..726529950 100644 --- a/resolwe/flow/management/commands/register.py +++ b/resolwe/flow/management/commands/register.py @@ -184,22 +184,10 @@ def register_processes(self, process_schemas, user, force=False, verbosity=1): continue p["entity_type"] = p["entity"]["type"] - p["entity_descriptor_schema"] = p["entity"].get( - "descriptor_schema", p["entity_type"] - ) p["entity_input"] = p["entity"].get("input", None) p["entity_always_create"] = p["entity"].get("always_create", False) p.pop("entity") - if not DescriptorSchema.objects.filter( - slug=p["entity_descriptor_schema"] - ).exists(): - self.stderr.write( - "Skip processor {}: Unknown descriptor schema '{}' used in 'entity' " - "field.".format(p["slug"], p["entity_descriptor_schema"]) - ) - continue - if "persistence" in p: persistence_mapping = { "RAW": Process.PERSISTENCE_RAW, @@ -452,8 +440,6 @@ def handle(self, *args, **options): self.register_descriptors( descriptor_schemas, user_admin, force, verbosity=verbosity ) - # NOTE: Descriptor schemas must be registered first, so - # processes can validate 'entity_descriptor_schema' field. self.register_processes(process_schemas, user_admin, force, verbosity=verbosity) if retire: diff --git a/resolwe/flow/migrations/0023_remove_entity_descriptor_and_more.py b/resolwe/flow/migrations/0023_remove_entity_descriptor_and_more.py new file mode 100644 index 000000000..e4f8ed2c8 --- /dev/null +++ b/resolwe/flow/migrations/0023_remove_entity_descriptor_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.11 on 2024-03-18 13:12 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("flow", "0022_fix_group_by"), + ] + + operations = [ + migrations.RemoveField( + model_name="entity", + name="descriptor", + ), + migrations.RemoveField( + model_name="entity", + name="descriptor_dirty", + ), + migrations.RemoveField( + model_name="entity", + name="descriptor_schema", + ), + migrations.RemoveField( + model_name="process", + name="entity_descriptor_schema", + ), + ] diff --git a/resolwe/flow/migrations/triggers_entity.sql b/resolwe/flow/migrations/triggers_entity.sql index 4588a7c32..538f51b81 100644 --- a/resolwe/flow/migrations/triggers_entity.sql +++ b/resolwe/flow/migrations/triggers_entity.sql @@ -26,8 +26,6 @@ CREATE OR REPLACE FUNCTION generate_resolwe_entity_search(entity flow_entity) FROM auth_user WHERE id = entity.contributor_id; - SELECT COALESCE(flatten_descriptor_values(entity.descriptor), '') INTO flat_descriptor; - SELECT -- Entity name. setweight(to_tsvector('simple', entity.name), 'A') || @@ -52,12 +50,7 @@ CREATE OR REPLACE FUNCTION generate_resolwe_entity_search(entity flow_entity) -- Owners last names. There is no guarantee that it is not NULL. setweight(to_tsvector('simple', COALESCE(owners.last_names, '')), 'B') || -- Entity tags. - setweight(to_tsvector('simple', array_to_string(entity.tags, ' ')), 'B') || - -- Entity descriptor. - setweight(to_tsvector('simple', flat_descriptor), 'C') || - setweight(to_tsvector('simple', get_characters(flat_descriptor)), 'D') || - setweight(to_tsvector('simple', get_numbers(flat_descriptor)), 'D') - + setweight(to_tsvector('simple', array_to_string(entity.tags, ' ')), 'B') INTO search; RETURN search; diff --git a/resolwe/flow/models/collection.py b/resolwe/flow/models/collection.py index 36d34a234..93a66d472 100644 --- a/resolwe/flow/models/collection.py +++ b/resolwe/flow/models/collection.py @@ -30,37 +30,12 @@ class Meta(BaseModel.Meta): settings = models.JSONField(default=dict) - #: collection descriptor schema - descriptor_schema = models.ForeignKey( - "flow.DescriptorSchema", blank=True, null=True, on_delete=models.PROTECT - ) - - #: collection descriptor - descriptor = models.JSONField(default=dict) - - #: indicate whether `descriptor` doesn't match `descriptor_schema` (is dirty) - descriptor_dirty = models.BooleanField(default=False) - #: tags for categorizing objects tags = ArrayField(models.CharField(max_length=255), default=list) #: field used for full-text search search = SearchVectorField(null=True) - def save(self, *args, **kwargs): - """Perform descriptor validation and save object.""" - if self.descriptor_schema: - try: - validate_schema(self.descriptor, self.descriptor_schema.schema) - self.descriptor_dirty = False - except DirtyError: - self.descriptor_dirty = True - elif self.descriptor and self.descriptor != {}: - raise ValueError( - "`descriptor_schema` must be defined if `descriptor` is given" - ) - super().save(*args, **kwargs) - class CollectionQuerySet(BaseQuerySet, PermissionQuerySet): """Query set for ``Collection`` objects.""" @@ -122,6 +97,17 @@ class Meta(BaseCollection.Meta): AnnotationField, related_name="collection" ) + #: collection descriptor schema + descriptor_schema = models.ForeignKey( + "flow.DescriptorSchema", blank=True, null=True, on_delete=models.PROTECT + ) + + #: collection descriptor + descriptor = models.JSONField(default=dict) + + #: indicate whether `descriptor` doesn't match `descriptor_schema` (is dirty) + descriptor_dirty = models.BooleanField(default=False) + def is_duplicate(self): """Return True if collection is a duplicate.""" return bool(self.duplicated) @@ -147,8 +133,18 @@ def delete_background(self): ) def save(self, *args, **kwargs): - """Add required annotation fields to the collection.""" + """Perform descriptor validation and save object.""" create = self.pk is None + if self.descriptor_schema: + try: + validate_schema(self.descriptor, self.descriptor_schema.schema) + self.descriptor_dirty = False + except DirtyError: + self.descriptor_dirty = True + elif self.descriptor and self.descriptor != {}: + raise ValueError( + "`descriptor_schema` must be defined if `descriptor` is given" + ) super().save(*args, **kwargs) if create: required_fields = AnnotationField.objects.filter(required=True) diff --git a/resolwe/flow/models/data.py b/resolwe/flow/models/data.py index c6da47c7e..faafaa57f 100644 --- a/resolwe/flow/models/data.py +++ b/resolwe/flow/models/data.py @@ -32,7 +32,6 @@ from resolwe.permissions.utils import assign_contributor_permissions, copy_permissions from .base import BaseModel, BaseQuerySet -from .descriptor import DescriptorSchema from .entity import Entity, EntityQuerySet from .history_manager import HistoryMixin from .secret import Secret diff --git a/resolwe/flow/models/process.py b/resolwe/flow/models/process.py index 43fe3ec1e..dddca191f 100644 --- a/resolwe/flow/models/process.py +++ b/resolwe/flow/models/process.py @@ -156,12 +156,6 @@ class Meta(BaseModel.Meta): create a new one. """ - entity_descriptor_schema = models.CharField(max_length=100, null=True, blank=True) - """ - Slug of the descriptor schema assigned to the Entity created with - :attr:`~resolwe.flow.models.Process.entity_type`. - """ - entity_input = models.CharField(max_length=100, null=True, blank=True) """ Limit the entity selection in @@ -170,8 +164,7 @@ class Meta(BaseModel.Meta): entity_always_create = models.BooleanField(default=False) """ - Create new entity, regardless of ``entity_input`` or - ``entity_descriptor_schema`` fields. + Create new entity, regardless of ``entity_input`` field. """ run = models.JSONField(default=dict) diff --git a/resolwe/flow/serializers/collection.py b/resolwe/flow/serializers/collection.py index df18fc0bf..cb8acd4e6 100644 --- a/resolwe/flow/serializers/collection.py +++ b/resolwe/flow/serializers/collection.py @@ -76,7 +76,6 @@ class Meta: model = Collection read_only_fields = ( "created", - "descriptor_dirty", "duplicated", "id", "modified", @@ -130,4 +129,5 @@ class Meta(BaseCollectionSerializer.Meta): "entity_count", "descriptor", "descriptor_schema", + "descriptor_dirty", ) diff --git a/resolwe/flow/serializers/process.py b/resolwe/flow/serializers/process.py index b96083af6..473309f41 100644 --- a/resolwe/flow/serializers/process.py +++ b/resolwe/flow/serializers/process.py @@ -24,7 +24,6 @@ class Meta: "data_name", "description", "entity_always_create", - "entity_descriptor_schema", "entity_input", "entity_type", "input_schema", diff --git a/resolwe/flow/tests/test_api.py b/resolwe/flow/tests/test_api.py index 123ad5150..6910d2837 100644 --- a/resolwe/flow/tests/test_api.py +++ b/resolwe/flow/tests/test_api.py @@ -53,7 +53,6 @@ def setUp(self): slug="test-process", version="1.0.0", contributor=self.contributor, - entity_descriptor_schema="test-schema", input_schema=[ {"name": "input_data", "type": "data:test:", "required": False} ], @@ -92,10 +91,7 @@ def setUp(self): ) self.entity = Entity.objects.create( - collection=self.collection, - contributor=self.contributor, - descriptor_schema=self.descriptor_schema, - name="Test entity", + collection=self.collection, contributor=self.contributor, name="Test entity" ) self.data = Data.objects.create( name="Test data", @@ -380,7 +376,6 @@ def setUp(self): version="1.0.0", contributor=self.contributor, entity_type="test-schema", - entity_descriptor_schema="test-schema", input_schema=[ {"name": "input_data", "type": "data:test:", "required": False} ], @@ -395,9 +390,7 @@ def setUp(self): descriptor_schema=self.descriptor_schema, ) self.entity = Entity.objects.create( - collection=self.collection, - contributor=self.contributor, - descriptor_schema=self.descriptor_schema, + collection=self.collection, contributor=self.contributor ) self.collection.set_permission(Permission.EDIT, self.contributor) self.proc.set_permission(Permission.VIEW, self.contributor) @@ -565,11 +558,7 @@ def test_prefetch(self): collection_2 = Collection.objects.create( contributor=self.user, descriptor_schema=descriptor_schema_2 ) - entity_2 = Entity.objects.create( - collection=collection_2, - contributor=self.user, - descriptor_schema=descriptor_schema_2, - ) + entity_2 = Entity.objects.create(collection=collection_2, contributor=self.user) for i in range(5): create_kwargs = { @@ -607,7 +596,7 @@ def test_prefetch(self): with CaptureQueriesContext(conn) as captured_queries: response = self.data_viewset(request) self.assertEqual(len(response.data), 10) - self.assertEqual(len(captured_queries), 12) + self.assertIn(len(captured_queries), [12, 13]) def test_descriptor_schema(self): # Descriptor schema can be assigned by slug. @@ -1647,10 +1636,7 @@ def test_prefetch(self): ) for i in range(5): - create_kwargs = { - "contributor": self.contributor, - "descriptor_schema": self.descriptor_schema, - } + create_kwargs = {"contributor": self.contributor} if i < 4: create_kwargs["collection"] = self.collection entity = Entity.objects.create(**create_kwargs) @@ -1659,10 +1645,7 @@ def test_prefetch(self): ) for i in range(5): - create_kwargs = { - "contributor": self.user, - "descriptor_schema": descriptor_schema_2, - } + create_kwargs = {"contributor": self.user} if i < 4: create_kwargs["collection"] = collection_2 entity = Entity.objects.create(**create_kwargs) @@ -1684,7 +1667,7 @@ def test_prefetch(self): with CaptureQueriesContext(conn) as captured_queries: response = self.entity_list_viewset(request) self.assertEqual(len(response.data), 10) - self.assertEqual(len(captured_queries), 7) + self.assertIn(len(captured_queries), [7, 8]) def test_list_filter_collection(self): request = factory.get("/", {}, format="json") diff --git a/resolwe/flow/tests/test_filtering.py b/resolwe/flow/tests/test_filtering.py index b9be631a7..9bef6d05c 100644 --- a/resolwe/flow/tests/test_filtering.py +++ b/resolwe/flow/tests/test_filtering.py @@ -70,6 +70,9 @@ def _check_filter( request = factory.get("/", query_args, format="json") force_authenticate(request, user or self.admin) response = self.viewset(request) + print("Got response") + print(response) + print(response.data) if status.is_success(response.status_code): self.assertEqual(len(response.data), len(expected)) @@ -451,13 +454,6 @@ def setUpTestData(cls): contributor=cls.contributor, collection=cls.collection1, description="My description!", - descriptor_schema=cls.descriptor_schema, - descriptor={ - "company": { - "name": "Genialis", - "departments": ["engineering", "operations"], - } - }, tags=["first-tag"], ), Entity.objects.create( @@ -465,9 +461,8 @@ def setUpTestData(cls): slug="test-entity-1", contributor=cls.contributor, collection=cls.collection2, - description="My favourite test entity", - descriptor_schema=cls.descriptor_schema, tags=["first-tag", "second-tag"], + description="My favourite test entity", ), Entity.objects.create( name="User test entity", @@ -545,12 +540,6 @@ def test_filter_description(self): self._check_filter({"description__contains": "Favourite"}, []) self._check_filter({"description__contains": "420"}, []) - def test_filter_descriptor_schema(self): - self._check_filter( - {"descriptor_schema": str(self.descriptor_schema.pk)}, self.entities[:2] - ) - self._check_filter({"descriptor_schema": "999999"}, []) - def test_filter_tags(self): self._check_filter({"tags": "first-tag"}, self.entities[:2]) self._check_filter({"tags": "first-tag,second-tag"}, [self.entities[1]]) @@ -677,10 +666,6 @@ def test_filter_text(self): self._check_filter({"text": "my description"}, [self.entities[0]]) self._check_filter({"text": "user"}, self.entities[2:]) - # By descriptor. - self._check_filter({"text": "genialis"}, [self.entities[0]]) - self._check_filter({"text": "engineering"}, [self.entities[0]]) - # By mixed fields. self._check_filter({"text": "test joe"}, self.entities[:2]) self._check_filter({"text": "joe my description"}, [self.entities[0]]) diff --git a/resolwe/flow/tests/test_manager.py b/resolwe/flow/tests/test_manager.py index ddf704719..1de79913b 100644 --- a/resolwe/flow/tests/test_manager.py +++ b/resolwe/flow/tests/test_manager.py @@ -81,7 +81,6 @@ def test_spawned_process(self): spawned_process = Process.objects.filter(slug="test-save-file").latest() # Patch the process to create Entity, so its bahaviour can be tested. spawned_process.entity_type = "test-schema" - spawned_process.entity_descriptor_schema = "test-schema" spawned_process.save() # Make sure user can spawn the process. diff --git a/resolwe/flow/tests/test_models.py b/resolwe/flow/tests/test_models.py index 01795739c..08a6f3f2e 100644 --- a/resolwe/flow/tests/test_models.py +++ b/resolwe/flow/tests/test_models.py @@ -323,7 +323,6 @@ def setUp(self): type="data:test:", contributor=self.contributor, entity_type="sample", - entity_descriptor_schema="sample", ) # Entity is created automatically when Data object is created self.data = Data.objects.create( @@ -373,7 +372,6 @@ def test_entity_inheritance(self): test_process = Process.objects.create( contributor=self.contributor, entity_type="sample", - entity_descriptor_schema="sample", input_schema=[ {"name": "data_list", "type": "list:data:test:", "required": False}, {"name": "data", "type": "data:test:", "required": False}, @@ -1396,7 +1394,6 @@ def test_hydrate_input_references(self): }, ], entity_type="sample", - entity_descriptor_schema="sample", ) data = Data.objects.create( diff --git a/resolwe/flow/tests/test_validation.py b/resolwe/flow/tests/test_validation.py index 11b6f9a8b..846e9cc9b 100644 --- a/resolwe/flow/tests/test_validation.py +++ b/resolwe/flow/tests/test_validation.py @@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError -from resolwe.flow.models import Collection, Data, DescriptorSchema, Entity, Process +from resolwe.flow.models import Collection, Data, DescriptorSchema, Process from resolwe.flow.models.utils import validate_data_object, validate_schema from resolwe.test import TestCase from resolwe.test.utils import create_data_location @@ -111,34 +111,6 @@ def test_validate_collection_descriptor(self): ): collection.save() - def test_validate_entity_descriptor(self): - descriptor_schema = DescriptorSchema.objects.create( - name="Test descriptor schema", - contributor=self.user, - schema=[{"name": "description", "type": "basic:string:", "required": True}], - ) - - entity = Entity.objects.create( - name="Test descriptor", - contributor=self.user, - descriptor_schema=descriptor_schema, - ) - self.assertEqual(entity.descriptor_dirty, True) - - entity.descriptor = {"description": "some value"} - entity.save() - self.assertEqual(entity.descriptor_dirty, False) - - entity.descriptor = {} - entity.save() - self.assertEqual(entity.descriptor_dirty, True) - - entity.descriptor = {"description": 42} - with self.assertRaisesRegex( - ValidationError, "is not valid under any of the given schemas" - ): - entity.save() - def test_referenced_storage(self): proc = Process.objects.create( name="Test process", diff --git a/resolwe/flow/views/entity.py b/resolwe/flow/views/entity.py index 0ed0ccdc6..494e9c26b 100644 --- a/resolwe/flow/views/entity.py +++ b/resolwe/flow/views/entity.py @@ -14,7 +14,7 @@ from rest_framework.response import Response from resolwe.flow.filters import EntityFilter -from resolwe.flow.models import AnnotationValue, Data, DescriptorSchema, Entity +from resolwe.flow.models import AnnotationValue, Data, Entity from resolwe.flow.serializers import EntitySerializer from resolwe.flow.serializers.annotations import AnnotationsByPathSerializer from resolwe.observers.mixins import ObservableMixin @@ -36,7 +36,6 @@ class EntityViewSet(ObservableMixin, BaseCollectionViewSet): serializer_class = EntitySerializer filterset_class = EntityFilter - qs_descriptor_schema = DescriptorSchema.objects.select_related("contributor") data_count_subquery = ( Data.objects.filter(entity_id=OuterRef("pk")) @@ -58,7 +57,7 @@ class EntityViewSet(ObservableMixin, BaseCollectionViewSet): .values("count") ) queryset = ( - Entity.objects.select_related("contributor", "descriptor_schema__contributor") + Entity.objects.select_related("contributor") .prefetch_related( Prefetch("collection", queryset=BaseCollectionViewSet.queryset) ) diff --git a/resolwe/observers/tests.py b/resolwe/observers/tests.py index 4fe8bab35..fbc6f96b1 100644 --- a/resolwe/observers/tests.py +++ b/resolwe/observers/tests.py @@ -59,7 +59,6 @@ def setUp(self): name="Dummy process", contributor=self.user_alice, entity_type="sample", - entity_descriptor_schema="sample", ) self.client_consumer = URLRouter( diff --git a/resolwe/process/tests/processes/python_test.py b/resolwe/process/tests/processes/python_test.py index 385a77652..cd3428579 100644 --- a/resolwe/process/tests/processes/python_test.py +++ b/resolwe/process/tests/processes/python_test.py @@ -628,23 +628,6 @@ def run(self, inputs, outputs): entity.name = inputs.entity_name -class ChangeEntityDescriptor(Process): - slug = "change-entity-descriptor" - name = "Change entity descriptor" - data_name = "{{ data_input | name | default('?') }}" - version = "1.0.0" - process_type = "data:name" - requirements = {"expression-engine": "jinja"} - - class Input: - entity_id = IntegerField(label="Entity id") - description = StringField(label="New description") - - def run(self, inputs, outputs): - entity = Entity.get(pk=inputs.entity_id) - entity.descriptor = {"Description": inputs.description} - - class TestStorage(Process): slug = "storage-objects-test" name = "Test working with storage objects" diff --git a/resolwe/process/tests/test_python_process.py b/resolwe/process/tests/test_python_process.py index a0c37b70c..75c4feca1 100644 --- a/resolwe/process/tests/test_python_process.py +++ b/resolwe/process/tests/test_python_process.py @@ -9,7 +9,6 @@ from resolwe.flow.models import ( Collection, Data, - DescriptorSchema, Entity, Process, Relation, @@ -62,7 +61,6 @@ def test_registration(self): self.assertEqual(process.description, "This is a process description.") self.assertEqual(process.data_name, "Foo: {{input_data | name}}") self.assertEqual(process.entity_type, "sample") - self.assertEqual(process.entity_descriptor_schema, "sample") self.assertEqual(process.entity_input, "input_data") self.assertEqual( process.requirements, @@ -597,39 +595,6 @@ def test_change_entity_name(self): entity.refresh_from_db() self.assertEqual(entity.name, "New entity name") - @with_docker_executor - @tag_process("change-entity-descriptor") - def test_change_descriptor(self): - """Assign descriptor to entity.""" - - descriptor_schema = DescriptorSchema.objects.create( - name="Descriptor schema", - contributor=self.contributor, - schema=[ - { - "name": "Description", - "type": "basic:string:", - "default": "default value", - } - ], - ) - entity = Entity.objects.create( - name="Entity", contributor=self.user, descriptor_schema=descriptor_schema - ) - - self.run_process( - "change-entity-descriptor", - { - "entity_id": entity.pk, - "description": "New description", - }, - ) - entity.refresh_from_db() - self.assertEqual( - entity.descriptor, - {"Description": "New description"}, - ) - class PythonProcessRequirementsTest(ProcessTestCase): def setUp(self): diff --git a/resolwe/rest/tests.py b/resolwe/rest/tests.py index 5bd65a191..382c92df9 100644 --- a/resolwe/rest/tests.py +++ b/resolwe/rest/tests.py @@ -91,7 +91,6 @@ def test_projection(self): data["entity"].keys(), [ "created", - "descriptor_dirty", "duplicated", "id", "modified",