Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Export ID on Taxonomy #34143

Merged
2 changes: 2 additions & 0 deletions openedx/core/djangoapps/content_tagging/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def create_taxonomy(
allow_multiple=True,
allow_free_text=False,
orgs: list[Organization] | None = None,
export_id: str | None = None,
) -> Taxonomy:
"""
Creates, saves, and returns a new Taxonomy with the given attributes.
Expand All @@ -29,6 +30,7 @@ def create_taxonomy(
enabled=enabled,
allow_multiple=allow_multiple,
allow_free_text=allow_free_text,
export_id=export_id,
)

if orgs is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def check_taxonomy(
allow_free_text=False,
system_defined=False,
visible_to_authors=True,
export_id=None,
**_
):
"""
Expand All @@ -75,6 +76,7 @@ def check_taxonomy(
assert data["allow_free_text"] == allow_free_text
assert data["system_defined"] == system_defined
assert data["visible_to_authors"] == visible_to_authors
assert data["export_id"] == export_id


class TestTaxonomyObjectsMixin:
Expand Down Expand Up @@ -174,19 +176,19 @@ def _setUp_taxonomies(self):
Create taxonomies for testing
"""
# Orphaned taxonomy
self.ot1 = Taxonomy.objects.create(name="ot1", enabled=True)
self.ot2 = Taxonomy.objects.create(name="ot2", enabled=False)
self.ot1 = tagging_api.create_taxonomy(name="ot1", enabled=True)
self.ot2 = tagging_api.create_taxonomy(name="ot2", enabled=False)

# System defined taxonomy
self.st1 = Taxonomy.objects.create(name="st1", enabled=True)
self.st1 = tagging_api.create_taxonomy(name="st1", enabled=True)
self.st1.taxonomy_class = SystemDefinedTaxonomy
self.st1.save()
TaxonomyOrg.objects.create(
taxonomy=self.st1,
rel_type=TaxonomyOrg.RelType.OWNER,
org=None,
)
self.st2 = Taxonomy.objects.create(name="st2", enabled=False)
self.st2 = tagging_api.create_taxonomy(name="st2", enabled=False)
self.st2.taxonomy_class = SystemDefinedTaxonomy
self.st2.save()
TaxonomyOrg.objects.create(
Expand All @@ -195,12 +197,12 @@ def _setUp_taxonomies(self):
)

# Global taxonomy, which contains tags
self.t1 = Taxonomy.objects.create(name="t1", enabled=True)
self.t1 = tagging_api.create_taxonomy(name="t1", enabled=True)
TaxonomyOrg.objects.create(
taxonomy=self.t1,
rel_type=TaxonomyOrg.RelType.OWNER,
)
self.t2 = Taxonomy.objects.create(name="t2", enabled=False)
self.t2 = tagging_api.create_taxonomy(name="t2", enabled=False)
TaxonomyOrg.objects.create(
taxonomy=self.t2,
rel_type=TaxonomyOrg.RelType.OWNER,
Expand All @@ -213,33 +215,33 @@ def _setUp_taxonomies(self):
Tag.objects.create(taxonomy=self.t1, value="anvil", parent=root1)

# OrgA taxonomy
self.tA1 = Taxonomy.objects.create(name="tA1", enabled=True)
self.tA1 = tagging_api.create_taxonomy(name="tA1", enabled=True)
TaxonomyOrg.objects.create(
taxonomy=self.tA1,
org=self.orgA, rel_type=TaxonomyOrg.RelType.OWNER,)
self.tA2 = Taxonomy.objects.create(name="tA2", enabled=False)
self.tA2 = tagging_api.create_taxonomy(name="tA2", enabled=False)
TaxonomyOrg.objects.create(
taxonomy=self.tA2,
org=self.orgA,
rel_type=TaxonomyOrg.RelType.OWNER,
)

# OrgB taxonomy
self.tB1 = Taxonomy.objects.create(name="tB1", enabled=True)
self.tB1 = tagging_api.create_taxonomy(name="tB1", enabled=True)
TaxonomyOrg.objects.create(
taxonomy=self.tB1,
org=self.orgB,
rel_type=TaxonomyOrg.RelType.OWNER,
)
self.tB2 = Taxonomy.objects.create(name="tB2", enabled=False)
self.tB2 = tagging_api.create_taxonomy(name="tB2", enabled=False)
TaxonomyOrg.objects.create(
taxonomy=self.tB2,
org=self.orgB,
rel_type=TaxonomyOrg.RelType.OWNER,
)

# OrgA and OrgB taxonomy
self.tBA1 = Taxonomy.objects.create(name="tBA1", enabled=True)
self.tBA1 = tagging_api.create_taxonomy(name="tBA1", enabled=True)
TaxonomyOrg.objects.create(
taxonomy=self.tBA1,
org=self.orgA,
Expand All @@ -250,7 +252,7 @@ def _setUp_taxonomies(self):
org=self.orgB,
rel_type=TaxonomyOrg.RelType.OWNER,
)
self.tBA2 = Taxonomy.objects.create(name="tBA2", enabled=False)
self.tBA2 = tagging_api.create_taxonomy(name="tBA2", enabled=False)
TaxonomyOrg.objects.create(
taxonomy=self.tBA2,
org=self.orgA,
Expand Down Expand Up @@ -466,6 +468,7 @@ def test_create_taxonomy(self, user_attr: str, expected_status: int) -> None:
"description": "This is a description",
"enabled": True,
"allow_multiple": True,
"export_id": "taxonomy_data",
}

if user_attr:
Expand Down Expand Up @@ -1029,6 +1032,7 @@ def _test_api_call(self, **kwargs) -> None:
"name": "new name",
"description": taxonomy.description,
"enabled": taxonomy.enabled,
"export_id": taxonomy.export_id,
},
)

Expand Down Expand Up @@ -1069,6 +1073,7 @@ def _test_api_call(self, **kwargs) -> None:
"name": "new name",
"description": taxonomy.description,
"enabled": taxonomy.enabled,
"export_id": taxonomy.export_id,
},
)

Expand Down Expand Up @@ -1327,16 +1332,25 @@ def setUp(self):
block_id='block_id'
)

self.multiple_taxonomy = Taxonomy.objects.create(name="Multiple Taxonomy", allow_multiple=True)
self.single_value_taxonomy = Taxonomy.objects.create(name="Required Taxonomy", allow_multiple=False)
self.multiple_taxonomy = tagging_api.create_taxonomy(
name="Multiple Taxonomy",
allow_multiple=True,
)
self.single_value_taxonomy = tagging_api.create_taxonomy(
name="Required Taxonomy",
allow_multiple=False,
)
for i in range(20):
# Valid ObjectTags
Tag.objects.create(taxonomy=self.tA1, value=f"Tag {i}")
Tag.objects.create(taxonomy=self.tA2, value=f"Tag {i}")
Tag.objects.create(taxonomy=self.multiple_taxonomy, value=f"Tag {i}")
Tag.objects.create(taxonomy=self.single_value_taxonomy, value=f"Tag {i}")

self.open_taxonomy = Taxonomy.objects.create(name="Enabled Free-Text Taxonomy", allow_free_text=True)
self.open_taxonomy = tagging_api.create_taxonomy(
name="Enabled Free-Text Taxonomy",
allow_free_text=True,
)

# Add org permissions to taxonomy
TaxonomyOrg.objects.create(
Expand Down Expand Up @@ -1701,6 +1715,7 @@ def test_import_global_admin(self, file_format: str) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand All @@ -1711,6 +1726,7 @@ def test_import_global_admin(self, file_format: str) -> None:
taxonomy = response.data
assert taxonomy["name"] == "Imported Taxonomy name"
assert taxonomy["description"] == "Imported Taxonomy description"
assert taxonomy["export_id"] == "imported_taxonomy"

# Check if the tags were created
url = TAXONOMY_TAGS_URL.format(pk=taxonomy["id"])
Expand Down Expand Up @@ -1746,6 +1762,7 @@ def test_import_orgA_admin(self, file_format: str) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand All @@ -1756,6 +1773,7 @@ def test_import_orgA_admin(self, file_format: str) -> None:
taxonomy = response.data
assert taxonomy["name"] == "Imported Taxonomy name"
assert taxonomy["description"] == "Imported Taxonomy description"
assert taxonomy["export_id"] == "imported_taxonomy"

# Check if the tags were created
url = TAXONOMY_TAGS_URL.format(pk=taxonomy["id"])
Expand All @@ -1780,6 +1798,7 @@ def test_import_no_file(self) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
},
format="multipart"
)
Expand All @@ -1804,6 +1823,7 @@ def test_import_no_name(self, file_format) -> None:
url,
{
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand All @@ -1814,6 +1834,29 @@ def test_import_no_name(self, file_format) -> None:
# Check if the taxonomy was not created
assert not Taxonomy.objects.filter(name="Imported Taxonomy name").exists()

@ddt.data(
"csv",
"json",
)
def test_import_no_export_id(self, file_format) -> None:
url = TAXONOMY_CREATE_IMPORT_URL
file = SimpleUploadedFile(f"taxonomy.{file_format}", b"invalid file content")
self.client.force_authenticate(user=self.staff)
response = self.client.post(
url,
{
"taxonomt_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"file": file,
},
format="multipart"
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.data["taxonomy_export_id"][0] == "This field is required."

# Check if the taxonomy was not created
assert not Taxonomy.objects.filter(name="Imported Taxonomy name").exists()

def test_import_invalid_format(self) -> None:
"""
Tests importing a taxonomy with an invalid file format.
Expand All @@ -1826,6 +1869,7 @@ def test_import_invalid_format(self) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy_id",
"file": file,
},
format="multipart"
Expand All @@ -1852,6 +1896,7 @@ def test_import_invalid_content(self, file_format) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand Down Expand Up @@ -1881,6 +1926,7 @@ def test_import_no_perm(self) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand All @@ -1900,7 +1946,7 @@ class TestImportTagsView(ImportTaxonomyMixin, APITestCase):
def setUp(self):
ImportTaxonomyMixin.setUp(self)

self.taxonomy = Taxonomy.objects.create(
self.taxonomy = tagging_api.create_taxonomy(
name="Test import taxonomy",
)
tag_1 = Tag.objects.create(
Expand Down Expand Up @@ -2009,6 +2055,7 @@ def test_import_invalid_content(self, file_format) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomy_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand Down Expand Up @@ -2078,6 +2125,7 @@ def test_import_no_perm(self) -> None:
{
"taxonomy_name": "Imported Taxonomy name",
"taxonomy_description": "Imported Taxonomy description",
"taxonomt_export_id": "imported_taxonomy",
"file": file,
},
format="multipart"
Expand Down
2 changes: 1 addition & 1 deletion requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ libsass==0.10.0
click==8.1.6

# pinning this version to avoid updates while the library is being developed
openedx-learning==0.4.4
openedx-learning==0.5.1

# Open AI version 1.0.0 dropped support for openai.ChatCompletion which is currently in use in enterprise.
openai<=0.28.1
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ openedx-filters==1.6.0
# via
# -r requirements/edx/kernel.in
# lti-consumer-xblock
openedx-learning==0.4.4
openedx-learning==0.5.1
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/kernel.in
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,7 @@ openedx-filters==1.6.0
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# lti-consumer-xblock
openedx-learning==0.4.4
openedx-learning==0.5.1
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/doc.txt
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ openedx-filters==1.6.0
# via
# -r requirements/edx/base.txt
# lti-consumer-xblock
openedx-learning==0.4.4
openedx-learning==0.5.1
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ openedx-filters==1.6.0
# via
# -r requirements/edx/base.txt
# lti-consumer-xblock
openedx-learning==0.4.4
openedx-learning==0.5.1
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down
Loading