Repository: carpentries/amy

Issue:
Select2 Tag widget error when using on empty event form
Perhaps a related issue - I also got a 500 Server Error when trying to accept a workshop request (e.g. https://amy.carpentries.org/requests/selforganised_submission/552/) but then on repeated attempts accepting some of the problematic requests worked so not sure what was happening but thought I should report it. This one is still causing problems: https://amy.carpentries.org/requests/selforganised_submission/552/

_Originally posted by @anenadic in https://github.com/carpentries/amy/issues/1650#issuecomment-623344963_


Discussion:
`Select2TagWidget` is trying to access 0th element of an empty list in `Select2TagWidget.optgroups` in `amy.workshops.fields`.

Resolving patch:
diff --git a/amy/workshops/fields.py b/amy/workshops/fields.py
--- a/amy/workshops/fields.py
+++ b/amy/workshops/fields.py
@@ -190,7 +190,11 @@ def value_from_datadict(self, data, files, name):
     def optgroups(self, name, value, attrs=None):
         """Example from
         https://django-select2.readthedocs.io/en/latest/django_select2.html#django_select2.forms.Select2TagWidget"""
-        values = value[0].split(TAG_SEPARATOR) if value[0] else []
+        try:
+            values = value[0].split(TAG_SEPARATOR)
+        except (IndexError, AttributeError):
+            values = []
+
         selected = set(values)
         subgroup = [
             self.create_option(name, v, v, selected, i)


Test patch:
diff --git a/amy/workshops/tests/test_fields.py b/amy/workshops/tests/test_fields.py
--- a/amy/workshops/tests/test_fields.py
+++ b/amy/workshops/tests/test_fields.py
@@ -1,28 +1,28 @@
 from django.core.exceptions import ValidationError
 
 from workshops.tests.base import TestBase
-from workshops.fields import NullableGithubUsernameField
+from workshops.fields import NullableGithubUsernameField, Select2TagWidget
 
 
 class TestNullableGHUsernameField(TestBase):
     def setUp(self):
         self.passing = [
-            'harrypotter',
-            'hp',
-            'hpotter',
-            'harry-potter',
-            'harry-potter123',
-            'Harry-Potter',
-            '',
+            "harrypotter",
+            "hp",
+            "hpotter",
+            "harry-potter",
+            "harry-potter123",
+            "Harry-Potter",
+            "",
             None,
         ]
 
         self.failing = [
-            'harry_potter',
-            'harry--potter',
-            '-harry',
-            'potter-',
-            'harry-averyveryverylongmiddlename-potter',
+            "harry_potter",
+            "harry--potter",
+            "-harry",
+            "potter-",
+            "harry-averyveryverylongmiddlename-potter",
         ]
 
         self.field = NullableGithubUsernameField()
@@ -37,3 +37,30 @@ def test_failing_usernames(self):
         for username in self.failing:
             with self.assertRaises(ValidationError):
                 self.field.run_validators(username)
+
+
+class TestSelect2TagWidget(TestBase):
+    def setUp(self):
+        self.widget = Select2TagWidget()
+
+    def test_optgroups(self):
+        # incorrect input
+        self.assertEqual(self.widget.optgroups("name", []), [(None, [], 0)])
+
+        # correct input (1 value)
+        option1 = self.widget.create_option("name", "Harry", "Harry", set(["Harry"]), 0)
+        self.assertEqual(
+            self.widget.optgroups("name", ["Harry"]), [(None, [option1], 0,)],
+        )
+
+        # correct input (2 values)
+        option1 = self.widget.create_option(
+            "name", "Harry", "Harry", set(["Harry", "Ron"]), 0
+        )
+        option2 = self.widget.create_option(
+            "name", "Ron", "Ron", set(["Harry", "Ron"]), 1
+        )
+        self.assertEqual(
+            self.widget.optgroups("name", ["Harry;Ron"]),
+            [(None, [option1, option2], 0,)],
+        )