data-primals-engine 1.3.0 → 1.3.1

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.
@@ -1,6 +1,6 @@
1
1
  // __tests__/data.integration.test.js
2
2
  import { ObjectId } from 'mongodb';
3
- import {vi, expect, describe, it, beforeEach, beforeAll, afterAll} from 'vitest';
3
+ import {vi, expect, describe, it, afterEach,beforeEach, beforeAll, afterAll} from 'vitest';
4
4
  import { Config } from '../src/config.js';
5
5
  import {
6
6
  insertData,
@@ -16,6 +16,7 @@ import {
16
16
  } from '../src/modules/mongodb.js';
17
17
  import {getRandom} from "../src/core.js";
18
18
  import {generateUniqueName, initEngine} from "../src/setenv.js";
19
+ import {purgeData} from "../src/modules/data/data.history.js";
19
20
 
20
21
  let testModelsColInstance;
21
22
  let testDatasColInstance;
@@ -29,7 +30,7 @@ async function setupTestContext() {
29
30
  // Créer un utilisateur unique pour ce test
30
31
  const currentTestUser = {
31
32
  username: generateUniqueName('testuserDataIntegration'),
32
- userPlan: 'free',
33
+ userPlan: 'premium',
33
34
  email: generateUniqueName('test') + '@example.com'
34
35
  };
35
36
 
@@ -111,11 +112,16 @@ async function setupTestContext() {
111
112
  }
112
113
  await testDatasColInstance.deleteMany({ _user: currentTestUser.username });
113
114
 
115
+ const purge = async ()=>{
116
+ await purgeData(currentTestUser);
117
+ }
118
+
114
119
  // Retourner toutes les variables nécessaires pour un test
115
120
  return {
116
121
  currentTestUser,
117
122
  comprehensiveTestModelDefinition,
118
- relatedModelDefinition
123
+ relatedModelDefinition,
124
+ purge
119
125
  };
120
126
  }
121
127
 
@@ -127,11 +133,10 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
127
133
  engine = await initEngine();
128
134
 
129
135
  })
130
-
131
136
  describe('insertData avec comprehensiveTestModel', () => {
132
137
  it('devrait insérer des données valides pour tous les types de champs', async () => {
133
138
 
134
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
139
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
135
140
  // 1. Créer un suffixe unique pour cette exécution de test
136
141
  const testSuffix = getRandom(1000, 9999); // Génère un nombre aléatoire
137
142
 
@@ -197,125 +202,143 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
197
202
  expect(new Date(insertedDoc.datetimeField).getFullYear()).toBe(new Date().getFullYear());
198
203
  expect(insertedDoc.booleanDefault).toBe(true);
199
204
  expect(insertedDoc.relationSingle.toString()).toBe(relatedDoc1.insertedIds[0].toString());
205
+
206
+ await purge();
200
207
  }, 10000);
201
208
 
202
209
  describe('Validations des champs à l\'insertion', () => {
203
210
  // --- STRING VALIDATIONS ---
204
211
  it('devrait rejeter un string requis non fourni', async () => {
205
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
212
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
206
213
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringUnique: 'test' /* stringRequired manquant */ }, {}, currentTestUser, false);
207
214
  expect(result.success).toBe(false);
208
215
  expect(result.error).toContain('stringRequired');
216
+ await purge();
209
217
  });
210
218
 
211
219
  it('devrait rejeter un string trop long pour maxlength', async () => {
212
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
220
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
213
221
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', stringMaxLength: '123456' }, {}, currentTestUser, false);
214
222
  expect(result.success).toBe(false);
215
223
  expect(result.error).toContain('stringMaxLength');
224
+ await purge();
216
225
  });
217
226
 
218
227
  it('devrait rejeter une valeur dupliquée pour un champ unique (stringUnique)', async () => {
219
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
228
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
220
229
  await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req1', stringUnique: 'duplicateMe', 'passwordField': 'pass', number: 1, enumField: 'test' }, {}, currentTestUser, false);
221
230
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req2', stringUnique: 'duplicateMe', 'passwordField': 'pass', number: 1, enumField: 'test' }, {}, currentTestUser, false);
222
231
  expect(result.success).toBe(false);
232
+ await purge();
223
233
  });
224
234
 
225
235
  // --- NUMBER VALIDATIONS ---
226
236
  it('devrait rejeter un number non numérique', async () => {
227
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
237
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
228
238
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', number: 'not-a-number' }, {}, currentTestUser, false);
229
239
  expect(result.success).toBe(false);
230
240
  expect(result.error).toContain('number');
241
+ await purge();
231
242
  });
232
243
 
233
244
  it('devrait rejeter un number infur à min (numberMinMax)', async () => {
234
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
245
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
235
246
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', numberMinMax: 5 }, {}, currentTestUser, false);
236
247
  expect(result.success).toBe(false);
237
248
  expect(result.error).toContain('numberMinMax');
249
+ await purge();
238
250
  });
239
251
 
240
252
  it('devrait rejeter un number supérieur à max (numberMinMax)', async () => {
241
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
253
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
242
254
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', numberMinMax: 25 }, {}, currentTestUser, false);
243
255
  expect(result.success).toBe(false);
244
256
  expect(result.error).toContain('numberMinMax');
257
+ await purge();
245
258
  });
246
259
 
247
260
  // --- ARRAY VALIDATIONS ---
248
261
  it('devrait rejeter un array avec trop d\'items (arrayString maxItems: 2)', async () => {
249
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
262
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
250
263
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', arrayString: ['a', 'b', 'c'] }, {}, currentTestUser, false);
251
264
  expect(result.success).toBe(false);
252
265
  expect(result.error).toContain('arrayString');
266
+ await purge();
253
267
  });
254
268
 
255
269
  it('devrait rejeter un array avec pas assez d\'items (arrayNumber minItems: 1)', async () => {
256
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
270
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
257
271
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', arrayNumber: [] }, {}, currentTestUser, false);
258
272
  expect(result.success).toBe(false);
259
273
  expect(result.error).toContain('arrayNumber');
274
+ await purge();
260
275
  });
261
276
 
262
277
  it('devrait rejeter un array avec un item de type incorrect (arrayNumber)', async () => {
263
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
278
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
264
279
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', arrayNumber: [1, 'not-a-number', 3] }, {}, currentTestUser, false);
265
280
  expect(result.success).toBe(false);
266
281
  expect(result.error).toContain('arrayNumber');
282
+ await purge();
267
283
  });
268
284
 
269
285
  // --- FILE VALIDATIONS (metadata) ---
270
286
  it('devrait rejeter un file avec un mimeType non autorisé', async () => {
271
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
287
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
272
288
  const mockFile = { name: 'test.txt', type: 'text/plain', size: 1024, guid: 'dummy-txt' };
273
289
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', fileField: mockFile }, {}, currentTestUser, false);
274
290
  expect(result.success).toBe(false);
275
291
  expect(result.error).toContain('image/png'); // Ou un message plus spécifique sur mimeTypes
276
292
  expect(result.error).toContain('text/plain'); // Ou un message plus spécifique sur mimeTypes
293
+ await purge();
277
294
  });
278
295
 
279
296
  it('devrait rejeter un file avec une taille supérieure à maxSize', async () => {
280
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
297
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
281
298
  const mockFile = { name: 'large.png', type: 'image/png', size: 1024 * 15, guid: 'dummy-large' }; // 15KB > 10KB
282
299
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', fileField: mockFile }, {}, currentTestUser, false);
283
300
  expect(result.success).toBe(false);
284
301
  expect(result.error).toContain('fileField'); // Ou un message plus spécifique sur maxSize
302
+ await purge();
285
303
  });
286
304
 
287
305
  // --- EMAIL, URL, PHONE, COLOR (basic format) ---
288
306
  it('devrait rejeter un email invalide', async () => {
289
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
307
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
290
308
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', emailField: 'not-an-email' }, {}, currentTestUser, false);
291
309
  expect(result.success).toBe(false);
292
310
  expect(result.error).toContain('emailField');
311
+ await purge();
293
312
  });
294
313
  it('devrait rejeter une URL invalide', async () => {
295
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
314
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
296
315
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', urlField: 'not a url' }, {}, currentTestUser, false);
297
316
  expect(result.success).toBe(false);
298
317
  expect(result.error).toContain('urlField');
318
+ await purge();
299
319
  });
300
320
  it('devrait rejeter une couleur invalide', async () => {
301
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
321
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
302
322
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', colorField: '#GGHHII' }, {}, currentTestUser, false);
303
323
  expect(result.success).toBe(false);
304
324
  expect(result.error).toContain('colorField');
325
+ await purge();
305
326
  });
306
327
 
307
328
  // --- DATE / DATETIME VALIDATIONS ---
308
329
  it('devrait rejeter une date invalide (format)', async () => {
309
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
330
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
310
331
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', dateField: 'not-a-date' }, {}, currentTestUser, false);
311
332
  expect(result.success).toBe(false);
312
333
  expect(result.error).toContain('dateField');
334
+ await purge();
313
335
  });
314
336
  it('devrait rejeter une date en dehors de min/max (dateMinMax)', async () => {
315
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
337
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
316
338
  const result = await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'req', dateMinMax: '2024-01-01' }, {}, currentTestUser, false);
317
339
  expect(result.success).toBe(false);
318
340
  expect(result.error).toContain('dateMinMax');
341
+ await purge();
319
342
  });
320
343
 
321
344
  // TODO: Ajouter des tests pour les autres types et contraintes (password, richtext, code, object, model, modelField)
@@ -326,7 +349,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
326
349
  // --- NOUVEAU TEST POUR $find ---
327
350
  it('devrait insérer des données avec des relations référencées par $find', async () => {
328
351
  // 1. Insérer les documents liés qui seront trouvés par $find
329
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
352
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
330
353
  const relatedDocA = await insertData(relatedModelDefinition.name, { relatedName: 'FindMeA', relatedValue: 111 }, {}, currentTestUser, false);
331
354
  const relatedDocB = await insertData(relatedModelDefinition.name, { relatedName: 'FindMeB', relatedValue: 222 }, {}, currentTestUser, false);
332
355
  const relatedDocC = await insertData(relatedModelDefinition.name, { relatedName: 'FindMeC', relatedValue: 222 }, {}, currentTestUser, false);
@@ -389,6 +412,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
389
412
  expect(insertedDoc.stringRequired).toBe('DocWithFind');
390
413
  expect(insertedDoc.enumField).toBe('beta');
391
414
 
415
+ await purge();
392
416
  }, 10000); // Augmenter le timeout si nécessaire
393
417
  });
394
418
 
@@ -397,7 +421,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
397
421
  let relatedDocId;
398
422
 
399
423
  const initTest = async () => {
400
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
424
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
401
425
  // Insert a base document and a related document to be used in edit tests
402
426
  const relatedInsert = await insertData(relatedModelDefinition.name, { relatedName: 'RelForEdit', relatedValue: 50 }, {}, currentTestUser, false);
403
427
  relatedDocId = relatedInsert.insertedIds[0];
@@ -412,10 +436,10 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
412
436
  const insertResult = await insertData(comprehensiveTestModelDefinition.name, initialData, {}, currentTestUser, false);
413
437
  docToEditId = insertResult.insertedIds[0];
414
438
 
415
- return { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition };
439
+ return { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge };
416
440
  };
417
441
  it('devrait modifier des données valides', async () => {
418
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
442
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
419
443
  const dataToEdit = { stringRequired: 'Edited String', numberMinMax: 12 };
420
444
  const result = await editData(comprehensiveTestModelDefinition.name, docToEditId, dataToEdit, {}, currentTestUser);
421
445
 
@@ -425,24 +449,29 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
425
449
  const editedDoc = await testDatasColInstance.findOne({ _id: new ObjectId(docToEditId) });
426
450
  expect(editedDoc.stringRequired).toBe('Edited String');
427
451
  expect(editedDoc.numberMinMax).toBe(12);
452
+
453
+ await purge();
428
454
  });
429
455
 
430
456
  it('devrait rejeter une modification avec un string requis vide', async () => {
431
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
457
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
432
458
  const result = await editData(comprehensiveTestModelDefinition.name, docToEditId, { stringRequired: '' }, {}, currentTestUser);
433
459
  expect(result.success).toBe(false);
434
460
  expect(result.error).toContain('stringRequired');
461
+
462
+ await purge();
435
463
  });
436
464
 
437
465
  it('devrait rejeter une modification avec un number hors des bornes (numberMinMax)', async () => {
438
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
466
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
439
467
  const result = await editData(comprehensiveTestModelDefinition.name, docToEditId, { stringRequired: 'test', numberMinMax: 50 }, {}, currentTestUser);
440
468
  expect(result.success).toBe(false);
441
469
  expect(result.error).toContain('numberMinMax');
470
+ await purge();
442
471
  });
443
472
 
444
473
  it('devrait rejeter une modification qui viole une contrainte unique (stringUnique)', async ({skip}) => {
445
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
474
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
446
475
  // Insert another doc to create the unique conflict
447
476
 
448
477
  await insertData(comprehensiveTestModelDefinition.name, { stringRequired: 'Other', stringUnique: 'UniqueValue', enumField: 'beta', passwordField: 'pass' }, {}, currentTestUser, false);
@@ -453,6 +482,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
453
482
  expect(result.success).toBe(false);
454
483
  expect(result.error).toContain('UniqueValue');
455
484
  expect(result.error).toContain('stringUnique');
485
+ await purge();
456
486
  });
457
487
 
458
488
  // TODO: Ajouter plus de tests de validation pour editData, similaires à ceux de insertData
@@ -461,7 +491,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
461
491
  // --- Tests deleteData (repris de votre exemple, peuvent être gardés tels quels ou adaptés) ---
462
492
  describe('deleteData (tests existants)', () => {
463
493
  it('supprimer des données par ID (deleteData)', async () => {
464
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
494
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
465
495
  const dataToDelete = { name: 'Objet à supprimer', value: 300 };
466
496
  // Utiliser le modèle simple pour ces tests delete pour ne pas avoir à remplir tous les champs requis de comprehensive
467
497
  const simpleModel = { name: 'simpleDeleteModel', _user: currentTestUser.username, description: '', fields: [{ name: 'name', type: 'string' }, { name: 'value', type: 'number' }] };
@@ -477,10 +507,12 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
477
507
 
478
508
  const deletedDoc = await testDatasColInstance.findOne({ _id: new ObjectId(docId) });
479
509
  expect(deletedDoc).toBeNull();
510
+ await purge();
511
+ await purge();
480
512
  });
481
513
 
482
514
  it('supprimer des données par filtre (deleteData)', async () => {
483
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
515
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
484
516
  const simpleModel = { name: 'deleteModelTest', _user: currentTestUser.username, description: '',fields: [{ name: 'name', type: 'string' }, { name: 'value', type: 'number' }] };
485
517
  await testModelsColInstance.insertOne(simpleModel);
486
518
 
@@ -501,6 +533,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
501
533
  expect(remainingCount).toBe(0);
502
534
  const totalRemaining = await testDatasColInstance.countDocuments({ _user: currentTestUser.username, _model: simpleModel.name });
503
535
  expect(totalRemaining).toBe(1);
536
+ await purge();
504
537
  });
505
538
  });
506
539
 
@@ -509,7 +542,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
509
542
  let relatedDocId_A1, relatedDocId_A2, relatedDocId_B1;
510
543
 
511
544
  const initTest =async () => {
512
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
545
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
513
546
 
514
547
  // Insérer des documents liés
515
548
  const relA1 = await insertData(relatedModelDefinition.name, { relatedName: 'Rel_Search_A1', relatedValue: 101 }, {}, currentTestUser, false);
@@ -544,11 +577,11 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
544
577
  const insertResult2 = await insertData(comprehensiveTestModelDefinition.name, data2, {}, currentTestUser, false);
545
578
  docId2 = insertResult2.insertedIds[0].toString();
546
579
 
547
- return { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition };
580
+ return { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge };
548
581
  };
549
582
 
550
583
  it('devrait trouver un document par une condition sur une relation simple ($find)', async () => {
551
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
584
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
552
585
  const searchParams = {
553
586
  model: comprehensiveTestModelDefinition.name,
554
587
  filter: {
@@ -566,10 +599,11 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
566
599
  // Vérifier que la relation est bien populée si depth > 0
567
600
  expect(data[0].relationSingle).toBeInstanceOf(Object);
568
601
  expect(data[0].relationSingle.relatedName).toBe('Rel_Search_A1');
602
+ await purge();
569
603
  });
570
604
 
571
605
  it('ne devrait pas trouver de document si la condition $find sur relation simple ne correspond pas', async () => {
572
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
606
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
573
607
  const searchParams = {
574
608
  model: comprehensiveTestModelDefinition.name,
575
609
  filter: {
@@ -582,10 +616,11 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
582
616
  const { data, count } = await searchData(searchParams, currentTestUser);
583
617
  expect(count).toBe(0);
584
618
  expect(data).toHaveLength(0);
619
+ await purge();
585
620
  });
586
621
 
587
622
  it('devrait trouver des documents par une condition sur une relation multiple ($find)', async () => {
588
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
623
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
589
624
  const searchParams = {
590
625
  model: comprehensiveTestModelDefinition.name,
591
626
  filter: {
@@ -604,11 +639,12 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
604
639
  // Note: searchData with depth > 0 will populate the relationMultiple array
605
640
  expect(data[0].relationMultiple).toBeInstanceOf(Array);
606
641
  expect(data[0].relationMultiple.some(rel => rel.relatedValue === 102)).toBe(true);
642
+ await purge();
607
643
  });
608
644
 
609
645
 
610
646
  it('devrait trouver des documents en combinant un filtre normal et un filtre $find', async () => {
611
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
647
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
612
648
  const searchParams = {
613
649
  model: comprehensiveTestModelDefinition.name,
614
650
  filter: {
@@ -623,10 +659,11 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
623
659
  expect(count).toBe(1);
624
660
  expect(data).toHaveLength(1);
625
661
  expect(data[0]._id.toString()).toBe(docId1.toString());
662
+ await purge();
626
663
  });
627
664
 
628
665
  it('devrait retourner un tableau vide si $find ne correspond à aucun document lié', async () => {
629
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
666
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await initTest();
630
667
  const searchParams = {
631
668
  model: comprehensiveTestModelDefinition.name,
632
669
  filter: {
@@ -639,6 +676,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
639
676
  const { data, count } = await searchData(searchParams,currentTestUser);
640
677
  expect(count).toBe(0);
641
678
  expect(data).toHaveLength(0);
679
+ await purge();
642
680
  });
643
681
 
644
682
  });
@@ -658,7 +696,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
658
696
  });
659
697
 
660
698
  it('devrait installer un pack, créer les modèles et insérer les données avec relations via $link', async () => {
661
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
699
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
662
700
  // 1. Définir le pack de données mock
663
701
  const mockPack = {
664
702
  name: 'test-pack-for-install',
@@ -729,10 +767,11 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
729
767
  const playerTwo = insertedUsers.find(u => u.username === 'playerTwo');
730
768
  const shield = insertedItems.find(i => i.itemName === 'Shield');
731
769
  expect(shield.owner.toString()).toBe(playerTwo._id.toString());
770
+ await purge();
732
771
  }, 10000);
733
772
 
734
773
  it("ne devrait installer que les modèles valides d'un pack et rapporter les erreurs", async () => {
735
- const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await setupTestContext();
774
+ const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition, purge } = await setupTestContext();
736
775
  const mockPackWithInvalidModel = {
737
776
  name: 'invalid-model-pack',
738
777
  models: [
@@ -769,6 +808,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
769
808
  // Vérifier en BDD que le modèle valide a bien été créé
770
809
  const validModel = await testModelsColInstance.findOne({ name: 'validPackModel', _user: currentTestUser.username });
771
810
  expect(validModel).not.toBeNull();
811
+ await purge();
772
812
  });
773
813
 
774
814
  it('devrait correctement insérer des données JSON depuis un pack', async () => {
@@ -17,29 +17,29 @@ describe('Event System', () => {
17
17
  }
18
18
  });
19
19
 
20
- it('should allow listening for and triggering an event', () => {
20
+ it('should allow listening for and triggering an event', async() => {
21
21
  const mockCallback = vitest.fn();
22
22
  const eventName = 'testEvent';
23
23
 
24
24
  Event.Listen(eventName, mockCallback);
25
- Event.Trigger(eventName);
25
+ await Event.Trigger(eventName);
26
26
 
27
27
  expect(mockCallback).toHaveBeenCalledTimes(1);
28
28
  });
29
- it('should pass arguments to the event callback', () => {
29
+ it('should pass arguments to the event callback', async() => {
30
30
  const mockCallback = vitest.fn();
31
31
  const eventName = 'testEventWithArgs';
32
32
  const arg1 = 'hello';
33
33
  const arg2 = 123;
34
34
 
35
35
  Event.Listen(eventName, mockCallback, "priority", "medium");
36
- Event.Trigger(eventName, "priority", "medium", arg1, arg2);
36
+ await Event.Trigger(eventName, "priority", "medium", arg1, arg2);
37
37
 
38
38
  expect(mockCallback).toHaveBeenCalledTimes(1);
39
39
  expect(mockCallback).toHaveBeenCalledWith(arg1, arg2);
40
40
  });
41
41
 
42
- it('should allow removing a specific callback', () => {
42
+ it('should allow removing a specific callback', async() => {
43
43
  const mockCallback1 = vitest.fn();
44
44
  const mockCallback2 = vitest.fn();
45
45
  const eventName = 'testEventRemoveCallback';
@@ -47,22 +47,22 @@ describe('Event System', () => {
47
47
  Event.Listen(eventName, mockCallback1);
48
48
  Event.Listen(eventName, mockCallback2);
49
49
  Event.RemoveCallback(eventName, mockCallback1);
50
- Event.Trigger(eventName);
50
+ await Event.Trigger(eventName);
51
51
 
52
52
  expect(mockCallback1).not.toHaveBeenCalled();
53
53
  expect(mockCallback2).toHaveBeenCalledTimes(1);
54
54
  });
55
55
 
56
- it('should not trigger a callback if the event is not listened to', () => {
56
+ it('should not trigger a callback if the event is not listened to', async() => {
57
57
  const mockCallback = vitest.fn();
58
58
  const eventName = 'nonExistentEvent';
59
59
 
60
- Event.Trigger(eventName);
60
+ await Event.Trigger(eventName);
61
61
 
62
62
  expect(mockCallback).not.toHaveBeenCalled();
63
63
  });
64
64
 
65
- it('should handle different systems and layers', () => {
65
+ it('should handle different systems and layers', async() => {
66
66
  const mockCallbackPriority = vitest.fn();
67
67
  const mockCallbackLog = vitest.fn();
68
68
  const eventName = 'testEventMultiSystem';
@@ -70,13 +70,13 @@ describe('Event System', () => {
70
70
  Event.Listen(eventName, mockCallbackPriority, 'priority', 'high');
71
71
  Event.Listen(eventName, mockCallbackLog, 'log', 'info');
72
72
 
73
- Event.Trigger(eventName, 'priority', 'high');
73
+ await Event.Trigger(eventName, 'priority', 'high');
74
74
  expect(mockCallbackPriority).toHaveBeenCalledTimes(1);
75
75
  expect(mockCallbackLog).not.toHaveBeenCalled();
76
76
 
77
77
  vitest.clearAllMocks(); // Reset mock counts
78
78
 
79
- Event.Trigger(eventName, 'log', 'info');
79
+ await Event.Trigger(eventName, 'log', 'info');
80
80
  expect(mockCallbackPriority).not.toHaveBeenCalled();
81
81
  expect(mockCallbackLog).toHaveBeenCalledTimes(1);
82
82
  });
@@ -92,7 +92,7 @@ describe('Event System', () => {
92
92
  });
93
93
 
94
94
  describe('Event.Trigger result merging', () => {
95
- it('should merge objects from multiple callbacks using spread operator', () => {
95
+ it('should merge objects from multiple callbacks using spread operator', async() => {
96
96
  const eventName = 'mergeObjectEvent';
97
97
  const callback1 = vitest.fn().mockReturnValue({ a: 1, b: 2 });
98
98
  const callback2 = vitest.fn().mockReturnValue({ b: 3, c: 4 }); // b will be overwritten
@@ -100,12 +100,12 @@ describe('Event System', () => {
100
100
  Event.Listen(eventName, callback1);
101
101
  Event.Listen(eventName, callback2);
102
102
 
103
- const result = Event.Trigger(eventName);
103
+ const result = await Event.Trigger(eventName);
104
104
 
105
105
  expect(result).toEqual({ a: 1, b: 3, c: 4 });
106
106
  });
107
107
 
108
- it('should concatenate arrays from multiple callbacks', () => {
108
+ it('should concatenate arrays from multiple callbacks', async() => {
109
109
  const eventName = 'mergeArrayEvent';
110
110
  const callback1 = vitest.fn().mockReturnValue([1, 2]);
111
111
  const callback2 = vitest.fn().mockReturnValue([3, 4]);
@@ -113,12 +113,12 @@ describe('Event System', () => {
113
113
  Event.Listen(eventName, callback1);
114
114
  Event.Listen(eventName, callback2);
115
115
 
116
- const result = Event.Trigger(eventName);
116
+ const result = await Event.Trigger(eventName);
117
117
 
118
118
  expect(result).toEqual([1, 2, 3, 4]);
119
119
  });
120
120
 
121
- it('should concatenate strings from multiple callbacks', () => {
121
+ it('should concatenate strings from multiple callbacks', async() => {
122
122
  const eventName = 'mergeStringEvent';
123
123
  const callback1 = vitest.fn().mockReturnValue('Hello ');
124
124
  const callback2 = vitest.fn().mockReturnValue('World');
@@ -126,12 +126,12 @@ describe('Event System', () => {
126
126
  Event.Listen(eventName, callback1);
127
127
  Event.Listen(eventName, callback2);
128
128
 
129
- const result = Event.Trigger(eventName);
129
+ const result = await Event.Trigger(eventName);
130
130
 
131
131
  expect(result).toBe('Hello World');
132
132
  });
133
133
 
134
- it('should add numbers from multiple callbacks', () => {
134
+ it('should add numbers from multiple callbacks', async() => {
135
135
  const eventName = 'mergeNumberEvent';
136
136
  const callback1 = vitest.fn().mockReturnValue(10);
137
137
  const callback2 = vitest.fn().mockReturnValue(20);
@@ -139,12 +139,12 @@ describe('Event System', () => {
139
139
  Event.Listen(eventName, callback1);
140
140
  Event.Listen(eventName, callback2);
141
141
 
142
- const result = Event.Trigger(eventName);
142
+ const result = await Event.Trigger(eventName);
143
143
 
144
144
  expect(result).toBe(30);
145
145
  });
146
146
 
147
- it('should perform a logical AND on booleans from multiple callbacks', () => {
147
+ it('should perform a logical AND on booleans from multiple callbacks', async() => {
148
148
  const eventName = 'mergeBooleanEvent';
149
149
 
150
150
  // Case 1: true && true -> true
@@ -152,23 +152,23 @@ describe('Event System', () => {
152
152
  const cb_true2 = vitest.fn().mockReturnValue(true);
153
153
  Event.Listen(eventName, cb_true1);
154
154
  Event.Listen(eventName, cb_true2);
155
- expect(Event.Trigger(eventName)).toBe(true);
155
+ expect(await Event.Trigger(eventName)).toBe(true);
156
156
  Event.RemoveAllCallbacks(eventName); // Clean up for next case
157
157
 
158
158
  // Case 2: true && false -> false
159
159
  const cb_false1 = vitest.fn().mockReturnValue(false);
160
160
  Event.Listen(eventName, cb_true1);
161
161
  Event.Listen(eventName, cb_false1);
162
- expect(Event.Trigger(eventName)).toBe(false);
162
+ expect(await Event.Trigger(eventName)).toBe(false);
163
163
  Event.RemoveAllCallbacks(eventName);
164
164
 
165
165
  // Case 3: false && true -> false
166
166
  Event.Listen(eventName, cb_false1);
167
167
  Event.Listen(eventName, cb_true1);
168
- expect(Event.Trigger(eventName)).toBe(false);
168
+ expect(await Event.Trigger(eventName)).toBe(false);
169
169
  });
170
170
 
171
- it('should handle mixed-type return values', () => {
171
+ it('should handle mixed-type return values', async() => {
172
172
  const eventName = 'mergeMixedEvent';
173
173
  const callback1 = vitest.fn().mockReturnValue(100); // number
174
174
  const callback2 = vitest.fn().mockReturnValue({ a: 1 }); // object
@@ -176,7 +176,7 @@ describe('Event System', () => {
176
176
  Event.Listen(eventName, callback1);
177
177
  Event.Listen(eventName, callback2);
178
178
 
179
- const result = Event.Trigger(eventName);
179
+ const result = await Event.Trigger(eventName);
180
180
 
181
181
  // The logic initializes `ret` with the first value (100).
182
182
  // When the second callback returns an object, it re-initializes `ret` to {}
@@ -184,7 +184,7 @@ describe('Event System', () => {
184
184
  expect(result).toEqual({ a: 1 });
185
185
  });
186
186
 
187
- it('should ignore null and undefined return values while merging', () => {
187
+ it('should ignore null and undefined return values while merging', async() => {
188
188
  const eventName = 'ignoreNullsEvent';
189
189
  const callback1 = vitest.fn().mockReturnValue(null);
190
190
  const callback2 = vitest.fn().mockReturnValue({ data: 'important' });
@@ -194,7 +194,7 @@ describe('Event System', () => {
194
194
  Event.Listen(eventName, callback2);
195
195
  Event.Listen(eventName, callback3);
196
196
 
197
- const result = Event.Trigger(eventName);
197
+ const result = await Event.Trigger(eventName);
198
198
 
199
199
  expect(result).toEqual({ data: 'important' });
200
200
  });
@@ -3,6 +3,7 @@ import { stopEngine } from '../src/setenv.js';
3
3
 
4
4
  export default async function () {
5
5
  console.log('\n--- Global Teardown: Stopping engine and database ---');
6
+
6
7
  await stopEngine();
7
8
  console.log('--- Global Teardown: Cleanup complete. ---');
8
9
  }