@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,219 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for sendInteraction action
|
|
3
|
-
* Tests sending user interactions via RPC
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Hex } from "viem";
|
|
7
|
-
import { vi } from "vitest";
|
|
8
|
-
|
|
9
|
-
// Mock computeProductId - must be before imports
|
|
10
|
-
vi.mock("../utils/computeProductId", () => ({
|
|
11
|
-
computeProductId: vi.fn(
|
|
12
|
-
() =>
|
|
13
|
-
"0xcomputed1234567890123456789012345678901234567890123456789012" as Hex
|
|
14
|
-
),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
import { describe, expect, it } from "../../tests/vitest-fixtures";
|
|
18
|
-
import type {
|
|
19
|
-
FrakClient,
|
|
20
|
-
PreparedInteraction,
|
|
21
|
-
SendInteractionParamsType,
|
|
22
|
-
SendInteractionReturnType,
|
|
23
|
-
} from "../types";
|
|
24
|
-
import { sendInteraction } from "./sendInteraction";
|
|
25
|
-
|
|
26
|
-
describe("sendInteraction", () => {
|
|
27
|
-
const mockInteraction: PreparedInteraction = {
|
|
28
|
-
interactionData: "0xdata" as Hex,
|
|
29
|
-
handlerTypeDenominator: "0x01" as Hex,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
describe("with productId provided", () => {
|
|
33
|
-
it("should use provided productId", async () => {
|
|
34
|
-
const mockResponse: SendInteractionReturnType = {
|
|
35
|
-
delegationId: "delegation-123",
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const mockClient = {
|
|
39
|
-
config: {
|
|
40
|
-
domain: "example.com",
|
|
41
|
-
},
|
|
42
|
-
request: vi.fn().mockResolvedValue(mockResponse),
|
|
43
|
-
} as unknown as FrakClient;
|
|
44
|
-
|
|
45
|
-
const params: SendInteractionParamsType = {
|
|
46
|
-
productId:
|
|
47
|
-
"0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
|
|
48
|
-
interaction: mockInteraction,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
await sendInteraction(mockClient, params);
|
|
52
|
-
|
|
53
|
-
expect(mockClient.request).toHaveBeenCalledWith({
|
|
54
|
-
method: "frak_sendInteraction",
|
|
55
|
-
params: [
|
|
56
|
-
"0xprovidedid567890123456789012345678901234567890123456789012",
|
|
57
|
-
mockInteraction,
|
|
58
|
-
undefined,
|
|
59
|
-
],
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("should return delegationId", async () => {
|
|
64
|
-
const mockResponse: SendInteractionReturnType = {
|
|
65
|
-
delegationId: "delegation-456",
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const mockClient = {
|
|
69
|
-
config: {
|
|
70
|
-
domain: "example.com",
|
|
71
|
-
},
|
|
72
|
-
request: vi.fn().mockResolvedValue(mockResponse),
|
|
73
|
-
} as unknown as FrakClient;
|
|
74
|
-
|
|
75
|
-
const params: SendInteractionParamsType = {
|
|
76
|
-
productId:
|
|
77
|
-
"0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
|
|
78
|
-
interaction: mockInteraction,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const result = await sendInteraction(mockClient, params);
|
|
82
|
-
|
|
83
|
-
expect(result).toEqual(mockResponse);
|
|
84
|
-
expect(result.delegationId).toBe("delegation-456");
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("should include validation signature when provided", async () => {
|
|
88
|
-
const mockResponse: SendInteractionReturnType = {
|
|
89
|
-
delegationId: "delegation-789",
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const mockClient = {
|
|
93
|
-
config: {
|
|
94
|
-
domain: "example.com",
|
|
95
|
-
},
|
|
96
|
-
request: vi.fn().mockResolvedValue(mockResponse),
|
|
97
|
-
} as unknown as FrakClient;
|
|
98
|
-
|
|
99
|
-
const params: SendInteractionParamsType = {
|
|
100
|
-
productId:
|
|
101
|
-
"0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
|
|
102
|
-
interaction: mockInteraction,
|
|
103
|
-
validation: "0xsignature1234567890" as Hex,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
await sendInteraction(mockClient, params);
|
|
107
|
-
|
|
108
|
-
expect(mockClient.request).toHaveBeenCalledWith({
|
|
109
|
-
method: "frak_sendInteraction",
|
|
110
|
-
params: [
|
|
111
|
-
"0xprovidedid567890123456789012345678901234567890123456789012",
|
|
112
|
-
mockInteraction,
|
|
113
|
-
"0xsignature1234567890",
|
|
114
|
-
],
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe("without productId provided", () => {
|
|
120
|
-
it("should compute productId from client.config", async () => {
|
|
121
|
-
const { computeProductId } = await import(
|
|
122
|
-
"../utils/computeProductId"
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const mockResponse: SendInteractionReturnType = {
|
|
126
|
-
delegationId: "delegation-computed",
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const mockClient = {
|
|
130
|
-
config: {
|
|
131
|
-
domain: "example.com",
|
|
132
|
-
},
|
|
133
|
-
request: vi.fn().mockResolvedValue(mockResponse),
|
|
134
|
-
} as unknown as FrakClient;
|
|
135
|
-
|
|
136
|
-
const params: SendInteractionParamsType = {
|
|
137
|
-
interaction: mockInteraction,
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
await sendInteraction(mockClient, params);
|
|
141
|
-
|
|
142
|
-
expect(computeProductId).toHaveBeenCalledWith(mockClient.config);
|
|
143
|
-
expect(mockClient.request).toHaveBeenCalledWith({
|
|
144
|
-
method: "frak_sendInteraction",
|
|
145
|
-
params: [
|
|
146
|
-
"0xcomputed1234567890123456789012345678901234567890123456789012",
|
|
147
|
-
mockInteraction,
|
|
148
|
-
undefined,
|
|
149
|
-
],
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it("should work with different interaction types", async () => {
|
|
154
|
-
const mockResponse: SendInteractionReturnType = {
|
|
155
|
-
delegationId: "delegation-different",
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const mockClient = {
|
|
159
|
-
config: {
|
|
160
|
-
domain: "example.com",
|
|
161
|
-
},
|
|
162
|
-
request: vi.fn().mockResolvedValue(mockResponse),
|
|
163
|
-
} as unknown as FrakClient;
|
|
164
|
-
|
|
165
|
-
const differentInteraction: PreparedInteraction = {
|
|
166
|
-
interactionData: "0xdifferentdata" as Hex,
|
|
167
|
-
handlerTypeDenominator: "0x02" as Hex,
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const params: SendInteractionParamsType = {
|
|
171
|
-
interaction: differentInteraction,
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const result = await sendInteraction(mockClient, params);
|
|
175
|
-
|
|
176
|
-
expect(result).toEqual(mockResponse);
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
describe("error handling", () => {
|
|
181
|
-
it("should propagate errors from client.request", async () => {
|
|
182
|
-
const error = new Error("Send interaction failed");
|
|
183
|
-
const mockClient = {
|
|
184
|
-
config: {
|
|
185
|
-
domain: "example.com",
|
|
186
|
-
},
|
|
187
|
-
request: vi.fn().mockRejectedValue(error),
|
|
188
|
-
} as unknown as FrakClient;
|
|
189
|
-
|
|
190
|
-
const params: SendInteractionParamsType = {
|
|
191
|
-
productId:
|
|
192
|
-
"0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
|
|
193
|
-
interaction: mockInteraction,
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
await expect(sendInteraction(mockClient, params)).rejects.toThrow(
|
|
197
|
-
"Send interaction failed"
|
|
198
|
-
);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("should handle network errors", async () => {
|
|
202
|
-
const error = new Error("Network timeout");
|
|
203
|
-
const mockClient = {
|
|
204
|
-
config: {
|
|
205
|
-
domain: "example.com",
|
|
206
|
-
},
|
|
207
|
-
request: vi.fn().mockRejectedValue(error),
|
|
208
|
-
} as unknown as FrakClient;
|
|
209
|
-
|
|
210
|
-
const params: SendInteractionParamsType = {
|
|
211
|
-
interaction: mockInteraction,
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
await expect(sendInteraction(mockClient, params)).rejects.toThrow(
|
|
215
|
-
"Network timeout"
|
|
216
|
-
);
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
});
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for interactionTypes constants
|
|
3
|
-
* Tests interaction type definitions and type utilities
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, expect, it } from "vitest";
|
|
7
|
-
import { interactionTypes } from "./interactionTypes";
|
|
8
|
-
|
|
9
|
-
describe("interactionTypes", () => {
|
|
10
|
-
describe("structure", () => {
|
|
11
|
-
it("should have all expected categories", () => {
|
|
12
|
-
expect(interactionTypes).toHaveProperty("press");
|
|
13
|
-
expect(interactionTypes).toHaveProperty("dapp");
|
|
14
|
-
expect(interactionTypes).toHaveProperty("webshop");
|
|
15
|
-
expect(interactionTypes).toHaveProperty("referral");
|
|
16
|
-
expect(interactionTypes).toHaveProperty("purchase");
|
|
17
|
-
expect(interactionTypes).toHaveProperty("retail");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("should have press interactions", () => {
|
|
21
|
-
expect(interactionTypes.press).toEqual({
|
|
22
|
-
openArticle: "0xc0a24ffb",
|
|
23
|
-
readArticle: "0xd5bd0fbe",
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("should have dapp interactions", () => {
|
|
28
|
-
expect(interactionTypes.dapp).toEqual({
|
|
29
|
-
proofVerifiableStorageUpdate: "0x2ab2aeef",
|
|
30
|
-
callableVerifiableStorageUpdate: "0xa07da986",
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should have webshop interactions", () => {
|
|
35
|
-
expect(interactionTypes.webshop).toEqual({
|
|
36
|
-
open: "0xb311798f",
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("should have referral interactions", () => {
|
|
41
|
-
expect(interactionTypes.referral).toEqual({
|
|
42
|
-
referred: "0x010cc3b9",
|
|
43
|
-
createLink: "0xb2c0f17c",
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("should have purchase interactions", () => {
|
|
48
|
-
expect(interactionTypes.purchase).toEqual({
|
|
49
|
-
started: "0xd87e90c3",
|
|
50
|
-
completed: "0x8403aeb4",
|
|
51
|
-
unsafeCompleted: "0x4d5b14e0",
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should have retail interactions", () => {
|
|
56
|
-
expect(interactionTypes.retail).toEqual({
|
|
57
|
-
customerMeeting: "0x74489004",
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe("interaction values", () => {
|
|
63
|
-
it("should have all interaction values as hex strings", () => {
|
|
64
|
-
Object.values(interactionTypes).forEach((category) => {
|
|
65
|
-
Object.values(category).forEach((value) => {
|
|
66
|
-
expect(value).toMatch(/^0x[a-f0-9]{8}$/);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("should have unique interaction values across all categories", () => {
|
|
72
|
-
const allValues = Object.values(interactionTypes).flatMap(
|
|
73
|
-
(category) => Object.values(category)
|
|
74
|
-
);
|
|
75
|
-
const uniqueValues = new Set(allValues);
|
|
76
|
-
expect(allValues.length).toBe(uniqueValues.size);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("specific interactions", () => {
|
|
81
|
-
it("should have correct press.openArticle value", () => {
|
|
82
|
-
expect(interactionTypes.press.openArticle).toBe("0xc0a24ffb");
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("should have correct press.readArticle value", () => {
|
|
86
|
-
expect(interactionTypes.press.readArticle).toBe("0xd5bd0fbe");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("should have correct webshop.open value", () => {
|
|
90
|
-
expect(interactionTypes.webshop.open).toBe("0xb311798f");
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("should have correct referral.referred value", () => {
|
|
94
|
-
expect(interactionTypes.referral.referred).toBe("0x010cc3b9");
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should have correct purchase.completed value", () => {
|
|
98
|
-
expect(interactionTypes.purchase.completed).toBe("0x8403aeb4");
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("should have correct purchase.unsafeCompleted value", () => {
|
|
102
|
-
expect(interactionTypes.purchase.unsafeCompleted).toBe(
|
|
103
|
-
"0x4d5b14e0"
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("should have correct retail.customerMeeting value", () => {
|
|
108
|
-
expect(interactionTypes.retail.customerMeeting).toBe("0x74489004");
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe("type safety", () => {
|
|
113
|
-
it("should be readonly (as const)", () => {
|
|
114
|
-
// TypeScript ensures this is readonly, but we can verify structure
|
|
115
|
-
expect(Object.isFrozen(interactionTypes)).toBe(false);
|
|
116
|
-
// The values should be consistent
|
|
117
|
-
expect(typeof interactionTypes.press.openArticle).toBe("string");
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it("should have consistent structure across categories", () => {
|
|
121
|
-
Object.values(interactionTypes).forEach((category) => {
|
|
122
|
-
expect(typeof category).toBe("object");
|
|
123
|
-
expect(category).not.toBeNull();
|
|
124
|
-
expect(Array.isArray(category)).toBe(false);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
});
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for productTypes constants
|
|
3
|
-
* Tests product type definitions and bitmask calculations
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, expect, it } from "vitest";
|
|
7
|
-
import { productTypes, productTypesMask } from "./productTypes";
|
|
8
|
-
|
|
9
|
-
describe("productTypes", () => {
|
|
10
|
-
describe("structure", () => {
|
|
11
|
-
it("should have all expected product types", () => {
|
|
12
|
-
expect(productTypes).toHaveProperty("dapp");
|
|
13
|
-
expect(productTypes).toHaveProperty("press");
|
|
14
|
-
expect(productTypes).toHaveProperty("webshop");
|
|
15
|
-
expect(productTypes).toHaveProperty("retail");
|
|
16
|
-
expect(productTypes).toHaveProperty("referral");
|
|
17
|
-
expect(productTypes).toHaveProperty("purchase");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("should have correct numeric values", () => {
|
|
21
|
-
expect(productTypes.dapp).toBe(1);
|
|
22
|
-
expect(productTypes.press).toBe(2);
|
|
23
|
-
expect(productTypes.webshop).toBe(3);
|
|
24
|
-
expect(productTypes.retail).toBe(4);
|
|
25
|
-
expect(productTypes.referral).toBe(30);
|
|
26
|
-
expect(productTypes.purchase).toBe(31);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe("productTypesMask", () => {
|
|
31
|
-
it("should have masks for all product types", () => {
|
|
32
|
-
expect(productTypesMask).toHaveProperty("dapp");
|
|
33
|
-
expect(productTypesMask).toHaveProperty("press");
|
|
34
|
-
expect(productTypesMask).toHaveProperty("webshop");
|
|
35
|
-
expect(productTypesMask).toHaveProperty("retail");
|
|
36
|
-
expect(productTypesMask).toHaveProperty("referral");
|
|
37
|
-
expect(productTypesMask).toHaveProperty("purchase");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("should calculate correct bitmask for dapp (value 1)", () => {
|
|
41
|
-
expect(productTypesMask.dapp).toBe(BigInt(1) << BigInt(1));
|
|
42
|
-
expect(productTypesMask.dapp).toBe(BigInt(2));
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("should calculate correct bitmask for press (value 2)", () => {
|
|
46
|
-
expect(productTypesMask.press).toBe(BigInt(1) << BigInt(2));
|
|
47
|
-
expect(productTypesMask.press).toBe(BigInt(4));
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("should calculate correct bitmask for webshop (value 3)", () => {
|
|
51
|
-
expect(productTypesMask.webshop).toBe(BigInt(1) << BigInt(3));
|
|
52
|
-
expect(productTypesMask.webshop).toBe(BigInt(8));
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should calculate correct bitmask for retail (value 4)", () => {
|
|
56
|
-
expect(productTypesMask.retail).toBe(BigInt(1) << BigInt(4));
|
|
57
|
-
expect(productTypesMask.retail).toBe(BigInt(16));
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("should calculate correct bitmask for referral (value 30)", () => {
|
|
61
|
-
expect(productTypesMask.referral).toBe(BigInt(1) << BigInt(30));
|
|
62
|
-
expect(productTypesMask.referral).toBe(BigInt(1073741824));
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("should calculate correct bitmask for purchase (value 31)", () => {
|
|
66
|
-
expect(productTypesMask.purchase).toBe(BigInt(1) << BigInt(31));
|
|
67
|
-
expect(productTypesMask.purchase).toBe(BigInt(2147483648));
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("should have all masks as BigInt values", () => {
|
|
71
|
-
Object.values(productTypesMask).forEach((mask) => {
|
|
72
|
-
expect(typeof mask).toBe("bigint");
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("should have unique mask values", () => {
|
|
77
|
-
const maskValues = Object.values(productTypesMask);
|
|
78
|
-
const uniqueValues = new Set(maskValues);
|
|
79
|
-
expect(maskValues.length).toBe(uniqueValues.size);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
describe("bitmask calculation", () => {
|
|
84
|
-
it("should correctly calculate bitmask from product type value", () => {
|
|
85
|
-
// Verify the formula: 1 << value
|
|
86
|
-
expect(productTypesMask.dapp).toBe(
|
|
87
|
-
BigInt(1) << BigInt(productTypes.dapp)
|
|
88
|
-
);
|
|
89
|
-
expect(productTypesMask.press).toBe(
|
|
90
|
-
BigInt(1) << BigInt(productTypes.press)
|
|
91
|
-
);
|
|
92
|
-
expect(productTypesMask.webshop).toBe(
|
|
93
|
-
BigInt(1) << BigInt(productTypes.webshop)
|
|
94
|
-
);
|
|
95
|
-
expect(productTypesMask.retail).toBe(
|
|
96
|
-
BigInt(1) << BigInt(productTypes.retail)
|
|
97
|
-
);
|
|
98
|
-
expect(productTypesMask.referral).toBe(
|
|
99
|
-
BigInt(1) << BigInt(productTypes.referral)
|
|
100
|
-
);
|
|
101
|
-
expect(productTypesMask.purchase).toBe(
|
|
102
|
-
BigInt(1) << BigInt(productTypes.purchase)
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it("should have masks that are powers of 2", () => {
|
|
107
|
-
Object.values(productTypesMask).forEach((mask) => {
|
|
108
|
-
// A power of 2 has exactly one bit set
|
|
109
|
-
// Check: mask & (mask - 1n) should be 0n
|
|
110
|
-
const isPowerOfTwo = mask > 0n && (mask & (mask - 1n)) === 0n;
|
|
111
|
-
expect(isPowerOfTwo).toBe(true);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe("type safety", () => {
|
|
117
|
-
it("should have consistent structure", () => {
|
|
118
|
-
const productKeys = Object.keys(productTypes);
|
|
119
|
-
const maskKeys = Object.keys(productTypesMask);
|
|
120
|
-
expect(productKeys.sort()).toEqual(maskKeys.sort());
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it("should have numeric values for product types", () => {
|
|
124
|
-
Object.values(productTypes).forEach((value) => {
|
|
125
|
-
expect(typeof value).toBe("number");
|
|
126
|
-
expect(Number.isInteger(value)).toBe(true);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The keys for each product types
|
|
3
|
-
* @inline
|
|
4
|
-
*/
|
|
5
|
-
export type ProductTypesKey = keyof typeof productTypes;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* List of the product types per denominator
|
|
9
|
-
*/
|
|
10
|
-
export const productTypes = {
|
|
11
|
-
// content type
|
|
12
|
-
dapp: 1,
|
|
13
|
-
press: 2,
|
|
14
|
-
webshop: 3,
|
|
15
|
-
retail: 4,
|
|
16
|
-
|
|
17
|
-
// feature type
|
|
18
|
-
referral: 30,
|
|
19
|
-
purchase: 31,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Bitmask for each product types
|
|
24
|
-
*/
|
|
25
|
-
export const productTypesMask: Record<ProductTypesKey, bigint> = Object.entries(
|
|
26
|
-
productTypes
|
|
27
|
-
).reduce(
|
|
28
|
-
(acc, [key, value]) => {
|
|
29
|
-
acc[key as ProductTypesKey] = BigInt(1) << BigInt(value);
|
|
30
|
-
return acc;
|
|
31
|
-
},
|
|
32
|
-
{} as Record<ProductTypesKey, bigint>
|
|
33
|
-
);
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { PressInteractionEncoder } from "./pressEncoder";
|
|
2
|
-
export { PurchaseInteractionEncoder } from "./purchaseEncoder";
|
|
3
|
-
export { ReferralInteractionEncoder } from "./referralEncoder";
|
|
4
|
-
export { RetailInteractionEncoder } from "./retailEncoder";
|
|
5
|
-
export { WebShopInteractionEncoder } from "./webshopEncoder";
|