From 039ccba6a814b1fe0d7a4af01507381d1c53e9d4 Mon Sep 17 00:00:00 2001
From: Raphael Gaschignard <raphael@rtpg.co>
Date: Wed, 9 Oct 2024 17:54:59 +1000
Subject: [PATCH] Fix test suite failing if unidecode is installed

---
 taggit/models.py     | 15 +++++++++++++--
 tests/test_models.py | 43 +++++++++++++++++++++++++++++++++++++++----
 tox.ini              |  1 +
 3 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/taggit/models.py b/taggit/models.py
index 0b14e7d9..8e981a08 100644
--- a/taggit/models.py
+++ b/taggit/models.py
@@ -9,9 +9,20 @@
 
 try:
     from unidecode import unidecode
+
+    unidecode_installed = True
 except ImportError:
+    unidecode_installed = False
+
 
-    def unidecode(tag):
+def slugify_unicode_stripping_prep(tag):
+    """
+    This handles stripping via unidecode if it's installed,
+    otherwise is a no-op
+    """
+    if unidecode_installed:
+        return unidecode(tag)
+    else:
         return tag
 
 
@@ -97,7 +108,7 @@ def save(self, *args, **kwargs):
 
     def slugify(self, tag, i=None):
         if getattr(settings, "TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING", False):
-            slug = slugify(unidecode(tag))
+            slug = slugify(slugify_unicode_stripping_prep(tag))
         else:
             slug = slugify(tag, allow_unicode=True)
         if i is not None:
diff --git a/tests/test_models.py b/tests/test_models.py
index 4a9b748c..1d356d99 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -1,8 +1,25 @@
+from contextlib import contextmanager
+from unittest import skipIf
+
 from django.test import TestCase, override_settings
 
+from taggit import models as taggit_models
 from tests.models import TestModel
 
 
+@contextmanager
+def disable_unidecode():
+    """
+    Disable unidecode temporarily
+    """
+    old_installed_value = taggit_models.unidecode_installed
+    taggit_models.unidecode_installed = False
+    try:
+        yield
+    finally:
+        taggit_models.unidecode_installed = old_installed_value
+
+
 class TestTaggableManager(TestCase):
     def test_duplicates(self):
         sample_obj = TestModel.objects.create()
@@ -22,17 +39,35 @@ def test_unicode_slugs(self):
         sample_obj.tags.add("あい うえお")
         self.assertEqual([tag.slug for tag in sample_obj.tags.all()], ["あい-うえお"])
 
-    def test_old_slugs(self):
+    def test_old_slugs_wo_unidecode(self):
+        """
+        Test that the setting that gives us the old slugification behavior
+        is in place
+        """
+        with (
+            disable_unidecode(),
+            override_settings(TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING=True),
+        ):
+            sample_obj = TestModel.objects.create()
+            sample_obj.tags.add("aあい うえおb")
+            # when unidecode is not installed, the unicode ends up being passed directly
+            # to slugify, and will get "wiped"
+            self.assertEqual([tag.slug for tag in sample_obj.tags.all()], ["a-b"])
+
+    @skipIf(
+        not taggit_models.unidecode_installed,
+        "This test requires unidecode to be installed",
+    )
+    def test_old_slugs_with_unidecode(self):
         """
         Test that the setting that gives us the old slugification behavior
         is in place
         """
         with override_settings(TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING=True):
             sample_obj = TestModel.objects.create()
-            # a unicode tag will be slugified for space reasons but
-            # unicode-ness will be kept by default
+            # unidecode will transform the tag on top of slugification
             sample_obj.tags.add("あい うえお")
-            self.assertEqual([tag.slug for tag in sample_obj.tags.all()], [""])
+            self.assertEqual([tag.slug for tag in sample_obj.tags.all()], ["ai-ueo"])
 
 
 class TestPrefetchCache(TestCase):
diff --git a/tox.ini b/tox.ini
index af630a80..ff642c5e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -24,6 +24,7 @@ deps =
     djmain: https://github.com/django/django/archive/main.tar.gz
     coverage
     djangorestframework
+    unidecode
 setenv =
     PYTHONWARNINGS=all
 commands =