From e072e6571771f5f62af454ef4030dc72a507e0cf Mon Sep 17 00:00:00 2001 From: Will Schurman Date: Thu, 20 Feb 2025 08:47:17 -0700 Subject: [PATCH] feat!: Default all loaders and mutators to enforcing --- .../GenericLocalMemoryCacher-full-test.ts | 41 +- ...tchedRedisCacheAdapter-integration-test.ts | 37 +- ...enericRedisCacher-full-integration-test.ts | 48 +-- .../GenericRedisCacher-integration-test.ts | 2 - .../src/__integration-tests__/errors-test.ts | 2 +- .../PostgresEntityIntegration-test.ts | 386 +++++++----------- ...PostgresEntityQueryContextProvider-test.ts | 39 +- .../PostgresInvalidSetup-test.ts | 27 +- .../src/__integration-tests__/errors-test.ts | 14 +- .../src/__tests__/NoteEntity-test.ts | 8 +- .../entity-example/src/routers/notesRouter.ts | 37 +- packages/entity-example/src/schema.ts | 18 +- .../EntityCacheInconsistency-test.ts | 21 +- .../EntityEdgesIntegration-test.ts | 15 +- .../EntityIntegrity-test.ts | 8 +- ...itySelfReferentialEdgesIntegration-test.ts | 26 +- .../LocalMemorySecondaryEntityCache-test.ts | 5 +- ...isSecondaryEntityCache-integration-test.ts | 5 +- ...ationResultBasedEntityAssociationLoader.ts | 6 +- packages/entity/src/Entity.ts | 170 +++++++- packages/entity/src/ReadonlyEntity.ts | 125 +++++- ...ResultBasedEntityAssociationLoader-test.ts | 105 ++--- packages/entity/src/__tests__/Entity-test.ts | 71 +++- .../__tests__/EntityAssociationLoader-test.ts | 10 +- .../__tests__/EntityCommonUseCases-test.ts | 31 +- .../entity/src/__tests__/EntityEdges-test.ts | 100 ++--- .../entity/src/__tests__/EntityLoader-test.ts | 8 +- ...tyMutator-MutationCacheConsistency-test.ts | 14 +- .../EntitySecondaryCacheLoader-test.ts | 12 +- .../EntitySelfReferentialEdges-test.ts | 134 +++--- .../src/__tests__/ReadonlyEntity-test.ts | 52 ++- .../TwoEntitySameTableDisjointRows-test.ts | 28 +- .../TwoEntitySameTableOverlappingRows-test.ts | 38 +- .../__tests__/EntityPrivacyUtils-test.ts | 66 +-- ...eletionPermissionInferenceBehavior-test.ts | 7 +- 35 files changed, 896 insertions(+), 820 deletions(-) diff --git a/packages/entity-cache-adapter-local-memory/src/__tests__/GenericLocalMemoryCacher-full-test.ts b/packages/entity-cache-adapter-local-memory/src/__tests__/GenericLocalMemoryCacher-full-test.ts index b213b8bd..ad70c4c4 100644 --- a/packages/entity-cache-adapter-local-memory/src/__tests__/GenericLocalMemoryCacher-full-test.ts +++ b/packages/entity-cache-adapter-local-memory/src/__tests__/GenericLocalMemoryCacher-full-test.ts @@ -26,15 +26,14 @@ describe(GenericLocalMemoryCacher, () => { const date = new Date(); const entity1Created = await LocalMemoryTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'blah') .setField('dateField', date) .createAsync(); // loading an entity should put it in cache - const entity1 = await LocalMemoryTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity1Created.getID()); + const entity1 = await LocalMemoryTestEntity.loader(viewerContext).loadByIDAsync( + entity1Created.getID(), + ); const localMemoryCacheAdapterProvider = ( entityCompanionProvider['cacheAdapterFlavors'] as ReadonlyMap< @@ -64,9 +63,10 @@ describe(GenericLocalMemoryCacher, () => { // simulate non existent db fetch, should write negative result ('') to cache const nonExistentId = uuidv4(); - const entityNonExistentResult = await LocalMemoryTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult = + await LocalMemoryTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult.ok).toBe(false); const nonExistentCachedResult = await entitySpecificGenericCacher.loadManyAsync([ @@ -77,15 +77,16 @@ describe(GenericLocalMemoryCacher, () => { }); // load again through entities framework to ensure it reads negative result - const entityNonExistentResult2 = await LocalMemoryTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult2 = + await LocalMemoryTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult2.ok).toBe(false); // invalidate from cache to ensure it invalidates correctly - await LocalMemoryTestEntity.loader(viewerContext) - .utils() - .invalidateFieldsAsync(entity1.getAllFields()); + await LocalMemoryTestEntity.loaderUtils(viewerContext).invalidateFieldsAsync( + entity1.getAllFields(), + ); const cachedResultMiss = await entitySpecificGenericCacher.loadManyAsync([ cacheKeyMaker('id', entity1.getID()), ]); @@ -104,15 +105,14 @@ describe(GenericLocalMemoryCacher, () => { const date = new Date(); const entity1Created = await LocalMemoryTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'blah') .setField('dateField', date) .createAsync(); // loading an entity will try to put it in cache but it's a noop cache, so it should be a miss - const entity1 = await LocalMemoryTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity1Created.getID()); + const entity1 = await LocalMemoryTestEntity.loader(viewerContext).loadByIDAsync( + entity1Created.getID(), + ); const localMemoryCacheAdapterProvider = ( entityCompanionProvider['cacheAdapterFlavors'] as ReadonlyMap< @@ -137,9 +137,10 @@ describe(GenericLocalMemoryCacher, () => { // a non existent db fetch should try to write negative result ('') but it's a noop cache, so it should be a miss const nonExistentId = uuidv4(); - const entityNonExistentResult = await LocalMemoryTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult = + await LocalMemoryTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult.ok).toBe(false); const nonExistentCachedResult = await entitySpecificGenericCacher.loadManyAsync([ diff --git a/packages/entity-cache-adapter-redis/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts b/packages/entity-cache-adapter-redis/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts index 772aab6f..5e904387 100644 --- a/packages/entity-cache-adapter-redis/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts +++ b/packages/entity-cache-adapter-redis/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts @@ -104,7 +104,6 @@ describe(GenericRedisCacher, () => { const cacheKeyMaker = genericCacher['makeCacheKey'].bind(genericCacher); const entity1Created = await RedisTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'blah') .createAsync(); @@ -120,11 +119,12 @@ describe(GenericRedisCacher, () => { createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext), ); const [entity1, entity2, entity3] = await Promise.all([ - RedisTestEntity.loader(viewerContext1).enforcing().loadByIDAsync(entity1Created.getID()), - RedisTestEntity.loader(viewerContext2).enforcing().loadByIDAsync(entity1Created.getID()), - RedisTestEntity.loader(viewerContext3) - .enforcing() - .loadByFieldEqualingAsync('name', entity1Created.getField('name')), + RedisTestEntity.loader(viewerContext1).loadByIDAsync(entity1Created.getID()), + RedisTestEntity.loader(viewerContext2).loadByIDAsync(entity1Created.getID()), + RedisTestEntity.loader(viewerContext3).loadByFieldEqualingAsync( + 'name', + entity1Created.getField('name'), + ), ]); expect(mgetSpy).toHaveBeenCalledTimes(1); @@ -141,30 +141,31 @@ describe(GenericRedisCacher, () => { }); const cacheKeyEntity1NameField = cacheKeyMaker('name', entity1Created.getField('name')); - await RedisTestEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('name', entity1Created.getField('name')); + await RedisTestEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'name', + entity1Created.getField('name'), + ); await expect(redis.get(cacheKeyEntity1NameField)).resolves.toEqual(cachedJSON); // simulate non existent db fetch, should write negative result ('') to cache const nonExistentId = uuidv4(); - const entityNonExistentResult = await RedisTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult = + await RedisTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult.ok).toBe(false); const cacheKeyNonExistent = cacheKeyMaker('id', nonExistentId); const nonExistentCachedValue = await redis.get(cacheKeyNonExistent); expect(nonExistentCachedValue).toEqual(''); // load again through entities framework to ensure it reads negative result - const entityNonExistentResult2 = await RedisTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult2 = + await RedisTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult2.ok).toBe(false); // invalidate from cache to ensure it invalidates correctly in both caches - await RedisTestEntity.loader(viewerContext) - .utils() - .invalidateFieldsAsync(entity1.getAllFields()); + await RedisTestEntity.loaderUtils(viewerContext).invalidateFieldsAsync(entity1.getAllFields()); await expect(redis.get(cacheKeyEntity1)).resolves.toBeNull(); await expect(redis.get(cacheKeyEntity1NameField)).resolves.toBeNull(); }); diff --git a/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts b/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts index 884f22fb..0272452b 100644 --- a/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts +++ b/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-full-integration-test.ts @@ -47,14 +47,13 @@ describe(GenericRedisCacher, () => { const cacheKeyMaker = genericCacher['makeCacheKey'].bind(genericCacher); const entity1Created = await RedisTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'blah') .createAsync(); // loading an entity should put it in cache - const entity1 = await RedisTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity1Created.getID()); + const entity1 = await RedisTestEntity.loader(viewerContext).loadByIDAsync( + entity1Created.getID(), + ); const cachedJSON = await (genericRedisCacheContext.redisClient as Redis).get( cacheKeyMaker('id', entity1.getID()), @@ -68,9 +67,10 @@ describe(GenericRedisCacher, () => { // simulate non existent db fetch, should write negative result ('') to cache const nonExistentId = uuidv4(); - const entityNonExistentResult = await RedisTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult = + await RedisTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult.ok).toBe(false); const nonExistentCachedValue = await (genericRedisCacheContext.redisClient as Redis).get( @@ -79,15 +79,14 @@ describe(GenericRedisCacher, () => { expect(nonExistentCachedValue).toEqual(''); // load again through entities framework to ensure it reads negative result - const entityNonExistentResult2 = await RedisTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(nonExistentId); + const entityNonExistentResult2 = + await RedisTestEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + nonExistentId, + ); expect(entityNonExistentResult2.ok).toBe(false); // invalidate from cache to ensure it invalidates correctly - await RedisTestEntity.loader(viewerContext) - .utils() - .invalidateFieldsAsync(entity1.getAllFields()); + await RedisTestEntity.loaderUtils(viewerContext).invalidateFieldsAsync(entity1.getAllFields()); const cachedValueNull = await (genericRedisCacheContext.redisClient as Redis).get( cacheKeyMaker('id', entity1.getID()), ); @@ -100,23 +99,20 @@ describe(GenericRedisCacher, () => { ); const date = new Date(); const entity1 = await enforceAsyncResult( - RedisTestEntity.creator(viewerContext) - .withAuthorizationResults() + RedisTestEntity.creatorWithAuthorizationResults(viewerContext) .setField('dateField', date) .createAsync(), ); expect(entity1.getField('dateField')).toEqual(date); - const entity2 = await RedisTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity1.getID()); + const entity2 = await RedisTestEntity.loader(viewerContext).loadByIDAsync(entity1.getID()); expect(entity2.getField('dateField')).toEqual(date); // simulate new request const vc2 = new TestViewerContext( createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext), ); - const entity3 = await RedisTestEntity.loader(vc2).enforcing().loadByIDAsync(entity1.getID()); + const entity3 = await RedisTestEntity.loader(vc2).loadByIDAsync(entity1.getID()); expect(entity3.getField('dateField')).toEqual(date); }); @@ -125,23 +121,21 @@ describe(GenericRedisCacher, () => { createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext), ); const entity1 = await enforceAsyncResult( - RedisTestEntity.creator(viewerContext) - .withAuthorizationResults() + RedisTestEntity.creatorWithAuthorizationResults(viewerContext) .setField('name', '') .createAsync(), ); - const entity2 = await RedisTestEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('name', ''); + const entity2 = await RedisTestEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'name', + '', + ); expect(entity2?.getID()).toEqual(entity1.getID()); // simulate new request const vc2 = new TestViewerContext( createRedisIntegrationTestEntityCompanionProvider(genericRedisCacheContext), ); - const entity3 = await RedisTestEntity.loader(vc2) - .enforcing() - .loadByFieldEqualingAsync('name', ''); + const entity3 = await RedisTestEntity.loader(vc2).loadByFieldEqualingAsync('name', ''); expect(entity3?.getID()).toEqual(entity1.getID()); }); }); diff --git a/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-integration-test.ts b/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-integration-test.ts index a624e6eb..9d8f900f 100644 --- a/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-integration-test.ts +++ b/packages/entity-cache-adapter-redis/src/__integration-tests__/GenericRedisCacher-integration-test.ts @@ -47,7 +47,6 @@ describe(GenericRedisCacher, () => { ); const date = new Date(); const entity1Created = await RedisTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'blah') .setField('dateField', date) .createAsync(); @@ -94,7 +93,6 @@ describe(GenericRedisCacher, () => { ); const date = new Date(); const entity1Created = await RedisTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'blah') .setField('dateField', date) .createAsync(); diff --git a/packages/entity-cache-adapter-redis/src/__integration-tests__/errors-test.ts b/packages/entity-cache-adapter-redis/src/__integration-tests__/errors-test.ts index b2e6ba72..57b081c5 100644 --- a/packages/entity-cache-adapter-redis/src/__integration-tests__/errors-test.ts +++ b/packages/entity-cache-adapter-redis/src/__integration-tests__/errors-test.ts @@ -40,7 +40,7 @@ describe(GenericRedisCacher, () => { ); await expect( - RedisTestEntity.creator(vc1).enforcing().setField('name', 'blah').createAsync(), + RedisTestEntity.creator(vc1).setField('name', 'blah').createAsync(), ).rejects.toThrow(EntityCacheAdapterTransientError); }); }); diff --git a/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityIntegration-test.ts b/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityIntegration-test.ts index 3f32e173..9c8e68cc 100644 --- a/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityIntegration-test.ts +++ b/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityIntegration-test.ts @@ -42,21 +42,18 @@ describe('postgres entity integration', () => { it('supports parallel partial updates', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc) .setField('name', 'hello') .createAsync(), ); // update two different fields at the same time (from the same entity) await Promise.all([ - PostgresTestEntity.updater(entity).enforcing().setField('hasACat', true).updateAsync(), - PostgresTestEntity.updater(entity).enforcing().setField('hasADog', false).updateAsync(), + PostgresTestEntity.updater(entity).setField('hasACat', true).updateAsync(), + PostgresTestEntity.updater(entity).setField('hasADog', false).updateAsync(), ]); - const loadedEntity = await PostgresTestEntity.loader(vc) - .enforcing() - .loadByIDAsync(entity.getID()); + const loadedEntity = await PostgresTestEntity.loader(vc).loadByIDAsync(entity.getID()); expect(loadedEntity.getField('hasACat')).toBe(true); expect(loadedEntity.getField('hasADog')).toBe(false); @@ -66,7 +63,7 @@ describe('postgres entity integration', () => { it('allows empty create', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc).withAuthorizationResults().createAsync(), + PostgresTestEntity.creatorWithAuthorizationResults(vc).createAsync(), ); expect(entity.getID()).toBeTruthy(); }); @@ -74,23 +71,21 @@ describe('postgres entity integration', () => { it('throws knex error upon empty update', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc) .setField('name', 'hello') .createAsync(), ); - await expect(PostgresTestEntity.updater(entity).enforcing().updateAsync()).rejects.toThrow(); + await expect(PostgresTestEntity.updater(entity).updateAsync()).rejects.toThrow(); }); it('throws error upon empty update for stub database adapter to match behavior', async () => { const vc = new ViewerContext(createUnitTestEntityCompanionProvider()); const entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc) .setField('name', 'hello') .createAsync(), ); - await expect(PostgresTestEntity.updater(entity).enforcing().updateAsync()).rejects.toThrow(); + await expect(PostgresTestEntity.updater(entity).updateAsync()).rejects.toThrow(); }); }); @@ -99,13 +94,12 @@ describe('postgres entity integration', () => { // put one in the DB const firstEntity = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'hello') .createAsync(), ); - await PostgresTestEntity.loader(vc1).enforcing().loadByIDAsync(firstEntity.getID()); + await PostgresTestEntity.loader(vc1).loadByIDAsync(firstEntity.getID()); const errorToThrow = new Error('Intentional error'); @@ -115,8 +109,7 @@ describe('postgres entity integration', () => { async (queryContext) => { // put another in the DB that will be rolled back due to error thrown await enforceAsyncResult( - PostgresTestEntity.creator(vc1, queryContext) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1, queryContext) .setField('name', 'hello') .createAsync(), ); @@ -127,9 +120,10 @@ describe('postgres entity integration', () => { ), ).rejects.toEqual(errorToThrow); - const entities = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByFieldEqualingAsync('name', 'hello'); + const entities = await PostgresTestEntity.loader(vc1).loadManyByFieldEqualingAsync( + 'name', + 'hello', + ); expect(entities).toHaveLength(1); }); @@ -142,8 +136,7 @@ describe('postgres entity integration', () => { ); const firstEntity = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'hello') .createAsync(), ); @@ -156,12 +149,11 @@ describe('postgres entity integration', () => { await vc1.runInTransactionForDatabaseAdaptorFlavorAsync( 'postgres', async (queryContext) => { - const entity = await PostgresTestEntity.loader(vc1, queryContext) - .enforcing() - .loadByIDAsync(firstEntity.getID()); + const entity = await PostgresTestEntity.loader(vc1, queryContext).loadByIDAsync( + firstEntity.getID(), + ); await setTimeout(delay); await PostgresTestEntity.updater(entity, queryContext) - .enforcing() .setField('name', entity.getField('name') + ',' + newName) .updateAsync(); }, @@ -199,8 +191,7 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('stringArray', ['hello', 'world']) .setField('jsonArrayField', ['hello', 'world']) .createAsync(), @@ -214,8 +205,7 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('jsonObjectField', { hello: 'world' }) .createAsync(), ); @@ -227,14 +217,12 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity1 = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('maybeJsonArrayField', ['hello', 'world']) .createAsync(), ); const entity2 = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('maybeJsonArrayField', { hello: 'world' }) .createAsync(), ); @@ -249,24 +237,21 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); let entity = await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('bigintField', '72057594037928038') .createAsync(), ); expect(entity.getField('bigintField')).toEqual('72057594037928038'); entity = await enforceAsyncResult( - PostgresTestEntity.updater(entity) - .withAuthorizationResults() + PostgresTestEntity.updaterWithAuthorizationResults(entity) .setField('bigintField', '10') .updateAsync(), ); expect(entity.getField('bigintField')).toEqual('10'); entity = await enforceAsyncResult( - PostgresTestEntity.updater(entity) - .withAuthorizationResults() + PostgresTestEntity.updaterWithAuthorizationResults(entity) .setField('bigintField', '-10') .updateAsync(), ); @@ -279,8 +264,7 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'hello') .setField('hasACat', false) .setField('hasADog', true) @@ -288,8 +272,7 @@ describe('postgres entity integration', () => { ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'world') .setField('hasACat', false) .setField('hasADog', true) @@ -297,34 +280,29 @@ describe('postgres entity integration', () => { ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'wat') .setField('hasACat', false) .setField('hasADog', false) .createAsync(), ); - const results = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByFieldEqualityConjunctionAsync([ - { - fieldName: 'hasACat', - fieldValue: false, - }, - { - fieldName: 'hasADog', - fieldValue: true, - }, - ]); + const results = await PostgresTestEntity.loader(vc1).loadManyByFieldEqualityConjunctionAsync([ + { + fieldName: 'hasACat', + fieldValue: false, + }, + { + fieldName: 'hasADog', + fieldValue: true, + }, + ]); expect(results).toHaveLength(2); - const results2 = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByFieldEqualityConjunctionAsync([ - { fieldName: 'hasADog', fieldValues: [true, false] }, - ]); + const results2 = await PostgresTestEntity.loader(vc1).loadManyByFieldEqualityConjunctionAsync( + [{ fieldName: 'hasADog', fieldValues: [true, false] }], + ); expect(results2).toHaveLength(3); }); @@ -332,29 +310,20 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() - .setField('name', 'a') - .createAsync(), + PostgresTestEntity.creatorWithAuthorizationResults(vc1).setField('name', 'a').createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() - .setField('name', 'b') - .createAsync(), + PostgresTestEntity.creatorWithAuthorizationResults(vc1).setField('name', 'b').createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() - .setField('name', 'c') - .createAsync(), + PostgresTestEntity.creatorWithAuthorizationResults(vc1).setField('name', 'c').createAsync(), ); - const results = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByFieldEqualityConjunctionAsync([], { + const results = await PostgresTestEntity.loader(vc1).loadManyByFieldEqualityConjunctionAsync( + [], + { limit: 2, offset: 1, orderBy: [ @@ -363,7 +332,8 @@ describe('postgres entity integration', () => { order: OrderByOrdering.DESCENDING, }, ], - }); + }, + ); expect(results).toHaveLength(2); expect(results.map((e) => e.getField('name'))).toEqual(['b', 'a']); }); @@ -371,56 +341,50 @@ describe('postgres entity integration', () => { it('supports null field values', async () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'a') .setField('hasADog', true) .createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'b') .setField('hasADog', true) .createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', null) .setField('hasADog', true) .createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', null) .setField('hasADog', false) .createAsync(), ); - const results = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByFieldEqualityConjunctionAsync([{ fieldName: 'name', fieldValue: null }]); + const results = await PostgresTestEntity.loader(vc1).loadManyByFieldEqualityConjunctionAsync([ + { fieldName: 'name', fieldValue: null }, + ]); expect(results).toHaveLength(2); expect(results[0]!.getField('name')).toBeNull(); - const results2 = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByFieldEqualityConjunctionAsync( - [ - { fieldName: 'name', fieldValues: ['a', null] }, - { fieldName: 'hasADog', fieldValue: true }, + const results2 = await PostgresTestEntity.loader(vc1).loadManyByFieldEqualityConjunctionAsync( + [ + { fieldName: 'name', fieldValues: ['a', null] }, + { fieldName: 'hasADog', fieldValue: true }, + ], + { + orderBy: [ + { + fieldName: 'name', + order: OrderByOrdering.DESCENDING, + }, ], - { - orderBy: [ - { - fieldName: 'name', - order: OrderByOrdering.DESCENDING, - }, - ], - }, - ); + }, + ); expect(results2).toHaveLength(2); expect(results2.map((e) => e.getField('name'))).toEqual([null, 'a']); }); @@ -430,17 +394,17 @@ describe('postgres entity integration', () => { it('loads by raw where clause', async () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'hello') .setField('hasACat', false) .setField('hasADog', true) .createAsync(), ); - const results = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByRawWhereClauseAsync('name = ?', ['hello']); + const results = await PostgresTestEntity.loader(vc1).loadManyByRawWhereClauseAsync( + 'name = ?', + ['hello'], + ); expect(results).toHaveLength(1); }); @@ -448,8 +412,7 @@ describe('postgres entity integration', () => { it('throws with invalid where clause', async () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'hello') .setField('hasACat', false) .setField('hasADog', true) @@ -457,9 +420,9 @@ describe('postgres entity integration', () => { ); await expect( - PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByRawWhereClauseAsync('invalid_column = ?', ['hello']), + PostgresTestEntity.loader(vc1).loadManyByRawWhereClauseAsync('invalid_column = ?', [ + 'hello', + ]), ).rejects.toThrow(); }); @@ -467,32 +430,30 @@ describe('postgres entity integration', () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'a') .setField('hasADog', true) .createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'b') .setField('hasADog', true) .createAsync(), ); await enforceAsyncResult( - PostgresTestEntity.creator(vc1) - .withAuthorizationResults() + PostgresTestEntity.creatorWithAuthorizationResults(vc1) .setField('name', 'c') .setField('hasADog', true) .createAsync(), ); - const results = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByRawWhereClauseAsync('has_a_dog = ?', [true], { + const results = await PostgresTestEntity.loader(vc1).loadManyByRawWhereClauseAsync( + 'has_a_dog = ?', + [true], + { limit: 2, offset: 1, orderBy: [ @@ -501,34 +462,37 @@ describe('postgres entity integration', () => { order: OrderByOrdering.ASCENDING, }, ], - }); + }, + ); expect(results).toHaveLength(2); expect(results.map((e) => e.getField('name'))).toEqual(['b', 'c']); - const resultsMultipleOrderBy = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByRawWhereClauseAsync('has_a_dog = ?', [true], { - orderBy: [ - { - fieldName: 'hasADog', - order: OrderByOrdering.ASCENDING, - }, - { - fieldName: 'name', - order: OrderByOrdering.DESCENDING, - }, - ], - }); + const resultsMultipleOrderBy = await PostgresTestEntity.loader( + vc1, + ).loadManyByRawWhereClauseAsync('has_a_dog = ?', [true], { + orderBy: [ + { + fieldName: 'hasADog', + order: OrderByOrdering.ASCENDING, + }, + { + fieldName: 'name', + order: OrderByOrdering.DESCENDING, + }, + ], + }); expect(resultsMultipleOrderBy).toHaveLength(3); expect(resultsMultipleOrderBy.map((e) => e.getField('name'))).toEqual(['c', 'b', 'a']); - const resultsOrderByRaw = await PostgresTestEntity.loader(vc1) - .enforcing() - .loadManyByRawWhereClauseAsync('has_a_dog = ?', [true], { + const resultsOrderByRaw = await PostgresTestEntity.loader(vc1).loadManyByRawWhereClauseAsync( + 'has_a_dog = ?', + [true], + { orderByRaw: 'has_a_dog ASC, name DESC', - }); + }, + ); expect(resultsOrderByRaw).toHaveLength(3); expect(resultsOrderByRaw.map((e) => e.getField('name'))).toEqual(['c', 'b', 'a']); @@ -543,63 +507,38 @@ describe('postgres entity integration', () => { ); await expect( - PostgresTriggerTestEntity.creator(vc1) - .enforcing() - .setField('name', 'beforeCreate') - .createAsync(), + PostgresTriggerTestEntity.creator(vc1).setField('name', 'beforeCreate').createAsync(), ).rejects.toThrowError('name cannot have value beforeCreate'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeCreate'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'beforeCreate'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.creator(vc1) - .enforcing() - .setField('name', 'afterCreate') - .createAsync(), + PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterCreate').createAsync(), ).rejects.toThrowError('name cannot have value afterCreate'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterCreate'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterCreate'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.creator(vc1) - .enforcing() - .setField('name', 'beforeAll') - .createAsync(), + PostgresTriggerTestEntity.creator(vc1).setField('name', 'beforeAll').createAsync(), ).rejects.toThrowError('name cannot have value beforeAll'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeAll'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'beforeAll'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.creator(vc1) - .enforcing() - .setField('name', 'afterAll') - .createAsync(), + PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterAll').createAsync(), ).rejects.toThrowError('name cannot have value afterAll'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterAll'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterAll'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.creator(vc1) - .enforcing() - .setField('name', 'afterCommit') - .createAsync(), + PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterCommit').createAsync(), ).rejects.toThrowError('name cannot have value afterCommit'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterCommit'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterCommit'), ).resolves.not.toBeNull(); }); }); @@ -611,68 +550,42 @@ describe('postgres entity integration', () => { ); const entity = await PostgresTriggerTestEntity.creator(vc1) - .enforcing() .setField('name', 'blah') .createAsync(); await expect( - PostgresTriggerTestEntity.updater(entity) - .enforcing() - .setField('name', 'beforeUpdate') - .updateAsync(), + PostgresTriggerTestEntity.updater(entity).setField('name', 'beforeUpdate').updateAsync(), ).rejects.toThrowError('name cannot have value beforeUpdate'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeUpdate'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'beforeUpdate'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.updater(entity) - .enforcing() - .setField('name', 'afterUpdate') - .updateAsync(), + PostgresTriggerTestEntity.updater(entity).setField('name', 'afterUpdate').updateAsync(), ).rejects.toThrowError('name cannot have value afterUpdate'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterUpdate'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterUpdate'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.updater(entity) - .enforcing() - .setField('name', 'beforeAll') - .updateAsync(), + PostgresTriggerTestEntity.updater(entity).setField('name', 'beforeAll').updateAsync(), ).rejects.toThrowError('name cannot have value beforeAll'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeAll'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'beforeAll'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.updater(entity) - .enforcing() - .setField('name', 'afterAll') - .updateAsync(), + PostgresTriggerTestEntity.updater(entity).setField('name', 'afterAll').updateAsync(), ).rejects.toThrowError('name cannot have value afterAll'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterAll'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterAll'), ).resolves.toBeNull(); await expect( - PostgresTriggerTestEntity.updater(entity) - .enforcing() - .setField('name', 'afterCommit') - .updateAsync(), + PostgresTriggerTestEntity.updater(entity).setField('name', 'afterCommit').updateAsync(), ).rejects.toThrowError('name cannot have value afterCommit'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterCommit'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterCommit'), ).resolves.not.toBeNull(); }); }); @@ -684,29 +597,23 @@ describe('postgres entity integration', () => { ); const entityBeforeDelete = await PostgresTriggerTestEntity.creator(vc1) - .enforcing() .setField('name', 'beforeDelete') .createAsync(); await expect( - PostgresTriggerTestEntity.deleter(entityBeforeDelete).enforcing().deleteAsync(), + PostgresTriggerTestEntity.deleter(entityBeforeDelete).deleteAsync(), ).rejects.toThrowError('name cannot have value beforeDelete'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeDelete'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'beforeDelete'), ).resolves.not.toBeNull(); const entityAfterDelete = await PostgresTriggerTestEntity.creator(vc1) - .enforcing() .setField('name', 'afterDelete') .createAsync(); await expect( - PostgresTriggerTestEntity.deleter(entityAfterDelete).enforcing().deleteAsync(), + PostgresTriggerTestEntity.deleter(entityAfterDelete).deleteAsync(), ).rejects.toThrowError('name cannot have value afterDelete'); await expect( - PostgresTriggerTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'afterDelete'), + PostgresTriggerTestEntity.loader(vc1).loadByFieldEqualingAsync('name', 'afterDelete'), ).resolves.not.toBeNull(); }); }); @@ -719,14 +626,14 @@ describe('postgres entity integration', () => { await expect( PostgresValidatorTestEntity.creator(vc1) - .enforcing() .setField('name', 'beforeCreateAndBeforeUpdate') .createAsync(), ).rejects.toThrowError('name cannot have value beforeCreateAndBeforeUpdate'); await expect( - PostgresValidatorTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate'), + PostgresValidatorTestEntity.loader(vc1).loadByFieldEqualingAsync( + 'name', + 'beforeCreateAndBeforeUpdate', + ), ).resolves.toBeNull(); }); }); @@ -737,20 +644,19 @@ describe('postgres entity integration', () => { ); const entity = await PostgresValidatorTestEntity.creator(vc1) - .enforcing() .setField('name', 'blah') .createAsync(); await expect( PostgresValidatorTestEntity.updater(entity) - .enforcing() .setField('name', 'beforeCreateAndBeforeUpdate') .updateAsync(), ).rejects.toThrowError('name cannot have value beforeCreateAndBeforeUpdate'); await expect( - PostgresValidatorTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate'), + PostgresValidatorTestEntity.loader(vc1).loadByFieldEqualingAsync( + 'name', + 'beforeCreateAndBeforeUpdate', + ), ).resolves.toBeNull(); }); }); @@ -761,14 +667,14 @@ describe('postgres entity integration', () => { ); const entityToDelete = await PostgresValidatorTestEntity.creator(vc1) - .enforcing() .setField('name', 'shouldBeDeleted') .createAsync(); - await PostgresValidatorTestEntity.deleter(entityToDelete).enforcing().deleteAsync(); + await PostgresValidatorTestEntity.deleter(entityToDelete).deleteAsync(); await expect( - PostgresValidatorTestEntity.loader(vc1) - .enforcing() - .loadByFieldEqualingAsync('name', 'shouldBeDeleted'), + PostgresValidatorTestEntity.loader(vc1).loadByFieldEqualingAsync( + 'name', + 'shouldBeDeleted', + ), ).resolves.toBeNull(); }); }); diff --git a/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityQueryContextProvider-test.ts b/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityQueryContextProvider-test.ts index 73e5ddf6..ce3863dd 100644 --- a/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityQueryContextProvider-test.ts +++ b/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityQueryContextProvider-test.ts @@ -34,21 +34,15 @@ describe(PostgresEntityQueryContextProvider, () => { it('supports nested transactions', async () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); - await PostgresUniqueTestEntity.creator(vc1) - .enforcing() - .setField('name', 'unique') - .createAsync(); + await PostgresUniqueTestEntity.creator(vc1).setField('name', 'unique').createAsync(); const id = ( - await PostgresUniqueTestEntity.creator(vc1).enforcing().setField('name', 'wat').createAsync() + await PostgresUniqueTestEntity.creator(vc1).setField('name', 'wat').createAsync() ).getID(); await vc1.runInTransactionForDatabaseAdaptorFlavorAsync('postgres', async (queryContext) => { - const entity = await PostgresUniqueTestEntity.loader(vc1, queryContext) - .enforcing() - .loadByIDAsync(id); + const entity = await PostgresUniqueTestEntity.loader(vc1, queryContext).loadByIDAsync(id); await PostgresUniqueTestEntity.updater(entity, queryContext) - .enforcing() .setField('name', 'wat2') .updateAsync(); @@ -56,26 +50,23 @@ describe(PostgresEntityQueryContextProvider, () => { // in this case the error triggered is a unique constraint violation try { await queryContext.runInNestedTransactionAsync(async (innerQueryContext) => { - const entity = await PostgresUniqueTestEntity.loader(vc1, innerQueryContext) - .enforcing() - .loadByIDAsync(id); + const entity = await PostgresUniqueTestEntity.loader( + vc1, + innerQueryContext, + ).loadByIDAsync(id); await PostgresUniqueTestEntity.updater(entity, innerQueryContext) - .enforcing() .setField('name', 'unique') .updateAsync(); }); } catch {} - const entity2 = await PostgresUniqueTestEntity.loader(vc1, queryContext) - .enforcing() - .loadByIDAsync(id); + const entity2 = await PostgresUniqueTestEntity.loader(vc1, queryContext).loadByIDAsync(id); await PostgresUniqueTestEntity.updater(entity2, queryContext) - .enforcing() .setField('name', 'wat3') .updateAsync(); }); - const entityLoaded = await PostgresUniqueTestEntity.loader(vc1).enforcing().loadByIDAsync(id); + const entityLoaded = await PostgresUniqueTestEntity.loader(vc1).loadByIDAsync(id); expect(entityLoaded.getField('name')).toEqual('wat3'); }); @@ -83,18 +74,18 @@ describe(PostgresEntityQueryContextProvider, () => { const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const id = ( - await PostgresUniqueTestEntity.creator(vc1).enforcing().setField('name', 'wat').createAsync() + await PostgresUniqueTestEntity.creator(vc1).setField('name', 'wat').createAsync() ).getID(); await vc1.runInTransactionForDatabaseAdaptorFlavorAsync('postgres', async (queryContext) => { await queryContext.runInNestedTransactionAsync(async (innerQueryContext) => { await innerQueryContext.runInNestedTransactionAsync(async (innerQueryContex2) => { await innerQueryContex2.runInNestedTransactionAsync(async (innerQueryContex3) => { - const entity = await PostgresUniqueTestEntity.loader(vc1, innerQueryContex3) - .enforcing() - .loadByIDAsync(id); + const entity = await PostgresUniqueTestEntity.loader( + vc1, + innerQueryContex3, + ).loadByIDAsync(id); await PostgresUniqueTestEntity.updater(entity, innerQueryContex3) - .enforcing() .setField('name', 'wat3') .updateAsync(); }); @@ -102,7 +93,7 @@ describe(PostgresEntityQueryContextProvider, () => { }); }); - const entityLoaded = await PostgresUniqueTestEntity.loader(vc1).enforcing().loadByIDAsync(id); + const entityLoaded = await PostgresUniqueTestEntity.loader(vc1).loadByIDAsync(id); expect(entityLoaded.getField('name')).toEqual('wat3'); }); }); diff --git a/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresInvalidSetup-test.ts b/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresInvalidSetup-test.ts index b5a77e37..4ad0e2e9 100644 --- a/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresInvalidSetup-test.ts +++ b/packages/entity-database-adapter-knex/src/__integration-tests__/PostgresInvalidSetup-test.ts @@ -35,60 +35,55 @@ describe('postgres entity integration', () => { it('throws after deletion of multiple rows or no rows', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity1 = await enforceAsyncResult( - InvalidTestEntity.creator(vc) - .withAuthorizationResults() + InvalidTestEntity.creatorWithAuthorizationResults(vc) .setField('id', 1) .setField('name', 'hello') .createAsync(), ); await enforceAsyncResult( - InvalidTestEntity.creator(vc) - .withAuthorizationResults() + InvalidTestEntity.creatorWithAuthorizationResults(vc) .setField('id', 1) .setField('name', 'world') .createAsync(), ); - await expect( - InvalidTestEntity.deleter(entity1).enforcing().deleteAsync(), - ).rejects.toThrowError('Excessive deletions from database adapter delete'); + await expect(InvalidTestEntity.deleter(entity1).deleteAsync()).rejects.toThrowError( + 'Excessive deletions from database adapter delete', + ); }); it('throws after update of multiple rows', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity1 = await enforceAsyncResult( - InvalidTestEntity.creator(vc) - .withAuthorizationResults() + InvalidTestEntity.creatorWithAuthorizationResults(vc) .setField('id', 1) .setField('name', 'hello') .createAsync(), ); await enforceAsyncResult( - InvalidTestEntity.creator(vc) - .withAuthorizationResults() + InvalidTestEntity.creatorWithAuthorizationResults(vc) .setField('id', 1) .setField('name', 'world') .createAsync(), ); await expect( - InvalidTestEntity.updater(entity1).enforcing().setField('name', 'blah').updateAsync(), + InvalidTestEntity.updater(entity1).setField('name', 'blah').updateAsync(), ).rejects.toThrowError('Excessive results from database adapter update'); }); it('throws after update of no rows', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); const entity1 = await enforceAsyncResult( - InvalidTestEntity.creator(vc) - .withAuthorizationResults() + InvalidTestEntity.creatorWithAuthorizationResults(vc) .setField('id', 1) .setField('name', 'hello') .createAsync(), ); - await InvalidTestEntity.deleter(entity1).enforcing().deleteAsync(); + await InvalidTestEntity.deleter(entity1).deleteAsync(); await expect( - InvalidTestEntity.updater(entity1).enforcing().setField('name', 'blah').updateAsync(), + InvalidTestEntity.updater(entity1).setField('name', 'blah').updateAsync(), ).rejects.toThrowError('Empty results from database adapter update'); }); }); diff --git a/packages/entity-database-adapter-knex/src/__integration-tests__/errors-test.ts b/packages/entity-database-adapter-knex/src/__integration-tests__/errors-test.ts index f728e77b..686e0c69 100644 --- a/packages/entity-database-adapter-knex/src/__integration-tests__/errors-test.ts +++ b/packages/entity-database-adapter-knex/src/__integration-tests__/errors-test.ts @@ -42,7 +42,6 @@ describe('postgres errors', () => { it('throws EntityDatabaseAdapterTransientError on Knex timeout', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .createAsync(); @@ -61,7 +60,7 @@ describe('postgres errors', () => { const vc2 = new ViewerContext( createKnexIntegrationTestEntityCompanionProvider(shortTimeoutKnexInstance), ); - await expect(ErrorsTestEntity.loader(vc2).enforcing().loadByIDAsync(1)).rejects.toThrow( + await expect(ErrorsTestEntity.loader(vc2).loadByIDAsync(1)).rejects.toThrow( EntityDatabaseAdapterTransientError, ); await shortTimeoutKnexInstance.destroy(); @@ -71,7 +70,6 @@ describe('postgres errors', () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', null as any) .createAsync(), @@ -82,7 +80,6 @@ describe('postgres errors', () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .setField('fieldForeignKey', 2) @@ -94,14 +91,12 @@ describe('postgres errors', () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .createAsync(); await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .createAsync(), @@ -111,7 +106,6 @@ describe('postgres errors', () => { it('throws EntityDatabaseAdapterUniqueConstraintError when unique constraint is violated', async () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 2) .setField('fieldNonNull', 'hello') .setField('fieldUnique', 'hello') @@ -119,7 +113,6 @@ describe('postgres errors', () => { await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .setField('fieldUnique', 'hello') @@ -131,7 +124,6 @@ describe('postgres errors', () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .setField('checkLessThan5', 2) @@ -140,7 +132,6 @@ describe('postgres errors', () => { await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 2) .setField('fieldNonNull', 'hello') .setField('checkLessThan5', 10) @@ -152,7 +143,6 @@ describe('postgres errors', () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .setField('fieldExclusion', 'what') @@ -161,7 +151,6 @@ describe('postgres errors', () => { await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 2) .setField('fieldNonNull', 'hello') .setField('fieldExclusion', 'what') @@ -173,7 +162,6 @@ describe('postgres errors', () => { const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance)); await expect( ErrorsTestEntity.creator(vc) - .enforcing() .setField('id', 1) .setField('fieldNonNull', 'hello') .setField('nonExistentColumn', 'what') diff --git a/packages/entity-example/src/__tests__/NoteEntity-test.ts b/packages/entity-example/src/__tests__/NoteEntity-test.ts index 42364b89..890c75c1 100644 --- a/packages/entity-example/src/__tests__/NoteEntity-test.ts +++ b/packages/entity-example/src/__tests__/NoteEntity-test.ts @@ -10,16 +10,16 @@ describe(NoteEntity, () => { const userId = uuidv4(); const viewerContext = new UserViewerContext(companionProvider, userId); - const createdEntityResult = await NoteEntity.creator(viewerContext) - .withAuthorizationResults() + const createdEntityResult = await NoteEntity.creatorWithAuthorizationResults(viewerContext) .setField('userID', userId) .setField('body', 'image') .setField('title', 'page') .createAsync(); expect(createdEntityResult.ok).toBe(true); - const createdEntityResultImpersonate = await NoteEntity.creator(viewerContext) - .withAuthorizationResults() + const createdEntityResultImpersonate = await NoteEntity.creatorWithAuthorizationResults( + viewerContext, + ) .setField('userID', uuidv4()) // a different user .setField('body', 'image') .setField('title', 'page') diff --git a/packages/entity-example/src/routers/notesRouter.ts b/packages/entity-example/src/routers/notesRouter.ts index 8bfbabb6..781a7029 100644 --- a/packages/entity-example/src/routers/notesRouter.ts +++ b/packages/entity-example/src/routers/notesRouter.ts @@ -19,9 +19,10 @@ router.get('/', async (ctx) => { const viewerContext = ctx.state.viewerContext; let notes: readonly NoteEntity[] = []; if (viewerContext.isUserViewerContext()) { - notes = await NoteEntity.loader(viewerContext) - .enforcing() - .loadManyByFieldEqualingAsync('userID', viewerContext.userID); + notes = await NoteEntity.loader(viewerContext).loadManyByFieldEqualingAsync( + 'userID', + viewerContext.userID, + ); } ctx.body = { notes: notes.map((note) => note.getAllFields()), @@ -30,9 +31,9 @@ router.get('/', async (ctx) => { router.get('/:id', async (ctx) => { const viewerContext = ctx.state.viewerContext; - const noteResult = await NoteEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(ctx.params['id']!); + const noteResult = await NoteEntity.loaderWithAuthorizationResults(viewerContext).loadByIDAsync( + ctx.params['id']!, + ); if (!noteResult.ok) { ctx.throw(403, noteResult.reason); return; @@ -55,8 +56,7 @@ router.post('/', async (ctx) => { const { title, body } = ctx.request.body as any; - const createResult = await NoteEntity.creator(viewerContext) - .withAuthorizationResults() + const createResult = await NoteEntity.creatorWithAuthorizationResults(viewerContext) .setField('userID', viewerContext.userID) .setField('title', title) .setField('body', body) @@ -75,16 +75,15 @@ router.put('/:id', async (ctx) => { const viewerContext = ctx.state.viewerContext; const { title, body } = ctx.request.body as any; - const noteLoadResult = await NoteEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(ctx.params['id']!); + const noteLoadResult = await NoteEntity.loaderWithAuthorizationResults( + viewerContext, + ).loadByIDAsync(ctx.params['id']!); if (!noteLoadResult.ok) { ctx.throw(403, noteLoadResult.reason); return; } - const noteUpdateResult = await NoteEntity.updater(noteLoadResult.value) - .withAuthorizationResults() + const noteUpdateResult = await NoteEntity.updaterWithAuthorizationResults(noteLoadResult.value) .setField('title', title) .setField('body', body) .updateAsync(); @@ -101,17 +100,17 @@ router.put('/:id', async (ctx) => { router.delete('/:id', async (ctx) => { const viewerContext = ctx.state.viewerContext; - const noteLoadResult = await NoteEntity.loader(viewerContext) - .withAuthorizationResults() - .loadByIDAsync(ctx.params['id']!); + const noteLoadResult = await NoteEntity.loaderWithAuthorizationResults( + viewerContext, + ).loadByIDAsync(ctx.params['id']!); if (!noteLoadResult.ok) { ctx.throw(403, noteLoadResult.reason); return; } - const noteDeleteResult = await NoteEntity.deleter(noteLoadResult.value) - .withAuthorizationResults() - .deleteAsync(); + const noteDeleteResult = await NoteEntity.deleterWithAuthorizationResults( + noteLoadResult.value, + ).deleteAsync(); if (!noteDeleteResult.ok) { ctx.throw(403, noteDeleteResult.reason); return; diff --git a/packages/entity-example/src/schema.ts b/packages/entity-example/src/schema.ts index 92466ca5..2b417939 100644 --- a/packages/entity-example/src/schema.ts +++ b/packages/entity-example/src/schema.ts @@ -46,16 +46,14 @@ export const resolvers: IResolvers = { return viewerContext.userID; }, async noteByID(_root, args, { viewerContext }) { - return await NoteEntity.loader(viewerContext).enforcing().loadByIDAsync(args.id); + return await NoteEntity.loader(viewerContext).loadByIDAsync(args.id); }, } as IObjectTypeResolver, User: { id: (root) => root, async notes(root, _args, { viewerContext }) { - return await NoteEntity.loader(viewerContext) - .enforcing() - .loadManyByFieldEqualingAsync('userID', root); + return await NoteEntity.loader(viewerContext).loadManyByFieldEqualingAsync('userID', root); }, } as IObjectTypeResolver, @@ -73,27 +71,21 @@ export const resolvers: IResolvers = { } return await NoteEntity.creator(viewerContext) - .enforcing() .setField('userID', viewerContext.userID) .setField('title', args.note.title) .setField('body', args.note.body) .createAsync(); }, async updateNote(_root, args, { viewerContext }) { - const existingNote = await NoteEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(args.id); + const existingNote = await NoteEntity.loader(viewerContext).loadByIDAsync(args.id); return await NoteEntity.updater(existingNote) - .enforcing() .setField('title', args.note.title) .setField('body', args.note.body) .updateAsync(); }, async deleteNote(_root, args, { viewerContext }) { - const existingNote = await NoteEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(args.id); - await NoteEntity.deleter(existingNote).enforcing().deleteAsync(); + const existingNote = await NoteEntity.loader(viewerContext).loadByIDAsync(args.id); + await NoteEntity.deleter(existingNote).deleteAsync(); return existingNote; }, } as IObjectTypeResolver, diff --git a/packages/entity-full-integration-tests/src/__integration-tests__/EntityCacheInconsistency-test.ts b/packages/entity-full-integration-tests/src/__integration-tests__/EntityCacheInconsistency-test.ts index ca115805..8dfef5b5 100644 --- a/packages/entity-full-integration-tests/src/__integration-tests__/EntityCacheInconsistency-test.ts +++ b/packages/entity-full-integration-tests/src/__integration-tests__/EntityCacheInconsistency-test.ts @@ -141,16 +141,13 @@ describe('Entity cache inconsistency', () => { ); const entity1 = await TestEntity.creator(viewerContext) - .enforcing() .setField('other_string', 'hello') .setField('third_string', 'initial') .createAsync(); // put entities in cache and dataloader - await TestEntity.loader(viewerContext).enforcing().loadByIDAsync(entity1.getID()); - await TestEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('other_string', 'hello'); + await TestEntity.loader(viewerContext).loadByIDAsync(entity1.getID()); + await TestEntity.loader(viewerContext).loadByFieldEqualingAsync('other_string', 'hello'); let openBarrier1: () => void; const barrier1 = new Promise((resolve) => { @@ -173,7 +170,7 @@ describe('Entity cache inconsistency', () => { const viewerContextInternal = new ViewerContext( createFullIntegrationTestEntityCompanionProvider(knexInstance, genericRedisCacheContext), ); - await TestEntity.loader(viewerContextInternal).enforcing().loadByIDAsync(entity1.getID()); + await TestEntity.loader(viewerContextInternal).loadByIDAsync(entity1.getID()); openBarrier2!(); })(), @@ -181,7 +178,6 @@ describe('Entity cache inconsistency', () => { 'postgres', async (queryContext) => { await TestEntity.updater(entity1, queryContext) - .enforcing() .setField('third_string', 'updated') .updateAsync(); @@ -198,12 +194,11 @@ describe('Entity cache inconsistency', () => { createFullIntegrationTestEntityCompanionProvider(knexInstance, genericRedisCacheContext), ); - const loadedById = await TestEntity.loader(viewerContextLast) - .enforcing() - .loadByIDAsync(entity1.getID()); - const loadedByField = await TestEntity.loader(viewerContextLast) - .enforcing() - .loadByFieldEqualingAsync('other_string', 'hello'); + const loadedById = await TestEntity.loader(viewerContextLast).loadByIDAsync(entity1.getID()); + const loadedByField = await TestEntity.loader(viewerContextLast).loadByFieldEqualingAsync( + 'other_string', + 'hello', + ); expect(loadedById.getField('third_string')).toEqual('updated'); expect(loadedByField!.getField('third_string')).toEqual('updated'); diff --git a/packages/entity-full-integration-tests/src/__integration-tests__/EntityEdgesIntegration-test.ts b/packages/entity-full-integration-tests/src/__integration-tests__/EntityEdgesIntegration-test.ts index 63e1e065..56de1434 100644 --- a/packages/entity-full-integration-tests/src/__integration-tests__/EntityEdgesIntegration-test.ts +++ b/packages/entity-full-integration-tests/src/__integration-tests__/EntityEdgesIntegration-test.ts @@ -79,29 +79,26 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { createFullIntegrationTestEntityCompanionProvider(knexInstance, genericRedisCacheContext), ); - const parent = await ParentEntity.creator(viewerContext).enforcing().createAsync(); + const parent = await ParentEntity.creator(viewerContext).createAsync(); const child = await ChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', parent.getID()) .createAsync(); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.not.toBeNull(); await expect( - ChildEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_id', parent.getID()), + ChildEntity.loader(viewerContext).loadByFieldEqualingAsync('parent_id', parent.getID()), ).resolves.not.toBeNull(); - await ParentEntity.deleter(parent).enforcing().deleteAsync(); + await ParentEntity.deleter(parent).deleteAsync(); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.toBeNull(); await expect( - ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()), + ChildEntity.loader(viewerContext).loadByIDNullableAsync(child.getID()), ).resolves.toBeNull(); }); }); diff --git a/packages/entity-full-integration-tests/src/__integration-tests__/EntityIntegrity-test.ts b/packages/entity-full-integration-tests/src/__integration-tests__/EntityIntegrity-test.ts index c90ee837..625a468a 100644 --- a/packages/entity-full-integration-tests/src/__integration-tests__/EntityIntegrity-test.ts +++ b/packages/entity-full-integration-tests/src/__integration-tests__/EntityIntegrity-test.ts @@ -129,10 +129,10 @@ describe('Entity integrity', () => { createFullIntegrationTestEntityCompanionProvider(knexInstance, genericRedisCacheContext), ); - const entity1 = await TestEntity.creator(viewerContext).enforcing().createAsync(); + const entity1 = await TestEntity.creator(viewerContext).createAsync(); await expect( - TestEntity.updater(entity1).enforcing().setField('id', uuidv4()).updateAsync(), + TestEntity.updater(entity1).setField('id', uuidv4()).updateAsync(), ).rejects.toThrow('id field updates not supported: (entityClass = TestEntity)'); // ensure cache consistency @@ -140,9 +140,7 @@ describe('Entity integrity', () => { createFullIntegrationTestEntityCompanionProvider(knexInstance, genericRedisCacheContext), ); - const loadedById = await TestEntity.loader(viewerContextLast) - .enforcing() - .loadByIDAsync(entity1.getID()); + const loadedById = await TestEntity.loader(viewerContextLast).loadByIDAsync(entity1.getID()); expect(loadedById.getID()).toEqual(entity1.getID()); }); diff --git a/packages/entity-full-integration-tests/src/__integration-tests__/EntitySelfReferentialEdgesIntegration-test.ts b/packages/entity-full-integration-tests/src/__integration-tests__/EntitySelfReferentialEdgesIntegration-test.ts index 7457cdc6..a97322d8 100644 --- a/packages/entity-full-integration-tests/src/__integration-tests__/EntitySelfReferentialEdgesIntegration-test.ts +++ b/packages/entity-full-integration-tests/src/__integration-tests__/EntitySelfReferentialEdgesIntegration-test.ts @@ -221,40 +221,38 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { createFullIntegrationTestEntityCompanionProvider(knexInstance, genericRedisCacheContext), ); - const category1 = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const category1 = await CategoryEntity.creator(viewerContext).createAsync(); const other1 = await OtherEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', category1.getID()) .createAsync(); await CategoryEntity.updater(category1) - .enforcing() .setField('parent_other_id', other1.getID()) .updateAsync(); - await CategoryEntity.deleter(category1).enforcing().deleteAsync(); + await CategoryEntity.deleter(category1).deleteAsync(); if (edgeDeletionBehavior === EntityEdgeDeletionBehavior.SET_NULL) { await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(category1.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(category1.getID()), ).resolves.toBeNull(); - const otherLoaded = await OtherEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(other1.getID()); + const otherLoaded = await OtherEntity.loader(viewerContext).loadByIDNullableAsync( + other1.getID(), + ); expect(otherLoaded?.getField('parent_category_id')).toBeNull(); } else if (edgeDeletionBehavior === EntityEdgeDeletionBehavior.SET_NULL_INVALIDATE_CACHE_ONLY) { await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(category1.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(category1.getID()), ).resolves.toBeNull(); - const otherLoaded = await OtherEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(other1.getID()); + const otherLoaded = await OtherEntity.loader(viewerContext).loadByIDNullableAsync( + other1.getID(), + ); expect(otherLoaded?.getField('parent_category_id')).toBeNull(); } else { await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(category1.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(category1.getID()), ).resolves.toBeNull(); await expect( - OtherEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(other1.getID()), + OtherEntity.loader(viewerContext).loadByIDNullableAsync(other1.getID()), ).resolves.toBeNull(); } }); diff --git a/packages/entity-secondary-cache-local-memory/src/__tests__/LocalMemorySecondaryEntityCache-test.ts b/packages/entity-secondary-cache-local-memory/src/__tests__/LocalMemorySecondaryEntityCache-test.ts index 6a47f81a..75aaf29f 100644 --- a/packages/entity-secondary-cache-local-memory/src/__tests__/LocalMemorySecondaryEntityCache-test.ts +++ b/packages/entity-secondary-cache-local-memory/src/__tests__/LocalMemorySecondaryEntityCache-test.ts @@ -175,7 +175,6 @@ describe(LocalMemorySecondaryEntityCache, () => { const viewerContext = new TestViewerContext(createTestEntityCompanionProvider()); const createdEntity = await LocalMemoryTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'wat') .createAsync(); @@ -184,7 +183,7 @@ describe(LocalMemorySecondaryEntityCache, () => { localMemoryTestEntityConfiguration, GenericLocalMemoryCacher.createLRUCache({}), ), - LocalMemoryTestEntity.loader(viewerContext).withAuthorizationResults(), + LocalMemoryTestEntity.loaderWithAuthorizationResults(viewerContext), ); const loadParams = { id: createdEntity.getID() }; @@ -220,7 +219,7 @@ describe(LocalMemorySecondaryEntityCache, () => { localMemoryTestEntityConfiguration, GenericLocalMemoryCacher.createLRUCache({}), ), - LocalMemoryTestEntity.loader(viewerContext).withAuthorizationResults(), + LocalMemoryTestEntity.loaderWithAuthorizationResults(viewerContext), ); const loadParams = { id: FAKE_ID }; diff --git a/packages/entity-secondary-cache-redis/src/__integration-tests__/RedisSecondaryEntityCache-integration-test.ts b/packages/entity-secondary-cache-redis/src/__integration-tests__/RedisSecondaryEntityCache-integration-test.ts index cd0725e7..a76b36d5 100644 --- a/packages/entity-secondary-cache-redis/src/__integration-tests__/RedisSecondaryEntityCache-integration-test.ts +++ b/packages/entity-secondary-cache-redis/src/__integration-tests__/RedisSecondaryEntityCache-integration-test.ts @@ -80,7 +80,6 @@ describe(RedisSecondaryEntityCache, () => { ); const createdEntity = await RedisTestEntity.creator(viewerContext) - .enforcing() .setField('name', 'wat') .createAsync(); @@ -90,7 +89,7 @@ describe(RedisSecondaryEntityCache, () => { genericRedisCacheContext, (loadParams) => `test-key-${loadParams.id}`, ), - RedisTestEntity.loader(viewerContext).withAuthorizationResults(), + RedisTestEntity.loaderWithAuthorizationResults(viewerContext), ); const loadParams = { id: createdEntity.getID() }; @@ -129,7 +128,7 @@ describe(RedisSecondaryEntityCache, () => { genericRedisCacheContext, (loadParams) => `test-key-${loadParams.id}`, ), - RedisTestEntity.loader(viewerContext).withAuthorizationResults(), + RedisTestEntity.loaderWithAuthorizationResults(viewerContext), ); const loadParams = { id: FAKE_ID }; diff --git a/packages/entity/src/AuthorizationResultBasedEntityAssociationLoader.ts b/packages/entity/src/AuthorizationResultBasedEntityAssociationLoader.ts index 1cc864ca..85ac291e 100644 --- a/packages/entity/src/AuthorizationResultBasedEntityAssociationLoader.ts +++ b/packages/entity/src/AuthorizationResultBasedEntityAssociationLoader.ts @@ -410,8 +410,7 @@ export default class AuthorizationResultBasedEntityAssociationLoader< let associatedEntityResult: Result> | null; if (associatedEntityLookupByField) { associatedEntityResult = await currentEntity - .associationLoader(this.queryContext) - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults(this.queryContext) .loadAssociatedEntityByFieldEqualingAsync( fieldIdentifyingAssociatedEntity, associatedEntityClass, @@ -419,8 +418,7 @@ export default class AuthorizationResultBasedEntityAssociationLoader< ); } else { const associatedEntityResultLocal = await currentEntity - .associationLoader(this.queryContext) - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults(this.queryContext) .loadAssociatedEntityAsync(fieldIdentifyingAssociatedEntity, associatedEntityClass); if (associatedEntityResultLocal.ok && associatedEntityResultLocal.value === null) { diff --git a/packages/entity/src/Entity.ts b/packages/entity/src/Entity.ts index 4e2a4e40..e3f78751 100644 --- a/packages/entity/src/Entity.ts +++ b/packages/entity/src/Entity.ts @@ -1,3 +1,11 @@ +import { + AuthorizationResultBasedCreateMutator, + AuthorizationResultBasedDeleteMutator, + AuthorizationResultBasedUpdateMutator, +} from './AuthorizationResultBasedEntityMutator'; +import EnforcingEntityCreator from './EnforcingEntityCreator'; +import EnforcingEntityDeleter from './EnforcingEntityDeleter'; +import EnforcingEntityUpdater from './EnforcingEntityUpdater'; import { EntityCompanionDefinition } from './EntityCompanionProvider'; import EntityCreator from './EntityCreator'; import EntityDeleter from './EntityDeleter'; @@ -65,16 +73,60 @@ export default abstract class Entity< .getViewerScopedEntityCompanionForClass(this) .getQueryContextProvider() .getQueryContext(), - ): EntityCreator< + ): EnforcingEntityCreator< TMFields, TMID, TMViewerContext, - TMViewerContext2, TMEntity, TMPrivacyPolicy, TMSelectedFields > { - return new EntityCreator(viewerContext, queryContext, this); + return new EntityCreator(viewerContext, queryContext, this).enforcing(); + } + + /** + * Vend mutator for creating a new entity in given query context. + * @param viewerContext - viewer context of creating user + * @param queryContext - query context in which to perform the create + * @returns mutator for creating an entity + */ + static creatorWithAuthorizationResults< + TMFields extends object, + TMID extends NonNullable, + TMViewerContext extends ViewerContext, + TMViewerContext2 extends TMViewerContext, + TMEntity extends Entity, + TMPrivacyPolicy extends EntityPrivacyPolicy< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMSelectedFields + >, + TMSelectedFields extends keyof TMFields = keyof TMFields, + >( + this: IEntityClass< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + >, + viewerContext: TMViewerContext2, + queryContext: EntityQueryContext = viewerContext + .getViewerScopedEntityCompanionForClass(this) + .getQueryContextProvider() + .getQueryContext(), + ): AuthorizationResultBasedCreateMutator< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityCreator(viewerContext, queryContext, this).withAuthorizationResults(); } /** @@ -111,8 +163,60 @@ export default abstract class Entity< .getViewerScopedEntityCompanionForClass(this) .getQueryContextProvider() .getQueryContext(), - ): EntityUpdater { - return new EntityUpdater(existingEntity, queryContext, this); + ): EnforcingEntityUpdater< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityUpdater(existingEntity, queryContext, this).enforcing(); + } + + /** + * Vend mutator for updating an existing entity in given query context. + * @param existingEntity - entity to update + * @param queryContext - query context in which to perform the update + * @returns mutator for updating existingEntity + */ + static updaterWithAuthorizationResults< + TMFields extends object, + TMID extends NonNullable, + TMViewerContext extends ViewerContext, + TMEntity extends Entity, + TMPrivacyPolicy extends EntityPrivacyPolicy< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMSelectedFields + >, + TMSelectedFields extends keyof TMFields = keyof TMFields, + >( + this: IEntityClass< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + >, + existingEntity: TMEntity, + queryContext: EntityQueryContext = existingEntity + .getViewerContext() + .getViewerScopedEntityCompanionForClass(this) + .getQueryContextProvider() + .getQueryContext(), + ): AuthorizationResultBasedUpdateMutator< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityUpdater(existingEntity, queryContext, this).withAuthorizationResults(); } /** @@ -149,8 +253,60 @@ export default abstract class Entity< .getViewerScopedEntityCompanionForClass(this) .getQueryContextProvider() .getQueryContext(), - ): EntityDeleter { - return new EntityDeleter(existingEntity, queryContext, this); + ): EnforcingEntityDeleter< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityDeleter(existingEntity, queryContext, this).enforcing(); + } + + /** + * Vend mutator for deleting an existing entity in given query context. + * @param existingEntity - entity to delete + * @param queryContext - query context in which to perform the delete + * @returns mutator for deleting existingEntity + */ + static deleterWithAuthorizationResults< + TMFields extends object, + TMID extends NonNullable, + TMViewerContext extends ViewerContext, + TMEntity extends Entity, + TMPrivacyPolicy extends EntityPrivacyPolicy< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMSelectedFields + >, + TMSelectedFields extends keyof TMFields = keyof TMFields, + >( + this: IEntityClass< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + >, + existingEntity: TMEntity, + queryContext: EntityQueryContext = existingEntity + .getViewerContext() + .getViewerScopedEntityCompanionForClass(this) + .getQueryContextProvider() + .getQueryContext(), + ): AuthorizationResultBasedDeleteMutator< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityDeleter(existingEntity, queryContext, this).withAuthorizationResults(); } } diff --git a/packages/entity/src/ReadonlyEntity.ts b/packages/entity/src/ReadonlyEntity.ts index 3aee3dcc..b0af084f 100644 --- a/packages/entity/src/ReadonlyEntity.ts +++ b/packages/entity/src/ReadonlyEntity.ts @@ -1,8 +1,13 @@ import invariant from 'invariant'; +import AuthorizationResultBasedEntityAssociationLoader from './AuthorizationResultBasedEntityAssociationLoader'; +import AuthorizationResultBasedEntityLoader from './AuthorizationResultBasedEntityLoader'; +import EnforcingEntityAssociationLoader from './EnforcingEntityAssociationLoader'; +import EnforcingEntityLoader from './EnforcingEntityLoader'; import { IEntityClass } from './Entity'; import EntityAssociationLoader from './EntityAssociationLoader'; import EntityLoader from './EntityLoader'; +import EntityLoaderUtils from './EntityLoaderUtils'; import EntityPrivacyPolicy from './EntityPrivacyPolicy'; import { EntityQueryContext } from './EntityQueryContext'; import ViewerContext from './ViewerContext'; @@ -82,12 +87,33 @@ export default abstract class ReadonlyEntity< } /** - * @returns EntityAssociationLoader for this entity + * @returns EnforcingEntityAssociationLoader for this entity */ associationLoader( queryContext?: EntityQueryContext, - ): EntityAssociationLoader { - return new EntityAssociationLoader(this, queryContext); + ): EnforcingEntityAssociationLoader { + return new EntityAssociationLoader( + this, + queryContext, + ).enforcing(); + } + + /** + * @returns AuthorizationResultBasedEntityAssociationLoader for this entity + */ + associationLoaderWithAuthorizationResults( + queryContext?: EntityQueryContext, + ): AuthorizationResultBasedEntityAssociationLoader< + TFields, + TID, + TViewerContext, + this, + TSelectedFields + > { + return new EntityAssociationLoader( + this, + queryContext, + ).withAuthorizationResults(); } /** @@ -148,15 +174,102 @@ export default abstract class ReadonlyEntity< .getViewerScopedEntityCompanionForClass(this) .getQueryContextProvider() .getQueryContext(), - ): EntityLoader< + ): EnforcingEntityLoader< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityLoader(viewerContext, queryContext, this).enforcing(); + } + + /** + * Vend loader for loading an entity in a given query context. + * @param viewerContext - viewer context of loading user + * @param queryContext - query context in which to perform the load + */ + static loaderWithAuthorizationResults< + TMFields extends object, + TMID extends NonNullable, + TMViewerContext extends ViewerContext, + TMViewerContext2 extends TMViewerContext, + TMEntity extends ReadonlyEntity, + TMPrivacyPolicy extends EntityPrivacyPolicy< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMSelectedFields + >, + TMSelectedFields extends keyof TMFields = keyof TMFields, + >( + this: IEntityClass< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + >, + viewerContext: TMViewerContext2, + queryContext: EntityQueryContext = viewerContext + .getViewerScopedEntityCompanionForClass(this) + .getQueryContextProvider() + .getQueryContext(), + ): AuthorizationResultBasedEntityLoader< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + > { + return new EntityLoader(viewerContext, queryContext, this).withAuthorizationResults(); + } + + /** + * Vend loader for loading an entity in a given query context. + * @param viewerContext - viewer context of loading user + * @param queryContext - query context in which to perform the load + */ + static loaderUtils< + TMFields extends object, + TMID extends NonNullable, + TMViewerContext extends ViewerContext, + TMViewerContext2 extends TMViewerContext, + TMEntity extends ReadonlyEntity, + TMPrivacyPolicy extends EntityPrivacyPolicy< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMSelectedFields + >, + TMSelectedFields extends keyof TMFields = keyof TMFields, + >( + this: IEntityClass< + TMFields, + TMID, + TMViewerContext, + TMEntity, + TMPrivacyPolicy, + TMSelectedFields + >, + viewerContext: TMViewerContext2, + queryContext: EntityQueryContext = viewerContext + .getViewerScopedEntityCompanionForClass(this) + .getQueryContextProvider() + .getQueryContext(), + ): EntityLoaderUtils< TMFields, TMID, TMViewerContext, - TMViewerContext2, TMEntity, TMPrivacyPolicy, TMSelectedFields > { - return new EntityLoader(viewerContext, queryContext, this); + return new EntityLoader(viewerContext, queryContext, this).utils(); } } diff --git a/packages/entity/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts b/packages/entity/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts index 8860d9d3..0538f715 100644 --- a/packages/entity/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts +++ b/packages/entity/src/__tests__/AuthorizationResultBasedEntityAssociationLoader-test.ts @@ -14,26 +14,23 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testOtherEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(), + TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(), ); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', testOtherEntity.getID()) .createAsync(), ); const loadedOther = await enforceAsyncResult( testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityAsync('stringField', TestEntity), ); expect(loadedOther.getID()).toEqual(testOtherEntity.getID()); const loadedOther2 = await enforceAsyncResult( testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityAsync('nullableField', TestEntity), ); expect(loadedOther2).toBeNull(); @@ -45,24 +42,21 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(), + TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(), ); const testOtherEntity1 = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', testEntity.getID()) .createAsync(), ); const testOtherEntity2 = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', testEntity.getID()) .createAsync(), ); const loaded = await enforceResultsAsync( testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadManyAssociatedEntitiesAsync(TestEntity, 'stringField'), ); expect(loaded).toHaveLength(2); @@ -76,17 +70,15 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testOtherEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(), + TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(), ); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', testOtherEntity.getID()) .createAsync(), ); const loadedOtherResult = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityByFieldEqualingAsync('stringField', TestEntity, 'customIdField'); expect(loadedOtherResult?.enforceValue().getID()).toEqual(testOtherEntity.getID()); }); @@ -95,14 +87,12 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', uuidv4()) .createAsync(), ); const loadedOtherResult = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityByFieldEqualingAsync('stringField', TestEntity, 'customIdField'); expect(loadedOtherResult).toBeNull(); }); @@ -111,14 +101,12 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', 'blah') .createAsync(), ); const loadedOtherResult = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityByFieldEqualingAsync('nullableField', TestEntity, 'customIdField'); expect(loadedOtherResult).toBeNull(); }); @@ -129,24 +117,21 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(), + TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(), ); const testOtherEntity1 = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', testEntity.getID()) .createAsync(), ); const testOtherEntity2 = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', testEntity.getID()) .createAsync(), ); const loaded = await enforceResultsAsync( testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadManyAssociatedEntitiesByFieldEqualingAsync( 'customIdField', TestEntity, @@ -162,12 +147,11 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(), + TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(), ); const loaded = await enforceResultsAsync( testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadManyAssociatedEntitiesByFieldEqualingAsync( 'nullableField', TestEntity, @@ -183,30 +167,26 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); const testEntity4 = await enforceAsyncResult( - TestEntity.creator(viewerContext).withAuthorizationResults().createAsync(), + TestEntity.creatorWithAuthorizationResults(viewerContext).createAsync(), ); const testEntity3 = await enforceAsyncResult( - TestEntity2.creator(viewerContext) - .withAuthorizationResults() + TestEntity2.creatorWithAuthorizationResults(viewerContext) .setField('foreignKey', testEntity4.getID()) .createAsync(), ); const testEntity2 = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('testIndexedField', testEntity3.getID()) .createAsync(), ); const testEntity = await enforceAsyncResult( - TestEntity2.creator(viewerContext) - .withAuthorizationResults() + TestEntity2.creatorWithAuthorizationResults(viewerContext) .setField('foreignKey', testEntity2.getID()) .createAsync(), ); const loaded2Result = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, @@ -216,8 +196,7 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { expect(loaded2Result?.enforceValue().getID()).toEqual(testEntity2.getID()); const loaded3Result = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, @@ -231,8 +210,7 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { expect(loaded3Result?.enforceValue().getID()).toEqual(testEntity3.getID()); const loaded4Result = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, @@ -255,15 +233,13 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity2.creator(viewerContext) - .withAuthorizationResults() + TestEntity2.creatorWithAuthorizationResults(viewerContext) .setField('foreignKey', uuidv4()) .createAsync(), ); const loadResult = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, @@ -279,21 +255,18 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const fieldValue = uuidv4(); const testEntity2 = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('stringField', fieldValue) .createAsync(), ); const testEntity = await enforceAsyncResult( - TestEntity2.creator(viewerContext) - .withAuthorizationResults() + TestEntity2.creatorWithAuthorizationResults(viewerContext) .setField('foreignKey', fieldValue) .createAsync(), ); const loaded2Result = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, @@ -309,15 +282,13 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity2.creator(viewerContext) - .withAuthorizationResults() + TestEntity2.creatorWithAuthorizationResults(viewerContext) .setField('foreignKey', uuidv4()) .createAsync(), ); const loaded2Result = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, @@ -333,15 +304,13 @@ describe(AuthorizationResultBasedEntityAssociationLoader, () => { const viewerContext = new TestViewerContext(companionProvider); const testEntity = await enforceAsyncResult( - TestEntity.creator(viewerContext) - .withAuthorizationResults() + TestEntity.creatorWithAuthorizationResults(viewerContext) .setField('nullableField', null) .createAsync(), ); const loadedResult = await testEntity - .associationLoader() - .withAuthorizationResults() + .associationLoaderWithAuthorizationResults() .loadAssociatedEntityThroughAsync([ { associatedEntityClass: TestEntity, diff --git a/packages/entity/src/__tests__/Entity-test.ts b/packages/entity/src/__tests__/Entity-test.ts index c34bb189..819cd3f7 100644 --- a/packages/entity/src/__tests__/Entity-test.ts +++ b/packages/entity/src/__tests__/Entity-test.ts @@ -1,22 +1,37 @@ +import { + AuthorizationResultBasedCreateMutator, + AuthorizationResultBasedDeleteMutator, + AuthorizationResultBasedUpdateMutator, +} from '../AuthorizationResultBasedEntityMutator'; +import EnforcingEntityCreator from '../EnforcingEntityCreator'; +import EnforcingEntityDeleter from '../EnforcingEntityDeleter'; +import EnforcingEntityUpdater from '../EnforcingEntityUpdater'; import Entity from '../Entity'; -import EntityCreator from '../EntityCreator'; -import EntityDeleter from '../EntityDeleter'; -import EntityUpdater from '../EntityUpdater'; import ViewerContext from '../ViewerContext'; import SimpleTestEntity from '../testfixtures/SimpleTestEntity'; import { createUnitTestEntityCompanionProvider } from '../utils/testing/createUnitTestEntityCompanionProvider'; describe(Entity, () => { describe('creator', () => { - it('creates a new EntityCreator', () => { + it('creates a new EnforcingEntityCreator', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - expect(SimpleTestEntity.creator(viewerContext)).toBeInstanceOf(EntityCreator); + expect(SimpleTestEntity.creator(viewerContext)).toBeInstanceOf(EnforcingEntityCreator); + }); + }); + + describe('creatorWithAuthorizationResults', () => { + it('creates a new AuthorizationResultBasedCreateMutator', () => { + const companionProvider = createUnitTestEntityCompanionProvider(); + const viewerContext = new ViewerContext(companionProvider); + expect(SimpleTestEntity.creatorWithAuthorizationResults(viewerContext)).toBeInstanceOf( + AuthorizationResultBasedCreateMutator, + ); }); }); describe('updater', () => { - it('creates a new EntityUpdater', () => { + it('creates a new EnforcingEntityUpdater', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); const data = { @@ -28,12 +43,48 @@ describe(Entity, () => { databaseFields: data, selectedFields: data, }); - expect(SimpleTestEntity.updater(testEntity)).toBeInstanceOf(EntityUpdater); + expect(SimpleTestEntity.updater(testEntity)).toBeInstanceOf(EnforcingEntityUpdater); + }); + }); + + describe('updaterWithAuthorizationResults', () => { + it('creates a new AuthorizationResultBasedUpdateMutator', () => { + const companionProvider = createUnitTestEntityCompanionProvider(); + const viewerContext = new ViewerContext(companionProvider); + const data = { + id: 'what', + }; + const testEntity = new SimpleTestEntity({ + viewerContext, + id: 'what', + databaseFields: data, + selectedFields: data, + }); + expect(SimpleTestEntity.updaterWithAuthorizationResults(testEntity)).toBeInstanceOf( + AuthorizationResultBasedUpdateMutator, + ); }); }); describe('deleter', () => { - it('creates a new EntityDeleter', () => { + it('creates a new EnforcingEntityDeleter', () => { + const companionProvider = createUnitTestEntityCompanionProvider(); + const viewerContext = new ViewerContext(companionProvider); + const data = { + id: 'what', + }; + const testEntity = new SimpleTestEntity({ + viewerContext, + id: 'what', + databaseFields: data, + selectedFields: data, + }); + expect(SimpleTestEntity.deleter(testEntity)).toBeInstanceOf(EnforcingEntityDeleter); + }); + }); + + describe('deleterWithAuthorizationResults', () => { + it('creates a new AuthorizationResultBasedDeleteMutator', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); const data = { @@ -45,7 +96,9 @@ describe(Entity, () => { databaseFields: data, selectedFields: data, }); - expect(SimpleTestEntity.deleter(testEntity)).toBeInstanceOf(EntityDeleter); + expect(SimpleTestEntity.deleterWithAuthorizationResults(testEntity)).toBeInstanceOf( + AuthorizationResultBasedDeleteMutator, + ); }); }); }); diff --git a/packages/entity/src/__tests__/EntityAssociationLoader-test.ts b/packages/entity/src/__tests__/EntityAssociationLoader-test.ts index e485a5eb..8d633f5d 100644 --- a/packages/entity/src/__tests__/EntityAssociationLoader-test.ts +++ b/packages/entity/src/__tests__/EntityAssociationLoader-test.ts @@ -10,10 +10,8 @@ describe(EntityAssociationLoader, () => { it('creates a new EnforcingEntityLoader', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestEntity.creator(viewerContext).enforcing().createAsync(); - expect(testEntity.associationLoader().enforcing()).toBeInstanceOf( - EnforcingEntityAssociationLoader, - ); + const testEntity = await SimpleTestEntity.creator(viewerContext).createAsync(); + expect(testEntity.associationLoader()).toBeInstanceOf(EnforcingEntityAssociationLoader); }); }); @@ -21,8 +19,8 @@ describe(EntityAssociationLoader, () => { it('creates a new AuthorizationResultBasedEntityAssociationLoader', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestEntity.creator(viewerContext).enforcing().createAsync(); - expect(testEntity.associationLoader().withAuthorizationResults()).toBeInstanceOf( + const testEntity = await SimpleTestEntity.creator(viewerContext).createAsync(); + expect(testEntity.associationLoaderWithAuthorizationResults()).toBeInstanceOf( AuthorizationResultBasedEntityAssociationLoader, ); }); diff --git a/packages/entity/src/__tests__/EntityCommonUseCases-test.ts b/packages/entity/src/__tests__/EntityCommonUseCases-test.ts index 49fb3a1c..22d07a01 100644 --- a/packages/entity/src/__tests__/EntityCommonUseCases-test.ts +++ b/packages/entity/src/__tests__/EntityCommonUseCases-test.ts @@ -118,22 +118,19 @@ it('runs through a common workflow', async () => { const vc2 = new TestUserViewerContext(entityCompanionProvider, uuidv4()); const blahOwner1 = await enforceAsyncResult( - BlahEntity.creator(vc1) - .withAuthorizationResults() + BlahEntity.creatorWithAuthorizationResults(vc1) .setField('ownerID', vc1.getUserID()) .createAsync(), ); await enforceAsyncResult( - BlahEntity.creator(vc1) - .withAuthorizationResults() + BlahEntity.creatorWithAuthorizationResults(vc1) .setField('ownerID', vc1.getUserID()) .createAsync(), ); const blahOwner2 = await enforceAsyncResult( - BlahEntity.creator(vc2) - .withAuthorizationResults() + BlahEntity.creatorWithAuthorizationResults(vc2) .setField('ownerID', vc2.getUserID()) .createAsync(), ); @@ -145,43 +142,43 @@ it('runs through a common workflow', async () => { // check that two people can't read each others data await expect( enforceAsyncResult( - BlahEntity.loader(vc1).withAuthorizationResults().loadByIDAsync(blahOwner2.getID()), + BlahEntity.loaderWithAuthorizationResults(vc1).loadByIDAsync(blahOwner2.getID()), ), ).rejects.toBeInstanceOf(EntityNotAuthorizedError); await expect( enforceAsyncResult( - BlahEntity.loader(vc2).withAuthorizationResults().loadByIDAsync(blahOwner1.getID()), + BlahEntity.loaderWithAuthorizationResults(vc2).loadByIDAsync(blahOwner1.getID()), ), ).rejects.toBeInstanceOf(EntityNotAuthorizedError); // check that all of owner 1's objects can be loaded const results = await enforceResultsAsync( - BlahEntity.loader(vc1) - .withAuthorizationResults() - .loadManyByFieldEqualingAsync('ownerID', vc1.getUserID()), + BlahEntity.loaderWithAuthorizationResults(vc1).loadManyByFieldEqualingAsync( + 'ownerID', + vc1.getUserID(), + ), ); expect(results).toHaveLength(2); // check that two people can't create objects owned by others await expect( enforceAsyncResult( - BlahEntity.creator(vc2) - .withAuthorizationResults() + BlahEntity.creatorWithAuthorizationResults(vc2) .setField('ownerID', blahOwner1.getID()) .createAsync(), ), ).rejects.toBeInstanceOf(EntityNotAuthorizedError); // check that empty load many returns nothing - const results2 = await BlahEntity.loader(vc1) - .withAuthorizationResults() - .loadManyByFieldEqualingManyAsync('ownerID', []); + const results2 = await BlahEntity.loaderWithAuthorizationResults( + vc1, + ).loadManyByFieldEqualingManyAsync('ownerID', []); for (const value in results2.values) { expect(value).toHaveLength(0); } // check that the user can't delete their own data (as specified by privacy rules) await expect( - enforceAsyncResult(BlahEntity.deleter(blahOwner2).withAuthorizationResults().deleteAsync()), + enforceAsyncResult(BlahEntity.deleterWithAuthorizationResults(blahOwner2).deleteAsync()), ).rejects.toBeInstanceOf(EntityNotAuthorizedError); }); diff --git a/packages/entity/src/__tests__/EntityEdges-test.ts b/packages/entity/src/__tests__/EntityEdges-test.ts index 3483ca21..e82fbd4f 100644 --- a/packages/entity/src/__tests__/EntityEdges-test.ts +++ b/packages/entity/src/__tests__/EntityEdges-test.ts @@ -527,42 +527,36 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parent = await ParentEntity.creator(viewerContext).enforcing().createAsync(); + const parent = await ParentEntity.creator(viewerContext).createAsync(); const child = await ChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', parent.getID()) .createAsync(); const grandchild = await GrandChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', child.getID()) .createAsync(); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.not.toBeNull(); await expect( - ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()), + ChildEntity.loader(viewerContext).loadByIDNullableAsync(child.getID()), ).resolves.not.toBeNull(); await expect( - GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(grandchild.getID()), + GrandChildEntity.loader(viewerContext).loadByIDNullableAsync(grandchild.getID()), ).resolves.not.toBeNull(); privacyPolicyEvaluationRecords.shouldRecord = true; - await ParentEntity.deleter(parent).enforcing().deleteAsync(); + await ParentEntity.deleter(parent).deleteAsync(); privacyPolicyEvaluationRecords.shouldRecord = false; await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.toBeNull(); await expect( - ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()), + ChildEntity.loader(viewerContext).loadByIDNullableAsync(child.getID()), ).resolves.toBeNull(); await expect( - GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(grandchild.getID()), + GrandChildEntity.loader(viewerContext).loadByIDNullableAsync(grandchild.getID()), ).resolves.toBeNull(); // two calls for each trigger, one beforeDelete, one afterDelete @@ -651,44 +645,38 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parent = await ParentEntity.creator(viewerContext).enforcing().createAsync(); + const parent = await ParentEntity.creator(viewerContext).createAsync(); const child = await ChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', parent.getID()) .createAsync(); const grandchild = await GrandChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', child.getID()) .createAsync(); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.not.toBeNull(); await expect( - ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()), + ChildEntity.loader(viewerContext).loadByIDNullableAsync(child.getID()), ).resolves.not.toBeNull(); await expect( - GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(grandchild.getID()), + GrandChildEntity.loader(viewerContext).loadByIDNullableAsync(grandchild.getID()), ).resolves.not.toBeNull(); privacyPolicyEvaluationRecords.shouldRecord = true; - await ParentEntity.deleter(parent).enforcing().deleteAsync(); + await ParentEntity.deleter(parent).deleteAsync(); privacyPolicyEvaluationRecords.shouldRecord = false; await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.toBeNull(); - const loadedChild = await ChildEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(child.getID()); + const loadedChild = await ChildEntity.loader(viewerContext).loadByIDAsync(child.getID()); expect(loadedChild.getField('parent_id')).toBeNull(); - const loadedGrandchild = await GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(grandchild.getID()); + const loadedGrandchild = await GrandChildEntity.loader(viewerContext).loadByIDAsync( + grandchild.getID(), + ); expect(loadedGrandchild.getField('parent_id')).toEqual(loadedChild.getID()); // two calls for only parent trigger, one beforeDelete, one afterDelete @@ -766,28 +754,22 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parent = await ParentEntity.creator(viewerContext).enforcing().createAsync(); + const parent = await ParentEntity.creator(viewerContext).createAsync(); const child = await ChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', parent.getID()) .createAsync(); const grandchild = await GrandChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', child.getID()) .createAsync(); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.not.toBeNull(); await expect( - ChildEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_id', parent.getID()), + ChildEntity.loader(viewerContext).loadByFieldEqualingAsync('parent_id', parent.getID()), ).resolves.not.toBeNull(); await expect( - GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_id', child.getID()), + GrandChildEntity.loader(viewerContext).loadByFieldEqualingAsync('parent_id', child.getID()), ).resolves.not.toBeNull(); const childCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass(ChildEntity)[ @@ -809,7 +791,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { expect(grandChildCachedBefore.get(child.getID())?.status).toEqual(CacheStatus.HIT); privacyPolicyEvaluationRecords.shouldRecord = true; - await ParentEntity.deleter(parent).enforcing().deleteAsync(); + await ParentEntity.deleter(parent).deleteAsync(); privacyPolicyEvaluationRecords.shouldRecord = false; const childCachedAfter = await childCacheAdapter.loadManyAsync('parent_id', [parent.getID()]); @@ -821,17 +803,15 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { expect(grandChildCachedAfter.get(child.getID())?.status).toEqual(CacheStatus.HIT); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.toBeNull(); - const loadedChild = await ChildEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(child.getID()); + const loadedChild = await ChildEntity.loader(viewerContext).loadByIDAsync(child.getID()); expect(loadedChild).not.toBeNull(); - const loadedGrandchild = await GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(grandchild.getID()); + const loadedGrandchild = await GrandChildEntity.loader(viewerContext).loadByIDAsync( + grandchild.getID(), + ); expect(loadedGrandchild.getField('parent_id')).toEqual(loadedChild.getID()); // two calls for only parent trigger, one beforeDelete, one afterDelete @@ -907,28 +887,22 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parent = await ParentEntity.creator(viewerContext).enforcing().createAsync(); + const parent = await ParentEntity.creator(viewerContext).createAsync(); const child = await ChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', parent.getID()) .createAsync(); const grandchild = await GrandChildEntity.creator(viewerContext) - .enforcing() .setField('parent_id', child.getID()) .createAsync(); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.not.toBeNull(); await expect( - ChildEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_id', parent.getID()), + ChildEntity.loader(viewerContext).loadByFieldEqualingAsync('parent_id', parent.getID()), ).resolves.not.toBeNull(); await expect( - GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_id', child.getID()), + GrandChildEntity.loader(viewerContext).loadByFieldEqualingAsync('parent_id', child.getID()), ).resolves.not.toBeNull(); const childCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass(ChildEntity)[ @@ -950,7 +924,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { expect(grandChildCachedBefore.get(child.getID())?.status).toEqual(CacheStatus.HIT); privacyPolicyEvaluationRecords.shouldRecord = true; - await ParentEntity.deleter(parent).enforcing().deleteAsync(); + await ParentEntity.deleter(parent).deleteAsync(); privacyPolicyEvaluationRecords.shouldRecord = false; const childCachedAfter = await childCacheAdapter.loadManyAsync('parent_id', [parent.getID()]); @@ -962,15 +936,13 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => { expect(grandChildCachedAfter.get(child.getID())?.status).toEqual(CacheStatus.MISS); await expect( - ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()), + ParentEntity.loader(viewerContext).loadByIDNullableAsync(parent.getID()), ).resolves.toBeNull(); await expect( - ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()), + ChildEntity.loader(viewerContext).loadByIDNullableAsync(child.getID()), ).resolves.not.toBeNull(); await expect( - GrandChildEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(grandchild.getID()), + GrandChildEntity.loader(viewerContext).loadByIDNullableAsync(grandchild.getID()), ).resolves.not.toBeNull(); // two calls for each trigger, one beforeDelete, one afterDelete diff --git a/packages/entity/src/__tests__/EntityLoader-test.ts b/packages/entity/src/__tests__/EntityLoader-test.ts index 84c75783..ce6e8ab5 100644 --- a/packages/entity/src/__tests__/EntityLoader-test.ts +++ b/packages/entity/src/__tests__/EntityLoader-test.ts @@ -11,9 +11,7 @@ describe(EntityLoader, () => { it('creates a new EnforcingEntityLoader', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - expect(SimpleTestEntity.loader(viewerContext).enforcing()).toBeInstanceOf( - EnforcingEntityLoader, - ); + expect(SimpleTestEntity.loader(viewerContext)).toBeInstanceOf(EnforcingEntityLoader); }); }); @@ -21,7 +19,7 @@ describe(EntityLoader, () => { it('creates a new AuthorizationResultBasedEntityLoader', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - expect(SimpleTestEntity.loader(viewerContext).withAuthorizationResults()).toBeInstanceOf( + expect(SimpleTestEntity.loaderWithAuthorizationResults(viewerContext)).toBeInstanceOf( AuthorizationResultBasedEntityLoader, ); }); @@ -31,7 +29,7 @@ describe(EntityLoader, () => { it('returns a instance of EntityLoaderUtils', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - expect(SimpleTestEntity.loader(viewerContext).utils()).toBeInstanceOf(EntityLoaderUtils); + expect(SimpleTestEntity.loaderUtils(viewerContext)).toBeInstanceOf(EntityLoaderUtils); }); }); }); diff --git a/packages/entity/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts b/packages/entity/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts index e9b60f76..7e5e92ff 100644 --- a/packages/entity/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +++ b/packages/entity/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts @@ -76,9 +76,9 @@ class TestNonTransactionalMutationTrigger extends EntityNonTransactionalMutation mutationInfo: EntityTriggerMutationInfo, ): Promise { if (mutationInfo.type === EntityMutationType.DELETE) { - const entityLoaded = await BlahEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(entity.getID()); + const entityLoaded = await BlahEntity.loader(viewerContext).loadByIDNullableAsync( + entity.getID(), + ); if (entityLoaded) { throw new Error( 'should not have been able to re-load the entity after delete. this means the cache has not been cleared', @@ -94,11 +94,9 @@ describe(EntityMutatorFactory, () => { const viewerContext = new ViewerContext(companionProvider); // put it in cache - const entity = await BlahEntity.creator(viewerContext).enforcing().createAsync(); - const entityLoaded = await BlahEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity.getID()); + const entity = await BlahEntity.creator(viewerContext).createAsync(); + const entityLoaded = await BlahEntity.loader(viewerContext).loadByIDAsync(entity.getID()); - await BlahEntity.deleter(entityLoaded).enforcing().deleteAsync(); + await BlahEntity.deleter(entityLoaded).deleteAsync(); }); }); diff --git a/packages/entity/src/__tests__/EntitySecondaryCacheLoader-test.ts b/packages/entity/src/__tests__/EntitySecondaryCacheLoader-test.ts index 893d98ac..665ffef6 100644 --- a/packages/entity/src/__tests__/EntitySecondaryCacheLoader-test.ts +++ b/packages/entity/src/__tests__/EntitySecondaryCacheLoader-test.ts @@ -32,7 +32,7 @@ describe(EntitySecondaryCacheLoader, () => { it('calls into secondary cache with correct params', async () => { const vc1 = new ViewerContext(createUnitTestEntityCompanionProvider()); - const createdEntity = await SimpleTestEntity.creator(vc1).enforcing().createAsync(); + const createdEntity = await SimpleTestEntity.creator(vc1).createAsync(); const loadParams = { id: createdEntity.getID() }; const secondaryEntityCacheMock = @@ -44,7 +44,7 @@ describe(EntitySecondaryCacheLoader, () => { const secondaryCacheLoader = new TestSecondaryRedisCacheLoader( secondaryEntityCache, - SimpleTestEntity.loader(vc1).withAuthorizationResults(), + SimpleTestEntity.loaderWithAuthorizationResults(vc1), ); await secondaryCacheLoader.loadManyAsync([loadParams]); @@ -57,7 +57,7 @@ describe(EntitySecondaryCacheLoader, () => { it('constructs and authorizes entities', async () => { const vc1 = new ViewerContext(createUnitTestEntityCompanionProvider()); - const createdEntity = await SimpleTestEntity.creator(vc1).enforcing().createAsync(); + const createdEntity = await SimpleTestEntity.creator(vc1).createAsync(); const loadParams = { id: createdEntity.getID() }; const secondaryEntityCacheMock = @@ -67,7 +67,7 @@ describe(EntitySecondaryCacheLoader, () => { ).thenResolve(new Map([[loadParams, createdEntity.getAllFields()]])); const secondaryEntityCache = instance(secondaryEntityCacheMock); - const loader = SimpleTestEntity.loader(vc1).withAuthorizationResults(); + const loader = SimpleTestEntity.loaderWithAuthorizationResults(vc1); const spiedPrivacyPolicy = spy(loader.utils['privacyPolicy']); const secondaryCacheLoader = new TestSecondaryRedisCacheLoader(secondaryEntityCache, loader); @@ -90,13 +90,13 @@ describe(EntitySecondaryCacheLoader, () => { it('calls invalidate on the secondary cache', async () => { const vc1 = new ViewerContext(createUnitTestEntityCompanionProvider()); - const createdEntity = await SimpleTestEntity.creator(vc1).enforcing().createAsync(); + const createdEntity = await SimpleTestEntity.creator(vc1).createAsync(); const loadParams = { id: createdEntity.getID() }; const secondaryEntityCacheMock = mock>(); const secondaryEntityCache = instance(secondaryEntityCacheMock); - const loader = SimpleTestEntity.loader(vc1).withAuthorizationResults(); + const loader = SimpleTestEntity.loaderWithAuthorizationResults(vc1); const secondaryCacheLoader = new TestSecondaryRedisCacheLoader(secondaryEntityCache, loader); await secondaryCacheLoader.invalidateManyAsync([loadParams]); diff --git a/packages/entity/src/__tests__/EntitySelfReferentialEdges-test.ts b/packages/entity/src/__tests__/EntitySelfReferentialEdges-test.ts index 4a8efda2..0520fc18 100644 --- a/packages/entity/src/__tests__/EntitySelfReferentialEdges-test.ts +++ b/packages/entity/src/__tests__/EntitySelfReferentialEdges-test.ts @@ -87,44 +87,34 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parentCategory = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const parentCategory = await CategoryEntity.creator(viewerContext).createAsync(); const subCategory = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', parentCategory.getID()) .createAsync(); const subSubCategory = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', subCategory.getID()) .createAsync(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(parentCategory.getID()), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(subCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subCategory.getID()), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(subSubCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subSubCategory.getID()), ).resolves.not.toBeNull(); - await CategoryEntity.deleter(parentCategory).enforcing().deleteAsync(); + await CategoryEntity.deleter(parentCategory).deleteAsync(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(parentCategory.getID()), ).resolves.toBeNull(); await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(subCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subCategory.getID()), ).resolves.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(subSubCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subSubCategory.getID()), ).resolves.toBeNull(); }); @@ -134,23 +124,21 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const categoryA = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const categoryA = await CategoryEntity.creator(viewerContext).createAsync(); const categoryB = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', categoryA.getID()) .createAsync(); await CategoryEntity.updater(categoryA) - .enforcing() .setField('parent_category_id', categoryB.getID()) .updateAsync(); - await CategoryEntity.deleter(categoryA).enforcing().deleteAsync(); + await CategoryEntity.deleter(categoryA).deleteAsync(); await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(categoryA.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(categoryA.getID()), ).resolves.toBeNull(); await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(categoryB.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(categoryB.getID()), ).resolves.toBeNull(); }); }); @@ -162,46 +150,38 @@ describe('EntityEdgeDeletionBehavior.SET_NULL', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parentCategory = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const parentCategory = await CategoryEntity.creator(viewerContext).createAsync(); const subCategory = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', parentCategory.getID()) .createAsync(); const subSubCategory = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', subCategory.getID()) .createAsync(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(parentCategory.getID()), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(subCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subCategory.getID()), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(subSubCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subSubCategory.getID()), ).resolves.not.toBeNull(); - await CategoryEntity.deleter(parentCategory).enforcing().deleteAsync(); + await CategoryEntity.deleter(parentCategory).deleteAsync(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(parentCategory.getID()), ).resolves.toBeNull(); - const loadedSubCategory = await CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(subCategory.getID()); + const loadedSubCategory = await CategoryEntity.loader(viewerContext).loadByIDAsync( + subCategory.getID(), + ); expect(loadedSubCategory.getField('parent_category_id')).toBeNull(); - const loadedSubSubCategory = await CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(subSubCategory.getID()); + const loadedSubSubCategory = await CategoryEntity.loader(viewerContext).loadByIDAsync( + subSubCategory.getID(), + ); expect(loadedSubSubCategory.getField('parent_category_id')).not.toBeNull(); }); @@ -211,21 +191,19 @@ describe('EntityEdgeDeletionBehavior.SET_NULL', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const categoryA = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const categoryA = await CategoryEntity.creator(viewerContext).createAsync(); const categoryB = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', categoryA.getID()) .createAsync(); await CategoryEntity.updater(categoryA) - .enforcing() .setField('parent_category_id', categoryB.getID()) .updateAsync(); - await CategoryEntity.deleter(categoryA).enforcing().deleteAsync(); + await CategoryEntity.deleter(categoryA).deleteAsync(); - const loadedCategoryB = await CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(categoryB.getID()); + const loadedCategoryB = await CategoryEntity.loader(viewerContext).loadByIDAsync( + categoryB.getID(), + ); expect(loadedCategoryB.getField('parent_category_id')).toBeNull(); }); }); @@ -239,30 +217,28 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const parentCategory = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const parentCategory = await CategoryEntity.creator(viewerContext).createAsync(); const subCategory = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', parentCategory.getID()) .createAsync(); const subSubCategory = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', subCategory.getID()) .createAsync(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(parentCategory.getID()), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_category_id', parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'parent_category_id', + parentCategory.getID(), + ), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_category_id', subCategory.getID()), + CategoryEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'parent_category_id', + subCategory.getID(), + ), ).resolves.not.toBeNull(); const categoryCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass( @@ -281,7 +257,7 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => { ); expect(subSubCategoryCachedBefore.get(subCategory.getID())?.status).toEqual(CacheStatus.HIT); - await CategoryEntity.deleter(parentCategory).enforcing().deleteAsync(); + await CategoryEntity.deleter(parentCategory).deleteAsync(); const subCategoryCachedAfter = await categoryCacheAdapter.loadManyAsync('parent_category_id', [ parentCategory.getID(), @@ -295,17 +271,13 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => { expect(subSubCategoryCachedAfter.get(subCategory.getID())?.status).toEqual(CacheStatus.MISS); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(parentCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(parentCategory.getID()), ).resolves.toBeNull(); await expect( - CategoryEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(subCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subCategory.getID()), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByIDNullableAsync(subSubCategory.getID()), + CategoryEntity.loader(viewerContext).loadByIDNullableAsync(subSubCategory.getID()), ).resolves.not.toBeNull(); }); @@ -317,25 +289,25 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new TestViewerContext(companionProvider); - const categoryA = await CategoryEntity.creator(viewerContext).enforcing().createAsync(); + const categoryA = await CategoryEntity.creator(viewerContext).createAsync(); const categoryB = await CategoryEntity.creator(viewerContext) - .enforcing() .setField('parent_category_id', categoryA.getID()) .createAsync(); await CategoryEntity.updater(categoryA) - .enforcing() .setField('parent_category_id', categoryB.getID()) .updateAsync(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_category_id', categoryA.getID()), + CategoryEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'parent_category_id', + categoryA.getID(), + ), ).resolves.not.toBeNull(); await expect( - CategoryEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('parent_category_id', categoryB.getID()), + CategoryEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'parent_category_id', + categoryB.getID(), + ), ).resolves.not.toBeNull(); const categoryCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass( @@ -350,7 +322,7 @@ describe('EntityEdgeDeletionBehavior.CASCADE_DELETE_INVALIDATE_CACHE', () => { expect(categoriesCachedBefore.get(categoryA.getID())?.status).toEqual(CacheStatus.HIT); expect(categoriesCachedBefore.get(categoryB.getID())?.status).toEqual(CacheStatus.HIT); - await CategoryEntity.deleter(categoryA).enforcing().deleteAsync(); + await CategoryEntity.deleter(categoryA).deleteAsync(); const categoriesCachedAfter = await categoryCacheAdapter.loadManyAsync('parent_category_id', [ categoryA.getID(), diff --git a/packages/entity/src/__tests__/ReadonlyEntity-test.ts b/packages/entity/src/__tests__/ReadonlyEntity-test.ts index c80f9473..344f08c3 100644 --- a/packages/entity/src/__tests__/ReadonlyEntity-test.ts +++ b/packages/entity/src/__tests__/ReadonlyEntity-test.ts @@ -1,7 +1,10 @@ import { instance, mock } from 'ts-mockito'; -import EntityAssociationLoader from '../EntityAssociationLoader'; -import EntityLoader from '../EntityLoader'; +import AuthorizationResultBasedEntityAssociationLoader from '../AuthorizationResultBasedEntityAssociationLoader'; +import AuthorizationResultBasedEntityLoader from '../AuthorizationResultBasedEntityLoader'; +import EnforcingEntityAssociationLoader from '../EnforcingEntityAssociationLoader'; +import EnforcingEntityLoader from '../EnforcingEntityLoader'; +import EntityLoaderUtils from '../EntityLoaderUtils'; import ReadonlyEntity from '../ReadonlyEntity'; import ViewerContext from '../ViewerContext'; import SimpleTestEntity from '../testfixtures/SimpleTestEntity'; @@ -157,7 +160,7 @@ describe(ReadonlyEntity, () => { }); describe('associationLoader', () => { - it('returns a new association loader', () => { + it('returns a new EnforcingEntityAssociationLoader', () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); const data = { @@ -169,15 +172,52 @@ describe(ReadonlyEntity, () => { databaseFields: data, selectedFields: data, }); - expect(testEntity.associationLoader()).toBeInstanceOf(EntityAssociationLoader); + expect(testEntity.associationLoader()).toBeInstanceOf(EnforcingEntityAssociationLoader); + }); + }); + + describe('associationLoaderWithAuthorizationResults', () => { + it('returns a new AuthorizationResultBasedEntityAssociationLoader', () => { + const companionProvider = createUnitTestEntityCompanionProvider(); + const viewerContext = new ViewerContext(companionProvider); + const data = { + id: 'what', + }; + const testEntity = new SimpleTestEntity({ + viewerContext, + id: 'what', + databaseFields: data, + selectedFields: data, + }); + expect(testEntity.associationLoaderWithAuthorizationResults()).toBeInstanceOf( + AuthorizationResultBasedEntityAssociationLoader, + ); }); }); describe('loader', () => { - it('creates a new EntityLoader', async () => { + it('creates a new EnforcingEntityLoader', async () => { + const companionProvider = createUnitTestEntityCompanionProvider(); + const viewerContext = new ViewerContext(companionProvider); + expect(SimpleTestEntity.loader(viewerContext)).toBeInstanceOf(EnforcingEntityLoader); + }); + }); + + describe('loaderWithAuthorizationResults', () => { + it('creates a new AuthorizationResultBasedEntityLoader', async () => { + const companionProvider = createUnitTestEntityCompanionProvider(); + const viewerContext = new ViewerContext(companionProvider); + expect(SimpleTestEntity.loaderWithAuthorizationResults(viewerContext)).toBeInstanceOf( + AuthorizationResultBasedEntityLoader, + ); + }); + }); + + describe('loaderUtils', () => { + it('creates a new EntityLoaderUtils', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - expect(SimpleTestEntity.loader(viewerContext)).toBeInstanceOf(EntityLoader); + expect(SimpleTestEntity.loaderUtils(viewerContext)).toBeInstanceOf(EntityLoaderUtils); }); }); }); diff --git a/packages/entity/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts b/packages/entity/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts index d56d8b96..5693368a 100644 --- a/packages/entity/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +++ b/packages/entity/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts @@ -14,13 +14,11 @@ describe('Two entities backed by the same table', () => { const viewerContext = new ViewerContext(companionProvider); const one = await OneTestEntity.creator(viewerContext) - .enforcing() .setField('entity_type', EntityType.ONE) .setField('common_other_field', 'wat') .createAsync(); const two = await TwoTestEntity.creator(viewerContext) - .enforcing() .setField('entity_type', EntityType.TWO) .setField('other_field', 'blah') .setField('common_other_field', 'wat') @@ -30,16 +28,16 @@ describe('Two entities backed by the same table', () => { expect(two).toBeInstanceOf(TwoTestEntity); await expect( - TwoTestEntity.loader(viewerContext).enforcing().loadByIDAsync(one.getID()), + TwoTestEntity.loader(viewerContext).loadByIDAsync(one.getID()), ).rejects.toThrowError('TwoTestEntity must be instantiated with two data'); await expect( - OneTestEntity.loader(viewerContext).enforcing().loadByIDAsync(two.getID()), + OneTestEntity.loader(viewerContext).loadByIDAsync(two.getID()), ).rejects.toThrowError('OneTestEntity must be instantiated with one data'); - const manyResults = await OneTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadManyByFieldEqualingAsync('common_other_field', 'wat'); + const manyResults = await OneTestEntity.loaderWithAuthorizationResults( + viewerContext, + ).loadManyByFieldEqualingAsync('common_other_field', 'wat'); const successfulManyResults = successfulResults(manyResults); const failedManyResults = failedResults(manyResults); @@ -51,14 +49,14 @@ describe('Two entities backed by the same table', () => { 'OneTestEntity must be instantiated with one data', ); - const fieldEqualityConjunctionResults = await OneTestEntity.loader(viewerContext) - .withAuthorizationResults() - .loadManyByFieldEqualityConjunctionAsync([ - { - fieldName: 'common_other_field', - fieldValue: 'wat', - }, - ]); + const fieldEqualityConjunctionResults = await OneTestEntity.loaderWithAuthorizationResults( + viewerContext, + ).loadManyByFieldEqualityConjunctionAsync([ + { + fieldName: 'common_other_field', + fieldValue: 'wat', + }, + ]); const successfulfieldEqualityConjunctionResultsResults = successfulResults( fieldEqualityConjunctionResults, ); diff --git a/packages/entity/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts b/packages/entity/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts index e2809dbe..77f66d7c 100644 --- a/packages/entity/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +++ b/packages/entity/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts @@ -13,18 +13,14 @@ describe('Two entities backed by the same table', () => { const viewerContext = new ViewerContext(companionProvider); const entity1 = await OneTestEntity.creator(viewerContext) - .enforcing() .setField('fake_field', 'hello') .createAsync(); expect(entity1).toBeInstanceOf(OneTestEntity); - const entity2 = await TwoTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity1.getID()); + const entity2 = await TwoTestEntity.loader(viewerContext).loadByIDAsync(entity1.getID()); expect(entity2).toBeInstanceOf(TwoTestEntity); const updated2 = await TwoTestEntity.updater(entity2) - .enforcing() .setField('fake_field', 'world') .setField('other_field', 'wat') .updateAsync(); @@ -34,9 +30,7 @@ describe('Two entities backed by the same table', () => { fake_field: 'world', }); - const loaded1 = await OneTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity1.getID()); + const loaded1 = await OneTestEntity.loader(viewerContext).loadByIDAsync(entity1.getID()); expect(loaded1.getAllFields()).toMatchObject({ id: updated2.getID(), fake_field: 'world', @@ -48,37 +42,37 @@ describe('Two entities backed by the same table', () => { const viewerContext = new ViewerContext(companionProvider); const entity = await TwoTestEntity.creator(viewerContext) - .enforcing() .setField('fake_field', 'hello') .setField('other_field', 'huh') .createAsync(); - const loadedEntity = await TwoTestEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('other_field', 'huh'); + const loadedEntity = await TwoTestEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'other_field', + 'huh', + ); expect(loadedEntity?.getAllFields()).toMatchObject({ id: entity.getID(), fake_field: 'hello', other_field: 'huh', }); - const loaded1 = await OneTestEntity.loader(viewerContext) - .enforcing() - .loadByIDAsync(entity.getID()); - await OneTestEntity.updater(loaded1).enforcing().setField('fake_field', 'world').updateAsync(); + const loaded1 = await OneTestEntity.loader(viewerContext).loadByIDAsync(entity.getID()); + await OneTestEntity.updater(loaded1).setField('fake_field', 'world').updateAsync(); - const loaded2 = await TwoTestEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('other_field', 'huh'); + const loaded2 = await TwoTestEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'other_field', + 'huh', + ); expect(loaded2?.getAllFields()).toMatchObject({ id: entity.getID(), fake_field: 'world', other_field: 'huh', }); - const loaded22 = await TwoTestEntity.loader(viewerContext) - .enforcing() - .loadByFieldEqualingAsync('fake_field', 'world'); + const loaded22 = await TwoTestEntity.loader(viewerContext).loadByFieldEqualingAsync( + 'fake_field', + 'world', + ); expect(loaded22?.getAllFields()).toMatchObject({ id: entity.getID(), fake_field: 'world', diff --git a/packages/entity/src/utils/__tests__/EntityPrivacyUtils-test.ts b/packages/entity/src/utils/__tests__/EntityPrivacyUtils-test.ts index 3481cb22..ec8712f4 100644 --- a/packages/entity/src/utils/__tests__/EntityPrivacyUtils-test.ts +++ b/packages/entity/src/utils/__tests__/EntityPrivacyUtils-test.ts @@ -50,9 +50,7 @@ describe(canViewerUpdateAsync, () => { it('appropriately executes update privacy policy', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyDeleteEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyDeleteEntity.creator(viewerContext).createAsync(); const canViewerUpdate = await canViewerUpdateAsync(SimpleTestDenyDeleteEntity, testEntity); expect(canViewerUpdate).toBe(true); const canViewerUpdateResult = await getCanViewerUpdateResultAsync( @@ -65,9 +63,7 @@ describe(canViewerUpdateAsync, () => { it('denies when policy denies', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); const canViewerUpdate = await canViewerUpdateAsync(SimpleTestDenyUpdateEntity, testEntity); expect(canViewerUpdate).toBe(false); const canViewerUpdateResult = await getCanViewerUpdateResultAsync( @@ -83,9 +79,7 @@ describe(canViewerUpdateAsync, () => { it('rethrows non-authorization errors', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestThrowOtherErrorEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestThrowOtherErrorEntity.creator(viewerContext).createAsync(); await expect(canViewerUpdateAsync(SimpleTestThrowOtherErrorEntity, testEntity)).rejects.toThrow( 'update error', ); @@ -99,9 +93,7 @@ describe(canViewerDeleteAsync, () => { it('appropriately executes update privacy policy', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); const canViewerDelete = await canViewerDeleteAsync(SimpleTestDenyUpdateEntity, testEntity); expect(canViewerDelete).toBe(true); const canViewerDeleteResult = await getCanViewerDeleteResultAsync( @@ -114,9 +106,7 @@ describe(canViewerDeleteAsync, () => { it('denies when policy denies', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyDeleteEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyDeleteEntity.creator(viewerContext).createAsync(); const canViewerDelete = await canViewerDeleteAsync(SimpleTestDenyDeleteEntity, testEntity); expect(canViewerDelete).toBe(false); const canViewerDeleteResult = await getCanViewerDeleteResultAsync( @@ -132,12 +122,9 @@ describe(canViewerDeleteAsync, () => { it('denies when recursive policy denies for CASCADE_DELETE', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); // add another entity referencing testEntity that would cascade deletion to itself when testEntity is deleted const leafEntity = await LeafDenyDeleteEntity.creator(viewerContext) - .enforcing() .setField('simple_test_deny_update_cascade_delete_id', testEntity.getID()) .createAsync(); const canViewerDelete = await canViewerDeleteAsync(SimpleTestDenyUpdateEntity, testEntity); @@ -155,12 +142,9 @@ describe(canViewerDeleteAsync, () => { it('denies when recursive policy denies for SET_NULL', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); // add another entity referencing testEntity that would set null to its column when testEntity is deleted const leafEntity = await LeafDenyUpdateEntity.creator(viewerContext) - .enforcing() .setField('simple_test_deny_update_set_null_id', testEntity.getID()) .createAsync(); const canViewerDelete = await canViewerDeleteAsync(SimpleTestDenyUpdateEntity, testEntity); @@ -178,17 +162,13 @@ describe(canViewerDeleteAsync, () => { it('allows when recursive policy allows for CASCADE_DELETE and SET_NULL', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); // add another entity referencing testEntity that would cascade deletion to itself when testEntity is deleted await LeafDenyUpdateEntity.creator(viewerContext) - .enforcing() .setField('simple_test_deny_update_cascade_delete_id', testEntity.getID()) .createAsync(); // add another entity referencing testEntity that would set null to its column when testEntity is deleted await LeafDenyDeleteEntity.creator(viewerContext) - .enforcing() .setField('simple_test_deny_update_set_null_id', testEntity.getID()) .createAsync(); @@ -204,9 +184,7 @@ describe(canViewerDeleteAsync, () => { it('rethrows non-authorization errors', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestThrowOtherErrorEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestThrowOtherErrorEntity.creator(viewerContext).createAsync(); await expect( canViewerDeleteAsync(SimpleTestThrowOtherErrorEntity, testEntity), ).rejects.toThrowError('delete error'); @@ -218,11 +196,8 @@ describe(canViewerDeleteAsync, () => { it('returns false when edge cannot be read', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); const leafEntity = await LeafDenyReadEntity.creator(viewerContext) - .enforcing() .setField('simple_test_id', testEntity.getID()) .createAsync(); const canViewerDelete = await canViewerDeleteAsync(SimpleTestDenyUpdateEntity, testEntity); @@ -240,11 +215,8 @@ describe(canViewerDeleteAsync, () => { it('rethrows non-authorization edge read errors', async () => { const companionProvider = createUnitTestEntityCompanionProvider(); const viewerContext = new ViewerContext(companionProvider); - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext).createAsync(); await SimpleTestThrowOtherErrorEntity.creator(viewerContext) - .enforcing() .setField('simple_test_id', testEntity.getID()) .createAsync(); await expect(canViewerDeleteAsync(SimpleTestDenyUpdateEntity, testEntity)).rejects.toThrowError( @@ -261,11 +233,11 @@ describe(canViewerDeleteAsync, () => { const canViewerDelete = await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync( 'postgres', async (queryContext) => { - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext, queryContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator( + viewerContext, + queryContext, + ).createAsync(); await LeafDenyReadEntity.creator(viewerContext, queryContext) - .enforcing() .setField('simple_test_id', testEntity.getID()) .createAsync(); // this would fail if transactions weren't supported or correctly passed through @@ -277,11 +249,11 @@ describe(canViewerDeleteAsync, () => { const canViewerDeleteResult = await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync( 'postgres', async (queryContext) => { - const testEntity = await SimpleTestDenyUpdateEntity.creator(viewerContext, queryContext) - .enforcing() - .createAsync(); + const testEntity = await SimpleTestDenyUpdateEntity.creator( + viewerContext, + queryContext, + ).createAsync(); await LeafDenyReadEntity.creator(viewerContext, queryContext) - .enforcing() .setField('simple_test_id', testEntity.getID()) .createAsync(); // this would fail if transactions weren't supported or correctly passed through diff --git a/packages/entity/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts b/packages/entity/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts index 6bbc5528..e481473d 100644 --- a/packages/entity/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts +++ b/packages/entity/src/utils/__tests__/canViewerDeleteAsync-edgeDeletionPermissionInferenceBehavior-test.ts @@ -21,20 +21,18 @@ describe(canViewerDeleteAsync, () => { const viewerContext = new ViewerContext(companionProvider); // create root - const testEntity = await TestEntity.creator(viewerContext).enforcing().createAsync(); + const testEntity = await TestEntity.creator(viewerContext).createAsync(); // create a bunch of leaves referencing root with // edgeDeletionPermissionInferenceBehavior = EntityEdgeDeletionPermissionInferenceBehavior.ONE_IMPLIES_ALL for (let i = 0; i < 10; i++) { await TestLeafEntity.creator(viewerContext) - .enforcing() .setField('test_entity_id', testEntity.getID()) .createAsync(); } for (let i = 0; i < 10; i++) { await TestLeafLookupByFieldEntity.creator(viewerContext) - .enforcing() .setField('test_entity_id', testEntity.getID()) .createAsync(); } @@ -65,12 +63,11 @@ describe(canViewerDeleteAsync, () => { const viewerContext = new ViewerContext(companionProvider); // create root - const testEntity = await TestEntity.creator(viewerContext).enforcing().createAsync(); + const testEntity = await TestEntity.creator(viewerContext).createAsync(); // create a bunch of leaves with no edgeDeletionPermissionInferenceBehavior for (let i = 0; i < 10; i++) { await TestLeafNoInferenceEntity.creator(viewerContext) - .enforcing() .setField('test_entity_id', testEntity.getID()) .createAsync(); }