diff --git a/course_discovery/apps/course_metadata/tests/test_widgets.py b/course_discovery/apps/course_metadata/tests/test_widgets.py index e1b7497206..0cb853b63b 100644 --- a/course_discovery/apps/course_metadata/tests/test_widgets.py +++ b/course_discovery/apps/course_metadata/tests/test_widgets.py @@ -1,19 +1,40 @@ -import ddt +import itertools + +from bs4 import BeautifulSoup from django.test import TestCase +from django.urls import reverse + +from course_discovery.apps.api.tests.mixins import SiteMixin +from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory +from course_discovery.apps.course_metadata.tests.factories import CourseFactory, ProgramFactory + -from course_discovery.apps.course_metadata.widgets import SortedModelSelect2Multiple +class SortedModelSelect2MultipleTests(SiteMixin, TestCase): + def setUp(self): + super().setUp() + self.user = UserFactory(is_staff=True, is_superuser=True) + self.client.login(username=self.user.username, password=USER_PASSWORD) + def test_program_ordered_m2m(self): + """ + Verify that program page sorted m2m fields render in order. The sorted + m2m field chosen for the test is the courses field + """ -@ddt.ddt -class SortedModelSelect2MultipleTests(TestCase): - @ddt.data( - (['1', '2'], [1, 2]), - (['2', '1'], [2, 1]), - (['3'], [3,]), - ) - @ddt.unpack - def test_optgroups_are_sorted(self, value, result_order): - choices = ((1, 'one'), (2, 'two'), (3, 'three')) - widget = SortedModelSelect2Multiple(url='requiredurl', choices=choices) - result = widget.optgroups('test', value) - assert result_order == [x[1][0]['value'] for x in result] + for courses in itertools.permutations( + [ + CourseFactory(title="Blade Runner 2049"), + CourseFactory(title="History of Western Literature"), + CourseFactory(title="Urdu Poetry") + ], + 2 + ): + program = ProgramFactory(courses=courses) + response = self.client.get(reverse('admin:course_metadata_program_change', args=(program.id,))) + response_content = BeautifulSoup(response.content) + options = response_content.find('select', {'name': 'courses'}).find_all('option') + assert len(options) == len(courses) + for idx, opt in enumerate(options): + assert 'selected' in opt.attrs + assert opt.get_text().endswith(courses[idx].title) + assert opt.attrs['value'] == str(courses[idx].id) diff --git a/course_discovery/apps/course_metadata/widgets.py b/course_discovery/apps/course_metadata/widgets.py index 0f85f435b3..a7d3519dc8 100644 --- a/course_discovery/apps/course_metadata/widgets.py +++ b/course_discovery/apps/course_metadata/widgets.py @@ -1,5 +1,3 @@ -from itertools import chain - from dal import autocomplete @@ -8,16 +6,9 @@ def optgroups(self, name, value, attrs=None): """ Return a sorted list of optgroups for this widget. - This is a simplified version of Django's version. The big difference is that we keep the results sorted and - only support one main group (because that's all we need right now). + This is a simplified version of Django's version. The big difference is that we keep the results sorted. """ - selected = [] - for index, (option_value, option_label) in enumerate(chain(self.choices)): - is_selected = str(option_value) in value - if is_selected: - subgroup = [self.create_option(name, option_value, option_label, is_selected, index, attrs=attrs)] - item = (None, subgroup, index) - selected.append(item) + selected = super().optgroups(name, value, attrs) ordered = [] for value_id in value: