@expo/entity 0.33.0 → 0.34.0
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/build/Entity.d.ts +6 -6
- package/build/Entity.js +6 -29
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +8 -8
- package/build/EntityAssociationLoader.js +4 -20
- package/build/EntityAssociationLoader.js.map +1 -1
- package/build/EntityFields.js +3 -2
- package/build/EntityFields.js.map +1 -1
- package/build/EntityMutationTriggerConfiguration.d.ts +5 -7
- package/build/EntityMutationTriggerConfiguration.js +3 -4
- package/build/EntityMutationTriggerConfiguration.js.map +1 -1
- package/build/EntityQueryContextProvider.d.ts +1 -1
- package/build/EntityQueryContextProvider.js +1 -1
- package/build/EntityQueryContextProvider.js.map +1 -1
- package/build/IEntityCacheAdapterProvider.d.ts +1 -1
- package/build/ReadonlyEntity.d.ts +1 -1
- package/build/ReadonlyEntity.js +1 -4
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerContext.d.ts +2 -2
- package/build/ViewerContext.js +3 -3
- package/build/ViewerContext.js.map +1 -1
- package/build/__tests__/Entity-test.js +13 -13
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +69 -37
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +19 -11
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +72 -40
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityFields-test.js +7 -1
- package/build/__tests__/EntityFields-test.js.map +1 -1
- package/build/__tests__/EntityLoader-constructor-test.js +1 -1
- package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +19 -19
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +6 -6
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +20 -20
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +10 -10
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +79 -47
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ReadonlyEntity-test.js +13 -13
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/ViewerContext-test.js +2 -2
- package/build/__tests__/ViewerContext-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +12 -8
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +15 -13
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/internal/EntityDataManager.js +1 -1
- package/build/internal/EntityDataManager.js.map +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js +11 -11
- package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
- package/build/testfixtures/SimpleTestEntity.d.ts +8 -8
- package/build/testfixtures/SimpleTestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity.d.ts +12 -12
- package/build/testfixtures/TestEntity.js.map +1 -1
- package/build/testfixtures/TestEntity2.d.ts +8 -8
- package/build/testfixtures/TestEntity2.js.map +1 -1
- package/build/testfixtures/TestViewerContext.d.ts +3 -0
- package/build/testfixtures/TestViewerContext.js +6 -0
- package/build/testfixtures/TestViewerContext.js.map +1 -1
- package/package.json +2 -2
- package/src/Entity.ts +6 -29
- package/src/EntityAssociationLoader.ts +9 -25
- package/src/EntityFields.ts +5 -3
- package/src/EntityMutationTriggerConfiguration.ts +5 -7
- package/src/EntityQueryContextProvider.ts +1 -1
- package/src/IEntityCacheAdapterProvider.ts +1 -1
- package/src/ReadonlyEntity.ts +1 -4
- package/src/ViewerContext.ts +5 -5
- package/src/__tests__/Entity-test.ts +43 -27
- package/src/__tests__/EntityAssociationLoader-test.ts +168 -86
- package/src/__tests__/EntityCommonUseCases-test.ts +36 -18
- package/src/__tests__/EntityEdges-test.ts +102 -40
- package/src/__tests__/EntityFields-test.ts +7 -1
- package/src/__tests__/EntityLoader-constructor-test.ts +1 -1
- package/src/__tests__/EntityLoader-test.ts +19 -19
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +19 -16
- package/src/__tests__/EntityMutator-test.ts +67 -61
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +20 -11
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +115 -47
- package/src/__tests__/ReadonlyEntity-test.ts +15 -13
- package/src/__tests__/ViewerContext-test.ts +3 -2
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +33 -22
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +30 -22
- package/src/internal/EntityDataManager.ts +1 -1
- package/src/internal/__tests__/EntityDataManager-test.ts +11 -11
- package/src/testfixtures/SimpleTestEntity.ts +8 -8
- package/src/testfixtures/TestEntity.ts +15 -12
- package/src/testfixtures/TestEntity2.ts +8 -8
- package/src/testfixtures/TestViewerContext.ts +12 -1
|
@@ -14,20 +14,24 @@ describe(EntityAssociationLoader, () => {
|
|
|
14
14
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
15
15
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
16
16
|
const testOtherEntity = await enforceAsyncResult(
|
|
17
|
-
TestEntity.creator(viewerContext).createAsync()
|
|
17
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext()).createAsync()
|
|
18
18
|
);
|
|
19
19
|
const testEntity = await enforceAsyncResult(
|
|
20
|
-
TestEntity.creator(viewerContext)
|
|
20
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
21
21
|
.setField('stringField', testOtherEntity.getID())
|
|
22
22
|
.createAsync()
|
|
23
23
|
);
|
|
24
24
|
const loadedOther = await enforceAsyncResult(
|
|
25
|
-
testEntity
|
|
25
|
+
testEntity
|
|
26
|
+
.associationLoader()
|
|
27
|
+
.loadAssociatedEntityAsync('stringField', TestEntity, viewerContext.getQueryContext())
|
|
26
28
|
);
|
|
27
29
|
expect(loadedOther.getID()).toEqual(testOtherEntity.getID());
|
|
28
30
|
|
|
29
31
|
const loadedOther2 = await enforceAsyncResult(
|
|
30
|
-
testEntity
|
|
32
|
+
testEntity
|
|
33
|
+
.associationLoader()
|
|
34
|
+
.loadAssociatedEntityAsync('nullableField', TestEntity, viewerContext.getQueryContext())
|
|
31
35
|
);
|
|
32
36
|
expect(loadedOther2).toBeNull();
|
|
33
37
|
});
|
|
@@ -37,15 +41,27 @@ describe(EntityAssociationLoader, () => {
|
|
|
37
41
|
it('loads many associated entities referencing this entity', async () => {
|
|
38
42
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
39
43
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
40
|
-
const testEntity = await enforceAsyncResult(
|
|
44
|
+
const testEntity = await enforceAsyncResult(
|
|
45
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext()).createAsync()
|
|
46
|
+
);
|
|
41
47
|
const testOtherEntity1 = await enforceAsyncResult(
|
|
42
|
-
TestEntity.creator(viewerContext
|
|
48
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
49
|
+
.setField('stringField', testEntity.getID())
|
|
50
|
+
.createAsync()
|
|
43
51
|
);
|
|
44
52
|
const testOtherEntity2 = await enforceAsyncResult(
|
|
45
|
-
TestEntity.creator(viewerContext
|
|
53
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
54
|
+
.setField('stringField', testEntity.getID())
|
|
55
|
+
.createAsync()
|
|
46
56
|
);
|
|
47
57
|
const loaded = await enforceResultsAsync(
|
|
48
|
-
testEntity
|
|
58
|
+
testEntity
|
|
59
|
+
.associationLoader()
|
|
60
|
+
.loadManyAssociatedEntitiesAsync(
|
|
61
|
+
TestEntity,
|
|
62
|
+
'stringField',
|
|
63
|
+
viewerContext.getQueryContext()
|
|
64
|
+
)
|
|
49
65
|
);
|
|
50
66
|
expect(loaded).toHaveLength(2);
|
|
51
67
|
expect(loaded.find((e) => e.getID() === testOtherEntity1.getID())).not.toBeUndefined();
|
|
@@ -58,16 +74,21 @@ describe(EntityAssociationLoader, () => {
|
|
|
58
74
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
59
75
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
60
76
|
const testOtherEntity = await enforceAsyncResult(
|
|
61
|
-
TestEntity.creator(viewerContext).createAsync()
|
|
77
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext()).createAsync()
|
|
62
78
|
);
|
|
63
79
|
const testEntity = await enforceAsyncResult(
|
|
64
|
-
TestEntity.creator(viewerContext)
|
|
80
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
65
81
|
.setField('stringField', testOtherEntity.getID())
|
|
66
82
|
.createAsync()
|
|
67
83
|
);
|
|
68
84
|
const loadedOtherResult = await testEntity
|
|
69
85
|
.associationLoader()
|
|
70
|
-
.loadAssociatedEntityByFieldEqualingAsync(
|
|
86
|
+
.loadAssociatedEntityByFieldEqualingAsync(
|
|
87
|
+
'stringField',
|
|
88
|
+
TestEntity,
|
|
89
|
+
'customIdField',
|
|
90
|
+
viewerContext.getQueryContext()
|
|
91
|
+
);
|
|
71
92
|
expect(loadedOtherResult?.enforceValue().getID()).toEqual(testOtherEntity.getID());
|
|
72
93
|
});
|
|
73
94
|
|
|
@@ -75,11 +96,18 @@ describe(EntityAssociationLoader, () => {
|
|
|
75
96
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
76
97
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
77
98
|
const testEntity = await enforceAsyncResult(
|
|
78
|
-
TestEntity.creator(viewerContext
|
|
99
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
100
|
+
.setField('stringField', uuidv4())
|
|
101
|
+
.createAsync()
|
|
79
102
|
);
|
|
80
103
|
const loadedOtherResult = await testEntity
|
|
81
104
|
.associationLoader()
|
|
82
|
-
.loadAssociatedEntityByFieldEqualingAsync(
|
|
105
|
+
.loadAssociatedEntityByFieldEqualingAsync(
|
|
106
|
+
'stringField',
|
|
107
|
+
TestEntity,
|
|
108
|
+
'customIdField',
|
|
109
|
+
viewerContext.getQueryContext()
|
|
110
|
+
);
|
|
83
111
|
expect(loadedOtherResult).toBeNull();
|
|
84
112
|
});
|
|
85
113
|
|
|
@@ -87,11 +115,18 @@ describe(EntityAssociationLoader, () => {
|
|
|
87
115
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
88
116
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
89
117
|
const testEntity = await enforceAsyncResult(
|
|
90
|
-
TestEntity.creator(viewerContext
|
|
118
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
119
|
+
.setField('stringField', 'blah')
|
|
120
|
+
.createAsync()
|
|
91
121
|
);
|
|
92
122
|
const loadedOtherResult = await testEntity
|
|
93
123
|
.associationLoader()
|
|
94
|
-
.loadAssociatedEntityByFieldEqualingAsync(
|
|
124
|
+
.loadAssociatedEntityByFieldEqualingAsync(
|
|
125
|
+
'nullableField',
|
|
126
|
+
TestEntity,
|
|
127
|
+
'customIdField',
|
|
128
|
+
viewerContext.getQueryContext()
|
|
129
|
+
);
|
|
95
130
|
expect(loadedOtherResult).toBeNull();
|
|
96
131
|
});
|
|
97
132
|
});
|
|
@@ -100,12 +135,18 @@ describe(EntityAssociationLoader, () => {
|
|
|
100
135
|
it('loads many associated entities by field equaling', async () => {
|
|
101
136
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
102
137
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
103
|
-
const testEntity = await enforceAsyncResult(
|
|
138
|
+
const testEntity = await enforceAsyncResult(
|
|
139
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext()).createAsync()
|
|
140
|
+
);
|
|
104
141
|
const testOtherEntity1 = await enforceAsyncResult(
|
|
105
|
-
TestEntity.creator(viewerContext
|
|
142
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
143
|
+
.setField('stringField', testEntity.getID())
|
|
144
|
+
.createAsync()
|
|
106
145
|
);
|
|
107
146
|
const testOtherEntity2 = await enforceAsyncResult(
|
|
108
|
-
TestEntity.creator(viewerContext
|
|
147
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
148
|
+
.setField('stringField', testEntity.getID())
|
|
149
|
+
.createAsync()
|
|
109
150
|
);
|
|
110
151
|
const loaded = await enforceResultsAsync(
|
|
111
152
|
testEntity
|
|
@@ -113,7 +154,8 @@ describe(EntityAssociationLoader, () => {
|
|
|
113
154
|
.loadManyAssociatedEntitiesByFieldEqualingAsync(
|
|
114
155
|
'customIdField',
|
|
115
156
|
TestEntity,
|
|
116
|
-
'stringField'
|
|
157
|
+
'stringField',
|
|
158
|
+
viewerContext.getQueryContext()
|
|
117
159
|
)
|
|
118
160
|
);
|
|
119
161
|
expect(loaded).toHaveLength(2);
|
|
@@ -124,14 +166,17 @@ describe(EntityAssociationLoader, () => {
|
|
|
124
166
|
it('returns empty results when field being queried by is null', async () => {
|
|
125
167
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
126
168
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
127
|
-
const testEntity = await enforceAsyncResult(
|
|
169
|
+
const testEntity = await enforceAsyncResult(
|
|
170
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext()).createAsync()
|
|
171
|
+
);
|
|
128
172
|
const loaded = await enforceResultsAsync(
|
|
129
173
|
testEntity
|
|
130
174
|
.associationLoader()
|
|
131
175
|
.loadManyAssociatedEntitiesByFieldEqualingAsync(
|
|
132
176
|
'nullableField',
|
|
133
177
|
TestEntity,
|
|
134
|
-
'stringField'
|
|
178
|
+
'stringField',
|
|
179
|
+
viewerContext.getQueryContext()
|
|
135
180
|
)
|
|
136
181
|
);
|
|
137
182
|
expect(loaded).toHaveLength(0);
|
|
@@ -142,53 +187,68 @@ describe(EntityAssociationLoader, () => {
|
|
|
142
187
|
it('chain loads associated entities', async () => {
|
|
143
188
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
144
189
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
145
|
-
const testEntity4 = await enforceAsyncResult(
|
|
190
|
+
const testEntity4 = await enforceAsyncResult(
|
|
191
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext()).createAsync()
|
|
192
|
+
);
|
|
146
193
|
const testEntity3 = await enforceAsyncResult(
|
|
147
|
-
TestEntity2.creator(viewerContext
|
|
194
|
+
TestEntity2.creator(viewerContext, viewerContext.getQueryContext())
|
|
195
|
+
.setField('foreignKey', testEntity4.getID())
|
|
196
|
+
.createAsync()
|
|
148
197
|
);
|
|
149
198
|
const testEntity2 = await enforceAsyncResult(
|
|
150
|
-
TestEntity.creator(viewerContext)
|
|
199
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
151
200
|
.setField('testIndexedField', testEntity3.getID())
|
|
152
201
|
.createAsync()
|
|
153
202
|
);
|
|
154
203
|
const testEntity = await enforceAsyncResult(
|
|
155
|
-
TestEntity2.creator(viewerContext
|
|
204
|
+
TestEntity2.creator(viewerContext, viewerContext.getQueryContext())
|
|
205
|
+
.setField('foreignKey', testEntity2.getID())
|
|
206
|
+
.createAsync()
|
|
156
207
|
);
|
|
157
208
|
|
|
158
|
-
const loaded2Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
209
|
+
const loaded2Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
210
|
+
[
|
|
211
|
+
{
|
|
212
|
+
associatedEntityClass: TestEntity,
|
|
213
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
viewerContext.getQueryContext()
|
|
217
|
+
);
|
|
164
218
|
expect(loaded2Result?.enforceValue().getID()).toEqual(testEntity2.getID());
|
|
165
219
|
|
|
166
|
-
const loaded3Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
220
|
+
const loaded3Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
221
|
+
[
|
|
222
|
+
{
|
|
223
|
+
associatedEntityClass: TestEntity,
|
|
224
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
associatedEntityClass: TestEntity2,
|
|
228
|
+
fieldIdentifyingAssociatedEntity: 'testIndexedField',
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
viewerContext.getQueryContext()
|
|
232
|
+
);
|
|
176
233
|
expect(loaded3Result?.enforceValue().getID()).toEqual(testEntity3.getID());
|
|
177
234
|
|
|
178
|
-
const loaded4Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
235
|
+
const loaded4Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
236
|
+
[
|
|
237
|
+
{
|
|
238
|
+
associatedEntityClass: TestEntity,
|
|
239
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
associatedEntityClass: TestEntity2,
|
|
243
|
+
fieldIdentifyingAssociatedEntity: 'testIndexedField',
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
associatedEntityClass: TestEntity,
|
|
247
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
viewerContext.getQueryContext()
|
|
251
|
+
);
|
|
192
252
|
expect(loaded4Result?.enforceValue().getID()).toEqual(testEntity4.getID());
|
|
193
253
|
});
|
|
194
254
|
|
|
@@ -197,15 +257,20 @@ describe(EntityAssociationLoader, () => {
|
|
|
197
257
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
198
258
|
|
|
199
259
|
const testEntity = await enforceAsyncResult(
|
|
200
|
-
TestEntity2.creator(viewerContext
|
|
260
|
+
TestEntity2.creator(viewerContext, viewerContext.getQueryContext())
|
|
261
|
+
.setField('foreignKey', uuidv4())
|
|
262
|
+
.createAsync()
|
|
201
263
|
);
|
|
202
264
|
|
|
203
|
-
const loadResult = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
265
|
+
const loadResult = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
266
|
+
[
|
|
267
|
+
{
|
|
268
|
+
associatedEntityClass: TestEntity,
|
|
269
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
viewerContext.getQueryContext()
|
|
273
|
+
);
|
|
209
274
|
expect(loadResult?.ok).toBe(false);
|
|
210
275
|
});
|
|
211
276
|
|
|
@@ -215,19 +280,26 @@ describe(EntityAssociationLoader, () => {
|
|
|
215
280
|
|
|
216
281
|
const fieldValue = uuidv4();
|
|
217
282
|
const testEntity2 = await enforceAsyncResult(
|
|
218
|
-
TestEntity.creator(viewerContext
|
|
283
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
284
|
+
.setField('stringField', fieldValue)
|
|
285
|
+
.createAsync()
|
|
219
286
|
);
|
|
220
287
|
const testEntity = await enforceAsyncResult(
|
|
221
|
-
TestEntity2.creator(viewerContext
|
|
288
|
+
TestEntity2.creator(viewerContext, viewerContext.getQueryContext())
|
|
289
|
+
.setField('foreignKey', fieldValue)
|
|
290
|
+
.createAsync()
|
|
222
291
|
);
|
|
223
292
|
|
|
224
|
-
const loaded2Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
293
|
+
const loaded2Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
294
|
+
[
|
|
295
|
+
{
|
|
296
|
+
associatedEntityClass: TestEntity,
|
|
297
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
298
|
+
associatedEntityLookupByField: 'stringField',
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
viewerContext.getQueryContext()
|
|
302
|
+
);
|
|
231
303
|
expect(loaded2Result?.enforceValue().getID()).toEqual(testEntity2.getID());
|
|
232
304
|
});
|
|
233
305
|
|
|
@@ -236,16 +308,21 @@ describe(EntityAssociationLoader, () => {
|
|
|
236
308
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
237
309
|
|
|
238
310
|
const testEntity = await enforceAsyncResult(
|
|
239
|
-
TestEntity2.creator(viewerContext
|
|
311
|
+
TestEntity2.creator(viewerContext, viewerContext.getQueryContext())
|
|
312
|
+
.setField('foreignKey', uuidv4())
|
|
313
|
+
.createAsync()
|
|
240
314
|
);
|
|
241
315
|
|
|
242
|
-
const loaded2Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
316
|
+
const loaded2Result = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
317
|
+
[
|
|
318
|
+
{
|
|
319
|
+
associatedEntityClass: TestEntity,
|
|
320
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
321
|
+
associatedEntityLookupByField: 'stringField',
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
viewerContext.getQueryContext()
|
|
325
|
+
);
|
|
249
326
|
expect(loaded2Result).toBeNull();
|
|
250
327
|
});
|
|
251
328
|
|
|
@@ -254,15 +331,20 @@ describe(EntityAssociationLoader, () => {
|
|
|
254
331
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
255
332
|
|
|
256
333
|
const testEntity = await enforceAsyncResult(
|
|
257
|
-
TestEntity.creator(viewerContext
|
|
334
|
+
TestEntity.creator(viewerContext, viewerContext.getQueryContext())
|
|
335
|
+
.setField('nullableField', null)
|
|
336
|
+
.createAsync()
|
|
258
337
|
);
|
|
259
338
|
|
|
260
|
-
const loadedResult = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
339
|
+
const loadedResult = await testEntity.associationLoader().loadAssociatedEntityThroughAsync(
|
|
340
|
+
[
|
|
341
|
+
{
|
|
342
|
+
associatedEntityClass: TestEntity,
|
|
343
|
+
fieldIdentifyingAssociatedEntity: 'nullableField',
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
viewerContext.getQueryContext()
|
|
347
|
+
);
|
|
266
348
|
expect(loadedResult).toBeNull();
|
|
267
349
|
});
|
|
268
350
|
});
|
|
@@ -7,15 +7,15 @@ import EntityConfiguration from '../EntityConfiguration';
|
|
|
7
7
|
import { UUIDField } from '../EntityFields';
|
|
8
8
|
import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from '../EntityPrivacyPolicy';
|
|
9
9
|
import { EntityQueryContext } from '../EntityQueryContext';
|
|
10
|
-
import ViewerContext from '../ViewerContext';
|
|
11
10
|
import { enforceResultsAsync } from '../entityUtils';
|
|
12
11
|
import EntityNotAuthorizedError from '../errors/EntityNotAuthorizedError';
|
|
13
12
|
import AlwaysAllowPrivacyPolicyRule from '../rules/AlwaysAllowPrivacyPolicyRule';
|
|
14
13
|
import AlwaysDenyPrivacyPolicyRule from '../rules/AlwaysDenyPrivacyPolicyRule';
|
|
15
14
|
import PrivacyPolicyRule, { RuleEvaluationResult } from '../rules/PrivacyPolicyRule';
|
|
15
|
+
import TestViewerContext from '../testfixtures/TestViewerContext';
|
|
16
16
|
import { createUnitTestEntityCompanionProvider } from '../utils/testing/createUnitTestEntityCompanionProvider';
|
|
17
17
|
|
|
18
|
-
class TestUserViewerContext extends
|
|
18
|
+
class TestUserViewerContext extends TestViewerContext {
|
|
19
19
|
constructor(entityCompanionProvider: EntityCompanionProvider, private readonly userID: string) {
|
|
20
20
|
super(entityCompanionProvider);
|
|
21
21
|
}
|
|
@@ -82,23 +82,23 @@ class DenyIfNotOwnerPrivacyPolicyRule extends PrivacyPolicyRule<
|
|
|
82
82
|
class BlahEntityPrivacyPolicy extends EntityPrivacyPolicy<
|
|
83
83
|
BlahFields,
|
|
84
84
|
string,
|
|
85
|
-
|
|
85
|
+
TestUserViewerContext,
|
|
86
86
|
BlahEntity
|
|
87
87
|
> {
|
|
88
88
|
protected override readonly createRules = [
|
|
89
89
|
new DenyIfNotOwnerPrivacyPolicyRule(),
|
|
90
|
-
new AlwaysAllowPrivacyPolicyRule<BlahFields, string,
|
|
90
|
+
new AlwaysAllowPrivacyPolicyRule<BlahFields, string, TestUserViewerContext, BlahEntity>(),
|
|
91
91
|
];
|
|
92
92
|
protected override readonly readRules = [
|
|
93
93
|
new DenyIfNotOwnerPrivacyPolicyRule(),
|
|
94
|
-
new AlwaysAllowPrivacyPolicyRule<BlahFields, string,
|
|
94
|
+
new AlwaysAllowPrivacyPolicyRule<BlahFields, string, TestUserViewerContext, BlahEntity>(),
|
|
95
95
|
];
|
|
96
96
|
protected override readonly updateRules = [
|
|
97
97
|
new DenyIfNotOwnerPrivacyPolicyRule(),
|
|
98
|
-
new AlwaysAllowPrivacyPolicyRule<BlahFields, string,
|
|
98
|
+
new AlwaysAllowPrivacyPolicyRule<BlahFields, string, TestUserViewerContext, BlahEntity>(),
|
|
99
99
|
];
|
|
100
100
|
protected override readonly deleteRules = [
|
|
101
|
-
new AlwaysDenyPrivacyPolicyRule<BlahFields, string,
|
|
101
|
+
new AlwaysDenyPrivacyPolicyRule<BlahFields, string, TestUserViewerContext, BlahEntity>(),
|
|
102
102
|
];
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -110,15 +110,21 @@ it('runs through a common workflow', async () => {
|
|
|
110
110
|
const vc2 = new TestUserViewerContext(entityCompanionProvider, uuidv4());
|
|
111
111
|
|
|
112
112
|
const blahOwner1 = await enforceAsyncResult(
|
|
113
|
-
BlahEntity.creator(vc1
|
|
113
|
+
BlahEntity.creator(vc1, vc1.getQueryContext())
|
|
114
|
+
.setField('ownerID', vc1.getUserID()!)
|
|
115
|
+
.createAsync()
|
|
114
116
|
);
|
|
115
117
|
|
|
116
118
|
await enforceAsyncResult(
|
|
117
|
-
BlahEntity.creator(vc1
|
|
119
|
+
BlahEntity.creator(vc1, vc1.getQueryContext())
|
|
120
|
+
.setField('ownerID', vc1.getUserID()!)
|
|
121
|
+
.createAsync()
|
|
118
122
|
);
|
|
119
123
|
|
|
120
124
|
const blahOwner2 = await enforceAsyncResult(
|
|
121
|
-
BlahEntity.creator(vc2
|
|
125
|
+
BlahEntity.creator(vc2, vc2.getQueryContext())
|
|
126
|
+
.setField('ownerID', vc2.getUserID()!)
|
|
127
|
+
.createAsync()
|
|
122
128
|
);
|
|
123
129
|
|
|
124
130
|
// sanity check created objects
|
|
@@ -127,33 +133,45 @@ it('runs through a common workflow', async () => {
|
|
|
127
133
|
|
|
128
134
|
// check that two people can't read each others data
|
|
129
135
|
await expect(
|
|
130
|
-
enforceAsyncResult(
|
|
136
|
+
enforceAsyncResult(
|
|
137
|
+
BlahEntity.loader(vc1, vc1.getQueryContext()).loadByIDAsync(blahOwner2.getID())
|
|
138
|
+
)
|
|
131
139
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
132
140
|
await expect(
|
|
133
|
-
enforceAsyncResult(
|
|
141
|
+
enforceAsyncResult(
|
|
142
|
+
BlahEntity.loader(vc2, vc2.getQueryContext()).loadByIDAsync(blahOwner1.getID())
|
|
143
|
+
)
|
|
134
144
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
135
145
|
|
|
136
146
|
// check that all of owner 1's objects can be loaded
|
|
137
147
|
const results = await enforceResultsAsync(
|
|
138
|
-
BlahEntity.loader(vc1
|
|
148
|
+
BlahEntity.loader(vc1, vc1.getQueryContext()).loadManyByFieldEqualingAsync(
|
|
149
|
+
'ownerID',
|
|
150
|
+
vc1.getUserID()!
|
|
151
|
+
)
|
|
139
152
|
);
|
|
140
153
|
expect(results).toHaveLength(2);
|
|
141
154
|
|
|
142
155
|
// check that two people can't create objects owned by others
|
|
143
156
|
await expect(
|
|
144
157
|
enforceAsyncResult(
|
|
145
|
-
BlahEntity.creator(vc2
|
|
158
|
+
BlahEntity.creator(vc2, vc2.getQueryContext())
|
|
159
|
+
.setField('ownerID', blahOwner1.getID())
|
|
160
|
+
.createAsync()
|
|
146
161
|
)
|
|
147
162
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
148
163
|
|
|
149
164
|
// check that empty load many returns nothing
|
|
150
|
-
const results2 = await BlahEntity.loader(
|
|
165
|
+
const results2 = await BlahEntity.loader(
|
|
166
|
+
vc1,
|
|
167
|
+
vc1.getQueryContext()
|
|
168
|
+
).loadManyByFieldEqualingManyAsync('ownerID', []);
|
|
151
169
|
for (const value in results2.values) {
|
|
152
170
|
expect(value).toHaveLength(0);
|
|
153
171
|
}
|
|
154
172
|
|
|
155
173
|
// check that the user can't delete their own data (as specified by privacy rules)
|
|
156
|
-
await expect(
|
|
157
|
-
|
|
158
|
-
);
|
|
174
|
+
await expect(
|
|
175
|
+
enforceAsyncResult(BlahEntity.deleteAsync(blahOwner2, vc1.getQueryContext()))
|
|
176
|
+
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
159
177
|
});
|