@classmethod
def sort_by(cls, seq: list[Any], sort_key: str, default: str = 'title'
) -> str:
- """Sort cls list by cls.sorters[sort_key] (reverse if '-'-prefixed)."""
+ """Sort cls list by cls.sorters[sort_key] (reverse if '-'-prefixed).
+
+ Before cls.sorters[sort_key] is applied, seq is sorted by .id_, to
+ ensure predictability where parts of seq are of same sort value.
+ """
reverse = False
if len(sort_key) > 1 and '-' == sort_key[0]:
sort_key = sort_key[1:]
reverse = True
if sort_key not in cls.sorters:
sort_key = default
+ seq.sort(key=lambda x: x.id_, reverse=reverse)
sorter: Callable[..., Any] = cls.sorters[sort_key]
seq.sort(key=sorter, reverse=reverse)
if reverse:
expected = self.GET_conditions_dict([cond2, cond3, cond1])
self.check_json_get('/conditions', expected)
# test other sortings
- # (NB: by .is_active has two items of =False, their order currently
- # is not explicitly made predictable, so _may_ fail until we do)
expected['sort_by'] = '-title'
- expected['conditions'] = self.as_id_list([cond1, cond3, cond2])
+ assert isinstance(expected['conditions'], list)
+ expected['conditions'].reverse()
self.check_json_get('/conditions?sort_by=-title', expected)
expected['sort_by'] = 'is_active'
expected['conditions'] = self.as_id_list([cond1, cond2, cond3])
self.check_json_get('/conditions?sort_by=is_active', expected)
expected['sort_by'] = '-is_active'
- expected['conditions'] = self.as_id_list([cond3, cond1, cond2])
+ expected['conditions'].reverse()
self.check_json_get('/conditions?sort_by=-is_active', expected)
# test pattern matching on title
expected = self.GET_conditions_dict([cond2, cond3])