@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,730 @@
|
|
|
1
|
+
import { enforceAsyncResult } from '@expo/results';
|
|
2
|
+
import { mock, instance, verify, spy, deepEqual, anyOfClass, anything, when } from 'ts-mockito';
|
|
3
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
4
|
+
|
|
5
|
+
import AuthorizationResultBasedEntityLoader from '../AuthorizationResultBasedEntityLoader';
|
|
6
|
+
import { OrderByOrdering } from '../EntityDatabaseAdapter';
|
|
7
|
+
import EntityLoaderUtils from '../EntityLoaderUtils';
|
|
8
|
+
import { EntityPrivacyPolicyEvaluationContext } from '../EntityPrivacyPolicy';
|
|
9
|
+
import ViewerContext from '../ViewerContext';
|
|
10
|
+
import { enforceResultsAsync } from '../entityUtils';
|
|
11
|
+
import EntityNotFoundError from '../errors/EntityNotFoundError';
|
|
12
|
+
import EntityDataManager from '../internal/EntityDataManager';
|
|
13
|
+
import ReadThroughEntityCache from '../internal/ReadThroughEntityCache';
|
|
14
|
+
import IEntityMetricsAdapter from '../metrics/IEntityMetricsAdapter';
|
|
15
|
+
import TestEntity, {
|
|
16
|
+
TestFields,
|
|
17
|
+
TestEntityPrivacyPolicy,
|
|
18
|
+
testEntityConfiguration,
|
|
19
|
+
} from '../testfixtures/TestEntity';
|
|
20
|
+
import { NoCacheStubCacheAdapterProvider } from '../utils/testing/StubCacheAdapter';
|
|
21
|
+
import StubDatabaseAdapter from '../utils/testing/StubDatabaseAdapter';
|
|
22
|
+
import StubQueryContextProvider from '../utils/testing/StubQueryContextProvider';
|
|
23
|
+
|
|
24
|
+
describe(AuthorizationResultBasedEntityLoader, () => {
|
|
25
|
+
it('loads entities', async () => {
|
|
26
|
+
const dateToInsert = new Date();
|
|
27
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
28
|
+
const privacyPolicyEvaluationContext =
|
|
29
|
+
instance(
|
|
30
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
31
|
+
);
|
|
32
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
33
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
34
|
+
|
|
35
|
+
const id1 = uuidv4();
|
|
36
|
+
const id2 = uuidv4();
|
|
37
|
+
const databaseAdapter = new StubDatabaseAdapter<TestFields>(
|
|
38
|
+
testEntityConfiguration,
|
|
39
|
+
StubDatabaseAdapter.convertFieldObjectsToDataStore(
|
|
40
|
+
testEntityConfiguration,
|
|
41
|
+
new Map([
|
|
42
|
+
[
|
|
43
|
+
testEntityConfiguration.tableName,
|
|
44
|
+
[
|
|
45
|
+
{
|
|
46
|
+
customIdField: id1,
|
|
47
|
+
testIndexedField: 'h1',
|
|
48
|
+
intField: 5,
|
|
49
|
+
stringField: 'huh',
|
|
50
|
+
dateField: dateToInsert,
|
|
51
|
+
nullableField: null,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
customIdField: id2,
|
|
55
|
+
testIndexedField: 'h2',
|
|
56
|
+
intField: 3,
|
|
57
|
+
stringField: 'huh',
|
|
58
|
+
dateField: dateToInsert,
|
|
59
|
+
nullableField: null,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
],
|
|
63
|
+
]),
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
const privacyPolicy = new TestEntityPrivacyPolicy();
|
|
67
|
+
const cacheAdapterProvider = new NoCacheStubCacheAdapterProvider();
|
|
68
|
+
const cacheAdapter = cacheAdapterProvider.getCacheAdapter(testEntityConfiguration);
|
|
69
|
+
const entityCache = new ReadThroughEntityCache(testEntityConfiguration, cacheAdapter);
|
|
70
|
+
const dataManager = new EntityDataManager(
|
|
71
|
+
databaseAdapter,
|
|
72
|
+
entityCache,
|
|
73
|
+
new StubQueryContextProvider(),
|
|
74
|
+
instance(mock<IEntityMetricsAdapter>()),
|
|
75
|
+
TestEntity.name,
|
|
76
|
+
);
|
|
77
|
+
const utils = new EntityLoaderUtils(
|
|
78
|
+
viewerContext,
|
|
79
|
+
queryContext,
|
|
80
|
+
privacyPolicyEvaluationContext,
|
|
81
|
+
testEntityConfiguration,
|
|
82
|
+
TestEntity,
|
|
83
|
+
/* entitySelectedFields */ undefined,
|
|
84
|
+
privacyPolicy,
|
|
85
|
+
dataManager,
|
|
86
|
+
metricsAdapter,
|
|
87
|
+
);
|
|
88
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
89
|
+
queryContext,
|
|
90
|
+
testEntityConfiguration,
|
|
91
|
+
TestEntity,
|
|
92
|
+
dataManager,
|
|
93
|
+
metricsAdapter,
|
|
94
|
+
utils,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const entity = await enforceAsyncResult(entityLoader.loadByIDAsync(id1));
|
|
98
|
+
expect(entity.getID()).toEqual(id1);
|
|
99
|
+
expect(entity.getField('dateField')).toEqual(dateToInsert);
|
|
100
|
+
|
|
101
|
+
const entities = await enforceResultsAsync(
|
|
102
|
+
entityLoader.loadManyByFieldEqualingAsync('stringField', 'huh'),
|
|
103
|
+
);
|
|
104
|
+
expect(entities.map((m) => m.getID())).toEqual([id1, id2]);
|
|
105
|
+
|
|
106
|
+
const entityResultNumber3 = await entityLoader.loadByFieldEqualingAsync('intField', 3);
|
|
107
|
+
expect(entityResultNumber3).not.toBeNull();
|
|
108
|
+
expect(entityResultNumber3!.enforceValue().getID()).toEqual(id2);
|
|
109
|
+
|
|
110
|
+
const entityResultNumber4 = await entityLoader.loadByFieldEqualingAsync('intField', 4);
|
|
111
|
+
expect(entityResultNumber4).toBeNull();
|
|
112
|
+
|
|
113
|
+
const entityResultDuplicateValues = await entityLoader.loadManyByFieldEqualingManyAsync(
|
|
114
|
+
'stringField',
|
|
115
|
+
['huh', 'huh'],
|
|
116
|
+
);
|
|
117
|
+
expect(entityResultDuplicateValues.size).toBe(1);
|
|
118
|
+
expect(entityResultDuplicateValues.get('huh')?.map((m) => m.enforceValue().getID())).toEqual([
|
|
119
|
+
id1,
|
|
120
|
+
id2,
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
await expect(entityLoader.loadByFieldEqualingAsync('stringField', 'huh')).rejects.toThrowError(
|
|
124
|
+
'loadByFieldEqualing: Multiple entities of type TestEntity found for stringField=huh',
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
await expect(entityLoader.loadByIDNullableAsync(uuidv4())).resolves.toBeNull();
|
|
128
|
+
await expect(entityLoader.loadByIDNullableAsync(id1)).resolves.not.toBeNull();
|
|
129
|
+
|
|
130
|
+
const nonExistentId = uuidv4();
|
|
131
|
+
const manyIdResults = await entityLoader.loadManyByIDsNullableAsync([nonExistentId, id1]);
|
|
132
|
+
expect(manyIdResults.get(nonExistentId)).toBeNull();
|
|
133
|
+
expect(manyIdResults.get(id1)).not.toBeNull();
|
|
134
|
+
|
|
135
|
+
await expect(enforceAsyncResult(entityLoader.loadByIDAsync(nonExistentId))).rejects.toThrow(
|
|
136
|
+
EntityNotFoundError,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
await expect(entityLoader.loadByIDAsync('not-a-uuid')).rejects.toThrowError(
|
|
140
|
+
'Entity field not valid: TestEntity (customIdField = not-a-uuid)',
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('loads entities with loadManyByFieldEqualityConjunction', async () => {
|
|
145
|
+
const privacyPolicy = new TestEntityPrivacyPolicy();
|
|
146
|
+
const spiedPrivacyPolicy = spy(privacyPolicy);
|
|
147
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
148
|
+
const privacyPolicyEvaluationContext =
|
|
149
|
+
instance(
|
|
150
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
151
|
+
);
|
|
152
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
153
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
154
|
+
|
|
155
|
+
const id1 = uuidv4();
|
|
156
|
+
const id2 = uuidv4();
|
|
157
|
+
const id3 = uuidv4();
|
|
158
|
+
const databaseAdapter = new StubDatabaseAdapter<TestFields>(
|
|
159
|
+
testEntityConfiguration,
|
|
160
|
+
StubDatabaseAdapter.convertFieldObjectsToDataStore(
|
|
161
|
+
testEntityConfiguration,
|
|
162
|
+
new Map([
|
|
163
|
+
[
|
|
164
|
+
testEntityConfiguration.tableName,
|
|
165
|
+
[
|
|
166
|
+
{
|
|
167
|
+
customIdField: id1,
|
|
168
|
+
stringField: 'huh',
|
|
169
|
+
intField: 4,
|
|
170
|
+
testIndexedField: '4',
|
|
171
|
+
dateField: new Date(),
|
|
172
|
+
nullableField: null,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
customIdField: id2,
|
|
176
|
+
stringField: 'huh',
|
|
177
|
+
intField: 4,
|
|
178
|
+
testIndexedField: '5',
|
|
179
|
+
dateField: new Date(),
|
|
180
|
+
nullableField: null,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
customIdField: id3,
|
|
184
|
+
stringField: 'huh2',
|
|
185
|
+
intField: 4,
|
|
186
|
+
testIndexedField: '6',
|
|
187
|
+
dateField: new Date(),
|
|
188
|
+
nullableField: null,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
],
|
|
192
|
+
]),
|
|
193
|
+
),
|
|
194
|
+
);
|
|
195
|
+
const cacheAdapterProvider = new NoCacheStubCacheAdapterProvider();
|
|
196
|
+
const cacheAdapter = cacheAdapterProvider.getCacheAdapter(testEntityConfiguration);
|
|
197
|
+
const entityCache = new ReadThroughEntityCache(testEntityConfiguration, cacheAdapter);
|
|
198
|
+
const dataManager = new EntityDataManager(
|
|
199
|
+
databaseAdapter,
|
|
200
|
+
entityCache,
|
|
201
|
+
new StubQueryContextProvider(),
|
|
202
|
+
instance(mock<IEntityMetricsAdapter>()),
|
|
203
|
+
TestEntity.name,
|
|
204
|
+
);
|
|
205
|
+
const utils = new EntityLoaderUtils(
|
|
206
|
+
viewerContext,
|
|
207
|
+
queryContext,
|
|
208
|
+
privacyPolicyEvaluationContext,
|
|
209
|
+
testEntityConfiguration,
|
|
210
|
+
TestEntity,
|
|
211
|
+
/* entitySelectedFields */ undefined,
|
|
212
|
+
privacyPolicy,
|
|
213
|
+
dataManager,
|
|
214
|
+
metricsAdapter,
|
|
215
|
+
);
|
|
216
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
217
|
+
queryContext,
|
|
218
|
+
testEntityConfiguration,
|
|
219
|
+
TestEntity,
|
|
220
|
+
dataManager,
|
|
221
|
+
metricsAdapter,
|
|
222
|
+
utils,
|
|
223
|
+
);
|
|
224
|
+
const entityResults = await enforceResultsAsync(
|
|
225
|
+
entityLoader.loadManyByFieldEqualityConjunctionAsync([
|
|
226
|
+
{
|
|
227
|
+
fieldName: 'stringField',
|
|
228
|
+
fieldValue: 'huh',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
fieldName: 'intField',
|
|
232
|
+
fieldValues: [4],
|
|
233
|
+
},
|
|
234
|
+
]),
|
|
235
|
+
);
|
|
236
|
+
expect(entityResults).toHaveLength(2);
|
|
237
|
+
verify(
|
|
238
|
+
spiedPrivacyPolicy.authorizeReadAsync(
|
|
239
|
+
viewerContext,
|
|
240
|
+
queryContext,
|
|
241
|
+
privacyPolicyEvaluationContext,
|
|
242
|
+
anyOfClass(TestEntity),
|
|
243
|
+
anything(),
|
|
244
|
+
),
|
|
245
|
+
).twice();
|
|
246
|
+
|
|
247
|
+
await expect(
|
|
248
|
+
entityLoader.loadManyByFieldEqualityConjunctionAsync([
|
|
249
|
+
{ fieldName: 'customIdField', fieldValue: 'not-a-uuid' },
|
|
250
|
+
]),
|
|
251
|
+
).rejects.toThrowError('Entity field not valid: TestEntity (customIdField = not-a-uuid)');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('loads entities with loadFirstByFieldEqualityConjunction', async () => {
|
|
255
|
+
const privacyPolicy = new TestEntityPrivacyPolicy();
|
|
256
|
+
const spiedPrivacyPolicy = spy(privacyPolicy);
|
|
257
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
258
|
+
const privacyPolicyEvaluationContext =
|
|
259
|
+
instance(
|
|
260
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
261
|
+
);
|
|
262
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
263
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
264
|
+
|
|
265
|
+
const id1 = uuidv4();
|
|
266
|
+
const id2 = uuidv4();
|
|
267
|
+
const id3 = uuidv4();
|
|
268
|
+
const databaseAdapter = new StubDatabaseAdapter<TestFields>(
|
|
269
|
+
testEntityConfiguration,
|
|
270
|
+
StubDatabaseAdapter.convertFieldObjectsToDataStore(
|
|
271
|
+
testEntityConfiguration,
|
|
272
|
+
new Map([
|
|
273
|
+
[
|
|
274
|
+
testEntityConfiguration.tableName,
|
|
275
|
+
[
|
|
276
|
+
{
|
|
277
|
+
customIdField: id1,
|
|
278
|
+
stringField: 'huh',
|
|
279
|
+
intField: 4,
|
|
280
|
+
testIndexedField: '4',
|
|
281
|
+
dateField: new Date(),
|
|
282
|
+
nullableField: null,
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
customIdField: id2,
|
|
286
|
+
stringField: 'huh',
|
|
287
|
+
intField: 4,
|
|
288
|
+
testIndexedField: '5',
|
|
289
|
+
dateField: new Date(),
|
|
290
|
+
nullableField: null,
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
customIdField: id3,
|
|
294
|
+
stringField: 'huh2',
|
|
295
|
+
intField: 4,
|
|
296
|
+
testIndexedField: '6',
|
|
297
|
+
dateField: new Date(),
|
|
298
|
+
nullableField: null,
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
],
|
|
302
|
+
]),
|
|
303
|
+
),
|
|
304
|
+
);
|
|
305
|
+
const cacheAdapterProvider = new NoCacheStubCacheAdapterProvider();
|
|
306
|
+
const cacheAdapter = cacheAdapterProvider.getCacheAdapter(testEntityConfiguration);
|
|
307
|
+
const entityCache = new ReadThroughEntityCache(testEntityConfiguration, cacheAdapter);
|
|
308
|
+
const dataManager = new EntityDataManager(
|
|
309
|
+
databaseAdapter,
|
|
310
|
+
entityCache,
|
|
311
|
+
new StubQueryContextProvider(),
|
|
312
|
+
instance(mock<IEntityMetricsAdapter>()),
|
|
313
|
+
TestEntity.name,
|
|
314
|
+
);
|
|
315
|
+
const utils = new EntityLoaderUtils(
|
|
316
|
+
viewerContext,
|
|
317
|
+
queryContext,
|
|
318
|
+
privacyPolicyEvaluationContext,
|
|
319
|
+
testEntityConfiguration,
|
|
320
|
+
TestEntity,
|
|
321
|
+
/* entitySelectedFields */ undefined,
|
|
322
|
+
privacyPolicy,
|
|
323
|
+
dataManager,
|
|
324
|
+
metricsAdapter,
|
|
325
|
+
);
|
|
326
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
327
|
+
queryContext,
|
|
328
|
+
testEntityConfiguration,
|
|
329
|
+
TestEntity,
|
|
330
|
+
dataManager,
|
|
331
|
+
metricsAdapter,
|
|
332
|
+
utils,
|
|
333
|
+
);
|
|
334
|
+
const result = await entityLoader.loadFirstByFieldEqualityConjunctionAsync(
|
|
335
|
+
[
|
|
336
|
+
{
|
|
337
|
+
fieldName: 'stringField',
|
|
338
|
+
fieldValue: 'huh',
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
fieldName: 'intField',
|
|
342
|
+
fieldValue: 4,
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
{ orderBy: [{ fieldName: 'testIndexedField', order: OrderByOrdering.DESCENDING }] },
|
|
346
|
+
);
|
|
347
|
+
expect(result).not.toBeNull();
|
|
348
|
+
expect(result!.ok).toBe(true);
|
|
349
|
+
expect(result!.enforceValue().getField('testIndexedField')).toEqual('5');
|
|
350
|
+
verify(
|
|
351
|
+
spiedPrivacyPolicy.authorizeReadAsync(
|
|
352
|
+
viewerContext,
|
|
353
|
+
queryContext,
|
|
354
|
+
privacyPolicyEvaluationContext,
|
|
355
|
+
anyOfClass(TestEntity),
|
|
356
|
+
anything(),
|
|
357
|
+
),
|
|
358
|
+
).once();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('loads entities with loadManyByRawWhereClauseAsync', async () => {
|
|
362
|
+
const privacyPolicy = new TestEntityPrivacyPolicy();
|
|
363
|
+
const spiedPrivacyPolicy = spy(privacyPolicy);
|
|
364
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
365
|
+
const privacyPolicyEvaluationContext =
|
|
366
|
+
instance(
|
|
367
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
368
|
+
);
|
|
369
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
370
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
371
|
+
|
|
372
|
+
const dataManagerMock = mock<EntityDataManager<TestFields>>(EntityDataManager);
|
|
373
|
+
when(
|
|
374
|
+
dataManagerMock.loadManyByRawWhereClauseAsync(
|
|
375
|
+
queryContext,
|
|
376
|
+
anything(),
|
|
377
|
+
anything(),
|
|
378
|
+
anything(),
|
|
379
|
+
),
|
|
380
|
+
).thenResolve([
|
|
381
|
+
{
|
|
382
|
+
customIdField: 'id',
|
|
383
|
+
stringField: 'huh',
|
|
384
|
+
intField: 4,
|
|
385
|
+
testIndexedField: '4',
|
|
386
|
+
dateField: new Date(),
|
|
387
|
+
nullableField: null,
|
|
388
|
+
},
|
|
389
|
+
]);
|
|
390
|
+
const dataManager = instance(dataManagerMock);
|
|
391
|
+
const utils = new EntityLoaderUtils(
|
|
392
|
+
viewerContext,
|
|
393
|
+
queryContext,
|
|
394
|
+
privacyPolicyEvaluationContext,
|
|
395
|
+
testEntityConfiguration,
|
|
396
|
+
TestEntity,
|
|
397
|
+
/* entitySelectedFields */ undefined,
|
|
398
|
+
privacyPolicy,
|
|
399
|
+
dataManager,
|
|
400
|
+
metricsAdapter,
|
|
401
|
+
);
|
|
402
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
403
|
+
queryContext,
|
|
404
|
+
testEntityConfiguration,
|
|
405
|
+
TestEntity,
|
|
406
|
+
dataManager,
|
|
407
|
+
metricsAdapter,
|
|
408
|
+
utils,
|
|
409
|
+
);
|
|
410
|
+
const result = await entityLoader.loadManyByRawWhereClauseAsync('id = ?', [1], {
|
|
411
|
+
orderBy: [{ fieldName: 'testIndexedField', order: OrderByOrdering.DESCENDING }],
|
|
412
|
+
});
|
|
413
|
+
expect(result).toHaveLength(1);
|
|
414
|
+
expect(result[0]).not.toBeNull();
|
|
415
|
+
expect(result[0]!.ok).toBe(true);
|
|
416
|
+
expect(result[0]!.enforceValue().getField('testIndexedField')).toEqual('4');
|
|
417
|
+
verify(
|
|
418
|
+
spiedPrivacyPolicy.authorizeReadAsync(
|
|
419
|
+
viewerContext,
|
|
420
|
+
queryContext,
|
|
421
|
+
privacyPolicyEvaluationContext,
|
|
422
|
+
anyOfClass(TestEntity),
|
|
423
|
+
anything(),
|
|
424
|
+
),
|
|
425
|
+
).once();
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('authorizes loaded entities', async () => {
|
|
429
|
+
const privacyPolicy = new TestEntityPrivacyPolicy();
|
|
430
|
+
const spiedPrivacyPolicy = spy(privacyPolicy);
|
|
431
|
+
|
|
432
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
433
|
+
const privacyPolicyEvaluationContext =
|
|
434
|
+
instance(
|
|
435
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
436
|
+
);
|
|
437
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
438
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
439
|
+
|
|
440
|
+
const id1 = uuidv4();
|
|
441
|
+
const databaseAdapter = new StubDatabaseAdapter<TestFields>(
|
|
442
|
+
testEntityConfiguration,
|
|
443
|
+
StubDatabaseAdapter.convertFieldObjectsToDataStore(
|
|
444
|
+
testEntityConfiguration,
|
|
445
|
+
new Map([
|
|
446
|
+
[
|
|
447
|
+
testEntityConfiguration.tableName,
|
|
448
|
+
[
|
|
449
|
+
{
|
|
450
|
+
customIdField: id1,
|
|
451
|
+
stringField: 'huh',
|
|
452
|
+
testIndexedField: '1',
|
|
453
|
+
intField: 3,
|
|
454
|
+
dateField: new Date(),
|
|
455
|
+
nullableField: null,
|
|
456
|
+
},
|
|
457
|
+
],
|
|
458
|
+
],
|
|
459
|
+
]),
|
|
460
|
+
),
|
|
461
|
+
);
|
|
462
|
+
const cacheAdapterProvider = new NoCacheStubCacheAdapterProvider();
|
|
463
|
+
const cacheAdapter = cacheAdapterProvider.getCacheAdapter(testEntityConfiguration);
|
|
464
|
+
const entityCache = new ReadThroughEntityCache(testEntityConfiguration, cacheAdapter);
|
|
465
|
+
const dataManager = new EntityDataManager(
|
|
466
|
+
databaseAdapter,
|
|
467
|
+
entityCache,
|
|
468
|
+
new StubQueryContextProvider(),
|
|
469
|
+
instance(mock<IEntityMetricsAdapter>()),
|
|
470
|
+
TestEntity.name,
|
|
471
|
+
);
|
|
472
|
+
const utils = new EntityLoaderUtils(
|
|
473
|
+
viewerContext,
|
|
474
|
+
queryContext,
|
|
475
|
+
privacyPolicyEvaluationContext,
|
|
476
|
+
testEntityConfiguration,
|
|
477
|
+
TestEntity,
|
|
478
|
+
/* entitySelectedFields */ undefined,
|
|
479
|
+
privacyPolicy,
|
|
480
|
+
dataManager,
|
|
481
|
+
metricsAdapter,
|
|
482
|
+
);
|
|
483
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
484
|
+
queryContext,
|
|
485
|
+
testEntityConfiguration,
|
|
486
|
+
TestEntity,
|
|
487
|
+
dataManager,
|
|
488
|
+
metricsAdapter,
|
|
489
|
+
utils,
|
|
490
|
+
);
|
|
491
|
+
const entity = await enforceAsyncResult(entityLoader.loadByIDAsync(id1));
|
|
492
|
+
verify(
|
|
493
|
+
spiedPrivacyPolicy.authorizeReadAsync(
|
|
494
|
+
viewerContext,
|
|
495
|
+
queryContext,
|
|
496
|
+
privacyPolicyEvaluationContext,
|
|
497
|
+
entity,
|
|
498
|
+
anything(),
|
|
499
|
+
),
|
|
500
|
+
).once();
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it('invalidates upon invalidate one', async () => {
|
|
504
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
505
|
+
const privacyPolicyEvaluationContext =
|
|
506
|
+
instance(
|
|
507
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
508
|
+
);
|
|
509
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
510
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
511
|
+
const privacyPolicy = instance(mock(TestEntityPrivacyPolicy));
|
|
512
|
+
const dataManagerMock = mock<EntityDataManager<TestFields>>();
|
|
513
|
+
const dataManagerInstance = instance(dataManagerMock);
|
|
514
|
+
|
|
515
|
+
const id1 = uuidv4();
|
|
516
|
+
const utils = new EntityLoaderUtils(
|
|
517
|
+
viewerContext,
|
|
518
|
+
queryContext,
|
|
519
|
+
privacyPolicyEvaluationContext,
|
|
520
|
+
testEntityConfiguration,
|
|
521
|
+
TestEntity,
|
|
522
|
+
/* entitySelectedFields */ undefined,
|
|
523
|
+
privacyPolicy,
|
|
524
|
+
dataManagerInstance,
|
|
525
|
+
metricsAdapter,
|
|
526
|
+
);
|
|
527
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
528
|
+
queryContext,
|
|
529
|
+
testEntityConfiguration,
|
|
530
|
+
TestEntity,
|
|
531
|
+
dataManagerInstance,
|
|
532
|
+
metricsAdapter,
|
|
533
|
+
utils,
|
|
534
|
+
);
|
|
535
|
+
await entityLoader.utils.invalidateFieldsAsync({ customIdField: id1 } as any);
|
|
536
|
+
|
|
537
|
+
verify(
|
|
538
|
+
dataManagerMock.invalidateObjectFieldsAsync(deepEqual({ customIdField: id1 } as any)),
|
|
539
|
+
).once();
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('invalidates upon invalidate by field', async () => {
|
|
543
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
544
|
+
const privacyPolicyEvaluationContext =
|
|
545
|
+
instance(
|
|
546
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
547
|
+
);
|
|
548
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
549
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
550
|
+
const privacyPolicy = instance(mock(TestEntityPrivacyPolicy));
|
|
551
|
+
const dataManagerMock = mock<EntityDataManager<TestFields>>();
|
|
552
|
+
const dataManagerInstance = instance(dataManagerMock);
|
|
553
|
+
|
|
554
|
+
const id1 = uuidv4();
|
|
555
|
+
const utils = new EntityLoaderUtils(
|
|
556
|
+
viewerContext,
|
|
557
|
+
queryContext,
|
|
558
|
+
privacyPolicyEvaluationContext,
|
|
559
|
+
testEntityConfiguration,
|
|
560
|
+
TestEntity,
|
|
561
|
+
/* entitySelectedFields */ undefined,
|
|
562
|
+
privacyPolicy,
|
|
563
|
+
dataManagerInstance,
|
|
564
|
+
metricsAdapter,
|
|
565
|
+
);
|
|
566
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
567
|
+
queryContext,
|
|
568
|
+
testEntityConfiguration,
|
|
569
|
+
TestEntity,
|
|
570
|
+
dataManagerInstance,
|
|
571
|
+
metricsAdapter,
|
|
572
|
+
utils,
|
|
573
|
+
);
|
|
574
|
+
await entityLoader.utils.invalidateFieldsAsync({ customIdField: id1 } as any);
|
|
575
|
+
verify(
|
|
576
|
+
dataManagerMock.invalidateObjectFieldsAsync(deepEqual({ customIdField: id1 } as any)),
|
|
577
|
+
).once();
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
it('invalidates upon invalidate by entity', async () => {
|
|
581
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
582
|
+
const privacyPolicyEvaluationContext =
|
|
583
|
+
instance(
|
|
584
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
585
|
+
);
|
|
586
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
587
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
588
|
+
const privacyPolicy = instance(mock(TestEntityPrivacyPolicy));
|
|
589
|
+
const dataManagerMock = mock<EntityDataManager<TestFields>>();
|
|
590
|
+
const dataManagerInstance = instance(dataManagerMock);
|
|
591
|
+
|
|
592
|
+
const id1 = uuidv4();
|
|
593
|
+
const entityMock = mock(TestEntity);
|
|
594
|
+
when(entityMock.getAllDatabaseFields()).thenReturn({ customIdField: id1 } as any);
|
|
595
|
+
const entityInstance = instance(entityMock);
|
|
596
|
+
|
|
597
|
+
const utils = new EntityLoaderUtils(
|
|
598
|
+
viewerContext,
|
|
599
|
+
queryContext,
|
|
600
|
+
privacyPolicyEvaluationContext,
|
|
601
|
+
testEntityConfiguration,
|
|
602
|
+
TestEntity,
|
|
603
|
+
/* entitySelectedFields */ undefined,
|
|
604
|
+
privacyPolicy,
|
|
605
|
+
dataManagerInstance,
|
|
606
|
+
metricsAdapter,
|
|
607
|
+
);
|
|
608
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
609
|
+
queryContext,
|
|
610
|
+
testEntityConfiguration,
|
|
611
|
+
TestEntity,
|
|
612
|
+
dataManagerInstance,
|
|
613
|
+
metricsAdapter,
|
|
614
|
+
utils,
|
|
615
|
+
);
|
|
616
|
+
await entityLoader.utils.invalidateEntityAsync(entityInstance);
|
|
617
|
+
verify(
|
|
618
|
+
dataManagerMock.invalidateObjectFieldsAsync(deepEqual({ customIdField: id1 } as any)),
|
|
619
|
+
).once();
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
it('returns error result when not allowed', async () => {
|
|
623
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
624
|
+
const privacyPolicyEvaluationContext =
|
|
625
|
+
instance(
|
|
626
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
627
|
+
);
|
|
628
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
629
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
630
|
+
const privacyPolicyMock = mock(TestEntityPrivacyPolicy);
|
|
631
|
+
const dataManagerMock = mock<EntityDataManager<TestFields>>();
|
|
632
|
+
|
|
633
|
+
const id1 = uuidv4();
|
|
634
|
+
when(
|
|
635
|
+
dataManagerMock.loadManyByFieldEqualingAsync(anything(), anything(), anything()),
|
|
636
|
+
).thenResolve(new Map().set(id1, [{ customIdField: id1 }]));
|
|
637
|
+
|
|
638
|
+
const rejectionError = new Error();
|
|
639
|
+
|
|
640
|
+
when(
|
|
641
|
+
privacyPolicyMock.authorizeReadAsync(
|
|
642
|
+
viewerContext,
|
|
643
|
+
queryContext,
|
|
644
|
+
privacyPolicyEvaluationContext,
|
|
645
|
+
anyOfClass(TestEntity),
|
|
646
|
+
anything(),
|
|
647
|
+
),
|
|
648
|
+
).thenReject(rejectionError);
|
|
649
|
+
|
|
650
|
+
const privacyPolicy = instance(privacyPolicyMock);
|
|
651
|
+
const dataManagerInstance = instance(dataManagerMock);
|
|
652
|
+
|
|
653
|
+
const utils = new EntityLoaderUtils(
|
|
654
|
+
viewerContext,
|
|
655
|
+
queryContext,
|
|
656
|
+
privacyPolicyEvaluationContext,
|
|
657
|
+
testEntityConfiguration,
|
|
658
|
+
TestEntity,
|
|
659
|
+
/* entitySelectedFields */ undefined,
|
|
660
|
+
privacyPolicy,
|
|
661
|
+
dataManagerInstance,
|
|
662
|
+
metricsAdapter,
|
|
663
|
+
);
|
|
664
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
665
|
+
queryContext,
|
|
666
|
+
testEntityConfiguration,
|
|
667
|
+
TestEntity,
|
|
668
|
+
dataManagerInstance,
|
|
669
|
+
metricsAdapter,
|
|
670
|
+
utils,
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
const entityResult = await entityLoader.loadByIDAsync(id1);
|
|
674
|
+
expect(entityResult.ok).toBe(false);
|
|
675
|
+
expect(entityResult.reason).toEqual(rejectionError);
|
|
676
|
+
expect(entityResult.value).toBe(undefined);
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
it('throws upon database adapter error', async () => {
|
|
680
|
+
const viewerContext = instance(mock(ViewerContext));
|
|
681
|
+
const privacyPolicyEvaluationContext =
|
|
682
|
+
instance(
|
|
683
|
+
mock<EntityPrivacyPolicyEvaluationContext<TestFields, string, ViewerContext, TestEntity>>(),
|
|
684
|
+
);
|
|
685
|
+
const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
|
|
686
|
+
const queryContext = new StubQueryContextProvider().getQueryContext();
|
|
687
|
+
const privacyPolicy = instance(mock(TestEntityPrivacyPolicy));
|
|
688
|
+
const dataManagerMock = mock<EntityDataManager<TestFields>>();
|
|
689
|
+
|
|
690
|
+
const error = new Error();
|
|
691
|
+
|
|
692
|
+
when(
|
|
693
|
+
dataManagerMock.loadManyByFieldEqualingAsync(anything(), anything(), anything()),
|
|
694
|
+
).thenReject(error);
|
|
695
|
+
|
|
696
|
+
const dataManagerInstance = instance(dataManagerMock);
|
|
697
|
+
|
|
698
|
+
const utils = new EntityLoaderUtils(
|
|
699
|
+
viewerContext,
|
|
700
|
+
queryContext,
|
|
701
|
+
privacyPolicyEvaluationContext,
|
|
702
|
+
testEntityConfiguration,
|
|
703
|
+
TestEntity,
|
|
704
|
+
/* entitySelectedFields */ undefined,
|
|
705
|
+
privacyPolicy,
|
|
706
|
+
dataManagerInstance,
|
|
707
|
+
metricsAdapter,
|
|
708
|
+
);
|
|
709
|
+
const entityLoader = new AuthorizationResultBasedEntityLoader(
|
|
710
|
+
queryContext,
|
|
711
|
+
testEntityConfiguration,
|
|
712
|
+
TestEntity,
|
|
713
|
+
dataManagerInstance,
|
|
714
|
+
metricsAdapter,
|
|
715
|
+
utils,
|
|
716
|
+
);
|
|
717
|
+
|
|
718
|
+
const loadByValue = uuidv4();
|
|
719
|
+
|
|
720
|
+
await expect(entityLoader.loadByIDAsync(loadByValue)).rejects.toEqual(error);
|
|
721
|
+
await expect(entityLoader.loadManyByIDsAsync([loadByValue])).rejects.toEqual(error);
|
|
722
|
+
await expect(entityLoader.loadManyByIDsNullableAsync([loadByValue])).rejects.toEqual(error);
|
|
723
|
+
await expect(
|
|
724
|
+
entityLoader.loadManyByFieldEqualingAsync('customIdField', loadByValue),
|
|
725
|
+
).rejects.toEqual(error);
|
|
726
|
+
await expect(
|
|
727
|
+
entityLoader.loadManyByFieldEqualingManyAsync('customIdField', [loadByValue]),
|
|
728
|
+
).rejects.toEqual(error);
|
|
729
|
+
});
|
|
730
|
+
});
|