@tapcart/mobile-components 0.11.4 → 0.11.6
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/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox.js +7 -5
- package/dist/components/ui/money.d.ts.map +1 -1
- package/dist/components/ui/money.js +55 -10
- package/dist/components/ui/money.test.d.ts +2 -0
- package/dist/components/ui/money.test.d.ts.map +1 -0
- package/dist/components/ui/money.test.js +57 -0
- package/dist/components/ui/radio-group.d.ts +6 -1
- package/dist/components/ui/radio-group.d.ts.map +1 -1
- package/dist/components/ui/radio-group.js +3 -3
- package/dist/lib/isVersion20.util.d.ts +2 -0
- package/dist/lib/isVersion20.util.d.ts.map +1 -0
- package/dist/lib/isVersion20.util.js +7 -0
- package/dist/lib/utils.wishlist.test.d.ts +2 -0
- package/dist/lib/utils.wishlist.test.d.ts.map +1 -0
- package/dist/lib/utils.wishlist.test.js +108 -0
- package/dist/styles.css +6 -0
- package/dist/tests/addItemToWishlist/addItemToWishlist.wishlistId.test.d.ts +2 -0
- package/dist/tests/addItemToWishlist/addItemToWishlist.wishlistId.test.d.ts.map +1 -0
- package/dist/tests/addItemToWishlist/addItemToWishlist.wishlistId.test.js +50 -0
- package/dist/tests/removeItemFromWishlist/removeItemFromWishlist.test.d.ts +2 -0
- package/dist/tests/removeItemFromWishlist/removeItemFromWishlist.test.d.ts.map +1 -0
- package/dist/tests/removeItemFromWishlist/removeItemFromWishlist.test.js +268 -0
- package/dist/tests/removeItemFromWishlists/removeItemFromWishlist.test.d.ts +2 -0
- package/dist/tests/removeItemFromWishlists/removeItemFromWishlist.test.d.ts.map +1 -0
- package/dist/tests/removeItemFromWishlists/removeItemFromWishlist.test.js +268 -0
- package/package.json +1 -1
|
@@ -12,6 +12,11 @@ export interface CheckboxProps extends React.ComponentPropsWithoutRef<typeof Che
|
|
|
12
12
|
numberAmount?: string;
|
|
13
13
|
subtext?: string;
|
|
14
14
|
onSelect?: React.ReactEventHandler;
|
|
15
|
+
labelTextColor?: string;
|
|
16
|
+
labelCountColor?: string;
|
|
17
|
+
checkedColor?: string;
|
|
18
|
+
unCheckedColor?: string;
|
|
19
|
+
disabledColor?: string;
|
|
15
20
|
}
|
|
16
21
|
declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLButtonElement>>;
|
|
17
22
|
export { Checkbox };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../components/ui/checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAO,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../components/ui/checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAO,MAAM,0BAA0B,CAAA;AAmG5D,QAAA,MAAM,gBAAgB;;mFAUpB,CAAA;AAEF,MAAM,WAAW,aACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,EACnE,YAAY,CAAC,OAAO,gBAAgB,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IAC9B,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;IAClC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,QAAA,MAAM,QAAQ,yFAqGb,CAAA;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAA"}
|
|
@@ -16,9 +16,11 @@ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
|
16
16
|
import { cva } from "class-variance-authority";
|
|
17
17
|
import { cn } from "../../lib/utils";
|
|
18
18
|
import { Text } from "./text";
|
|
19
|
-
const Check = ({ className }) => (_jsxs("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", className: className }, { children: [_jsx("g", Object.assign({ clipPath: "url(#clip0_1465_24)" }, { children: _jsx("path", { d: "M5.667 21H5.66695C4.98414 21 4.32733 20.7382 3.83183 20.2684C3.33941 19.8015 3.04358 19.1646 3.00429 18.4875L3 18.3202V5.667C3 4.24616 4.11102 3.08465 5.51221 3.0043L5.67982 3H18.333C19.7538 3 20.9153 4.11101 20.9957 5.51219L21 5.67983V18.333C21 19.7538 19.889 20.9153 18.4878 20.9957L18.3202 21H5.667ZM16.4141 8.58593L16.414 8.58579C16.0389 8.21085 15.5303 8.00021 15 8.00021C14.4697 8.00021 13.9611 8.21085 13.586 8.58579L10.9998 11.1712L10.4138 10.5856L10.392 10.5638L10.3689 10.5434L10.2749 10.4604L10.2505 10.4388L10.2247 10.4189C9.82271 10.1081 9.31749 9.96192 8.81164 10.0101C8.3058 10.0583 7.83726 10.2972 7.50119 10.6783C7.16512 11.0595 6.98673 11.5542 7.00224 12.0621C7.01775 12.57 7.226 13.053 7.58469 13.4129L7.58589 13.4141L9.58589 15.4141L9.60784 15.4361L9.63111 15.4566L9.72511 15.5396L9.74895 15.5607L9.77407 15.5801C10.1589 15.8786 10.6394 16.0265 11.1254 15.9959C11.6115 15.9654 12.0697 15.7585 12.4141 15.4141L12.4141 15.4141L16.4141 11.4141L16.4361 11.3922L16.4566 11.3689L16.5396 11.2749L16.5607 11.2511L16.5801 11.2259C16.8786 10.8411 17.0265 10.3606 16.9959 9.87457C16.9654 9.38851 16.7585 8.93031 16.4141 8.58593Z", fill: "currentColor", stroke: "currentColor", strokeWidth: "2" }) })), _jsx("defs", { children: _jsx("clipPath", Object.assign({ id: "clip0_1465_24" }, { children: _jsx("rect", { width: "24", height: "24", fill: "white" }) })) })] })));
|
|
20
|
-
const Unchecked = ({ className
|
|
21
|
-
|
|
19
|
+
const Check = ({ className, color }) => (_jsxs("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", className: className, style: { color: color } }, { children: [_jsx("g", Object.assign({ clipPath: "url(#clip0_1465_24)" }, { children: _jsx("path", { d: "M5.667 21H5.66695C4.98414 21 4.32733 20.7382 3.83183 20.2684C3.33941 19.8015 3.04358 19.1646 3.00429 18.4875L3 18.3202V5.667C3 4.24616 4.11102 3.08465 5.51221 3.0043L5.67982 3H18.333C19.7538 3 20.9153 4.11101 20.9957 5.51219L21 5.67983V18.333C21 19.7538 19.889 20.9153 18.4878 20.9957L18.3202 21H5.667ZM16.4141 8.58593L16.414 8.58579C16.0389 8.21085 15.5303 8.00021 15 8.00021C14.4697 8.00021 13.9611 8.21085 13.586 8.58579L10.9998 11.1712L10.4138 10.5856L10.392 10.5638L10.3689 10.5434L10.2749 10.4604L10.2505 10.4388L10.2247 10.4189C9.82271 10.1081 9.31749 9.96192 8.81164 10.0101C8.3058 10.0583 7.83726 10.2972 7.50119 10.6783C7.16512 11.0595 6.98673 11.5542 7.00224 12.0621C7.01775 12.57 7.226 13.053 7.58469 13.4129L7.58589 13.4141L9.58589 15.4141L9.60784 15.4361L9.63111 15.4566L9.72511 15.5396L9.74895 15.5607L9.77407 15.5801C10.1589 15.8786 10.6394 16.0265 11.1254 15.9959C11.6115 15.9654 12.0697 15.7585 12.4141 15.4141L12.4141 15.4141L16.4141 11.4141L16.4361 11.3922L16.4566 11.3689L16.5396 11.2749L16.5607 11.2511L16.5801 11.2259C16.8786 10.8411 17.0265 10.3606 16.9959 9.87457C16.9654 9.38851 16.7585 8.93031 16.4141 8.58593Z", fill: "currentColor", stroke: "currentColor", strokeWidth: "2" }) })), _jsx("defs", { children: _jsx("clipPath", Object.assign({ id: "clip0_1465_24" }, { children: _jsx("rect", { width: "24", height: "24", fill: "white" }) })) })] })));
|
|
20
|
+
const Unchecked = ({ className, color }) => {
|
|
21
|
+
return (_jsxs("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", className: className, style: { color: color } }, { children: [_jsx("g", Object.assign({ clipPath: "url(#clip0_1465_32)" }, { children: _jsx("path", { d: "M3 5C3 4.46957 3.21071 3.96086 3.58579 3.58579C3.96086 3.21071 4.46957 3 5 3H19C19.5304 3 20.0391 3.21071 20.4142 3.58579C20.7893 3.96086 21 4.46957 21 5V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V5Z", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })), _jsx("defs", { children: _jsx("clipPath", Object.assign({ id: "clip0_1465_32" }, { children: _jsx("rect", { width: "24", height: "24", fill: "white" }) })) })] })));
|
|
22
|
+
};
|
|
23
|
+
const DisabledCheckbox = ({ className, color }) => (_jsxs("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", className: className, style: { color: color } }, { children: [_jsxs("g", Object.assign({ clipPath: "url(#clip0_1465_43)" }, { children: [_jsx("path", { d: "M8 4H18C18.5304 4 19.0391 4.21071 19.4142 4.58579C19.7893 4.96086 20 5.46957 20 6V16M19.416 19.412C19.2303 19.5983 19.0096 19.7462 18.7666 19.8471C18.5236 19.948 18.2631 19.9999 18 20H6C5.46957 20 4.96086 19.7893 4.58579 19.4142C4.21071 19.0391 4 18.5304 4 18V6C4 5.448 4.224 4.948 4.586 4.586", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M3 3L21 21", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] })), _jsx("defs", { children: _jsx("clipPath", Object.assign({ id: "clip0_1465_43" }, { children: _jsx("rect", { width: "24", height: "24", fill: "white" }) })) })] })));
|
|
22
24
|
const checkboxVariants = cva("flex flex-col group group-disabled", {
|
|
23
25
|
variants: {
|
|
24
26
|
deactivated: {
|
|
@@ -31,8 +33,8 @@ const checkboxVariants = cva("flex flex-col group group-disabled", {
|
|
|
31
33
|
},
|
|
32
34
|
});
|
|
33
35
|
const Checkbox = React.forwardRef((_a, ref) => {
|
|
34
|
-
var { id, className, label, numberAmount, subtext, selected = false, onCheck, onSelect, deactivated = false } = _a, props = __rest(_a, ["id", "className", "label", "numberAmount", "subtext", "selected", "onCheck", "onSelect", "deactivated"]);
|
|
35
|
-
return (_jsx("div", Object.assign({ className: cn(checkboxVariants({ deactivated })) }, { children: _jsx(CheckboxPrimitive.Root, Object.assign({ ref: ref, className: cn("w-full peer h-6 shrink-0 self-start rounded ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 group ", className), id: id, checked: selected, onSelect: onSelect, onCheckedChange: onCheck, disabled: deactivated !== null && deactivated !== void 0 ? deactivated : false }, props, { children: _jsxs("div", Object.assign({ className: "grid grid-cols-[auto,auto,1fr] gap-2 items-start group " }, { children: [_jsxs("div", Object.assign({ className: "grid" }, { children: [_jsx(CheckboxPrimitive.Indicator, Object.assign({ className: "flex items-center justify-center text-current col-start-1 row-start-1" }, { children: !deactivated && (_jsx(Check, { className: "col-start-1 row-start-1 items-center z-50 text-coreColors-brandColorPrimary" })) })), _jsxs("div", Object.assign({ className: "flex items-center justify-center col-start-1 row-start-1" }, { children: [!deactivated && !selected && (_jsx(Unchecked, { className: "text-coreColors-secondaryIcon" })), deactivated && (_jsx(DisabledCheckbox, { className: "text-stateColors-disabled" }))] }))] })), _jsxs("div", Object.assign({ className: "flex flex-col gap-2 items-start overflow-x-auto" }, { children: [label && (_jsx("label", Object.assign({ htmlFor: id, className: "max-w-full" }, { children: _jsxs("span", Object.assign({ className: "flex gap-2" }, { children: [_jsx(Text, Object.assign({ type: "body-primary", className: "group-disabled:text-stateColors-disabled text-ellipsis overflow-hidden " }, { children: label })), numberAmount && (_jsxs(Text, Object.assign({ type: "body-primary", className: "text-textColors-secondaryColor group-disabled:text-stateColors-disabled inline" }, { children: ["(", numberAmount, ")"] })))] })) }))), subtext && (_jsx(Text, Object.assign({ type: "body-secondary", className: "group-disabled:text-stateColors-disabled" }, { children: subtext })))] }))] })) })) })));
|
|
36
|
+
var { id, className, label, numberAmount, subtext, selected = false, onCheck, onSelect, deactivated = false, labelTextColor, labelCountColor, checkedColor, unCheckedColor, disabledColor } = _a, props = __rest(_a, ["id", "className", "label", "numberAmount", "subtext", "selected", "onCheck", "onSelect", "deactivated", "labelTextColor", "labelCountColor", "checkedColor", "unCheckedColor", "disabledColor"]);
|
|
37
|
+
return (_jsx("div", Object.assign({ className: cn(checkboxVariants({ deactivated })) }, { children: _jsx(CheckboxPrimitive.Root, Object.assign({ ref: ref, className: cn("w-full peer h-6 shrink-0 self-start rounded ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 group ", className), id: id, checked: selected, onSelect: onSelect, onCheckedChange: onCheck, disabled: deactivated !== null && deactivated !== void 0 ? deactivated : false }, props, { children: _jsxs("div", Object.assign({ className: "grid grid-cols-[auto,auto,1fr] gap-2 items-start group " }, { children: [_jsxs("div", Object.assign({ className: "grid" }, { children: [_jsx(CheckboxPrimitive.Indicator, Object.assign({ className: "flex items-center justify-center text-current col-start-1 row-start-1" }, { children: !deactivated && (_jsx(Check, { className: "col-start-1 row-start-1 items-center z-50 text-coreColors-brandColorPrimary", color: checkedColor })) })), _jsxs("div", Object.assign({ className: "flex items-center justify-center col-start-1 row-start-1" }, { children: [!deactivated && !selected && (_jsx(Unchecked, { className: "text-coreColors-secondaryIcon", color: unCheckedColor })), deactivated && (_jsx(DisabledCheckbox, { className: "text-stateColors-disabled", color: disabledColor }))] }))] })), _jsxs("div", Object.assign({ className: "flex flex-col gap-2 items-start overflow-x-auto" }, { children: [label && (_jsx("label", Object.assign({ htmlFor: id, className: "max-w-full" }, { children: _jsxs("span", Object.assign({ className: "flex gap-2" }, { children: [_jsx(Text, Object.assign({ type: "body-primary", className: "group-disabled:text-stateColors-disabled text-ellipsis overflow-hidden ", fontColor: labelTextColor }, { children: label })), numberAmount && (_jsxs(Text, Object.assign({ type: "body-primary", className: "text-textColors-secondaryColor group-disabled:text-stateColors-disabled inline", fontColor: labelCountColor }, { children: ["(", numberAmount, ")"] })))] })) }))), subtext && (_jsx(Text, Object.assign({ type: "body-secondary", className: "group-disabled:text-stateColors-disabled" }, { children: subtext })))] }))] })) })) })));
|
|
36
38
|
});
|
|
37
39
|
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
38
40
|
export { Checkbox };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"money.d.ts","sourceRoot":"","sources":["../../../components/ui/money.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGjE,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,QAAA,MAAM,aAAa,gGAMjB,CAAA;AAEF,MAAM,WAAW,UACf,SAAQ,SAAS,EACf,YAAY,CAAC,OAAO,aAAa,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC7B;AAED,iBAAS,KAAK,CAAC,EACb,KAAK,EACL,MAAM,EACN,QAAQ,EACR,aAAqB,EACrB,MAAM,EACN,GAAG,KAAK,EACT,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"money.d.ts","sourceRoot":"","sources":["../../../components/ui/money.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGjE,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,QAAA,MAAM,aAAa,gGAMjB,CAAA;AAEF,MAAM,WAAW,UACf,SAAQ,SAAS,EACf,YAAY,CAAC,OAAO,aAAa,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC7B;AAED,iBAAS,KAAK,CAAC,EACb,KAAK,EACL,MAAM,EACN,QAAQ,EACR,aAAqB,EACrB,MAAM,EACN,GAAG,KAAK,EACT,EAAE,UAAU,2CAiFZ;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -13,7 +13,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import * as React from "react";
|
|
15
15
|
import { cva } from "class-variance-authority";
|
|
16
|
-
import { usePathname } from "next/navigation";
|
|
16
|
+
import { usePathname, useSearchParams } from "next/navigation";
|
|
17
17
|
const moneyVariants = cva("", {
|
|
18
18
|
variants: {},
|
|
19
19
|
defaultVariants: {
|
|
@@ -24,15 +24,60 @@ const moneyVariants = cva("", {
|
|
|
24
24
|
function Money(_a) {
|
|
25
25
|
var _b, _c;
|
|
26
26
|
var { price, locale, currency, hideZeroCents = false, styles } = _a, props = __rest(_a, ["price", "locale", "currency", "hideZeroCents", "styles"]);
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
const searchParams = useSearchParams();
|
|
28
|
+
const countryFromParams = (searchParams === null || searchParams === void 0 ? void 0 : searchParams.get("country")) || undefined;
|
|
29
|
+
// Derive a candidate locale from the route or prop, then normalize to a valid BCP 47 tag
|
|
30
|
+
const routeCandidate = ((_c = (_b = usePathname()) === null || _b === void 0 ? void 0 : _b.split("/")) === null || _c === void 0 ? void 0 : _c.pop()) || "";
|
|
31
|
+
const normalizeLocale = (baseLocale, countryParam) => {
|
|
32
|
+
const DEFAULT_LOCALE = "en-US";
|
|
33
|
+
const raw = (baseLocale || "").replace(/_/g, "-").trim();
|
|
34
|
+
let languageCode = "";
|
|
35
|
+
let regionCode = "";
|
|
36
|
+
if (raw.includes("-")) {
|
|
37
|
+
const [langPart, regionPart] = raw.split("-");
|
|
38
|
+
if (langPart)
|
|
39
|
+
languageCode = langPart.toLowerCase();
|
|
40
|
+
if (regionPart)
|
|
41
|
+
regionCode = regionPart.toUpperCase();
|
|
42
|
+
}
|
|
43
|
+
else if (raw.length === 2) {
|
|
44
|
+
if (/^[a-z]{2}$/.test(raw)) {
|
|
45
|
+
// language only (e.g., "en")
|
|
46
|
+
languageCode = raw.toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
else if (/^[A-Z]{2}$/.test(raw)) {
|
|
49
|
+
// region only (e.g., "US")
|
|
50
|
+
regionCode = raw.toUpperCase();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
languageCode = raw.toLowerCase();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (raw) {
|
|
57
|
+
// fallback: treat as language subtag
|
|
58
|
+
languageCode = raw.toLowerCase();
|
|
59
|
+
}
|
|
60
|
+
// If a country param is present, prefer it as region
|
|
61
|
+
if (countryParam) {
|
|
62
|
+
regionCode = countryParam.toUpperCase();
|
|
63
|
+
}
|
|
64
|
+
// Ensure we always have a sensible language
|
|
65
|
+
if (!languageCode) {
|
|
66
|
+
languageCode = "en";
|
|
67
|
+
}
|
|
68
|
+
const candidate = regionCode
|
|
69
|
+
? `${languageCode}-${regionCode}`
|
|
70
|
+
: languageCode;
|
|
71
|
+
try {
|
|
72
|
+
// Validate and canonicalize via NumberFormat
|
|
73
|
+
const formatter = new Intl.NumberFormat(candidate);
|
|
74
|
+
return formatter.resolvedOptions().locale;
|
|
75
|
+
}
|
|
76
|
+
catch (_a) {
|
|
77
|
+
return DEFAULT_LOCALE;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const language = normalizeLocale(routeCandidate || locale, countryFromParams);
|
|
36
81
|
const formatter = React.useMemo(() => new Intl.NumberFormat(language, {
|
|
37
82
|
style: "currency",
|
|
38
83
|
currency: currency,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"money.test.d.ts","sourceRoot":"","sources":["../../../components/ui/money.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import { Money } from "./money";
|
|
4
|
+
jest.mock("next/navigation", () => ({
|
|
5
|
+
usePathname: jest.fn(),
|
|
6
|
+
useSearchParams: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
const mockedUsePathname = require("next/navigation").usePathname;
|
|
9
|
+
const mockedUseSearchParams = require("next/navigation")
|
|
10
|
+
.useSearchParams;
|
|
11
|
+
function makeSearchParams(params) {
|
|
12
|
+
return {
|
|
13
|
+
get: (key) => params[key],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
describe("Money", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
mockedUsePathname.mockReset();
|
|
19
|
+
mockedUseSearchParams.mockReset();
|
|
20
|
+
});
|
|
21
|
+
it("formats USD with default en-US when no locale provided", () => {
|
|
22
|
+
mockedUsePathname.mockReturnValue("/");
|
|
23
|
+
mockedUseSearchParams.mockReturnValue(makeSearchParams({}));
|
|
24
|
+
render(_jsx(Money, { price: 1234.56, currency: "USD", locale: "" }));
|
|
25
|
+
expect(screen.getByText(/\$1,234.56/)).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
it("removes trailing cents when hideZeroCents is true", () => {
|
|
28
|
+
mockedUsePathname.mockReturnValue("/");
|
|
29
|
+
mockedUseSearchParams.mockReturnValue(makeSearchParams({}));
|
|
30
|
+
render(_jsx(Money, { price: 100, currency: "USD", locale: "en-US", hideZeroCents: true }));
|
|
31
|
+
expect(screen.getByText("$100")).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
it("uses route locale when valid (e.g., fr-FR)", () => {
|
|
34
|
+
mockedUsePathname.mockReturnValue("/shop/fr-FR");
|
|
35
|
+
mockedUseSearchParams.mockReturnValue(makeSearchParams({}));
|
|
36
|
+
render(_jsx(Money, { price: 1234.56, currency: "EUR", locale: "en-US" }));
|
|
37
|
+
expect(screen.getByText(/1\s?234,56\s?€/)).toBeTruthy();
|
|
38
|
+
});
|
|
39
|
+
it("normalizes underscore and applies country param for region", () => {
|
|
40
|
+
mockedUsePathname.mockReturnValue("/shop/es_es");
|
|
41
|
+
mockedUseSearchParams.mockReturnValue(makeSearchParams({ country: "mx" }));
|
|
42
|
+
render(_jsx(Money, { price: 50, currency: "MXN", locale: "es" }));
|
|
43
|
+
expect(screen.getByText(/\$\s?50(\.00)?/)).toBeTruthy();
|
|
44
|
+
});
|
|
45
|
+
it("avoids malformed tags like en-us-US and falls back safely", () => {
|
|
46
|
+
mockedUsePathname.mockReturnValue("/en-us-US");
|
|
47
|
+
mockedUseSearchParams.mockReturnValue(makeSearchParams({}));
|
|
48
|
+
render(_jsx(Money, { price: 10, currency: "USD", locale: "en-us-US" }));
|
|
49
|
+
expect(screen.getByText(/\$10(\.00)?/)).toBeTruthy();
|
|
50
|
+
});
|
|
51
|
+
it("handles region-only input via country param", () => {
|
|
52
|
+
mockedUsePathname.mockReturnValue("/US");
|
|
53
|
+
mockedUseSearchParams.mockReturnValue(makeSearchParams({ country: "US" }));
|
|
54
|
+
render(_jsx(Money, { price: 20, currency: "USD", locale: "" }));
|
|
55
|
+
expect(screen.getByText(/\$20(\.00)?/)).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -11,12 +11,17 @@ export interface RadioGroupItemProps {
|
|
|
11
11
|
selected?: boolean;
|
|
12
12
|
value: string;
|
|
13
13
|
onClick?: React.ReactEventHandler;
|
|
14
|
+
labelTextColor?: string;
|
|
15
|
+
labelCountColor?: string;
|
|
16
|
+
selectedColor?: string;
|
|
17
|
+
unselectedColor?: string;
|
|
18
|
+
disabledColor?: string;
|
|
14
19
|
}
|
|
15
20
|
declare const radiogroupItemVariants: (props?: ({
|
|
16
21
|
variant?: "default" | "selected" | "deactivated" | null | undefined;
|
|
17
22
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
18
23
|
declare const RadioGroupItem: {
|
|
19
|
-
({ value, label, subtext, numberAmount, onSelect, onClick, selected, className, variant, ...props }: RadioGroupItemProps & VariantProps<typeof radiogroupItemVariants>): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
({ value, label, subtext, numberAmount, onSelect, onClick, selected, className, variant, labelTextColor, labelCountColor, selectedColor, unselectedColor, disabledColor, ...props }: RadioGroupItemProps & VariantProps<typeof radiogroupItemVariants>): import("react/jsx-runtime").JSX.Element;
|
|
20
25
|
displayName: string | undefined;
|
|
21
26
|
};
|
|
22
27
|
export { RadioGroup, RadioGroupItem, radiogroupItemVariants };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../../components/ui/radio-group.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAA;AAElE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAKjE,QAAA,MAAM,UAAU,+JAWd,CAAA;AAGF,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../../components/ui/radio-group.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAA;AAElE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAKjE,QAAA,MAAM,UAAU,+JAWd,CAAA;AAGF,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAA;IACjC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,QAAA,MAAM,sBAAsB;;mFAc3B,CAAA;AA2CD,QAAA,MAAM,cAAc;yLAgBjB,mBAAmB,GAAG,aAAa,6BAA6B,CAAC;;CA+EnE,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAA"}
|
|
@@ -34,10 +34,10 @@ const radiogroupItemVariants = cva("grid grid-cols-[auto,auto,1fr] gap-2 items-c
|
|
|
34
34
|
variant: "default",
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
|
-
const RadioGroupItemLabels = ({ label, numberAmount, subtext, }) => (_jsxs("div", Object.assign({ className: "col-span-2" }, { children: [_jsxs("div", Object.assign({ className: "flex flex-row items-center" }, { children: [_jsx(Text, Object.assign({ type: "body-primary", className: "group-disabled:text-stateColors-disabled mr-2" }, { children: label })), numberAmount ? (_jsx(Text, Object.assign({ type: "body-primary", className: "text-textColors-secondaryColor group-disabled:text-stateColors-disabled" }, { children: `(${numberAmount})` }))) : null] })), subtext ? (_jsx(Text, Object.assign({ type: "body-secondary", className: "group-disabled:text-stateColors-disabled mt-1" }, { children: subtext }))) : null] })));
|
|
37
|
+
const RadioGroupItemLabels = ({ label, numberAmount, subtext, labelColor, labelCountColor, }) => (_jsxs("div", Object.assign({ className: "col-span-2" }, { children: [_jsxs("div", Object.assign({ className: "flex flex-row items-center" }, { children: [_jsx(Text, Object.assign({ type: "body-primary", className: "group-disabled:text-stateColors-disabled mr-2", fontColor: labelColor }, { children: label })), numberAmount ? (_jsx(Text, Object.assign({ type: "body-primary", className: "text-textColors-secondaryColor group-disabled:text-stateColors-disabled", fontColor: labelCountColor }, { children: `(${numberAmount})` }))) : null] })), subtext ? (_jsx(Text, Object.assign({ type: "body-secondary", className: "group-disabled:text-stateColors-disabled mt-1" }, { children: subtext }))) : null] })));
|
|
38
38
|
const RadioGroupItem = (_a) => {
|
|
39
|
-
var { value, label = "", subtext, numberAmount = 0, onSelect = () => { }, onClick = () => { }, selected = false, className, variant = "default" } = _a, props = __rest(_a, ["value", "label", "subtext", "numberAmount", "onSelect", "onClick", "selected", "className", "variant"]);
|
|
40
|
-
return (_jsx("div", Object.assign({ className: cn(radiogroupItemVariants({ variant }), className) }, { children: variant === "deactivated" ? (_jsxs(_Fragment, { children: [_jsx(Icon, { name: "circle-off", size: "md", className: "text-stateColors-disabled" }), _jsx(RadioGroupItemLabels, { label: label, numberAmount: numberAmount, subtext: subtext })] })) : (_jsx(RadioGroupPrimitive.Item, Object.assign({ value: value, onSelect: onSelect, checked: selected, onClick: onClick, className: cn("flex items-center justify-center cursor-pointer", className) }, props, { children: selected || variant === "selected" ? (_jsxs("div", Object.assign({ className: "grid grid-cols-[auto,auto,1fr] gap-2 items-center group" }, { children: [_jsx(Icon, { name: "circle-dot-filled", size: "md", className: "text-coreColors-brandColorPrimary z-10" }), _jsx(RadioGroupItemLabels, { label: label, numberAmount: numberAmount, subtext: subtext })] }))) : (_jsxs("div", Object.assign({ className: "grid grid-cols-[auto,auto,1fr] gap-2 items-center group" }, { children: [_jsxs("div", Object.assign({ className: "grid" }, { children: [_jsx(RadioGroupPrimitive.Indicator, Object.assign({ className: "flex items-center justify-center col-start-1 row-start-1" }, { children: _jsx(Icon, { name: "circle-dot-filled", size: "md", className: "text-coreColors-brandColorPrimary z-10" }) })), _jsx("div", Object.assign({ className: "flex items-center justify-center col-start-1 row-start-1" }, { children: _jsx(Icon, { name: "circle", size: "md", className: "col-start-1 row-start-1 text-coreColors-secondaryIcon items-center z-1" }) }))] })), _jsx(RadioGroupItemLabels, { label: label, numberAmount: numberAmount, subtext: subtext })] }))) }))) })));
|
|
39
|
+
var { value, label = "", subtext, numberAmount = 0, onSelect = () => { }, onClick = () => { }, selected = false, className, variant = "default", labelTextColor, labelCountColor, selectedColor, unselectedColor, disabledColor } = _a, props = __rest(_a, ["value", "label", "subtext", "numberAmount", "onSelect", "onClick", "selected", "className", "variant", "labelTextColor", "labelCountColor", "selectedColor", "unselectedColor", "disabledColor"]);
|
|
40
|
+
return (_jsx("div", Object.assign({ className: cn(radiogroupItemVariants({ variant }), className) }, { children: variant === "deactivated" ? (_jsxs(_Fragment, { children: [_jsx(Icon, { name: "circle-off", size: "md", className: "text-stateColors-disabled", style: { color: disabledColor } }), _jsx(RadioGroupItemLabels, { label: label, numberAmount: numberAmount, subtext: subtext, labelColor: labelTextColor, labelCountColor: labelCountColor })] })) : (_jsx(RadioGroupPrimitive.Item, Object.assign({ value: value, onSelect: onSelect, checked: selected, onClick: onClick, className: cn("flex items-center justify-center cursor-pointer", className) }, props, { children: selected || variant === "selected" ? (_jsxs("div", Object.assign({ className: "grid grid-cols-[auto,auto,1fr] gap-2 items-center group" }, { children: [_jsx(Icon, { name: "circle-dot-filled", size: "md", className: "text-coreColors-brandColorPrimary z-10", color: selectedColor }), _jsx(RadioGroupItemLabels, { label: label, numberAmount: numberAmount, subtext: subtext, labelColor: labelTextColor, labelCountColor: labelCountColor })] }))) : (_jsxs("div", Object.assign({ className: "grid grid-cols-[auto,auto,1fr] gap-2 items-center group" }, { children: [_jsxs("div", Object.assign({ className: "grid" }, { children: [_jsx(RadioGroupPrimitive.Indicator, Object.assign({ className: "flex items-center justify-center col-start-1 row-start-1" }, { children: _jsx(Icon, { name: "circle-dot-filled", size: "md", className: "text-coreColors-brandColorPrimary z-10" }) })), _jsx("div", Object.assign({ className: "flex items-center justify-center col-start-1 row-start-1" }, { children: _jsx(Icon, { name: "circle", size: "md", className: "col-start-1 row-start-1 text-coreColors-secondaryIcon items-center z-1", color: unselectedColor }) }))] })), _jsx(RadioGroupItemLabels, { label: label, numberAmount: numberAmount, subtext: subtext, labelColor: labelTextColor, labelCountColor: labelCountColor })] }))) }))) })));
|
|
41
41
|
};
|
|
42
42
|
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
|
|
43
43
|
export { RadioGroup, RadioGroupItem, radiogroupItemVariants };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isVersion20.util.d.ts","sourceRoot":"","sources":["../../lib/isVersion20.util.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,YAAa,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OAIhE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.wishlist.test.d.ts","sourceRoot":"","sources":["../../lib/utils.wishlist.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { findWishlistEntry, getEnabledWishlistIntegration, supportsMultipleWishlists, } from "./utils";
|
|
2
|
+
describe("getEnabledWishlistIntegration", () => {
|
|
3
|
+
it("returns the first enabled wishlist integration", () => {
|
|
4
|
+
const integrations = [
|
|
5
|
+
{ name: "tapcart-search", enabled: true },
|
|
6
|
+
{ name: "tapcart-wishlist", enabled: true, multiwishlist: true },
|
|
7
|
+
{ name: "swym", enabled: true },
|
|
8
|
+
];
|
|
9
|
+
const result = getEnabledWishlistIntegration(integrations);
|
|
10
|
+
expect(result).toEqual({
|
|
11
|
+
name: "tapcart-wishlist",
|
|
12
|
+
enabled: true,
|
|
13
|
+
multiwishlist: true,
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
it("returns null when no wishlist integration is enabled", () => {
|
|
17
|
+
const integrations = [
|
|
18
|
+
{ name: "tapcart-search", enabled: true },
|
|
19
|
+
{ name: "tapcart-wishlist", enabled: false },
|
|
20
|
+
];
|
|
21
|
+
expect(getEnabledWishlistIntegration(integrations)).toBeNull();
|
|
22
|
+
});
|
|
23
|
+
it("returns null when integrations is not an array", () => {
|
|
24
|
+
expect(getEnabledWishlistIntegration(undefined)).toBeNull();
|
|
25
|
+
expect(getEnabledWishlistIntegration(null)).toBeNull();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe("supportsMultipleWishlists", () => {
|
|
29
|
+
it("respects explicit multiwishlist flag", () => {
|
|
30
|
+
expect(supportsMultipleWishlists({
|
|
31
|
+
name: "tapcart-wishlist",
|
|
32
|
+
enabled: true,
|
|
33
|
+
multiwishlist: false,
|
|
34
|
+
})).toBe(false);
|
|
35
|
+
expect(supportsMultipleWishlists({
|
|
36
|
+
name: "tapcart-wishlist",
|
|
37
|
+
enabled: true,
|
|
38
|
+
multiwishlist: true,
|
|
39
|
+
})).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
it("defaults to true for known integrations when flag is omitted", () => {
|
|
42
|
+
expect(supportsMultipleWishlists({
|
|
43
|
+
name: "tapcart-wishlist-v2",
|
|
44
|
+
enabled: true,
|
|
45
|
+
})).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
it("returns false for unknown integrations", () => {
|
|
48
|
+
expect(supportsMultipleWishlists({
|
|
49
|
+
name: "not-a-wishlist",
|
|
50
|
+
enabled: true,
|
|
51
|
+
})).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("findWishlistEntry", () => {
|
|
55
|
+
const wishlists = [
|
|
56
|
+
{
|
|
57
|
+
id: "wl-1",
|
|
58
|
+
items: [
|
|
59
|
+
{
|
|
60
|
+
id: "item-1",
|
|
61
|
+
productId: "gid://shopify/Product/123",
|
|
62
|
+
variantId: "gid://shopify/ProductVariant/456",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
_id: "wl-2",
|
|
68
|
+
items: [
|
|
69
|
+
{
|
|
70
|
+
id: "item-2",
|
|
71
|
+
productId: "789",
|
|
72
|
+
variantId: "654",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
it("finds an entry when product and variant match across gid representations", () => {
|
|
78
|
+
const match = findWishlistEntry(wishlists, "123", "456");
|
|
79
|
+
expect(match).toEqual({
|
|
80
|
+
wishlistId: "wl-1",
|
|
81
|
+
item: {
|
|
82
|
+
id: "item-1",
|
|
83
|
+
productId: "gid://shopify/Product/123",
|
|
84
|
+
variantId: "gid://shopify/ProductVariant/456",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
it("falls back to product-only lookup when variant is omitted", () => {
|
|
89
|
+
const match = findWishlistEntry(wishlists, "789");
|
|
90
|
+
expect(match).toEqual({
|
|
91
|
+
wishlistId: "wl-2",
|
|
92
|
+
item: {
|
|
93
|
+
id: "item-2",
|
|
94
|
+
productId: "789",
|
|
95
|
+
variantId: "654",
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
it("returns null when no matching entry is found", () => {
|
|
100
|
+
const match = findWishlistEntry(wishlists, "999", "888");
|
|
101
|
+
expect(match).toBeNull();
|
|
102
|
+
});
|
|
103
|
+
it("handles empty or invalid inputs gracefully", () => {
|
|
104
|
+
expect(findWishlistEntry(undefined, "123")).toBeNull();
|
|
105
|
+
expect(findWishlistEntry([], "123")).toBeNull();
|
|
106
|
+
expect(findWishlistEntry(wishlists, undefined)).toBeNull();
|
|
107
|
+
});
|
|
108
|
+
});
|
package/dist/styles.css
CHANGED
|
@@ -778,6 +778,9 @@ video {
|
|
|
778
778
|
.top-\[50\%\] {
|
|
779
779
|
top: 50%;
|
|
780
780
|
}
|
|
781
|
+
.z-0 {
|
|
782
|
+
z-index: 0;
|
|
783
|
+
}
|
|
781
784
|
.z-10 {
|
|
782
785
|
z-index: 10;
|
|
783
786
|
}
|
|
@@ -886,6 +889,9 @@ video {
|
|
|
886
889
|
.ml-2 {
|
|
887
890
|
margin-left: 0.5rem;
|
|
888
891
|
}
|
|
892
|
+
.ml-4 {
|
|
893
|
+
margin-left: 1rem;
|
|
894
|
+
}
|
|
889
895
|
.ml-auto {
|
|
890
896
|
margin-left: auto;
|
|
891
897
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addItemToWishlist.wishlistId.test.d.ts","sourceRoot":"","sources":["../../../tests/addItemToWishlist/addItemToWishlist.wishlistId.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { addItemToWishlist } from "../../lib/utils";
|
|
11
|
+
describe("addItemToWishlist with explicit wishlistId", () => {
|
|
12
|
+
let mockTapcart;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.clearAllMocks();
|
|
15
|
+
mockTapcart = {
|
|
16
|
+
action: jest.fn().mockResolvedValue(true),
|
|
17
|
+
variables: {
|
|
18
|
+
customer: { id: "customer-123" },
|
|
19
|
+
wishlists: [{ id: "wishlist-1" }],
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
it("should use the provided wishlistId without opening the drawer", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
const integrations = [
|
|
25
|
+
{
|
|
26
|
+
name: "tapcart-wishlist",
|
|
27
|
+
enabled: true,
|
|
28
|
+
multiwishlist: false,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
const product = {
|
|
32
|
+
id: "gid://shopify/Product/123",
|
|
33
|
+
variants: [{ id: "gid://shopify/ProductVariant/456" }],
|
|
34
|
+
};
|
|
35
|
+
const result = yield addItemToWishlist({
|
|
36
|
+
Tapcart: mockTapcart,
|
|
37
|
+
integrations,
|
|
38
|
+
product,
|
|
39
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
40
|
+
wishlistId: "gid://shopify/Wishlist/789",
|
|
41
|
+
});
|
|
42
|
+
expect(result).toBe(true);
|
|
43
|
+
expect(mockTapcart.action).toHaveBeenCalledTimes(1);
|
|
44
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/add", {
|
|
45
|
+
productId: "123",
|
|
46
|
+
variantId: "456",
|
|
47
|
+
wishlistId: "789",
|
|
48
|
+
});
|
|
49
|
+
}));
|
|
50
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removeItemFromWishlist.test.d.ts","sourceRoot":"","sources":["../../../tests/removeItemFromWishlist/removeItemFromWishlist.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { removeItemFromWishlist } from "../../lib/utils";
|
|
11
|
+
describe("removeItemFromWishlist", () => {
|
|
12
|
+
let mockTapcart;
|
|
13
|
+
let consoleErrorSpy;
|
|
14
|
+
let consoleLogSpy;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
// Reset mocks before each test
|
|
17
|
+
jest.clearAllMocks();
|
|
18
|
+
// Spy on console methods
|
|
19
|
+
consoleErrorSpy = jest.spyOn(console, "error").mockImplementation();
|
|
20
|
+
consoleLogSpy = jest.spyOn(console, "log").mockImplementation();
|
|
21
|
+
// Default mock Tapcart instance
|
|
22
|
+
mockTapcart = {
|
|
23
|
+
action: jest.fn(),
|
|
24
|
+
variables: {
|
|
25
|
+
customer: { id: "customer-123" },
|
|
26
|
+
wishlists: [
|
|
27
|
+
{
|
|
28
|
+
id: "wishlist-1",
|
|
29
|
+
items: [
|
|
30
|
+
{
|
|
31
|
+
productId: "gid://shopify/Product/123",
|
|
32
|
+
variantId: "gid://shopify/ProductVariant/456",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
consoleErrorSpy.mockRestore();
|
|
42
|
+
consoleLogSpy.mockRestore();
|
|
43
|
+
});
|
|
44
|
+
describe("validation and error handling", () => {
|
|
45
|
+
it("should return false when Tapcart instance is missing", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
const result = yield removeItemFromWishlist({
|
|
47
|
+
Tapcart: null,
|
|
48
|
+
productId: "gid://shopify/Product/123",
|
|
49
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
50
|
+
});
|
|
51
|
+
expect(result).toBe(false);
|
|
52
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Tapcart instance is missing");
|
|
53
|
+
}));
|
|
54
|
+
it("should handle errors gracefully and return false", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
+
// Mock Tapcart.action to throw an error
|
|
56
|
+
mockTapcart.action = jest.fn().mockImplementation(() => {
|
|
57
|
+
throw new Error("Test error");
|
|
58
|
+
});
|
|
59
|
+
const result = yield removeItemFromWishlist({
|
|
60
|
+
Tapcart: mockTapcart,
|
|
61
|
+
productId: "gid://shopify/Product/123",
|
|
62
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
63
|
+
});
|
|
64
|
+
expect(result).toBe(false);
|
|
65
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Failed to remove from wishlist", expect.any(Error));
|
|
66
|
+
}));
|
|
67
|
+
});
|
|
68
|
+
describe("variant ID handling", () => {
|
|
69
|
+
it("should return false when variant ID is missing from both wishlist entry and selectedVariantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
|
+
// Mock Tapcart with no variant ID in wishlist entry
|
|
71
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = null;
|
|
72
|
+
const result = yield removeItemFromWishlist({
|
|
73
|
+
Tapcart: mockTapcart,
|
|
74
|
+
productId: "gid://shopify/Product/123",
|
|
75
|
+
selectedVariantId: null,
|
|
76
|
+
});
|
|
77
|
+
expect(result).toBe(false);
|
|
78
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing variant id for wishlist removal");
|
|
79
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
80
|
+
}));
|
|
81
|
+
it("should use variant ID from wishlist entry when available", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
// Mock Tapcart.action to return a success result
|
|
83
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
84
|
+
const result = yield removeItemFromWishlist({
|
|
85
|
+
Tapcart: mockTapcart,
|
|
86
|
+
productId: "gid://shopify/Product/123",
|
|
87
|
+
selectedVariantId: null,
|
|
88
|
+
});
|
|
89
|
+
expect(result).toBe(true);
|
|
90
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
91
|
+
productId: "gid://shopify/Product/123",
|
|
92
|
+
variantId: "456",
|
|
93
|
+
wishlistId: "wishlist-1",
|
|
94
|
+
});
|
|
95
|
+
}));
|
|
96
|
+
it("should use selectedVariantId when wishlist entry has no variant ID", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
97
|
+
// Mock Tapcart with no variant ID in wishlist entry
|
|
98
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = null;
|
|
99
|
+
// Mock Tapcart.action to return a success result
|
|
100
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
101
|
+
const result = yield removeItemFromWishlist({
|
|
102
|
+
Tapcart: mockTapcart,
|
|
103
|
+
productId: "gid://shopify/Product/123",
|
|
104
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
105
|
+
});
|
|
106
|
+
expect(result).toBe(true);
|
|
107
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
108
|
+
productId: "gid://shopify/Product/123",
|
|
109
|
+
variantId: "789",
|
|
110
|
+
wishlistId: "wishlist-1",
|
|
111
|
+
});
|
|
112
|
+
}));
|
|
113
|
+
it("should prioritize wishlist entry variant ID over selectedVariantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
// Mock Tapcart.action to return a success result
|
|
115
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
116
|
+
const result = yield removeItemFromWishlist({
|
|
117
|
+
Tapcart: mockTapcart,
|
|
118
|
+
productId: "gid://shopify/Product/123",
|
|
119
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
120
|
+
});
|
|
121
|
+
expect(result).toBe(true);
|
|
122
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
123
|
+
productId: "gid://shopify/Product/123",
|
|
124
|
+
variantId: "456",
|
|
125
|
+
wishlistId: "wishlist-1",
|
|
126
|
+
});
|
|
127
|
+
}));
|
|
128
|
+
});
|
|
129
|
+
describe("wishlist ID handling", () => {
|
|
130
|
+
it("should return false when wishlist ID is missing", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
131
|
+
// Mock Tapcart with no wishlist ID
|
|
132
|
+
mockTapcart.variables.wishlists = [];
|
|
133
|
+
const result = yield removeItemFromWishlist({
|
|
134
|
+
Tapcart: mockTapcart,
|
|
135
|
+
productId: "gid://shopify/Product/123",
|
|
136
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
137
|
+
});
|
|
138
|
+
expect(result).toBe(false);
|
|
139
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing wishlist id for wishlist removal");
|
|
140
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
141
|
+
}));
|
|
142
|
+
it("should use wishlist ID from wishlist entry when available", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
+
// Mock Tapcart.action to return a success result
|
|
144
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
145
|
+
const result = yield removeItemFromWishlist({
|
|
146
|
+
Tapcart: mockTapcart,
|
|
147
|
+
productId: "gid://shopify/Product/123",
|
|
148
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
149
|
+
});
|
|
150
|
+
expect(result).toBe(true);
|
|
151
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
152
|
+
productId: "gid://shopify/Product/123",
|
|
153
|
+
variantId: "456",
|
|
154
|
+
wishlistId: "wishlist-1", // From wishlist entry
|
|
155
|
+
});
|
|
156
|
+
}));
|
|
157
|
+
});
|
|
158
|
+
describe("GID handling", () => {
|
|
159
|
+
it("should extract IDs from GID format", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
// Mock Tapcart with GID format
|
|
161
|
+
mockTapcart.variables.wishlists[0].items[0].productId = "gid://shopify/Product/123?param=value";
|
|
162
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = "gid://shopify/ProductVariant/456?param=value";
|
|
163
|
+
// Mock Tapcart.action to return a success result
|
|
164
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
165
|
+
const result = yield removeItemFromWishlist({
|
|
166
|
+
Tapcart: mockTapcart,
|
|
167
|
+
productId: "gid://shopify/Product/123?param=value",
|
|
168
|
+
selectedVariantId: "gid://shopify/ProductVariant/789?param=value",
|
|
169
|
+
});
|
|
170
|
+
expect(result).toBe(true);
|
|
171
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
172
|
+
productId: "gid://shopify/Product/123?param=value",
|
|
173
|
+
variantId: "456",
|
|
174
|
+
wishlistId: "wishlist-1",
|
|
175
|
+
});
|
|
176
|
+
}));
|
|
177
|
+
it("should handle plain IDs without GID format", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
178
|
+
// Mock Tapcart with plain IDs
|
|
179
|
+
mockTapcart.variables.wishlists[0].items[0].productId = "123";
|
|
180
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = "456";
|
|
181
|
+
// Mock Tapcart.action to return a success result
|
|
182
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
183
|
+
const result = yield removeItemFromWishlist({
|
|
184
|
+
Tapcart: mockTapcart,
|
|
185
|
+
productId: "123",
|
|
186
|
+
selectedVariantId: "789",
|
|
187
|
+
});
|
|
188
|
+
expect(result).toBe(true);
|
|
189
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
190
|
+
productId: "123",
|
|
191
|
+
variantId: "456",
|
|
192
|
+
wishlistId: "wishlist-1",
|
|
193
|
+
});
|
|
194
|
+
}));
|
|
195
|
+
it("should use the provided wishlistId when supplied", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
196
|
+
mockTapcart.variables.wishlists = [];
|
|
197
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
198
|
+
const result = yield removeItemFromWishlist({
|
|
199
|
+
Tapcart: mockTapcart,
|
|
200
|
+
productId: "gid://shopify/Product/123",
|
|
201
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
202
|
+
wishlistId: "gid://shopify/Wishlist/789",
|
|
203
|
+
});
|
|
204
|
+
expect(result).toBe(true);
|
|
205
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
206
|
+
productId: "gid://shopify/Product/123",
|
|
207
|
+
variantId: "456",
|
|
208
|
+
wishlistId: "789",
|
|
209
|
+
});
|
|
210
|
+
}));
|
|
211
|
+
});
|
|
212
|
+
describe("edge cases", () => {
|
|
213
|
+
it("should handle undefined wishlists array", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
mockTapcart.variables.wishlists = undefined;
|
|
215
|
+
const result = yield removeItemFromWishlist({
|
|
216
|
+
Tapcart: mockTapcart,
|
|
217
|
+
productId: "gid://shopify/Product/123",
|
|
218
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
219
|
+
});
|
|
220
|
+
expect(result).toBe(false);
|
|
221
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing wishlist id for wishlist removal");
|
|
222
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
223
|
+
}));
|
|
224
|
+
it("should handle empty wishlists array", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
225
|
+
mockTapcart.variables.wishlists = [];
|
|
226
|
+
const result = yield removeItemFromWishlist({
|
|
227
|
+
Tapcart: mockTapcart,
|
|
228
|
+
productId: "gid://shopify/Product/123",
|
|
229
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
230
|
+
});
|
|
231
|
+
expect(result).toBe(false);
|
|
232
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing wishlist id for wishlist removal");
|
|
233
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
234
|
+
}));
|
|
235
|
+
it("should handle wishlist entry with undefined variantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
236
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = undefined;
|
|
237
|
+
// Mock Tapcart.action to return a success result
|
|
238
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
239
|
+
const result = yield removeItemFromWishlist({
|
|
240
|
+
Tapcart: mockTapcart,
|
|
241
|
+
productId: "gid://shopify/Product/123",
|
|
242
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
243
|
+
});
|
|
244
|
+
expect(result).toBe(true);
|
|
245
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
246
|
+
productId: "gid://shopify/Product/123",
|
|
247
|
+
variantId: "789",
|
|
248
|
+
wishlistId: "wishlist-1",
|
|
249
|
+
});
|
|
250
|
+
}));
|
|
251
|
+
it("should handle wishlist entry with null variantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
252
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = null;
|
|
253
|
+
// Mock Tapcart.action to return a success result
|
|
254
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
255
|
+
const result = yield removeItemFromWishlist({
|
|
256
|
+
Tapcart: mockTapcart,
|
|
257
|
+
productId: "gid://shopify/Product/123",
|
|
258
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
259
|
+
});
|
|
260
|
+
expect(result).toBe(true);
|
|
261
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
262
|
+
productId: "gid://shopify/Product/123",
|
|
263
|
+
variantId: "789",
|
|
264
|
+
wishlistId: "wishlist-1",
|
|
265
|
+
});
|
|
266
|
+
}));
|
|
267
|
+
});
|
|
268
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removeItemFromWishlist.test.d.ts","sourceRoot":"","sources":["../../../tests/removeItemFromWishlists/removeItemFromWishlist.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { removeItemFromWishlist } from "../../lib/utils";
|
|
11
|
+
describe("removeItemFromWishlist", () => {
|
|
12
|
+
let mockTapcart;
|
|
13
|
+
let consoleErrorSpy;
|
|
14
|
+
let consoleLogSpy;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
// Reset mocks before each test
|
|
17
|
+
jest.clearAllMocks();
|
|
18
|
+
// Spy on console methods
|
|
19
|
+
consoleErrorSpy = jest.spyOn(console, "error").mockImplementation();
|
|
20
|
+
consoleLogSpy = jest.spyOn(console, "log").mockImplementation();
|
|
21
|
+
// Default mock Tapcart instance
|
|
22
|
+
mockTapcart = {
|
|
23
|
+
action: jest.fn(),
|
|
24
|
+
variables: {
|
|
25
|
+
customer: { id: "customer-123" },
|
|
26
|
+
wishlists: [
|
|
27
|
+
{
|
|
28
|
+
id: "wishlist-1",
|
|
29
|
+
items: [
|
|
30
|
+
{
|
|
31
|
+
productId: "gid://shopify/Product/123",
|
|
32
|
+
variantId: "gid://shopify/ProductVariant/456",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
consoleErrorSpy.mockRestore();
|
|
42
|
+
consoleLogSpy.mockRestore();
|
|
43
|
+
});
|
|
44
|
+
describe("validation and error handling", () => {
|
|
45
|
+
it("should return false when Tapcart instance is missing", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
const result = yield removeItemFromWishlist({
|
|
47
|
+
Tapcart: null,
|
|
48
|
+
productId: "gid://shopify/Product/123",
|
|
49
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
50
|
+
});
|
|
51
|
+
expect(result).toBe(false);
|
|
52
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Tapcart instance is missing");
|
|
53
|
+
}));
|
|
54
|
+
it("should handle errors gracefully and return false", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
+
// Mock Tapcart.action to throw an error
|
|
56
|
+
mockTapcart.action = jest.fn().mockImplementation(() => {
|
|
57
|
+
throw new Error("Test error");
|
|
58
|
+
});
|
|
59
|
+
const result = yield removeItemFromWishlist({
|
|
60
|
+
Tapcart: mockTapcart,
|
|
61
|
+
productId: "gid://shopify/Product/123",
|
|
62
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
63
|
+
});
|
|
64
|
+
expect(result).toBe(false);
|
|
65
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Failed to remove from wishlist", expect.any(Error));
|
|
66
|
+
}));
|
|
67
|
+
});
|
|
68
|
+
describe("variant ID handling", () => {
|
|
69
|
+
it("should return false when variant ID is missing from both wishlist entry and selectedVariantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
|
+
// Mock Tapcart with no variant ID in wishlist entry
|
|
71
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = null;
|
|
72
|
+
const result = yield removeItemFromWishlist({
|
|
73
|
+
Tapcart: mockTapcart,
|
|
74
|
+
productId: "gid://shopify/Product/123",
|
|
75
|
+
selectedVariantId: null,
|
|
76
|
+
});
|
|
77
|
+
expect(result).toBe(false);
|
|
78
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing variant id for wishlist removal");
|
|
79
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
80
|
+
}));
|
|
81
|
+
it("should use variant ID from wishlist entry when available", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
// Mock Tapcart.action to return a success result
|
|
83
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
84
|
+
const result = yield removeItemFromWishlist({
|
|
85
|
+
Tapcart: mockTapcart,
|
|
86
|
+
productId: "gid://shopify/Product/123",
|
|
87
|
+
selectedVariantId: null,
|
|
88
|
+
});
|
|
89
|
+
expect(result).toBe(true);
|
|
90
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
91
|
+
productId: "gid://shopify/Product/123",
|
|
92
|
+
variantId: "456",
|
|
93
|
+
wishlistId: "wishlist-1",
|
|
94
|
+
});
|
|
95
|
+
}));
|
|
96
|
+
it("should use selectedVariantId when wishlist entry has no variant ID", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
97
|
+
// Mock Tapcart with no variant ID in wishlist entry
|
|
98
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = null;
|
|
99
|
+
// Mock Tapcart.action to return a success result
|
|
100
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
101
|
+
const result = yield removeItemFromWishlist({
|
|
102
|
+
Tapcart: mockTapcart,
|
|
103
|
+
productId: "gid://shopify/Product/123",
|
|
104
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
105
|
+
});
|
|
106
|
+
expect(result).toBe(true);
|
|
107
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
108
|
+
productId: "gid://shopify/Product/123",
|
|
109
|
+
variantId: "789",
|
|
110
|
+
wishlistId: "wishlist-1",
|
|
111
|
+
});
|
|
112
|
+
}));
|
|
113
|
+
it("should prioritize wishlist entry variant ID over selectedVariantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
// Mock Tapcart.action to return a success result
|
|
115
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
116
|
+
const result = yield removeItemFromWishlist({
|
|
117
|
+
Tapcart: mockTapcart,
|
|
118
|
+
productId: "gid://shopify/Product/123",
|
|
119
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
120
|
+
});
|
|
121
|
+
expect(result).toBe(true);
|
|
122
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
123
|
+
productId: "gid://shopify/Product/123",
|
|
124
|
+
variantId: "456",
|
|
125
|
+
wishlistId: "wishlist-1",
|
|
126
|
+
});
|
|
127
|
+
}));
|
|
128
|
+
});
|
|
129
|
+
describe("wishlist ID handling", () => {
|
|
130
|
+
it("should return false when wishlist ID is missing", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
131
|
+
// Mock Tapcart with no wishlist ID
|
|
132
|
+
mockTapcart.variables.wishlists = [];
|
|
133
|
+
const result = yield removeItemFromWishlist({
|
|
134
|
+
Tapcart: mockTapcart,
|
|
135
|
+
productId: "gid://shopify/Product/123",
|
|
136
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
137
|
+
});
|
|
138
|
+
expect(result).toBe(false);
|
|
139
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing wishlist id for wishlist removal");
|
|
140
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
141
|
+
}));
|
|
142
|
+
it("should use wishlist ID from wishlist entry when available", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
+
// Mock Tapcart.action to return a success result
|
|
144
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
145
|
+
const result = yield removeItemFromWishlist({
|
|
146
|
+
Tapcart: mockTapcart,
|
|
147
|
+
productId: "gid://shopify/Product/123",
|
|
148
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
149
|
+
});
|
|
150
|
+
expect(result).toBe(true);
|
|
151
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
152
|
+
productId: "gid://shopify/Product/123",
|
|
153
|
+
variantId: "456",
|
|
154
|
+
wishlistId: "wishlist-1", // From wishlist entry
|
|
155
|
+
});
|
|
156
|
+
}));
|
|
157
|
+
});
|
|
158
|
+
describe("GID handling", () => {
|
|
159
|
+
it("should extract IDs from GID format", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
// Mock Tapcart with GID format
|
|
161
|
+
mockTapcart.variables.wishlists[0].items[0].productId = "gid://shopify/Product/123?param=value";
|
|
162
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = "gid://shopify/ProductVariant/456?param=value";
|
|
163
|
+
// Mock Tapcart.action to return a success result
|
|
164
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
165
|
+
const result = yield removeItemFromWishlist({
|
|
166
|
+
Tapcart: mockTapcart,
|
|
167
|
+
productId: "gid://shopify/Product/123?param=value",
|
|
168
|
+
selectedVariantId: "gid://shopify/ProductVariant/789?param=value",
|
|
169
|
+
});
|
|
170
|
+
expect(result).toBe(true);
|
|
171
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
172
|
+
productId: "gid://shopify/Product/123?param=value",
|
|
173
|
+
variantId: "456",
|
|
174
|
+
wishlistId: "wishlist-1",
|
|
175
|
+
});
|
|
176
|
+
}));
|
|
177
|
+
it("should handle plain IDs without GID format", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
178
|
+
// Mock Tapcart with plain IDs
|
|
179
|
+
mockTapcart.variables.wishlists[0].items[0].productId = "123";
|
|
180
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = "456";
|
|
181
|
+
// Mock Tapcart.action to return a success result
|
|
182
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
183
|
+
const result = yield removeItemFromWishlist({
|
|
184
|
+
Tapcart: mockTapcart,
|
|
185
|
+
productId: "123",
|
|
186
|
+
selectedVariantId: "789",
|
|
187
|
+
});
|
|
188
|
+
expect(result).toBe(true);
|
|
189
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
190
|
+
productId: "123",
|
|
191
|
+
variantId: "456",
|
|
192
|
+
wishlistId: "wishlist-1",
|
|
193
|
+
});
|
|
194
|
+
}));
|
|
195
|
+
it("should use the provided wishlistId when supplied", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
196
|
+
mockTapcart.variables.wishlists = [];
|
|
197
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
198
|
+
const result = yield removeItemFromWishlist({
|
|
199
|
+
Tapcart: mockTapcart,
|
|
200
|
+
productId: "gid://shopify/Product/123",
|
|
201
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
202
|
+
wishlistId: "gid://shopify/Wishlist/789",
|
|
203
|
+
});
|
|
204
|
+
expect(result).toBe(true);
|
|
205
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
206
|
+
productId: "gid://shopify/Product/123",
|
|
207
|
+
variantId: "456",
|
|
208
|
+
wishlistId: "789",
|
|
209
|
+
});
|
|
210
|
+
}));
|
|
211
|
+
});
|
|
212
|
+
describe("edge cases", () => {
|
|
213
|
+
it("should handle undefined wishlists array", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
mockTapcart.variables.wishlists = undefined;
|
|
215
|
+
const result = yield removeItemFromWishlist({
|
|
216
|
+
Tapcart: mockTapcart,
|
|
217
|
+
productId: "gid://shopify/Product/123",
|
|
218
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
219
|
+
});
|
|
220
|
+
expect(result).toBe(false);
|
|
221
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing wishlist id for wishlist removal");
|
|
222
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
223
|
+
}));
|
|
224
|
+
it("should handle empty wishlists array", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
225
|
+
mockTapcart.variables.wishlists = [];
|
|
226
|
+
const result = yield removeItemFromWishlist({
|
|
227
|
+
Tapcart: mockTapcart,
|
|
228
|
+
productId: "gid://shopify/Product/123",
|
|
229
|
+
selectedVariantId: "gid://shopify/ProductVariant/456",
|
|
230
|
+
});
|
|
231
|
+
expect(result).toBe(false);
|
|
232
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Missing wishlist id for wishlist removal");
|
|
233
|
+
expect(mockTapcart.action).not.toHaveBeenCalled();
|
|
234
|
+
}));
|
|
235
|
+
it("should handle wishlist entry with undefined variantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
236
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = undefined;
|
|
237
|
+
// Mock Tapcart.action to return a success result
|
|
238
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
239
|
+
const result = yield removeItemFromWishlist({
|
|
240
|
+
Tapcart: mockTapcart,
|
|
241
|
+
productId: "gid://shopify/Product/123",
|
|
242
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
243
|
+
});
|
|
244
|
+
expect(result).toBe(true);
|
|
245
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
246
|
+
productId: "gid://shopify/Product/123",
|
|
247
|
+
variantId: "789",
|
|
248
|
+
wishlistId: "wishlist-1",
|
|
249
|
+
});
|
|
250
|
+
}));
|
|
251
|
+
it("should handle wishlist entry with null variantId", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
252
|
+
mockTapcart.variables.wishlists[0].items[0].variantId = null;
|
|
253
|
+
// Mock Tapcart.action to return a success result
|
|
254
|
+
mockTapcart.action = jest.fn().mockResolvedValue(true);
|
|
255
|
+
const result = yield removeItemFromWishlist({
|
|
256
|
+
Tapcart: mockTapcart,
|
|
257
|
+
productId: "gid://shopify/Product/123",
|
|
258
|
+
selectedVariantId: "gid://shopify/ProductVariant/789",
|
|
259
|
+
});
|
|
260
|
+
expect(result).toBe(true);
|
|
261
|
+
expect(mockTapcart.action).toHaveBeenCalledWith("wishlist/item/remove", {
|
|
262
|
+
productId: "gid://shopify/Product/123",
|
|
263
|
+
variantId: "789",
|
|
264
|
+
wishlistId: "wishlist-1",
|
|
265
|
+
});
|
|
266
|
+
}));
|
|
267
|
+
});
|
|
268
|
+
});
|