@adobe/acc-js-sdk 1.1.58 → 1.1.60
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/docs/changeLog.html +15 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/application.js +7 -3
- package/src/client.js +13 -5
- package/src/util.js +18 -1
- package/test/application.test.js +30 -1
- package/test/client.test.js +98 -8
- package/test/util.test.js +99 -0
package/docs/changeLog.html
CHANGED
|
@@ -3,8 +3,22 @@ layout: page
|
|
|
3
3
|
title: Change Log
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<section class="changelog"><h1>Version 1.1.60</h1>
|
|
7
|
+
<h2>2025/09/04</h2>
|
|
8
|
+
<li>
|
|
9
|
+
Ability to bypass the cache to get a schema
|
|
10
|
+
</li>
|
|
11
|
+
</section>
|
|
12
|
+
|
|
13
|
+
<section class="changelog"><h1>Version 1.1.59</h1>
|
|
14
|
+
<h2>2025/08/22</h2>
|
|
15
|
+
<li>
|
|
16
|
+
In previous commit, computing the UUID was not working in a browser context
|
|
17
|
+
</li>
|
|
18
|
+
</section>
|
|
19
|
+
|
|
6
20
|
<section class="changelog"><h1>Version 1.1.58</h1>
|
|
7
|
-
<h2>2025/
|
|
21
|
+
<h2>2025/08/20</h2>
|
|
8
22
|
<li>
|
|
9
23
|
Bumped dependencies version to fix vulnerabilities
|
|
10
24
|
</li>
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/acc-js-sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.60",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@adobe/acc-js-sdk",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.60",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^1.7.8",
|
package/package.json
CHANGED
package/src/application.js
CHANGED
|
@@ -1419,15 +1419,19 @@ class Application {
|
|
|
1419
1419
|
* Using the `XtkSchema` API makes it easier to navigate schemas than using a plain XML or JSON object
|
|
1420
1420
|
*
|
|
1421
1421
|
* @param {string} schemaId
|
|
1422
|
+
* @param {boolean} withoutCache if true, the schema will be fetched from the server without using the cache, defaults to false
|
|
1422
1423
|
* @returns {Campaign.XtkSchema} the schema, or null if the schema was not found
|
|
1423
1424
|
*/
|
|
1424
|
-
async getSchema(schemaId) {
|
|
1425
|
+
async getSchema(schemaId, withoutCache = false) {
|
|
1426
|
+
if (withoutCache) {
|
|
1427
|
+
return this._getSchema(schemaId, withoutCache);
|
|
1428
|
+
}
|
|
1425
1429
|
return this._schemaCache.getSchema(schemaId);
|
|
1426
1430
|
}
|
|
1427
1431
|
|
|
1428
1432
|
// Private function: get a schema without using the SchemaCache
|
|
1429
|
-
async _getSchema(schemaId) {
|
|
1430
|
-
const xml = await this.client.getSchema(schemaId, "xml");
|
|
1433
|
+
async _getSchema(schemaId, withoutCache = false) {
|
|
1434
|
+
const xml = await this.client.getSchema(schemaId, "xml", undefined, withoutCache);
|
|
1431
1435
|
if (!xml)
|
|
1432
1436
|
return null;
|
|
1433
1437
|
return newSchema(xml, this);
|
package/src/client.js
CHANGED
|
@@ -38,7 +38,7 @@ const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
|
|
|
38
38
|
const { Util } = require('./util.js');
|
|
39
39
|
const { XtkJobInterface } = require('./xtkJob.js');
|
|
40
40
|
const qsStringify = require('qs-stringify');
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
/**
|
|
43
43
|
* @namespace Campaign
|
|
44
44
|
*
|
|
@@ -636,9 +636,16 @@ const fileUploader = (client) => {
|
|
|
636
636
|
// If a prefix is provided, we use it with a UUID (i.e. 'customPrefix-123e4567-e89b-12d3-a456-426614174000')
|
|
637
637
|
const oldBehaviorPrefix = 'RES';
|
|
638
638
|
const prefix = Util.validateFileResPrefix(fileResPrefix, oldBehaviorPrefix);
|
|
639
|
-
|
|
639
|
+
const getUUIDOrFallback = async() => {
|
|
640
|
+
try {
|
|
641
|
+
return Util.getUUID();
|
|
642
|
+
} catch (error) {
|
|
643
|
+
// In case getUUID throws, fall back to increasing the counter
|
|
644
|
+
return await client.NLWS.xtkCounter.increaseValue({ name: 'xtkResource' });
|
|
645
|
+
}
|
|
646
|
+
};
|
|
640
647
|
const suffix = (prefix === oldBehaviorPrefix) ?
|
|
641
|
-
await client.NLWS.xtkCounter.increaseValue({ name: 'xtkResource' }) :
|
|
648
|
+
await client.NLWS.xtkCounter.increaseValue({ name: 'xtkResource' }) : await getUUIDOrFallback();
|
|
642
649
|
|
|
643
650
|
const internalName = (prefix === oldBehaviorPrefix) ? `${prefix}${suffix}` : `${prefix}_${suffix}`;
|
|
644
651
|
|
|
@@ -1936,9 +1943,10 @@ class Client {
|
|
|
1936
1943
|
* @param {string} schemaId the schema id, such as "xtk:session", or "nms:recipient"
|
|
1937
1944
|
* @param {string} representation an optional representation of the schema: "BadgerFish", "SimpleJson" or "xml". If not set, we'll use the client default representation
|
|
1938
1945
|
* @param {boolean} internal indicates an "internal" call, i.e. a call performed by the SDK itself rather than the user of the SDK. For instance, the SDK will dynamically load schemas to find method definitions
|
|
1946
|
+
* @param {boolean} withoutCache if true, the schema will be fetched from the server without using the cache, defaults to false
|
|
1939
1947
|
* @returns {XML.XtkObject} the schema definition, as either a DOM document or a JSON object
|
|
1940
1948
|
*/
|
|
1941
|
-
async getSchema(schemaId, representation, internal) {
|
|
1949
|
+
async getSchema(schemaId, representation, internal, withoutCache = false) {
|
|
1942
1950
|
// Support for Orchestrated Campaign XDM schemas (do not use cache)
|
|
1943
1951
|
const pipeIndex = schemaId.indexOf("|");
|
|
1944
1952
|
if( pipeIndex != -1 && schemaId.startsWith("xdm:") ) {
|
|
@@ -1948,7 +1956,7 @@ class Client {
|
|
|
1948
1956
|
return entity;
|
|
1949
1957
|
}
|
|
1950
1958
|
var entity = await this._entityCache.get("xtk:schema", schemaId);
|
|
1951
|
-
if (!entity) {
|
|
1959
|
+
if (!entity || withoutCache) {
|
|
1952
1960
|
// special case of "temp:group:*" schemas for nms:group
|
|
1953
1961
|
// Schema "temp:group:*" is not cached because life cycle of this kind of schema is not the same as the others schemas
|
|
1954
1962
|
if (schemaId.startsWith("temp:group:")) {
|
package/src/util.js
CHANGED
|
@@ -143,7 +143,7 @@ class Util {
|
|
|
143
143
|
return schemaId;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
static validateFileResPrefix(prefix, defaultPrefix =
|
|
146
|
+
static validateFileResPrefix(prefix, defaultPrefix = 'RES') {
|
|
147
147
|
const regex = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
148
148
|
|
|
149
149
|
if (typeof prefix !== "string" || !regex.test(prefix)) {
|
|
@@ -153,6 +153,23 @@ class Util {
|
|
|
153
153
|
return prefix;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
static getUUID() {
|
|
157
|
+
if (globalThis.crypto &&
|
|
158
|
+
globalThis.crypto.randomUUID &&
|
|
159
|
+
typeof globalThis.crypto.randomUUID === 'function') {
|
|
160
|
+
return globalThis.crypto.randomUUID(); // browser
|
|
161
|
+
}
|
|
162
|
+
const nodeCrypto = (() => {
|
|
163
|
+
return require("crypto");
|
|
164
|
+
})();
|
|
165
|
+
if (nodeCrypto && nodeCrypto.randomUUID) {
|
|
166
|
+
return nodeCrypto.randomUUID(); // Node
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
//Nothing worked
|
|
170
|
+
throw new Error('Unable to generate UUID');
|
|
171
|
+
}
|
|
172
|
+
|
|
156
173
|
/**
|
|
157
174
|
* Test if an object is a promise
|
|
158
175
|
* @param {*} object the object to test
|
package/test/application.test.js
CHANGED
|
@@ -2543,7 +2543,36 @@ describe('Application', () => {
|
|
|
2543
2543
|
client._transport.mockReturnValueOnce(Mock.GET_MISSING_SCHEMA_RESPONSE);
|
|
2544
2544
|
const schema = await client.application.getSchema("xtk:dummy")
|
|
2545
2545
|
expect(schema).toBeNull();
|
|
2546
|
-
})
|
|
2546
|
+
});
|
|
2547
|
+
|
|
2548
|
+
it("Should respect withoutCache parameter", async () => {
|
|
2549
|
+
const client = await Mock.makeClient();
|
|
2550
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
2551
|
+
await client.NLWS.xtkSession.logon();
|
|
2552
|
+
|
|
2553
|
+
// First call - should use cache
|
|
2554
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2555
|
+
const schema = await client.application.getSchema("xtk:session");
|
|
2556
|
+
expect(schema.namespace).toBe("xtk");
|
|
2557
|
+
expect(schema.name).toBe("session");
|
|
2558
|
+
expect(client._transport).toHaveBeenCalledTimes(2); // Logon + getSchema
|
|
2559
|
+
|
|
2560
|
+
// Second call - should use cache (no transport call)
|
|
2561
|
+
const schema2 = await client.application.getSchema("xtk:session");
|
|
2562
|
+
expect(schema2.namespace).toBe("xtk");
|
|
2563
|
+
expect(schema2.name).toBe("session");
|
|
2564
|
+
expect(client._transport).toHaveBeenCalledTimes(2); // Still only 2 calls (no new transport call)
|
|
2565
|
+
|
|
2566
|
+
// Third call with withoutCache=true - should bypass cache and make transport call
|
|
2567
|
+
client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
|
|
2568
|
+
const schema3 = await client.application.getSchema("xtk:session", true);
|
|
2569
|
+
expect(schema3.namespace).toBe("xtk");
|
|
2570
|
+
expect(schema3.name).toBe("session");
|
|
2571
|
+
expect(client._transport).toHaveBeenCalledTimes(3); // Now 3 calls (bypassed cache)
|
|
2572
|
+
|
|
2573
|
+
client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
|
|
2574
|
+
await client.NLWS.xtkSession.logoff();
|
|
2575
|
+
});
|
|
2547
2576
|
});
|
|
2548
2577
|
|
|
2549
2578
|
describe("application.hasPackage", () => {
|
package/test/client.test.js
CHANGED
|
@@ -436,6 +436,42 @@ describe('ACC Client', function () {
|
|
|
436
436
|
await client.NLWS.xtkSession.logoff();
|
|
437
437
|
});
|
|
438
438
|
|
|
439
|
+
it("Should respect withoutCache parameter", async () => {
|
|
440
|
+
const client = await Mock.makeClient();
|
|
441
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
442
|
+
await client.NLWS.xtkSession.logon();
|
|
443
|
+
|
|
444
|
+
// First call - should cache the schema
|
|
445
|
+
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
446
|
+
var schema = await client.getSchema("nms:extAccount");
|
|
447
|
+
expect(schema["namespace"]).toBe("nms");
|
|
448
|
+
expect(schema["name"]).toBe("extAccount");
|
|
449
|
+
expect(client._transport).toHaveBeenCalledTimes(2); // Logon + getSchema
|
|
450
|
+
|
|
451
|
+
// Second call - should use cache (no transport call)
|
|
452
|
+
schema = await client.getSchema("nms:extAccount");
|
|
453
|
+
expect(schema["namespace"]).toBe("nms");
|
|
454
|
+
expect(schema["name"]).toBe("extAccount");
|
|
455
|
+
expect(client._transport).toHaveBeenCalledTimes(2); // Still only 2 calls (no new transport call)
|
|
456
|
+
|
|
457
|
+
// Third call with withoutCache=true - should bypass cache and make transport call
|
|
458
|
+
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
459
|
+
schema = await client.getSchema("nms:extAccount", undefined, undefined, true);
|
|
460
|
+
expect(schema["namespace"]).toBe("nms");
|
|
461
|
+
expect(schema["name"]).toBe("extAccount");
|
|
462
|
+
expect(client._transport).toHaveBeenCalledTimes(3); // Now 3 calls (bypassed cache)
|
|
463
|
+
|
|
464
|
+
// Fourth call with withoutCache=true and custom representation - should bypass cache
|
|
465
|
+
client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
|
|
466
|
+
schema = await client.getSchema("nms:extAccount", "xml", undefined, true);
|
|
467
|
+
expect(schema.getAttribute("namespace")).toBe("nms");
|
|
468
|
+
expect(schema.getAttribute("name")).toBe("extAccount");
|
|
469
|
+
expect(client._transport).toHaveBeenCalledTimes(4); // Now 4 calls (bypassed cache again)
|
|
470
|
+
|
|
471
|
+
client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
|
|
472
|
+
await client.NLWS.xtkSession.logoff();
|
|
473
|
+
});
|
|
474
|
+
|
|
439
475
|
it("Should return XDM schema definition", async () => {
|
|
440
476
|
const client = await Mock.makeClient();
|
|
441
477
|
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
@@ -3604,7 +3640,7 @@ describe('ACC Client', function () {
|
|
|
3604
3640
|
statusCode: 500,
|
|
3605
3641
|
});
|
|
3606
3642
|
});
|
|
3607
|
-
});
|
|
3643
|
+
}); // "File uploader - on server"
|
|
3608
3644
|
|
|
3609
3645
|
describe("File uploader - on browser", () => {
|
|
3610
3646
|
beforeEach(() => {
|
|
@@ -4218,8 +4254,6 @@ describe('ACC Client', function () {
|
|
|
4218
4254
|
statusCode: 400,
|
|
4219
4255
|
});
|
|
4220
4256
|
});
|
|
4221
|
-
});
|
|
4222
|
-
|
|
4223
4257
|
it("Test uploads by specifying a file prefix", async () => {
|
|
4224
4258
|
// Create a mock client and logon
|
|
4225
4259
|
const client = await Mock.makeClient();
|
|
@@ -4261,13 +4295,69 @@ describe('ACC Client', function () {
|
|
|
4261
4295
|
); // xtk:fileRes#GetURL
|
|
4262
4296
|
|
|
4263
4297
|
// Call upload
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4298
|
+
await client.fileUploader.upload({
|
|
4299
|
+
type: "text/html",
|
|
4300
|
+
size: 12345,
|
|
4301
|
+
}, undefined, 'PREFIX');
|
|
4268
4302
|
expect(Util.validateFileResPrefix).toHaveBeenLastCalledWith('PREFIX', 'RES');
|
|
4269
4303
|
});
|
|
4270
|
-
|
|
4304
|
+
|
|
4305
|
+
it("Test uploads by with a file prefix but getUUID throws", async () => {
|
|
4306
|
+
// Create a mock client and logon
|
|
4307
|
+
const client = await Mock.makeClient();
|
|
4308
|
+
client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
|
|
4309
|
+
await client.NLWS.xtkSession.logon();
|
|
4310
|
+
|
|
4311
|
+
// Mock the upload protocol
|
|
4312
|
+
// - the upload.jsp (which returns the content of an iframe and JS to eval)
|
|
4313
|
+
// - call to xtk:session#Write
|
|
4314
|
+
// - call to xtk:fileRes#PublishIfNeeded
|
|
4315
|
+
// - call to xtk:fileRes#GetURL
|
|
4316
|
+
|
|
4317
|
+
client._transport.mockReturnValueOnce(
|
|
4318
|
+
Promise.resolve(`Ok
|
|
4319
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
4320
|
+
<head>
|
|
4321
|
+
<script type="text/javascript">if(window.parent&&window.parent.document.controller&&"function"==typeof window.parent.document.controller.uploadFileCallBack){var aFilesInfo=new Array;aFilesInfo.push({paramName:"file",fileName:"test.txt",newFileName:"d8e8fca2dc0f896fd7cb4cb0031ba249.txt",md5:"d8e8fca2dc0f896fd7cb4cb0031ba249"}),window.parent.document.controller.uploadFileCallBack(aFilesInfo)}</script>
|
|
4322
|
+
</head>
|
|
4323
|
+
<body></body>
|
|
4324
|
+
</html>`)
|
|
4325
|
+
); // upload.jsp
|
|
4326
|
+
|
|
4327
|
+
client._transport.mockReturnValueOnce(
|
|
4328
|
+
Promise.resolve(Mock.GET_XTK_COUNTER_RESPONSE)
|
|
4329
|
+
); // GetEntityIfMoreRecentResponse - counter
|
|
4330
|
+
client._transport.mockReturnValueOnce(
|
|
4331
|
+
Mock.INCREASE_VALUE_RESPONSE
|
|
4332
|
+
); // xtk:counter#IncreaseValue
|
|
4333
|
+
|
|
4334
|
+
client._transport.mockReturnValueOnce(
|
|
4335
|
+
Mock.GET_XTK_SESSION_SCHEMA_RESPONSE
|
|
4336
|
+
); // GetEntityIfMoreRecentResponse - session
|
|
4337
|
+
|
|
4338
|
+
client._transport.mockReturnValueOnce(Mock.FILE_RES_WRITE_RESPONSE); // xtk:session#Write
|
|
4339
|
+
jest.spyOn(Util, 'getUUID').mockImplementation(() => { throw new Error('UUID error'); });
|
|
4340
|
+
|
|
4341
|
+
client._transport.mockReturnValueOnce(
|
|
4342
|
+
Promise.resolve(Mock.GET_FILERES_QUERY_SCHEMA_RESPONSE)
|
|
4343
|
+
); // GetEntityIfMoreRecentResponse - fileRes
|
|
4344
|
+
client._transport.mockReturnValueOnce(
|
|
4345
|
+
Promise.resolve(Mock.PUBLISH_IF_NEEDED_RESPONSE)
|
|
4346
|
+
); // xtk:fileRes#PublishIfNeeded
|
|
4347
|
+
|
|
4348
|
+
client._transport.mockReturnValueOnce(
|
|
4349
|
+
Promise.resolve(Mock.GET_URL_RESPONSE)
|
|
4350
|
+
); // xtk:fileRes#GetURL
|
|
4351
|
+
|
|
4352
|
+
// Call upload
|
|
4353
|
+
await client.fileUploader.upload({
|
|
4354
|
+
type: "text/html",
|
|
4355
|
+
size: 12345,
|
|
4356
|
+
}, undefined, 'PREFIX');
|
|
4357
|
+
expect(Util.getUUID).toHaveBeenCalledTimes(1);
|
|
4358
|
+
});
|
|
4359
|
+
}); // "File uploader - on browser"
|
|
4360
|
+
}); // 'upload'
|
|
4271
4361
|
|
|
4272
4362
|
describe('uploadAemAsset', () => {
|
|
4273
4363
|
// write unit test for client.fileUploader.uploadAemAsset method
|
package/test/util.test.js
CHANGED
|
@@ -458,5 +458,104 @@ describe('Util', function() {
|
|
|
458
458
|
expect(Util.validateFileResPrefix("132Invalid", "customDefault")).toBe("customDefault");
|
|
459
459
|
});
|
|
460
460
|
});
|
|
461
|
+
|
|
462
|
+
describe("GetUUID", () => {
|
|
463
|
+
describe("UUID - on server node", () => {
|
|
464
|
+
describe("node <= 16", () => {
|
|
465
|
+
describe('code coverage: getUUID', () => {
|
|
466
|
+
let originalCrypto;
|
|
467
|
+
// on old Node versions, crypto may not be available
|
|
468
|
+
// deleting globalThis.crypto to simulate the environment on newer Node
|
|
469
|
+
beforeEach(() => {
|
|
470
|
+
// Save the original crypto
|
|
471
|
+
originalCrypto = globalThis.crypto;
|
|
472
|
+
delete globalThis.crypto;
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
afterEach(() => {
|
|
476
|
+
// Restore it after the test
|
|
477
|
+
globalThis.crypto = originalCrypto;
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it('should handle require("crypto") throwing', () => {
|
|
481
|
+
// Force require("crypto") to throw
|
|
482
|
+
jest.mock('crypto', () => {
|
|
483
|
+
throw new Error('mock require failure');
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// Re-require the module AFTER mocking
|
|
487
|
+
const UUIDHelper = require('../src/util.js').Util;
|
|
488
|
+
|
|
489
|
+
let exceptionCaught = false;
|
|
490
|
+
try{
|
|
491
|
+
UUIDHelper.getUUID();
|
|
492
|
+
} catch (e) {
|
|
493
|
+
exceptionCaught = true;
|
|
494
|
+
}
|
|
495
|
+
expect(exceptionCaught).toBe(true);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it('should handle require("crypto") throwing', () => {
|
|
499
|
+
// Force require("crypto") to not have randomUUID
|
|
500
|
+
jest.mock('crypto', () => ({}));
|
|
501
|
+
|
|
502
|
+
// Re-require the module AFTER mocking
|
|
503
|
+
const UUIDHelper = require('../src/util.js').Util;
|
|
504
|
+
|
|
505
|
+
let exceptionCaught = false;
|
|
506
|
+
try{
|
|
507
|
+
UUIDHelper.getUUID();
|
|
508
|
+
} catch (e) {
|
|
509
|
+
exceptionCaught = e.message === 'Unable to generate UUID';
|
|
510
|
+
}
|
|
511
|
+
expect(exceptionCaught).toBe(true);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it('should fallback to node crypto when globalThis.crypto is not available', () => {
|
|
515
|
+
jest.unmock('crypto');
|
|
516
|
+
// Spy on require
|
|
517
|
+
const spy = jest.spyOn(require('crypto'), 'randomUUID').mockReturnValue('mock-uuid');
|
|
518
|
+
|
|
519
|
+
// Re-import the module if your getUUID function is from a module
|
|
520
|
+
const uuid = Util.getUUID(); // or just call getUUID() if it's in scope
|
|
521
|
+
|
|
522
|
+
expect(uuid).toBe('mock-uuid');
|
|
523
|
+
expect(spy).toHaveBeenCalled();
|
|
524
|
+
spy.mockRestore();
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
describe("node > 16", () => {
|
|
530
|
+
it('should return a correct UUID v4', () => {
|
|
531
|
+
// x is [0-9a-f], Y is 8, 9, a or b
|
|
532
|
+
// uuid format: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx
|
|
533
|
+
const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
534
|
+
expect(uuidV4Regex.test(Util.getUUID())).toBe(true);
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
describe("UUID - on browser", () => {
|
|
539
|
+
// code coverage test as we mock the browser return values
|
|
540
|
+
it('should return a correct UUID v4', () => {
|
|
541
|
+
if (!globalThis.crypto || !globalThis.crypto.randomUUID){
|
|
542
|
+
globalThis.crypto = {
|
|
543
|
+
...globalThis.crypto,
|
|
544
|
+
randomUUID: jest.fn(),
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// x is [0-9a-f], Y is 8, 9, a or b
|
|
549
|
+
// uuid v4 format: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx
|
|
550
|
+
// Mocking crypto.randomUUID to return a specific valid v4 UUID
|
|
551
|
+
jest.spyOn(globalThis.crypto, 'randomUUID').mockReturnValue('123e4567-e89b-42d3-a456-426614174000');
|
|
552
|
+
const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
553
|
+
expect(uuidV4Regex.test(Util.getUUID())).toBe(true);
|
|
554
|
+
// Mocking crypto.randomUUID to return a specific an invalid v4 UUID
|
|
555
|
+
jest.spyOn(globalThis.crypto, 'randomUUID').mockReturnValue('12345678-1234-0234-0567-426614174000');
|
|
556
|
+
expect(uuidV4Regex.test(Util.getUUID())).toBe(false);
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
});
|
|
461
560
|
});
|
|
462
561
|
|