@expo/entity 0.38.0 → 0.40.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.d.ts +99 -0
- package/build/AuthorizationResultBasedEntityAssociationLoader.js +124 -0
- package/build/AuthorizationResultBasedEntityAssociationLoader.js.map +1 -0
- package/build/AuthorizationResultBasedEntityLoader.d.ts +1 -1
- package/build/AuthorizationResultBasedEntityLoader.js.map +1 -1
- package/build/{EntityMutator.d.ts → AuthorizationResultBasedEntityMutator.d.ts} +5 -17
- package/build/{EntityMutator.js → AuthorizationResultBasedEntityMutator.js} +22 -48
- package/build/AuthorizationResultBasedEntityMutator.js.map +1 -0
- package/build/EnforcingEntityAssociationLoader.d.ts +79 -0
- package/build/EnforcingEntityAssociationLoader.js +62 -0
- package/build/EnforcingEntityAssociationLoader.js.map +1 -0
- package/build/EnforcingEntityCreator.d.ts +24 -0
- package/build/EnforcingEntityCreator.js +32 -0
- package/build/EnforcingEntityCreator.js.map +1 -0
- package/build/EnforcingEntityDeleter.d.ts +17 -0
- package/build/EnforcingEntityDeleter.js +22 -0
- package/build/EnforcingEntityDeleter.js.map +1 -0
- package/build/EnforcingEntityUpdater.d.ts +24 -0
- package/build/EnforcingEntityUpdater.js +32 -0
- package/build/EnforcingEntityUpdater.js.map +1 -0
- package/build/Entity.d.ts +8 -12
- package/build/Entity.js +9 -34
- package/build/Entity.js.map +1 -1
- package/build/EntityAssociationLoader.d.ts +12 -91
- package/build/EntityAssociationLoader.js +20 -126
- package/build/EntityAssociationLoader.js.map +1 -1
- package/build/EntityCompanionProvider.d.ts +2 -2
- package/build/EntityCompanionProvider.js.map +1 -1
- package/build/EntityCreator.d.ts +27 -0
- package/build/EntityCreator.js +39 -0
- package/build/EntityCreator.js.map +1 -0
- package/build/EntityDatabaseAdapter.js +2 -2
- package/build/EntityDatabaseAdapter.js.map +1 -1
- package/build/EntityDeleter.d.ts +27 -0
- package/build/EntityDeleter.js +40 -0
- package/build/EntityDeleter.js.map +1 -0
- package/build/EntityLoader.d.ts +4 -14
- package/build/EntityLoader.js +7 -20
- package/build/EntityLoader.js.map +1 -1
- package/build/EntityLoaderFactory.d.ts +2 -2
- package/build/EntityLoaderFactory.js +4 -2
- package/build/EntityLoaderFactory.js.map +1 -1
- package/build/EntityMutatorFactory.d.ts +4 -4
- package/build/EntityMutatorFactory.js +4 -4
- package/build/EntityMutatorFactory.js.map +1 -1
- package/build/EntitySecondaryCacheLoader.d.ts +3 -3
- package/build/EntitySecondaryCacheLoader.js +1 -3
- package/build/EntitySecondaryCacheLoader.js.map +1 -1
- package/build/EntityUpdater.d.ts +27 -0
- package/build/EntityUpdater.js +40 -0
- package/build/EntityUpdater.js.map +1 -0
- package/build/ReadonlyEntity.d.ts +2 -2
- package/build/ReadonlyEntity.js +4 -6
- package/build/ReadonlyEntity.js.map +1 -1
- package/build/ViewerScopedEntityLoaderFactory.d.ts +2 -2
- package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
- package/build/ViewerScopedEntityMutatorFactory.d.ts +4 -4
- package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.d.ts +1 -0
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js +273 -0
- package/build/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.js.map +1 -0
- package/build/__tests__/{EntityLoader-constructor-test.js → AuthorizationResultBasedEntityLoader-constructor-test.js} +11 -11
- package/build/__tests__/AuthorizationResultBasedEntityLoader-constructor-test.js.map +1 -0
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.d.ts +1 -0
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js +401 -0
- package/build/__tests__/AuthorizationResultBasedEntityLoader-test.js.map +1 -0
- package/build/__tests__/EnforcingEntityAssociationLoader-test.d.ts +1 -0
- package/build/__tests__/EnforcingEntityAssociationLoader-test.js +115 -0
- package/build/__tests__/EnforcingEntityAssociationLoader-test.js.map +1 -0
- package/build/__tests__/Entity-test.js +23 -5
- package/build/__tests__/Entity-test.js.map +1 -1
- package/build/__tests__/EntityAssociationLoader-test.js +14 -184
- package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
- package/build/__tests__/EntityCommonUseCases-test.js +34 -12
- package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
- package/build/__tests__/EntityCompanion-test.js +17 -7
- package/build/__tests__/EntityCompanion-test.js.map +1 -1
- package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
- package/build/__tests__/EntityEdges-test.js +41 -23
- package/build/__tests__/EntityEdges-test.js.map +1 -1
- package/build/__tests__/EntityLoader-test.js +22 -386
- package/build/__tests__/EntityLoader-test.js.map +1 -1
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +4 -3
- package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
- package/build/__tests__/EntityMutator-test.js +67 -70
- package/build/__tests__/EntityMutator-test.js.map +1 -1
- package/build/__tests__/EntityPrivacyPolicy-test.js +17 -7
- package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
- package/build/__tests__/EntitySecondaryCacheLoader-test.js +7 -7
- package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
- package/build/__tests__/EntitySelfReferentialEdges-test.js +36 -24
- package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
- package/build/__tests__/ReadonlyEntity-test.js +1 -1
- package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +4 -2
- package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +7 -4
- package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
- package/build/__tests__/entityUtils-test.js +8 -0
- package/build/__tests__/entityUtils-test.js.map +1 -1
- package/build/entityUtils.d.ts +7 -0
- package/build/entityUtils.js +20 -10
- package/build/entityUtils.js.map +1 -1
- package/build/errors/EntityCacheAdapterError.js +17 -7
- package/build/errors/EntityCacheAdapterError.js.map +1 -1
- package/build/errors/EntityDatabaseAdapterError.js +17 -7
- package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
- package/build/errors/EntityInvalidFieldValueError.js +17 -7
- package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
- package/build/errors/EntityNotAuthorizedError.js +17 -7
- package/build/errors/EntityNotAuthorizedError.js.map +1 -1
- package/build/errors/EntityNotFoundError.js +17 -7
- package/build/errors/EntityNotFoundError.js.map +1 -1
- package/build/index.d.ts +19 -11
- package/build/index.js +24 -7
- package/build/index.js.map +1 -1
- package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
- package/build/internal/__tests__/EntityDataManager-test.js +42 -32
- package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
- package/build/internal/__tests__/ReadThroughEntityCache-test.js +17 -7
- package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js +17 -7
- package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js +17 -7
- package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js +17 -7
- package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
- package/build/utils/EntityPrivacyUtils.d.ts +32 -4
- package/build/utils/EntityPrivacyUtils.js +68 -24
- package/build/utils/EntityPrivacyUtils.js.map +1 -1
- package/build/utils/__tests__/EntityPrivacyUtils-test.js +148 -23
- package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -1
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js +8 -5
- package/build/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.js.map +1 -1
- package/build/utils/collections/__tests__/maps-test.js +1 -1
- package/build/utils/collections/__tests__/maps-test.js.map +1 -1
- package/build/utils/collections/maps.js +2 -2
- package/build/utils/collections/maps.js.map +1 -1
- package/build/utils/mergeEntityMutationTriggerConfigurations.js +1 -2
- package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +1 -1
- package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
- package/build/utils/testing/StubDatabaseAdapter.js +17 -7
- package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
- package/build/utils/testing/StubQueryContextProvider.d.ts +1 -3
- package/build/utils/testing/StubQueryContextProvider.js +1 -3
- package/build/utils/testing/StubQueryContextProvider.js.map +1 -1
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js +2 -1
- package/build/utils/testing/createUnitTestEntityCompanionProvider.js.map +1 -1
- package/build/utils/testing/describeFieldTestCase.js +1 -1
- package/build/utils/testing/describeFieldTestCase.js.map +1 -1
- package/package.json +19 -3
- package/src/AuthorizationResultBasedEntityAssociationLoader.ts +492 -0
- package/src/AuthorizationResultBasedEntityLoader.ts +2 -2
- package/src/{EntityMutator.ts → AuthorizationResultBasedEntityMutator.ts} +62 -58
- package/src/EnforcingEntityAssociationLoader.ts +390 -0
- package/src/EnforcingEntityCreator.ts +55 -0
- package/src/EnforcingEntityDeleter.ts +44 -0
- package/src/EnforcingEntityUpdater.ts +55 -0
- package/src/Entity.ts +20 -65
- package/src/EntityAssociationLoader.ts +38 -495
- package/src/EntityCompanionProvider.ts +5 -2
- package/src/EntityCreator.ts +73 -0
- package/src/EntityDeleter.ts +73 -0
- package/src/EntityLoader.ts +10 -49
- package/src/EntityLoaderFactory.ts +20 -3
- package/src/EntityMutatorFactory.ts +32 -7
- package/src/EntitySecondaryCacheLoader.ts +5 -7
- package/src/EntityUpdater.ts +73 -0
- package/src/ReadonlyEntity.ts +14 -13
- package/src/ViewerScopedEntityLoaderFactory.ts +9 -2
- package/src/ViewerScopedEntityMutatorFactory.ts +29 -4
- package/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts +354 -0
- package/src/__tests__/{EntityLoader-constructor-test.ts → AuthorizationResultBasedEntityLoader-constructor-test.ts} +17 -10
- package/src/__tests__/AuthorizationResultBasedEntityLoader-test.ts +730 -0
- package/src/__tests__/EnforcingEntityAssociationLoader-test.ts +253 -0
- package/src/__tests__/Entity-test.ts +24 -5
- package/src/__tests__/EntityAssociationLoader-test.ts +16 -259
- package/src/__tests__/EntityCommonUseCases-test.ts +20 -8
- package/src/__tests__/EntityCompanion-test.ts +1 -1
- package/src/__tests__/EntityDatabaseAdapter-test.ts +6 -6
- package/src/__tests__/EntityEdges-test.ts +24 -16
- package/src/__tests__/EntityLoader-test.ts +25 -675
- package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +4 -3
- package/src/__tests__/EntityMutator-test.ts +116 -103
- package/src/__tests__/EntitySecondaryCacheLoader-test.ts +7 -7
- package/src/__tests__/EntitySelfReferentialEdges-test.ts +36 -24
- package/src/__tests__/ReadonlyEntity-test.ts +1 -1
- package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +4 -2
- package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +7 -4
- package/src/__tests__/entityUtils-test.ts +12 -0
- package/src/entityUtils.ts +24 -9
- package/src/index.ts +19 -11
- package/src/internal/EntityFieldTransformationUtils.ts +2 -2
- package/src/internal/__tests__/EntityDataManager-test.ts +29 -29
- package/src/utils/EntityPrivacyUtils.ts +188 -107
- package/src/utils/__tests__/EntityPrivacyUtils-test.ts +169 -29
- package/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts +8 -5
- package/src/utils/collections/__tests__/maps-test.ts +1 -1
- package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +1 -1
- package/src/utils/testing/StubDatabaseAdapter.ts +1 -1
- package/src/utils/testing/StubQueryContextProvider.ts +1 -3
- package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +3 -1
- package/build/EntityMutator.js.map +0 -1
- package/build/__tests__/EntityLoader-constructor-test.js.map +0 -1
- /package/build/__tests__/{EntityLoader-constructor-test.d.ts → AuthorizationResultBasedEntityLoader-constructor-test.d.ts} +0 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { enforceAsyncResult } from '@expo/results';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
import AuthorizationResultBasedEntityAssociationLoader from '../AuthorizationResultBasedEntityAssociationLoader';
|
|
5
|
+
import { enforceResultsAsync } from '../entityUtils';
|
|
6
|
+
import TestEntity from '../testfixtures/TestEntity';
|
|
7
|
+
import TestEntity2 from '../testfixtures/TestEntity2';
|
|
8
|
+
import TestViewerContext from '../testfixtures/TestViewerContext';
|
|
9
|
+
import { createUnitTestEntityCompanionProvider } from '../utils/testing/createUnitTestEntityCompanionProvider';
|
|
10
|
+
|
|
11
|
+
describe(AuthorizationResultBasedEntityAssociationLoader, () => {
|
|
12
|
+
describe('loadAssociatedEntityAsync', () => {
|
|
13
|
+
it('loads associated entities by ID and correctly handles a null value', async () => {
|
|
14
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
15
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
16
|
+
const testOtherEntity = await enforceAsyncResult(
|
|
17
|
+
TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(),
|
|
18
|
+
);
|
|
19
|
+
const testEntity = await enforceAsyncResult(
|
|
20
|
+
TestEntity.creator(viewerContext)
|
|
21
|
+
.withAuthorizationResults()
|
|
22
|
+
.setField('stringField', testOtherEntity.getID())
|
|
23
|
+
.createAsync(),
|
|
24
|
+
);
|
|
25
|
+
const loadedOther = await enforceAsyncResult(
|
|
26
|
+
testEntity
|
|
27
|
+
.associationLoader()
|
|
28
|
+
.withAuthorizationResults()
|
|
29
|
+
.loadAssociatedEntityAsync('stringField', TestEntity),
|
|
30
|
+
);
|
|
31
|
+
expect(loadedOther.getID()).toEqual(testOtherEntity.getID());
|
|
32
|
+
|
|
33
|
+
const loadedOther2 = await enforceAsyncResult(
|
|
34
|
+
testEntity
|
|
35
|
+
.associationLoader()
|
|
36
|
+
.withAuthorizationResults()
|
|
37
|
+
.loadAssociatedEntityAsync('nullableField', TestEntity),
|
|
38
|
+
);
|
|
39
|
+
expect(loadedOther2).toBeNull();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('loadManyAssociatedEntitiesAsync', () => {
|
|
44
|
+
it('loads many associated entities referencing this entity', async () => {
|
|
45
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
46
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
47
|
+
const testEntity = await enforceAsyncResult(
|
|
48
|
+
TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(),
|
|
49
|
+
);
|
|
50
|
+
const testOtherEntity1 = await enforceAsyncResult(
|
|
51
|
+
TestEntity.creator(viewerContext)
|
|
52
|
+
.withAuthorizationResults()
|
|
53
|
+
.setField('stringField', testEntity.getID())
|
|
54
|
+
.createAsync(),
|
|
55
|
+
);
|
|
56
|
+
const testOtherEntity2 = await enforceAsyncResult(
|
|
57
|
+
TestEntity.creator(viewerContext)
|
|
58
|
+
.withAuthorizationResults()
|
|
59
|
+
.setField('stringField', testEntity.getID())
|
|
60
|
+
.createAsync(),
|
|
61
|
+
);
|
|
62
|
+
const loaded = await enforceResultsAsync(
|
|
63
|
+
testEntity
|
|
64
|
+
.associationLoader()
|
|
65
|
+
.withAuthorizationResults()
|
|
66
|
+
.loadManyAssociatedEntitiesAsync(TestEntity, 'stringField'),
|
|
67
|
+
);
|
|
68
|
+
expect(loaded).toHaveLength(2);
|
|
69
|
+
expect(loaded.find((e) => e.getID() === testOtherEntity1.getID())).not.toBeUndefined();
|
|
70
|
+
expect(loaded.find((e) => e.getID() === testOtherEntity2.getID())).not.toBeUndefined();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('loadAssociatedEntityByFieldEqualingAsync', () => {
|
|
75
|
+
it('loads associated entity by field equaling', async () => {
|
|
76
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
77
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
78
|
+
const testOtherEntity = await enforceAsyncResult(
|
|
79
|
+
TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(),
|
|
80
|
+
);
|
|
81
|
+
const testEntity = await enforceAsyncResult(
|
|
82
|
+
TestEntity.creator(viewerContext)
|
|
83
|
+
.withAuthorizationResults()
|
|
84
|
+
.setField('stringField', testOtherEntity.getID())
|
|
85
|
+
.createAsync(),
|
|
86
|
+
);
|
|
87
|
+
const loadedOtherResult = await testEntity
|
|
88
|
+
.associationLoader()
|
|
89
|
+
.withAuthorizationResults()
|
|
90
|
+
.loadAssociatedEntityByFieldEqualingAsync('stringField', TestEntity, 'customIdField');
|
|
91
|
+
expect(loadedOtherResult?.enforceValue().getID()).toEqual(testOtherEntity.getID());
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('returns null when loading associated entities by field equaling a non existent association', async () => {
|
|
95
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
96
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
97
|
+
const testEntity = await enforceAsyncResult(
|
|
98
|
+
TestEntity.creator(viewerContext)
|
|
99
|
+
.withAuthorizationResults()
|
|
100
|
+
.setField('stringField', uuidv4())
|
|
101
|
+
.createAsync(),
|
|
102
|
+
);
|
|
103
|
+
const loadedOtherResult = await testEntity
|
|
104
|
+
.associationLoader()
|
|
105
|
+
.withAuthorizationResults()
|
|
106
|
+
.loadAssociatedEntityByFieldEqualingAsync('stringField', TestEntity, 'customIdField');
|
|
107
|
+
expect(loadedOtherResult).toBeNull();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('returns null when load-by field is null', async () => {
|
|
111
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
112
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
113
|
+
const testEntity = await enforceAsyncResult(
|
|
114
|
+
TestEntity.creator(viewerContext)
|
|
115
|
+
.withAuthorizationResults()
|
|
116
|
+
.setField('stringField', 'blah')
|
|
117
|
+
.createAsync(),
|
|
118
|
+
);
|
|
119
|
+
const loadedOtherResult = await testEntity
|
|
120
|
+
.associationLoader()
|
|
121
|
+
.withAuthorizationResults()
|
|
122
|
+
.loadAssociatedEntityByFieldEqualingAsync('nullableField', TestEntity, 'customIdField');
|
|
123
|
+
expect(loadedOtherResult).toBeNull();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('loadManyAssociatedEntitiesByFieldEqualingAsync', () => {
|
|
128
|
+
it('loads many associated entities by field equaling', async () => {
|
|
129
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
130
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
131
|
+
const testEntity = await enforceAsyncResult(
|
|
132
|
+
TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(),
|
|
133
|
+
);
|
|
134
|
+
const testOtherEntity1 = await enforceAsyncResult(
|
|
135
|
+
TestEntity.creator(viewerContext)
|
|
136
|
+
.withAuthorizationResults()
|
|
137
|
+
.setField('stringField', testEntity.getID())
|
|
138
|
+
.createAsync(),
|
|
139
|
+
);
|
|
140
|
+
const testOtherEntity2 = await enforceAsyncResult(
|
|
141
|
+
TestEntity.creator(viewerContext)
|
|
142
|
+
.withAuthorizationResults()
|
|
143
|
+
.setField('stringField', testEntity.getID())
|
|
144
|
+
.createAsync(),
|
|
145
|
+
);
|
|
146
|
+
const loaded = await enforceResultsAsync(
|
|
147
|
+
testEntity
|
|
148
|
+
.associationLoader()
|
|
149
|
+
.withAuthorizationResults()
|
|
150
|
+
.loadManyAssociatedEntitiesByFieldEqualingAsync(
|
|
151
|
+
'customIdField',
|
|
152
|
+
TestEntity,
|
|
153
|
+
'stringField',
|
|
154
|
+
),
|
|
155
|
+
);
|
|
156
|
+
expect(loaded).toHaveLength(2);
|
|
157
|
+
expect(loaded.find((e) => e.getID() === testOtherEntity1.getID())).not.toBeUndefined();
|
|
158
|
+
expect(loaded.find((e) => e.getID() === testOtherEntity2.getID())).not.toBeUndefined();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('returns empty results when field being queried by is null', async () => {
|
|
162
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
163
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
164
|
+
const testEntity = await enforceAsyncResult(
|
|
165
|
+
TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(),
|
|
166
|
+
);
|
|
167
|
+
const loaded = await enforceResultsAsync(
|
|
168
|
+
testEntity
|
|
169
|
+
.associationLoader()
|
|
170
|
+
.withAuthorizationResults()
|
|
171
|
+
.loadManyAssociatedEntitiesByFieldEqualingAsync(
|
|
172
|
+
'nullableField',
|
|
173
|
+
TestEntity,
|
|
174
|
+
'stringField',
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
expect(loaded).toHaveLength(0);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('loadAssociatedEntityThroughAsync', () => {
|
|
182
|
+
it('chain loads associated entities', async () => {
|
|
183
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
184
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
185
|
+
const testEntity4 = await enforceAsyncResult(
|
|
186
|
+
TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(),
|
|
187
|
+
);
|
|
188
|
+
const testEntity3 = await enforceAsyncResult(
|
|
189
|
+
TestEntity2.creator(viewerContext)
|
|
190
|
+
.withAuthorizationResults()
|
|
191
|
+
.setField('foreignKey', testEntity4.getID())
|
|
192
|
+
.createAsync(),
|
|
193
|
+
);
|
|
194
|
+
const testEntity2 = await enforceAsyncResult(
|
|
195
|
+
TestEntity.creator(viewerContext)
|
|
196
|
+
.withAuthorizationResults()
|
|
197
|
+
.setField('testIndexedField', testEntity3.getID())
|
|
198
|
+
.createAsync(),
|
|
199
|
+
);
|
|
200
|
+
const testEntity = await enforceAsyncResult(
|
|
201
|
+
TestEntity2.creator(viewerContext)
|
|
202
|
+
.withAuthorizationResults()
|
|
203
|
+
.setField('foreignKey', testEntity2.getID())
|
|
204
|
+
.createAsync(),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const loaded2Result = await testEntity
|
|
208
|
+
.associationLoader()
|
|
209
|
+
.withAuthorizationResults()
|
|
210
|
+
.loadAssociatedEntityThroughAsync([
|
|
211
|
+
{
|
|
212
|
+
associatedEntityClass: TestEntity,
|
|
213
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
214
|
+
},
|
|
215
|
+
]);
|
|
216
|
+
expect(loaded2Result?.enforceValue().getID()).toEqual(testEntity2.getID());
|
|
217
|
+
|
|
218
|
+
const loaded3Result = await testEntity
|
|
219
|
+
.associationLoader()
|
|
220
|
+
.withAuthorizationResults()
|
|
221
|
+
.loadAssociatedEntityThroughAsync([
|
|
222
|
+
{
|
|
223
|
+
associatedEntityClass: TestEntity,
|
|
224
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
associatedEntityClass: TestEntity2,
|
|
228
|
+
fieldIdentifyingAssociatedEntity: 'testIndexedField',
|
|
229
|
+
},
|
|
230
|
+
]);
|
|
231
|
+
expect(loaded3Result?.enforceValue().getID()).toEqual(testEntity3.getID());
|
|
232
|
+
|
|
233
|
+
const loaded4Result = await testEntity
|
|
234
|
+
.associationLoader()
|
|
235
|
+
.withAuthorizationResults()
|
|
236
|
+
.loadAssociatedEntityThroughAsync([
|
|
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
|
+
expect(loaded4Result?.enforceValue().getID()).toEqual(testEntity4.getID());
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('fails when chain loading associated entity fails', async () => {
|
|
254
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
255
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
256
|
+
|
|
257
|
+
const testEntity = await enforceAsyncResult(
|
|
258
|
+
TestEntity2.creator(viewerContext)
|
|
259
|
+
.withAuthorizationResults()
|
|
260
|
+
.setField('foreignKey', uuidv4())
|
|
261
|
+
.createAsync(),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const loadResult = await testEntity
|
|
265
|
+
.associationLoader()
|
|
266
|
+
.withAuthorizationResults()
|
|
267
|
+
.loadAssociatedEntityThroughAsync([
|
|
268
|
+
{
|
|
269
|
+
associatedEntityClass: TestEntity,
|
|
270
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
271
|
+
},
|
|
272
|
+
]);
|
|
273
|
+
expect(loadResult?.ok).toBe(false);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('supports chain loading by field equality', async () => {
|
|
277
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
278
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
279
|
+
|
|
280
|
+
const fieldValue = uuidv4();
|
|
281
|
+
const testEntity2 = await enforceAsyncResult(
|
|
282
|
+
TestEntity.creator(viewerContext)
|
|
283
|
+
.withAuthorizationResults()
|
|
284
|
+
.setField('stringField', fieldValue)
|
|
285
|
+
.createAsync(),
|
|
286
|
+
);
|
|
287
|
+
const testEntity = await enforceAsyncResult(
|
|
288
|
+
TestEntity2.creator(viewerContext)
|
|
289
|
+
.withAuthorizationResults()
|
|
290
|
+
.setField('foreignKey', fieldValue)
|
|
291
|
+
.createAsync(),
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const loaded2Result = await testEntity
|
|
295
|
+
.associationLoader()
|
|
296
|
+
.withAuthorizationResults()
|
|
297
|
+
.loadAssociatedEntityThroughAsync([
|
|
298
|
+
{
|
|
299
|
+
associatedEntityClass: TestEntity,
|
|
300
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
301
|
+
associatedEntityLookupByField: 'stringField',
|
|
302
|
+
},
|
|
303
|
+
]);
|
|
304
|
+
expect(loaded2Result?.enforceValue().getID()).toEqual(testEntity2.getID());
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('returns null when chain loading by field equality returns null', async () => {
|
|
308
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
309
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
310
|
+
|
|
311
|
+
const testEntity = await enforceAsyncResult(
|
|
312
|
+
TestEntity2.creator(viewerContext)
|
|
313
|
+
.withAuthorizationResults()
|
|
314
|
+
.setField('foreignKey', uuidv4())
|
|
315
|
+
.createAsync(),
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
const loaded2Result = await testEntity
|
|
319
|
+
.associationLoader()
|
|
320
|
+
.withAuthorizationResults()
|
|
321
|
+
.loadAssociatedEntityThroughAsync([
|
|
322
|
+
{
|
|
323
|
+
associatedEntityClass: TestEntity,
|
|
324
|
+
fieldIdentifyingAssociatedEntity: 'foreignKey',
|
|
325
|
+
associatedEntityLookupByField: 'stringField',
|
|
326
|
+
},
|
|
327
|
+
]);
|
|
328
|
+
expect(loaded2Result).toBeNull();
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it('returns null when chain loading by field is null', async () => {
|
|
332
|
+
const companionProvider = createUnitTestEntityCompanionProvider();
|
|
333
|
+
const viewerContext = new TestViewerContext(companionProvider);
|
|
334
|
+
|
|
335
|
+
const testEntity = await enforceAsyncResult(
|
|
336
|
+
TestEntity.creator(viewerContext)
|
|
337
|
+
.withAuthorizationResults()
|
|
338
|
+
.setField('nullableField', null)
|
|
339
|
+
.createAsync(),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const loadedResult = await testEntity
|
|
343
|
+
.associationLoader()
|
|
344
|
+
.withAuthorizationResults()
|
|
345
|
+
.loadAssociatedEntityThroughAsync([
|
|
346
|
+
{
|
|
347
|
+
associatedEntityClass: TestEntity,
|
|
348
|
+
fieldIdentifyingAssociatedEntity: 'nullableField',
|
|
349
|
+
},
|
|
350
|
+
]);
|
|
351
|
+
expect(loadedResult).toBeNull();
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { instance, mock } from 'ts-mockito';
|
|
2
2
|
|
|
3
|
+
import AuthorizationResultBasedEntityLoader from '../AuthorizationResultBasedEntityLoader';
|
|
3
4
|
import Entity from '../Entity';
|
|
4
5
|
import { EntityCompanionDefinition } from '../EntityCompanionProvider';
|
|
5
6
|
import EntityConfiguration from '../EntityConfiguration';
|
|
6
7
|
import { StringField } from '../EntityFields';
|
|
7
|
-
import
|
|
8
|
+
import EntityLoaderUtils from '../EntityLoaderUtils';
|
|
8
9
|
import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from '../EntityPrivacyPolicy';
|
|
9
10
|
import ViewerContext from '../ViewerContext';
|
|
10
11
|
import EntityDataManager from '../internal/EntityDataManager';
|
|
@@ -94,7 +95,7 @@ export default class TestEntity extends Entity<
|
|
|
94
95
|
selectedFields: Readonly<TestFields>;
|
|
95
96
|
}) {
|
|
96
97
|
if (constructorParams.selectedFields.id === ID_SENTINEL_THROW_LITERAL) {
|
|
97
|
-
// eslint-disable-next-line no-throw-literal,@typescript-eslint/
|
|
98
|
+
// eslint-disable-next-line no-throw-literal,@typescript-eslint/only-throw-error
|
|
98
99
|
throw 'hello';
|
|
99
100
|
} else if (constructorParams.selectedFields.id === ID_SENTINEL_THROW_ERROR) {
|
|
100
101
|
throw new Error('world');
|
|
@@ -118,7 +119,7 @@ export default class TestEntity extends Entity<
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
describe(
|
|
122
|
+
describe(AuthorizationResultBasedEntityLoader, () => {
|
|
122
123
|
it('handles thrown errors and literals from constructor', async () => {
|
|
123
124
|
const viewerContext = instance(mock(ViewerContext));
|
|
124
125
|
const privacyPolicyEvaluationContext =
|
|
@@ -134,7 +135,7 @@ describe(EntityLoader, () => {
|
|
|
134
135
|
>(),
|
|
135
136
|
);
|
|
136
137
|
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
137
|
-
const queryContext = StubQueryContextProvider.getQueryContext();
|
|
138
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
138
139
|
|
|
139
140
|
const databaseAdapter = new StubDatabaseAdapter<TestFields>(
|
|
140
141
|
testEntityConfiguration,
|
|
@@ -162,11 +163,11 @@ describe(EntityLoader, () => {
|
|
|
162
163
|
const dataManager = new EntityDataManager(
|
|
163
164
|
databaseAdapter,
|
|
164
165
|
entityCache,
|
|
165
|
-
StubQueryContextProvider,
|
|
166
|
+
new StubQueryContextProvider(),
|
|
166
167
|
metricsAdapter,
|
|
167
168
|
TestEntity.name,
|
|
168
169
|
);
|
|
169
|
-
const
|
|
170
|
+
const utils = new EntityLoaderUtils(
|
|
170
171
|
viewerContext,
|
|
171
172
|
queryContext,
|
|
172
173
|
privacyPolicyEvaluationContext,
|
|
@@ -177,19 +178,25 @@ describe(EntityLoader, () => {
|
|
|
177
178
|
dataManager,
|
|
178
179
|
metricsAdapter,
|
|
179
180
|
);
|
|
181
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
182
|
+
queryContext,
|
|
183
|
+
testEntityConfiguration,
|
|
184
|
+
TestEntity,
|
|
185
|
+
dataManager,
|
|
186
|
+
metricsAdapter,
|
|
187
|
+
utils,
|
|
188
|
+
);
|
|
180
189
|
|
|
181
190
|
let capturedThrownThing1: any;
|
|
182
191
|
try {
|
|
183
|
-
await entityLoader.
|
|
192
|
+
await entityLoader.loadByIDAsync(ID_SENTINEL_THROW_LITERAL);
|
|
184
193
|
} catch (e) {
|
|
185
194
|
capturedThrownThing1 = e;
|
|
186
195
|
}
|
|
187
196
|
expect(capturedThrownThing1).not.toBeInstanceOf(Error);
|
|
188
197
|
expect(capturedThrownThing1).toEqual('hello');
|
|
189
198
|
|
|
190
|
-
const result = await entityLoader
|
|
191
|
-
.withAuthorizationResults()
|
|
192
|
-
.loadByIDAsync(ID_SENTINEL_THROW_ERROR);
|
|
199
|
+
const result = await entityLoader.loadByIDAsync(ID_SENTINEL_THROW_ERROR);
|
|
193
200
|
expect(result.ok).toBe(false);
|
|
194
201
|
expect(result.enforceError().message).toEqual('world');
|
|
195
202
|
});
|