Commit cd4916b6 by cahrens

MySQL order_by is case insensitive.

Tests run with SQLlite though, which is case sensitive.
parent a8284058
...@@ -122,7 +122,7 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase): ...@@ -122,7 +122,7 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
'id': 'topic_{}'.format(i), 'id': 'topic_{}'.format(i),
'name': name, 'name': name,
'description': 'Description for topic {}.'.format(i) 'description': 'Description for topic {}.'.format(i)
} for i, name in enumerate([u'sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power']) } for i, name in enumerate([u'Sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power'])
] ]
} }
cls.test_course_1 = CourseFactory.create( cls.test_course_1 = CourseFactory.create(
...@@ -201,9 +201,8 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase): ...@@ -201,9 +201,8 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
sender=CourseTeam, sender=CourseTeam,
dispatch_uid='teams.signals.course_team_post_save_callback' dispatch_uid='teams.signals.course_team_post_save_callback'
): ):
# 'solar team' is intentionally lower case to test case insensitivity in name ordering
self.test_team_1 = CourseTeamFactory.create( self.test_team_1 = CourseTeamFactory.create(
name=u'sólar team', name=u'Sólar team',
course_id=self.test_course_1.id, course_id=self.test_course_1.id,
topic_id='topic_0' topic_id='topic_0'
) )
...@@ -445,24 +444,24 @@ class TestListTeamsAPI(TeamAPITestCase): ...@@ -445,24 +444,24 @@ class TestListTeamsAPI(TeamAPITestCase):
) )
def test_filter_topic_id(self): def test_filter_topic_id(self):
self.verify_names({'course_id': self.test_course_1.id, 'topic_id': 'topic_0'}, 200, [u'sólar team']) self.verify_names({'course_id': self.test_course_1.id, 'topic_id': 'topic_0'}, 200, [u'Sólar team'])
def test_filter_include_inactive(self): def test_filter_include_inactive(self):
self.verify_names({'include_inactive': True}, 200, ['Coal Team', 'Nuclear Team', u'sólar team', 'Wind Team']) self.verify_names({'include_inactive': True}, 200, ['Coal Team', 'Nuclear Team', u'Sólar team', 'Wind Team'])
@ddt.data( @ddt.data(
(None, 200, ['Nuclear Team', u'sólar team', 'Wind Team']), (None, 200, ['Nuclear Team', u'Sólar team', 'Wind Team']),
('name', 200, ['Nuclear Team', u'sólar team', 'Wind Team']), ('name', 200, ['Nuclear Team', u'Sólar team', 'Wind Team']),
# Note that "Nuclear Team" and "solar team" have the same open_slots. # Note that "Nuclear Team" and "Solar team" have the same open_slots.
# "solar team" comes first due to secondary sort by last_activity_at. # "Solar team" comes first due to secondary sort by last_activity_at.
('open_slots', 200, ['Wind Team', u'sólar team', 'Nuclear Team']), ('open_slots', 200, ['Wind Team', u'Sólar team', 'Nuclear Team']),
# Note that "Wind Team" and "Nuclear Team" have the same last_activity_at. # Note that "Wind Team" and "Nuclear Team" have the same last_activity_at.
# "Wind Team" comes first due to secondary sort by open_slots. # "Wind Team" comes first due to secondary sort by open_slots.
('last_activity_at', 200, [u'sólar team', 'Wind Team', 'Nuclear Team']), ('last_activity_at', 200, [u'Sólar team', 'Wind Team', 'Nuclear Team']),
) )
@ddt.unpack @ddt.unpack
def test_order_by(self, field, status, names): def test_order_by(self, field, status, names):
# Make "solar team" the most recently active team. # Make "Solar team" the most recently active team.
# The CourseTeamFactory sets the last_activity_at to a fixed time (in the past), so all of the # The CourseTeamFactory sets the last_activity_at to a fixed time (in the past), so all of the
# other teams have the same last_activity_at. # other teams have the same last_activity_at.
with skip_signal( with skip_signal(
...@@ -471,7 +470,7 @@ class TestListTeamsAPI(TeamAPITestCase): ...@@ -471,7 +470,7 @@ class TestListTeamsAPI(TeamAPITestCase):
sender=CourseTeam, sender=CourseTeam,
dispatch_uid='teams.signals.course_team_post_save_callback' dispatch_uid='teams.signals.course_team_post_save_callback'
): ):
solar_team = self.test_team_name_id_map[u'sólar team'] solar_team = self.test_team_name_id_map[u'Sólar team']
solar_team.last_activity_at = datetime.utcnow().replace(tzinfo=pytz.utc) solar_team.last_activity_at = datetime.utcnow().replace(tzinfo=pytz.utc)
solar_team.save() solar_team.save()
...@@ -810,11 +809,11 @@ class TestListTopicsAPI(TeamAPITestCase): ...@@ -810,11 +809,11 @@ class TestListTopicsAPI(TeamAPITestCase):
self.get_topics_list(400) self.get_topics_list(400)
@ddt.data( @ddt.data(
(None, 200, ['Coal Power', 'Nuclear Power', u'sólar power', 'Wind Power'], 'name'), (None, 200, ['Coal Power', 'Nuclear Power', u'Sólar power', 'Wind Power'], 'name'),
('name', 200, ['Coal Power', 'Nuclear Power', u'sólar power', 'Wind Power'], 'name'), ('name', 200, ['Coal Power', 'Nuclear Power', u'Sólar power', 'Wind Power'], 'name'),
# Note that "Nuclear Power" and "solar power" both have 2 teams. "Coal Power" and "Window Power" # Note that "Nuclear Power" and "Solar power" both have 2 teams. "Coal Power" and "Window Power"
# both have 0 teams. The secondary sort is alphabetical by name. # both have 0 teams. The secondary sort is alphabetical by name.
('team_count', 200, ['Nuclear Power', u'sólar power', 'Coal Power', 'Wind Power'], 'team_count'), ('team_count', 200, ['Nuclear Power', u'Sólar power', 'Coal Power', 'Wind Power'], 'team_count'),
('no_such_field', 400, [], None), ('no_such_field', 400, [], None),
) )
@ddt.unpack @ddt.unpack
...@@ -865,7 +864,7 @@ class TestListTopicsAPI(TeamAPITestCase): ...@@ -865,7 +864,7 @@ class TestListTopicsAPI(TeamAPITestCase):
'page': 1, 'page': 1,
'order_by': 'team_count' 'order_by': 'team_count'
}) })
self.assertEqual(["Wind Power", u'sólar power'], [topic['name'] for topic in topics['results']]) self.assertEqual(["Wind Power", u'Sólar power'], [topic['name'] for topic in topics['results']])
topics = self.get_topics_list(data={ topics = self.get_topics_list(data={
'course_id': self.test_course_1.id, 'course_id': self.test_course_1.id,
...@@ -981,7 +980,7 @@ class TestListMembershipAPI(TeamAPITestCase): ...@@ -981,7 +980,7 @@ class TestListMembershipAPI(TeamAPITestCase):
@ddt.data( @ddt.data(
('student_enrolled_both_courses_other_team', 'TestX/TS101/Test_Course', 200, 'Nuclear Team'), ('student_enrolled_both_courses_other_team', 'TestX/TS101/Test_Course', 200, 'Nuclear Team'),
('student_enrolled_both_courses_other_team', 'MIT/6.002x/Circuits', 200, 'Another Team'), ('student_enrolled_both_courses_other_team', 'MIT/6.002x/Circuits', 200, 'Another Team'),
('student_enrolled', 'TestX/TS101/Test_Course', 200, u'sólar team'), ('student_enrolled', 'TestX/TS101/Test_Course', 200, u'Sólar team'),
('student_enrolled', 'MIT/6.002x/Circuits', 400, ''), ('student_enrolled', 'MIT/6.002x/Circuits', 400, ''),
) )
@ddt.unpack @ddt.unpack
......
...@@ -361,8 +361,8 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView): ...@@ -361,8 +361,8 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
queryset = CourseTeam.objects.filter(**result_filter) queryset = CourseTeam.objects.filter(**result_filter)
order_by_input = request.QUERY_PARAMS.get('order_by', 'name') order_by_input = request.QUERY_PARAMS.get('order_by', 'name')
if order_by_input == 'name': if order_by_input == 'name':
queryset = queryset.extra(select={'lower_name': "lower(name)"}) # MySQL does case-insensitive order_by.
queryset = queryset.order_by('lower_name') queryset = queryset.order_by('name')
elif order_by_input == 'open_slots': elif order_by_input == 'open_slots':
queryset = queryset.annotate(team_size=Count('users')) queryset = queryset.annotate(team_size=Count('users'))
queryset = queryset.order_by('team_size', '-last_activity_at') queryset = queryset.order_by('team_size', '-last_activity_at')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment