diff --git a/openedx_tagging/core/tagging/api.py b/openedx_tagging/core/tagging/api.py index 590efb7a..46d5e623 100644 --- a/openedx_tagging/core/tagging/api.py +++ b/openedx_tagging/core/tagging/api.py @@ -176,14 +176,13 @@ def import_tags(taxonomy: Taxonomy, tags: BytesIO, format: TaxonomyDataFormat, r tags.close() - new_tags = [] updated_tags = [] def create_update_tag(tag): """ Function to create a new Tag or update an existing one. - This function keeps a creation/update history with `new_tags` and `updated_tags`, + This function keeps a creation/update history with `updated_tags`, a same tag can't be created/updated in a same taxonomy import. Also, recursively, creates the parents of the `tag`. @@ -197,7 +196,7 @@ def create_update_tag(tag): tag_parent_name = tag.get('parent_name') # Check if the tag has not already been created or updated - if tag_id not in new_tags and tag_id not in updated_tags: + if tag_id not in updated_tags: try: # Update tag tag_instance = taxonomy.tag_set.get(external_id=tag_id) @@ -214,7 +213,7 @@ def create_update_tag(tag): value=tag_name, external_id=tag_id, ) - new_tags.append(tag_id) + updated_tags.append(tag_id) if tag_parent_id and tag_parent_name: # Parent creation/update @@ -229,10 +228,6 @@ def create_update_tag(tag): # Create and update tags with transaction.atomic(): - # Delete all old Tags linked to the taxonomy - if replace: - Tag.objects.filter(taxonomy=taxonomy).delete() - for tag in tags_data: try: create_update_tag(tag) @@ -243,7 +238,12 @@ def create_update_tag(tag): f"Invalid JSON format: Missing '{key}' on a tag ({tag})" ) ) - resync_tags() + + # If replace, delete all not updated tags (Not present in the file) + if replace: + taxonomy.tag_set.exclude(external_id__in=updated_tags).delete() + + resync_object_tags(ObjectTag.objects.filter(taxonomy=taxonomy)) def export_tags(taxonomy: Taxonomy, format: TaxonomyDataFormat) -> str: """ diff --git a/tests/openedx_tagging/core/tagging/test_api.py b/tests/openedx_tagging/core/tagging/test_api.py index 5701e0f1..eb32d198 100644 --- a/tests/openedx_tagging/core/tagging/test_api.py +++ b/tests/openedx_tagging/core/tagging/test_api.py @@ -2,9 +2,9 @@ from io import BytesIO import json +from unittest.mock import patch import ddt -from unittest.mock import patch from django.test.testcases import TestCase import openedx_tagging.core.tagging.api as tagging_api @@ -326,6 +326,37 @@ def test_import_tags_json_validations(self, json_data): with self.assertRaises(ValueError): tagging_api.import_tags(taxonomy, json_file, tagging_api.TaxonomyDataFormat.JSON) + def test_import_tags_resync(self): + object_id = 'course_1' + object_tag = ObjectTag( + object_id=object_id, + object_type='course', + taxonomy=self.taxonomy, + tag=self.bacteria, + ) + tagging_api.resync_object_tags([object_tag]) + object_tag = ObjectTag.objects.get(object_id=object_id) + self.assertEqual(object_tag.tag.value, 'Bacteria') + self.assertEqual(object_tag._value, 'Bacteria') + + json_data = {"tags": [{"id": "tag_1", "name": "Bacteria 2.0"}]} + json_file = BytesIO(json.dumps(json_data).encode()) + + # Import + tagging_api.import_tags(self.taxonomy, json_file, tagging_api.TaxonomyDataFormat.JSON) + object_tag = ObjectTag.objects.get(object_id=object_id) + self.assertEqual(object_tag.tag.value, 'Bacteria 2.0') + self.assertEqual(object_tag._value, 'Bacteria 2.0') + + json_data = {"tags": [{"id": "tag_1", "name": "Bacteria 3.0"}]} + json_file = BytesIO(json.dumps(json_data).encode()) + + # Import and replace + tagging_api.import_tags(self.taxonomy, json_file, tagging_api.TaxonomyDataFormat.JSON, replace=True) + object_tag = ObjectTag.objects.get(object_id=object_id) + self.assertEqual(object_tag.tag.value, 'Bacteria 3.0') + self.assertEqual(object_tag._value, 'Bacteria 3.0') + def test_export_tags_json(self): json_data = { "name": "Life on Earth",