Skip to content

test(api): cover canonical url-slug redirects for datasets, AI models, use cases (DataSpaceFrontend#524, #525) - #253

Merged
saqibmanan merged 1 commit into
CIfrom
test-sync/DataSpaceFrontend-pr525
Nov 13, 2026
Merged

saqibmanan merged 1 commit into
CIfrom
test-sync/DataSpaceFrontend-pr525

Conversation

@saqibmanan

@saqibmanan saqibmanan commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Source

Both on the same provider-flow-update branch, ~80 minutes apart. #525 is a same-day refactor of #524's own feature (moves queries into queries.ts files, deletes lib/canonical-redirect.ts, simplifies the redirect condition to fire only for a legacy integer/UUID id). Treated as one coverage unit: what matters is the behaviour that survived into the final, deployed state, not either diff in isolation.

Confirmed deployed: DataSpaceFrontend "Deploy DataSpace" run for the #525 merge commit (run 42182886658) completed with promote → success and rollback → skipped. Live on dev now.

What actually changed (from the diff, not the titles)

lib/public-link.ts (new) introduces isUuid, isIntegerId, publicHref, publicPageUrl, datasetLookup, aiModelLookup. Applied to:

  • Canonical redirects: /datasets/[datasetIdentifier], /aimodels/[modelId], /usecases/[useCaseSlug] now 308-redirect a legacy raw id (dataset UUID, AI model/use case integer id) to /<section>/<urlSlug>. Visiting the urlSlug address directly serves with no further redirect.
  • Listing/card links: home Datasets/UseCases, ListingComponent, publishers' Datasets/UseCases, search's UnifiedListingComponent, dataset SimilarDatasets/DatasetConnected, usecase DatasetStories, the AI model/use case publish-preview links, and the collaboratives detail page all switched from linking by raw id to urlSlug (falling back to id).
  • Sitemap route (app/sitemap/[entityPage]/route.ts): dataset/aimodel/usecase <url><loc> entries switched from raw id to urlSlug.
  • A correctness fix bundled into the same unit: DatasetDetailsPage's chart-count query and analytics trackDataset call now wait for the dataset's real UUID (recordId, from the GraphQL response) instead of firing on whatever string is in the URL — needed because that URL segment can now be a slug, not a UUID.

Categories added, and why

Per the test-sync policy's §3 (new/changed UI page behaviour → smoke, +functional), and since the whole user-visible surface here is "does the right page load at the right address" — a smoke-level concern. Added to tests/api/smoke/test_api_053_canonical_url_slug_redirect.py:

  • test_dataset_legacy_id_redirects_to_canonical_slug
  • test_aimodel_legacy_id_redirects_to_canonical_slug
  • test_usecase_legacy_id_redirects_to_canonical_slug
  • test_dataset_canonical_slug_serves_without_redirecting
  • test_aimodel_canonical_slug_serves_without_redirecting
  • test_usecase_canonical_slug_serves_without_redirecting

All unauthenticated (public detail pages, no login) — this run has no test credentials, so coverage is scoped to what can be proven without them.

Not readonly: git merge-base --is-ancestor 8c4d7c62a7d555870677c9c4e76a638fdc2e7e9e origin/main on DataSpaceFrontend is false — this hasn't shipped to main/prod. Prod's backend GraphQL schema doesn't even have a urlSlug field yet (Cannot query field 'urlSlug' on type 'TypeDataset', confirmed live against api.datakeep.civicdays.in). Marking this readonly would fail every DataSpaceBackend/DataSpaceFrontend main deploy's smoke gate until the backend half ships too. Gated with deployed_pr("DataSpaceFrontend#525", site="HOME_URL_DEV") instead — skips wherever the frontend under test doesn't yet serve the merge commit, and turns on by itself once it does. Follow-up: add readonly once #525 is on main.

Red → green proof

GREEN, today, on dev (HOME_URL_DEV=https://dev.civicdataspace.in API_BASE_URL=https://dev.api.civicdataspace.in):

tests/api/smoke/test_api_053_canonical_url_slug_redirect.py::test_dataset_legacy_id_redirects_to_canonical_slug PASSED
tests/api/smoke/test_api_053_canonical_url_slug_redirect.py::test_aimodel_legacy_id_redirects_to_canonical_slug PASSED
tests/api/smoke/test_api_053_canonical_url_slug_redirect.py::test_usecase_legacy_id_redirects_to_canonical_slug PASSED
tests/api/smoke/test_api_053_canonical_url_slug_redirect.py::test_dataset_canonical_slug_serves_without_redirecting PASSED
tests/api/smoke/test_api_053_canonical_url_slug_redirect.py::test_aimodel_canonical_slug_serves_without_redirecting PASSED
tests/api/smoke/test_api_053_canonical_url_slug_redirect.py::test_usecase_canonical_slug_serves_without_redirecting PASSED
6 passed in 7.69s

RED, today, on prod (HOME_URL_DEV=https://civicdataspace.in API_BASE_URL=https://api.datakeep.civicdays.in), which still runs the pre-#524 code — a real "parent commit" red, not a flipped assertion. Ran with the deployed_pr marker temporarily stripped locally (restored before committing — final diff has no test-content changes, only the marker gate):

FAILED test_dataset_legacy_id_redirects_to_canonical_slug
  AssertionError: expected a 308 permanent redirect off the raw dataset id 'd4134c28-1b40-4e16-a3c0-cecd672e9cfc', got 200.
FAILED test_aimodel_legacy_id_redirects_to_canonical_slug
  AssertionError: expected a 308 permanent redirect off the raw AI model id 46, got 200.
FAILED test_usecase_legacy_id_redirects_to_canonical_slug
  AssertionError: expected a 308 permanent redirect off the raw use case id '314', got 200.
3 failed in 3.49s

(Only the 3 legacy-id tests are schema-safe to point at prod — the 3 canonical-slug tests query urlSlug in their fixtures, which doesn't exist on prod's backend schema, so they're dev-only by construction and weren't part of the red run.)

With the deployed_pr marker restored and pointed at prod, the 3 legacy-id tests correctly skip instead of failing: deployed_pr DataSpaceFrontend#525: https://civicdataspace.in runs 92cd5219, which doesn't include 8c4d7c62 yet — confirming the gate itself works.

Collection check, matching run-smoke.yml's real pull_request filter (tests/api/smoke -m smoke):

$ pytest tests/api/smoke -m "smoke" --collect-only -q | grep 053
<all 6 tests listed>

Gaps — deliberately not covered here

  • Listing/card links now use urlSlug (home, search, publishers, SimilarDatasets, DatasetConnected, DatasetStories, collaboratives) — this is React-client-rendered (confirmed: curl'ing /datasets returns no server-rendered href in the initial HTML), so checking it needs a real browser, not an HTTP client. This cloud run has no credentials but these are public pages, so a browser check wouldn't need any — it's simply out of scope for an HTTP-only unauthenticated pass. A local/authenticated run should add a Selenium check (existing locators//pages/ Page Objects for dataset/use case listing cards) asserting card hrefs end in the item's urlSlug, not its raw id.
  • Sitemap route's switch to urlSlug (app/sitemap/[entityPage]/route.ts) — untestable right now: dev's sitemap is disabled by design (DataSpaceFrontend#493, covered by test_api_027_dev_noindex.py; confirmed live: /sitemap.xml on dev returns "Sitemaps are not enabled"), and the feature isn't on prod yet either. Once #525 (or whichever PR carries it) reaches main, extend test_api_006_seo_sitemap.py's prod checks to assert dataset/aimodel/usecase <url><loc> entries end in the backend's urlSlug, cross-checked per record, not just that the count matches.
  • DatasetDetailsPage's chart-count/analytics fix (waiting for recordId before firing) — a real bug fix bundled into this diff, but it only matters once a dataset is reached by its slug (which the canonical-redirect tests above already exercise end-to-end as part of a normal page load); no separate assertion added, since the existing chart-count and analytics calls aren't independently observable without a browser and TanStack Query internals.
  • No regression marker used: regression is never selected by any CI event here (deselected on push/PR/dispatch alike), so a regression-only test would merge and silently never run. Everything above carries smoke + api instead.

Safe to merge

Yes — not gated on the backend shipping anything further; deployed_pr handles the only real hazard (dev rolling back or not yet carrying #525), and this file is not readonly so it never touches the main-deploy prod gate.

@saqibmanan saqibmanan self-assigned this Nov 12, 2026
@saqibmanan
saqibmanan force-pushed the test-sync/DataSpaceFrontend-pr525 branch from 4bbb145 to fd645bf Compare November 13, 2026 19:03
@saqibmanan
saqibmanan marked this pull request as ready for review November 13, 2026 19:36
@saqibmanan
saqibmanan merged commit 2899013 into CI Nov 13, 2026
6 checks passed
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.

1 participant