Skip to content

fix: categories() returned only ['APPLICATION'] — serve the canonical id list - #761

Closed
Agi-Asi wants to merge 2 commits into
facundoolano:mainfrom
Agi-Asi:fix/categories-empty-list
Closed

Agi-Asi wants to merge 2 commits into
facundoolano:mainfrom
Agi-Asi:fix/categories-empty-list

Conversation

@Agi-Asi

@Agi-Asi Agi-Asi commented Aug 27, 2026

Copy link
Copy Markdown

Problem

categories() returns just ['APPLICATION'] (#671). Google Play no longer renders the category navigation menu in the static HTML of /store/apps — it is lazy-loaded client side — so the cheerio scrape of ul li a hrefs finds nothing and only the hardcoded APPLICATION entry survives. Verified live: the store page markup contains zero matching anchors today ($('ul li a') → 0 elements).

Fix

Serve the category ids from constants.category instead of scraping. That list is already the source of truth this library maintains (it's what list() accepts), and every id maps to a live /store/apps/category/<ID> page — spot-checked APPLICATION, GAME, GAME_ACTION, ART_AND_DESIGN, WATCH_FACE, ANDROID_WEAR, FAMILY against the live store, all 200s.

The function keeps its promise-returning signature and keeps accepting (and ignoring) its options argument, so existing callers are unaffected — they just get the full 54-entry list back instead of one entry.

Notably, the existing test should have all categories from constant list of categories asserts exactly categories() ⊆ constants.category, which this implementation satisfies by construction.

Testing

  • Existing categories tests pass; the first one gains a regression guard against the single-entry degradation (length > 1, includes APPLICATION and GAME).
  • npm test: 84 passing, 0 failing; npm run lint: clean

Fixes #671

CI runs 'npm audit' as a required step, and the current lockfile fails
it with 6 vulnerabilities (3 high, 2 moderate, 1 low), all in dev-tool
transitive dependencies:

- serialize-javascript <=7.0.4 (high, RCE + DoS advisories) via mocha
- diff 5.0.0-5.2.1 (jsdiff DoS in parsePatch/applyPatch) via mocha
- js-yaml 4.0.0-4.3.0 (quadratic-CPU DoS advisories) via eslint/mocha
- brace-expansion (DoS family) via minimatch consumers
- ajv <6.14.0 (ReDoS) via eslint

None are fixable by 'npm audit fix' alone: even mocha@latest still pins
vulnerable serialize-javascript/diff ranges. Add npm 'overrides' pinning
each package to its patched line and regenerate the lockfile.

Runtime dependencies are untouched — the diff is dev-tree only, and the
full CI sequence passes clean: npm ci, npm run lint, npm test
(84 passing), npm audit (found 0 vulnerabilities).
@Agi-Asi

Agi-Asi commented Aug 27, 2026

Copy link
Copy Markdown
Author

Note: CI's npm audit step currently fails on main itself (6 dev-tree vulnerabilities), which cancelled this PR's test matrix. I've rebased this branch on top of the lockfile fix proposed in #762 so the full pipeline (lint, tests on 16/18/20, audit) can run green here. If #762 lands first this PR reduces to its own single commit; happy to rebase either way.

@Agi-Asi
Agi-Asi force-pushed the fix/categories-empty-list branch from d07b78c to f2cccef Compare August 27, 2026 09:40
… id list

Google Play no longer renders the category navigation menu in the
static HTML of /store/apps (it is lazy-loaded client side), so the
cheerio scrape of 'ul li a' hrefs found nothing and categories()
silently degraded to just ['APPLICATION'] — verified live: the store
page markup contains zero matching anchors.

Serve the category ids from constants.category instead. That list is
already the source of truth this library maintains for list()
validation, and every id maps to a live /store/apps/category/<ID>
page (spot-checked APPLICATION, GAME, GAME_ACTION, ART_AND_DESIGN,
WATCH_FACE, ANDROID_WEAR, FAMILY against the live store). The function
keeps its async signature and keeps accepting (and ignoring) options,
so existing callers are unaffected — they just get the full list back
instead of one entry.

The existing test 'should have all categories from constant list of
categories' (categories ⊆ constants.category) is now exactly
satisfied; the first test gains a regression guard against the
single-entry degradation.

Fixes facundoolano#671
@Agi-Asi
Agi-Asi force-pushed the fix/categories-empty-list branch from f2cccef to cab05a0 Compare August 27, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

categories() does not list all the categories.

2 participants