@frak-labs/core-sdk 0.1.0-beta.8d103039 → 0.1.0-beta.b0bd1f8a

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 (90) hide show
  1. package/cdn/bundle.iife.js +14 -0
  2. package/dist/actions-CEEObPYc.js +1 -0
  3. package/dist/actions-DbQhWYx8.cjs +1 -0
  4. package/dist/actions.cjs +1 -1
  5. package/dist/actions.d.cts +3 -1481
  6. package/dist/actions.d.ts +3 -1481
  7. package/dist/actions.js +1 -1
  8. package/dist/bundle.cjs +1 -13
  9. package/dist/bundle.d.cts +6 -2087
  10. package/dist/bundle.d.ts +6 -2087
  11. package/dist/bundle.js +1 -13
  12. package/dist/index-7OZ39x1U.d.ts +195 -0
  13. package/dist/index-C6FxkWPC.d.cts +511 -0
  14. package/dist/index-UFX7xCg3.d.ts +351 -0
  15. package/dist/index-d8xS4ryI.d.ts +511 -0
  16. package/dist/index-p4FqSp8z.d.cts +351 -0
  17. package/dist/index-zDq-VlKx.d.cts +195 -0
  18. package/dist/index.cjs +1 -13
  19. package/dist/index.d.cts +4 -1387
  20. package/dist/index.d.ts +4 -1387
  21. package/dist/index.js +1 -13
  22. package/dist/interaction-DMJ3ZfaF.d.cts +45 -0
  23. package/dist/interaction-KX1h9a7V.d.ts +45 -0
  24. package/dist/interactions-DnfM3oe0.js +1 -0
  25. package/dist/interactions-EIXhNLf6.cjs +1 -0
  26. package/dist/interactions.cjs +1 -1
  27. package/dist/interactions.d.cts +2 -182
  28. package/dist/interactions.d.ts +2 -182
  29. package/dist/interactions.js +1 -1
  30. package/dist/openSso-D--Airj6.d.cts +1018 -0
  31. package/dist/openSso-DsKJ4y0j.d.ts +1018 -0
  32. package/dist/productTypes-BUkXJKZ7.cjs +1 -0
  33. package/dist/productTypes-CGb1MmBF.js +1 -0
  34. package/dist/src-B_xO0AR6.cjs +13 -0
  35. package/dist/src-D2d52OZa.js +13 -0
  36. package/dist/trackEvent-CHnYa85W.js +1 -0
  37. package/dist/trackEvent-GuQm_1Nm.cjs +1 -0
  38. package/package.json +21 -17
  39. package/src/actions/displayEmbeddedWallet.test.ts +194 -0
  40. package/src/actions/displayModal.test.ts +387 -0
  41. package/src/actions/getProductInformation.test.ts +133 -0
  42. package/src/actions/index.ts +19 -19
  43. package/src/actions/openSso.test.ts +407 -0
  44. package/src/actions/prepareSso.test.ts +223 -0
  45. package/src/actions/referral/processReferral.ts +1 -1
  46. package/src/actions/referral/referralInteraction.ts +1 -1
  47. package/src/actions/sendInteraction.test.ts +219 -0
  48. package/src/actions/trackPurchaseStatus.test.ts +287 -0
  49. package/src/actions/watchWalletStatus.test.ts +372 -0
  50. package/src/bundle.ts +1 -1
  51. package/src/clients/createIFrameFrakClient.ts +2 -2
  52. package/src/clients/index.ts +1 -1
  53. package/src/clients/setupClient.test.ts +343 -0
  54. package/src/clients/setupClient.ts +3 -1
  55. package/src/clients/transports/iframeLifecycleManager.test.ts +399 -0
  56. package/src/clients/transports/iframeLifecycleManager.ts +3 -1
  57. package/src/index.ts +72 -74
  58. package/src/interactions/index.ts +2 -2
  59. package/src/interactions/pressEncoder.test.ts +215 -0
  60. package/src/interactions/pressEncoder.ts +1 -1
  61. package/src/interactions/purchaseEncoder.test.ts +291 -0
  62. package/src/interactions/purchaseEncoder.ts +8 -3
  63. package/src/interactions/referralEncoder.test.ts +170 -0
  64. package/src/interactions/retailEncoder.test.ts +107 -0
  65. package/src/interactions/retailEncoder.ts +1 -1
  66. package/src/interactions/webshopEncoder.test.ts +56 -0
  67. package/src/types/index.ts +51 -50
  68. package/src/types/lifecycle/index.ts +1 -1
  69. package/src/types/rpc/embedded/loggedIn.ts +1 -1
  70. package/src/types/rpc/embedded/loggedOut.ts +1 -1
  71. package/src/types/rpc/modal/index.ts +11 -11
  72. package/src/utils/FrakContext.test.ts +407 -0
  73. package/src/utils/FrakContext.ts +8 -2
  74. package/src/utils/compression/b64.test.ts +181 -0
  75. package/src/utils/compression/compress.test.ts +123 -0
  76. package/src/utils/compression/decompress.test.ts +145 -0
  77. package/src/utils/compression/index.ts +1 -1
  78. package/src/utils/computeProductId.test.ts +80 -0
  79. package/src/utils/constants.test.ts +23 -0
  80. package/src/utils/formatAmount.test.ts +113 -0
  81. package/src/utils/getCurrencyAmountKey.test.ts +44 -0
  82. package/src/utils/getSupportedCurrency.test.ts +51 -0
  83. package/src/utils/getSupportedLocale.test.ts +64 -0
  84. package/src/utils/iframeHelper.test.ts +450 -0
  85. package/src/utils/iframeHelper.ts +4 -3
  86. package/src/utils/index.ts +12 -12
  87. package/src/utils/sso.test.ts +361 -0
  88. package/src/utils/trackEvent.test.ts +162 -0
  89. package/cdn/bundle.js +0 -19
  90. package/cdn/bundle.js.LICENSE.txt +0 -10
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Tests for compressJsonToB64 utility function
3
+ * Tests JSON compression to base64url-encoded string
4
+ */
5
+
6
+ import { vi } from "vitest";
7
+
8
+ // Mock the frame-connector module - must be before imports
9
+ vi.mock("@frak-labs/frame-connector", () => ({
10
+ compressJson: vi.fn((data: unknown) => {
11
+ // Simple mock: convert JSON to Uint8Array
12
+ const jsonString = JSON.stringify(data);
13
+ return new TextEncoder().encode(jsonString);
14
+ }),
15
+ }));
16
+
17
+ import { describe, expect, it } from "../../../tests/vitest-fixtures";
18
+ import { compressJsonToB64 } from "./compress";
19
+
20
+ describe("compressJsonToB64", () => {
21
+ describe("success cases", () => {
22
+ it("should compress and encode simple object", () => {
23
+ const data = { key: "value" };
24
+ const result = compressJsonToB64(data);
25
+
26
+ // Result should be a base64url-encoded string
27
+ expect(result).toBeDefined();
28
+ expect(typeof result).toBe("string");
29
+ expect(result.length).toBeGreaterThan(0);
30
+ // Base64url should not contain +, /, or = characters
31
+ expect(result).not.toMatch(/[+/=]/);
32
+ });
33
+
34
+ it("should compress and encode array data", () => {
35
+ const data = [1, 2, 3, 4, 5];
36
+ const result = compressJsonToB64(data);
37
+
38
+ expect(result).toBeDefined();
39
+ expect(typeof result).toBe("string");
40
+ expect(result.length).toBeGreaterThan(0);
41
+ expect(result).not.toMatch(/[+/=]/);
42
+ });
43
+
44
+ it("should compress and encode nested object", () => {
45
+ const data = {
46
+ user: {
47
+ name: "John",
48
+ address: {
49
+ city: "Paris",
50
+ country: "France",
51
+ },
52
+ },
53
+ };
54
+ const result = compressJsonToB64(data);
55
+
56
+ expect(result).toBeDefined();
57
+ expect(typeof result).toBe("string");
58
+ expect(result.length).toBeGreaterThan(0);
59
+ });
60
+
61
+ it("should compress and encode string data", () => {
62
+ const data = "Hello, World!";
63
+ const result = compressJsonToB64(data);
64
+
65
+ expect(result).toBeDefined();
66
+ expect(typeof result).toBe("string");
67
+ expect(result.length).toBeGreaterThan(0);
68
+ });
69
+
70
+ it("should compress and encode number data", () => {
71
+ const data = 12345;
72
+ const result = compressJsonToB64(data);
73
+
74
+ expect(result).toBeDefined();
75
+ expect(typeof result).toBe("string");
76
+ expect(result.length).toBeGreaterThan(0);
77
+ });
78
+
79
+ it("should compress and encode boolean data", () => {
80
+ const data = true;
81
+ const result = compressJsonToB64(data);
82
+
83
+ expect(result).toBeDefined();
84
+ expect(typeof result).toBe("string");
85
+ expect(result.length).toBeGreaterThan(0);
86
+ });
87
+
88
+ it("should compress and encode null", () => {
89
+ const data = null;
90
+ const result = compressJsonToB64(data);
91
+
92
+ expect(result).toBeDefined();
93
+ expect(typeof result).toBe("string");
94
+ expect(result.length).toBeGreaterThan(0);
95
+ });
96
+ });
97
+
98
+ describe("edge cases", () => {
99
+ it("should handle empty object", () => {
100
+ const data = {};
101
+ const result = compressJsonToB64(data);
102
+
103
+ expect(result).toBeDefined();
104
+ expect(typeof result).toBe("string");
105
+ });
106
+
107
+ it("should handle empty array", () => {
108
+ const data: unknown[] = [];
109
+ const result = compressJsonToB64(data);
110
+
111
+ expect(result).toBeDefined();
112
+ expect(typeof result).toBe("string");
113
+ });
114
+
115
+ it("should handle empty string", () => {
116
+ const data = "";
117
+ const result = compressJsonToB64(data);
118
+
119
+ expect(result).toBeDefined();
120
+ expect(typeof result).toBe("string");
121
+ });
122
+ });
123
+ });
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Tests for decompressJsonFromB64 utility function
3
+ * Tests decompression of base64url-encoded JSON strings
4
+ */
5
+
6
+ import { vi } from "vitest";
7
+
8
+ // Mock the frame-connector module - must be before imports
9
+ vi.mock("@frak-labs/frame-connector", () => ({
10
+ compressJson: vi.fn((data: unknown) => {
11
+ // Simple mock: convert JSON to Uint8Array
12
+ const jsonString = JSON.stringify(data);
13
+ return new TextEncoder().encode(jsonString);
14
+ }),
15
+ decompressJson: vi.fn((data: Uint8Array) => {
16
+ // Simple mock: convert Uint8Array back to JSON
17
+ const jsonString = new TextDecoder().decode(data);
18
+ return JSON.parse(jsonString);
19
+ }),
20
+ }));
21
+
22
+ import { describe, expect, it } from "../../../tests/vitest-fixtures";
23
+ import { compressJsonToB64 } from "./compress";
24
+ import { decompressJsonFromB64 } from "./decompress";
25
+
26
+ describe("decompressJsonFromB64", () => {
27
+ describe("success cases", () => {
28
+ it("should decompress simple object", () => {
29
+ const original = { key: "value" };
30
+ const compressed = compressJsonToB64(original);
31
+ const decompressed =
32
+ decompressJsonFromB64<typeof original>(compressed);
33
+
34
+ expect(decompressed).toEqual(original);
35
+ });
36
+
37
+ it("should decompress array data", () => {
38
+ const original = [1, 2, 3, 4, 5];
39
+ const compressed = compressJsonToB64(original);
40
+ const decompressed =
41
+ decompressJsonFromB64<typeof original>(compressed);
42
+
43
+ expect(decompressed).toEqual(original);
44
+ });
45
+
46
+ it("should decompress nested object", () => {
47
+ const original = {
48
+ user: {
49
+ name: "John",
50
+ address: {
51
+ city: "Paris",
52
+ country: "France",
53
+ },
54
+ },
55
+ };
56
+ const compressed = compressJsonToB64(original);
57
+ const decompressed =
58
+ decompressJsonFromB64<typeof original>(compressed);
59
+
60
+ expect(decompressed).toEqual(original);
61
+ });
62
+
63
+ it("should decompress string data", () => {
64
+ const original = "Hello, World!";
65
+ const compressed = compressJsonToB64(original);
66
+ const decompressed = decompressJsonFromB64<string>(compressed);
67
+
68
+ expect(decompressed).toBe(original);
69
+ });
70
+
71
+ it("should decompress number data", () => {
72
+ const original = 12345;
73
+ const compressed = compressJsonToB64(original);
74
+ const decompressed = decompressJsonFromB64<number>(compressed);
75
+
76
+ expect(decompressed).toBe(original);
77
+ });
78
+
79
+ it("should decompress boolean data", () => {
80
+ const original = true;
81
+ const compressed = compressJsonToB64(original);
82
+ const decompressed = decompressJsonFromB64<boolean>(compressed);
83
+
84
+ expect(decompressed).toBe(original);
85
+ });
86
+
87
+ it("should decompress null", () => {
88
+ const original = null;
89
+ const compressed = compressJsonToB64(original);
90
+ const decompressed = decompressJsonFromB64<null>(compressed);
91
+
92
+ expect(decompressed).toBeNull();
93
+ });
94
+ });
95
+
96
+ describe("round-trip compression", () => {
97
+ it("should preserve data through compress-decompress cycle", () => {
98
+ const original = {
99
+ id: 123,
100
+ name: "Test User",
101
+ tags: ["tag1", "tag2", "tag3"],
102
+ metadata: {
103
+ created: "2024-01-01",
104
+ updated: "2024-01-02",
105
+ },
106
+ };
107
+
108
+ const compressed = compressJsonToB64(original);
109
+ const decompressed =
110
+ decompressJsonFromB64<typeof original>(compressed);
111
+
112
+ expect(decompressed).toEqual(original);
113
+ });
114
+
115
+ it("should handle empty object round-trip", () => {
116
+ const original = {};
117
+ const compressed = compressJsonToB64(original);
118
+ const decompressed =
119
+ decompressJsonFromB64<typeof original>(compressed);
120
+
121
+ expect(decompressed).toEqual(original);
122
+ });
123
+
124
+ it("should handle empty array round-trip", () => {
125
+ const original: unknown[] = [];
126
+ const compressed = compressJsonToB64(original);
127
+ const decompressed =
128
+ decompressJsonFromB64<typeof original>(compressed);
129
+
130
+ expect(decompressed).toEqual(original);
131
+ });
132
+ });
133
+
134
+ describe("edge cases", () => {
135
+ it("should handle empty object round-trip gracefully", () => {
136
+ // Empty objects should compress and decompress correctly
137
+ const original = {};
138
+ const compressed = compressJsonToB64(original);
139
+ const decompressed =
140
+ decompressJsonFromB64<typeof original>(compressed);
141
+
142
+ expect(decompressed).toEqual(original);
143
+ });
144
+ });
145
+ });
@@ -1,3 +1,3 @@
1
+ export { base64urlDecode, base64urlEncode } from "./b64";
1
2
  export { compressJsonToB64 } from "./compress";
2
3
  export { decompressJsonFromB64 } from "./decompress";
3
- export { base64urlDecode, base64urlEncode } from "./b64";
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Tests for computeProductId utility function
3
+ * Tests product ID computation from domain names with normalization
4
+ */
5
+
6
+ import { keccak256, toHex } from "viem";
7
+ import { describe, expect, it } from "../../tests/vitest-fixtures";
8
+ import { computeProductId } from "./computeProductId";
9
+
10
+ describe("computeProductId", () => {
11
+ it("should compute product ID from current domain (window.location.host)", () => {
12
+ // In JSDOM test environment, window.location.host is "localhost:3000"
13
+ const productId = computeProductId();
14
+
15
+ // Should compute keccak256 hash of window.location.host
16
+ const expectedId = keccak256(toHex(window.location.host));
17
+ expect(productId).toBe(expectedId);
18
+ });
19
+
20
+ it("should compute product ID from custom domain", () => {
21
+ const customDomain = "custom-domain.com";
22
+ const productId = computeProductId({ domain: customDomain });
23
+
24
+ // Should compute keccak256 hash of custom domain
25
+ const expectedId = keccak256(toHex(customDomain));
26
+ expect(productId).toBe(expectedId);
27
+ });
28
+
29
+ it("should remove www. prefix from domain before hashing", () => {
30
+ const domainWithWww = "www.example.com";
31
+ const productId = computeProductId({ domain: domainWithWww });
32
+
33
+ // Should compute keccak256 hash of "example.com" (www. removed)
34
+ const expectedId = keccak256(toHex("example.com"));
35
+ expect(productId).toBe(expectedId);
36
+ });
37
+
38
+ it("should produce same product ID for domain with and without www", () => {
39
+ const withWww = computeProductId({ domain: "www.example.com" });
40
+ const withoutWww = computeProductId({ domain: "example.com" });
41
+
42
+ // Both should produce the same hash
43
+ expect(withWww).toBe(withoutWww);
44
+ });
45
+
46
+ it("should produce different product IDs for different domains", () => {
47
+ const domain1ProductId = computeProductId({ domain: "domain1.com" });
48
+ const domain2ProductId = computeProductId({ domain: "domain2.com" });
49
+
50
+ // Different domains should produce different hashes
51
+ expect(domain1ProductId).not.toBe(domain2ProductId);
52
+ });
53
+
54
+ it("should use window.location.host when domain is not provided", () => {
55
+ // When no domain is provided, it should default to window.location.host
56
+ const productId = computeProductId();
57
+
58
+ // Should produce same result as using window.location.host explicitly
59
+ const expectedId = keccak256(toHex(window.location.host));
60
+ expect(productId).toBe(expectedId);
61
+ });
62
+
63
+ it("should handle subdomains correctly", () => {
64
+ const subdomain = "blog.example.com";
65
+ const productId = computeProductId({ domain: subdomain });
66
+
67
+ // Should compute keccak256 hash of "blog.example.com" (subdomain preserved)
68
+ const expectedId = keccak256(toHex(subdomain));
69
+ expect(productId).toBe(expectedId);
70
+ });
71
+
72
+ it("should only remove www prefix, not other w-prefixed subdomains", () => {
73
+ const domain = "web.example.com";
74
+ const productId = computeProductId({ domain });
75
+
76
+ // Should NOT remove "web." prefix, only "www."
77
+ const expectedId = keccak256(toHex("web.example.com"));
78
+ expect(productId).toBe(expectedId);
79
+ });
80
+ });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Tests for constants
3
+ * Tests backup key constant value
4
+ */
5
+
6
+ import { describe, expect, it } from "../../tests/vitest-fixtures";
7
+ import { BACKUP_KEY } from "./constants";
8
+
9
+ describe("constants", () => {
10
+ describe("BACKUP_KEY", () => {
11
+ it("should have correct backup key value", () => {
12
+ expect(BACKUP_KEY).toBe("nexus-wallet-backup");
13
+ });
14
+
15
+ it("should be a string", () => {
16
+ expect(typeof BACKUP_KEY).toBe("string");
17
+ });
18
+
19
+ it("should not be empty", () => {
20
+ expect(BACKUP_KEY.length).toBeGreaterThan(0);
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Tests for formatAmount utility function
3
+ * Tests currency formatting with proper locale support
4
+ */
5
+
6
+ import { describe, expect, it } from "../../tests/vitest-fixtures";
7
+ import { formatAmount } from "./formatAmount";
8
+
9
+ describe("formatAmount", () => {
10
+ it("should format EUR with French locale by default", () => {
11
+ const formatted = formatAmount(1000, "eur");
12
+
13
+ // French locale formats EUR with space between number and symbol
14
+ // Expected format: "1 000 €" or "1 000,00 €" depending on locale
15
+ expect(formatted).toContain("€");
16
+ expect(formatted).toContain("1");
17
+ });
18
+
19
+ it("should format USD with US locale", () => {
20
+ const formatted = formatAmount(1000, "usd");
21
+
22
+ // US locale formats USD with $ prefix
23
+ expect(formatted).toContain("$");
24
+ expect(formatted).toContain("1");
25
+ });
26
+
27
+ it("should format GBP with British locale", () => {
28
+ const formatted = formatAmount(1000, "gbp");
29
+
30
+ // British locale formats GBP with £ symbol
31
+ expect(formatted).toContain("£");
32
+ expect(formatted).toContain("1");
33
+ });
34
+
35
+ it("should format integer amounts without decimal places", () => {
36
+ const formatted = formatAmount(1000, "eur");
37
+
38
+ // Integer amounts should not show .00
39
+ // French locale: "1 000 €" or "1 000,00 €"
40
+ expect(formatted).toBeDefined();
41
+ expect(formatted.length).toBeGreaterThan(0);
42
+ });
43
+
44
+ it("should format decimal amounts with up to 2 decimal places", () => {
45
+ const formatted = formatAmount(1234.56, "eur");
46
+
47
+ // Should include decimal separator and digits
48
+ expect(formatted).toBeDefined();
49
+ expect(formatted).toContain("1");
50
+ });
51
+
52
+ it("should handle zero amount", () => {
53
+ const formatted = formatAmount(0, "eur");
54
+
55
+ // Should format zero properly
56
+ expect(formatted).toContain("0");
57
+ expect(formatted).toContain("€");
58
+ });
59
+
60
+ it("should handle large amounts", () => {
61
+ const formatted = formatAmount(1000000, "eur");
62
+
63
+ // Should format large numbers with proper thousand separators
64
+ expect(formatted).toContain("€");
65
+ expect(formatted).toBeDefined();
66
+ });
67
+
68
+ it("should default to EUR when currency is not provided", () => {
69
+ const formatted = formatAmount(1000);
70
+
71
+ // Should default to EUR
72
+ expect(formatted).toContain("€");
73
+ });
74
+
75
+ it("should format negative amounts", () => {
76
+ const formatted = formatAmount(-500, "eur");
77
+
78
+ // Should handle negative amounts
79
+ expect(formatted).toContain("-");
80
+ expect(formatted).toContain("€");
81
+ });
82
+
83
+ it("should round amounts with more than 2 decimal places", () => {
84
+ const formatted = formatAmount(1234.5678, "eur");
85
+
86
+ // Should round to max 2 decimal places
87
+ expect(formatted).toBeDefined();
88
+ // The exact format depends on locale, but should be rounded
89
+ });
90
+
91
+ it("should format small decimal amounts", () => {
92
+ const formatted = formatAmount(0.99, "usd");
93
+
94
+ // Should handle small amounts properly
95
+ expect(formatted).toContain("$");
96
+ expect(formatted).toContain("0");
97
+ });
98
+
99
+ it("should use correct locale for each currency", () => {
100
+ const eurFormatted = formatAmount(1000, "eur");
101
+ const usdFormatted = formatAmount(1000, "usd");
102
+ const gbpFormatted = formatAmount(1000, "gbp");
103
+
104
+ // Each should use different currency symbols
105
+ expect(eurFormatted).toContain("€");
106
+ expect(usdFormatted).toContain("$");
107
+ expect(gbpFormatted).toContain("£");
108
+
109
+ // All should be different formats due to different locales
110
+ expect(eurFormatted).not.toBe(usdFormatted);
111
+ expect(usdFormatted).not.toBe(gbpFormatted);
112
+ });
113
+ });
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Tests for getCurrencyAmountKey utility function
3
+ * Tests currency amount key generation
4
+ */
5
+
6
+ import { describe, expect, it } from "../../tests/vitest-fixtures";
7
+ import type { Currency } from "../types";
8
+ import { getCurrencyAmountKey } from "./getCurrencyAmountKey";
9
+
10
+ describe("getCurrencyAmountKey", () => {
11
+ it("should return eurAmount for undefined input", () => {
12
+ const result = getCurrencyAmountKey(undefined);
13
+
14
+ expect(result).toBe("eurAmount");
15
+ });
16
+
17
+ it("should return eurAmount for EUR", () => {
18
+ const result = getCurrencyAmountKey("eur");
19
+
20
+ expect(result).toBe("eurAmount");
21
+ });
22
+
23
+ it("should return usdAmount for USD", () => {
24
+ const result = getCurrencyAmountKey("usd");
25
+
26
+ expect(result).toBe("usdAmount");
27
+ });
28
+
29
+ it("should return gbpAmount for GBP", () => {
30
+ const result = getCurrencyAmountKey("gbp");
31
+
32
+ expect(result).toBe("gbpAmount");
33
+ });
34
+
35
+ it("should generate correct key format for all currencies", () => {
36
+ const validCurrencies: Currency[] = ["eur", "usd", "gbp"];
37
+
38
+ for (const currency of validCurrencies) {
39
+ const result = getCurrencyAmountKey(currency);
40
+ // Should match pattern: {currency}Amount
41
+ expect(result).toBe(`${currency}Amount`);
42
+ }
43
+ });
44
+ });
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tests for getSupportedCurrency utility function
3
+ * Tests currency validation and fallback behavior
4
+ */
5
+
6
+ import { describe, expect, it } from "../../tests/vitest-fixtures";
7
+ import type { Currency } from "../types";
8
+ import { getSupportedCurrency } from "./getSupportedCurrency";
9
+
10
+ describe("getSupportedCurrency", () => {
11
+ it("should return EUR for undefined input", () => {
12
+ const result = getSupportedCurrency(undefined);
13
+
14
+ expect(result).toBe("eur");
15
+ });
16
+
17
+ it("should return EUR when provided", () => {
18
+ const result = getSupportedCurrency("eur");
19
+
20
+ expect(result).toBe("eur");
21
+ });
22
+
23
+ it("should return USD when provided", () => {
24
+ const result = getSupportedCurrency("usd");
25
+
26
+ expect(result).toBe("usd");
27
+ });
28
+
29
+ it("should return GBP when provided", () => {
30
+ const result = getSupportedCurrency("gbp");
31
+
32
+ expect(result).toBe("gbp");
33
+ });
34
+
35
+ it("should fall back to EUR for invalid currency", () => {
36
+ // Force cast to test runtime behavior
37
+ const invalidCurrency = "invalid" as Currency;
38
+ const result = getSupportedCurrency(invalidCurrency);
39
+
40
+ expect(result).toBe("eur");
41
+ });
42
+
43
+ it("should handle all valid currencies", () => {
44
+ const validCurrencies: Currency[] = ["eur", "usd", "gbp"];
45
+
46
+ for (const currency of validCurrencies) {
47
+ const result = getSupportedCurrency(currency);
48
+ expect(result).toBe(currency);
49
+ }
50
+ });
51
+ });
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Tests for getSupportedLocale utility function
3
+ * Tests locale resolution from currency
4
+ */
5
+
6
+ import { describe, expect, it } from "../../tests/vitest-fixtures";
7
+ import { locales } from "../constants/locales";
8
+ import type { Currency } from "../types";
9
+ import { getSupportedLocale } from "./getSupportedLocale";
10
+
11
+ describe("getSupportedLocale", () => {
12
+ it("should return EUR locale for undefined input", () => {
13
+ const result = getSupportedLocale(undefined);
14
+
15
+ expect(result).toBe(locales.eur);
16
+ expect(result).toBe("fr-FR");
17
+ });
18
+
19
+ it("should return French locale for EUR", () => {
20
+ const result = getSupportedLocale("eur");
21
+
22
+ expect(result).toBe(locales.eur);
23
+ expect(result).toBe("fr-FR");
24
+ });
25
+
26
+ it("should return US locale for USD", () => {
27
+ const result = getSupportedLocale("usd");
28
+
29
+ expect(result).toBe(locales.usd);
30
+ expect(result).toBe("en-US");
31
+ });
32
+
33
+ it("should return GB locale for GBP", () => {
34
+ const result = getSupportedLocale("gbp");
35
+
36
+ expect(result).toBe(locales.gbp);
37
+ expect(result).toBe("en-GB");
38
+ });
39
+
40
+ it("should fall back to EUR locale for invalid currency", () => {
41
+ // Force cast to test runtime behavior
42
+ const invalidCurrency = "invalid" as Currency;
43
+ const result = getSupportedLocale(invalidCurrency);
44
+
45
+ expect(result).toBe(locales.eur);
46
+ expect(result).toBe("fr-FR");
47
+ });
48
+
49
+ it("should return valid locale format", () => {
50
+ const validCurrencies: Currency[] = ["eur", "usd", "gbp"];
51
+
52
+ for (const currency of validCurrencies) {
53
+ const result = getSupportedLocale(currency);
54
+ // Should match locale format like "en-US", "fr-FR", etc.
55
+ expect(result).toMatch(/^[a-z]{2}-[A-Z]{2}$/);
56
+ }
57
+ });
58
+
59
+ it("should map all supported currencies to their locales", () => {
60
+ expect(getSupportedLocale("eur")).toBe("fr-FR");
61
+ expect(getSupportedLocale("usd")).toBe("en-US");
62
+ expect(getSupportedLocale("gbp")).toBe("en-GB");
63
+ });
64
+ });