@tapcart/mobile-components 0.11.5 → 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/money.d.ts.map +1 -1
- package/dist/components/ui/money.js +53 -21
- 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/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
|
@@ -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"}
|
|
@@ -25,27 +25,59 @@ 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
27
|
const searchParams = useSearchParams();
|
|
28
|
-
const countryFromParams = searchParams === null || searchParams === void 0 ? void 0 : searchParams.get("country");
|
|
29
|
-
//
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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);
|
|
49
81
|
const formatter = React.useMemo(() => new Intl.NumberFormat(language, {
|
|
50
82
|
style: "currency",
|
|
51
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
|
+
});
|
|
@@ -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
|
+
});
|