data-primals-engine 1.1.8 → 1.2.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.
- package/README.md +72 -25
- package/client/src/App.scss +11 -6
- package/client/src/AssistantChat.scss +0 -1
- package/client/src/ChartConfigModal.jsx +0 -1
- package/client/src/ConditionBuilder.jsx +0 -2
- package/client/src/ConditionBuilder2.jsx +47 -6
- package/client/src/ContentView.jsx +0 -1
- package/client/src/CronBuilder.scss +0 -1
- package/client/src/CronPartBuilder.jsx +0 -1
- package/client/src/Dashboard.jsx +0 -1
- package/client/src/Dashboard.scss +0 -1
- package/client/src/DashboardChart.jsx +0 -1
- package/client/src/DashboardView.jsx +0 -1
- package/client/src/DataEditor.jsx +0 -4
- package/client/src/DisplayFlexNodeRenderer.jsx +0 -1
- package/client/src/DocumentationPageLayout.jsx +0 -2
- package/client/src/DocumentationPageLayout.scss +0 -1
- package/client/src/Field.jsx +1 -1
- package/client/src/FlexNode.jsx +0 -1
- package/client/src/KanbanView.scss +0 -1
- package/client/src/ModelCreator.jsx +4 -4
- package/client/src/ModelCreator.scss +10 -0
- package/client/src/ModelCreatorField.jsx +34 -34
- package/client/src/RTE.jsx +2 -1
- package/client/src/RestoreDialog.jsx +0 -1
- package/client/src/TourSpotlight.jsx +0 -1
- package/client/src/filter.js +2 -0
- package/client/src/hooks/useDragAndDrop.js +0 -1
- package/issues.txt +0 -0
- package/package.json +3 -2
- package/src/constants.js +6 -0
- package/src/core.js +6 -0
- package/src/data.js +0 -2
- package/src/defaultModels.js +33 -0
- package/src/migrate.js +0 -1
- package/src/modules/assistant.js +211 -133
- package/src/modules/data.js +88 -69
- package/src/modules/user.js +111 -56
- package/src/modules/workflow.js +10 -12
- package/src/providers.js +1 -1
- package/src/workers/crypto-worker.js +0 -1
- package/test/data.integration.test.js +53 -70
- package/test/user.test.js +203 -0
- package/test/workflow.integration.test.js +1 -1
|
@@ -471,7 +471,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
471
471
|
const insertResult = await insertData(simpleModel.name, dataToDelete, {}, currentTestUser, false);
|
|
472
472
|
const docId = insertResult.insertedIds[0];
|
|
473
473
|
|
|
474
|
-
const deleteResult = await deleteData(simpleModel.name, [docId],
|
|
474
|
+
const deleteResult = await deleteData(simpleModel.name, [docId], currentTestUser);
|
|
475
475
|
|
|
476
476
|
expect(deleteResult.success).toBe(true);
|
|
477
477
|
expect(deleteResult.deletedCount).toBe(1);
|
|
@@ -493,7 +493,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
493
493
|
input: '$name',
|
|
494
494
|
regex: "^Item Filtrable"
|
|
495
495
|
} };
|
|
496
|
-
const deleteResult = await deleteData(simpleModel.name,
|
|
496
|
+
const deleteResult = await deleteData(simpleModel.name, filter, currentTestUser);
|
|
497
497
|
|
|
498
498
|
expect(deleteResult.success).toBe(true);
|
|
499
499
|
expect(deleteResult.deletedCount).toBe(2);
|
|
@@ -551,19 +551,16 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
551
551
|
it('devrait trouver un document par une condition sur une relation simple ($find)', async () => {
|
|
552
552
|
const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
|
|
553
553
|
const searchParams = {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
autoExpand: true,
|
|
563
|
-
depth: 8
|
|
564
|
-
}
|
|
554
|
+
model: comprehensiveTestModelDefinition.name,
|
|
555
|
+
filter: {
|
|
556
|
+
relationSingle: {
|
|
557
|
+
"$find": { "$and": [{"$eq": ["$$this.relatedValue", 101]}] }
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
autoExpand: true,
|
|
561
|
+
depth: 8
|
|
565
562
|
};
|
|
566
|
-
const { data, count } = await searchData(searchParams);
|
|
563
|
+
const { data, count } = await searchData(searchParams, currentTestUser);
|
|
567
564
|
expect(count).toBe(1);
|
|
568
565
|
expect(data).toHaveLength(1);
|
|
569
566
|
expect(data[0]._id.toString()).toBe(docId1.toString());
|
|
@@ -575,18 +572,15 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
575
572
|
it('ne devrait pas trouver de document si la condition $find sur relation simple ne correspond pas', async () => {
|
|
576
573
|
const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
|
|
577
574
|
const searchParams = {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
},
|
|
586
|
-
depth: 1
|
|
587
|
-
}
|
|
575
|
+
model: comprehensiveTestModelDefinition.name,
|
|
576
|
+
filter: {
|
|
577
|
+
relationSingle: {
|
|
578
|
+
"$find": { "$eq": ["$$this.relatedName", "NonExistentRelName"] }
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
depth: 1
|
|
588
582
|
};
|
|
589
|
-
const { data, count } = await searchData(searchParams);
|
|
583
|
+
const { data, count } = await searchData(searchParams, currentTestUser);
|
|
590
584
|
expect(count).toBe(0);
|
|
591
585
|
expect(data).toHaveLength(0);
|
|
592
586
|
});
|
|
@@ -594,20 +588,17 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
594
588
|
it('devrait trouver des documents par une condition sur une relation multiple ($find)', async () => {
|
|
595
589
|
const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
|
|
596
590
|
const searchParams = {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
},
|
|
607
|
-
depth: 1
|
|
608
|
-
}
|
|
591
|
+
model: comprehensiveTestModelDefinition.name,
|
|
592
|
+
filter: {
|
|
593
|
+
$and: [{$ne:["$stringRequired", null]}, {
|
|
594
|
+
relationMultiple: { // Le champ qui est un tableau de relations
|
|
595
|
+
"$find": {"$eq": ["$$this.relatedValue", 102]} // Condition sur les documents liés
|
|
596
|
+
}
|
|
597
|
+
}]
|
|
598
|
+
},
|
|
599
|
+
depth: 1
|
|
609
600
|
};
|
|
610
|
-
const { data, count } = await searchData(searchParams);
|
|
601
|
+
const { data, count } = await searchData(searchParams, currentTestUser);
|
|
611
602
|
expect(count).toBe(1);
|
|
612
603
|
expect(data).toHaveLength(1);
|
|
613
604
|
expect(data[0]._id.toString()).toBe(docId1.toString());
|
|
@@ -620,19 +611,16 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
620
611
|
it('devrait trouver des documents en combinant un filtre normal et un filtre $find', async () => {
|
|
621
612
|
const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
|
|
622
613
|
const searchParams = {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
},
|
|
632
|
-
depth: 1
|
|
633
|
-
}
|
|
614
|
+
model: comprehensiveTestModelDefinition.name,
|
|
615
|
+
filter: {
|
|
616
|
+
stringRequired: "SearchDoc1", // Filtre sur le modèle principal
|
|
617
|
+
relationSingle: {
|
|
618
|
+
"$find": {"$gt": ["$$this.relatedValue", 100] } // Filtre sur la relation
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
depth: 1
|
|
634
622
|
};
|
|
635
|
-
const { data, count } = await searchData(searchParams);
|
|
623
|
+
const { data, count } = await searchData(searchParams,currentTestUser);
|
|
636
624
|
expect(count).toBe(1);
|
|
637
625
|
expect(data).toHaveLength(1);
|
|
638
626
|
expect(data[0]._id.toString()).toBe(docId1.toString());
|
|
@@ -641,26 +629,21 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
641
629
|
it('devrait retourner un tableau vide si $find ne correspond à aucun document lié', async () => {
|
|
642
630
|
const { currentTestUser, comprehensiveTestModelDefinition, relatedModelDefinition } = await initTest();
|
|
643
631
|
const searchParams = {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
},
|
|
652
|
-
depth: 1
|
|
653
|
-
}
|
|
632
|
+
model: comprehensiveTestModelDefinition.name,
|
|
633
|
+
filter: {
|
|
634
|
+
relationMultiple: {
|
|
635
|
+
"$find": { "$eq": ["$$this.relatedName", "NonExistentRelNameForMultiple"] }
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
depth: 1
|
|
654
639
|
};
|
|
655
|
-
const { data, count } = await searchData(searchParams);
|
|
640
|
+
const { data, count } = await searchData(searchParams,currentTestUser);
|
|
656
641
|
expect(count).toBe(0);
|
|
657
642
|
expect(data).toHaveLength(0);
|
|
658
643
|
});
|
|
659
644
|
|
|
660
645
|
});
|
|
661
646
|
|
|
662
|
-
// Dans C:/Dev/hackersonline-engine/test/data.integration.test.js
|
|
663
|
-
|
|
664
647
|
describe('installPack', () => {
|
|
665
648
|
let testPacksColInstance;
|
|
666
649
|
|
|
@@ -824,8 +807,8 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
824
807
|
// Cleanup before starting to ensure a clean state
|
|
825
808
|
await deleteModels({ name: productModel.name, _user: user.username });
|
|
826
809
|
await deleteModels({ name: orderModel.name, _user: user.username });
|
|
827
|
-
await deleteData(productModel.name,
|
|
828
|
-
await deleteData(orderModel.name,
|
|
810
|
+
await deleteData(productModel.name, {}, user);
|
|
811
|
+
await deleteData(orderModel.name, {}, user);
|
|
829
812
|
|
|
830
813
|
// Create models
|
|
831
814
|
await createModel({ ...productModel, _user: user.username });
|
|
@@ -843,8 +826,8 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
843
826
|
afterAll(async () => {
|
|
844
827
|
await deleteModels({ name: productModel.name, _user: user.username });
|
|
845
828
|
await deleteModels({ name: orderModel.name, _user: user.username });
|
|
846
|
-
await deleteData(productModel.name,
|
|
847
|
-
await deleteData(orderModel.name,
|
|
829
|
+
await deleteData(productModel.name, {}, user);
|
|
830
|
+
await deleteData(orderModel.name, {}, user);
|
|
848
831
|
});
|
|
849
832
|
|
|
850
833
|
it('should ALLOW inserting data with a valid relation', async () => {
|
|
@@ -852,7 +835,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
852
835
|
expect(result.success).toBe(true);
|
|
853
836
|
expect(result.insertedIds).toHaveLength(1);
|
|
854
837
|
// Cleanup the created order for test isolation
|
|
855
|
-
await deleteData(orderModel.name, result.insertedIds,
|
|
838
|
+
await deleteData(orderModel.name, result.insertedIds, user);
|
|
856
839
|
});
|
|
857
840
|
|
|
858
841
|
it('should REJECT inserting data with a relation that does not respect the filter', async () => {
|
|
@@ -873,7 +856,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
873
856
|
expect(result.modifiedCount).toBeGreaterThanOrEqual(0);
|
|
874
857
|
|
|
875
858
|
// Cleanup
|
|
876
|
-
await deleteData(orderModel.name, initialOrder.insertedIds,
|
|
859
|
+
await deleteData(orderModel.name, initialOrder.insertedIds, user);
|
|
877
860
|
});
|
|
878
861
|
|
|
879
862
|
it('should REJECT updating data with a relation that does not respect the filter', async () => {
|
|
@@ -885,7 +868,7 @@ describe('Intégration des fonctions CRUD de données avec validation complète'
|
|
|
885
868
|
expect(result.success).toBe(false);
|
|
886
869
|
expect(result.error).toContain('produit');
|
|
887
870
|
// Cleanup
|
|
888
|
-
await deleteData(orderModel.name, initialOrder.insertedIds,
|
|
871
|
+
await deleteData(orderModel.name, initialOrder.insertedIds, user);
|
|
889
872
|
});
|
|
890
873
|
});
|
|
891
874
|
});
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { expect, describe, it, beforeEach, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import { hasPermission, getUserActivePermissions } from '../src/modules/user.js';
|
|
3
|
+
import {initEngine} from "data-primals-engine/setenv";
|
|
4
|
+
import {generateUniqueName} from "../src/setenv.js";
|
|
5
|
+
import {
|
|
6
|
+
getCollectionForUser as getAppUserCollection,
|
|
7
|
+
modelsCollection as getAppModelsCollection
|
|
8
|
+
} from "data-primals-engine/modules/mongodb";
|
|
9
|
+
import {Config} from "../src/index.js";
|
|
10
|
+
let permRead, permWrite, permDelete, permManage;
|
|
11
|
+
let roleEditor;
|
|
12
|
+
let testUser, adminUser, roleViewer;
|
|
13
|
+
let currentTestUser;
|
|
14
|
+
let testModelsColInstance, testDatasColInstance;
|
|
15
|
+
// Cette fonction va remplacer la logique de votre beforeEach pour la création de contexte
|
|
16
|
+
async function setupTestContext() {
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// Créer un utilisateur unique pour ce test
|
|
20
|
+
const username = generateUniqueName('testuserDataIntegration');
|
|
21
|
+
currentTestUser = {
|
|
22
|
+
username,
|
|
23
|
+
userPlan: 'free',
|
|
24
|
+
_model: 'user',
|
|
25
|
+
_user: username,
|
|
26
|
+
email: generateUniqueName('test') + '@example.com'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Initialize collection instances after the engine is ready
|
|
30
|
+
testModelsColInstance = getAppModelsCollection;
|
|
31
|
+
testDatasColInstance = await getAppUserCollection(currentTestUser);
|
|
32
|
+
|
|
33
|
+
await testDatasColInstance.deleteMany({}); // Nettoyage de la base de test
|
|
34
|
+
// 1. Créer les permissions
|
|
35
|
+
const permissions = await testDatasColInstance.insertMany([
|
|
36
|
+
{ _model: 'permission', name: 'post:read', description: 'Lire les articles' },
|
|
37
|
+
{ _model: 'permission', name: 'post:write', description: 'Écrire des articles' },
|
|
38
|
+
{ _model: 'permission', name: 'post:delete', description: 'Supprimer des articles' },
|
|
39
|
+
{ _model: 'permission', name: 'user:manage', description: 'Gérer les utilisateurs' }
|
|
40
|
+
]);
|
|
41
|
+
permRead = permissions.insertedIds[0];
|
|
42
|
+
permWrite = permissions.insertedIds[1];
|
|
43
|
+
permDelete = permissions.insertedIds[2];
|
|
44
|
+
permManage = permissions.insertedIds[3];
|
|
45
|
+
|
|
46
|
+
// 2. Créer les rôles
|
|
47
|
+
const roles = await testDatasColInstance.insertMany([
|
|
48
|
+
{ _user: currentTestUser.username, _model: 'role', name: 'Viewer', permissions: [permRead.toString()] },
|
|
49
|
+
{ _user: currentTestUser.username, _model: 'role', name: 'Editor', permissions: [permRead.toString(), permWrite.toString()] }
|
|
50
|
+
]);
|
|
51
|
+
roleViewer = roles.insertedIds[0];
|
|
52
|
+
roleEditor = roles.insertedIds[1];
|
|
53
|
+
|
|
54
|
+
// 3. Créer les utilisateurs
|
|
55
|
+
const users = await testDatasColInstance.insertMany([
|
|
56
|
+
{ _user: currentTestUser.username, _model: 'user', roles: [roleEditor.toString()] },
|
|
57
|
+
{ _user: currentTestUser.username, _model: 'user', roles: [roleEditor.toString()] }
|
|
58
|
+
]);
|
|
59
|
+
testUser = {...currentTestUser, _id: users.insertedIds[0].toString(), roles: [roleEditor.toString()] };
|
|
60
|
+
adminUser = {...currentTestUser, _id: users.insertedIds[1].toString(), roles: [roleEditor.toString()] };
|
|
61
|
+
};
|
|
62
|
+
let engine;
|
|
63
|
+
describe('User Permission Logic', () => {
|
|
64
|
+
|
|
65
|
+
// --- SETUP : Création des données de test avant tous les tests ---
|
|
66
|
+
beforeAll(async () => {
|
|
67
|
+
Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant"]);
|
|
68
|
+
engine = await initEngine();
|
|
69
|
+
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// --- Tests pour la fonction principale de calcul ---
|
|
73
|
+
describe('getUserActivePermissions()', () => {
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
beforeEach(async () =>{
|
|
77
|
+
await setupTestContext();
|
|
78
|
+
})
|
|
79
|
+
it('should return base permissions from the user\'s role', async () => {
|
|
80
|
+
const permissions = await getUserActivePermissions(testUser);
|
|
81
|
+
expect(permissions).to.be.an.instanceOf(Set);
|
|
82
|
+
expect(permissions.size).to.equal(2);
|
|
83
|
+
expect(permissions.has('post:read')).to.be.true;
|
|
84
|
+
expect(permissions.has('post:write')).to.be.true;
|
|
85
|
+
expect(permissions.has('post:delete')).to.be.false;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should grant a temporary permission via an exception', async () => {
|
|
89
|
+
|
|
90
|
+
// Ajoute une exception qui donne la permission de supprimer, expirant demain
|
|
91
|
+
const futureDate = new Date();
|
|
92
|
+
futureDate.setDate(futureDate.getDate() + 1);
|
|
93
|
+
|
|
94
|
+
await testDatasColInstance.insertOne({
|
|
95
|
+
_model: 'userPermission',
|
|
96
|
+
user: testUser._id,
|
|
97
|
+
permission: permDelete,
|
|
98
|
+
isGranted: true,
|
|
99
|
+
expiresAt: futureDate
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const permissions = await getUserActivePermissions(testUser);
|
|
103
|
+
expect(permissions.size).to.equal(3);
|
|
104
|
+
expect(permissions.has('post:delete')).to.be.true;
|
|
105
|
+
|
|
106
|
+
// Nettoyage de l'exception pour ne pas affecter les autres tests
|
|
107
|
+
await testDatasColInstance.deleteOne({ _model: 'userPermission', user: testUser._id });
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should NOT grant an expired temporary permission', async () => {
|
|
111
|
+
// Ajoute une exception qui a expiré hier
|
|
112
|
+
const pastDate = new Date();
|
|
113
|
+
pastDate.setDate(pastDate.getDate() - 1);
|
|
114
|
+
|
|
115
|
+
await testDatasColInstance.insertOne({
|
|
116
|
+
_model: 'userPermission',
|
|
117
|
+
user: testUser._id,
|
|
118
|
+
permission: permDelete,
|
|
119
|
+
isGranted: true,
|
|
120
|
+
expiresAt: pastDate
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const permissions = await getUserActivePermissions(testUser);
|
|
124
|
+
expect(permissions.size).to.equal(2); // Revient la normale
|
|
125
|
+
expect(permissions.has('post:delete')).to.be.false;
|
|
126
|
+
|
|
127
|
+
await testDatasColInstance.deleteOne({ _model: 'userPermission', user: testUser._id });
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should revoke a base permission via an exception', async () => {
|
|
131
|
+
// L'utilisateur est "Editor", mais on lui retire le droit d'écriture temporairement
|
|
132
|
+
const futureDate = new Date();
|
|
133
|
+
futureDate.setDate(futureDate.getDate() + 1);
|
|
134
|
+
|
|
135
|
+
await testDatasColInstance.insertOne({
|
|
136
|
+
_model: 'userPermission',
|
|
137
|
+
user: testUser._id,
|
|
138
|
+
permission: permWrite,
|
|
139
|
+
isGranted: false, // Révocation
|
|
140
|
+
expiresAt: futureDate
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const permissions = await getUserActivePermissions(testUser);
|
|
144
|
+
expect(permissions.size).to.equal(1);
|
|
145
|
+
expect(permissions.has('post:read')).to.be.true;
|
|
146
|
+
expect(permissions.has('post:write')).to.be.false; // La permission a été retirée
|
|
147
|
+
|
|
148
|
+
await testDatasColInstance.deleteOne({ _model: 'userPermission', user: testUser._id });
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should restore a revoked permission if the revocation has expired', async () => {
|
|
152
|
+
// La révocation a expiré, l'utilisateur devrait retrouver son droit d'écriture
|
|
153
|
+
const pastDate = new Date();
|
|
154
|
+
pastDate.setDate(pastDate.getDate() - 1);
|
|
155
|
+
|
|
156
|
+
await testDatasColInstance.insertOne({
|
|
157
|
+
_model: 'userPermission',
|
|
158
|
+
user: testUser._id,
|
|
159
|
+
permission: permWrite,
|
|
160
|
+
isGranted: false,
|
|
161
|
+
expiresAt: pastDate
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const permissions = await getUserActivePermissions(testUser);
|
|
165
|
+
expect(permissions.size).to.equal(2);
|
|
166
|
+
expect(permissions.has('post:write')).to.be.true; // La permission est de retour
|
|
167
|
+
|
|
168
|
+
await testDatasColInstance.deleteOne({ _model: 'userPermission', user: testUser._id });
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// --- Tests pour la fonction publique `hasPermission` ---
|
|
173
|
+
describe('hasPermission()', () => {
|
|
174
|
+
beforeEach(async () => {
|
|
175
|
+
await setupTestContext();
|
|
176
|
+
});
|
|
177
|
+
it('should return true for a permission the user has', async () => {
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
console.log(await testDatasColInstance.find({ _model: 'permission' }).toArray());
|
|
181
|
+
console.log(await testDatasColInstance.find({ _model: 'role' }).toArray());
|
|
182
|
+
console.log(await testDatasColInstance.find({ _model: 'user' }).toArray());
|
|
183
|
+
console.log(await testDatasColInstance.find({ _model: 'userPermission' }).toArray());
|
|
184
|
+
const result = await hasPermission('post:read', testUser);
|
|
185
|
+
expect(result).to.be.true;
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should return false for a permission the user does not have', async () => {
|
|
189
|
+
const result = await hasPermission('user:manage', testUser);
|
|
190
|
+
expect(result).to.be.false;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should return true if user has at least one of the required permissions', async () => {
|
|
194
|
+
const result = await hasPermission(['user:manage', 'post:write'], testUser);
|
|
195
|
+
expect(result).to.be.true;
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should return false if user has none of the required permissions', async () => {
|
|
199
|
+
const result = await hasPermission(['user:manage', 'post:delete'], testUser);
|
|
200
|
+
expect(result).to.be.false;
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
@@ -299,7 +299,7 @@ describe('Intégration des Workflows - triggerWorkflows', () => {
|
|
|
299
299
|
}, {}, mockUser, false);
|
|
300
300
|
|
|
301
301
|
// 2. Act: Supprimer la donnée
|
|
302
|
-
const deleteResult = await deleteData(targetDataModel.name, [projectId],
|
|
302
|
+
const deleteResult = await deleteData(targetDataModel.name, [projectId], mockUser, true, true);
|
|
303
303
|
expect(deleteResult.success).toBe(true);
|
|
304
304
|
|
|
305
305
|
// 3. Assert: Un `workflowRun` doit être créé
|