@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,151 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the admin/content-marketing page.
|
|
3
|
+
* WHAT: 7 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 ADS SETTINGS WERE WRITTEN BY THE ADMIN FORM WHILE UNDECLARED ON THE
|
|
10
|
+
* SETTINGS TYPE, which is how a whole group escapes every type-driven review —
|
|
11
|
+
* provider credentials and every draft, paused and scheduled ad went out through
|
|
12
|
+
* an unauthenticated public endpoint, unmasked and invisible to any reader
|
|
13
|
+
* checking the interface. Two cases here read the PUBLIC response rather than the
|
|
14
|
+
* admin form.
|
|
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-content-marketing-ads-crud-preview": {
|
|
25
|
+
roles: ["admin", "guest"],
|
|
26
|
+
startPage: "/admin/ads",
|
|
27
|
+
steps: [
|
|
28
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
29
|
+
"Open the admin ads surface and read every existing ad, its status and its provider settings.",
|
|
30
|
+
"Create an ad named 'QA Ad crud-preview' in a DRAFT state, with a placement and any provider credential field filled in.",
|
|
31
|
+
"Save, RELOAD, and read every field including how the credential is displayed.",
|
|
32
|
+
"Use the preview and read what it renders.",
|
|
33
|
+
"Open / in a private window and check the draft ad is NOT rendered anywhere.",
|
|
34
|
+
"Open that page's source and search for the ad's name and for the credential value.",
|
|
35
|
+
"Delete the ad.",
|
|
36
|
+
],
|
|
37
|
+
inputs: { name: "QA Ad crud-preview", status: "draft" },
|
|
38
|
+
expectedBehaviour: "A draft ad is invisible publicly and its provider credentials never leave the server. The ads group was written by the admin form while undeclared on the settings type, so it was published wholesale by an unauthenticated endpoint — including drafts and unmasked credentials — and nothing type-driven could see it.",
|
|
39
|
+
expectedUiState: "The ad round-trips with its credential MASKED in the admin form. The public page does not render it and its source contains neither the ad's name nor the credential value. A draft appearing publicly, or a credential in the source, is a leak rather than a display bug.",
|
|
40
|
+
expectedData: { credentialInPublicSource: 0 },
|
|
41
|
+
endResult: "The ad is deleted by the final step.",
|
|
42
|
+
},
|
|
43
|
+
"checklist-admin-content-marketing-newsletter-export-admin": {
|
|
44
|
+
roles: ["admin"],
|
|
45
|
+
startPage: "/admin/newsletter",
|
|
46
|
+
steps: [
|
|
47
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
48
|
+
"Open the admin newsletter surface and read the subscriber count and the rows.",
|
|
49
|
+
"Read whether subscriber email addresses are shown in full or masked.",
|
|
50
|
+
"Trigger the export and read what the page does immediately.",
|
|
51
|
+
"Navigate away and back, then read whether the export's progress is still reported.",
|
|
52
|
+
"Wait for it to finish and open the exported file.",
|
|
53
|
+
"Compare the file's row count against the subscriber count shown.",
|
|
54
|
+
],
|
|
55
|
+
expectedBehaviour: "The export runs as a background job rather than inside the request — an unbounded scan of every subscriber is exactly the shape that dies at the ten-second function ceiling in production while a small local list passes. The page subscribes to the job's progress instead of waiting on a response.",
|
|
56
|
+
expectedUiState: "The export returns immediately with a job accepted rather than freezing the page. Progress survives navigating away and back. The finished file's row count matches the subscriber count. A request that hangs and then times out is the failure.",
|
|
57
|
+
endResult: "An export file exists. Note whether subscriber emails are exposed in the LIST as well as in the file — the file is expected to carry them, the list is a judgement.",
|
|
58
|
+
},
|
|
59
|
+
"checklist-admin-content-marketing-contact-submissions-admin": {
|
|
60
|
+
roles: ["admin", "guest"],
|
|
61
|
+
startPage: "/contact",
|
|
62
|
+
steps: [
|
|
63
|
+
"Open /contact in a private window and submit a message: name 'QA Contact submissions-admin', email qa-contact-admin@mailnull.com, subject 'Checklist submission', message 'Sent by the tester checklist.'.",
|
|
64
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
65
|
+
"Open the admin contact submissions surface and find that message.",
|
|
66
|
+
"Read every field of it and check the full message body is readable from the list or a detail view.",
|
|
67
|
+
"Read the row actions offered and check at least one lets you VIEW rather than only act.",
|
|
68
|
+
"Use any status control to mark it handled, then RELOAD and read the status.",
|
|
69
|
+
"Search zzzznope and read the result count.",
|
|
70
|
+
],
|
|
71
|
+
inputs: {
|
|
72
|
+
name: "QA Contact submissions-admin",
|
|
73
|
+
email: "qa-contact-admin@mailnull.com",
|
|
74
|
+
message: "Sent by the tester checklist.",
|
|
75
|
+
},
|
|
76
|
+
expectedBehaviour: "A submitted message arrives in the admin surface with its full body readable. This is the round trip the contact form's own case cannot prove — a form that shows a confirmation and delivers nothing looks identical to one that works, from the sender's side.",
|
|
77
|
+
expectedUiState: "The submission appears with its name, email, subject and full body. A view affordance exists alongside any actions. The status change survives a reload. 'zzzznope' returns zero rows rather than the full list.",
|
|
78
|
+
expectedData: { nonsenseResultCount: 0 },
|
|
79
|
+
endResult: "The submission remains, marked handled. Its arrival is the assertion — a missing message means the contact form delivers nowhere.",
|
|
80
|
+
},
|
|
81
|
+
"checklist-admin-content-marketing-media-library-admin": {
|
|
82
|
+
roles: ["admin"],
|
|
83
|
+
startPage: "/admin/media",
|
|
84
|
+
steps: [
|
|
85
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
86
|
+
"Open the admin media library and read the grid.",
|
|
87
|
+
"Check every tile renders its image rather than an empty bordered box.",
|
|
88
|
+
"Read the filter and sort controls and use each, confirming the results change.",
|
|
89
|
+
"Search for a known filename, then search zzzznope and read the count.",
|
|
90
|
+
"Open one item and read its detail — filename, dimensions, where it is used.",
|
|
91
|
+
"Read whether any stored URL shown is a proxy path rather than a raw bucket URL.",
|
|
92
|
+
],
|
|
93
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
94
|
+
expectedBehaviour: "The library lists stored media with working previews. Every tile is a clickable image inside a control, which is the exact shape that collapses to nothing when a shrink-to-fit wrapper sits between the button and the image — the tile renders as an empty box while the control still works.",
|
|
95
|
+
expectedUiState: "Every tile shows its image at the same size as its neighbours. Filters and sorts change the grid and 'zzzznope' returns none. Stored URLs are proxy paths, since a raw bucket URL bypasses the watermark and the private-bucket guarantee.",
|
|
96
|
+
expectedData: { nonsenseResultCount: 0 },
|
|
97
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
98
|
+
},
|
|
99
|
+
"checklist-admin-content-marketing-navigation-editor-admin": {
|
|
100
|
+
roles: ["admin", "guest"],
|
|
101
|
+
startPage: "/admin/navigation",
|
|
102
|
+
steps: [
|
|
103
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
104
|
+
"Open /admin/navigation and read every nav item, its label and its destination.",
|
|
105
|
+
"Create one labelled 'QA Nav navigation-editor' pointing at /about, and save.",
|
|
106
|
+
"RELOAD and read every field of it.",
|
|
107
|
+
"Open / in a private window and find the new item in the public navigation.",
|
|
108
|
+
"Click it and confirm it lands on /about.",
|
|
109
|
+
"Reorder two items, save, reload, and check the new order holds publicly.",
|
|
110
|
+
"Delete the item and confirm it disappears from both the editor and the public nav.",
|
|
111
|
+
],
|
|
112
|
+
inputs: { label: "QA Nav navigation-editor", href: "/about" },
|
|
113
|
+
expectedBehaviour: "The editor is the source of the public navigation, so a create, a reorder and a delete all reach it. A nav entry pointing at a page that does not exist is blocked elsewhere as a hard failure; this case is the other half — an entry that exists and never renders.",
|
|
114
|
+
expectedUiState: "The new item appears in the public navigation and resolves to /about. The reorder holds after a reload, publicly as well as in the editor. After the delete it is gone from both.",
|
|
115
|
+
endResult: "The item is deleted and the original order restored. An item saved in the editor but absent from the public nav is the failure.",
|
|
116
|
+
},
|
|
117
|
+
"checklist-admin-content-marketing-settings-navigation-actions": {
|
|
118
|
+
roles: ["admin"],
|
|
119
|
+
startPage: "/admin/site",
|
|
120
|
+
steps: [
|
|
121
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
122
|
+
"Open /admin/site and read every tab in the strip.",
|
|
123
|
+
"Open the header search and type a settings term such as fees.",
|
|
124
|
+
"Click the result and read which tab opens.",
|
|
125
|
+
"Read the URL and check it names the tab.",
|
|
126
|
+
"Copy that URL, open it in a new tab, and confirm it opens on the same tab.",
|
|
127
|
+
"Open /admin/site with an unknown tab value and read what happens.",
|
|
128
|
+
],
|
|
129
|
+
expectedBehaviour: "Settings are reachable by deep link and by search, and search reaches individual tabs rather than only the page. Landing on the first of nineteen tabs and leaving the admin to hunt is a fail rather than a partial pass, and an unknown tab value falls back quietly because the realistic cause is a stale bookmark.",
|
|
130
|
+
expectedUiState: "The search result opens the named tab, the URL carries it, and the copied URL reopens the same tab. An unknown value opens the default with no error banner and no blank panel.",
|
|
131
|
+
endResult: "Read-only; nothing is saved.",
|
|
132
|
+
},
|
|
133
|
+
"checklist-admin-content-marketing-features-feature-flags-admin": {
|
|
134
|
+
roles: ["admin", "guest"],
|
|
135
|
+
startPage: "/admin/site",
|
|
136
|
+
steps: [
|
|
137
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
138
|
+
"Open the feature-flags surface and read every flag and its state.",
|
|
139
|
+
"Write down the state of each.",
|
|
140
|
+
"Turn ONE flag off and save.",
|
|
141
|
+
"RELOAD and check only that flag changed.",
|
|
142
|
+
"Open the public surface that flag controls and confirm the behaviour changed.",
|
|
143
|
+
"Turn it back on, save, and confirm the behaviour returns.",
|
|
144
|
+
"Open /api/site-settings in a private window and read whether any flag is present in the response.",
|
|
145
|
+
],
|
|
146
|
+
expectedBehaviour: "A flag reaches the behaviour it names, and a save of one leaves the others alone. The public settings response is an ALLOW-LIST projection: a flag such as the admin checkout bypass has no business being readable by an anonymous caller, and it was published for a long time because the response was built by spreading the document and deleting three keys.",
|
|
147
|
+
expectedUiState: "Only the toggled flag changes after the reload. The public behaviour follows it in both directions. The public settings response carries no operational flag — specifically nothing naming a checkout bypass or an admin capability.",
|
|
148
|
+
expectedData: { operationalFlagsInPublicResponse: 0 },
|
|
149
|
+
endResult: "Every flag is back in its original state. A flag visible in the public response is a projection leak rather than a settings bug.",
|
|
150
|
+
},
|
|
151
|
+
};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the admin/coupons page.
|
|
3
|
+
* WHAT: 11 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 ROUTE ONCE ACCEPTED EVERY EDIT AND WROTE NOTHING. The handler returned a
|
|
10
|
+
* 200 echoing the submission back while only activate and deactivate reached a
|
|
11
|
+
* repository write — so a changed name, discount, limit or validity looked saved,
|
|
12
|
+
* looked correct on screen, and was gone on reload. That is why
|
|
13
|
+
* coupon-admin-edit-actually-saves exists and why nearly every case here ends in
|
|
14
|
+
* a reload rather than a confirmation message.
|
|
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-coupons-coupon-create-percentage": {
|
|
25
|
+
roles: ["admin", "buyer"],
|
|
26
|
+
startPage: "/admin/coupons",
|
|
27
|
+
steps: [
|
|
28
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
29
|
+
"Open /admin/coupons and create a percentage coupon coded QAADMIN15 at 15%, maximum discount 200, minimum purchase 500, valid for a week.",
|
|
30
|
+
"Save, RELOAD, and read every field.",
|
|
31
|
+
"Sign out and sign in as vivaan.kapoor@gmail.com / TempPass123!.",
|
|
32
|
+
"Add product-beyblade-original-driger-v (₹1,799) to the cart and reach the checkout coupon step.",
|
|
33
|
+
"Apply QAADMIN15 and read the discount amount.",
|
|
34
|
+
"Compare it against 15% of ₹1,799 and against the ₹200 cap.",
|
|
35
|
+
],
|
|
36
|
+
inputs: { code: "QAADMIN15", percent: 15, maxDiscount: 200, minPurchase: 500, itemPrice: 1799 },
|
|
37
|
+
expectedBehaviour: "A percentage coupon applies its rate and then its cap. 15% of ₹1,799 is ₹269.85, above the ₹200 maximum, so the cap is what the buyer receives — a cap that is stored and not applied is invisible until a large enough cart reaches it.",
|
|
38
|
+
expectedUiState: "After the reload every field holds. At checkout the discount is ₹200.00, not ₹269.85. A discount of ₹269.85 means the cap was ignored.",
|
|
39
|
+
expectedData: { appliedDiscount: 200 },
|
|
40
|
+
endResult: "Leave the coupon in place — later cases read it.",
|
|
41
|
+
},
|
|
42
|
+
"checklist-admin-coupons-coupon-create-fixed-freeship-bxgy": {
|
|
43
|
+
roles: ["admin", "buyer"],
|
|
44
|
+
startPage: "/admin/coupons",
|
|
45
|
+
steps: [
|
|
46
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
47
|
+
"Open /admin/coupons and read every coupon TYPE the form offers.",
|
|
48
|
+
"Create a fixed-amount coupon coded QAFIXED100 at ₹100 off with no minimum, and save.",
|
|
49
|
+
"Create a free-shipping coupon coded QAFREESHIP with no minimum, and save.",
|
|
50
|
+
"Create a buy-X-get-Y coupon coded QABXGY if the form offers that type, and save.",
|
|
51
|
+
"RELOAD each and read its type and settings.",
|
|
52
|
+
"As vivaan.kapoor@gmail.com / TempPass123!, apply each in turn at checkout and read what each changes.",
|
|
53
|
+
"Delete all three.",
|
|
54
|
+
],
|
|
55
|
+
inputs: { fixedCode: "QAFIXED100", fixedAmount: 100, freeShipCode: "QAFREESHIP", bxgyCode: "QABXGY" },
|
|
56
|
+
expectedBehaviour: "Each type does something different at checkout: fixed reduces the subtotal by a flat amount, free shipping zeroes the shipping line specifically, and buy-X-get-Y discounts by quantity. A type that saves but behaves identically to another has not been implemented, only listed.",
|
|
57
|
+
expectedUiState: "The fixed coupon reduces the subtotal by ₹100. The free-shipping one zeroes the SHIPPING line rather than the subtotal — a free-shipping coupon that takes its value off the subtotal is the failure worth naming. Buy-X-get-Y changes the total by quantity.",
|
|
58
|
+
endResult: "All three coupons are deleted by the final step.",
|
|
59
|
+
},
|
|
60
|
+
"checklist-admin-coupons-coupon-per-user-limit-enforced": {
|
|
61
|
+
roles: ["admin", "buyer"],
|
|
62
|
+
startPage: "/admin/coupons",
|
|
63
|
+
steps: [
|
|
64
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
65
|
+
"Open /admin/coupons, find TESTERLIMITED, and read its per-user limit, total limit and current usage.",
|
|
66
|
+
"Sign in as vivaan.kapoor@gmail.com / TempPass123! and place an order applying TESTERLIMITED.",
|
|
67
|
+
"Attempt a second order applying it again and read the refusal.",
|
|
68
|
+
"Sign in as rehan.sheikh@gmail.com / TempPass123! and apply TESTERLIMITED at checkout.",
|
|
69
|
+
"Sign back in as admin and read the usage count.",
|
|
70
|
+
],
|
|
71
|
+
inputs: { code: "TESTERLIMITED", perUserLimit: 1 },
|
|
72
|
+
expectedBehaviour: "TESTERLIMITED is one use per user with NO total limit, so exhausting it for one buyer must leave it fully usable by the next. Enforcing a per-user limit as if it were global withdraws the coupon from everybody after a single redemption.",
|
|
73
|
+
expectedUiState: "The same buyer's second attempt is refused with a limit message. A DIFFERENT buyer's attempt is accepted. The admin usage count has risen by the number of redemptions, and the coupon still reads as active.",
|
|
74
|
+
expectedData: { perUserLimit: 1 },
|
|
75
|
+
endResult: "The cross-account half is the case — the same-account half alone passes under either reading.",
|
|
76
|
+
},
|
|
77
|
+
"checklist-admin-coupons-coupon-min-max-discount": {
|
|
78
|
+
roles: ["admin", "buyer"],
|
|
79
|
+
startPage: "/admin/coupons",
|
|
80
|
+
steps: [
|
|
81
|
+
"Sign in as admin@letitrip.in / TempPass123! and confirm QAADMIN15 has a minimum purchase of 500 and a maximum discount of 200.",
|
|
82
|
+
"Sign in as vivaan.kapoor@gmail.com / TempPass123!.",
|
|
83
|
+
"Add product-tester-standard-3 (₹99) to the cart alone and apply QAADMIN15 at checkout.",
|
|
84
|
+
"Read the refusal and whether it names the required amount.",
|
|
85
|
+
"Add product-beyblade-original-driger-v (₹1,799) so the subtotal clears the minimum, and apply again.",
|
|
86
|
+
"Read the discount amount.",
|
|
87
|
+
"Type 799.50 into a money field elsewhere in the coupon form and check a decimal is accepted.",
|
|
88
|
+
],
|
|
89
|
+
inputs: { code: "QAADMIN15", minPurchase: 500, maxDiscount: 200 },
|
|
90
|
+
expectedBehaviour: "The minimum gates whether the coupon applies at all and the maximum caps what it gives. The minimum is measured against the items the coupon could actually discount rather than the whole cart, and money is decimal rupees throughout — a validator rejecting 799.50 as a non-integer is a leftover from the old whole-number storage.",
|
|
91
|
+
expectedUiState: "Below the minimum the coupon is refused with a message naming the threshold, not a bare 'Invalid coupon'. Above it the discount is capped at ₹200.00. A decimal amount is accepted in the coupon form.",
|
|
92
|
+
endResult: "Nothing is ordered; leave checkout without placing.",
|
|
93
|
+
},
|
|
94
|
+
"checklist-admin-coupons-coupon-scope-admin-vs-seller": {
|
|
95
|
+
roles: ["admin"],
|
|
96
|
+
startPage: "/admin/coupons",
|
|
97
|
+
steps: [
|
|
98
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
99
|
+
"Open /admin/coupons and read the scope shown on every row.",
|
|
100
|
+
"Filter or sort by scope if the list offers it, and read the results.",
|
|
101
|
+
"Open a seller-scoped coupon and read which store it belongs to.",
|
|
102
|
+
"Open an admin-scoped coupon and read whether it names a store at all.",
|
|
103
|
+
"Read whether the admin can change a coupon's scope after creation.",
|
|
104
|
+
],
|
|
105
|
+
expectedBehaviour: "There are exactly two scopes and no third: platform-wide with no store, or seller-scoped to one store. The distinction decides which stacking bucket a coupon occupies at checkout, so a row that does not show its scope hides the one field that determines its behaviour.",
|
|
106
|
+
expectedUiState: "Every row shows its scope. Seller-scoped coupons name their store; admin-scoped ones do not name any. Any scope filter returns rows for both values.",
|
|
107
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
108
|
+
},
|
|
109
|
+
"checklist-admin-coupons-coupon-expire-reject": {
|
|
110
|
+
roles: ["admin", "buyer"],
|
|
111
|
+
startPage: "/admin/coupons",
|
|
112
|
+
steps: [
|
|
113
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
114
|
+
"Open /admin/coupons and find TESTEREXPIRED, reading its end date and its active flag.",
|
|
115
|
+
"Note that it is still marked active while its end date is in the past.",
|
|
116
|
+
"Sign in as vivaan.kapoor@gmail.com / TempPass123! and apply TESTEREXPIRED at checkout.",
|
|
117
|
+
"Read the exact wording of the refusal.",
|
|
118
|
+
"Sign back in as admin, deactivate an ACTIVE coupon, and apply that one as the buyer.",
|
|
119
|
+
"Compare the two refusal messages.",
|
|
120
|
+
],
|
|
121
|
+
inputs: { expiredCode: "TESTEREXPIRED" },
|
|
122
|
+
expectedBehaviour: "Expiry and deactivation are two separate reasons and both refuse. TESTEREXPIRED is seeded past its end date while still flagged active precisely so the DATE check is exercised rather than the flag — a validator reading only the flag would accept it.",
|
|
123
|
+
expectedUiState: "The expired coupon is refused with a message naming expiry. The deactivated one is refused with a different message. Two identical generic refusals mean only one of the two checks is running.",
|
|
124
|
+
endResult: "Reactivate the coupon that was deactivated. Leaving it off silently breaks every later case that applies it.",
|
|
125
|
+
},
|
|
126
|
+
"checklist-admin-coupons-coupon-admin-is-platform-wide": {
|
|
127
|
+
roles: ["admin", "buyer"],
|
|
128
|
+
startPage: "/admin/coupons",
|
|
129
|
+
steps: [
|
|
130
|
+
"Sign in as admin@letitrip.in / TempPass123! and confirm QAADMIN15 is admin-scoped with no store.",
|
|
131
|
+
"Sign in as vivaan.kapoor@gmail.com / TempPass123!.",
|
|
132
|
+
"Add product-beyblade-burst-regalia-genesis (₹1,399, Beyblade Arena) to the cart.",
|
|
133
|
+
"Add prizedraw-beyblade-original-vintage-vault (₹299, LetItRip Official) and set its quantity to 2.",
|
|
134
|
+
"Apply QAADMIN15 at checkout and read the discount.",
|
|
135
|
+
"Place the order and open both resulting orders in /user/orders.",
|
|
136
|
+
"Read the QAADMIN15 amount on each and add them together.",
|
|
137
|
+
],
|
|
138
|
+
inputs: { code: "QAADMIN15", arenaSubtotal: 1399, officialSubtotal: 598 },
|
|
139
|
+
expectedBehaviour: "A platform coupon applies across the whole cart and is then prorated across the per-store orders by their share of the subtotal. The parts must reconcile exactly to what the buyer was shown, or the platform absorbed or overcharged the difference.",
|
|
140
|
+
expectedUiState: "The discount is computed against the combined subtotal rather than one store's. Both orders carry a share of it and the two shares sum to the single figure shown at checkout — not to more, and not to less.",
|
|
141
|
+
expectedData: { orderCount: 2 },
|
|
142
|
+
endResult: "Two orders exist, each with its prorated share. The reconciliation is the assertion.",
|
|
143
|
+
},
|
|
144
|
+
"checklist-admin-coupons-coupon-admin-no-stacking-toggle": {
|
|
145
|
+
roles: ["admin"],
|
|
146
|
+
startPage: "/admin/coupons",
|
|
147
|
+
steps: [
|
|
148
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
149
|
+
"Open /admin/coupons and start creating a coupon.",
|
|
150
|
+
"Read every field and toggle the form offers.",
|
|
151
|
+
"Look for any control about combining with seller coupons or with other platform coupons.",
|
|
152
|
+
"Open an existing coupon's editor and look for the same.",
|
|
153
|
+
],
|
|
154
|
+
expectedBehaviour: "Stacking is a platform rule, not a per-coupon setting — one coupon per store plus one platform-wide, unconditionally. The old combine-with-seller-coupons opt-out was removed because nothing read it, and a control that appears to configure a rule it cannot change is worse than no control at all.",
|
|
155
|
+
expectedUiState: "No stacking or combinability toggle is offered on either the create or the edit form. A toggle present here is the finding, whether or not it saves.",
|
|
156
|
+
endResult: "Read-only; leave the form without saving.",
|
|
157
|
+
},
|
|
158
|
+
"checklist-admin-coupons-coupon-admin-category-restriction-enforced": {
|
|
159
|
+
roles: ["admin", "buyer"],
|
|
160
|
+
startPage: "/admin/coupons",
|
|
161
|
+
steps: [
|
|
162
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
163
|
+
"Create a coupon coded QACATADMIN20 at 20%, restricted to the Beyblade Burst category, no minimum.",
|
|
164
|
+
"Save, RELOAD, and confirm the restriction persisted.",
|
|
165
|
+
"Sign in as vivaan.kapoor@gmail.com / TempPass123!.",
|
|
166
|
+
"Add product-beyblade-metal-storm-pegasus (₹1,299, Metal Fight) alone and apply QACATADMIN20 — read the refusal.",
|
|
167
|
+
"Add product-beyblade-burst-regalia-genesis (₹1,399, Burst) and apply again.",
|
|
168
|
+
"Read the discount and compare it against 20% of ₹1,399.",
|
|
169
|
+
"Sign back in as admin and delete the coupon.",
|
|
170
|
+
],
|
|
171
|
+
inputs: { code: "QACATADMIN20", percent: 20, burstPrice: 1399, metalPrice: 1299 },
|
|
172
|
+
expectedBehaviour: "The restriction is tested by set intersection against each product's full category chain, and the discount covers only the eligible items. The category is fetched lazily — the cart snapshots none — so the lookup fires only when a coupon actually carries a restriction, and the common case costs no extra reads.",
|
|
173
|
+
expectedUiState: "The Metal-only cart is refused with a message naming the category. With the Burst item added the coupon applies at about ₹279.80 — 20% of ₹1,399 — not 20% of the ₹2,698 combined subtotal.",
|
|
174
|
+
expectedData: { eligibleSubtotal: 1399 },
|
|
175
|
+
endResult: "The coupon is deleted by the final step.",
|
|
176
|
+
},
|
|
177
|
+
"checklist-admin-coupons-coupon-admin-edit-actually-saves": {
|
|
178
|
+
roles: ["admin"],
|
|
179
|
+
startPage: "/admin/coupons",
|
|
180
|
+
steps: [
|
|
181
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
182
|
+
"Open /admin/coupons and open QAADMIN15's editor.",
|
|
183
|
+
"Write down every field: name, description, discount, maximum, minimum, usage limits and both validity dates.",
|
|
184
|
+
"Change the NAME and the discount percentage, and save.",
|
|
185
|
+
"Read the confirmation message.",
|
|
186
|
+
"RELOAD the editor and compare every field against what was written down.",
|
|
187
|
+
"Change only the validity end date, save, RELOAD, and check the start date is still there.",
|
|
188
|
+
"Use the deactivate action, then reactivate it, reloading after each.",
|
|
189
|
+
],
|
|
190
|
+
inputs: { code: "QAADMIN15" },
|
|
191
|
+
expectedBehaviour: "🛑 This is the case the page exists for. The handler once returned a 200 echoing the submission while only activate and deactivate reached a repository write — so a changed name, discount, limit or date looked saved and was gone on reload, with no error to notice. The validity object must also MERGE rather than replace: sending one sub-field wholesale wipes the other date.",
|
|
192
|
+
expectedUiState: "After the reload the new name and discount are present. After the end-date edit the start date is unchanged. Deactivate and reactivate both persist. A success message followed by the ORIGINAL values after reload is the exact failure, and without the reload the screen looks identical either way.",
|
|
193
|
+
expectedData: { changesPersisted: true },
|
|
194
|
+
endResult: "Restore QAADMIN15's original name and percentage, or delete it. This case cannot be judged from the confirmation message — only from the reload.",
|
|
195
|
+
},
|
|
196
|
+
"checklist-admin-coupons-coupon-admin-usage-visible": {
|
|
197
|
+
roles: ["admin", "buyer"],
|
|
198
|
+
startPage: "/admin/coupons",
|
|
199
|
+
steps: [
|
|
200
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
201
|
+
"Open /admin/coupons and read the usage figure on every row.",
|
|
202
|
+
"Note the figure for ARENA25.",
|
|
203
|
+
"Sign in as vivaan.kapoor@gmail.com / TempPass123! and place an order applying ARENA25.",
|
|
204
|
+
"Sign back in as admin and read ARENA25's usage figure again.",
|
|
205
|
+
"Open the coupon's detail and read whether it shows total usage, per-user usage, or both.",
|
|
206
|
+
"Reload and confirm the figure persists.",
|
|
207
|
+
],
|
|
208
|
+
inputs: { code: "ARENA25" },
|
|
209
|
+
expectedBehaviour: "Redemption is counted at checkout, per user as well as globally, and the per-user record is written as a side effect of applying the coupon. That write is fire-and-forget, so a failure is silent — a usage figure that never moves is how you find out it failed.",
|
|
210
|
+
expectedUiState: "The usage figure is exactly one higher after the order and survives a reload. A figure that does not move means the usage write failed without anything surfacing it.",
|
|
211
|
+
expectedData: { usageIncrement: 1 },
|
|
212
|
+
endResult: "One order exists carrying the discount. Delete QAADMIN15 as the last action on this page.",
|
|
213
|
+
},
|
|
214
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the admin/events-raffles-spin page.
|
|
3
|
+
* WHAT: 8 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 EVENT TYPE PICKER HAS BEEN WRONG BEFORE in a way no query error
|
|
10
|
+
* surfaced: it offered three types the event union has never had, so each matched
|
|
11
|
+
* zero rows forever, while omitting five real ones. Two cases here read the picker
|
|
12
|
+
* and the filter chips against the real union rather than trusting either.
|
|
13
|
+
*
|
|
14
|
+
* The two "view before deciding" cases are the same defect as the moderation
|
|
15
|
+
* pages: a row that offers Confirm and Waitlist without showing the entry lets an
|
|
16
|
+
* admin act on a record they were never able to read.
|
|
17
|
+
*
|
|
18
|
+
* @tag domain:tester
|
|
19
|
+
* @tag layer:seed
|
|
20
|
+
* @tag pattern:none
|
|
21
|
+
* @tag access:server-only
|
|
22
|
+
* @tag consumers:seed-data/authored/index.ts
|
|
23
|
+
* @tag sideEffects:none
|
|
24
|
+
*/
|
|
25
|
+
export const authored = {
|
|
26
|
+
"checklist-admin-events-raffles-spin-raffle-create-open": {
|
|
27
|
+
roles: ["admin", "buyer"],
|
|
28
|
+
startPage: "/admin/events/new",
|
|
29
|
+
steps: [
|
|
30
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
31
|
+
"Open /admin/events/new and read every option in the event type picker.",
|
|
32
|
+
"Write the list down and compare it against the real event types the catalogue supports.",
|
|
33
|
+
"Create an event titled 'QA Event raffle-open' with an open raffle, a prize, a start date of today and an end date a week out.",
|
|
34
|
+
"Save, RELOAD, and read the raffle type, the prize and the dates.",
|
|
35
|
+
"Sign out, sign in as rehan.sheikh@gmail.com / TempPass123!, and enter the raffle from its public page.",
|
|
36
|
+
"Sign back in as admin and read the entry count on the event.",
|
|
37
|
+
],
|
|
38
|
+
inputs: { title: "QA Event raffle-open", raffleType: "open" },
|
|
39
|
+
expectedBehaviour: "The type picker offers every real event type and no invented ones. An option whose value is not a stored type matches nothing forever with no error — the picker once offered three such and omitted five real ones, under a comment deferring the fix.",
|
|
40
|
+
expectedUiState: "The picker's options match the real type list, with no contest, giveaway or flash-sale style values that the union does not carry, and with lottery present. After the reload the raffle settings hold, and the buyer's entry raises the count.",
|
|
41
|
+
endResult: "Leave the event in place — the draw case reads it.",
|
|
42
|
+
},
|
|
43
|
+
"checklist-admin-events-raffles-spin-raffle-create-top-n-scorers": {
|
|
44
|
+
roles: ["admin", "buyer"],
|
|
45
|
+
startPage: "/admin/events/new",
|
|
46
|
+
steps: [
|
|
47
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
48
|
+
"Create an event titled 'QA Event raffle-scorers' with a top-N-scorers raffle, N set to 3, and a prize.",
|
|
49
|
+
"Save, RELOAD, and read the raffle type and the N value.",
|
|
50
|
+
"Open the public page and read how the Overview tab describes who can win.",
|
|
51
|
+
"Sign in as rehan.sheikh@gmail.com / TempPass123! and enter, then read the Leaderboard tab.",
|
|
52
|
+
"Read whether the leaderboard is ordered by score and whether the qualifying cut-off is stated.",
|
|
53
|
+
],
|
|
54
|
+
inputs: { title: "QA Event raffle-scorers", raffleType: "top_n_scorers", topN: 3 },
|
|
55
|
+
expectedBehaviour: "A top-N-scorers raffle draws from the highest-scoring entries, so the leaderboard must rank by score and the public page must state how many qualify. Ranking by entry time instead silently changes who can win, and nothing errors.",
|
|
56
|
+
expectedUiState: "After the reload the type and N hold. The public Overview states the rule, and the Leaderboard is ordered by score with the cut-off named. A leaderboard ordered by entry time is the failure.",
|
|
57
|
+
endResult: "Delete the event after reading it.",
|
|
58
|
+
},
|
|
59
|
+
"checklist-admin-events-raffles-spin-raffle-create-top-n-participants": {
|
|
60
|
+
roles: ["admin", "buyer"],
|
|
61
|
+
startPage: "/admin/events/new",
|
|
62
|
+
steps: [
|
|
63
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
64
|
+
"Create an event titled 'QA Event raffle-participants' with a top-N-participants raffle, N set to 3, and a prize.",
|
|
65
|
+
"Save, RELOAD, and read the raffle type and N.",
|
|
66
|
+
"Open the public page and read how the Overview tab describes who can win.",
|
|
67
|
+
"Compare that description against the scorers event's.",
|
|
68
|
+
"Enter as rehan.sheikh@gmail.com / TempPass123! and compare the two leaderboards' ordering.",
|
|
69
|
+
],
|
|
70
|
+
inputs: { title: "QA Event raffle-participants", raffleType: "top_n_participants", topN: 3 },
|
|
71
|
+
expectedBehaviour: "This variant draws by participation rather than by score — a genuinely different rule from the scorers one. The two exist side by side precisely so the difference is checkable: identical leaderboards on both means the raffle type is not reaching the ranking.",
|
|
72
|
+
expectedUiState: "The type and N hold after the reload, and the Overview describes a different rule from the scorers event. The two leaderboards order differently. Identical ordering on both is the failure.",
|
|
73
|
+
endResult: "Delete the event after reading it.",
|
|
74
|
+
},
|
|
75
|
+
"checklist-admin-events-raffles-spin-raffle-draw-winner": {
|
|
76
|
+
roles: ["admin", "buyer"],
|
|
77
|
+
startPage: "/admin/events",
|
|
78
|
+
steps: [
|
|
79
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
80
|
+
"Open 'QA Event raffle-open' in the admin and read the entry list.",
|
|
81
|
+
"Trigger the raffle draw and read the winner named.",
|
|
82
|
+
"RELOAD and read the winner again.",
|
|
83
|
+
"Read whether the winner's name and entry are both recorded on the event.",
|
|
84
|
+
"Sign in as the winning buyer and check they were notified.",
|
|
85
|
+
"Sign back in as admin and attempt to draw a second time, reading what happens.",
|
|
86
|
+
],
|
|
87
|
+
expectedBehaviour: "The draw picks once with real randomness, records the winner on the event, and notifies them. A second draw must be refused — redrawing replaces a winner who has already been told they won, and the notification cannot be recalled.",
|
|
88
|
+
expectedUiState: "The winner is named and survives the reload. The event records both the winner and their entry. The buyer has a notification. The second draw attempt is refused rather than producing a new winner.",
|
|
89
|
+
expectedData: { drawsPermitted: 1 },
|
|
90
|
+
endResult: "Delete the event afterwards. A second draw succeeding is the most serious failure on this page.",
|
|
91
|
+
},
|
|
92
|
+
"checklist-admin-events-raffles-spin-spin-wheel-create": {
|
|
93
|
+
roles: ["admin", "buyer"],
|
|
94
|
+
startPage: "/admin/events/new",
|
|
95
|
+
steps: [
|
|
96
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
97
|
+
"Create an event titled 'QA Event spin-create' of the spin-wheel type.",
|
|
98
|
+
"Define three prizes with labels and weights, set a maximum of 2 spins per user, and set a spin window covering today.",
|
|
99
|
+
"Save, RELOAD, and read every prize, weight, the maximum and the window.",
|
|
100
|
+
"Open the public page and read the wheel and its segments.",
|
|
101
|
+
"Check the wheel shows the prize labels and does NOT disclose their weights.",
|
|
102
|
+
],
|
|
103
|
+
inputs: { title: "QA Event spin-create", prizeCount: 3, maxPerUser: 2 },
|
|
104
|
+
expectedBehaviour: "Prizes, weights, the per-user maximum and the window all round-trip. Weights are the odds and belong server-side — a public wheel that renders them tells every visitor which segment is worthless.",
|
|
105
|
+
expectedUiState: "After the reload all four groups of settings hold. The public wheel shows three labelled segments and no weight values anywhere on the page or in its source.",
|
|
106
|
+
expectedData: { weightsInPublicSource: 0 },
|
|
107
|
+
endResult: "Leave the event in place — the limits case reads it.",
|
|
108
|
+
},
|
|
109
|
+
"checklist-admin-events-raffles-spin-spin-wheel-limits-enforced": {
|
|
110
|
+
roles: ["admin", "buyer"],
|
|
111
|
+
startPage: "/admin/events",
|
|
112
|
+
steps: [
|
|
113
|
+
"Sign in as rehan.sheikh@gmail.com / TempPass123! and open 'QA Event spin-create'.",
|
|
114
|
+
"Spin once and read the prize and the remaining count.",
|
|
115
|
+
"Spin a second time and read the remaining count.",
|
|
116
|
+
"Attempt a third spin and read the refusal.",
|
|
117
|
+
"RELOAD the page and attempt another spin.",
|
|
118
|
+
"Sign out and sign in as admin@letitrip.in / TempPass123!, then narrow the spin window so it is closed.",
|
|
119
|
+
"Sign back in as the buyer and attempt a spin, reading the refusal.",
|
|
120
|
+
],
|
|
121
|
+
inputs: { maxPerUser: 2 },
|
|
122
|
+
expectedBehaviour: "The per-user cap and the window are both enforced server-side. A cap held in the browser resets on refresh and is no cap at all, and the two refusals must read differently — 'no spins left' and 'the window is closed' are different facts and a single generic message tells the buyer neither.",
|
|
123
|
+
expectedUiState: "The remaining count falls with each spin and the third is refused naming the limit. After the reload it is still refused. With the window closed the refusal names the window instead. A fresh spin available after a reload is the failure.",
|
|
124
|
+
expectedData: { spinsAfterReload: 0 },
|
|
125
|
+
endResult: "Delete the event afterwards.",
|
|
126
|
+
},
|
|
127
|
+
"checklist-admin-events-raffles-spin-event-entries-admin-view": {
|
|
128
|
+
roles: ["admin"],
|
|
129
|
+
startPage: "/admin/events",
|
|
130
|
+
steps: [
|
|
131
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
132
|
+
"Open an event's entries page and read every column.",
|
|
133
|
+
"Read every status filter offered and select each, noting any that returns nothing.",
|
|
134
|
+
"For each empty filter, check the unfiltered list for rows of that status.",
|
|
135
|
+
"Read the row actions offered and check at least one lets you VIEW an entry.",
|
|
136
|
+
"Use the search if one is offered, then search zzzznope and read the count.",
|
|
137
|
+
"Check whether buyer email addresses are shown in full.",
|
|
138
|
+
],
|
|
139
|
+
inputs: { nonsenseQuery: "zzzznope" },
|
|
140
|
+
expectedBehaviour: "Entries are readable and filterable, and every status chip names a value entries actually hold. The entry document carries the participant's email, which is PII — how much of it this list exposes is worth recording rather than assuming.",
|
|
141
|
+
expectedUiState: "Every filter returns its own rows or is empty with none unfiltered either. A view affordance exists alongside the actions. 'zzzznope' returns none. Record exactly how buyer emails are displayed.",
|
|
142
|
+
expectedData: { nonsenseResultCount: 0 },
|
|
143
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
144
|
+
},
|
|
145
|
+
"checklist-admin-events-raffles-spin-event-entries-view-before-deciding": {
|
|
146
|
+
roles: ["admin"],
|
|
147
|
+
startPage: "/admin/events",
|
|
148
|
+
steps: [
|
|
149
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
150
|
+
"Open the entries page for an event that collects responses — a poll, survey or feedback event.",
|
|
151
|
+
"Find a row offering Confirm, Waitlist or Cancel.",
|
|
152
|
+
"WITHOUT using any of those, look for a way to read the entry's actual content first.",
|
|
153
|
+
"Open the entry and read the participant's response in full.",
|
|
154
|
+
"Return to the list and check the same content is reachable from the row itself.",
|
|
155
|
+
],
|
|
156
|
+
expectedBehaviour: "An admin can read an entry before deciding on it. A row offering Confirm, Waitlist and Cancel without showing what was submitted is a decision made blind — the same shape as approving a catalogue submission whose photos were never rendered, or confirming a bug report whose comment and screenshot are not on screen.",
|
|
157
|
+
expectedUiState: "The entry's response is readable from the list or from a detail view reachable from the row, before any action is taken. A row with only mutations is the failure, and it looks complete because the buttons work.",
|
|
158
|
+
endResult: "Read-only; take no action on any entry. Report whether the content was reachable WITHOUT deciding.",
|
|
159
|
+
},
|
|
160
|
+
};
|