@expo/entity 0.40.0 → 0.41.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/AuthorizationResultBasedEntityAssociationLoader.js +2 -4
- package/build/AuthorizationResultBasedEntityAssociationLoader.js.map +1 -1
- package/build/Entity.d.ts +28 -6
- package/build/Entity.js +41 -3
- package/build/Entity.js.map +1 -1
- package/build/ReadonlyEntity.d.ts +24 -5
- package/build/ReadonlyEntity.js +31 -3
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js +37 -68
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/Entity-test.js +49 -9
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +4 -4
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +9 -17
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +32 -64
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +3 -3
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +4 -8
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +6 -6
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +35 -81
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ReadonlyEntity-test.js +39 -6
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +4 -10
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +7 -22
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +13 -47
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -1
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js +2 -5
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js.map +1 -1
- package/package.json +2 -2
- package/src/AuthorizationResultBasedEntityAssociationLoader.ts +2 -4
- package/src/Entity.ts +163 -7
- package/src/ReadonlyEntity.ts +119 -6
- package/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts +37 -68
- package/src/__tests__/Entity-test.ts +62 -9
- package/src/__tests__/EntityAssociationLoader-test.ts +4 -6
- package/src/__tests__/EntityCommonUseCases-test.ts +14 -17
- package/src/__tests__/EntityEdges-test.ts +36 -64
- package/src/__tests__/EntityLoader-test.ts +3 -5
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +6 -8
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +6 -6
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +53 -81
- package/src/__tests__/ReadonlyEntity-test.ts +46 -6
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +13 -15
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +16 -22
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +19 -47
- package/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts +2 -5
package/src/ReadonlyEntity.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
2
|
|
|
3
|
+
import AuthorizationResultBasedEntityAssociationLoader from './AuthorizationResultBasedEntityAssociationLoader';
|
|
4
|
+
import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader';
|
|
5
|
+
import EnforcingEntityAssociationLoader from './EnforcingEntityAssociationLoader';
|
|
6
|
+
import EnforcingEntityLoader from './EnforcingEntityLoader';
|
|
3
7
|
import { IEntityClass } from './Entity';
|
|
4
8
|
import EntityAssociationLoader from './EntityAssociationLoader';
|
|
5
9
|
import EntityLoader from './EntityLoader';
|
|
10
|
+
import EntityLoaderUtils from './EntityLoaderUtils';
|
|
6
11
|
import EntityPrivacyPolicy from './EntityPrivacyPolicy';
|
|
7
12
|
import { EntityQueryContext } from './EntityQueryContext';
|
|
8
13
|
import ViewerContext from './ViewerContext';
|
|
@@ -82,12 +87,33 @@ export default abstract class ReadonlyEntity<
|
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
/**
|
|
85
|
-
* @returns
|
|
90
|
+
* @returns EnforcingEntityAssociationLoader for this entity
|
|
86
91
|
*/
|
|
87
92
|
associationLoader(
|
|
88
93
|
queryContext?: EntityQueryContext,
|
|
89
|
-
):
|
|
90
|
-
return new EntityAssociationLoader
|
|
94
|
+
): EnforcingEntityAssociationLoader<TFields, TID, TViewerContext, this, TSelectedFields> {
|
|
95
|
+
return new EntityAssociationLoader<TFields, TID, TViewerContext, this, TSelectedFields>(
|
|
96
|
+
this,
|
|
97
|
+
queryContext,
|
|
98
|
+
).enforcing();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @returns AuthorizationResultBasedEntityAssociationLoader for this entity
|
|
103
|
+
*/
|
|
104
|
+
associationLoaderWithAuthorizationResults(
|
|
105
|
+
queryContext?: EntityQueryContext,
|
|
106
|
+
): AuthorizationResultBasedEntityAssociationLoader<
|
|
107
|
+
TFields,
|
|
108
|
+
TID,
|
|
109
|
+
TViewerContext,
|
|
110
|
+
this,
|
|
111
|
+
TSelectedFields
|
|
112
|
+
> {
|
|
113
|
+
return new EntityAssociationLoader<TFields, TID, TViewerContext, this, TSelectedFields>(
|
|
114
|
+
this,
|
|
115
|
+
queryContext,
|
|
116
|
+
).withAuthorizationResults();
|
|
91
117
|
}
|
|
92
118
|
|
|
93
119
|
/**
|
|
@@ -148,15 +174,102 @@ export default abstract class ReadonlyEntity<
|
|
|
148
174
|
.getViewerScopedEntityCompanionForClass(this)
|
|
149
175
|
.getQueryContextProvider()
|
|
150
176
|
.getQueryContext(),
|
|
151
|
-
):
|
|
177
|
+
): EnforcingEntityLoader<
|
|
178
|
+
TMFields,
|
|
179
|
+
TMID,
|
|
180
|
+
TMViewerContext,
|
|
181
|
+
TMEntity,
|
|
182
|
+
TMPrivacyPolicy,
|
|
183
|
+
TMSelectedFields
|
|
184
|
+
> {
|
|
185
|
+
return new EntityLoader(viewerContext, queryContext, this).enforcing();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Vend loader for loading an entity in a given query context.
|
|
190
|
+
* @param viewerContext - viewer context of loading user
|
|
191
|
+
* @param queryContext - query context in which to perform the load
|
|
192
|
+
*/
|
|
193
|
+
static loaderWithAuthorizationResults<
|
|
194
|
+
TMFields extends object,
|
|
195
|
+
TMID extends NonNullable<TMFields[TMSelectedFields]>,
|
|
196
|
+
TMViewerContext extends ViewerContext,
|
|
197
|
+
TMViewerContext2 extends TMViewerContext,
|
|
198
|
+
TMEntity extends ReadonlyEntity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
|
|
199
|
+
TMPrivacyPolicy extends EntityPrivacyPolicy<
|
|
200
|
+
TMFields,
|
|
201
|
+
TMID,
|
|
202
|
+
TMViewerContext,
|
|
203
|
+
TMEntity,
|
|
204
|
+
TMSelectedFields
|
|
205
|
+
>,
|
|
206
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
207
|
+
>(
|
|
208
|
+
this: IEntityClass<
|
|
209
|
+
TMFields,
|
|
210
|
+
TMID,
|
|
211
|
+
TMViewerContext,
|
|
212
|
+
TMEntity,
|
|
213
|
+
TMPrivacyPolicy,
|
|
214
|
+
TMSelectedFields
|
|
215
|
+
>,
|
|
216
|
+
viewerContext: TMViewerContext2,
|
|
217
|
+
queryContext: EntityQueryContext = viewerContext
|
|
218
|
+
.getViewerScopedEntityCompanionForClass(this)
|
|
219
|
+
.getQueryContextProvider()
|
|
220
|
+
.getQueryContext(),
|
|
221
|
+
): AuthorizationResultBasedEntityLoader<
|
|
222
|
+
TMFields,
|
|
223
|
+
TMID,
|
|
224
|
+
TMViewerContext,
|
|
225
|
+
TMEntity,
|
|
226
|
+
TMPrivacyPolicy,
|
|
227
|
+
TMSelectedFields
|
|
228
|
+
> {
|
|
229
|
+
return new EntityLoader(viewerContext, queryContext, this).withAuthorizationResults();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Vend loader for loading an entity in a given query context.
|
|
234
|
+
* @param viewerContext - viewer context of loading user
|
|
235
|
+
* @param queryContext - query context in which to perform the load
|
|
236
|
+
*/
|
|
237
|
+
static loaderUtils<
|
|
238
|
+
TMFields extends object,
|
|
239
|
+
TMID extends NonNullable<TMFields[TMSelectedFields]>,
|
|
240
|
+
TMViewerContext extends ViewerContext,
|
|
241
|
+
TMViewerContext2 extends TMViewerContext,
|
|
242
|
+
TMEntity extends ReadonlyEntity<TMFields, TMID, TMViewerContext, TMSelectedFields>,
|
|
243
|
+
TMPrivacyPolicy extends EntityPrivacyPolicy<
|
|
244
|
+
TMFields,
|
|
245
|
+
TMID,
|
|
246
|
+
TMViewerContext,
|
|
247
|
+
TMEntity,
|
|
248
|
+
TMSelectedFields
|
|
249
|
+
>,
|
|
250
|
+
TMSelectedFields extends keyof TMFields = keyof TMFields,
|
|
251
|
+
>(
|
|
252
|
+
this: IEntityClass<
|
|
253
|
+
TMFields,
|
|
254
|
+
TMID,
|
|
255
|
+
TMViewerContext,
|
|
256
|
+
TMEntity,
|
|
257
|
+
TMPrivacyPolicy,
|
|
258
|
+
TMSelectedFields
|
|
259
|
+
>,
|
|
260
|
+
viewerContext: TMViewerContext2,
|
|
261
|
+
queryContext: EntityQueryContext = viewerContext
|
|
262
|
+
.getViewerScopedEntityCompanionForClass(this)
|
|
263
|
+
.getQueryContextProvider()
|
|
264
|
+
.getQueryContext(),
|
|
265
|
+
): EntityLoaderUtils<
|
|
152
266
|
TMFields,
|
|
153
267
|
TMID,
|
|
154
268
|
TMViewerContext,
|
|
155
|
-
TMViewerContext2,
|
|
156
269
|
TMEntity,
|
|
157
270
|
TMPrivacyPolicy,
|
|
158
271
|
TMSelectedFields
|
|
159
272
|
> {
|
|
160
|
-
return new EntityLoader(viewerContext, queryContext, this);
|
|
273
|
+
return new EntityLoader(viewerContext, queryContext, this).utils();
|
|
161
274
|
}
|
|
162
275
|
}
|
|
@@ -14,26 +14,23 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
14
14
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
15
15
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
16
16
|
const testOtherEntity = await enforceAsyncResult(
|
|
17
|
-
TestEntity.
|
|
17
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(),
|
|
18
18
|
);
|
|
19
19
|
const testEntity = await enforceAsyncResult(
|
|
20
|
-
TestEntity.
|
|
21
|
-
.withAuthorizationResults()
|
|
20
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
22
21
|
.setField('stringField', testOtherEntity.getID())
|
|
23
22
|
.createAsync(),
|
|
24
23
|
);
|
|
25
24
|
const loadedOther = await enforceAsyncResult(
|
|
26
25
|
testEntity
|
|
27
|
-
.
|
|
28
|
-
.withAuthorizationResults()
|
|
26
|
+
.associationLoaderWithAuthorizationResults()
|
|
29
27
|
.loadAssociatedEntityAsync('stringField', TestEntity),
|
|
30
28
|
);
|
|
31
29
|
expect(loadedOther.getID()).toEqual(testOtherEntity.getID());
|
|
32
30
|
|
|
33
31
|
const loadedOther2 = await enforceAsyncResult(
|
|
34
32
|
testEntity
|
|
35
|
-
.
|
|
36
|
-
.withAuthorizationResults()
|
|
33
|
+
.associationLoaderWithAuthorizationResults()
|
|
37
34
|
.loadAssociatedEntityAsync('nullableField', TestEntity),
|
|
38
35
|
);
|
|
39
36
|
expect(loadedOther2).toBeNull();
|
|
@@ -45,24 +42,21 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
45
42
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
46
43
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
47
44
|
const testEntity = await enforceAsyncResult(
|
|
48
|
-
TestEntity.
|
|
45
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(),
|
|
49
46
|
);
|
|
50
47
|
const testOtherEntity1 = await enforceAsyncResult(
|
|
51
|
-
TestEntity.
|
|
52
|
-
.withAuthorizationResults()
|
|
48
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
53
49
|
.setField('stringField', testEntity.getID())
|
|
54
50
|
.createAsync(),
|
|
55
51
|
);
|
|
56
52
|
const testOtherEntity2 = await enforceAsyncResult(
|
|
57
|
-
TestEntity.
|
|
58
|
-
.withAuthorizationResults()
|
|
53
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
59
54
|
.setField('stringField', testEntity.getID())
|
|
60
55
|
.createAsync(),
|
|
61
56
|
);
|
|
62
57
|
const loaded = await enforceResultsAsync(
|
|
63
58
|
testEntity
|
|
64
|
-
.
|
|
65
|
-
.withAuthorizationResults()
|
|
59
|
+
.associationLoaderWithAuthorizationResults()
|
|
66
60
|
.loadManyAssociatedEntitiesAsync(TestEntity, 'stringField'),
|
|
67
61
|
);
|
|
68
62
|
expect(loaded).toHaveLength(2);
|
|
@@ -76,17 +70,15 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
76
70
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
77
71
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
78
72
|
const testOtherEntity = await enforceAsyncResult(
|
|
79
|
-
TestEntity.
|
|
73
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(),
|
|
80
74
|
);
|
|
81
75
|
const testEntity = await enforceAsyncResult(
|
|
82
|
-
TestEntity.
|
|
83
|
-
.withAuthorizationResults()
|
|
76
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
84
77
|
.setField('stringField', testOtherEntity.getID())
|
|
85
78
|
.createAsync(),
|
|
86
79
|
);
|
|
87
80
|
const loadedOtherResult = await testEntity
|
|
88
|
-
.
|
|
89
|
-
.withAuthorizationResults()
|
|
81
|
+
.associationLoaderWithAuthorizationResults()
|
|
90
82
|
.loadAssociatedEntityByFieldEqualingAsync('stringField', TestEntity, 'customIdField');
|
|
91
83
|
expect(loadedOtherResult?.enforceValue().getID()).toEqual(testOtherEntity.getID());
|
|
92
84
|
});
|
|
@@ -95,14 +87,12 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
95
87
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
96
88
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
97
89
|
const testEntity = await enforceAsyncResult(
|
|
98
|
-
TestEntity.
|
|
99
|
-
.withAuthorizationResults()
|
|
90
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
100
91
|
.setField('stringField', uuidv4())
|
|
101
92
|
.createAsync(),
|
|
102
93
|
);
|
|
103
94
|
const loadedOtherResult = await testEntity
|
|
104
|
-
.
|
|
105
|
-
.withAuthorizationResults()
|
|
95
|
+
.associationLoaderWithAuthorizationResults()
|
|
106
96
|
.loadAssociatedEntityByFieldEqualingAsync('stringField', TestEntity, 'customIdField');
|
|
107
97
|
expect(loadedOtherResult).toBeNull();
|
|
108
98
|
});
|
|
@@ -111,14 +101,12 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
111
101
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
112
102
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
113
103
|
const testEntity = await enforceAsyncResult(
|
|
114
|
-
TestEntity.
|
|
115
|
-
.withAuthorizationResults()
|
|
104
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
116
105
|
.setField('stringField', 'blah')
|
|
117
106
|
.createAsync(),
|
|
118
107
|
);
|
|
119
108
|
const loadedOtherResult = await testEntity
|
|
120
|
-
.
|
|
121
|
-
.withAuthorizationResults()
|
|
109
|
+
.associationLoaderWithAuthorizationResults()
|
|
122
110
|
.loadAssociatedEntityByFieldEqualingAsync('nullableField', TestEntity, 'customIdField');
|
|
123
111
|
expect(loadedOtherResult).toBeNull();
|
|
124
112
|
});
|
|
@@ -129,24 +117,21 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
129
117
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
130
118
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
131
119
|
const testEntity = await enforceAsyncResult(
|
|
132
|
-
TestEntity.
|
|
120
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(),
|
|
133
121
|
);
|
|
134
122
|
const testOtherEntity1 = await enforceAsyncResult(
|
|
135
|
-
TestEntity.
|
|
136
|
-
.withAuthorizationResults()
|
|
123
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
137
124
|
.setField('stringField', testEntity.getID())
|
|
138
125
|
.createAsync(),
|
|
139
126
|
);
|
|
140
127
|
const testOtherEntity2 = await enforceAsyncResult(
|
|
141
|
-
TestEntity.
|
|
142
|
-
.withAuthorizationResults()
|
|
128
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
143
129
|
.setField('stringField', testEntity.getID())
|
|
144
130
|
.createAsync(),
|
|
145
131
|
);
|
|
146
132
|
const loaded = await enforceResultsAsync(
|
|
147
133
|
testEntity
|
|
148
|
-
.
|
|
149
|
-
.withAuthorizationResults()
|
|
134
|
+
.associationLoaderWithAuthorizationResults()
|
|
150
135
|
.loadManyAssociatedEntitiesByFieldEqualingAsync(
|
|
151
136
|
'customIdField',
|
|
152
137
|
TestEntity,
|
|
@@ -162,12 +147,11 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
162
147
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
163
148
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
164
149
|
const testEntity = await enforceAsyncResult(
|
|
165
|
-
TestEntity.
|
|
150
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(),
|
|
166
151
|
);
|
|
167
152
|
const loaded = await enforceResultsAsync(
|
|
168
153
|
testEntity
|
|
169
|
-
.
|
|
170
|
-
.withAuthorizationResults()
|
|
154
|
+
.associationLoaderWithAuthorizationResults()
|
|
171
155
|
.loadManyAssociatedEntitiesByFieldEqualingAsync(
|
|
172
156
|
'nullableField',
|
|
173
157
|
TestEntity,
|
|
@@ -183,30 +167,26 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
183
167
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
184
168
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
185
169
|
const testEntity4 = await enforceAsyncResult(
|
|
186
|
-
TestEntity.
|
|
170
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(),
|
|
187
171
|
);
|
|
188
172
|
const testEntity3 = await enforceAsyncResult(
|
|
189
|
-
TestEntity2.
|
|
190
|
-
.withAuthorizationResults()
|
|
173
|
+
TestEntity2.creatorWithAuthorizationResults(viewerContext)
|
|
191
174
|
.setField('foreignKey', testEntity4.getID())
|
|
192
175
|
.createAsync(),
|
|
193
176
|
);
|
|
194
177
|
const testEntity2 = await enforceAsyncResult(
|
|
195
|
-
TestEntity.
|
|
196
|
-
.withAuthorizationResults()
|
|
178
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
197
179
|
.setField('testIndexedField', testEntity3.getID())
|
|
198
180
|
.createAsync(),
|
|
199
181
|
);
|
|
200
182
|
const testEntity = await enforceAsyncResult(
|
|
201
|
-
TestEntity2.
|
|
202
|
-
.withAuthorizationResults()
|
|
183
|
+
TestEntity2.creatorWithAuthorizationResults(viewerContext)
|
|
203
184
|
.setField('foreignKey', testEntity2.getID())
|
|
204
185
|
.createAsync(),
|
|
205
186
|
);
|
|
206
187
|
|
|
207
188
|
const loaded2Result = await testEntity
|
|
208
|
-
.
|
|
209
|
-
.withAuthorizationResults()
|
|
189
|
+
.associationLoaderWithAuthorizationResults()
|
|
210
190
|
.loadAssociatedEntityThroughAsync([
|
|
211
191
|
{
|
|
212
192
|
associatedEntityClass: TestEntity,
|
|
@@ -216,8 +196,7 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
216
196
|
expect(loaded2Result?.enforceValue().getID()).toEqual(testEntity2.getID());
|
|
217
197
|
|
|
218
198
|
const loaded3Result = await testEntity
|
|
219
|
-
.
|
|
220
|
-
.withAuthorizationResults()
|
|
199
|
+
.associationLoaderWithAuthorizationResults()
|
|
221
200
|
.loadAssociatedEntityThroughAsync([
|
|
222
201
|
{
|
|
223
202
|
associatedEntityClass: TestEntity,
|
|
@@ -231,8 +210,7 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
231
210
|
expect(loaded3Result?.enforceValue().getID()).toEqual(testEntity3.getID());
|
|
232
211
|
|
|
233
212
|
const loaded4Result = await testEntity
|
|
234
|
-
.
|
|
235
|
-
.withAuthorizationResults()
|
|
213
|
+
.associationLoaderWithAuthorizationResults()
|
|
236
214
|
.loadAssociatedEntityThroughAsync([
|
|
237
215
|
{
|
|
238
216
|
associatedEntityClass: TestEntity,
|
|
@@ -255,15 +233,13 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
255
233
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
256
234
|
|
|
257
235
|
const testEntity = await enforceAsyncResult(
|
|
258
|
-
TestEntity2.
|
|
259
|
-
.withAuthorizationResults()
|
|
236
|
+
TestEntity2.creatorWithAuthorizationResults(viewerContext)
|
|
260
237
|
.setField('foreignKey', uuidv4())
|
|
261
238
|
.createAsync(),
|
|
262
239
|
);
|
|
263
240
|
|
|
264
241
|
const loadResult = await testEntity
|
|
265
|
-
.
|
|
266
|
-
.withAuthorizationResults()
|
|
242
|
+
.associationLoaderWithAuthorizationResults()
|
|
267
243
|
.loadAssociatedEntityThroughAsync([
|
|
268
244
|
{
|
|
269
245
|
associatedEntityClass: TestEntity,
|
|
@@ -279,21 +255,18 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
279
255
|
|
|
280
256
|
const fieldValue = uuidv4();
|
|
281
257
|
const testEntity2 = await enforceAsyncResult(
|
|
282
|
-
TestEntity.
|
|
283
|
-
.withAuthorizationResults()
|
|
258
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
284
259
|
.setField('stringField', fieldValue)
|
|
285
260
|
.createAsync(),
|
|
286
261
|
);
|
|
287
262
|
const testEntity = await enforceAsyncResult(
|
|
288
|
-
TestEntity2.
|
|
289
|
-
.withAuthorizationResults()
|
|
263
|
+
TestEntity2.creatorWithAuthorizationResults(viewerContext)
|
|
290
264
|
.setField('foreignKey', fieldValue)
|
|
291
265
|
.createAsync(),
|
|
292
266
|
);
|
|
293
267
|
|
|
294
268
|
const loaded2Result = await testEntity
|
|
295
|
-
.
|
|
296
|
-
.withAuthorizationResults()
|
|
269
|
+
.associationLoaderWithAuthorizationResults()
|
|
297
270
|
.loadAssociatedEntityThroughAsync([
|
|
298
271
|
{
|
|
299
272
|
associatedEntityClass: TestEntity,
|
|
@@ -309,15 +282,13 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
309
282
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
310
283
|
|
|
311
284
|
const testEntity = await enforceAsyncResult(
|
|
312
|
-
TestEntity2.
|
|
313
|
-
.withAuthorizationResults()
|
|
285
|
+
TestEntity2.creatorWithAuthorizationResults(viewerContext)
|
|
314
286
|
.setField('foreignKey', uuidv4())
|
|
315
287
|
.createAsync(),
|
|
316
288
|
);
|
|
317
289
|
|
|
318
290
|
const loaded2Result = await testEntity
|
|
319
|
-
.
|
|
320
|
-
.withAuthorizationResults()
|
|
291
|
+
.associationLoaderWithAuthorizationResults()
|
|
321
292
|
.loadAssociatedEntityThroughAsync([
|
|
322
293
|
{
|
|
323
294
|
associatedEntityClass: TestEntity,
|
|
@@ -333,15 +304,13 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
|
333
304
|
const viewerContext = new TestViewerContext(companionProvider);
|
|
334
305
|
|
|
335
306
|
const testEntity = await enforceAsyncResult(
|
|
336
|
-
TestEntity.
|
|
337
|
-
.withAuthorizationResults()
|
|
307
|
+
TestEntity.creatorWithAuthorizationResults(viewerContext)
|
|
338
308
|
.setField('nullableField', null)
|
|
339
309
|
.createAsync(),
|
|
340
310
|
);
|
|
341
311
|
|
|
342
312
|
const loadedResult = await testEntity
|
|
343
|
-
.
|
|
344
|
-
.withAuthorizationResults()
|
|
313
|
+
.associationLoaderWithAuthorizationResults()
|
|
345
314
|
.loadAssociatedEntityThroughAsync([
|
|
346
315
|
{
|
|
347
316
|
associatedEntityClass: TestEntity,
|
|
@@ -1,22 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationResultBasedCreateMutator,
|
|
3
|
+
AuthorizationResultBasedDeleteMutator,
|
|
4
|
+
AuthorizationResultBasedUpdateMutator,
|
|
5
|
+
} from '../AuthorizationResultBasedEntityMutator';
|
|
6
|
+
import EnforcingEntityCreator from '../EnforcingEntityCreator';
|
|
7
|
+
import EnforcingEntityDeleter from '../EnforcingEntityDeleter';
|
|
8
|
+
import EnforcingEntityUpdater from '../EnforcingEntityUpdater';
|
|
1
9
|
import Entity from '../Entity';
|
|
2
|
-
import EntityCreator from '../EntityCreator';
|
|
3
|
-
import EntityDeleter from '../EntityDeleter';
|
|
4
|
-
import EntityUpdater from '../EntityUpdater';
|
|
5
10
|
import ViewerContext from '../ViewerContext';
|
|
6
11
|
import SimpleTestEntity from '../testfixtures/SimpleTestEntity';
|
|
7
12
|
import { createUnitTestEntityCompanionProvider } from '../utils/testing/createUnitTestEntityCompanionProvider';
|
|
8
13
|
|
|
9
14
|
describe(Entity, () => {
|
|
10
15
|
describe('creator', () => {
|
|
11
|
-
it('creates a new
|
|
16
|
+
it('creates a new EnforcingEntityCreator', () => {
|
|
12
17
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
13
18
|
const viewerContext = new ViewerContext(companionProvider);
|
|
14
|
-
expect(SimpleTestEntity.creator(viewerContext)).toBeInstanceOf(
|
|
19
|
+
expect(SimpleTestEntity.creator(viewerContext)).toBeInstanceOf(EnforcingEntityCreator);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('creatorWithAuthorizationResults', () => {
|
|
24
|
+
it('creates a new AuthorizationResultBasedCreateMutator', () => {
|
|
25
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
26
|
+
const viewerContext = new ViewerContext(companionProvider);
|
|
27
|
+
expect(SimpleTestEntity.creatorWithAuthorizationResults(viewerContext)).toBeInstanceOf(
|
|
28
|
+
AuthorizationResultBasedCreateMutator,
|
|
29
|
+
);
|
|
15
30
|
});
|
|
16
31
|
});
|
|
17
32
|
|
|
18
33
|
describe('updater', () => {
|
|
19
|
-
it('creates a new
|
|
34
|
+
it('creates a new EnforcingEntityUpdater', () => {
|
|
20
35
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
21
36
|
const viewerContext = new ViewerContext(companionProvider);
|
|
22
37
|
const data = {
|
|
@@ -28,12 +43,48 @@ describe(Entity, () => {
|
|
|
28
43
|
databaseFields: data,
|
|
29
44
|
selectedFields: data,
|
|
30
45
|
});
|
|
31
|
-
expect(SimpleTestEntity.updater(testEntity)).toBeInstanceOf(
|
|
46
|
+
expect(SimpleTestEntity.updater(testEntity)).toBeInstanceOf(EnforcingEntityUpdater);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('updaterWithAuthorizationResults', () => {
|
|
51
|
+
it('creates a new AuthorizationResultBasedUpdateMutator', () => {
|
|
52
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
53
|
+
const viewerContext = new ViewerContext(companionProvider);
|
|
54
|
+
const data = {
|
|
55
|
+
id: 'what',
|
|
56
|
+
};
|
|
57
|
+
const testEntity = new SimpleTestEntity({
|
|
58
|
+
viewerContext,
|
|
59
|
+
id: 'what',
|
|
60
|
+
databaseFields: data,
|
|
61
|
+
selectedFields: data,
|
|
62
|
+
});
|
|
63
|
+
expect(SimpleTestEntity.updaterWithAuthorizationResults(testEntity)).toBeInstanceOf(
|
|
64
|
+
AuthorizationResultBasedUpdateMutator,
|
|
65
|
+
);
|
|
32
66
|
});
|
|
33
67
|
});
|
|
34
68
|
|
|
35
69
|
describe('deleter', () => {
|
|
36
|
-
it('creates a new
|
|
70
|
+
it('creates a new EnforcingEntityDeleter', () => {
|
|
71
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
72
|
+
const viewerContext = new ViewerContext(companionProvider);
|
|
73
|
+
const data = {
|
|
74
|
+
id: 'what',
|
|
75
|
+
};
|
|
76
|
+
const testEntity = new SimpleTestEntity({
|
|
77
|
+
viewerContext,
|
|
78
|
+
id: 'what',
|
|
79
|
+
databaseFields: data,
|
|
80
|
+
selectedFields: data,
|
|
81
|
+
});
|
|
82
|
+
expect(SimpleTestEntity.deleter(testEntity)).toBeInstanceOf(EnforcingEntityDeleter);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('deleterWithAuthorizationResults', () => {
|
|
87
|
+
it('creates a new AuthorizationResultBasedDeleteMutator', () => {
|
|
37
88
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
38
89
|
const viewerContext = new ViewerContext(companionProvider);
|
|
39
90
|
const data = {
|
|
@@ -45,7 +96,9 @@ describe(Entity, () => {
|
|
|
45
96
|
databaseFields: data,
|
|
46
97
|
selectedFields: data,
|
|
47
98
|
});
|
|
48
|
-
expect(SimpleTestEntity.
|
|
99
|
+
expect(SimpleTestEntity.deleterWithAuthorizationResults(testEntity)).toBeInstanceOf(
|
|
100
|
+
AuthorizationResultBasedDeleteMutator,
|
|
101
|
+
);
|
|
49
102
|
});
|
|
50
103
|
});
|
|
51
104
|
});
|
|
@@ -10,10 +10,8 @@ describe(EntityAssociationLoader, () => {
|
|
|
10
10
|
it('creates a new EnforcingEntityLoader', async () => {
|
|
11
11
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
12
12
|
const viewerContext = new ViewerContext(companionProvider);
|
|
13
|
-
const testEntity = await SimpleTestEntity.creator(viewerContext).
|
|
14
|
-
expect(testEntity.associationLoader()
|
|
15
|
-
EnforcingEntityAssociationLoader,
|
|
16
|
-
);
|
|
13
|
+
const testEntity = await SimpleTestEntity.creator(viewerContext).createAsync();
|
|
14
|
+
expect(testEntity.associationLoader()).toBeInstanceOf(EnforcingEntityAssociationLoader);
|
|
17
15
|
});
|
|
18
16
|
});
|
|
19
17
|
|
|
@@ -21,8 +19,8 @@ describe(EntityAssociationLoader, () => {
|
|
|
21
19
|
it('creates a new AuthorizationResultBasedEntityAssociationLoader', async () => {
|
|
22
20
|
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
23
21
|
const viewerContext = new ViewerContext(companionProvider);
|
|
24
|
-
const testEntity = await SimpleTestEntity.creator(viewerContext).
|
|
25
|
-
expect(testEntity.
|
|
22
|
+
const testEntity = await SimpleTestEntity.creator(viewerContext).createAsync();
|
|
23
|
+
expect(testEntity.associationLoaderWithAuthorizationResults()).toBeInstanceOf(
|
|
26
24
|
AuthorizationResultBasedEntityAssociationLoader,
|
|
27
25
|
);
|
|
28
26
|
});
|
|
@@ -118,22 +118,19 @@ it('runs through a common workflow', async () => {
|
|
|
118
118
|
const vc2 = new TestUserViewerContext(entityCompanionProvider, uuidv4());
|
|
119
119
|
|
|
120
120
|
const blahOwner1 = await enforceAsyncResult(
|
|
121
|
-
BlahEntity.
|
|
122
|
-
.withAuthorizationResults()
|
|
121
|
+
BlahEntity.creatorWithAuthorizationResults(vc1)
|
|
123
122
|
.setField('ownerID', vc1.getUserID())
|
|
124
123
|
.createAsync(),
|
|
125
124
|
);
|
|
126
125
|
|
|
127
126
|
await enforceAsyncResult(
|
|
128
|
-
BlahEntity.
|
|
129
|
-
.withAuthorizationResults()
|
|
127
|
+
BlahEntity.creatorWithAuthorizationResults(vc1)
|
|
130
128
|
.setField('ownerID', vc1.getUserID())
|
|
131
129
|
.createAsync(),
|
|
132
130
|
);
|
|
133
131
|
|
|
134
132
|
const blahOwner2 = await enforceAsyncResult(
|
|
135
|
-
BlahEntity.
|
|
136
|
-
.withAuthorizationResults()
|
|
133
|
+
BlahEntity.creatorWithAuthorizationResults(vc2)
|
|
137
134
|
.setField('ownerID', vc2.getUserID())
|
|
138
135
|
.createAsync(),
|
|
139
136
|
);
|
|
@@ -145,43 +142,43 @@ it('runs through a common workflow', async () => {
|
|
|
145
142
|
// check that two people can't read each others data
|
|
146
143
|
await expect(
|
|
147
144
|
enforceAsyncResult(
|
|
148
|
-
BlahEntity.
|
|
145
|
+
BlahEntity.loaderWithAuthorizationResults(vc1).loadByIDAsync(blahOwner2.getID()),
|
|
149
146
|
),
|
|
150
147
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
151
148
|
await expect(
|
|
152
149
|
enforceAsyncResult(
|
|
153
|
-
BlahEntity.
|
|
150
|
+
BlahEntity.loaderWithAuthorizationResults(vc2).loadByIDAsync(blahOwner1.getID()),
|
|
154
151
|
),
|
|
155
152
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
156
153
|
|
|
157
154
|
// check that all of owner 1's objects can be loaded
|
|
158
155
|
const results = await enforceResultsAsync(
|
|
159
|
-
BlahEntity.
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
BlahEntity.loaderWithAuthorizationResults(vc1).loadManyByFieldEqualingAsync(
|
|
157
|
+
'ownerID',
|
|
158
|
+
vc1.getUserID(),
|
|
159
|
+
),
|
|
162
160
|
);
|
|
163
161
|
expect(results).toHaveLength(2);
|
|
164
162
|
|
|
165
163
|
// check that two people can't create objects owned by others
|
|
166
164
|
await expect(
|
|
167
165
|
enforceAsyncResult(
|
|
168
|
-
BlahEntity.
|
|
169
|
-
.withAuthorizationResults()
|
|
166
|
+
BlahEntity.creatorWithAuthorizationResults(vc2)
|
|
170
167
|
.setField('ownerID', blahOwner1.getID())
|
|
171
168
|
.createAsync(),
|
|
172
169
|
),
|
|
173
170
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
174
171
|
|
|
175
172
|
// check that empty load many returns nothing
|
|
176
|
-
const results2 = await BlahEntity.
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
const results2 = await BlahEntity.loaderWithAuthorizationResults(
|
|
174
|
+
vc1,
|
|
175
|
+
).loadManyByFieldEqualingManyAsync('ownerID', []);
|
|
179
176
|
for (const value in results2.values) {
|
|
180
177
|
expect(value).toHaveLength(0);
|
|
181
178
|
}
|
|
182
179
|
|
|
183
180
|
// check that the user can't delete their own data (as specified by privacy rules)
|
|
184
181
|
await expect(
|
|
185
|
-
enforceAsyncResult(BlahEntity.
|
|
182
|
+
enforceAsyncResult(BlahEntity.deleterWithAuthorizationResults(blahOwner2).deleteAsync()),
|
|
186
183
|
).rejects.toBeInstanceOf(EntityNotAuthorizedError);
|
|
187
184
|
});
|