Repository navigation
groupProductDataSections: null и пустая строка в sort_order трактуются как 0, а отсутствие ключа — как «в конец» #656
Description
Проблема
groupProductDataSections() по-разному трактует «значение не задано» в зависимости от того, каким именно способом оно не задано.
vueManager/src/utils/groupProductDataSections.js:39-40:
const sortA = Number.isFinite(Number(a.sort_order)) ? Number(a.sort_order) : Number.MAX_SAFE_INTEGERNumber() даёт:
sort_order |
Number() |
результат |
|---|---|---|
0 |
0 |
в начало |
null |
0 |
в начало |
'' |
0 |
в начало |
отсутствует / undefined |
NaN |
в конец |
'abc' |
NaN |
в конец |
То есть null и пустая строка молча превращаются в приоритет 0 и уезжают в начало списка, а отсутствующий ключ — в конец. Интуитивно все три означают одно и то же «порядок не задан», и вести себя должны одинаково.
Насколько это опасно сегодня
Не опасно. На текущем источнике данных не воспроизводится:
- колонка объявлена как
null="false" default="0"(core/components/minishop3/schema/minishop3.mysql.schema.xml:562), то естьNULLв базе быть не может; ConfigService::getSections()кастует значение вint;- оба пути записи — сид-миграция
20251021000000_seed_page_sections.php(10/20/30/40) иConfigService::saveSections(), гдеsortOrder = $index— всегда проставляют осмысленное целое.
Это спящий риск, а не активный баг.
Почему всё же стоит починить
Функция вынесена в utils/ как переиспользуемая и не содержит никаких предположений об источнике данных. Первый же вызов с другим источником — ответ стороннего аддона, кэш, ручной ввод, будущий эндпоинт, отдающий null вместо 0 — даст молча неверный порядок секций без единой ошибки в консоли.
Цена починки сейчас — одна строка и один тест. Цена диагностики потом — как обычно у таких багов, несоизмеримо больше: порядок «просто неправильный», исключений нет.
Предлагаемое решение
Считать «не заданным» всё, что не является конечным числом, включая null и пустую строку:
const toSort = v => (v === null || v === '' || v === undefined || !Number.isFinite(Number(v)))
? Number.MAX_SAFE_INTEGER
: Number(v)Важно сохранить текущее корректное поведение для 0: автор верно использовал Number.isFinite, а не truthy-проверку, поэтому sort_order: 0 сейчас обрабатывается как валидное значение — эту деталь при правке не потерять.
Критерии приёмки
-
null,''и отсутствующий ключ дают одинаковый результат -
sort_order: 0по-прежнему трактуется как валидное значение и идёт в начало - Тай-брейк при одинаковом
sort_orderпо-прежнему стабилен (по числовомуid, затем по строке) - Тесты на все перечисленные случаи, включая тай-брейк — сейчас он единственная нетривиальная ветка функции без явного покрытия
Контекст
Найдено при ревью PR #620 (issue #611). Сам PR корректен и уже влит — эта находка касается граничных случаев, которые на текущих данных не возникают.
Activity