@mohasinac/appkit 3.8.2 → 3.9.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/live/LiveItemDetailView.js +2 -2
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +4 -4
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +8 -8
- package/dist/_internal/client/features/lottery/LotteryAdminSlotView.d.ts +1 -1
- package/dist/_internal/client/features/lottery/LotteryAdminSlotView.js +2 -2
- package/dist/_internal/server/features/bundles/actions.js +2 -2
- package/dist/_internal/server/features/bundles/og.d.ts +1 -1
- package/dist/_internal/server/features/bundles/og.js +4 -5
- package/dist/_internal/server/features/checkout/actions.js +57 -21
- package/dist/_internal/server/features/checkout/stock-restore.d.ts +19 -0
- package/dist/_internal/server/features/checkout/stock-restore.js +80 -0
- package/dist/_internal/server/features/checkout/upi-resolution.d.ts +11 -0
- package/dist/_internal/server/features/checkout/upi-resolution.js +28 -0
- package/dist/_internal/server/features/classified/og.js +1 -1
- package/dist/_internal/server/features/digital-code/og.js +1 -1
- package/dist/_internal/server/features/item-requests/og.d.ts +2 -2
- package/dist/_internal/server/features/item-requests/og.js +4 -5
- package/dist/_internal/server/features/live/og.js +1 -1
- package/dist/_internal/server/features/lottery/adapters.d.ts +2 -2
- package/dist/_internal/server/features/lottery/adapters.js +1 -1
- package/dist/_internal/server/features/orders/actions.d.ts +28 -0
- package/dist/_internal/server/features/orders/actions.js +239 -4
- package/dist/_internal/server/features/orders/adapters.js +3 -0
- package/dist/_internal/server/features/payments/data.js +3 -2
- package/dist/_internal/server/features/payouts/actions.d.ts +2 -2
- package/dist/_internal/server/features/payouts/actions.js +4 -3
- package/dist/_internal/server/features/pre-orders/service.d.ts +1 -1
- package/dist/_internal/server/features/pre-orders/service.js +3 -2
- package/dist/_internal/server/features/prize-draws/og.js +5 -5
- package/dist/_internal/server/features/products/og.js +1 -1
- package/dist/_internal/server/features/promotions/service.js +3 -1
- package/dist/_internal/server/features/refunds/actions.d.ts +2 -2
- package/dist/_internal/server/features/refunds/actions.js +7 -6
- package/dist/_internal/server/functions/firestore.js +1 -1
- package/dist/_internal/server/functions/scheduled.d.ts +4 -1
- package/dist/_internal/server/functions/scheduled.js +26 -2
- package/dist/_internal/server/jobs/core/emiInstallmentReminder.js +1 -1
- package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +4 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +15 -4
- package/dist/_internal/server/jobs/core/hardBanReinstatement.d.ts +16 -0
- package/dist/_internal/server/jobs/core/hardBanReinstatement.js +63 -0
- package/dist/_internal/server/jobs/core/jobRunners.js +3 -1
- package/dist/_internal/server/jobs/core/onScamReportCreate.js +1 -1
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.d.ts +10 -0
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.js +60 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.d.ts +15 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +59 -0
- package/dist/_internal/server/jobs/core/pendingOrderTimeout.d.ts +7 -0
- package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +32 -6
- package/dist/_internal/server/jobs/handlers/hardBanReinstatement.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/hardBanReinstatement.js +2 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/index.js +3 -0
- package/dist/_internal/server/jobs/handlers/messages.d.ts +4 -0
- package/dist/_internal/server/jobs/handlers/messages.js +4 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +3 -3
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +12 -12
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +1 -1
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +5 -5
- package/dist/_internal/server/jobs/handlers/paymentReviewAutoApprove.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/paymentReviewAutoApprove.js +2 -0
- package/dist/_internal/server/jobs/handlers/paymentWindowTimeout.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/paymentWindowTimeout.js +2 -0
- package/dist/_internal/shared/actions/action-registry.js +27 -0
- package/dist/_internal/shared/checkout/order-math.js +3 -2
- package/dist/_internal/shared/checkout/rules/_defaults.js +1 -0
- package/dist/_internal/shared/checkout/rules/preorder.rule.js +7 -0
- package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +7 -0
- package/dist/_internal/shared/checkout/rules/types.d.ts +11 -0
- package/dist/_internal/shared/features/auctions/errors.js +1 -1
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +0 -1
- package/dist/_internal/shared/features/categories/bundle-copy.js +0 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +6 -6
- package/dist/_internal/shared/features/categories/bundle-schemas.js +2 -2
- package/dist/_internal/shared/features/checkout/config.d.ts +3 -3
- package/dist/_internal/shared/features/checkout/config.js +3 -3
- package/dist/_internal/shared/features/emi/schedule.d.ts +6 -6
- package/dist/_internal/shared/features/emi/schedule.js +10 -9
- package/dist/_internal/shared/features/promotions/errors.js +1 -1
- package/dist/_internal/shared/fees/calculator.d.ts +5 -5
- package/dist/_internal/shared/fees/calculator.js +19 -19
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/constants/api-endpoints.d.ts +9 -0
- package/dist/constants/api-endpoints.js +3 -0
- package/dist/constants/field-names.d.ts +4 -0
- package/dist/constants/field-names.js +4 -0
- package/dist/features/admin/components/AdminArtView.js +2 -2
- package/dist/features/admin/components/AdminBidsView.js +2 -2
- package/dist/features/admin/components/AdminBundleEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminBundleEditorView.js +8 -8
- package/dist/features/admin/components/AdminBundlesView.js +6 -6
- package/dist/features/admin/components/AdminClassifiedView.js +2 -2
- package/dist/features/admin/components/AdminDigitalCodesView.js +2 -2
- package/dist/features/admin/components/AdminLiveView.js +2 -2
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +6 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +45 -5
- package/dist/features/admin/components/AdminOrdersView.js +8 -3
- package/dist/features/admin/components/AdminPayoutsView.js +2 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -2
- package/dist/features/admin/components/AdminReturnRequestsView.js +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +11 -11
- package/dist/features/admin/components/AdminStickersView.js +2 -2
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/hooks/useAdminListingData.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminListingData.js +3 -2
- package/dist/features/admin/schemas/firestore.d.ts +9 -7
- package/dist/features/admin/schemas/firestore.js +4 -3
- package/dist/features/auctions/components/AuctionBidsTable.js +3 -3
- package/dist/features/auth/checkout-value-otp.d.ts +46 -0
- package/dist/features/auth/checkout-value-otp.js +73 -0
- package/dist/features/auth/repository/user.repository.d.ts +6 -0
- package/dist/features/auth/repository/user.repository.js +19 -0
- package/dist/features/auth/schemas/firestore.d.ts +10 -0
- package/dist/features/auth/schemas/firestore.js +2 -0
- package/dist/features/cart/actions/cart-actions.d.ts +1 -1
- package/dist/features/cart/actions/cart-actions.js +4 -4
- package/dist/features/cart/components/CartView.d.ts +2 -2
- package/dist/features/cart/components/ShippingPicker.d.ts +4 -4
- package/dist/features/cart/components/ShippingPicker.js +11 -11
- package/dist/features/cart/repository/cart.repository.d.ts +1 -1
- package/dist/features/cart/repository/cart.repository.js +2 -2
- package/dist/features/cart/schemas/firestore.d.ts +2 -2
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +3 -3
- package/dist/features/catalogue/components/PublicCatalogueView.js +2 -2
- package/dist/features/catalogue/schemas/validation.js +1 -1
- package/dist/features/categories/components/BundleCollage.js +2 -2
- package/dist/features/categories/components/BundleDetailView.js +2 -2
- package/dist/features/categories/components/BundleItemsPicker.d.ts +1 -1
- package/dist/features/categories/components/BundleItemsPicker.js +2 -2
- package/dist/features/categories/components/CategoryBundlesListing.js +2 -2
- package/dist/features/categories/schemas/firestore.d.ts +1 -1
- package/dist/features/categories/schemas/index.d.ts +3 -3
- package/dist/features/categories/schemas/index.js +2 -2
- package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +16 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +83 -0
- package/dist/features/checkout/actions/index.d.ts +1 -0
- package/dist/features/checkout/actions/index.js +1 -0
- package/dist/features/checkout/schemas/firestore.d.ts +1 -1
- package/dist/features/classified/components/index.d.ts +0 -4
- package/dist/features/classified/components/index.js +0 -2
- package/dist/features/digital-codes/components/index.d.ts +0 -4
- package/dist/features/digital-codes/components/index.js +0 -2
- package/dist/features/events/schemas/index.d.ts +1 -1
- package/dist/features/events/schemas/index.js +1 -1
- package/dist/features/homepage/components/FeaturedBundlesSection.js +2 -2
- package/dist/features/live/components/index.d.ts +0 -4
- package/dist/features/live/components/index.js +0 -2
- package/dist/features/lottery/types/index.d.ts +3 -3
- package/dist/features/lottery/types/index.js +5 -5
- package/dist/features/orders/components/OrderPaymentSummary.js +2 -2
- package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
- package/dist/features/orders/components/RefundHistoryTable.js +1 -1
- package/dist/features/orders/components/RefundRequestView.js +1 -1
- package/dist/features/orders/constants/payment-window.d.ts +10 -0
- package/dist/features/orders/constants/payment-window.js +10 -0
- package/dist/features/orders/repository/orders.repository.d.ts +25 -0
- package/dist/features/orders/repository/orders.repository.js +50 -1
- package/dist/features/orders/schemas/firestore.d.ts +50 -2
- package/dist/features/orders/schemas/index.d.ts +24 -24
- package/dist/features/orders/schemas/index.js +20 -20
- package/dist/features/orders/types/index.d.ts +4 -0
- package/dist/features/orders/utils/bundle-grouping.d.ts +1 -1
- package/dist/features/orders/utils/bundle-grouping.js +1 -1
- package/dist/features/payments/schemas/index.d.ts +10 -10
- package/dist/features/payments/schemas/index.js +9 -9
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -2
- package/dist/features/products/components/ArtStickersListView.d.ts +7 -0
- package/dist/features/products/components/ArtStickersListView.js +57 -0
- package/dist/features/products/components/GroupSettingsPanel.js +1 -1
- package/dist/features/products/components/MakeOfferButton.js +3 -3
- package/dist/features/products/components/MarketplaceBundleCard.d.ts +1 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
- package/dist/features/products/components/PrizeDrawCollage.js +2 -2
- package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
- package/dist/features/products/components/PrizeRevealModal.js +1 -1
- package/dist/features/products/components/ProductDetailPageView.js +2 -9
- package/dist/features/products/components/ProductForm.js +2 -2
- package/dist/features/products/components/ProductGrid.js +2 -2
- package/dist/features/products/components/ProductsIndexListing.d.ts +13 -1
- package/dist/features/products/components/ProductsIndexListing.js +7 -5
- package/dist/features/products/components/ProductsIndexPageView.js +6 -1
- package/dist/features/products/constants/listing-tabs.d.ts +42 -17
- package/dist/features/products/constants/listing-tabs.js +25 -6
- package/dist/features/products/schemas/catalog-product.d.ts +5 -5
- package/dist/features/products/schemas/catalog-product.js +1 -1
- package/dist/features/products/schemas/firestore.d.ts +5 -5
- package/dist/features/products/schemas/firestore.js +2 -2
- package/dist/features/products/types/index.d.ts +5 -2
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/schemas/firestore.d.ts +2 -0
- package/dist/features/promotions/schemas/firestore.js +1 -0
- package/dist/features/promotions/schemas/index.d.ts +14 -14
- package/dist/features/promotions/schemas/index.js +6 -6
- package/dist/features/scams/components/ScamProfileView.js +3 -7
- package/dist/features/scams/components/ScamRegistryView.js +2 -6
- package/dist/features/scams/schemas/firestore.d.ts +1 -1
- package/dist/features/search/components/Search.d.ts +1 -1
- package/dist/features/seller/actions/offer-actions.js +1 -1
- package/dist/features/seller/components/PrintCenterView.js +2 -2
- package/dist/features/seller/components/QuickProductForm.js +5 -5
- package/dist/features/seller/components/SellerArtView.js +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerBundlesView.js +6 -6
- package/dist/features/seller/components/SellerClassifiedView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
- package/dist/features/seller/components/SellerLiveView.js +2 -2
- package/dist/features/seller/components/SellerOffersView.js +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +3 -3
- package/dist/features/seller/components/SellerPayoutRequestView.js +2 -2
- package/dist/features/seller/components/SellerPayoutSettingsView.js +2 -2
- package/dist/features/seller/components/SellerPayoutsView.js +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +2 -2
- package/dist/features/seller/components/SellerProductShell.js +8 -8
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerShippingView.js +6 -6
- package/dist/features/seller/components/SellerStickersView.js +2 -2
- package/dist/features/seller/hooks/useSellerListingData.d.ts +1 -1
- package/dist/features/seller/hooks/useSellerListingData.js +3 -2
- package/dist/features/shipments/components/AdminShipmentEditorView.js +10 -10
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +4 -4
- package/dist/features/shipments/components/AdminShipmentProjectionsView.js +5 -5
- package/dist/features/shipments/components/AdminShipmentsView.js +4 -4
- package/dist/features/shipments/repository/shipment-lots.repository.d.ts +2 -2
- package/dist/features/shipments/repository/shipment-lots.repository.js +8 -8
- package/dist/features/shipments/schemas/firestore.d.ts +21 -21
- package/dist/features/shipments/schemas/firestore.js +9 -9
- package/dist/features/shipments/schemas/validation.d.ts +30 -30
- package/dist/features/shipments/schemas/validation.js +6 -6
- package/dist/features/shipments/utils/cost-allocation.d.ts +5 -5
- package/dist/features/shipments/utils/cost-allocation.js +39 -38
- package/dist/features/store-extensions/schemas/firestore.d.ts +5 -5
- package/dist/features/stores/components/StoreDetailLayoutView.js +9 -13
- package/dist/features/stores/schemas/firestore.d.ts +7 -7
- package/dist/features/stores/schemas/index.d.ts +84 -84
- package/dist/features/stores/schemas/index.js +5 -5
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +1 -1
- package/dist/features/tester/seed-data/products-tester-seed-data.js +6 -6
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +9 -2
- package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +8 -1
- package/dist/features/whatsapp-bot/helpers/whatsapp.js +13 -2
- package/dist/features/whatsapp-bot/types/index.d.ts +9 -1
- package/dist/index.d.ts +3 -7
- package/dist/index.js +7 -5
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +6 -0
- package/dist/schemas/firestore-helpers.d.ts +2 -2
- package/dist/schemas/firestore-helpers.js +2 -2
- package/dist/schemas/registry.d.ts +73 -73
- package/dist/seed/bids-seed-data.js +6 -6
- package/dist/seed/blog-posts-seed-data.js +1 -0
- package/dist/seed/cart-seed-data.js +13 -13
- package/dist/seed/catalogue-seed-data.js +6 -6
- package/dist/seed/categories-seed-data.js +5 -5
- package/dist/seed/claimed-coupons-seed-data.js +3 -3
- package/dist/seed/coupons-seed-data.js +20 -20
- package/dist/seed/events-seed-data.js +27 -27
- package/dist/seed/factories/bid.factory.js +1 -1
- package/dist/seed/faq-seed-data.js +20 -1
- package/dist/seed/grouped-listings-seed-data.d.ts +2 -2
- package/dist/seed/grouped-listings-seed-data.js +3 -3
- package/dist/seed/offers-seed-data.js +19 -19
- package/dist/seed/orders-seed-data.js +29 -29
- package/dist/seed/payouts-seed-data.js +7 -7
- package/dist/seed/products-auctions-seed-data.js +6 -6
- package/dist/seed/products-preorders-seed-data.d.ts +2 -2
- package/dist/seed/products-preorders-seed-data.js +1 -1
- package/dist/seed/products-standard-seed-data.js +8 -8
- package/dist/seed/scammers-seed-data.js +2 -2
- package/dist/seed/shipments-seed-data.js +29 -29
- package/dist/seed/site-settings-seed-data.js +3 -2
- package/dist/seed/store-extensions-seed-data.js +8 -8
- package/dist/seed/stores-seed-data.js +37 -8
- package/dist/seed/users-seed-data.js +38 -1
- package/dist/server-entry.d.ts +1 -3
- package/dist/server-entry.js +1 -3
- package/dist/server.d.ts +2 -1
- package/dist/server.js +3 -1
- package/dist/ui/components/PriceDisplay.js +3 -12
- package/dist/utils/number.formatter.d.ts +2 -7
- package/dist/utils/number.formatter.js +3 -8
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +8 -3
- package/dist/_internal/client/scaffolds/DashboardScaffold.d.ts +0 -34
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +0 -26
- package/dist/_internal/client/theme/__tests__/ThemeProvider.test.d.ts +0 -1
- package/dist/_internal/client/theme/__tests__/ThemeProvider.test.js +0 -109
- package/dist/_internal/server/features/auctions/__tests__/service.test.d.ts +0 -1
- package/dist/_internal/server/features/auctions/__tests__/service.test.js +0 -140
- package/dist/_internal/server/features/checkout/__tests__/actions.test.d.ts +0 -1
- package/dist/_internal/server/features/checkout/__tests__/actions.test.js +0 -600
- package/dist/_internal/server/features/refunds/__tests__/actions.test.d.ts +0 -1
- package/dist/_internal/server/features/refunds/__tests__/actions.test.js +0 -263
- package/dist/_internal/server/jobs/core/__tests__/auctionSettlement.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/auctionSettlement.test.js +0 -249
- package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.js +0 -65
- package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.js +0 -163
- package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.js +0 -115
- package/dist/_internal/server/jobs/core/__tests__/onBidPlaced.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onBidPlaced.test.js +0 -201
- package/dist/_internal/server/jobs/core/__tests__/onOrderCreate.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onOrderCreate.test.js +0 -169
- package/dist/_internal/server/jobs/core/__tests__/onOrderStatusChange.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onOrderStatusChange.test.js +0 -148
- package/dist/_internal/server/jobs/core/__tests__/onProductStockChange.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onProductStockChange.test.js +0 -210
- package/dist/_internal/server/jobs/core/__tests__/onReviewWrite.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onReviewWrite.test.js +0 -190
- package/dist/_internal/server/jobs/core/__tests__/onUserBanChange.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onUserBanChange.test.js +0 -161
- package/dist/_internal/server/jobs/core/__tests__/payoutBatch.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/payoutBatch.test.js +0 -302
- package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.js +0 -96
- package/dist/_internal/server/jobs/core/__tests__/triggerEventRaffle.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/triggerEventRaffle.test.js +0 -252
- package/dist/_internal/server/jobs/core/__tests__/wrapJobHandler.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/wrapJobHandler.test.js +0 -129
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +0 -15
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +0 -38
- package/dist/_internal/server/providers/index.d.ts +0 -11
- package/dist/_internal/server/providers/index.js +0 -11
- package/dist/_internal/server/providers/payment/razorpay-mock.d.ts +0 -52
- package/dist/_internal/server/providers/payment/razorpay-mock.js +0 -118
- package/dist/_internal/server/providers/resolve.d.ts +0 -36
- package/dist/_internal/server/providers/resolve.js +0 -31
- package/dist/_internal/server/providers/shipping/shiprocket-mock.d.ts +0 -29
- package/dist/_internal/server/providers/shipping/shiprocket-mock.js +0 -152
- package/dist/_internal/shared/types/__tests__/action-result.test.d.ts +0 -1
- package/dist/_internal/shared/types/__tests__/action-result.test.js +0 -65
- package/dist/errors/__tests__/error-mapping.test.d.ts +0 -1
- package/dist/errors/__tests__/error-mapping.test.js +0 -122
- package/dist/errors/__tests__/safe-read.test.d.ts +0 -1
- package/dist/errors/__tests__/safe-read.test.js +0 -39
- package/dist/features/addresses/repository/__tests__/addresses.repository.test.d.ts +0 -1
- package/dist/features/addresses/repository/__tests__/addresses.repository.test.js +0 -386
- package/dist/features/admin/components/AdminListingScaffold.d.ts +0 -41
- package/dist/features/admin/components/AdminListingScaffold.js +0 -68
- package/dist/features/admin/components/QuickActionsPanel.d.ts +0 -15
- package/dist/features/admin/components/QuickActionsPanel.js +0 -5
- package/dist/features/admin/repository/__tests__/notification.repository.test.d.ts +0 -1
- package/dist/features/admin/repository/__tests__/notification.repository.test.js +0 -356
- package/dist/features/admin/repository/__tests__/site-settings.repository.test.d.ts +0 -1
- package/dist/features/admin/repository/__tests__/site-settings.repository.test.js +0 -298
- package/dist/features/auctions/repository/__tests__/bid.repository.test.d.ts +0 -1
- package/dist/features/auctions/repository/__tests__/bid.repository.test.js +0 -290
- package/dist/features/auctions/repository/auctions.repository.d.ts +0 -12
- package/dist/features/auctions/repository/auctions.repository.js +0 -42
- package/dist/features/auth/repository/__tests__/session.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/session.repository.test.js +0 -310
- package/dist/features/auth/repository/__tests__/session.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/session.test.js +0 -146
- package/dist/features/auth/repository/__tests__/sms-counter.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/sms-counter.repository.test.js +0 -171
- package/dist/features/auth/repository/__tests__/sms-counter.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/sms-counter.test.js +0 -88
- package/dist/features/auth/repository/__tests__/token.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/token.repository.test.js +0 -260
- package/dist/features/auth/repository/__tests__/token.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/token.test.js +0 -140
- package/dist/features/auth/repository/__tests__/user.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/user.repository.test.js +0 -352
- package/dist/features/auth/repository/__tests__/user.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/user.test.js +0 -226
- package/dist/features/before-after/repository/before-after.repository.d.ts +0 -13
- package/dist/features/before-after/repository/before-after.repository.js +0 -36
- package/dist/features/before-after/server.d.ts +0 -6
- package/dist/features/before-after/server.js +0 -6
- package/dist/features/cart/repository/__tests__/cart.repository.test.d.ts +0 -1
- package/dist/features/cart/repository/__tests__/cart.repository.test.js +0 -371
- package/dist/features/categories/repository/__tests__/categories.repository.test.d.ts +0 -1
- package/dist/features/categories/repository/__tests__/categories.repository.test.js +0 -813
- package/dist/features/collections/repository/collections.repository.d.ts +0 -8
- package/dist/features/collections/repository/collections.repository.js +0 -16
- package/dist/features/collections/server.d.ts +0 -6
- package/dist/features/collections/server.js +0 -6
- package/dist/features/events/repository/__tests__/event.repository.test.d.ts +0 -1
- package/dist/features/events/repository/__tests__/event.repository.test.js +0 -299
- package/dist/features/faq/repository/__tests__/faqs.repository.test.d.ts +0 -1
- package/dist/features/faq/repository/__tests__/faqs.repository.test.js +0 -311
- package/dist/features/forms/Form.d.ts +0 -25
- package/dist/features/forms/Form.js +0 -37
- package/dist/features/history/repository/__tests__/user-history.repository.test.d.ts +0 -1
- package/dist/features/history/repository/__tests__/user-history.repository.test.js +0 -180
- package/dist/features/homepage/repository/__tests__/carousel.repository.test.d.ts +0 -1
- package/dist/features/homepage/repository/__tests__/carousel.repository.test.js +0 -182
- package/dist/features/homepage/repository/__tests__/homepage-sections.repository.test.d.ts +0 -1
- package/dist/features/homepage/repository/__tests__/homepage-sections.repository.test.js +0 -185
- package/dist/features/layout/ListingLayout.d.ts +0 -34
- package/dist/features/layout/ListingLayout.js +0 -103
- package/dist/features/messages/repository/__tests__/conversations.repository.test.d.ts +0 -1
- package/dist/features/messages/repository/__tests__/conversations.repository.test.js +0 -257
- package/dist/features/orders/repository/__tests__/orders.repository.test.d.ts +0 -1
- package/dist/features/orders/repository/__tests__/orders.repository.test.js +0 -211
- package/dist/features/payments/repository/__tests__/payout.repository.test.d.ts +0 -1
- package/dist/features/payments/repository/__tests__/payout.repository.test.js +0 -292
- package/dist/features/pre-orders/repository/preorders.repository.d.ts +0 -8
- package/dist/features/pre-orders/repository/preorders.repository.js +0 -25
- package/dist/features/products/repository/__tests__/product-features.repository.test.d.ts +0 -1
- package/dist/features/products/repository/__tests__/product-features.repository.test.js +0 -329
- package/dist/features/products/repository/__tests__/products.repository.test.d.ts +0 -1
- package/dist/features/products/repository/__tests__/products.repository.test.js +0 -607
- package/dist/features/promotions/repository/__tests__/claimed-coupons.repository.test.d.ts +0 -1
- package/dist/features/promotions/repository/__tests__/claimed-coupons.repository.test.js +0 -219
- package/dist/features/promotions/repository/__tests__/coupons.repository.test.d.ts +0 -1
- package/dist/features/promotions/repository/__tests__/coupons.repository.test.js +0 -480
- package/dist/features/promotions/repository/promotions.repository.d.ts +0 -14
- package/dist/features/promotions/repository/promotions.repository.js +0 -43
- package/dist/features/reviews/repository/__tests__/reviews.repository.test.d.ts +0 -1
- package/dist/features/reviews/repository/__tests__/reviews.repository.test.js +0 -327
- package/dist/features/scams/repository/__tests__/scammer.repository.test.d.ts +0 -1
- package/dist/features/scams/repository/__tests__/scammer.repository.test.js +0 -385
- package/dist/features/search/repository/__tests__/search.repository.test.d.ts +0 -1
- package/dist/features/search/repository/__tests__/search.repository.test.js +0 -369
- package/dist/features/seller/components/SellerStatCard.d.ts +0 -14
- package/dist/features/seller/components/SellerStatCard.js +0 -6
- package/dist/features/seller/components/seller-products-styles.d.ts +0 -7
- package/dist/features/seller/components/seller-products-styles.js +0 -14
- package/dist/features/seller/repository/__tests__/offer.repository.test.d.ts +0 -1
- package/dist/features/seller/repository/__tests__/offer.repository.test.js +0 -458
- package/dist/features/seller/repository/seller.repository.d.ts +0 -22
- package/dist/features/seller/repository/seller.repository.js +0 -72
- package/dist/features/site-settings/components/__tests__/ThemeManagerView.test.d.ts +0 -1
- package/dist/features/site-settings/components/__tests__/ThemeManagerView.test.js +0 -37
- package/dist/features/stores/repository/__tests__/store.repository.test.d.ts +0 -1
- package/dist/features/stores/repository/__tests__/store.repository.test.js +0 -261
- package/dist/features/stores/repository/stores.repository.d.ts +0 -11
- package/dist/features/stores/repository/stores.repository.js +0 -37
- package/dist/features/support/repository/__tests__/support.repository.test.d.ts +0 -1
- package/dist/features/support/repository/__tests__/support.repository.test.js +0 -312
- package/dist/features/wishlist/repository/__tests__/user-wishlist.repository.test.d.ts +0 -1
- package/dist/features/wishlist/repository/__tests__/user-wishlist.repository.test.js +0 -139
- package/dist/features/wishlist/repository/wishlist.repository.d.ts +0 -13
- package/dist/features/wishlist/repository/wishlist.repository.js +0 -31
- package/dist/providers/db-firebase/__tests__/filter-aliases.test.d.ts +0 -1
- package/dist/providers/db-firebase/__tests__/filter-aliases.test.js +0 -93
- package/dist/providers/shipping-shiprocket/index.d.ts +0 -297
- package/dist/providers/shipping-shiprocket/index.js +0 -194
- package/dist/providers/shipping-shiprocket/shiprocket-provider.d.ts +0 -45
- package/dist/providers/shipping-shiprocket/shiprocket-provider.js +0 -168
- package/dist/react/contexts/ThemeContext.d.ts +0 -13
- package/dist/react/contexts/ThemeContext.js +0 -64
- package/dist/schemas/webhooks/shiprocket.d.ts +0 -30
- package/dist/schemas/webhooks/shiprocket.js +0 -22
- package/dist/seed/actions/demo-seed-actions.d.ts +0 -42
- package/dist/seed/actions/demo-seed-actions.js +0 -36
- package/dist/seed/actions/index.d.ts +0 -1
- package/dist/seed/actions/index.js +0 -1
- package/dist/seed/sub-listings-seed-data.d.ts +0 -123
- package/dist/seed/sub-listings-seed-data.js +0 -447
- package/dist/seed/tester-checklist-seed-data.d.ts +0 -2
- package/dist/seed/tester-checklist-seed-data.js +0 -248
- package/dist/ui/components/DashboardStatsCard.d.ts +0 -15
- package/dist/ui/components/DashboardStatsCard.js +0 -27
- package/dist/ui/components/DashboardStatsCard.style.css +0 -68
- package/dist/ui/components/DynamicSelect.d.ts +0 -23
- package/dist/ui/components/DynamicSelect.js +0 -77
- package/dist/ui/components/DynamicSelect.style.css +0 -101
- package/dist/ui/components/InlineCreateSelect.d.ts +0 -48
- package/dist/ui/components/InlineCreateSelect.js +0 -75
- package/dist/ui/components/ListingViewShell.d.ts +0 -37
- package/dist/ui/components/ListingViewShell.js +0 -9
- package/dist/ui/components/PaginatedMultiSelect.d.ts +0 -28
- package/dist/ui/components/PaginatedMultiSelect.js +0 -141
- package/dist/ui/components/PaginatedMultiSelect.style.css +0 -272
- package/dist/ui/components/SectionTabs.d.ts +0 -19
- package/dist/ui/components/SectionTabs.js +0 -66
- package/dist/ui/components/SectionTabs.style.css +0 -164
- package/dist/ui/components/__tests__/BulkActionBar.test.d.ts +0 -1
- package/dist/ui/components/__tests__/BulkActionBar.test.js +0 -96
- package/dist/ui/components/__tests__/ListingToolbar.test.d.ts +0 -1
- package/dist/ui/components/__tests__/ListingToolbar.test.js +0 -125
- package/dist/ui/components/__tests__/new-primitives.test.d.ts +0 -1
- package/dist/ui/components/__tests__/new-primitives.test.js +0 -187
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
// Mock all repository imports before importing the module under test.
|
|
3
|
-
vi.mock("../../../../../repositories", () => ({
|
|
4
|
-
productRepository: { list: vi.fn() },
|
|
5
|
-
blogRepository: { listAll: vi.fn() },
|
|
6
|
-
eventRepository: { list: vi.fn() },
|
|
7
|
-
couponsRepository: { list: vi.fn() },
|
|
8
|
-
storeRepository: { listStores: vi.fn() },
|
|
9
|
-
categoriesRepository: { list: vi.fn() },
|
|
10
|
-
bidRepository: { list: vi.fn() },
|
|
11
|
-
payoutRepository: { list: vi.fn() },
|
|
12
|
-
orderRepository: { listAll: vi.fn() },
|
|
13
|
-
reviewRepository: { listAll: vi.fn() },
|
|
14
|
-
faqsRepository: { list: vi.fn() },
|
|
15
|
-
notificationRepository: { list: vi.fn() },
|
|
16
|
-
scammerRepository: { listAll: vi.fn() },
|
|
17
|
-
productFeaturesRepository: { list: vi.fn() },
|
|
18
|
-
homepageSectionsRepository: { list: vi.fn() },
|
|
19
|
-
userRepository: { list: vi.fn() },
|
|
20
|
-
eventEntryRepository: { listForEvent: vi.fn() },
|
|
21
|
-
productTemplateRepository: { listByStore: vi.fn() },
|
|
22
|
-
}));
|
|
23
|
-
import { runListingProcessor } from "../listingProcessor";
|
|
24
|
-
import { productRepository, blogRepository, eventRepository, couponsRepository, storeRepository, } from "../../../../../repositories";
|
|
25
|
-
function makeCtx() {
|
|
26
|
-
return {
|
|
27
|
-
job: "test",
|
|
28
|
-
db: {},
|
|
29
|
-
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
30
|
-
env: vi.fn(),
|
|
31
|
-
now: new Date(),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
const EMPTY_RESULT = {
|
|
35
|
-
items: [],
|
|
36
|
-
total: 0,
|
|
37
|
-
page: 1,
|
|
38
|
-
pageSize: 20,
|
|
39
|
-
totalPages: 0,
|
|
40
|
-
hasMore: false,
|
|
41
|
-
};
|
|
42
|
-
beforeEach(() => {
|
|
43
|
-
vi.clearAllMocks();
|
|
44
|
-
productRepository.list.mockResolvedValue(EMPTY_RESULT);
|
|
45
|
-
blogRepository.listAll.mockResolvedValue(EMPTY_RESULT);
|
|
46
|
-
eventRepository.list.mockResolvedValue(EMPTY_RESULT);
|
|
47
|
-
couponsRepository.list.mockResolvedValue(EMPTY_RESULT);
|
|
48
|
-
storeRepository.listStores.mockResolvedValue(EMPTY_RESULT);
|
|
49
|
-
});
|
|
50
|
-
describe("runListingProcessor", () => {
|
|
51
|
-
it("throws 400 when body is missing collection", async () => {
|
|
52
|
-
const ctx = makeCtx();
|
|
53
|
-
await expect(runListingProcessor({}, ctx)).rejects.toMatchObject({ httpStatus: 400, message: "Missing collection" });
|
|
54
|
-
});
|
|
55
|
-
it("throws 400 for an unsupported collection name", async () => {
|
|
56
|
-
const ctx = makeCtx();
|
|
57
|
-
await expect(runListingProcessor({ collection: "nonexistent" }, ctx)).rejects.toMatchObject({ httpStatus: 400 });
|
|
58
|
-
});
|
|
59
|
-
it("calls the correct lister for 'products'", async () => {
|
|
60
|
-
const ctx = makeCtx();
|
|
61
|
-
await runListingProcessor({ collection: "products", f: "status==published" }, ctx);
|
|
62
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ filters: "status==published" }), {});
|
|
63
|
-
});
|
|
64
|
-
it("calls blogRepository for 'blogPosts'", async () => {
|
|
65
|
-
const ctx = makeCtx();
|
|
66
|
-
await runListingProcessor({ collection: "blogPosts" }, ctx);
|
|
67
|
-
expect(blogRepository.listAll).toHaveBeenCalled();
|
|
68
|
-
});
|
|
69
|
-
it("calls eventRepository for 'events'", async () => {
|
|
70
|
-
const ctx = makeCtx();
|
|
71
|
-
await runListingProcessor({ collection: "events" }, ctx);
|
|
72
|
-
expect(eventRepository.list).toHaveBeenCalled();
|
|
73
|
-
});
|
|
74
|
-
it("passes filters and sorts to the lister", async () => {
|
|
75
|
-
const ctx = makeCtx();
|
|
76
|
-
await runListingProcessor({
|
|
77
|
-
collection: "products",
|
|
78
|
-
f: "brand==hasbro",
|
|
79
|
-
s: "-price",
|
|
80
|
-
}, ctx);
|
|
81
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ filters: "brand==hasbro", sorts: "-price" }), {});
|
|
82
|
-
});
|
|
83
|
-
it("uses default sort when s is absent", async () => {
|
|
84
|
-
const ctx = makeCtx();
|
|
85
|
-
await runListingProcessor({ collection: "products" }, ctx);
|
|
86
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ sorts: "-createdAt" }), {});
|
|
87
|
-
});
|
|
88
|
-
it("clamps pageSize to MAX_PAGE_SIZE (100)", async () => {
|
|
89
|
-
const ctx = makeCtx();
|
|
90
|
-
await runListingProcessor({ collection: "products", ps: 999 }, ctx);
|
|
91
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ pageSize: "100" }), {});
|
|
92
|
-
});
|
|
93
|
-
it("uses DEFAULT_PAGE_SIZE when ps is 0", async () => {
|
|
94
|
-
const ctx = makeCtx();
|
|
95
|
-
await runListingProcessor({ collection: "products", ps: 0 }, ctx);
|
|
96
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ pageSize: "20" }), {});
|
|
97
|
-
});
|
|
98
|
-
it("uses DEFAULT_PAGE_SIZE when ps is negative", async () => {
|
|
99
|
-
const ctx = makeCtx();
|
|
100
|
-
await runListingProcessor({ collection: "products", ps: -5 }, ctx);
|
|
101
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ pageSize: "20" }), {});
|
|
102
|
-
});
|
|
103
|
-
it("reads page from p param", async () => {
|
|
104
|
-
const ctx = makeCtx();
|
|
105
|
-
await runListingProcessor({ collection: "products", p: 3 }, ctx);
|
|
106
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ page: "3" }), {});
|
|
107
|
-
});
|
|
108
|
-
it("decodes a valid cursor and uses its page over p", async () => {
|
|
109
|
-
// Encode page=5 as a cursor
|
|
110
|
-
const cursor = Buffer.from(JSON.stringify({ page: 5 }), "utf8").toString("base64");
|
|
111
|
-
const ctx = makeCtx();
|
|
112
|
-
await runListingProcessor({ collection: "products", cursor, p: 1 }, ctx);
|
|
113
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ page: "5" }), {});
|
|
114
|
-
});
|
|
115
|
-
it("falls back to p when cursor is invalid base64 JSON", async () => {
|
|
116
|
-
const ctx = makeCtx();
|
|
117
|
-
await runListingProcessor({ collection: "products", cursor: "!!!notbase64!!!", p: 2 }, ctx);
|
|
118
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.objectContaining({ page: "2" }), {});
|
|
119
|
-
});
|
|
120
|
-
it("encodes the next cursor when hasMore is true", async () => {
|
|
121
|
-
productRepository.list.mockResolvedValue({
|
|
122
|
-
...EMPTY_RESULT,
|
|
123
|
-
hasMore: true,
|
|
124
|
-
page: 1,
|
|
125
|
-
});
|
|
126
|
-
const ctx = makeCtx();
|
|
127
|
-
const result = await runListingProcessor({ collection: "products", p: 1 }, ctx);
|
|
128
|
-
expect(result.cursor).not.toBeNull();
|
|
129
|
-
// Decode and verify it points to page 2
|
|
130
|
-
const decoded = JSON.parse(Buffer.from(result.cursor, "base64").toString("utf8"));
|
|
131
|
-
expect(decoded.page).toBe(2);
|
|
132
|
-
});
|
|
133
|
-
it("returns null cursor when hasMore is false", async () => {
|
|
134
|
-
const ctx = makeCtx();
|
|
135
|
-
const result = await runListingProcessor({ collection: "products" }, ctx);
|
|
136
|
-
expect(result.cursor).toBeNull();
|
|
137
|
-
});
|
|
138
|
-
it("passes baseOpts to the lister", async () => {
|
|
139
|
-
const ctx = makeCtx();
|
|
140
|
-
await runListingProcessor({
|
|
141
|
-
collection: "products",
|
|
142
|
-
baseOpts: { storeId: "store-abc" },
|
|
143
|
-
}, ctx);
|
|
144
|
-
expect(productRepository.list).toHaveBeenCalledWith(expect.any(Object), { storeId: "store-abc" });
|
|
145
|
-
});
|
|
146
|
-
it("calls stores lister with activeOnly=true by default", async () => {
|
|
147
|
-
const ctx = makeCtx();
|
|
148
|
-
await runListingProcessor({ collection: "stores" }, ctx);
|
|
149
|
-
expect(storeRepository.listStores).toHaveBeenCalledWith(expect.any(Object), true);
|
|
150
|
-
});
|
|
151
|
-
it("returns the items from the lister result", async () => {
|
|
152
|
-
const items = [{ id: "p1" }, { id: "p2" }];
|
|
153
|
-
productRepository.list.mockResolvedValue({
|
|
154
|
-
...EMPTY_RESULT,
|
|
155
|
-
items,
|
|
156
|
-
total: 2,
|
|
157
|
-
});
|
|
158
|
-
const ctx = makeCtx();
|
|
159
|
-
const result = await runListingProcessor({ collection: "products" }, ctx);
|
|
160
|
-
expect(result.items).toEqual(items);
|
|
161
|
-
expect(result.total).toBe(2);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
vi.mock("../../../../../providers/db-firebase/admin-storage-lite", () => ({
|
|
3
|
-
getAdminStorageLite: vi.fn(),
|
|
4
|
-
}));
|
|
5
|
-
import { runMediaTmpCleanup } from "../mediaTmpCleanup";
|
|
6
|
-
import { getAdminStorageLite } from "../../../../../providers/db-firebase/admin-storage-lite";
|
|
7
|
-
function makeCtx(envOverrides = {}) {
|
|
8
|
-
return {
|
|
9
|
-
job: "media-tmp-cleanup",
|
|
10
|
-
db: {},
|
|
11
|
-
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
12
|
-
env: (key) => envOverrides[key],
|
|
13
|
-
now: new Date("2026-01-15T12:00:00Z"),
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
function makeFile(name, updatedOffset, cutoffBase) {
|
|
17
|
-
const updated = new Date(cutoffBase.getTime() + updatedOffset).toISOString();
|
|
18
|
-
return {
|
|
19
|
-
name,
|
|
20
|
-
getMetadata: vi.fn().mockResolvedValue([{ updated }]),
|
|
21
|
-
delete: vi.fn().mockResolvedValue(undefined),
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function setupBucket(files) {
|
|
25
|
-
const bucket = {
|
|
26
|
-
getFiles: vi.fn().mockResolvedValue([files]),
|
|
27
|
-
};
|
|
28
|
-
getAdminStorageLite.mockReturnValue({
|
|
29
|
-
bucket: vi.fn(() => bucket),
|
|
30
|
-
});
|
|
31
|
-
return bucket;
|
|
32
|
-
}
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
vi.clearAllMocks();
|
|
35
|
-
delete process.env.FIREBASE_ADMIN_STORAGE_BUCKET;
|
|
36
|
-
delete process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET;
|
|
37
|
-
});
|
|
38
|
-
describe("runMediaTmpCleanup", () => {
|
|
39
|
-
it("does nothing when no files exist under tmp/", async () => {
|
|
40
|
-
setupBucket([]);
|
|
41
|
-
const ctx = makeCtx();
|
|
42
|
-
await runMediaTmpCleanup(ctx);
|
|
43
|
-
// Should complete without error
|
|
44
|
-
});
|
|
45
|
-
it("skips files newer than the TTL cutoff", async () => {
|
|
46
|
-
// cutoff = now - 24h; file updated 1ms AFTER cutoff → not stale
|
|
47
|
-
const ctx = makeCtx();
|
|
48
|
-
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
49
|
-
const newFile = makeFile("tmp/new-file.jpg", 1000, cutoff); // updated after cutoff
|
|
50
|
-
setupBucket([newFile]);
|
|
51
|
-
await runMediaTmpCleanup(ctx);
|
|
52
|
-
expect(newFile.delete).not.toHaveBeenCalled();
|
|
53
|
-
});
|
|
54
|
-
it("deletes files older than the TTL cutoff", async () => {
|
|
55
|
-
const ctx = makeCtx();
|
|
56
|
-
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
57
|
-
const oldFile = makeFile("tmp/old-file.jpg", -1000, cutoff); // updated before cutoff
|
|
58
|
-
setupBucket([oldFile]);
|
|
59
|
-
await runMediaTmpCleanup(ctx);
|
|
60
|
-
expect(oldFile.delete).toHaveBeenCalledOnce();
|
|
61
|
-
});
|
|
62
|
-
it("uses MEDIA_TMP_TTL_HOURS env var to override default TTL", async () => {
|
|
63
|
-
const ctx = makeCtx({ MEDIA_TMP_TTL_HOURS: "1" });
|
|
64
|
-
// With 1h TTL, cutoff = now - 1h
|
|
65
|
-
// A file updated 2h ago should be deleted
|
|
66
|
-
const cutoff = new Date(Date.now() - 1 * 60 * 60 * 1000);
|
|
67
|
-
const twoHourOldFile = makeFile("tmp/old.jpg", -60 * 60 * 1000, cutoff);
|
|
68
|
-
setupBucket([twoHourOldFile]);
|
|
69
|
-
await runMediaTmpCleanup(ctx);
|
|
70
|
-
expect(twoHourOldFile.delete).toHaveBeenCalledOnce();
|
|
71
|
-
});
|
|
72
|
-
it("swallows 404 errors without logging them as errors", async () => {
|
|
73
|
-
const ctx = makeCtx();
|
|
74
|
-
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
75
|
-
const staleFile = makeFile("tmp/gone.jpg", -1000, cutoff);
|
|
76
|
-
const notFoundErr = Object.assign(new Error("Not found"), { code: 404 });
|
|
77
|
-
staleFile.delete.mockRejectedValue(notFoundErr);
|
|
78
|
-
setupBucket([staleFile]);
|
|
79
|
-
await expect(runMediaTmpCleanup(ctx)).resolves.toBeUndefined();
|
|
80
|
-
expect(ctx.logger.error).not.toHaveBeenCalledWith("Failed to delete tmp file", expect.anything(), expect.anything());
|
|
81
|
-
});
|
|
82
|
-
it("logs a non-404 delete error but continues processing", async () => {
|
|
83
|
-
const ctx = makeCtx();
|
|
84
|
-
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
85
|
-
const failFile = makeFile("tmp/fail.jpg", -1000, cutoff);
|
|
86
|
-
const okFile = makeFile("tmp/ok.jpg", -2000, cutoff);
|
|
87
|
-
const genericErr = Object.assign(new Error("Permission denied"), { code: 403 });
|
|
88
|
-
failFile.delete.mockRejectedValue(genericErr);
|
|
89
|
-
setupBucket([failFile, okFile]);
|
|
90
|
-
await runMediaTmpCleanup(ctx);
|
|
91
|
-
expect(ctx.logger.error).toHaveBeenCalledWith("Failed to delete tmp file", genericErr, expect.any(Object));
|
|
92
|
-
expect(okFile.delete).toHaveBeenCalledOnce();
|
|
93
|
-
});
|
|
94
|
-
it("skips files missing updated/timeCreated metadata", async () => {
|
|
95
|
-
const ctx = makeCtx();
|
|
96
|
-
const noMetaFile = {
|
|
97
|
-
name: "tmp/no-meta.jpg",
|
|
98
|
-
getMetadata: vi.fn().mockResolvedValue([{}]),
|
|
99
|
-
delete: vi.fn(),
|
|
100
|
-
};
|
|
101
|
-
setupBucket([noMetaFile]);
|
|
102
|
-
await runMediaTmpCleanup(ctx);
|
|
103
|
-
expect(noMetaFile.delete).not.toHaveBeenCalled();
|
|
104
|
-
});
|
|
105
|
-
it("throws when bucket.getFiles itself fails", async () => {
|
|
106
|
-
const bucket = {
|
|
107
|
-
getFiles: vi.fn().mockRejectedValue(new Error("Storage unavailable")),
|
|
108
|
-
};
|
|
109
|
-
getAdminStorageLite.mockReturnValue({
|
|
110
|
-
bucket: vi.fn(() => bucket),
|
|
111
|
-
});
|
|
112
|
-
const ctx = makeCtx();
|
|
113
|
-
await expect(runMediaTmpCleanup(ctx)).rejects.toThrow("Storage unavailable");
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
const { mockGetWinningBid, mockMarkWinning, mockMarkOutbid, mockIncrementBidCount, mockBatchCommit, mockBatchUpdate, mockSendNotification, mockRtdbPush, mockDecryptPii, } = vi.hoisted(() => ({
|
|
3
|
-
mockGetWinningBid: vi.fn(),
|
|
4
|
-
mockMarkWinning: vi.fn(),
|
|
5
|
-
mockMarkOutbid: vi.fn(),
|
|
6
|
-
mockIncrementBidCount: vi.fn(),
|
|
7
|
-
mockBatchCommit: vi.fn().mockResolvedValue(undefined),
|
|
8
|
-
mockBatchUpdate: vi.fn(),
|
|
9
|
-
mockSendNotification: vi.fn().mockResolvedValue(undefined),
|
|
10
|
-
mockRtdbPush: vi.fn().mockResolvedValue(undefined),
|
|
11
|
-
mockDecryptPii: vi.fn((v) => v),
|
|
12
|
-
}));
|
|
13
|
-
vi.mock("../../../../../repositories", () => ({
|
|
14
|
-
bidRepository: {
|
|
15
|
-
getWinningBid: mockGetWinningBid,
|
|
16
|
-
markWinning: mockMarkWinning,
|
|
17
|
-
markOutbid: mockMarkOutbid,
|
|
18
|
-
},
|
|
19
|
-
productRepository: {
|
|
20
|
-
incrementBidCountInBatch: mockIncrementBidCount,
|
|
21
|
-
},
|
|
22
|
-
}));
|
|
23
|
-
vi.mock("../../../../../features/admin/actions/notification-actions", () => ({
|
|
24
|
-
sendNotification: mockSendNotification,
|
|
25
|
-
}));
|
|
26
|
-
vi.mock("../../../../../providers/db-firebase", () => ({
|
|
27
|
-
getAdminRealtimeDb: vi.fn(() => ({
|
|
28
|
-
ref: vi.fn(() => ({ push: mockRtdbPush })),
|
|
29
|
-
})),
|
|
30
|
-
}));
|
|
31
|
-
vi.mock("../../../../../security/index", () => ({
|
|
32
|
-
decryptPii: mockDecryptPii,
|
|
33
|
-
}));
|
|
34
|
-
vi.mock("../../../../../errors/normalize", () => ({
|
|
35
|
-
normalizeError: vi.fn(),
|
|
36
|
-
}));
|
|
37
|
-
import { handleBidPlaced } from "../onBidPlaced";
|
|
38
|
-
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
39
|
-
function makeCtx() {
|
|
40
|
-
const batch = {
|
|
41
|
-
update: mockBatchUpdate,
|
|
42
|
-
commit: mockBatchCommit,
|
|
43
|
-
set: vi.fn(),
|
|
44
|
-
delete: vi.fn(),
|
|
45
|
-
};
|
|
46
|
-
return {
|
|
47
|
-
db: {
|
|
48
|
-
collection: vi.fn().mockReturnValue({
|
|
49
|
-
doc: vi.fn().mockReturnValue({ id: "bid-ref-1" }),
|
|
50
|
-
}),
|
|
51
|
-
batch: vi.fn().mockReturnValue(batch),
|
|
52
|
-
},
|
|
53
|
-
now: new Date(),
|
|
54
|
-
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function makeInput(overrides = {}) {
|
|
58
|
-
return {
|
|
59
|
-
bidId: "bid-charizard-ravi-001",
|
|
60
|
-
bid: {
|
|
61
|
-
id: "bid-charizard-ravi-001",
|
|
62
|
-
productId: "auction-charizard",
|
|
63
|
-
productTitle: "Pokemon Charizard",
|
|
64
|
-
userId: "user-ravi",
|
|
65
|
-
userName: "Ravi Kumar",
|
|
66
|
-
bidAmount: 25000,
|
|
67
|
-
currency: "INR",
|
|
68
|
-
...overrides,
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function makePrevWinning(userId = "user-ankit") {
|
|
73
|
-
return {
|
|
74
|
-
ref: { id: "bid-ref-prev" },
|
|
75
|
-
data: { userId, bidAmount: 20000 },
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
beforeEach(() => {
|
|
79
|
-
vi.clearAllMocks();
|
|
80
|
-
mockBatchCommit.mockResolvedValue(undefined);
|
|
81
|
-
mockSendNotification.mockResolvedValue(undefined);
|
|
82
|
-
mockRtdbPush.mockResolvedValue(undefined);
|
|
83
|
-
mockDecryptPii.mockImplementation((v) => v);
|
|
84
|
-
mockGetWinningBid.mockResolvedValue(null);
|
|
85
|
-
});
|
|
86
|
-
// ── Tests ────────────────────────────────────────────────────────────────────
|
|
87
|
-
describe("handleBidPlaced — marks new bid as winning", () => {
|
|
88
|
-
it("calls bidRepository.markWinning with new bid ref", async () => {
|
|
89
|
-
const ctx = makeCtx();
|
|
90
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
91
|
-
expect(mockMarkWinning).toHaveBeenCalledWith(expect.any(Object), expect.any(Object));
|
|
92
|
-
});
|
|
93
|
-
it("calls productRepository.incrementBidCountInBatch with correct args", async () => {
|
|
94
|
-
const ctx = makeCtx();
|
|
95
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
96
|
-
expect(mockIncrementBidCount).toHaveBeenCalledWith(expect.any(Object), "auction-charizard", 25000, "user-ravi");
|
|
97
|
-
});
|
|
98
|
-
it("commits the batch", async () => {
|
|
99
|
-
const ctx = makeCtx();
|
|
100
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
101
|
-
expect(mockBatchCommit).toHaveBeenCalledOnce();
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
describe("handleBidPlaced — first bid (no previous winner)", () => {
|
|
105
|
-
it("does NOT call markOutbid when no previous winner", async () => {
|
|
106
|
-
mockGetWinningBid.mockResolvedValue(null);
|
|
107
|
-
const ctx = makeCtx();
|
|
108
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
109
|
-
expect(mockMarkOutbid).not.toHaveBeenCalled();
|
|
110
|
-
});
|
|
111
|
-
it("does NOT send outbid notification when no previous winner", async () => {
|
|
112
|
-
mockGetWinningBid.mockResolvedValue(null);
|
|
113
|
-
const ctx = makeCtx();
|
|
114
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
115
|
-
expect(mockSendNotification).not.toHaveBeenCalled();
|
|
116
|
-
});
|
|
117
|
-
it("does NOT push to RTDB when no previous winner", async () => {
|
|
118
|
-
mockGetWinningBid.mockResolvedValue(null);
|
|
119
|
-
const ctx = makeCtx();
|
|
120
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
121
|
-
expect(mockRtdbPush).not.toHaveBeenCalled();
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
describe("handleBidPlaced — outbid notification", () => {
|
|
125
|
-
it("marks previous winner as outbid when different user", async () => {
|
|
126
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ankit"));
|
|
127
|
-
const ctx = makeCtx();
|
|
128
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
129
|
-
expect(mockMarkOutbid).toHaveBeenCalledWith(expect.any(Object), expect.any(Object));
|
|
130
|
-
});
|
|
131
|
-
it("sends bid_outbid notification to the outbid user", async () => {
|
|
132
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ankit"));
|
|
133
|
-
const ctx = makeCtx();
|
|
134
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
135
|
-
expect(mockSendNotification).toHaveBeenCalledWith(expect.objectContaining({ userId: "user-ankit", type: "bid_outbid" }));
|
|
136
|
-
});
|
|
137
|
-
it("pushes outbid event to RTDB for real-time notification", async () => {
|
|
138
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ankit"));
|
|
139
|
-
const ctx = makeCtx();
|
|
140
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
141
|
-
expect(mockRtdbPush).toHaveBeenCalledWith(expect.objectContaining({ type: "bid_outbid" }));
|
|
142
|
-
});
|
|
143
|
-
it("outbid notification message includes bid amount and product title", async () => {
|
|
144
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ankit"));
|
|
145
|
-
const ctx = makeCtx();
|
|
146
|
-
await handleBidPlaced(makeInput({ productTitle: "Charizard 1st Ed", bidAmount: 30000 }), ctx);
|
|
147
|
-
const notifCall = mockSendNotification.mock.calls[0][0];
|
|
148
|
-
expect(notifCall.message).toMatch(/Charizard 1st Ed/);
|
|
149
|
-
});
|
|
150
|
-
it("does NOT outbid the same user who placed the new bid", async () => {
|
|
151
|
-
// Same user re-bids (bidder is already the winner)
|
|
152
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ravi")); // same as input.bid.userId
|
|
153
|
-
const ctx = makeCtx();
|
|
154
|
-
await handleBidPlaced(makeInput({ userId: "user-ravi" }), ctx);
|
|
155
|
-
expect(mockMarkOutbid).not.toHaveBeenCalled();
|
|
156
|
-
expect(mockSendNotification).not.toHaveBeenCalled();
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
describe("handleBidPlaced — RTDB failure is non-fatal", () => {
|
|
160
|
-
it("RTDB push failure → logs but does NOT re-throw", async () => {
|
|
161
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ankit"));
|
|
162
|
-
mockRtdbPush.mockRejectedValue(new Error("RTDB unavailable"));
|
|
163
|
-
const ctx = makeCtx();
|
|
164
|
-
await expect(handleBidPlaced(makeInput(), ctx)).resolves.toBeUndefined();
|
|
165
|
-
expect(ctx.logger.error).toHaveBeenCalledWith(expect.stringMatching(/Realtime DB/i), expect.any(Error));
|
|
166
|
-
});
|
|
167
|
-
it("Firestore outbid notification still sent even if RTDB fails", async () => {
|
|
168
|
-
mockGetWinningBid.mockResolvedValue(makePrevWinning("user-ankit"));
|
|
169
|
-
mockRtdbPush.mockRejectedValue(new Error("RTDB unavailable"));
|
|
170
|
-
const ctx = makeCtx();
|
|
171
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
172
|
-
// sendNotification (Firestore) should still have been called before RTDB
|
|
173
|
-
expect(mockSendNotification).toHaveBeenCalledWith(expect.objectContaining({ type: "bid_outbid" }));
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
describe("handleBidPlaced — PII decryption", () => {
|
|
177
|
-
it("decrypts userName via decryptPii before use", async () => {
|
|
178
|
-
mockDecryptPii.mockImplementation((v) => `decrypted:${v}`);
|
|
179
|
-
const ctx = makeCtx();
|
|
180
|
-
await handleBidPlaced(makeInput({ userName: "encrypted_name" }), ctx);
|
|
181
|
-
expect(mockDecryptPii).toHaveBeenCalledWith("encrypted_name");
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
describe("handleBidPlaced — error propagation", () => {
|
|
185
|
-
it("Firestore batch.commit failure → re-throws", async () => {
|
|
186
|
-
mockBatchCommit.mockRejectedValue(new Error("Firestore unavailable"));
|
|
187
|
-
const ctx = makeCtx();
|
|
188
|
-
await expect(handleBidPlaced(makeInput(), ctx)).rejects.toThrow("Firestore unavailable");
|
|
189
|
-
});
|
|
190
|
-
it("logs error with bidId and productId before re-throwing", async () => {
|
|
191
|
-
mockBatchCommit.mockRejectedValue(new Error("Firestore unavailable"));
|
|
192
|
-
const ctx = makeCtx();
|
|
193
|
-
try {
|
|
194
|
-
await handleBidPlaced(makeInput(), ctx);
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
// expected
|
|
198
|
-
}
|
|
199
|
-
expect(ctx.logger.error).toHaveBeenCalledWith(expect.any(String), expect.any(Error), expect.objectContaining({ bidId: "bid-charizard-ravi-001" }));
|
|
200
|
-
});
|
|
201
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
const { mockSendWhatsApp, mockBuildMessage, mockStoreFindBySlug, mockUserFindById, mockDecryptPii, } = vi.hoisted(() => ({
|
|
3
|
-
mockSendWhatsApp: vi.fn(),
|
|
4
|
-
mockBuildMessage: vi.fn().mockReturnValue("Purchase announcement message"),
|
|
5
|
-
mockStoreFindBySlug: vi.fn(),
|
|
6
|
-
mockUserFindById: vi.fn(),
|
|
7
|
-
mockDecryptPii: vi.fn((v) => v),
|
|
8
|
-
}));
|
|
9
|
-
vi.mock("../../../../../repositories", () => ({
|
|
10
|
-
storeRepository: { findBySlug: mockStoreFindBySlug },
|
|
11
|
-
userRepository: { findById: mockUserFindById },
|
|
12
|
-
}));
|
|
13
|
-
vi.mock("../../../../../features/whatsapp-bot/server", () => ({
|
|
14
|
-
sendWhatsAppBusinessMessage: mockSendWhatsApp,
|
|
15
|
-
buildPurchaseAnnouncementMessage: mockBuildMessage,
|
|
16
|
-
}));
|
|
17
|
-
vi.mock("../../../../../security/index", () => ({
|
|
18
|
-
decryptPii: mockDecryptPii,
|
|
19
|
-
}));
|
|
20
|
-
vi.mock("../../../../../errors/normalize", () => ({
|
|
21
|
-
normalizeError: vi.fn(),
|
|
22
|
-
}));
|
|
23
|
-
import { handleOrderCreate } from "../onOrderCreate";
|
|
24
|
-
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
25
|
-
function makeCtx(envOverrides = {}) {
|
|
26
|
-
const defaults = {
|
|
27
|
-
WHATSAPP_PHONE_NUMBER_ID: "phone-number-id-123",
|
|
28
|
-
WHATSAPP_CLOUD_API_TOKEN: "token-abc",
|
|
29
|
-
WHATSAPP_ADMIN_NOTIFY_NUMBERS: "919876543210",
|
|
30
|
-
...envOverrides,
|
|
31
|
-
};
|
|
32
|
-
return {
|
|
33
|
-
env: (key) => defaults[key],
|
|
34
|
-
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
function makeInput(overrides = {}) {
|
|
38
|
-
return {
|
|
39
|
-
orderId: "order-1",
|
|
40
|
-
order: {
|
|
41
|
-
buyerDisplayName: "Ravi Kumar",
|
|
42
|
-
buyerId: "user-ravi",
|
|
43
|
-
items: [{ title: "Pokemon Charizard" }],
|
|
44
|
-
totalAmount: 25000,
|
|
45
|
-
storeId: "store-pokemon-palace",
|
|
46
|
-
...overrides,
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
beforeEach(() => {
|
|
51
|
-
vi.clearAllMocks();
|
|
52
|
-
mockSendWhatsApp.mockResolvedValue(true);
|
|
53
|
-
mockBuildMessage.mockReturnValue("Purchase announcement message");
|
|
54
|
-
mockDecryptPii.mockImplementation((v) => v);
|
|
55
|
-
mockStoreFindBySlug.mockResolvedValue(null);
|
|
56
|
-
mockUserFindById.mockResolvedValue(null);
|
|
57
|
-
});
|
|
58
|
-
// ── Tests ────────────────────────────────────────────────────────────────────
|
|
59
|
-
describe("handleOrderCreate — WhatsApp not configured", () => {
|
|
60
|
-
it("skips when WHATSAPP_PHONE_NUMBER_ID is missing", async () => {
|
|
61
|
-
const ctx = makeCtx({ WHATSAPP_PHONE_NUMBER_ID: undefined });
|
|
62
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
63
|
-
expect(mockSendWhatsApp).not.toHaveBeenCalled();
|
|
64
|
-
});
|
|
65
|
-
it("skips when WHATSAPP_CLOUD_API_TOKEN is missing", async () => {
|
|
66
|
-
const ctx = makeCtx({ WHATSAPP_CLOUD_API_TOKEN: undefined });
|
|
67
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
68
|
-
expect(mockSendWhatsApp).not.toHaveBeenCalled();
|
|
69
|
-
});
|
|
70
|
-
it("logs that WhatsApp is not configured", async () => {
|
|
71
|
-
const ctx = makeCtx({ WHATSAPP_PHONE_NUMBER_ID: undefined });
|
|
72
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
73
|
-
expect(ctx.logger.info).toHaveBeenCalledWith(expect.stringMatching(/not configured/i), expect.any(Object));
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe("handleOrderCreate — admin notification", () => {
|
|
77
|
-
it("sends announcement to each admin number in WHATSAPP_ADMIN_NOTIFY_NUMBERS", async () => {
|
|
78
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "919876543210,918765432109" });
|
|
79
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
80
|
-
expect(mockSendWhatsApp).toHaveBeenCalledTimes(2);
|
|
81
|
-
});
|
|
82
|
-
it("sends to 0 admin numbers when env var is empty", async () => {
|
|
83
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "" });
|
|
84
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
85
|
-
// No admin calls, store lookup still happens
|
|
86
|
-
const waCallArgs = mockSendWhatsApp.mock.calls.map((c) => c[0].toPhone);
|
|
87
|
-
expect(waCallArgs).toHaveLength(0);
|
|
88
|
-
});
|
|
89
|
-
it("strips non-digit chars from admin numbers", async () => {
|
|
90
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "+91 987-654-3210" });
|
|
91
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
92
|
-
const call = mockSendWhatsApp.mock.calls[0][0];
|
|
93
|
-
expect(call.toPhone).toBe("919876543210");
|
|
94
|
-
});
|
|
95
|
-
it("sends announcement with the built message", async () => {
|
|
96
|
-
const ctx = makeCtx();
|
|
97
|
-
mockBuildMessage.mockReturnValue("Custom message content");
|
|
98
|
-
await handleOrderCreate(makeInput(), ctx);
|
|
99
|
-
const call = mockSendWhatsApp.mock.calls[0][0];
|
|
100
|
-
expect(call.message).toBe("Custom message content");
|
|
101
|
-
});
|
|
102
|
-
it("one admin send failure is non-fatal, function still completes", async () => {
|
|
103
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "91111,91222" });
|
|
104
|
-
mockSendWhatsApp.mockRejectedValueOnce(new Error("WA error")).mockResolvedValue(true);
|
|
105
|
-
await expect(handleOrderCreate(makeInput(), ctx)).resolves.toBeUndefined();
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
describe("handleOrderCreate — store owner notification", () => {
|
|
109
|
-
it("sends to store owner phone when store + owner + phone all exist", async () => {
|
|
110
|
-
mockStoreFindBySlug.mockResolvedValue({ ownerId: "user-seller-1" });
|
|
111
|
-
mockUserFindById.mockResolvedValue({ phoneNumber: "encrypted_phone_91999" });
|
|
112
|
-
mockDecryptPii.mockReturnValue("919999999999");
|
|
113
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "" });
|
|
114
|
-
await handleOrderCreate(makeInput({ storeId: "store-A" }), ctx);
|
|
115
|
-
expect(mockSendWhatsApp).toHaveBeenCalledWith(expect.objectContaining({ toPhone: "919999999999" }));
|
|
116
|
-
});
|
|
117
|
-
it("skips store owner if store not found", async () => {
|
|
118
|
-
mockStoreFindBySlug.mockResolvedValue(null);
|
|
119
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "" });
|
|
120
|
-
await handleOrderCreate(makeInput({ storeId: "store-nonexistent" }), ctx);
|
|
121
|
-
expect(mockSendWhatsApp).not.toHaveBeenCalled();
|
|
122
|
-
});
|
|
123
|
-
it("skips store owner if owner has no phone number", async () => {
|
|
124
|
-
mockStoreFindBySlug.mockResolvedValue({ ownerId: "user-seller-1" });
|
|
125
|
-
mockUserFindById.mockResolvedValue({ phoneNumber: null });
|
|
126
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "" });
|
|
127
|
-
await handleOrderCreate(makeInput({ storeId: "store-A" }), ctx);
|
|
128
|
-
expect(mockSendWhatsApp).not.toHaveBeenCalled();
|
|
129
|
-
});
|
|
130
|
-
it("skips store owner notification when storeId is absent from order", async () => {
|
|
131
|
-
const ctx = makeCtx({ WHATSAPP_ADMIN_NOTIFY_NUMBERS: "" });
|
|
132
|
-
await handleOrderCreate(makeInput({ storeId: undefined }), ctx);
|
|
133
|
-
expect(mockStoreFindBySlug).not.toHaveBeenCalled();
|
|
134
|
-
});
|
|
135
|
-
it("store owner lookup failure is non-fatal", async () => {
|
|
136
|
-
mockStoreFindBySlug.mockRejectedValue(new Error("Firestore error"));
|
|
137
|
-
const ctx = makeCtx();
|
|
138
|
-
await expect(handleOrderCreate(makeInput(), ctx)).resolves.toBeUndefined();
|
|
139
|
-
expect(ctx.logger.error).toHaveBeenCalledWith(expect.stringMatching(/Store owner lookup failed/i), expect.any(Error), expect.any(Object));
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
describe("handleOrderCreate — message content", () => {
|
|
143
|
-
it("uses buyerDisplayName in announcement", async () => {
|
|
144
|
-
const ctx = makeCtx();
|
|
145
|
-
await handleOrderCreate(makeInput({ buyerDisplayName: "Priya Singh" }), ctx);
|
|
146
|
-
expect(mockBuildMessage).toHaveBeenCalledWith(expect.objectContaining({ buyerName: "Priya Singh" }));
|
|
147
|
-
});
|
|
148
|
-
it("uses 'A customer' as fallback when buyerDisplayName is missing", async () => {
|
|
149
|
-
const ctx = makeCtx();
|
|
150
|
-
await handleOrderCreate(makeInput({ buyerDisplayName: undefined }), ctx);
|
|
151
|
-
expect(mockBuildMessage).toHaveBeenCalledWith(expect.objectContaining({ buyerName: "A customer" }));
|
|
152
|
-
});
|
|
153
|
-
it("uses first item title as firstItemName", async () => {
|
|
154
|
-
const ctx = makeCtx();
|
|
155
|
-
await handleOrderCreate(makeInput({ items: [{ title: "Charizard PSA 9" }] }), ctx);
|
|
156
|
-
expect(mockBuildMessage).toHaveBeenCalledWith(expect.objectContaining({ firstItemName: "Charizard PSA 9" }));
|
|
157
|
-
});
|
|
158
|
-
it("falls back to item.name when title is missing", async () => {
|
|
159
|
-
const ctx = makeCtx();
|
|
160
|
-
await handleOrderCreate(makeInput({ items: [{ name: "Blastoise" }] }), ctx);
|
|
161
|
-
expect(mockBuildMessage).toHaveBeenCalledWith(expect.objectContaining({ firstItemName: "Blastoise" }));
|
|
162
|
-
});
|
|
163
|
-
it("additionalItemCount = items.length - 1", async () => {
|
|
164
|
-
const ctx = makeCtx();
|
|
165
|
-
const items = [{ title: "A" }, { title: "B" }, { title: "C" }];
|
|
166
|
-
await handleOrderCreate(makeInput({ items }), ctx);
|
|
167
|
-
expect(mockBuildMessage).toHaveBeenCalledWith(expect.objectContaining({ additionalItemCount: 2 }));
|
|
168
|
-
});
|
|
169
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|