@tapcart/mobile-components 0.11.6 → 0.11.7

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.
Files changed (27) hide show
  1. package/dist/components/hooks/use-infinite-wishlist.d.ts.map +1 -1
  2. package/dist/components/hooks/use-infinite-wishlist.js +15 -2
  3. package/dist/components/ui/image.d.ts.map +1 -1
  4. package/dist/components/ui/image.js +2 -1
  5. package/dist/lib/utils/html.d.ts +16 -0
  6. package/dist/lib/utils/html.d.ts.map +1 -0
  7. package/dist/lib/utils/html.js +56 -0
  8. package/dist/styles.css +7 -6
  9. package/dist/tests/utils/html.test.d.ts +2 -0
  10. package/dist/tests/utils/html.test.d.ts.map +1 -0
  11. package/dist/tests/utils/html.test.js +104 -0
  12. package/package.json +1 -1
  13. package/dist/lib/isVersion20.util.d.ts +0 -2
  14. package/dist/lib/isVersion20.util.d.ts.map +0 -1
  15. package/dist/lib/isVersion20.util.js +0 -7
  16. package/dist/lib/utils.wishlist.test.d.ts +0 -2
  17. package/dist/lib/utils.wishlist.test.d.ts.map +0 -1
  18. package/dist/lib/utils.wishlist.test.js +0 -108
  19. package/dist/tests/addItemToWishlist/addItemToWishlist.wishlistId.test.d.ts +0 -2
  20. package/dist/tests/addItemToWishlist/addItemToWishlist.wishlistId.test.d.ts.map +0 -1
  21. package/dist/tests/addItemToWishlist/addItemToWishlist.wishlistId.test.js +0 -50
  22. package/dist/tests/removeItemFromWishlist/removeItemFromWishlist.test.d.ts +0 -2
  23. package/dist/tests/removeItemFromWishlist/removeItemFromWishlist.test.d.ts.map +0 -1
  24. package/dist/tests/removeItemFromWishlist/removeItemFromWishlist.test.js +0 -268
  25. package/dist/tests/removeItemFromWishlists/removeItemFromWishlist.test.d.ts +0 -2
  26. package/dist/tests/removeItemFromWishlists/removeItemFromWishlist.test.d.ts.map +0 -1
  27. package/dist/tests/removeItemFromWishlists/removeItemFromWishlist.test.js +0 -268
@@ -1 +1 @@
1
- {"version":3,"file":"use-infinite-wishlist.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-infinite-wishlist.ts"],"names":[],"mappings":"AAOA,KAAK,cAAc,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,KAAK,0BAA0B,GAAG;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,gBAAgB,EAAE,OAAO,CAAA;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,eAAe,EAAE,KAAK,CAAC;QACrB,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;KACd,CAAC,CAAA;IACF,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAED,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,OAAO,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,aAAa,CAAC,EAAE;QACd,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAKD,wBAAgB,mBAAmB,CAAC,EAClC,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,UAAkB,EAClB,cAAmB,EACnB,UAAe,GAChB,EAAE,0BAA0B;;;;;;;;;EAsN5B"}
1
+ {"version":3,"file":"use-infinite-wishlist.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-infinite-wishlist.ts"],"names":[],"mappings":"AAOA,KAAK,cAAc,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,KAAK,0BAA0B,GAAG;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,gBAAgB,EAAE,OAAO,CAAA;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,eAAe,EAAE,KAAK,CAAC;QACrB,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;KACd,CAAC,CAAA;IACF,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAED,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,OAAO,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,aAAa,CAAC,EAAE;QACd,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF,CAAA;AAKD,wBAAgB,mBAAmB,CAAC,EAClC,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,UAAkB,EAClB,cAAmB,EACnB,UAAe,GAChB,EAAE,0BAA0B;;;;;;;;;EAsO5B"}
@@ -77,7 +77,13 @@ export function useInfiniteWishlist({ initialProductIds, chunkSize, apiUrl, shou
77
77
  handleFetchError(err, "fetch mocked products");
78
78
  return [];
79
79
  }
80
- }), [apiUrl, collectionToFetchID]);
80
+ }), [
81
+ apiUrl,
82
+ collectionToFetchID,
83
+ queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.language,
84
+ queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.country,
85
+ queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.appId,
86
+ ]);
81
87
  const fetchProducts = useCallback((ids) => __awaiter(this, void 0, void 0, function* () {
82
88
  if (!ids.length)
83
89
  return [];
@@ -85,6 +91,13 @@ export function useInfiniteWishlist({ initialProductIds, chunkSize, apiUrl, shou
85
91
  return fetchMockedProducts();
86
92
  const queryParams = new URLSearchParams();
87
93
  queryParams.set("ids", getProductGidsFromIds(ids).join(","));
94
+ // Add country and language parameters for correct currency/pricing
95
+ if (queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.country) {
96
+ queryParams.set("country", queryVariables.country);
97
+ }
98
+ if (queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.language) {
99
+ queryParams.set("language", queryVariables.language);
100
+ }
88
101
  const url = `${apiUrl}/products/by-ids?${queryParams.toString()}`;
89
102
  try {
90
103
  const response = yield fetch(url);
@@ -115,7 +128,7 @@ export function useInfiniteWishlist({ initialProductIds, chunkSize, apiUrl, shou
115
128
  handleFetchError(err, "fetch products");
116
129
  return [];
117
130
  }
118
- }), [apiUrl, shouldMock, fetchMockedProducts, variantIds]);
131
+ }), [apiUrl, shouldMock, fetchMockedProducts, variantIds, queryVariables]);
119
132
  const loadMore = useCallback(() => __awaiter(this, void 0, void 0, function* () {
120
133
  if (loadingRef.current ||
121
134
  (!shouldMock && !(allProductIds.length - loadedIndex > 0))) {
@@ -1 +1 @@
1
- {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../components/ui/image.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../components/ui/image.tsx"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
14
14
  /* eslint-disable @next/next/no-img-element */
15
15
  import * as React from "react";
16
16
  import ReactDOM from "react-dom";
17
+ import { stripHtml } from "../../lib/utils/html";
17
18
  function ImagePreload({ imgAttributes }) {
18
19
  const opts = {
19
20
  as: "image",
@@ -102,7 +103,7 @@ export const Image = React.forwardRef((_a, ref) => {
102
103
  : "";
103
104
  const nHeight = autoHeight ? "auto" : fixedHeight;
104
105
  const nSrc = src || (data === null || data === void 0 ? void 0 : data.url);
105
- const nAlt = (data === null || data === void 0 ? void 0 : data.altText) && !alt ? data === null || data === void 0 ? void 0 : data.altText : alt || "";
106
+ const nAlt = stripHtml((data === null || data === void 0 ? void 0 : data.altText) && !alt ? data === null || data === void 0 ? void 0 : data.altText : alt || "");
106
107
  const nAspectRatio = aspectRatio
107
108
  ? aspectRatio
108
109
  : normalizedData.unitsMatch
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Strips HTML tags from a string using DOM parsing to handle nested elements correctly.
3
+ *
4
+ * @param html - The HTML string to strip tags from
5
+ * @returns Clean text content with HTML tags removed
6
+ *
7
+ * @example
8
+ * ```
9
+ * stripHtml('<p><strong>New Arrivals</strong></p>') // returns 'New Arrivals'
10
+ * stripHtml('<div>Hello <span>World</span>!</div>') // returns 'Hello World!'
11
+ * stripHtml('<p>First</p><p>Second</p>') // returns 'First Second'
12
+ * stripHtml('Plain text') // returns 'Plain text'
13
+ * ```
14
+ */
15
+ export declare const stripHtml: (html: string | null | undefined) => string;
16
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../lib/utils/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,SAAU,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,MAgD3D,CAAA"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Strips HTML tags from a string using DOM parsing to handle nested elements correctly.
3
+ *
4
+ * @param html - The HTML string to strip tags from
5
+ * @returns Clean text content with HTML tags removed
6
+ *
7
+ * @example
8
+ * ```
9
+ * stripHtml('<p><strong>New Arrivals</strong></p>') // returns 'New Arrivals'
10
+ * stripHtml('<div>Hello <span>World</span>!</div>') // returns 'Hello World!'
11
+ * stripHtml('<p>First</p><p>Second</p>') // returns 'First Second'
12
+ * stripHtml('Plain text') // returns 'Plain text'
13
+ * ```
14
+ */
15
+ export const stripHtml = (html) => {
16
+ // Handle null, undefined, or empty inputs
17
+ if (typeof html !== "string") {
18
+ return "";
19
+ }
20
+ try {
21
+ // Create a temporary DOM element
22
+ const tempDiv = document.createElement("div");
23
+ // Set the HTML content
24
+ tempDiv.innerHTML = html;
25
+ // Add spaces between block-level elements for accessibility and screen reader compatibility
26
+ // This ensures proper separation between content blocks while preserving existing meaningful whitespace
27
+ const blockElements = tempDiv.querySelectorAll("p, div, h1, h2, h3, h4, h5, h6, li, blockquote, pre, section, article, aside, header, footer, main, nav");
28
+ blockElements.forEach((element, index) => {
29
+ var _a;
30
+ // Skip the first element (index 0) to avoid adding a leading space
31
+ if (index === 0)
32
+ return;
33
+ // Check if there's already meaningful whitespace before this element
34
+ const prevSibling = element.previousSibling;
35
+ const hasWhitespaceBefore = prevSibling &&
36
+ prevSibling.nodeType === Node.TEXT_NODE &&
37
+ /\s$/.test(prevSibling.textContent || "");
38
+ // If whitespace already exists, don't add another space
39
+ if (hasWhitespaceBefore)
40
+ return;
41
+ // Only insert a space if there's no existing whitespace
42
+ // This prevents "FirstSecond" and ensures "First Second" for screen readers
43
+ const spaceNode = document.createTextNode(" ");
44
+ (_a = element.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(spaceNode, element);
45
+ });
46
+ // Extract text content (this handles nested elements automatically)
47
+ const textContent = tempDiv.textContent || tempDiv.innerText || "";
48
+ // Return trimmed text
49
+ return textContent.trim();
50
+ }
51
+ catch (error) {
52
+ // If DOM parsing fails for any reason, return the original string
53
+ console.warn("Failed to strip HTML, returning original string:", error);
54
+ return html;
55
+ }
56
+ };
package/dist/styles.css CHANGED
@@ -778,9 +778,6 @@ video {
778
778
  .top-\[50\%\] {
779
779
  top: 50%;
780
780
  }
781
- .z-0 {
782
- z-index: 0;
783
- }
784
781
  .z-10 {
785
782
  z-index: 10;
786
783
  }
@@ -844,6 +841,10 @@ video {
844
841
  margin-top: 0px;
845
842
  margin-bottom: 0px;
846
843
  }
844
+ .my-1 {
845
+ margin-top: 0.25rem;
846
+ margin-bottom: 0.25rem;
847
+ }
847
848
  .my-3 {
848
849
  margin-top: 0.75rem;
849
850
  margin-bottom: 0.75rem;
@@ -889,9 +890,6 @@ video {
889
890
  .ml-2 {
890
891
  margin-left: 0.5rem;
891
892
  }
892
- .ml-4 {
893
- margin-left: 1rem;
894
- }
895
893
  .ml-auto {
896
894
  margin-left: auto;
897
895
  }
@@ -1685,6 +1683,9 @@ video {
1685
1683
  .border-t-\[0px\] {
1686
1684
  border-top-width: 0px;
1687
1685
  }
1686
+ .border-solid {
1687
+ border-style: solid;
1688
+ }
1688
1689
  .border-none {
1689
1690
  border-style: none;
1690
1691
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=html.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.test.d.ts","sourceRoot":"","sources":["../../../tests/utils/html.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { stripHtml } from "../../lib/utils/html";
2
+ describe("stripHtml", () => {
3
+ describe("nested HTML handling", () => {
4
+ it("should strip nested HTML tags correctly", () => {
5
+ const result = stripHtml("<p><strong>New Arrivals</strong></p>");
6
+ expect(result).toBe("New Arrivals");
7
+ });
8
+ it("should handle multiple nested elements", () => {
9
+ const result = stripHtml("<div>Hello <span>World</span>!</div>");
10
+ expect(result).toBe("Hello World!");
11
+ });
12
+ it("should handle deeply nested HTML", () => {
13
+ const result = stripHtml("<div><p><span><strong>Deep</strong> <em>nested</em></span> text</p></div>");
14
+ expect(result).toBe("Deep nested text");
15
+ });
16
+ it("should handle multiple paragraph elements at the top level", () => {
17
+ const result = stripHtml("<p>First paragraph</p><p>Second paragraph</p><p>Third paragraph</p>");
18
+ expect(result).toBe("First paragraph Second paragraph Third paragraph");
19
+ });
20
+ it("should handle mixed block-level elements with spaces", () => {
21
+ const result = stripHtml("<h1>Title</h1><p>Content</p><div>Footer</div>");
22
+ expect(result).toBe("Title Content Footer");
23
+ });
24
+ it("should handle list items with spaces", () => {
25
+ const result = stripHtml("<li>Item 1</li><li>Item 2</li><li>Item 3</li>");
26
+ expect(result).toBe("Item 1 Item 2 Item 3");
27
+ });
28
+ });
29
+ describe("plain text handling", () => {
30
+ it("should return plain text unchanged", () => {
31
+ const result = stripHtml("Plain text");
32
+ expect(result).toBe("Plain text");
33
+ });
34
+ it("should trim whitespace from result", () => {
35
+ const result = stripHtml("<p> Trimmed text </p>");
36
+ expect(result).toBe("Trimmed text");
37
+ });
38
+ });
39
+ describe("edge cases", () => {
40
+ it("should handle null input", () => {
41
+ const result = stripHtml(null);
42
+ expect(result).toBe("");
43
+ });
44
+ it("should handle undefined input", () => {
45
+ const result = stripHtml(undefined);
46
+ expect(result).toBe("");
47
+ });
48
+ it("should handle empty string", () => {
49
+ const result = stripHtml("");
50
+ expect(result).toBe("");
51
+ });
52
+ it("should handle non-string input", () => {
53
+ const result = stripHtml(123);
54
+ expect(result).toBe("");
55
+ });
56
+ it("should handle malformed HTML", () => {
57
+ const result = stripHtml("<p>Malformed <strong>content</p>");
58
+ expect(result).toBe("Malformed content");
59
+ });
60
+ it("should handle HTML with script tags", () => {
61
+ const result = stripHtml("<p>Safe content</p><script>alert('xss')</script>");
62
+ expect(result).toBe("Safe contentalert('xss')");
63
+ });
64
+ it("should handle self-closing tags", () => {
65
+ const result = stripHtml("<p>Line 1<br/>Line 2</p>");
66
+ expect(result).toBe("Line 1Line 2");
67
+ });
68
+ });
69
+ describe("error handling", () => {
70
+ it("should handle DOM parsing errors gracefully", () => {
71
+ const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
72
+ // Create a scenario that might cause DOM parsing to fail
73
+ const originalCreateElement = document.createElement;
74
+ document.createElement = jest.fn().mockImplementation(() => {
75
+ throw new Error("DOM error");
76
+ });
77
+ const result = stripHtml("<p>Error content</p>");
78
+ expect(result).toBe("<p>Error content</p>");
79
+ expect(consoleSpy).toHaveBeenCalledWith("Failed to strip HTML, returning original string:", expect.any(Error));
80
+ document.createElement = originalCreateElement;
81
+ consoleSpy.mockRestore();
82
+ });
83
+ });
84
+ describe("HTML entities", () => {
85
+ it("should handle HTML entities correctly", () => {
86
+ const result = stripHtml("<p>Hello &amp; goodbye &lt; &gt; &quot; &#x27;</p>");
87
+ expect(result).toBe("Hello & goodbye < > \" '");
88
+ });
89
+ it("should handle numeric HTML entities", () => {
90
+ const result = stripHtml("<p>&#8364; &#169; &#174;</p>");
91
+ expect(result).toBe("€ © ®");
92
+ });
93
+ });
94
+ describe("whitespace handling", () => {
95
+ it("should preserve meaningful whitespace", () => {
96
+ const result = stripHtml("<p>Hello <span>beautiful</span> world</p>");
97
+ expect(result).toBe("Hello beautiful world");
98
+ });
99
+ it("should handle line breaks and tabs", () => {
100
+ const result = stripHtml("<div>Line 1\n<p>Line 2</p>\t<span>Line 3</span></div>");
101
+ expect(result).toBe("Line 1\nLine 2\tLine 3");
102
+ });
103
+ });
104
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapcart/mobile-components",
3
- "version": "0.11.6",
3
+ "version": "0.11.7",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "style": "dist/styles.css",
@@ -1,2 +0,0 @@
1
- export declare const isVersion20: (version: string | null | undefined) => boolean;
2
- //# sourceMappingURL=isVersion20.util.d.ts.map
@@ -1 +0,0 @@
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"}
@@ -1,7 +0,0 @@
1
- import { SemVer } from "semver";
2
- export const isVersion20 = (version) => {
3
- if (!version)
4
- return false;
5
- const currentVersion = new SemVer(version || "0.0.0");
6
- return currentVersion.compare("13.20.0") >= 0;
7
- };
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=utils.wishlist.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.wishlist.test.d.ts","sourceRoot":"","sources":["../../lib/utils.wishlist.test.ts"],"names":[],"mappings":""}
@@ -1,108 +0,0 @@
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
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=addItemToWishlist.wishlistId.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"addItemToWishlist.wishlistId.test.d.ts","sourceRoot":"","sources":["../../../tests/addItemToWishlist/addItemToWishlist.wishlistId.test.ts"],"names":[],"mappings":""}
@@ -1,50 +0,0 @@
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
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=removeItemFromWishlist.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"removeItemFromWishlist.test.d.ts","sourceRoot":"","sources":["../../../tests/removeItemFromWishlist/removeItemFromWishlist.test.ts"],"names":[],"mappings":""}
@@ -1,268 +0,0 @@
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
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=removeItemFromWishlist.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"removeItemFromWishlist.test.d.ts","sourceRoot":"","sources":["../../../tests/removeItemFromWishlists/removeItemFromWishlist.test.ts"],"names":[],"mappings":""}
@@ -1,268 +0,0 @@
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
- });