@mohasinac/appkit 4.34.0 → 4.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +32 -2
- package/dist/_internal/server/features/seo/sitemap.js +2 -2
- package/dist/_internal/server/functions/scheduled.d.ts +1 -2
- package/dist/_internal/server/functions/scheduled.js +8 -9
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +15 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +15 -6
- package/dist/_internal/server/jobs/handlers/index.d.ts +0 -1
- package/dist/_internal/server/jobs/handlers/index.js +0 -1
- package/dist/features/auth/schemas/firestore.d.ts +1 -0
- package/dist/features/tester/components/TesterChecklistStepRow.d.ts +9 -1
- package/dist/features/tester/components/TesterChecklistStepRow.js +31 -2
- package/dist/features/tester/components/TesterHubView.js +8 -0
- package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +16 -1
- package/dist/features/tester/repository/tester-checklist-item.repository.js +32 -6
- package/dist/features/tester/schemas/firestore.d.ts +109 -0
- package/dist/features/tester/schemas/firestore.js +14 -0
- package/dist/features/tester/seed-data/_money-flows.d.ts +23 -0
- package/dist/features/tester/seed-data/_money-flows.js +430 -0
- package/dist/features/tester/seed-data/authored/_types.d.ts +33 -0
- package/dist/features/tester/seed-data/authored/_types.js +35 -0
- package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +207 -0
- package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +298 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.js +33 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program.js +138 -0
- package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__address-filters.js +36 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +75 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +72 -0
- package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__state-picker.js +54 -0
- package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__unban-request.js +39 -0
- package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +226 -0
- package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +82 -0
- package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +177 -0
- package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__bundles.js +97 -0
- package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +232 -0
- package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +306 -0
- package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +158 -0
- package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +78 -0
- package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__content-deletes.js +261 -0
- package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__content-marketing.js +151 -0
- package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__coupons.js +214 -0
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +160 -0
- package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__media-watermark.js +104 -0
- package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +350 -0
- package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +105 -0
- package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__site-system.js +590 -0
- package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +235 -0
- package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__users-trust.js +569 -0
- package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__bidding.js +417 -0
- package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__browsing-search.js +653 -0
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +533 -0
- package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +379 -0
- package/dist/features/tester/seed-data/authored/buying__cart.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__cart.js +1171 -0
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +140 -0
- package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__my-orders.js +257 -0
- package/dist/features/tester/seed-data/authored/buying__offers.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__offers.js +1111 -0
- package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +252 -0
- package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__product-detail.js +387 -0
- package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__return-request.js +152 -0
- package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +242 -0
- package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__reviews.js +113 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +283 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +167 -0
- package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +90 -0
- package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +344 -0
- package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/community-support__public-profile.js +53 -0
- package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +76 -0
- package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__blog.js +93 -0
- package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +149 -0
- package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +121 -0
- package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +207 -0
- package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__events.js +318 -0
- package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +65 -0
- package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +147 -0
- package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__search.js +332 -0
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +53 -0
- package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +52 -0
- package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +35 -0
- package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +141 -0
- package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +35 -0
- package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +95 -0
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +191 -0
- package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +158 -0
- package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +106 -0
- package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +88 -0
- package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__general-design.js +204 -0
- package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +301 -0
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +407 -0
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +214 -0
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +275 -0
- package/dist/features/tester/seed-data/authored/index.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/index.js +237 -0
- package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +102 -0
- package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +50 -0
- package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +66 -0
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +115 -0
- package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +136 -0
- package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +69 -0
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +263 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +102 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +234 -0
- package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +126 -0
- package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +255 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +59 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +88 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +51 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +35 -0
- package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__become-seller.js +94 -0
- package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +107 -0
- package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +285 -0
- package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +326 -0
- package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +136 -0
- package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__media-limits.js +128 -0
- package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +167 -0
- package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +117 -0
- package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +88 -0
- package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +151 -0
- package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +105 -0
- package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-guide.js +33 -0
- package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +347 -0
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +166 -0
- package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +89 -0
- package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-orders.js +195 -0
- package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +180 -0
- package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +164 -0
- package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +116 -0
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +111 -0
- package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__og-images.js +91 -0
- package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__page-metadata.js +122 -0
- package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +105 -0
- package/dist/features/tester/seed-data/events-tester-seed-data.js +77 -5
- package/dist/features/tester/seed-data/offers-tester-seed-data.js +23 -9
- package/dist/features/tester/seed-data/products-tester-seed-data.js +65 -49
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +744 -1
- package/dist/features/tester/seed-data/tester-window.d.ts +25 -0
- package/dist/features/tester/seed-data/tester-window.js +66 -0
- package/dist/seed/carousel-slides-seed-data.js +1 -1
- package/dist/seed/products-standard-seed-data.js +2 -2
- package/dist/seed/reviews-seed-data.js +6 -1
- package/dist/seed/users-seed-data.js +107 -4
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +6 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the admin/buyer-data-admin page.
|
|
3
|
+
* WHAT: 12 case(s), keyed by full checklist id.
|
|
4
|
+
*
|
|
5
|
+
* Written by hand, case by case, against the label each one states. There is no
|
|
6
|
+
* generator: the authoring scripts were deleted once it was clear they were
|
|
7
|
+
* scaffolding around work that is simply writing.
|
|
8
|
+
*
|
|
9
|
+
* 🛑 THIS PAGE IS BUYER DATA, so two questions run through every case: can the
|
|
10
|
+
* admin READ a row before acting on it, and is more PII exposed than the task
|
|
11
|
+
* needs. Several of these listings were dead ends — a row you could see and never
|
|
12
|
+
* open — and two of them are dead ends for a legitimate reason: their list query
|
|
13
|
+
* returns a per-user summary only, so the honest fix was to route to the owning
|
|
14
|
+
* user rather than widen the payload.
|
|
15
|
+
*
|
|
16
|
+
* @tag domain:tester
|
|
17
|
+
* @tag layer:seed
|
|
18
|
+
* @tag pattern:none
|
|
19
|
+
* @tag access:server-only
|
|
20
|
+
* @tag consumers:seed-data/authored/index.ts
|
|
21
|
+
* @tag sideEffects:none
|
|
22
|
+
*/
|
|
23
|
+
export const authored = {
|
|
24
|
+
"checklist-admin-buyer-data-admin-carts-admin-view": {
|
|
25
|
+
roles: ["admin"],
|
|
26
|
+
startPage: "/admin/carts",
|
|
27
|
+
steps: [
|
|
28
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
29
|
+
"Open the admin carts listing and read every column.",
|
|
30
|
+
"Check each row identifies whose cart it is and how many items it holds.",
|
|
31
|
+
"Read whether guest carts are distinguishable from signed-in ones.",
|
|
32
|
+
"Use every filter and sort offered, confirming each changes the rows.",
|
|
33
|
+
"Search zzzznope and read the count.",
|
|
34
|
+
],
|
|
35
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
36
|
+
expectedBehaviour: "The list identifies each cart and its size. A cart document is keyed on the user id for signed-in buyers and on a session id for guests, so both kinds appear and the row has to say which it is — an unattributed row is a cart nobody can act on.",
|
|
37
|
+
expectedUiState: "Rows show an owner and an item count. Guest carts are marked as such rather than showing a blank owner. Filters and sorts change the rows and 'zzzznope' returns none.",
|
|
38
|
+
expectedData: { nonsenseResultCount: 0 },
|
|
39
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
40
|
+
},
|
|
41
|
+
"checklist-admin-buyer-data-admin-carts-admin-row-opens-items": {
|
|
42
|
+
roles: ["admin"],
|
|
43
|
+
startPage: "/admin/carts",
|
|
44
|
+
steps: [
|
|
45
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
46
|
+
"Open the admin carts listing and find a row whose item count is greater than one.",
|
|
47
|
+
"Click the row and read what opens.",
|
|
48
|
+
"Read whether the individual ITEMS are listed — titles, quantities, prices.",
|
|
49
|
+
"Read the row action menu and check it offers a view rather than only mutations.",
|
|
50
|
+
"Close and try opening a different row the same way.",
|
|
51
|
+
],
|
|
52
|
+
expectedBehaviour: "A row opens to show the cart's items. The list already computes the item count from the items array and then discards it, so the data needed to render the detail is present at list time — this is a UI wiring gap rather than a missing query, and the fix is a detail view rather than a wider payload.",
|
|
53
|
+
expectedUiState: "Clicking a row opens a detail showing each item with its title, quantity and price. A row that offers only actions, or does nothing on click, is the dead-end failure this page family exists to close.",
|
|
54
|
+
endResult: "Read-only; close without acting.",
|
|
55
|
+
},
|
|
56
|
+
"checklist-admin-buyer-data-admin-wishlists-admin-view": {
|
|
57
|
+
roles: ["admin"],
|
|
58
|
+
startPage: "/admin/wishlists",
|
|
59
|
+
steps: [
|
|
60
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
61
|
+
"Open the admin wishlists listing and read every column.",
|
|
62
|
+
"Check each row names the owning user and the number of items.",
|
|
63
|
+
"Read whether the item titles themselves are shown in the list.",
|
|
64
|
+
"Use every filter and sort offered.",
|
|
65
|
+
"Search zzzznope and read the count.",
|
|
66
|
+
],
|
|
67
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
68
|
+
expectedBehaviour: "One wishlist exists per user, so the list is one row per owner with a count. The list query deliberately returns a per-user SUMMARY rather than every item — widening it to carry each wishlist's contents would load unbounded data on a page that only needs counts.",
|
|
69
|
+
expectedUiState: "Rows name the owner and the item count. Item titles are not expected in the list itself. Filters change the rows and 'zzzznope' returns none.",
|
|
70
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
71
|
+
},
|
|
72
|
+
"checklist-admin-buyer-data-admin-wishlists-history-admin-row-opens-user": {
|
|
73
|
+
roles: ["admin"],
|
|
74
|
+
startPage: "/admin/wishlists",
|
|
75
|
+
steps: [
|
|
76
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
77
|
+
"Open the admin wishlists listing and click a row.",
|
|
78
|
+
"Read where it lands.",
|
|
79
|
+
"Check whether it opens the owning USER rather than a wishlist detail.",
|
|
80
|
+
"Go back, open the admin history listing, and click a row there.",
|
|
81
|
+
"Read where that lands.",
|
|
82
|
+
"From the user page reached, check the wishlist or history is readable in context.",
|
|
83
|
+
],
|
|
84
|
+
expectedBehaviour: "These two rows route to the owning user rather than to a per-record detail, and that is the correct answer rather than a shortcut: their list queries return only a per-user summary, so a detail view would have to fetch separately, and the user page is where the rest of that person's data already is.",
|
|
85
|
+
expectedUiState: "Both rows open the owning user's admin page. Neither is inert. From there the wishlist or history contents are reachable. A row that does nothing at all is the failure; a row routing to the user is a pass.",
|
|
86
|
+
endResult: "Read-only; close without acting.",
|
|
87
|
+
},
|
|
88
|
+
"checklist-admin-buyer-data-admin-history-admin-view": {
|
|
89
|
+
roles: ["admin"],
|
|
90
|
+
startPage: "/admin/history",
|
|
91
|
+
steps: [
|
|
92
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
93
|
+
"Open the admin browsing-history listing and read every column.",
|
|
94
|
+
"Check each row names the owning user and the number of entries.",
|
|
95
|
+
"Read the highest entry count in the list.",
|
|
96
|
+
"Use every filter and sort offered.",
|
|
97
|
+
"Search zzzznope and read the count.",
|
|
98
|
+
],
|
|
99
|
+
inputs: { nonsenseQuery: "zzzznope", historyCap: 50 },
|
|
100
|
+
expectedBehaviour: "History is one document per user, capped at fifty entries with the oldest silently evicted. So no row should report more than fifty — a higher count means the cap is not being applied on write and the document grows without bound.",
|
|
101
|
+
expectedUiState: "Rows name the owner and an entry count, and no count exceeds fifty. Filters change the rows and 'zzzznope' returns none.",
|
|
102
|
+
expectedData: { maxEntryCount: 50 },
|
|
103
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
104
|
+
},
|
|
105
|
+
"checklist-admin-buyer-data-admin-notifications-admin-view": {
|
|
106
|
+
roles: ["admin"],
|
|
107
|
+
startPage: "/admin/notifications",
|
|
108
|
+
steps: [
|
|
109
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
110
|
+
"Open the admin notifications listing and read every column.",
|
|
111
|
+
"Read every type filter offered and select each, noting any that returns nothing.",
|
|
112
|
+
"For each empty filter, check the unfiltered list for rows of that type.",
|
|
113
|
+
"Open a row's view action and read the full body and payload.",
|
|
114
|
+
"Read whether the recipient is identified.",
|
|
115
|
+
"Search zzzznope and read the count.",
|
|
116
|
+
],
|
|
117
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
118
|
+
expectedBehaviour: "Every type chip names a value notifications actually carry. The type union is a single runtime list, and for a long time the filters were built from a nine-value copy while twenty-seven types existed — eighteen were unfilterable and two could not be allow-listed for any channel at all.",
|
|
119
|
+
expectedUiState: "Every type filter returns its own rows or is empty with none unfiltered either. A row opens to show the full body and payload rather than only the title. 'zzzznope' returns none.",
|
|
120
|
+
expectedData: { nonsenseResultCount: 0 },
|
|
121
|
+
endResult: "Read-only. A chip empty while matching rows sit unfiltered is the finding, named by type.",
|
|
122
|
+
},
|
|
123
|
+
"checklist-admin-buyer-data-admin-reviews-admin-view": {
|
|
124
|
+
roles: ["admin"],
|
|
125
|
+
startPage: "/admin/reviews",
|
|
126
|
+
steps: [
|
|
127
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
128
|
+
"Open /admin/reviews and read every column, including any review images.",
|
|
129
|
+
"Check each image tile renders rather than showing a placeholder icon.",
|
|
130
|
+
"Read the search box's placeholder for how it matches.",
|
|
131
|
+
"Type a reviewer's FULL name and read the results.",
|
|
132
|
+
"Type only the first half and read the results.",
|
|
133
|
+
"Search zzzznope and read the count.",
|
|
134
|
+
"Open a review and read its full body, rating and any seller response.",
|
|
135
|
+
],
|
|
136
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
137
|
+
expectedBehaviour: "Reviewer names are PII-encrypted at rest, so they match exactly through a blind index and a partial cannot match — by design rather than omission, which is why the box must SAY so. Review images are stored as plain URL strings; a renderer expecting objects reads undefined off each and falls back to a placeholder, which makes every review photo vanish at once.",
|
|
138
|
+
expectedUiState: "Image tiles render real photos rather than placeholder icons. The full name returns rows, the partial returns none, and the box states that matching is exact. 'zzzznope' returns none.",
|
|
139
|
+
expectedData: { partialMatchCount: 0 },
|
|
140
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
141
|
+
},
|
|
142
|
+
"checklist-admin-buyer-data-admin-store-addresses-admin": {
|
|
143
|
+
roles: ["admin"],
|
|
144
|
+
startPage: "/admin/addresses",
|
|
145
|
+
steps: [
|
|
146
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
147
|
+
"Open the admin addresses listing and read every column.",
|
|
148
|
+
"Read whether store pickup addresses and buyer delivery addresses are distinguishable.",
|
|
149
|
+
"Use any owner-type filter and confirm it separates the two.",
|
|
150
|
+
"Read how names and phone numbers are displayed.",
|
|
151
|
+
"Read the sort dropdown's default and check it is one of the offered options.",
|
|
152
|
+
"Search zzzznope and read the count.",
|
|
153
|
+
],
|
|
154
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
155
|
+
expectedBehaviour: "Both kinds live in one collection discriminated by owner type, so the list must show which is which. Names, phones and street lines are PII-encrypted at rest — how much this list decrypts and displays is worth recording rather than assuming. A default sort that is not among the offered options opens the dropdown with nothing selected, which this listing family has done before.",
|
|
156
|
+
expectedUiState: "Rows identify their owner type and an owner-type filter separates them. The sort default is one of the options. 'zzzznope' returns none. Record exactly how much of each name and phone is shown.",
|
|
157
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
158
|
+
},
|
|
159
|
+
"checklist-admin-buyer-data-admin-store-addresses-admin-row-opens-detail": {
|
|
160
|
+
roles: ["admin"],
|
|
161
|
+
startPage: "/admin/addresses",
|
|
162
|
+
steps: [
|
|
163
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
164
|
+
"Open the admin addresses listing and click a store-owned row.",
|
|
165
|
+
"Read what opens and whether every field is shown, including the landmark.",
|
|
166
|
+
"Go back and click a buyer-owned row.",
|
|
167
|
+
"Read what opens there.",
|
|
168
|
+
"Check the row action menu offers a view rather than only mutations.",
|
|
169
|
+
],
|
|
170
|
+
expectedBehaviour: "A row opens to its full detail for both owner types. The landmark is the field worth naming: a form that cannot express it sends undefined and overwrites, so a detail view that never shows it hides whether the value survived.",
|
|
171
|
+
expectedUiState: "Both kinds open to a detail showing every stored field, landmark included. A view affordance exists alongside any actions. A row offering only Delete is a dead end.",
|
|
172
|
+
endResult: "Read-only; close without acting.",
|
|
173
|
+
},
|
|
174
|
+
"checklist-admin-buyer-data-admin-addresses-crud-admin": {
|
|
175
|
+
roles: ["admin"],
|
|
176
|
+
startPage: "/admin/addresses",
|
|
177
|
+
steps: [
|
|
178
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
179
|
+
"Open the admin addresses listing and create one: 'QA Address admin-crud', '13 Test Lane', Indore, Madhya Pradesh, 452010, landmark 'Beside the arena'.",
|
|
180
|
+
"Save, RELOAD, and read every field including the landmark.",
|
|
181
|
+
"Edit ONLY the street to '14 Test Lane', save, RELOAD, and read every field again.",
|
|
182
|
+
"Type abcdef into the postal code field and attempt to save.",
|
|
183
|
+
"Read where the error appears.",
|
|
184
|
+
"Delete the address and RELOAD to confirm.",
|
|
185
|
+
],
|
|
186
|
+
inputs: {
|
|
187
|
+
name: "QA Address admin-crud",
|
|
188
|
+
streetBefore: "13 Test Lane",
|
|
189
|
+
streetAfter: "14 Test Lane",
|
|
190
|
+
landmark: "Beside the arena",
|
|
191
|
+
badPostcode: "abcdef",
|
|
192
|
+
},
|
|
193
|
+
expectedBehaviour: "Create, edit and delete persist and an edit to one field leaves the rest alone. The postal code is validated by FORMAT rather than by length: a length-only rule accepts 'abcdef' as a valid six-character Indian PIN code, and one admin route did exactly that.",
|
|
194
|
+
expectedUiState: "After each reload every value holds, including the landmark after the street edit. 'abcdef' is rejected on the postal code field before any request is sent, not returned as a server error with nothing marked.",
|
|
195
|
+
endResult: "The address is deleted by the final step.",
|
|
196
|
+
},
|
|
197
|
+
"checklist-admin-buyer-data-admin-stores-admin-view": {
|
|
198
|
+
roles: ["admin"],
|
|
199
|
+
startPage: "/admin/stores",
|
|
200
|
+
steps: [
|
|
201
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
202
|
+
"Open /admin/stores and read every column and status chip.",
|
|
203
|
+
"Select each status chip in turn and read the rows returned.",
|
|
204
|
+
"Note whether the pending and suspended chips return anything.",
|
|
205
|
+
"Open a verified store's editor, change ONE unrelated field such as its description, and save.",
|
|
206
|
+
"RELOAD and read whether it is still verified, still featured, and whether its capabilities are unchanged.",
|
|
207
|
+
"Restore the description.",
|
|
208
|
+
],
|
|
209
|
+
expectedBehaviour: "🛑 This is the highest-severity case on the page. The list serializer once omitted the verified, featured, capabilities and notes fields, so the editor seeded them as undefined and the save handler sent those defaults back unconditionally — saving ANY unrelated field silently un-verified the store and reset its capabilities. The seed carries a pending and a suspended store precisely so those chips are not permanently empty.",
|
|
210
|
+
expectedUiState: "Every status chip returns rows or is genuinely empty. After the description save and reload the store is STILL verified, still featured, and its capabilities are unchanged. A store that quietly lost its verified badge is the failure, and the save reported success.",
|
|
211
|
+
expectedData: { verifiedPreserved: true },
|
|
212
|
+
endResult: "The description is restored and the store's flags are as they were. Re-read every flag after the reload, not just the one that was edited.",
|
|
213
|
+
},
|
|
214
|
+
"checklist-admin-buyer-data-admin-admin-store-detail-page": {
|
|
215
|
+
roles: ["admin"],
|
|
216
|
+
startPage: "/admin/stores",
|
|
217
|
+
steps: [
|
|
218
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
219
|
+
"Open /admin/stores and open a store's detail panel from the list.",
|
|
220
|
+
"Write down every field label it shows.",
|
|
221
|
+
"Note the store id and close the panel.",
|
|
222
|
+
"Open that store's standalone admin detail page directly by URL.",
|
|
223
|
+
"Write down every field label and compare the two lists.",
|
|
224
|
+
"Reload the standalone page and confirm it loads the same store.",
|
|
225
|
+
"Read whether the store's WhatsApp access token appears anywhere on either surface.",
|
|
226
|
+
],
|
|
227
|
+
expectedBehaviour: "The panel and the page render from one shared content component, so their fields match by construction. The store document's WhatsApp token is decrypted on every read, so any surface that does not deliberately project it is handling plaintext — an admin page is allowed to show more than a public one, but not the raw credential.",
|
|
228
|
+
expectedUiState: "Both surfaces show the same fields and the standalone page survives a reload. The access token is masked or absent on both. A field in one and not the other means a second copy of the content component has appeared.",
|
|
229
|
+
expectedData: { rawTokenShown: 0 },
|
|
230
|
+
endResult: "Read-only; nothing persists.",
|
|
231
|
+
},
|
|
232
|
+
};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the admin/catalog-listings page.
|
|
3
|
+
* WHAT: 17 case(s), keyed by full checklist id.
|
|
4
|
+
*
|
|
5
|
+
* Written by hand, case by case, against the label each one states. There is no
|
|
6
|
+
* generator: the authoring scripts were deleted once it was clear they were
|
|
7
|
+
* scaffolding around work that is simply writing.
|
|
8
|
+
*
|
|
9
|
+
* 🛑 THE ADMIN TYPE CHIPS ONCE USED DISPLAY LABELS AS FILTER VALUES, translated
|
|
10
|
+
* through an indirection map that hid two entirely missing types. A filter value
|
|
11
|
+
* is compared byte-exactly, so a chip reading "Pre-orders" against a stored
|
|
12
|
+
* "pre-order" matches nothing forever with no error. Four cases here read the
|
|
13
|
+
* chips against the real union rather than trusting the labels.
|
|
14
|
+
*
|
|
15
|
+
* Categories are the other theme: a product carries its FULL ancestor chain so a
|
|
16
|
+
* parent page can match on its own id alone, and nothing on the write side
|
|
17
|
+
* derives that chain yet.
|
|
18
|
+
*
|
|
19
|
+
* @tag domain:tester
|
|
20
|
+
* @tag layer:seed
|
|
21
|
+
* @tag pattern:none
|
|
22
|
+
* @tag access:server-only
|
|
23
|
+
* @tag consumers:seed-data/authored/index.ts
|
|
24
|
+
* @tag sideEffects:none
|
|
25
|
+
*/
|
|
26
|
+
export const authored = {
|
|
27
|
+
"checklist-admin-catalog-listings-brands-crud": {
|
|
28
|
+
roles: ["admin", "guest"],
|
|
29
|
+
startPage: "/admin/categories",
|
|
30
|
+
steps: [
|
|
31
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
32
|
+
"Open the admin brands surface and create one named 'QA Brand admin-crud' with a website, a country and a founding year.",
|
|
33
|
+
"Upload public/test-media/sample-image.png to the field labelled for the hero or cover image.",
|
|
34
|
+
"Save, RELOAD, and read every field.",
|
|
35
|
+
"Open /brands/{slug} in a private window and read the hero banner and the 'About this brand' panel.",
|
|
36
|
+
"Check the uploaded image is what renders as the hero.",
|
|
37
|
+
"Rename the brand, save, reload, and check its URL slug is unchanged.",
|
|
38
|
+
"Delete the brand and confirm it disappears from /brands.",
|
|
39
|
+
],
|
|
40
|
+
inputs: { name: "QA Brand admin-crud", image: "public/test-media/sample-image.png" },
|
|
41
|
+
expectedBehaviour: "Brands are category rows discriminated by type, not a separate collection. The image field that actually drives the public hero is the COVER image — a form once offered a 'Logo' input that fed the hero and a 'Banner' input that fed a field with no readers anywhere, so every uploaded banner was silently discarded. Website, country and founding year must render publicly rather than being accepted and never shown.",
|
|
42
|
+
expectedUiState: "After the reload every field holds. The public page's hero is the uploaded image, and the 'About this brand' panel shows the website, country and year. The slug is unchanged after the rename.",
|
|
43
|
+
endResult: "The brand is deleted. Record any field the form accepts that never appears publicly — that is a field with no reader.",
|
|
44
|
+
},
|
|
45
|
+
"checklist-admin-catalog-listings-categories-crud": {
|
|
46
|
+
roles: ["admin", "guest"],
|
|
47
|
+
startPage: "/admin/categories",
|
|
48
|
+
steps: [
|
|
49
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
50
|
+
"Open /admin/categories and read the tree, noting the two roots and how depth is shown.",
|
|
51
|
+
"Create a child category named 'QA Category admin-crud' under category-beyblade-burst.",
|
|
52
|
+
"Save, RELOAD, and read its parent, its tier and its position in the tree.",
|
|
53
|
+
"Open /categories in a private window and find it beneath its parent.",
|
|
54
|
+
"Rename it, save, reload, and check its slug is unchanged.",
|
|
55
|
+
"Delete it and confirm it disappears from the tree and from /categories.",
|
|
56
|
+
],
|
|
57
|
+
inputs: { name: "QA Category admin-crud", parent: "category-beyblade-burst" },
|
|
58
|
+
expectedBehaviour: "Creating a child places it in the tree with its full ancestor chain derived rather than hand-written — the chain, tier, path and position are all computed, and hand-writing any of them is how a tree goes inconsistent. The slug is immutable after creation, as everywhere else.",
|
|
59
|
+
expectedUiState: "After the reload the category sits under Beyblade Burst at the right depth, and it appears there publicly. Its slug survives the rename. After the delete it is gone from both surfaces.",
|
|
60
|
+
endResult: "The category is deleted by the final step.",
|
|
61
|
+
},
|
|
62
|
+
"checklist-admin-catalog-listings-products-crud": {
|
|
63
|
+
roles: ["admin", "guest"],
|
|
64
|
+
startPage: "/admin/products",
|
|
65
|
+
steps: [
|
|
66
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
67
|
+
"Open /admin/products and create a product titled 'QA Product admin-crud' at 600 with a category, a brand, stock 3 and an image.",
|
|
68
|
+
"Save, RELOAD, and read every field.",
|
|
69
|
+
"Open its public page and read the title, price, stock badge, category links and brand link.",
|
|
70
|
+
"Count the category links shown.",
|
|
71
|
+
"Edit ONLY the price to 700, save, RELOAD, and compare every other field.",
|
|
72
|
+
"Delete the product and confirm the public page no longer resolves.",
|
|
73
|
+
],
|
|
74
|
+
inputs: { title: "QA Product admin-crud", priceBefore: 600, priceAfter: 700, stock: 3 },
|
|
75
|
+
expectedBehaviour: "An admin create and edit round-trip, and an edit writes back only what changed. The category link count is worth recording: a product is supposed to carry its full ancestor chain so every ancestor page can find it, and nothing on the write side derives that chain — so a product created through a form against a deep category gets ONE slug and is invisible on every ancestor page.",
|
|
76
|
+
expectedUiState: "After each reload the values hold and only the price differs after the edit. Record how many category links the public page shows — one, where the chosen category has ancestors, is the known gap rather than a surprise. After the delete the public URL no longer resolves.",
|
|
77
|
+
expectedData: { unintendedFieldChanges: 0 },
|
|
78
|
+
endResult: "The product is deleted. Report the category link count either way.",
|
|
79
|
+
},
|
|
80
|
+
"checklist-admin-catalog-listings-products-default-listing-not-empty": {
|
|
81
|
+
roles: ["admin"],
|
|
82
|
+
startPage: "/admin/products",
|
|
83
|
+
steps: [
|
|
84
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
85
|
+
"Open /admin/products with NO query parameters at all.",
|
|
86
|
+
"Read the result count and the rows.",
|
|
87
|
+
"Read which availability scope and which status filter are applied by default.",
|
|
88
|
+
"Switch to the All scope and compare the count.",
|
|
89
|
+
"Clear every filter and compare again.",
|
|
90
|
+
],
|
|
91
|
+
expectedBehaviour: "The admin listing opens showing rows. This page shares one query implementation with the public browse path, reached through a sentinel that lets any status through — so an admin listing that opens empty usually means a filter default meant for the public path is being applied here, where an admin needs to see drafts and archived rows too.",
|
|
92
|
+
expectedUiState: "The default view holds rows rather than an empty state. The All scope returns at least as many. An empty default listing with rows appearing only after clearing filters is the failure.",
|
|
93
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
94
|
+
},
|
|
95
|
+
"checklist-admin-catalog-listings-categories-toggle-filters": {
|
|
96
|
+
roles: ["admin"],
|
|
97
|
+
startPage: "/admin/categories",
|
|
98
|
+
steps: [
|
|
99
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
100
|
+
"Open /admin/categories and note the total row count.",
|
|
101
|
+
"Read every toggle and filter offered above the list.",
|
|
102
|
+
"Use each in turn and read the resulting count and rows.",
|
|
103
|
+
"Write down any toggle that leaves the count unchanged.",
|
|
104
|
+
"Clear everything and confirm the original count returns.",
|
|
105
|
+
],
|
|
106
|
+
expectedBehaviour: "Every toggle changes the list. A toggle that renders, counts toward the filter badge and matches nothing is inert — that happens when it reads a field the document does not have, and nothing raises. Category rows carry a type discriminator, so filters separating categories from brands, bundles and sublistings are the ones most likely to be reading the wrong field.",
|
|
107
|
+
expectedUiState: "Each toggle visibly changes the rows. A toggle leaving the count identical while incrementing the filter badge is the failure, named specifically.",
|
|
108
|
+
expectedData: { inertToggles: 0 },
|
|
109
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
110
|
+
},
|
|
111
|
+
"checklist-admin-catalog-listings-admin-products-type-chips-all-types": {
|
|
112
|
+
roles: ["admin"],
|
|
113
|
+
startPage: "/admin/products",
|
|
114
|
+
steps: [
|
|
115
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
116
|
+
"Open /admin/products and read every listing-type chip offered.",
|
|
117
|
+
"Write the list down and compare it against the nine types the catalogue supports.",
|
|
118
|
+
"Select each chip in turn and read the result count and the rows.",
|
|
119
|
+
"Write down any chip returning zero rows, and any returning the full unfiltered list.",
|
|
120
|
+
"Check whether a chip for `bundle` is offered.",
|
|
121
|
+
],
|
|
122
|
+
expectedBehaviour: "Nine chips, each filtering to its own type. The chips once used display LABELS as filter values through an indirection map that hid two missing types entirely — and a filter value is compared byte-exactly, so a chip reading 'Pre-orders' against a stored 'pre-order' matches nothing forever. A chip for `bundle` must NOT exist: it stopped being a listing type and would match zero rows permanently.",
|
|
123
|
+
expectedUiState: "Nine chips are offered and each returns only its own type. No `bundle` chip. A chip returning zero while that type demonstrably exists is the byte-exactness failure; one returning everything is the dropped-filter failure.",
|
|
124
|
+
expectedData: { typeChipCount: 9 },
|
|
125
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
126
|
+
},
|
|
127
|
+
"checklist-admin-catalog-listings-admin-products-type-chips-multi-select": {
|
|
128
|
+
roles: ["admin"],
|
|
129
|
+
startPage: "/admin/products",
|
|
130
|
+
steps: [
|
|
131
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
132
|
+
"Open /admin/products and tick the Auctions chip, reading the count.",
|
|
133
|
+
"Tick Pre-orders as well and read the count.",
|
|
134
|
+
"Check the count is the sum of the two rather than either alone.",
|
|
135
|
+
"Read the URL and check it encodes both types.",
|
|
136
|
+
"Open the sort dropdown and read which options are offered with two types selected.",
|
|
137
|
+
"Untick both and confirm the unfiltered count returns.",
|
|
138
|
+
],
|
|
139
|
+
expectedBehaviour: "Multiple type chips form an OR, so selecting two returns both sets. The alias layer has to split a joined value before looking each part up — testing the whole joined string as one token returns an empty value that is then dropped, so the filter vanishes and the page shows everything. The sort dropdown narrows to options valid for every selected type, since a sort valid for one alone would fail the others.",
|
|
140
|
+
expectedUiState: "Two chips ticked returns the sum of their individual counts, and the URL carries both. The sort dropdown offers only sorts common to both. A combined selection returning the FULL unfiltered list is the dropped-filter failure.",
|
|
141
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
142
|
+
},
|
|
143
|
+
"checklist-admin-catalog-listings-admin-products-featured-promoted-sorts": {
|
|
144
|
+
roles: ["admin"],
|
|
145
|
+
startPage: "/admin/products",
|
|
146
|
+
steps: [
|
|
147
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
148
|
+
"Open /admin/products and read the sort dropdown's options.",
|
|
149
|
+
"Select 'Featured first' and read the row order.",
|
|
150
|
+
"Select 'Promoted first' and read the row order.",
|
|
151
|
+
"Compare both against the default order.",
|
|
152
|
+
"Reload with one applied and read the order on first paint.",
|
|
153
|
+
],
|
|
154
|
+
expectedBehaviour: "Both sorts reorder the rows. A sort whose field is not marked sortable is dropped before the query runs, so the dropdown changes and nothing moves — these two shipped exactly that way and went unreported, because a sort that does nothing looks like a list already in that order.",
|
|
155
|
+
expectedUiState: "Featured rows rise under the first and promoted under the second, and both differ from the default. After a reload the chosen order holds on first paint rather than re-sorting a moment later.",
|
|
156
|
+
expectedData: { inertSortOptions: 0 },
|
|
157
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
158
|
+
},
|
|
159
|
+
"checklist-admin-catalog-listings-admin-per-type-pages-have-filters": {
|
|
160
|
+
roles: ["admin"],
|
|
161
|
+
startPage: "/admin/products",
|
|
162
|
+
steps: [
|
|
163
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
164
|
+
"Open each per-type admin listing in turn — auctions, pre-orders, prize draws, classifieds, digital codes, live items, art and stickers.",
|
|
165
|
+
"On each, read the filters offered and note whether any are specific to that type.",
|
|
166
|
+
"Use each type-specific filter and confirm it changes the rows.",
|
|
167
|
+
"Write down any page offering no filters at all.",
|
|
168
|
+
"Write down any filter that changes nothing.",
|
|
169
|
+
],
|
|
170
|
+
expectedBehaviour: "Each type's page offers the facets that type actually has — a classified's city, a live item's species, an auction's bid range — on top of the shared ones. A facet that renders and matches nothing is inert, which happens when it emits a field the query allowlist does not carry, and nothing raises.",
|
|
171
|
+
expectedUiState: "Every per-type page offers filters including its own, and each visibly changes the rows. A page with no filters, or a filter that leaves the count identical while incrementing the badge, are both findings named by page.",
|
|
172
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
173
|
+
},
|
|
174
|
+
"checklist-admin-catalog-listings-admin-listing-reset-restores-defaults": {
|
|
175
|
+
roles: ["admin"],
|
|
176
|
+
startPage: "/admin/products",
|
|
177
|
+
steps: [
|
|
178
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
179
|
+
"Open /admin/products and note the default count, scope and sort.",
|
|
180
|
+
"Apply a search term, two type chips, a status filter and a different sort.",
|
|
181
|
+
"Read the URL and the count.",
|
|
182
|
+
"Use the reset control.",
|
|
183
|
+
"Read the URL, the count, the scope, the sort and every filter control.",
|
|
184
|
+
"Reload and read them again.",
|
|
185
|
+
],
|
|
186
|
+
expectedBehaviour: "Reset returns every control AND the URL to the defaults, not just the visible chips. A reset that clears the drawer while leaving the search term or the sort in the URL produces a list the controls no longer describe.",
|
|
187
|
+
expectedUiState: "After reset the count, scope and sort match the untouched defaults and the URL carries no leftover parameters. The search box is empty. Reloading reproduces the default view.",
|
|
188
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
189
|
+
},
|
|
190
|
+
"checklist-admin-catalog-listings-admin-address-payment-status-chips-in-url": {
|
|
191
|
+
roles: ["admin"],
|
|
192
|
+
startPage: "/admin/addresses",
|
|
193
|
+
steps: [
|
|
194
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
195
|
+
"Open /admin/addresses and select a status chip.",
|
|
196
|
+
"Read the URL and check it encodes the selection.",
|
|
197
|
+
"Copy the URL, open it in a new tab, and read which chip is active on arrival.",
|
|
198
|
+
"Press the browser back button and read which chip is active.",
|
|
199
|
+
"Repeat all of this on the admin payment-methods listing.",
|
|
200
|
+
],
|
|
201
|
+
expectedBehaviour: "Chip state lives in the URL on both listings, so a filtered view is shareable and the back button walks the selections. A chip held in component state alone makes the URL describe a different page from the one on screen.",
|
|
202
|
+
expectedUiState: "Both listings encode the chip in the URL, the copied URL arrives with the same chip active, and back returns to the previous selection. One press per selection — two presses to undo one chip is the double-navigation failure.",
|
|
203
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
204
|
+
},
|
|
205
|
+
"checklist-admin-catalog-listings-admin-listing-sort-dropdown-preselected": {
|
|
206
|
+
roles: ["admin"],
|
|
207
|
+
startPage: "/admin/products",
|
|
208
|
+
steps: [
|
|
209
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
210
|
+
"Open /admin/products with no query parameters and read the sort dropdown's selection.",
|
|
211
|
+
"Check something is selected rather than the control being blank.",
|
|
212
|
+
"Confirm the selected option is one of the options the dropdown offers.",
|
|
213
|
+
"Repeat on /admin/orders, /admin/addresses and the admin payment-methods listing.",
|
|
214
|
+
"Write down any listing whose dropdown opens with nothing selected.",
|
|
215
|
+
],
|
|
216
|
+
expectedBehaviour: "A listing's default sort is one of the options it offers. Where the default names a field the dropdown does not list, the control opens blank — the list IS sorted, but nothing on screen says how, and two of these listings shipped exactly that way.",
|
|
217
|
+
expectedUiState: "Every listing opens with a sort visibly selected and that selection is among its own options. A blank dropdown is the failure, named by listing.",
|
|
218
|
+
endResult: "Read-only; nothing persists.",
|
|
219
|
+
},
|
|
220
|
+
"checklist-admin-catalog-listings-sublisting-categories-crud": {
|
|
221
|
+
roles: ["admin", "guest"],
|
|
222
|
+
startPage: "/admin/categories",
|
|
223
|
+
steps: [
|
|
224
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
225
|
+
"Open the admin sublisting-categories surface and read the existing rows.",
|
|
226
|
+
"Create one named 'QA Sublisting admin-crud' with a description and save.",
|
|
227
|
+
"RELOAD and read every field.",
|
|
228
|
+
"Rename it, save, RELOAD, and read the derived page title and description.",
|
|
229
|
+
"Check they reflect the NEW name rather than the original.",
|
|
230
|
+
"Delete it and confirm it is gone.",
|
|
231
|
+
],
|
|
232
|
+
inputs: { name: "QA Sublisting admin-crud" },
|
|
233
|
+
expectedBehaviour: "Derived page metadata is recomputed on rename. Deriving it only at creation freezes the title and description at the original name, so the page keeps describing itself as something it is no longer called — a create-time transform the update path does not repeat.",
|
|
234
|
+
expectedUiState: "After the rename and reload both the name and the derived title and description reflect the new name. Metadata still naming the original is the failure.",
|
|
235
|
+
endResult: "The sublisting category is deleted by the final step.",
|
|
236
|
+
},
|
|
237
|
+
"checklist-admin-catalog-listings-carousel-crud": {
|
|
238
|
+
roles: ["admin", "guest"],
|
|
239
|
+
startPage: "/admin/carousels",
|
|
240
|
+
steps: [
|
|
241
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
242
|
+
"Open /admin/carousels and read what the page lists.",
|
|
243
|
+
"Check it lists NAMED carousels rather than rendering a flat slide editor.",
|
|
244
|
+
"Create a carousel named 'QA Carousel admin-crud' and add a slide with a title, an image and a link.",
|
|
245
|
+
"Save, RELOAD, and read the carousel's name, status and its slide.",
|
|
246
|
+
"Set it active and open / in a private window to find it.",
|
|
247
|
+
"Count the active carousels and check the cap is respected.",
|
|
248
|
+
"Delete the carousel.",
|
|
249
|
+
],
|
|
250
|
+
inputs: { name: "QA Carousel admin-crud", maxActive: 5 },
|
|
251
|
+
expectedBehaviour: "The list page lists named carousels — it once rendered the flat slide editor instead, so there was no list at all. At most five may be active at once, and a slide's background may be an image, a video, a colour or a gradient; a video background renders through a real video element, so its URL must be directly playable rather than routed through the image proxy, which rejects video outright.",
|
|
252
|
+
expectedUiState: "The page lists named carousels. After the reload the carousel holds its name, status and slide. Activating it shows it publicly. Attempting a sixth active carousel is refused rather than silently accepted.",
|
|
253
|
+
endResult: "The carousel is deleted by the final step.",
|
|
254
|
+
},
|
|
255
|
+
"checklist-admin-catalog-listings-sections-crud": {
|
|
256
|
+
roles: ["admin", "guest"],
|
|
257
|
+
startPage: "/admin",
|
|
258
|
+
steps: [
|
|
259
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
260
|
+
"Open the homepage sections editor and read every section, its type and its order.",
|
|
261
|
+
"Create a section, choosing a type, and configure every field it offers.",
|
|
262
|
+
"Save, RELOAD, and read every field back.",
|
|
263
|
+
"Open / in a private window and find the new section in the right position.",
|
|
264
|
+
"Change ONE field, save, RELOAD, and check every other field is unchanged.",
|
|
265
|
+
"Delete the section and confirm it disappears from the public homepage.",
|
|
266
|
+
],
|
|
267
|
+
expectedBehaviour: "A section round-trips every field its type offers, and the public homepage reflects its configuration and position. Saving one field must not rewrite the others — a form submitting its whole object from partly-populated state blanks every field it did not load, and the save reports success.",
|
|
268
|
+
expectedUiState: "After each reload every field holds and only the edited one differs. The public homepage shows the section in its configured position and with its configured content. After the delete it is gone publicly.",
|
|
269
|
+
expectedData: { unintendedFieldChanges: 0 },
|
|
270
|
+
endResult: "The section is deleted by the final step.",
|
|
271
|
+
},
|
|
272
|
+
"checklist-admin-catalog-listings-art-stickers-crud": {
|
|
273
|
+
roles: ["admin", "guest"],
|
|
274
|
+
startPage: "/admin/products",
|
|
275
|
+
steps: [
|
|
276
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
277
|
+
"Create an art listing titled 'QA Art Print admin-crud' at 700 with a size, material, finish and edition size.",
|
|
278
|
+
"Save, RELOAD, and read all four print fields.",
|
|
279
|
+
"Open the admin listing filtered to art and check the listing appears there.",
|
|
280
|
+
"Read every other row in that filtered view and check none is an ordinary product.",
|
|
281
|
+
"Open the public art tab and check the listing appears there too.",
|
|
282
|
+
"Delete the listing.",
|
|
283
|
+
],
|
|
284
|
+
inputs: { title: "QA Art Print admin-crud", price: 700 },
|
|
285
|
+
expectedBehaviour: "Art and stickers are real listing types with their own fields and their own filter value. They were added to the type union and the plugin registry without being added to the repository's alias map, so their queries ran with NO type filter — the filtered view rendered and returned the whole catalogue, which looks like a working page.",
|
|
286
|
+
expectedUiState: "The print fields round-trip. The art-filtered admin view holds only art listings — an ordinary Beyblade product among them is the dropped-filter failure. The public art tab shows it too.",
|
|
287
|
+
expectedData: { ordinaryProductsInFilteredView: 0 },
|
|
288
|
+
endResult: "The listing is deleted by the final step.",
|
|
289
|
+
},
|
|
290
|
+
"checklist-admin-catalog-listings-deals-featured-crud": {
|
|
291
|
+
roles: ["admin", "guest"],
|
|
292
|
+
startPage: "/admin/products",
|
|
293
|
+
steps: [
|
|
294
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
295
|
+
"Open /admin/products and open a product's editor.",
|
|
296
|
+
"Set its featured flag on and save.",
|
|
297
|
+
"RELOAD and confirm the flag is still on.",
|
|
298
|
+
"Open / in a private window and find the product in a featured section.",
|
|
299
|
+
"Set the promoted or on-sale flag on, save, reload, and check the public surface that flag drives.",
|
|
300
|
+
"Turn both flags back off, save, and confirm the product leaves those surfaces.",
|
|
301
|
+
],
|
|
302
|
+
expectedBehaviour: "Featured, promoted and on-sale flags reach the public surfaces they drive, in both directions. Turning a flag off must remove the product from its section — a flag that only ever adds is half a flag, and the homepage sections that read them filter by availability too, so a sold-out featured product should not appear.",
|
|
303
|
+
expectedUiState: "Each flag survives its reload and its public surface follows it on and off. The product appears in the featured section when flagged and leaves when unflagged.",
|
|
304
|
+
endResult: "Both flags are off by the final step, so the seeded product is left as it was.",
|
|
305
|
+
},
|
|
306
|
+
};
|