@futdevpro/fsm-dynamo 1.14.19 → 1.14.21

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 (31) hide show
  1. package/build/_models/control-models/error.control-model.d.ts.map +1 -1
  2. package/build/_models/control-models/error.control-model.js +3 -0
  3. package/build/_models/control-models/error.control-model.js.map +1 -1
  4. package/build/_modules/crypto/_collections/crypto.util.d.ts.map +1 -1
  5. package/build/_modules/crypto/_collections/crypto.util.edge.spec.d.ts +2 -0
  6. package/build/_modules/crypto/_collections/crypto.util.edge.spec.d.ts.map +1 -0
  7. package/build/_modules/crypto/_collections/crypto.util.edge.spec.js +551 -0
  8. package/build/_modules/crypto/_collections/crypto.util.edge.spec.js.map +1 -0
  9. package/build/_modules/crypto/_collections/crypto.util.extra.spec.d.ts +2 -0
  10. package/build/_modules/crypto/_collections/crypto.util.extra.spec.d.ts.map +1 -0
  11. package/build/_modules/crypto/_collections/crypto.util.extra.spec.js +555 -0
  12. package/build/_modules/crypto/_collections/crypto.util.extra.spec.js.map +1 -0
  13. package/build/_modules/crypto/_collections/crypto.util.js +33 -3
  14. package/build/_modules/crypto/_collections/crypto.util.js.map +1 -1
  15. package/build/_modules/crypto/_collections/crypto.util.simple.spec.d.ts +2 -0
  16. package/build/_modules/crypto/_collections/crypto.util.simple.spec.d.ts.map +1 -0
  17. package/build/_modules/crypto/_collections/crypto.util.simple.spec.js +429 -0
  18. package/build/_modules/crypto/_collections/crypto.util.simple.spec.js.map +1 -0
  19. package/futdevpro-fsm-dynamo-01.14.21.tgz +0 -0
  20. package/package.json +2 -2
  21. package/src/_models/control-models/error.control-model.ts +4 -0
  22. package/src/_modules/crypto/_collections/crypto.util.edge.spec.ts +606 -0
  23. package/src/_modules/crypto/_collections/crypto.util.extra.spec.ts +643 -0
  24. package/src/_modules/crypto/_collections/crypto.util.simple.spec.ts +513 -0
  25. package/src/_modules/crypto/_collections/crypto.util.ts +81 -48
  26. package/build/_modules/crypto/_collections/crypto.util.spec.d.ts +0 -2
  27. package/build/_modules/crypto/_collections/crypto.util.spec.d.ts.map +0 -1
  28. package/build/_modules/crypto/_collections/crypto.util.spec.js +0 -1180
  29. package/build/_modules/crypto/_collections/crypto.util.spec.js.map +0 -1
  30. package/futdevpro-fsm-dynamo-01.14.19.tgz +0 -0
  31. package/src/_modules/crypto/_collections/crypto.util.spec.ts +0 -1370
@@ -1,1180 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const crypto_util_1 = require("./crypto.util");
4
- describe('| DyFM_Crypto', () => {
5
- const testKey = 'test-secret-key-123';
6
- const testData = { id: 1, name: 'test' };
7
- describe('| encrypt', () => {
8
- it('| should successfully encrypt data', () => {
9
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
10
- expect(encrypted).toBeDefined();
11
- expect(typeof encrypted).toBe('string');
12
- expect(encrypted).toMatch(/^[A-Za-z0-9\-_]+$/);
13
- });
14
- it('| should encrypt different data with different results', () => {
15
- const data1 = { id: 1 };
16
- const data2 = { id: 2 };
17
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(data1, testKey);
18
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(data2, testKey);
19
- expect(encrypted1).not.toEqual(encrypted2);
20
- });
21
- it('| should throw DyFM_Error when encryption fails', () => {
22
- // @ts-ignore - Testing invalid input
23
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(undefined, testKey)).toThrow();
24
- });
25
- it('| should handle complex objects', () => {
26
- const complexData = {
27
- id: 1,
28
- name: 'test',
29
- nested: {
30
- value: 'nested-value',
31
- array: [1, 2, 3]
32
- }
33
- };
34
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(complexData, testKey);
35
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
36
- expect(decrypted).toEqual(complexData);
37
- });
38
- it('| should get the same result with the same input', () => {
39
- const complexData = {
40
- id: 2,
41
- name: 'test',
42
- nested: {
43
- value: 'nested-value',
44
- array: [1, 2, 3]
45
- }
46
- };
47
- const expectedResult = JSON.stringify(complexData);
48
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(complexData, testKey);
49
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
50
- const result = JSON.stringify(decrypted);
51
- expect(result).toBe(expectedResult);
52
- });
53
- it('| should not effect the original object', () => {
54
- const complexData = {
55
- id: 1,
56
- name: 'test',
57
- nested: { value: 'nested-value', array: [1, 2, 3] }
58
- };
59
- const originalData = JSON.stringify(complexData);
60
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(complexData, testKey);
61
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
62
- const result = JSON.stringify(decrypted);
63
- expect(result).toBe(originalData);
64
- });
65
- it('| should handle arrays', () => {
66
- const arrayData = [1, 'test', { nested: true }];
67
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(arrayData, testKey);
68
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
69
- expect(decrypted).toEqual(arrayData);
70
- });
71
- it('| should handle primitive values', () => {
72
- const stringData = 'test string';
73
- const numberData = 42;
74
- const booleanData = true;
75
- const encryptedString = crypto_util_1.DyFM_Crypto.encrypt(stringData, testKey);
76
- const encryptedNumber = crypto_util_1.DyFM_Crypto.encrypt(numberData, testKey);
77
- const encryptedBoolean = crypto_util_1.DyFM_Crypto.encrypt(booleanData, testKey);
78
- expect(crypto_util_1.DyFM_Crypto.decrypt(encryptedString, testKey)).toBe(stringData);
79
- expect(crypto_util_1.DyFM_Crypto.decrypt(encryptedNumber, testKey)).toBe(numberData);
80
- expect(crypto_util_1.DyFM_Crypto.decrypt(encryptedBoolean, testKey)).toBe(booleanData);
81
- });
82
- });
83
- describe('| decrypt', () => {
84
- it('| should successfully decrypt encrypted data', () => {
85
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
86
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
87
- expect(decrypted).toEqual(testData);
88
- });
89
- it('| should throw DyFM_Error when decryption fails', () => {
90
- expect(() => crypto_util_1.DyFM_Crypto.decrypt('invalid-encrypted-data', testKey)).toThrow();
91
- });
92
- it('| should throw DyFM_Error when using wrong key', () => {
93
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
94
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(encrypted, 'wrong-key')).toThrow();
95
- });
96
- it('| should throw DyFM_Error when encrypted data is modified', () => {
97
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
98
- const modified = encrypted.slice(0, -1) + 'A';
99
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(modified, testKey)).toThrow();
100
- });
101
- });
102
- describe('| URL-safe encryption', () => {
103
- it('| should produce URL-safe strings', () => {
104
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
105
- expect(encrypted).toMatch(/^[A-Za-z0-9\-_]+$/);
106
- });
107
- it('| should work in HTTP headers', () => {
108
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
109
- const header = `Bearer ${encrypted}`;
110
- const extracted = header.split(' ')[1];
111
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(extracted, testKey);
112
- expect(decrypted).toEqual(testData);
113
- });
114
- it('| should work in URLs', () => {
115
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
116
- const url = `https://example.com/api?token=${encrypted}`;
117
- const params = new URLSearchParams(url.split('?')[1]);
118
- const extracted = params.get('token');
119
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(extracted, testKey);
120
- expect(decrypted).toEqual(testData);
121
- });
122
- });
123
- describe('| LONG-TERM STABILITY TESTS - Cross-platform compatibility', () => {
124
- describe('| Deterministic encryption consistency', () => {
125
- it('| should produce identical encrypted output for identical input across multiple calls', () => {
126
- const testData = { id: 1, name: 'test', timestamp: '2024-01-01T00:00:00Z' };
127
- const key = 'stable-test-key-123';
128
- // Multiple encryption calls should produce identical results
129
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
130
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
131
- const encrypted3 = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
132
- expect(encrypted1).toBe(encrypted2);
133
- expect(encrypted2).toBe(encrypted3);
134
- expect(encrypted1).toBe(encrypted3);
135
- // All should decrypt to the same data
136
- const decrypted1 = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
137
- const decrypted2 = crypto_util_1.DyFM_Crypto.decrypt(encrypted2, key);
138
- const decrypted3 = crypto_util_1.DyFM_Crypto.decrypt(encrypted3, key);
139
- expect(decrypted1).toEqual(decrypted2);
140
- expect(decrypted2).toEqual(decrypted3);
141
- expect(decrypted1).toEqual(testData);
142
- });
143
- it('| should maintain consistency with different data types and structures', () => {
144
- const testCases = [
145
- { data: { id: 1, name: 'simple' }, key: 'key1' },
146
- { data: 'plain string', key: 'key2' },
147
- { data: [1, 2, 3, 'array'], key: 'key3' },
148
- { data: { nested: { deep: { value: true } } }, key: 'key4' },
149
- { data: { empty: {}, null: null }, key: 'key5' } // Removed undefined as it gets filtered out
150
- ];
151
- testCases.forEach(({ data, key }) => {
152
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(data, key);
153
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(data, key);
154
- expect(encrypted1).toBe(encrypted2);
155
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
156
- expect(decrypted).toEqual(data);
157
- });
158
- });
159
- it('| should handle edge cases consistently', () => {
160
- const edgeCases = [
161
- { data: 'non-empty', key: 'non-empty-string-key' },
162
- { data: 0, key: 'zero-number-key' },
163
- { data: false, key: 'false-boolean-key' },
164
- { data: { a: 0, b: false, c: 'non-empty' }, key: 'mixed-edge-key' }
165
- ];
166
- edgeCases.forEach(({ data, key }) => {
167
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(data, key);
168
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(data, key);
169
- expect(encrypted1).toBe(encrypted2);
170
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
171
- expect(decrypted).toEqual(data);
172
- });
173
- });
174
- });
175
- describe('| Cross-version compatibility simulation', () => {
176
- it('| should handle data encrypted with different configurations consistently', () => {
177
- const testData = { id: 1, name: 'config-test' };
178
- const key = 'config-test-key';
179
- // Test with default config
180
- const defaultEncrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
181
- const defaultDecrypted = crypto_util_1.DyFM_Crypto.decrypt(defaultEncrypted, key);
182
- expect(defaultDecrypted).toEqual(testData);
183
- // Test with custom config
184
- const customConfig = { keyIterations: 500, keySize: 6 };
185
- const customEncrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, key, customConfig);
186
- const customDecrypted = crypto_util_1.DyFM_Crypto.decrypt(customEncrypted, key, customConfig);
187
- expect(customDecrypted).toEqual(testData);
188
- // Test that different configs produce different encrypted results
189
- expect(defaultEncrypted).not.toBe(customEncrypted);
190
- });
191
- it('| should maintain backward compatibility with existing encrypted data', () => {
192
- // Simulate data that was encrypted with previous version
193
- const legacyData = { id: 1, name: 'legacy-test', version: '1.0' };
194
- const key = 'legacy-key';
195
- // Encrypt with current implementation
196
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(legacyData, key);
197
- // Simulate system restart/reload
198
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, key);
199
- expect(decrypted).toEqual(legacyData);
200
- // Re-encrypt should produce same result
201
- const reEncrypted = crypto_util_1.DyFM_Crypto.encrypt(decrypted, key);
202
- expect(reEncrypted).toBe(encrypted);
203
- });
204
- });
205
- describe('| Platform independence tests', () => {
206
- it('| should handle different character encodings consistently', () => {
207
- const unicodeData = {
208
- hungarian: 'árvíztűrő tükörfúrógép',
209
- chinese: '你好世界',
210
- emoji: '🚀💻🔒',
211
- special: '!@#$%^&*()_+-=[]{}|;:,.<>?'
212
- };
213
- const key = 'unicode-test-key';
214
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(unicodeData, key);
215
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, key);
216
- expect(decrypted).toEqual(unicodeData);
217
- // Multiple encryptions should be identical
218
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(unicodeData, key);
219
- expect(encrypted).toBe(encrypted2);
220
- });
221
- it('| should handle large data objects consistently', () => {
222
- // Create a large object with many properties
223
- const largeData = { id: 1 };
224
- for (let i = 0; i < 100; i++) {
225
- largeData[`prop${i}`] = `value${i}`;
226
- }
227
- const key = 'large-data-key';
228
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(largeData, key);
229
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(largeData, key);
230
- expect(encrypted1).toBe(encrypted2);
231
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
232
- expect(decrypted).toEqual(largeData);
233
- });
234
- it('| should handle nested circular references gracefully', () => {
235
- const circularData = { id: 1, name: 'circular' };
236
- circularData.self = circularData;
237
- const key = 'circular-key';
238
- // Should handle circular references without crashing
239
- expect(() => {
240
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(circularData, key);
241
- // Note: JSON.stringify will fail on circular refs, so this test ensures graceful handling
242
- }).toThrow(); // Expected to throw due to circular reference
243
- });
244
- });
245
- describe('| Time-based stability tests', () => {
246
- it('| should maintain consistency across time-based operations', () => {
247
- const timeData = {
248
- timestamp: new Date().toISOString(),
249
- id: 1,
250
- name: 'time-test'
251
- };
252
- const key = 'time-test-key';
253
- // Encrypt same data multiple times
254
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(timeData, key);
255
- // Simulate time passing
256
- setTimeout(() => {
257
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(timeData, key);
258
- expect(encrypted1).toBe(encrypted2);
259
- }, 100);
260
- });
261
- it('| should handle date objects consistently', () => {
262
- const dateData = {
263
- created: new Date('2024-01-01T00:00:00Z'),
264
- updated: new Date('2024-12-31T23:59:59Z'),
265
- id: 1
266
- };
267
- const key = 'date-test-key';
268
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(dateData, key);
269
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(dateData, key);
270
- expect(encrypted1).toBe(encrypted2);
271
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
272
- // Compare ISO strings since JSON serialization converts dates to strings
273
- expect(decrypted.created).toEqual(dateData.created.toISOString());
274
- expect(decrypted.updated).toEqual(dateData.updated.toISOString());
275
- expect(decrypted.id).toBe(dateData.id);
276
- });
277
- });
278
- describe('| Memory and performance stability', () => {
279
- it('| should handle multiple encryption/decryption cycles without memory leaks', () => {
280
- const testData = { id: 1, name: 'memory-test' };
281
- const key = 'memory-test-key';
282
- // Perform many encryption/decryption cycles
283
- for (let i = 0; i < 1000; i++) {
284
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
285
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, key);
286
- expect(decrypted).toEqual(testData);
287
- }
288
- });
289
- it('| should maintain consistent performance across multiple operations', () => {
290
- const testData = { id: 1, name: 'performance-test' };
291
- const key = 'performance-test-key';
292
- const startTime = Date.now();
293
- // Perform multiple operations
294
- for (let i = 0; i < 100; i++) {
295
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
296
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, key);
297
- expect(decrypted).toEqual(testData);
298
- }
299
- const endTime = Date.now();
300
- const duration = endTime - startTime;
301
- // Should complete within reasonable time (adjust threshold as needed)
302
- expect(duration).toBeLessThan(5000); // 5 seconds max
303
- });
304
- });
305
- });
306
- describe('| edge cases', () => {
307
- describe('| empty and null values', () => {
308
- it('| should handle empty objects', () => {
309
- const emptyObj = {};
310
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(emptyObj, testKey);
311
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
312
- expect(decrypted).toEqual(emptyObj);
313
- });
314
- it('| should handle empty arrays', () => {
315
- const emptyArr = [];
316
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(emptyArr, testKey);
317
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
318
- expect(decrypted).toEqual(emptyArr);
319
- });
320
- it('| should handle null values in objects', () => {
321
- const dataWithNull = {
322
- id: 1,
323
- name: null,
324
- nested: { value: null }
325
- };
326
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(dataWithNull, testKey);
327
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
328
- expect(decrypted).toEqual(dataWithNull);
329
- });
330
- it('| should handle undefined values in objects', () => {
331
- const dataWithUndefined = {
332
- id: 1,
333
- name: undefined,
334
- nested: { value: undefined }
335
- };
336
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(dataWithUndefined, testKey);
337
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
338
- expect(decrypted).toEqual({ id: 1, nested: {} });
339
- });
340
- });
341
- describe('| key edge cases', () => {
342
- it('| should handle very long keys', () => {
343
- const longKey = 'a'.repeat(1000);
344
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, longKey);
345
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, longKey);
346
- expect(decrypted).toEqual(testData);
347
- });
348
- it('| should handle empty key', () => {
349
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(testData, '')).toThrow();
350
- });
351
- it('| should handle whitespace-only keys', () => {
352
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(testData, ' ')).toThrow();
353
- });
354
- });
355
- describe('| encrypted data manipulation', () => {
356
- it('| should detect when encrypted data is truncated', () => {
357
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
358
- const truncated = encrypted.slice(0, -10);
359
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(truncated, testKey)).toThrow();
360
- });
361
- it('| should detect when encrypted data is extended', () => {
362
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
363
- const extended = encrypted + 'A'.repeat(10);
364
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(extended, testKey)).toThrow();
365
- });
366
- it('| should detect when encrypted data is modified in the middle', () => {
367
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
368
- const midPoint = Math.floor(encrypted.length / 2);
369
- const modified = encrypted.slice(0, midPoint) + 'X' + encrypted.slice(midPoint + 1);
370
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(modified, testKey)).toThrow();
371
- });
372
- });
373
- describe('| JSON handling edge cases', () => {
374
- it('| should handle double-stringified JSON data correctly', () => {
375
- const testData = {
376
- username: 'Itharen',
377
- password: 'asdasd',
378
- roles: [],
379
- permissions: [],
380
- activeSubscriptions: [],
381
- clientUserIds: {},
382
- oauth2Data: {}
383
- };
384
- // Simulate double stringification
385
- const doubleStringified = JSON.stringify(JSON.stringify(testData));
386
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(doubleStringified, testKey);
387
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
388
- // The crypto utility should automatically handle double-stringified JSON
389
- // and return the original object directly
390
- expect(decrypted).toEqual(testData);
391
- });
392
- it('| should handle character-by-character JSON data correctly', () => {
393
- // Create a character-by-character object like in the example
394
- const charByCharData = {
395
- '0': '{',
396
- '1': '"',
397
- '2': '_',
398
- '3': '_',
399
- '4': 'c',
400
- '5': 'r',
401
- '6': 'e',
402
- '7': 'a',
403
- '8': 't',
404
- '9': 'e',
405
- '10': 'd',
406
- '11': '"',
407
- '12': ':',
408
- '13': '"',
409
- '14': '2',
410
- '15': '0',
411
- '16': '2',
412
- '17': '5',
413
- '18': '-',
414
- '19': '0',
415
- '20': '5',
416
- '21': '-',
417
- '22': '1',
418
- '23': '3',
419
- '24': 'T',
420
- '25': '1',
421
- '26': '0',
422
- '27': ':',
423
- '28': '4',
424
- '29': '0',
425
- '30': ':',
426
- '31': '4',
427
- '32': '4',
428
- '33': '.',
429
- '34': '7',
430
- '35': '6',
431
- '36': '0',
432
- '37': 'Z',
433
- '38': '"',
434
- '39': ',',
435
- '40': '"',
436
- '41': '_',
437
- '42': '_',
438
- '43': 'l',
439
- '44': 'a',
440
- '45': 's',
441
- '46': 't',
442
- '47': 'M',
443
- '48': 'o',
444
- '49': 'd',
445
- '50': 'i',
446
- '51': 'f',
447
- '52': 'i',
448
- '53': 'e',
449
- '54': 'd',
450
- '55': '"',
451
- '56': ':',
452
- '57': '"',
453
- '58': '2',
454
- '59': '0',
455
- '60': '2',
456
- '61': '5',
457
- '62': '-',
458
- '63': '0',
459
- '64': '5',
460
- '65': '-',
461
- '66': '1',
462
- '67': '3',
463
- '68': 'T',
464
- '69': '1',
465
- '70': '0',
466
- '71': ':',
467
- '72': '4',
468
- '73': '0',
469
- '74': ':',
470
- '75': '4',
471
- '76': '4',
472
- '77': '.',
473
- '78': '7',
474
- '79': '6',
475
- '80': '0',
476
- '81': 'Z',
477
- '82': '"',
478
- '83': ',',
479
- '84': '"',
480
- '85': '_',
481
- '86': '_',
482
- '87': 'v',
483
- '88': '"',
484
- '89': ':',
485
- '90': '0',
486
- '91': ',',
487
- '92': '"',
488
- '93': 'u',
489
- '94': 's',
490
- '95': 'e',
491
- '96': 'r',
492
- '97': 'n',
493
- '98': 'a',
494
- '99': 'm',
495
- '100': 'e',
496
- '101': '"',
497
- '102': ':',
498
- '103': '"',
499
- '104': 'I',
500
- '105': 't',
501
- '106': 'h',
502
- '107': 'a',
503
- '108': 'r',
504
- '109': 'e',
505
- '110': 'n',
506
- '111': '"',
507
- '112': ',',
508
- '113': '"',
509
- '114': 'p',
510
- '115': 'r',
511
- '116': 'e',
512
- '117': 'v',
513
- '118': 'i',
514
- '119': 'o',
515
- '120': 'u',
516
- '121': 's',
517
- '122': 'E',
518
- '123': 'm',
519
- '124': 'a',
520
- '125': 'i',
521
- '126': 'l',
522
- '127': 's',
523
- '128': '"',
524
- '129': ':',
525
- '130': '[',
526
- '131': ']',
527
- '132': ',',
528
- '133': '"',
529
- '134': 'p',
530
- '135': 'a',
531
- '136': 's',
532
- '137': 's',
533
- '138': 'w',
534
- '139': 'o',
535
- '140': 'r',
536
- '141': 'd',
537
- '142': '"',
538
- '143': ':',
539
- '144': '"',
540
- '145': 'a',
541
- '146': 's',
542
- '147': 'd',
543
- '148': 'a',
544
- '149': 's',
545
- '150': 'd',
546
- '151': '"',
547
- '152': ',',
548
- '153': '"',
549
- '154': 'r',
550
- '155': 'o',
551
- '156': 'l',
552
- '157': 'e',
553
- '158': 's',
554
- '159': '"',
555
- '160': ':',
556
- '161': '[',
557
- '162': ']',
558
- '163': ',',
559
- '164': '"',
560
- '165': 'p',
561
- '166': 'e',
562
- '167': 'r',
563
- '168': 'm',
564
- '169': 'i',
565
- '170': 's',
566
- '171': 's',
567
- '172': 'i',
568
- '173': 'o',
569
- '174': 'n',
570
- '175': 's',
571
- '176': '"',
572
- '177': ':',
573
- '178': '[',
574
- '179': ']',
575
- '180': ',',
576
- '181': '"',
577
- '182': 'a',
578
- '183': 'c',
579
- '184': 't',
580
- '185': 'i',
581
- '186': 'v',
582
- '187': 'e',
583
- '188': 'S',
584
- '189': 'u',
585
- '190': 'b',
586
- '191': 's',
587
- '192': 'c',
588
- '193': 'r',
589
- '194': 'i',
590
- '195': 'p',
591
- '196': 't',
592
- '197': 'i',
593
- '198': 'o',
594
- '199': 'n',
595
- '200': 's',
596
- '201': '"',
597
- '202': ':',
598
- '203': '[',
599
- '204': ']',
600
- '205': ',',
601
- '206': '"',
602
- '207': 'c',
603
- '208': 'l',
604
- '209': 'i',
605
- '210': 'e',
606
- '211': 'n',
607
- '212': 't',
608
- '213': 'U',
609
- '214': 's',
610
- '215': 'e',
611
- '216': 'r',
612
- '217': 'I',
613
- '218': 'd',
614
- '219': 's',
615
- '220': '"',
616
- '221': ':',
617
- '222': '{',
618
- '223': '}',
619
- '224': ',',
620
- '225': '"',
621
- '226': 'o',
622
- '227': 'a',
623
- '228': 'u',
624
- '229': 't',
625
- '230': 'h',
626
- '231': '2',
627
- '232': 'D',
628
- '233': 'a',
629
- '234': 't',
630
- '235': 'a',
631
- '236': '"',
632
- '237': ':',
633
- '238': '{',
634
- '239': '}',
635
- '240': '}'
636
- };
637
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(charByCharData, testKey);
638
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
639
- // Should be able to parse the decrypted data back to the original object
640
- expect(decrypted).toEqual(charByCharData);
641
- });
642
- });
643
- describe('| cross-environment consistency', () => {
644
- it('| should produce same encrypted output for same input across different environments', () => {
645
- const testData = {
646
- id: 1,
647
- name: 'test',
648
- timestamp: '2024-03-20T10:00:00Z'
649
- };
650
- const key = 'test-secret-key-123';
651
- // Simulate different environments by creating new instances
652
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
653
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(testData, key);
654
- expect(encrypted1).toBe(encrypted2);
655
- expect(crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key)).toEqual(testData);
656
- expect(crypto_util_1.DyFM_Crypto.decrypt(encrypted2, key)).toEqual(testData);
657
- });
658
- it('| should maintain encryption consistency with different data types', () => {
659
- const testCases = [
660
- { data: { id: 1 }, key: 'key1' },
661
- { data: 'string data', key: 'key2' },
662
- { data: [1, 2, 3], key: 'key3' },
663
- { data: { nested: { value: true } }, key: 'key4' }
664
- ];
665
- testCases.forEach(({ data, key }) => {
666
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(data, key);
667
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(data, key);
668
- expect(encrypted1).toBe(encrypted2);
669
- });
670
- });
671
- });
672
- describe('| database persistence', () => {
673
- it('| should successfully encrypt and decrypt data after database storage simulation', () => {
674
- const originalData = {
675
- id: 1,
676
- name: 'test user',
677
- email: 'test@example.com',
678
- settings: {
679
- theme: 'dark',
680
- notifications: true
681
- }
682
- };
683
- const key = 'db-storage-key';
684
- // Simulate database storage and retrieval
685
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(originalData, key);
686
- const storedData = encrypted; // Simulating database storage
687
- const retrievedData = storedData; // Simulating database retrieval
688
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(retrievedData, key);
689
- expect(decrypted).toEqual(originalData);
690
- });
691
- it('| should handle multiple encryption/decryption cycles for database operations', () => {
692
- const userData = {
693
- id: 1,
694
- name: 'test user',
695
- lastLogin: '2024-01-01T10:00:00.000Z',
696
- preferences: {
697
- language: 'en',
698
- timezone: 'UTC'
699
- }
700
- };
701
- const key = 'persistent-key';
702
- // Simulate multiple database operations
703
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(userData, key);
704
- const decrypted1 = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
705
- // Simulate data update with a different timestamp
706
- const updatedData = {
707
- ...decrypted1,
708
- lastLogin: '2024-01-02T15:30:00.000Z'
709
- };
710
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(updatedData, key);
711
- const decrypted2 = crypto_util_1.DyFM_Crypto.decrypt(encrypted2, key);
712
- expect(decrypted1).toEqual(userData);
713
- expect(decrypted2).toEqual(updatedData);
714
- expect(decrypted2.lastLogin).not.toBe(userData.lastLogin);
715
- });
716
- it('| should maintain data integrity through multiple database operations', () => {
717
- const sensitiveData = {
718
- id: 1,
719
- password: 'hashed-password-123',
720
- securityQuestions: [
721
- { question: 'What is your pet name?', answer: 'Fluffy' },
722
- { question: 'Where were you born?', answer: 'New York' }
723
- ]
724
- };
725
- const key = 'sensitive-data-key';
726
- // Simulate multiple database operations with the same data
727
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(sensitiveData, key);
728
- const decrypted1 = crypto_util_1.DyFM_Crypto.decrypt(encrypted1, key);
729
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(decrypted1, key);
730
- const decrypted2 = crypto_util_1.DyFM_Crypto.decrypt(encrypted2, key);
731
- expect(decrypted1).toEqual(sensitiveData);
732
- expect(decrypted2).toEqual(sensitiveData);
733
- expect(encrypted1).toBe(encrypted2); // Different encryption instances
734
- });
735
- });
736
- describe('| special characters', () => {
737
- it('| should handle Unicode characters', () => {
738
- const unicodeData = {
739
- text: 'Hello 世界! 🌍',
740
- emoji: '👋',
741
- special: '!!!@@@###$$$%%%^^^&&&***((()))___+++---===[[[]]]{{{}}}|||;;;:::,,,...<<<>>>' +
742
- 'ĐĐĐđđđßßߤ¤¤×××÷÷÷¨¨¨¨~~~ˇˇˇ^^^˘˘˘°°°˛˛˛```˙˙˙´´´˝˝˝˝¸¸¸§§§' +
743
- '???ééééáááűűűúúúőőőóóóüüüöööíííÉÉÉÁÁÁŰŰŰÚÚÚŐŐŐÓÓÓÜÖÖÖÍÍÍ'
744
- };
745
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(unicodeData, testKey);
746
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
747
- expect(decrypted).toEqual(unicodeData);
748
- });
749
- it('| should handle special characters in object keys', () => {
750
- const specialKeyData = {
751
- 'key-with-spaces': 'value',
752
- 'key.with.dots': 'value',
753
- 'key-with-special-chars!@#': 'value',
754
- 'key-with-unicode-世界': 'value'
755
- };
756
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(specialKeyData, testKey);
757
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
758
- expect(decrypted).toEqual(specialKeyData);
759
- });
760
- it('| should handle special characters in nested objects', () => {
761
- const nestedData = {
762
- level1: {
763
- 'special-key!@#': {
764
- 'nested-key-世界': 'value with special chars!@#'
765
- }
766
- }
767
- };
768
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(nestedData, testKey);
769
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
770
- expect(decrypted).toEqual(nestedData);
771
- });
772
- it('| should handle special characters in arrays', () => {
773
- const arrayData = [
774
- 'Hello 世界!',
775
- { 'special-key': 'value with !@#' },
776
- ['nested', 'array', 'with', 'special', 'chars!@#']
777
- ];
778
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(arrayData, testKey);
779
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, testKey);
780
- expect(decrypted).toEqual(arrayData);
781
- });
782
- });
783
- });
784
- describe('| TIME MANIPULATION TESTS - Cross-temporal consistency', () => {
785
- const testKey = 'time-test-key-456';
786
- const testData = {
787
- id: 123,
788
- name: 'time-test',
789
- timestamp: new Date().toISOString(),
790
- nested: { value: 'time-dependent-test' }
791
- };
792
- let originalDateNow;
793
- let originalDateConstructor;
794
- beforeEach(() => {
795
- // Store original Date functions
796
- originalDateNow = Date.now;
797
- originalDateConstructor = Date;
798
- });
799
- afterEach(() => {
800
- // Restore original Date functions
801
- Date.now = originalDateNow;
802
- global.Date = originalDateConstructor;
803
- });
804
- it('| should produce identical encrypted output regardless of system time', () => {
805
- const baseTime = 1609459200000; // 2021-01-01 00:00:00 UTC
806
- // Mock Date.now to return fixed time
807
- Date.now = jasmine.createSpy('Date.now').and.returnValue(baseTime);
808
- // Mock Date constructor to return fixed date
809
- global.Date = jasmine.createSpy('Date').and.callFake((args) => {
810
- if (!args) {
811
- return new originalDateConstructor(baseTime);
812
- }
813
- return new originalDateConstructor(args);
814
- });
815
- const encrypted1 = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
816
- const encrypted2 = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
817
- expect(encrypted1).toEqual(encrypted2);
818
- expect(encrypted1).toBeDefined();
819
- });
820
- it('| should maintain consistency across different time zones', () => {
821
- const timeZones = [
822
- 0, // UTC
823
- -5, // EST
824
- 1, // CET
825
- 9, // JST
826
- -8, // PST
827
- 5.5 // IST
828
- ];
829
- const results = [];
830
- timeZones.forEach(offset => {
831
- const baseTime = 1609459200000 + (offset * 3600000); // Adjust for timezone
832
- Date.now = jasmine.createSpy('Date.now').and.returnValue(baseTime);
833
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
834
- results.push(encrypted);
835
- });
836
- // All results should be identical regardless of timezone
837
- const firstResult = results[0];
838
- results.forEach(result => {
839
- expect(result).toEqual(firstResult);
840
- });
841
- });
842
- it('| should handle time-based data consistently', () => {
843
- const timeBasedData = {
844
- createdAt: new Date('2023-01-01T00:00:00Z'),
845
- updatedAt: new Date('2023-12-31T23:59:59Z'),
846
- timestamp: Date.now(),
847
- timeString: new Date().toISOString()
848
- };
849
- // Test with different system times
850
- const times = [
851
- 1609459200000, // 2021-01-01
852
- 1640995200000, // 2022-01-01
853
- 1672531200000, // 2023-01-01
854
- 1704067200000 // 2024-01-01
855
- ];
856
- const results = [];
857
- times.forEach(time => {
858
- Date.now = jasmine.createSpy('Date.now').and.returnValue(time);
859
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(timeBasedData, testKey);
860
- results.push(encrypted);
861
- });
862
- // All results should be identical
863
- const firstResult = results[0];
864
- results.forEach(result => {
865
- expect(result).toEqual(firstResult);
866
- });
867
- });
868
- it('| should maintain consistency across date boundaries', () => {
869
- const boundaryTimes = [
870
- 1609459200000, // 2021-01-01 00:00:00
871
- 1609459259999, // 2021-01-01 00:00:59
872
- 1609459260000, // 2021-01-01 00:01:00
873
- 1609545600000, // 2021-01-02 00:00:00
874
- 1609632000000, // 2021-01-03 00:00:00
875
- 1640995200000, // 2022-01-01 00:00:00
876
- 1672531200000 // 2023-01-01 00:00:00
877
- ];
878
- const results = [];
879
- boundaryTimes.forEach(time => {
880
- Date.now = jasmine.createSpy('Date.now').and.returnValue(time);
881
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
882
- results.push(encrypted);
883
- });
884
- // All results should be identical
885
- const firstResult = results[0];
886
- results.forEach(result => {
887
- expect(result).toEqual(firstResult);
888
- });
889
- });
890
- it('| should handle leap year transitions consistently', () => {
891
- const leapYearTimes = [
892
- 1609459200000, // 2021-01-01 (not leap year)
893
- 1640995200000, // 2022-01-01 (not leap year)
894
- 1672531200000, // 2023-01-01 (not leap year)
895
- 1704067200000, // 2024-01-01 (leap year)
896
- 1735689600000, // 2025-01-01 (not leap year)
897
- 1735689600000 + (365 * 24 * 60 * 60 * 1000), // 2025-12-31
898
- 1735689600000 + (366 * 24 * 60 * 60 * 1000) // 2026-01-01
899
- ];
900
- const results = [];
901
- leapYearTimes.forEach(time => {
902
- Date.now = jasmine.createSpy('Date.now').and.returnValue(time);
903
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
904
- results.push(encrypted);
905
- });
906
- // All results should be identical
907
- const firstResult = results[0];
908
- results.forEach(result => {
909
- expect(result).toEqual(firstResult);
910
- });
911
- });
912
- it('| should maintain consistency across daylight saving time transitions', () => {
913
- // DST transition times (approximate)
914
- const dstTimes = [
915
- 1615708800000, // 2021-03-14 (DST start)
916
- 1615712400000, // 2021-03-14 01:00 (DST start + 1 hour)
917
- 1636243200000, // 2021-11-07 (DST end)
918
- 1636246800000, // 2021-11-07 01:00 (DST end + 1 hour)
919
- 1648339200000, // 2022-03-13 (DST start)
920
- 1648342800000, // 2022-03-13 01:00 (DST start + 1 hour)
921
- 1668816000000, // 2022-11-06 (DST end)
922
- 1668819600000 // 2022-11-06 01:00 (DST end + 1 hour)
923
- ];
924
- const results = [];
925
- dstTimes.forEach(time => {
926
- Date.now = jasmine.createSpy('Date.now').and.returnValue(time);
927
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
928
- results.push(encrypted);
929
- });
930
- // All results should be identical
931
- const firstResult = results[0];
932
- results.forEach(result => {
933
- expect(result).toEqual(firstResult);
934
- });
935
- });
936
- it('| should handle microsecond precision consistently', () => {
937
- const baseTime = 1609459200000;
938
- const microsecondOffsets = [
939
- 0,
940
- 1,
941
- 10,
942
- 100,
943
- 1000,
944
- 10000,
945
- 100000,
946
- 999999
947
- ];
948
- const results = [];
949
- microsecondOffsets.forEach(offset => {
950
- const time = baseTime + offset;
951
- Date.now = jasmine.createSpy('Date.now').and.returnValue(time);
952
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
953
- results.push(encrypted);
954
- });
955
- // All results should be identical
956
- const firstResult = results[0];
957
- results.forEach(result => {
958
- expect(result).toEqual(firstResult);
959
- });
960
- });
961
- it('| should maintain consistency across different Date object states', () => {
962
- const testDataWithDates = {
963
- date1: new Date('2023-01-01'),
964
- date2: new Date('2023-12-31'),
965
- date3: new Date(),
966
- date4: new Date(0), // Unix epoch
967
- date5: new Date(8640000000000000), // Max safe date
968
- date6: new Date(-8640000000000000) // Min safe date
969
- };
970
- const results = [];
971
- // Test with different system times
972
- const systemTimes = [1609459200000, 1640995200000, 1672531200000];
973
- systemTimes.forEach(systemTime => {
974
- Date.now = jasmine.createSpy('Date.now').and.returnValue(systemTime);
975
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testDataWithDates, testKey);
976
- results.push(encrypted);
977
- });
978
- // All results should be identical
979
- const firstResult = results[0];
980
- results.forEach(result => {
981
- expect(result).toEqual(firstResult);
982
- });
983
- });
984
- it('| should handle time-based encryption/decryption cycles consistently', () => {
985
- const cycles = 10;
986
- const results = [];
987
- for (let i = 0; i < cycles; i++) {
988
- // Simulate different system times
989
- const time = 1609459200000 + (i * 86400000); // Add 1 day each cycle
990
- Date.now = jasmine.createSpy('Date.now').and.returnValue(time);
991
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
992
- results.push(encrypted);
993
- }
994
- // All results should be identical
995
- const firstResult = results[0];
996
- results.forEach(result => {
997
- expect(result).toEqual(firstResult);
998
- });
999
- });
1000
- it('| should maintain consistency with real-world time scenarios', () => {
1001
- const realWorldScenarios = [
1002
- { name: 'New Year 2021', time: 1609459200000 },
1003
- { name: 'Leap Day 2020', time: 1583020800000 },
1004
- { name: 'DST Start 2021', time: 1615708800000 },
1005
- { name: 'DST End 2021', time: 1636243200000 },
1006
- { name: 'Midnight UTC', time: 1609459200000 },
1007
- { name: 'Noon UTC', time: 1609459200000 + (12 * 3600000) },
1008
- { name: 'End of Day', time: 1609459200000 + (23 * 3600000) + (59 * 60000) + (59 * 1000) }
1009
- ];
1010
- const results = [];
1011
- realWorldScenarios.forEach(scenario => {
1012
- Date.now = jasmine.createSpy('Date.now').and.returnValue(scenario.time);
1013
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(testData, testKey);
1014
- results.push(encrypted);
1015
- });
1016
- // All results should be identical
1017
- const firstResult = results[0];
1018
- results.forEach((result, index) => {
1019
- expect(result).toEqual(firstResult);
1020
- });
1021
- });
1022
- });
1023
- describe('| ERROR HANDLING TESTS - Comprehensive validation', () => {
1024
- const validKey = 'valid-test-key-123';
1025
- const validData = { id: 1, name: 'test' };
1026
- describe('| Encryption Error Cases', () => {
1027
- it('| should throw descriptive error when encrypting undefined data', () => {
1028
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(undefined, validKey)).toThrow();
1029
- });
1030
- it('| should throw descriptive error when encrypting null data', () => {
1031
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(null, validKey)).toThrow();
1032
- });
1033
- it('| should throw descriptive error when encrypting empty string', () => {
1034
- expect(() => crypto_util_1.DyFM_Crypto.encrypt('', validKey)).toThrow();
1035
- });
1036
- it('| should allow empty object for backward compatibility', () => {
1037
- expect(() => crypto_util_1.DyFM_Crypto.encrypt({}, validKey)).not.toThrow();
1038
- });
1039
- it('| should allow empty array for backward compatibility', () => {
1040
- expect(() => crypto_util_1.DyFM_Crypto.encrypt([], validKey)).not.toThrow();
1041
- });
1042
- it('| should throw descriptive error when key is missing', () => {
1043
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(validData, undefined)).toThrow();
1044
- });
1045
- it('| should throw descriptive error when key is null', () => {
1046
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(validData, null)).toThrow();
1047
- });
1048
- it('| should throw descriptive error when key is not a string', () => {
1049
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(validData, 123)).toThrow();
1050
- });
1051
- it('| should throw descriptive error when key is empty string', () => {
1052
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(validData, '')).toThrow();
1053
- });
1054
- it('| should throw descriptive error when key is only whitespace', () => {
1055
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(validData, ' ')).toThrow();
1056
- });
1057
- it('| should warn about short keys but still work', () => {
1058
- // This test just ensures encryption works with short keys
1059
- // Note: Warning is shown in console but spy might not catch it in test environment
1060
- expect(() => crypto_util_1.DyFM_Crypto.encrypt(validData, 'short')).not.toThrow();
1061
- });
1062
- });
1063
- describe('| Decryption Error Cases', () => {
1064
- it('| should throw descriptive error when decrypting undefined data', () => {
1065
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(undefined, validKey)).toThrow();
1066
- });
1067
- it('| should throw descriptive error when decrypting null data', () => {
1068
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(null, validKey)).toThrow();
1069
- });
1070
- it('| should throw descriptive error when decrypting non-string data', () => {
1071
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(123, validKey)).toThrow();
1072
- });
1073
- it('| should throw descriptive error when decrypting empty string', () => {
1074
- expect(() => crypto_util_1.DyFM_Crypto.decrypt('', validKey)).toThrow();
1075
- });
1076
- it('| should throw descriptive error when decrypting too short data', () => {
1077
- expect(() => crypto_util_1.DyFM_Crypto.decrypt('short', validKey)).toThrow();
1078
- });
1079
- it('| should throw descriptive error when decrypting invalid format', () => {
1080
- expect(() => crypto_util_1.DyFM_Crypto.decrypt('invalid!@#format', validKey)).toThrow();
1081
- });
1082
- it('| should throw descriptive error when key is missing for decryption', () => {
1083
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, validKey);
1084
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(encrypted, undefined)).toThrow();
1085
- });
1086
- it('| should throw descriptive error when key is wrong type for decryption', () => {
1087
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, validKey);
1088
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(encrypted, 123)).toThrow();
1089
- });
1090
- it('| should throw descriptive error when key is empty for decryption', () => {
1091
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, validKey);
1092
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(encrypted, '')).toThrow();
1093
- });
1094
- it('| should handle decryption with proper key validation', () => {
1095
- // Test that decryption works with valid key
1096
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, validKey);
1097
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(encrypted, validKey)).not.toThrow();
1098
- });
1099
- });
1100
- describe('| Decryption Failure Scenarios', () => {
1101
- it('| should throw descriptive error when decrypting with wrong key', () => {
1102
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, validKey);
1103
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(encrypted, 'wrong-key-123')).toThrow();
1104
- });
1105
- it('| should throw descriptive error when decrypting corrupted data', () => {
1106
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, validKey);
1107
- const corrupted = encrypted.substring(0, encrypted.length - 10); // Remove last 10 characters
1108
- expect(() => crypto_util_1.DyFM_Crypto.decrypt(corrupted, validKey)).toThrow();
1109
- });
1110
- it('| should throw descriptive error when decrypting invalid base64', () => {
1111
- expect(() => crypto_util_1.DyFM_Crypto.decrypt('invalid-base64!@#', validKey)).toThrow();
1112
- });
1113
- it('| should throw descriptive error when decrypting completely wrong data', () => {
1114
- expect(() => crypto_util_1.DyFM_Crypto.decrypt('this-is-not-encrypted-data', validKey)).toThrow();
1115
- });
1116
- });
1117
- describe('| Edge Case Validations', () => {
1118
- it('| should allow valid data with minimum key length', () => {
1119
- const shortKey = '12345678'; // 8 characters minimum
1120
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, shortKey);
1121
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, shortKey);
1122
- expect(decrypted).toEqual(validData);
1123
- });
1124
- it('| should allow valid data with whitespace in key', () => {
1125
- const keyWithSpaces = ' valid-key-123 ';
1126
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(validData, keyWithSpaces);
1127
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, keyWithSpaces);
1128
- expect(decrypted).toEqual(validData);
1129
- });
1130
- it('| should handle special characters in data', () => {
1131
- const specialData = {
1132
- special: '!@#$%^&*()_+-=[]{}|;:,.<>?',
1133
- unicode: '世界你好',
1134
- emoji: '🚀💻🔐'
1135
- };
1136
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(specialData, validKey);
1137
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, validKey);
1138
- expect(decrypted).toEqual(specialData);
1139
- });
1140
- it('| should handle very long data', () => {
1141
- const longData = {
1142
- text: 'A'.repeat(10000),
1143
- array: Array(1000).fill(0).map((_, i) => i),
1144
- nested: {
1145
- level1: { level2: { level3: { data: 'deep nested data' } } }
1146
- }
1147
- };
1148
- const encrypted = crypto_util_1.DyFM_Crypto.encrypt(longData, validKey);
1149
- const decrypted = crypto_util_1.DyFM_Crypto.decrypt(encrypted, validKey);
1150
- expect(decrypted).toEqual(longData);
1151
- });
1152
- });
1153
- describe('| Error Code Validation', () => {
1154
- it('| should have specific error codes for different failure types', () => {
1155
- try {
1156
- crypto_util_1.DyFM_Crypto.encrypt(undefined, validKey);
1157
- fail('Should have thrown an error');
1158
- }
1159
- catch (error) {
1160
- expect(error._errorCode).toBe('DyFM-CRY-DATA-UNDEFINED');
1161
- }
1162
- try {
1163
- crypto_util_1.DyFM_Crypto.encrypt(validData, '');
1164
- fail('Should have thrown an error');
1165
- }
1166
- catch (error) {
1167
- expect(error._errorCode).toBe('DyFM-CRY-KEY-MISSING');
1168
- }
1169
- try {
1170
- crypto_util_1.DyFM_Crypto.decrypt('', validKey);
1171
- fail('Should have thrown an error');
1172
- }
1173
- catch (error) {
1174
- expect(error._errorCode).toBe('DyFM-CRY-ENCRYPTED-EMPTY');
1175
- }
1176
- });
1177
- });
1178
- });
1179
- });
1180
- //# sourceMappingURL=crypto.util.spec.js.map