Files
daily_console_web/src/features/store-admin/appAisle.test.ts
2026-09-08 12:03:23 +05:30

92 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* The fold from the catalogue's 31 categories into the app's ten aisles.
*
* The stakes here are not cosmetic. `subcategoryid` is the only thing the
* customer app groups by, and a category that folds to nothing lands the
* product in "Uncategorized" — which is the state the whole platform was in.
*/
import assert from 'node:assert/strict';
import { test } from 'node:test';
import {
APP_AISLES,
FALLBACK_AISLE_IDS,
aisleForCategory,
aisleIdForCategory,
aisleIdsFrom,
} from './appAisle';
import { CATEGORY_REGISTRY, UNKNOWN_CATEGORY } from './productCategory';
const ids = aisleIdsFrom(undefined);
test('every one of the 31 categories folds into an aisle', () => {
const orphans = CATEGORY_REGISTRY.map((entry) => entry.category).filter(
(category) => aisleForCategory(category) === null,
);
assert.deepEqual(orphans, [], 'a category with no aisle is a product the app cannot show');
});
// "General" is the ladder saying it does not know. Inventing an aisle for it
// would put an unidentified product on a real shelf, which is worse than the
// app's own "Uncategorized" heading — that one at least tells the truth.
test('the unknown bucket deliberately has no aisle', () => {
assert.equal(aisleForCategory(UNKNOWN_CATEGORY), null);
assert.equal(aisleIdForCategory(UNKNOWN_CATEGORY, ids), 0);
});
test('a name that is not a category at all folds to nothing', () => {
assert.equal(aisleForCategory(''), null);
assert.equal(aisleForCategory(undefined), null);
assert.equal(aisleForCategory('Category 2'), null, 'the old default is not an aisle');
});
test('the things a shopper would look for land where they would look', () => {
assert.equal(aisleForCategory('Spices & Masalas'), 'Foodgrains & Pulses');
assert.equal(aisleForCategory('Dairy'), 'Dairy, Deli & Egg');
assert.equal(aisleForCategory('Hair Care'), 'Beauty & Personal Care');
assert.equal(aisleForCategory('Household Cleaning'), 'Hygiene Essentials');
assert.equal(aisleForCategory('Cooking Oils'), 'Oil & Ghee');
assert.equal(aisleForCategory('Biscuits & Cookies'), 'Bakes & Nuts');
});
// The registry writes an en-dash; a sheet typed by hand will not. Two strings
// that read the same must not reach different aisles.
test('dash and spacing variants reach the same aisle', () => {
assert.equal(aisleForCategory('Household – Agarbatti'), 'Hygiene Essentials');
assert.equal(aisleForCategory('Household - Agarbatti'), 'Hygiene Essentials');
assert.equal(aisleForCategory('household—agarbatti'), 'Hygiene Essentials');
assert.equal(aisleForCategory(' HEALTH CARE – ANTISEPTIC '), 'Hygiene Essentials');
});
/* ── Ids come from the platform's list, never from the wrong table ────────── */
// `productsubcategories` holds these ten names at 14-23; the app's utils list
// holds the same ten at 9-18. Matching on the name is what keeps a product out
// of the second set, which the grouping does not read.
test('ids are taken from the rows the API returned, by name', () => {
const live = aisleIdsFrom([
{ subcatid: 15, subcatname: 'Dairy, Deli & Egg', categoryid: 2 },
{ subcatid: 21, subcatname: 'Snacks & Drinks', categoryid: 2 },
]);
assert.equal(aisleIdForCategory('Dairy', live), 15);
assert.equal(aisleIdForCategory('Chocolates', live), 21);
});
// A name the API did not return has no id from it — but the aisle is still one
// of the ten, so the last-known id is better than 0, which means "no aisle".
test('a missing row falls back to the last known id rather than to zero', () => {
const partial = aisleIdsFrom([{ subcatid: 15, subcatname: 'Dairy, Deli & Egg', categoryid: 2 }]);
assert.equal(aisleIdForCategory('Cooking Oils', partial), FALLBACK_AISLE_IDS['Oil & Ghee']);
});
test('an empty response falls back to the whole known list', () => {
const empty = aisleIdsFrom([]);
assert.equal(empty.size, APP_AISLES.length);
assert.equal(aisleIdForCategory('Eggs', empty), FALLBACK_AISLE_IDS['Dairy, Deli & Egg']);
});
test('every aisle has an id, and no two share one', () => {
const values = APP_AISLES.map((aisle) => FALLBACK_AISLE_IDS[aisle]);
assert.equal(new Set(values).size, values.length);
assert.ok(values.every((id) => id > 0));
});