@frak-labs/core-sdk 0.1.1 → 0.2.0-beta.7898df5b
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/README.md +58 -0
- package/cdn/bundle.js +14 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +3 -3
- package/dist/actions.d.ts +3 -3
- package/dist/actions.js +1 -1
- package/dist/bundle.cjs +1 -1
- package/dist/bundle.d.cts +4 -6
- package/dist/bundle.d.ts +4 -6
- package/dist/bundle.js +1 -1
- package/dist/computeLegacyProductId-CCAZvLa5.d.cts +537 -0
- package/dist/computeLegacyProductId-b5cUWdAm.d.ts +537 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -1
- package/dist/{openSso-D--Airj6.d.cts → openSso-B0g7-807.d.cts} +173 -136
- package/dist/{openSso-DsKJ4y0j.d.ts → openSso-CMzwvaCa.d.ts} +173 -136
- package/dist/setupClient-BICl5fdX.js +13 -0
- package/dist/setupClient-nl8Dhh4V.cjs +13 -0
- package/dist/siweAuthenticate-BWmI2_TN.cjs +1 -0
- package/dist/{index-d8xS4ryI.d.ts → siweAuthenticate-CVigMOxz.d.cts} +113 -92
- package/dist/{index-C6FxkWPC.d.cts → siweAuthenticate-CnCZ7mok.d.ts} +113 -92
- package/dist/siweAuthenticate-zczqxm0a.js +1 -0
- package/dist/trackEvent-CeLFVzZn.js +1 -0
- package/dist/trackEvent-Ew5r5zfI.cjs +1 -0
- package/package.json +11 -22
- package/src/actions/displayEmbeddedWallet.ts +1 -0
- package/src/actions/displayModal.test.ts +12 -11
- package/src/actions/displayModal.ts +7 -18
- package/src/actions/ensureIdentity.ts +68 -0
- package/src/actions/{getProductInformation.test.ts → getMerchantInformation.test.ts} +33 -50
- package/src/actions/getMerchantInformation.ts +16 -0
- package/src/actions/index.ts +3 -2
- package/src/actions/openSso.ts +4 -2
- package/src/actions/referral/processReferral.test.ts +117 -242
- package/src/actions/referral/processReferral.ts +134 -204
- package/src/actions/referral/referralInteraction.test.ts +4 -12
- package/src/actions/referral/referralInteraction.ts +3 -13
- package/src/actions/sendInteraction.ts +46 -22
- package/src/actions/trackPurchaseStatus.test.ts +354 -141
- package/src/actions/trackPurchaseStatus.ts +48 -11
- package/src/actions/watchWalletStatus.ts +2 -3
- package/src/actions/wrapper/modalBuilder.test.ts +0 -14
- package/src/actions/wrapper/modalBuilder.ts +3 -12
- package/src/bundle.ts +0 -1
- package/src/clients/createIFrameFrakClient.ts +10 -5
- package/src/clients/transports/iframeLifecycleManager.test.ts +163 -4
- package/src/clients/transports/iframeLifecycleManager.ts +172 -33
- package/src/constants/interactionTypes.ts +12 -41
- package/src/index.ts +27 -16
- package/src/types/config.ts +6 -0
- package/src/types/context.ts +48 -6
- package/src/types/index.ts +15 -11
- package/src/types/lifecycle/client.ts +24 -1
- package/src/types/lifecycle/iframe.ts +6 -0
- package/src/types/rpc/displayModal.ts +2 -4
- package/src/types/rpc/embedded/index.ts +2 -2
- package/src/types/rpc/interaction.ts +31 -39
- package/src/types/rpc/merchantInformation.ts +77 -0
- package/src/types/rpc/modal/index.ts +0 -4
- package/src/types/rpc/modal/login.ts +5 -1
- package/src/types/rpc/walletStatus.ts +1 -7
- package/src/types/rpc.ts +22 -30
- package/src/types/tracking.ts +31 -0
- package/src/utils/FrakContext.test.ts +270 -186
- package/src/utils/FrakContext.ts +78 -56
- package/src/utils/backendUrl.test.ts +83 -0
- package/src/utils/backendUrl.ts +62 -0
- package/src/utils/clientId.test.ts +41 -0
- package/src/utils/clientId.ts +43 -0
- package/src/utils/compression/compress.test.ts +1 -1
- package/src/utils/compression/compress.ts +2 -2
- package/src/utils/compression/decompress.test.ts +8 -4
- package/src/utils/compression/decompress.ts +2 -2
- package/src/utils/{computeProductId.ts → computeLegacyProductId.ts} +2 -2
- package/src/utils/constants.ts +5 -0
- package/src/utils/deepLinkWithFallback.test.ts +243 -0
- package/src/utils/deepLinkWithFallback.ts +103 -0
- package/src/utils/formatAmount.ts +6 -0
- package/src/utils/iframeHelper.test.ts +18 -5
- package/src/utils/iframeHelper.ts +10 -3
- package/src/utils/index.ts +16 -1
- package/src/utils/merchantId.test.ts +653 -0
- package/src/utils/merchantId.ts +143 -0
- package/src/utils/sso.ts +18 -11
- package/src/utils/trackEvent.test.ts +23 -5
- package/src/utils/trackEvent.ts +13 -0
- package/cdn/bundle.iife.js +0 -14
- package/dist/actions-B5j-i1p0.cjs +0 -1
- package/dist/actions-q090Z0oR.js +0 -1
- package/dist/index-7OZ39x1U.d.ts +0 -195
- package/dist/index-CRsQWnTs.d.cts +0 -351
- package/dist/index-Ck1hudEi.d.ts +0 -351
- package/dist/index-zDq-VlKx.d.cts +0 -195
- package/dist/interaction-DMJ3ZfaF.d.cts +0 -45
- package/dist/interaction-KX1h9a7V.d.ts +0 -45
- package/dist/interactions-DnfM3oe0.js +0 -1
- package/dist/interactions-EIXhNLf6.cjs +0 -1
- package/dist/interactions.cjs +0 -1
- package/dist/interactions.d.cts +0 -2
- package/dist/interactions.d.ts +0 -2
- package/dist/interactions.js +0 -1
- package/dist/productTypes-BUkXJKZ7.cjs +0 -1
- package/dist/productTypes-CGb1MmBF.js +0 -1
- package/dist/src-1LQ4eLq5.js +0 -13
- package/dist/src-hW71KjPN.cjs +0 -13
- package/dist/trackEvent-CHnYa85W.js +0 -1
- package/dist/trackEvent-GuQm_1Nm.cjs +0 -1
- package/src/actions/getProductInformation.ts +0 -14
- package/src/actions/openSso.test.ts +0 -407
- package/src/actions/sendInteraction.test.ts +0 -219
- package/src/constants/interactionTypes.test.ts +0 -128
- package/src/constants/productTypes.test.ts +0 -130
- package/src/constants/productTypes.ts +0 -33
- package/src/interactions/index.ts +0 -5
- package/src/interactions/pressEncoder.test.ts +0 -215
- package/src/interactions/pressEncoder.ts +0 -53
- package/src/interactions/purchaseEncoder.test.ts +0 -291
- package/src/interactions/purchaseEncoder.ts +0 -99
- package/src/interactions/referralEncoder.test.ts +0 -170
- package/src/interactions/referralEncoder.ts +0 -47
- package/src/interactions/retailEncoder.test.ts +0 -107
- package/src/interactions/retailEncoder.ts +0 -37
- package/src/interactions/webshopEncoder.test.ts +0 -56
- package/src/interactions/webshopEncoder.ts +0 -30
- package/src/types/rpc/modal/openSession.ts +0 -25
- package/src/types/rpc/productInformation.ts +0 -59
- package/src/utils/computeProductId.test.ts +0 -80
- package/src/utils/sso.test.ts +0 -361
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { vi } from "vitest"; // Keep vi from vitest for vi.mock() hoisting
|
|
1
|
+
import type { Address } from "viem";
|
|
2
|
+
import { vi } from "vitest";
|
|
4
3
|
import {
|
|
5
4
|
afterEach,
|
|
6
5
|
beforeEach,
|
|
@@ -11,22 +10,13 @@ import {
|
|
|
11
10
|
import type {
|
|
12
11
|
FrakClient,
|
|
13
12
|
FrakContext,
|
|
13
|
+
FrakContextV2,
|
|
14
14
|
WalletStatusReturnType,
|
|
15
15
|
} from "../../types";
|
|
16
16
|
import { processReferral } from "./processReferral";
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
vi.
|
|
20
|
-
computeProductId: vi.fn(
|
|
21
|
-
() =>
|
|
22
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001" as Hex
|
|
23
|
-
),
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
// Mock dependencies
|
|
27
|
-
vi.mock("../../index", () => ({
|
|
28
|
-
displayEmbeddedWallet: vi.fn(),
|
|
29
|
-
sendInteraction: vi.fn(),
|
|
18
|
+
vi.mock("../sendInteraction", () => ({
|
|
19
|
+
sendInteraction: vi.fn().mockResolvedValue(undefined),
|
|
30
20
|
}));
|
|
31
21
|
|
|
32
22
|
vi.mock("../../utils", () => ({
|
|
@@ -34,33 +24,19 @@ vi.mock("../../utils", () => ({
|
|
|
34
24
|
replaceUrl: vi.fn(),
|
|
35
25
|
},
|
|
36
26
|
trackEvent: vi.fn(),
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
vi.mock("../../interactions", () => ({
|
|
40
|
-
ReferralInteractionEncoder: {
|
|
41
|
-
referred: vi.fn(({ referrer }: { referrer: Address }) => ({
|
|
42
|
-
interactionData: `0x${referrer.slice(2)}` as Hex,
|
|
43
|
-
handlerTypeDenominator: "0x01" as Hex,
|
|
44
|
-
})),
|
|
45
|
-
},
|
|
27
|
+
resolveMerchantId: vi.fn().mockResolvedValue(undefined),
|
|
28
|
+
getClientId: vi.fn().mockReturnValue("test-client-id"),
|
|
46
29
|
}));
|
|
47
30
|
|
|
48
31
|
describe("processReferral", () => {
|
|
49
32
|
let mockClient: FrakClient;
|
|
50
33
|
let mockAddress: Address;
|
|
51
|
-
let mockReferrerAddress: Address;
|
|
52
|
-
let mockProductId: Hex;
|
|
53
34
|
let mockWalletStatus: WalletStatusReturnType;
|
|
54
|
-
let mockFrakContext: Partial<FrakContext>;
|
|
55
35
|
|
|
56
36
|
beforeEach(async () => {
|
|
57
37
|
vi.clearAllMocks();
|
|
58
38
|
|
|
59
39
|
mockAddress = "0x1234567890123456789012345678901234567890" as Address;
|
|
60
|
-
mockReferrerAddress =
|
|
61
|
-
"0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address;
|
|
62
|
-
mockProductId =
|
|
63
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001" as Hex;
|
|
64
40
|
|
|
65
41
|
mockClient = {
|
|
66
42
|
openPanel: {
|
|
@@ -78,17 +54,8 @@ describe("processReferral", () => {
|
|
|
78
54
|
mockWalletStatus = {
|
|
79
55
|
key: "connected" as const,
|
|
80
56
|
wallet: mockAddress,
|
|
81
|
-
interactionSession: {
|
|
82
|
-
startTimestamp: Date.now() - 3600000,
|
|
83
|
-
endTimestamp: Date.now() + 3600000,
|
|
84
|
-
},
|
|
85
57
|
};
|
|
86
58
|
|
|
87
|
-
mockFrakContext = {
|
|
88
|
-
r: mockReferrerAddress,
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// Mock window.location
|
|
92
59
|
Object.defineProperty(window, "location", {
|
|
93
60
|
value: {
|
|
94
61
|
href: "https://example.com/test",
|
|
@@ -101,19 +68,6 @@ describe("processReferral", () => {
|
|
|
101
68
|
vi.clearAllMocks();
|
|
102
69
|
});
|
|
103
70
|
|
|
104
|
-
it("should return 'no-referrer' when frakContext has no referrer", async () => {
|
|
105
|
-
const utils = await import("../../utils");
|
|
106
|
-
|
|
107
|
-
const result = await processReferral(mockClient, {
|
|
108
|
-
walletStatus: mockWalletStatus,
|
|
109
|
-
frakContext: {},
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
expect(result).toBe("no-referrer");
|
|
113
|
-
// sendInteraction should not be called when there's no referrer
|
|
114
|
-
expect(utils.FrakContextManager.replaceUrl).toHaveBeenCalled();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
71
|
it("should return 'no-referrer' when frakContext is null", async () => {
|
|
118
72
|
const result = await processReferral(mockClient, {
|
|
119
73
|
walletStatus: mockWalletStatus,
|
|
@@ -121,177 +75,150 @@ describe("processReferral", () => {
|
|
|
121
75
|
});
|
|
122
76
|
|
|
123
77
|
expect(result).toBe("no-referrer");
|
|
124
|
-
// sendInteraction should not be called when there's no referrer
|
|
125
78
|
});
|
|
126
79
|
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
expect(result).toBe("self-referral");
|
|
136
|
-
// sendInteraction should not be called for self-referrals
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it("should successfully process referral when all conditions are met", async () => {
|
|
140
|
-
const utils = await import("../../utils");
|
|
141
|
-
|
|
142
|
-
// Mock client.request for sendInteraction
|
|
143
|
-
vi.mocked(mockClient.request).mockResolvedValue({
|
|
144
|
-
delegationId: "delegation-123",
|
|
145
|
-
} as any);
|
|
146
|
-
|
|
147
|
-
const result = await processReferral(mockClient, {
|
|
148
|
-
walletStatus: mockWalletStatus,
|
|
149
|
-
frakContext: mockFrakContext,
|
|
150
|
-
productId: mockProductId,
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
expect(result).toBe("success");
|
|
154
|
-
|
|
155
|
-
// sendInteraction uses client.request internally
|
|
156
|
-
expect(mockClient.request).toHaveBeenCalled();
|
|
157
|
-
expect(utils.trackEvent).toHaveBeenCalledWith(
|
|
158
|
-
mockClient,
|
|
159
|
-
"user_referred",
|
|
160
|
-
{
|
|
161
|
-
properties: {
|
|
162
|
-
referrer: mockReferrerAddress,
|
|
163
|
-
},
|
|
164
|
-
}
|
|
165
|
-
);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
it("should handle wallet not connected scenario", async () => {
|
|
169
|
-
// Mock client.request for displayEmbeddedWallet and sendInteraction
|
|
170
|
-
vi.mocked(mockClient.request)
|
|
171
|
-
.mockResolvedValueOnce({
|
|
172
|
-
wallet: mockAddress,
|
|
173
|
-
} as any)
|
|
174
|
-
.mockResolvedValueOnce({
|
|
175
|
-
delegationId: "delegation-123",
|
|
176
|
-
} as any);
|
|
177
|
-
|
|
178
|
-
const result = await processReferral(mockClient, {
|
|
179
|
-
walletStatus: undefined,
|
|
180
|
-
frakContext: mockFrakContext,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
expect(result).toBe("success");
|
|
184
|
-
expect(mockClient.request).toHaveBeenCalled();
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it("should handle missing interaction session", async () => {
|
|
188
|
-
const statusWithoutSession: WalletStatusReturnType = {
|
|
189
|
-
key: "connected" as const,
|
|
190
|
-
wallet: mockAddress,
|
|
191
|
-
interactionSession: undefined,
|
|
80
|
+
describe("V2 context", () => {
|
|
81
|
+
const v2Context: FrakContextV2 = {
|
|
82
|
+
v: 2,
|
|
83
|
+
c: "referrer-client-id",
|
|
84
|
+
m: "merchant-uuid",
|
|
85
|
+
t: 1709654400,
|
|
192
86
|
};
|
|
193
87
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
88
|
+
it("should successfully process v2 referral", async () => {
|
|
89
|
+
const utils = await import("../../utils");
|
|
90
|
+
const { sendInteraction } = await import("../sendInteraction");
|
|
91
|
+
|
|
92
|
+
const result = await processReferral(mockClient, {
|
|
93
|
+
walletStatus: mockWalletStatus,
|
|
94
|
+
frakContext: v2Context,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(result).toBe("success");
|
|
98
|
+
|
|
99
|
+
expect(utils.trackEvent).toHaveBeenCalledWith(
|
|
100
|
+
mockClient,
|
|
101
|
+
"user_referred_started",
|
|
102
|
+
{
|
|
103
|
+
properties: {
|
|
104
|
+
referrerClientId: "referrer-client-id",
|
|
105
|
+
walletStatus: "connected",
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
expect(sendInteraction).toHaveBeenCalledWith(mockClient, {
|
|
111
|
+
type: "arrival",
|
|
112
|
+
referrerClientId: "referrer-client-id",
|
|
113
|
+
referrerMerchantId: "merchant-uuid",
|
|
114
|
+
referralTimestamp: 1709654400,
|
|
115
|
+
landingUrl: "https://example.com/test",
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("should return 'self-referral' when v2 context has same clientId as current user", async () => {
|
|
120
|
+
const utils = await import("../../utils");
|
|
121
|
+
vi.mocked(utils.getClientId).mockReturnValue("referrer-client-id");
|
|
122
|
+
|
|
123
|
+
const v2SelfReferralContext: FrakContextV2 = {
|
|
124
|
+
v: 2,
|
|
125
|
+
c: "referrer-client-id",
|
|
126
|
+
m: "merchant-uuid",
|
|
127
|
+
t: 1709654400,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const result = await processReferral(mockClient, {
|
|
131
|
+
walletStatus: mockWalletStatus,
|
|
132
|
+
frakContext: v2SelfReferralContext,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(result).toBe("self-referral");
|
|
136
|
+
vi.mocked(utils.getClientId).mockReturnValue("test-client-id");
|
|
223
137
|
});
|
|
224
|
-
|
|
225
|
-
// The error gets caught and mapped
|
|
226
|
-
expect(["error", "no-wallet", "success"]).toContain(result);
|
|
227
138
|
});
|
|
228
139
|
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
);
|
|
234
|
-
// Mock client.request to throw error for sendInteraction
|
|
235
|
-
vi.mocked(mockClient.request).mockRejectedValue(error);
|
|
236
|
-
|
|
237
|
-
const result = await processReferral(mockClient, {
|
|
238
|
-
walletStatus: mockWalletStatus,
|
|
239
|
-
frakContext: mockFrakContext,
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// sendInteraction is in Promise.allSettled, so errors are caught
|
|
243
|
-
// The function might still succeed or return error depending on implementation
|
|
244
|
-
expect(["no-session", "error", "success"]).toContain(result);
|
|
245
|
-
});
|
|
140
|
+
describe("V1 context (backward compat)", () => {
|
|
141
|
+
const v1Context: FrakContext = {
|
|
142
|
+
r: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address,
|
|
143
|
+
};
|
|
246
144
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
145
|
+
it("should successfully process v1 referral", async () => {
|
|
146
|
+
const utils = await import("../../utils");
|
|
147
|
+
|
|
148
|
+
const result = await processReferral(mockClient, {
|
|
149
|
+
walletStatus: mockWalletStatus,
|
|
150
|
+
frakContext: v1Context,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
expect(result).toBe("success");
|
|
154
|
+
|
|
155
|
+
expect(utils.trackEvent).toHaveBeenCalledWith(
|
|
156
|
+
mockClient,
|
|
157
|
+
"user_referred_started",
|
|
158
|
+
{
|
|
159
|
+
properties: {
|
|
160
|
+
referrer: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
|
|
161
|
+
walletStatus: "connected",
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should return 'self-referral' when v1 referrer matches current wallet", async () => {
|
|
168
|
+
const result = await processReferral(mockClient, {
|
|
169
|
+
walletStatus: mockWalletStatus,
|
|
170
|
+
frakContext: {
|
|
171
|
+
r: mockAddress,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
251
174
|
|
|
252
|
-
|
|
253
|
-
walletStatus: mockWalletStatus,
|
|
254
|
-
frakContext: mockFrakContext,
|
|
175
|
+
expect(result).toBe("self-referral");
|
|
255
176
|
});
|
|
256
|
-
|
|
257
|
-
// sendInteraction is called inside pushReferralInteraction which is inside Promise.allSettled
|
|
258
|
-
// So the error might be caught and the function might still succeed
|
|
259
|
-
expect(["error", "success"]).toContain(result);
|
|
260
177
|
});
|
|
261
178
|
|
|
262
179
|
it("should update URL context when alwaysAppendUrl is true", async () => {
|
|
263
180
|
const utils = await import("../../utils");
|
|
264
181
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
182
|
+
const v2Context: FrakContextV2 = {
|
|
183
|
+
v: 2,
|
|
184
|
+
c: "referrer-client-id",
|
|
185
|
+
m: "merchant-uuid",
|
|
186
|
+
t: 1709654400,
|
|
187
|
+
};
|
|
269
188
|
|
|
270
189
|
await processReferral(mockClient, {
|
|
271
190
|
walletStatus: mockWalletStatus,
|
|
272
|
-
frakContext:
|
|
191
|
+
frakContext: v2Context,
|
|
273
192
|
options: {
|
|
274
193
|
alwaysAppendUrl: true,
|
|
275
194
|
},
|
|
276
195
|
});
|
|
277
196
|
|
|
197
|
+
expect(utils.getClientId()).toBe("test-client-id");
|
|
198
|
+
|
|
278
199
|
expect(utils.FrakContextManager.replaceUrl).toHaveBeenCalledWith({
|
|
279
200
|
url: window.location.href,
|
|
280
|
-
context: {
|
|
201
|
+
context: expect.objectContaining({
|
|
202
|
+
v: 2,
|
|
203
|
+
c: "test-client-id",
|
|
204
|
+
m: "merchant-uuid",
|
|
205
|
+
}),
|
|
281
206
|
});
|
|
282
207
|
});
|
|
283
208
|
|
|
284
209
|
it("should remove URL context when alwaysAppendUrl is false", async () => {
|
|
285
210
|
const utils = await import("../../utils");
|
|
286
211
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
212
|
+
const v2Context: FrakContextV2 = {
|
|
213
|
+
v: 2,
|
|
214
|
+
c: "referrer-client-id",
|
|
215
|
+
m: "merchant-uuid",
|
|
216
|
+
t: 1709654400,
|
|
217
|
+
};
|
|
291
218
|
|
|
292
219
|
await processReferral(mockClient, {
|
|
293
220
|
walletStatus: mockWalletStatus,
|
|
294
|
-
frakContext:
|
|
221
|
+
frakContext: v2Context,
|
|
295
222
|
options: {
|
|
296
223
|
alwaysAppendUrl: false,
|
|
297
224
|
},
|
|
@@ -302,56 +229,4 @@ describe("processReferral", () => {
|
|
|
302
229
|
context: null,
|
|
303
230
|
});
|
|
304
231
|
});
|
|
305
|
-
|
|
306
|
-
it("should remove URL context by default", async () => {
|
|
307
|
-
const utils = await import("../../utils");
|
|
308
|
-
|
|
309
|
-
// Mock client.request for sendInteraction
|
|
310
|
-
vi.mocked(mockClient.request).mockResolvedValue({
|
|
311
|
-
delegationId: "delegation-123",
|
|
312
|
-
} as any);
|
|
313
|
-
|
|
314
|
-
await processReferral(mockClient, {
|
|
315
|
-
walletStatus: mockWalletStatus,
|
|
316
|
-
frakContext: mockFrakContext,
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
expect(utils.FrakContextManager.replaceUrl).toHaveBeenCalledWith({
|
|
320
|
-
url: window.location.href,
|
|
321
|
-
context: null,
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it("should handle sendInteraction failures gracefully", async () => {
|
|
326
|
-
const utils = await import("../../utils");
|
|
327
|
-
|
|
328
|
-
// Mock client.request to throw error only for sendInteraction call
|
|
329
|
-
// Note: sendInteraction uses Promise.allSettled, so errors are caught
|
|
330
|
-
// We use mockImplementation to ensure the rejection is properly handled
|
|
331
|
-
// by returning a rejected promise that will be caught by Promise.allSettled
|
|
332
|
-
vi.mocked(mockClient.request).mockImplementation(async (request) => {
|
|
333
|
-
// Only reject for frak_sendInteraction calls (sendInteraction)
|
|
334
|
-
if (request.method === "frak_sendInteraction") {
|
|
335
|
-
// Return a rejected promise that will be caught by Promise.allSettled
|
|
336
|
-
return Promise.reject(new Error("Network error"));
|
|
337
|
-
}
|
|
338
|
-
// For any other calls (e.g., displayEmbeddedWallet), resolve successfully
|
|
339
|
-
return { delegationId: "delegation-123" } as any;
|
|
340
|
-
});
|
|
341
|
-
// trackEvent errors are also caught in Promise.allSettled
|
|
342
|
-
// Even though trackEvent is synchronous (returns void), we return a rejected promise
|
|
343
|
-
// so that Promise.allSettled can properly catch it without causing unhandled rejections
|
|
344
|
-
vi.mocked(utils.trackEvent).mockImplementation(() => {
|
|
345
|
-
return Promise.reject(new Error("Track failed")) as any;
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
const result = await processReferral(mockClient, {
|
|
349
|
-
walletStatus: mockWalletStatus,
|
|
350
|
-
frakContext: mockFrakContext,
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
// sendInteraction is in Promise.allSettled, so errors are caught
|
|
354
|
-
// The function might still succeed or return error depending on implementation
|
|
355
|
-
expect(["error", "success"]).toContain(result);
|
|
356
|
-
});
|
|
357
232
|
});
|