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
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
130 changes: 115 additions & 15 deletions openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py
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,35 @@ 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 = Taxonomy.objects.create(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please use the create_taxonomy API method to create these taxonomies?

name="ot1",
enabled=True,
export_id="ot1",
)
self.ot2 = Taxonomy.objects.create(
name="ot2",
enabled=False,
export_id="ot2",
)

# System defined taxonomy
self.st1 = Taxonomy.objects.create(name="st1", enabled=True)
self.st1 = Taxonomy.objects.create(
name="st1",
enabled=True,
export_id="st1",
)
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 = Taxonomy.objects.create(
name="st2",
enabled=False,
export_id="st2",
)
self.st2.taxonomy_class = SystemDefinedTaxonomy
self.st2.save()
TaxonomyOrg.objects.create(
Expand All @@ -195,12 +213,20 @@ def _setUp_taxonomies(self):
)

# Global taxonomy, which contains tags
self.t1 = Taxonomy.objects.create(name="t1", enabled=True)
self.t1 = Taxonomy.objects.create(
name="t1",
enabled=True,
export_id="t1",
)
TaxonomyOrg.objects.create(
taxonomy=self.t1,
rel_type=TaxonomyOrg.RelType.OWNER,
)
self.t2 = Taxonomy.objects.create(name="t2", enabled=False)
self.t2 = Taxonomy.objects.create(
name="t2",
enabled=False,
export_id="t2",
)
TaxonomyOrg.objects.create(
taxonomy=self.t2,
rel_type=TaxonomyOrg.RelType.OWNER,
Expand All @@ -213,33 +239,53 @@ 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 = Taxonomy.objects.create(
name="tA1",
enabled=True,
export_id="tA1",
)
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 = Taxonomy.objects.create(
name="tA2",
enabled=False,
export_id="tA2",
)
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 = Taxonomy.objects.create(
name="tB1",
enabled=True,
export_id="tB1",
)
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 = Taxonomy.objects.create(
name="tB2",
enabled=False,
export_id="tB2",
)
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 = Taxonomy.objects.create(
name="tBA1",
enabled=True,
export_id="tBA1",
)
TaxonomyOrg.objects.create(
taxonomy=self.tBA1,
org=self.orgA,
Expand All @@ -250,7 +296,11 @@ def _setUp_taxonomies(self):
org=self.orgB,
rel_type=TaxonomyOrg.RelType.OWNER,
)
self.tBA2 = Taxonomy.objects.create(name="tBA2", enabled=False)
self.tBA2 = Taxonomy.objects.create(
name="tBA2",
enabled=False,
export_id="tBA2",
)
TaxonomyOrg.objects.create(
taxonomy=self.tBA2,
org=self.orgA,
Expand Down Expand Up @@ -466,6 +516,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 +1080,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 +1121,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 +1380,28 @@ 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 = Taxonomy.objects.create(
name="Multiple Taxonomy",
allow_multiple=True,
export_id="multiple_taxonomy",
)
self.single_value_taxonomy = Taxonomy.objects.create(
name="Required Taxonomy",
allow_multiple=False,
export_id="required_taxonomy",
)
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 = Taxonomy.objects.create(
name="Enabled Free-Text Taxonomy",
allow_free_text=True,
export_id="enabled_free_text_taxonomy",
)

# Add org permissions to taxonomy
TaxonomyOrg.objects.create(
Expand Down Expand Up @@ -1701,6 +1766,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 +1777,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 +1813,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 +1824,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 +1849,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 +1874,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 +1885,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 +1920,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 +1947,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 +1977,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 @@ -1902,6 +1999,7 @@ def setUp(self):

self.taxonomy = Taxonomy.objects.create(
name="Test import taxonomy",
export_id="test_import_taxonomy",
)
tag_1 = Tag.objects.create(
taxonomy=self.taxonomy,
Expand Down Expand Up @@ -2009,6 +2107,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 +2177,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 @@ -103,7 +103,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.0

# 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 @@ -780,7 +780,7 @@ openedx-filters==1.6.0
# via
# -r requirements/edx/kernel.in
# lti-consumer-xblock
openedx-learning==0.4.4
openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/FAL-3620-export-id-on-taxonomies
# 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 @@ -1311,7 +1311,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 @ git+https://github.com/open-craft/openedx-learning.git@chris/FAL-3620-export-id-on-taxonomies
# 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 @@ -922,7 +922,7 @@ openedx-filters==1.6.0
# via
# -r requirements/edx/base.txt
# lti-consumer-xblock
openedx-learning==0.4.4
openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/FAL-3620-export-id-on-taxonomies
# via
# -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/kernel.in
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ openedx-calc # Library supporting mathematical calculatio
openedx-django-require
openedx-events # Open edX Events from Hooks Extension Framework (OEP-50)
openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50)
openedx-learning # Open edX Learning core (experimental)
git+https://github.com/open-craft/openedx-learning.git@chris/FAL-3620-export-id-on-taxonomies#egg=openedx-learning # Open edX Learning core (experimental)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Bump version with openedx/openedx-learning#145

openedx-mongodbproxy
openedx-django-wiki
openedx-blockstore
Expand Down
Loading
Loading