@expo/entity 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/build/AuthorizationResultBasedEntityLoader.d.ts +128 -0
  2. package/build/AuthorizationResultBasedEntityLoader.js +196 -0
  3. package/build/AuthorizationResultBasedEntityLoader.js.map +1 -0
  4. package/build/ComposedEntityCacheAdapter.js +1 -0
  5. package/build/ComposedEntityCacheAdapter.js.map +1 -1
  6. package/build/ComposedSecondaryEntityCache.js +1 -0
  7. package/build/ComposedSecondaryEntityCache.js.map +1 -1
  8. package/build/EnforcingEntityLoader.d.ts +5 -4
  9. package/build/EnforcingEntityLoader.js +4 -2
  10. package/build/EnforcingEntityLoader.js.map +1 -1
  11. package/build/Entity.d.ts +4 -31
  12. package/build/Entity.js +19 -46
  13. package/build/Entity.js.map +1 -1
  14. package/build/EntityAssociationLoader.d.ts +9 -9
  15. package/build/EntityAssociationLoader.js +37 -12
  16. package/build/EntityAssociationLoader.js.map +1 -1
  17. package/build/EntityCompanion.js +9 -1
  18. package/build/EntityCompanion.js.map +1 -1
  19. package/build/EntityCompanionProvider.d.ts +3 -1
  20. package/build/EntityCompanionProvider.js +10 -4
  21. package/build/EntityCompanionProvider.js.map +1 -1
  22. package/build/EntityConfiguration.d.ts +2 -1
  23. package/build/EntityConfiguration.js +19 -1
  24. package/build/EntityConfiguration.js.map +1 -1
  25. package/build/EntityDatabaseAdapter.d.ts +2 -2
  26. package/build/EntityDatabaseAdapter.js +5 -3
  27. package/build/EntityDatabaseAdapter.js.map +1 -1
  28. package/build/EntityFieldDefinition.d.ts +21 -10
  29. package/build/EntityFieldDefinition.js +8 -9
  30. package/build/EntityFieldDefinition.js.map +1 -1
  31. package/build/EntityFields.d.ts +10 -0
  32. package/build/EntityFields.js +15 -1
  33. package/build/EntityFields.js.map +1 -1
  34. package/build/EntityLoader.d.ts +12 -125
  35. package/build/EntityLoader.js +24 -239
  36. package/build/EntityLoader.js.map +1 -1
  37. package/build/EntityLoaderFactory.d.ts +1 -1
  38. package/build/EntityLoaderFactory.js +3 -0
  39. package/build/EntityLoaderFactory.js.map +1 -1
  40. package/build/EntityLoaderUtils.d.ts +58 -0
  41. package/build/EntityLoaderUtils.js +109 -0
  42. package/build/EntityLoaderUtils.js.map +1 -0
  43. package/build/EntityMutator.d.ts +1 -0
  44. package/build/EntityMutator.js +71 -56
  45. package/build/EntityMutator.js.map +1 -1
  46. package/build/EntityMutatorFactory.js +9 -0
  47. package/build/EntityMutatorFactory.js.map +1 -1
  48. package/build/EntityPrivacyPolicy.d.ts +11 -5
  49. package/build/EntityPrivacyPolicy.js +5 -7
  50. package/build/EntityPrivacyPolicy.js.map +1 -1
  51. package/build/EntityQueryContext.d.ts +2 -1
  52. package/build/EntityQueryContext.js +11 -6
  53. package/build/EntityQueryContext.js.map +1 -1
  54. package/build/EntityQueryContextProvider.d.ts +1 -1
  55. package/build/EntityQueryContextProvider.js +1 -1
  56. package/build/EntityQueryContextProvider.js.map +1 -1
  57. package/build/EntitySecondaryCacheLoader.js +5 -1
  58. package/build/EntitySecondaryCacheLoader.js.map +1 -1
  59. package/build/GenericEntityCacheAdapter.js +1 -0
  60. package/build/GenericEntityCacheAdapter.js.map +1 -1
  61. package/build/GenericSecondaryEntityCache.js +2 -0
  62. package/build/GenericSecondaryEntityCache.js.map +1 -1
  63. package/build/IEntityCacheAdapterProvider.d.ts +1 -1
  64. package/build/IEntityDatabaseAdapterProvider.d.ts +1 -1
  65. package/build/ReadonlyEntity.d.ts +1 -1
  66. package/build/ReadonlyEntity.js +9 -2
  67. package/build/ReadonlyEntity.js.map +1 -1
  68. package/build/ViewerContext.d.ts +2 -2
  69. package/build/ViewerContext.js +5 -3
  70. package/build/ViewerContext.js.map +1 -1
  71. package/build/ViewerScopedEntityCompanion.js +2 -0
  72. package/build/ViewerScopedEntityCompanion.js.map +1 -1
  73. package/build/ViewerScopedEntityCompanionProvider.d.ts +0 -1
  74. package/build/ViewerScopedEntityCompanionProvider.js +2 -1
  75. package/build/ViewerScopedEntityCompanionProvider.js.map +1 -1
  76. package/build/ViewerScopedEntityLoaderFactory.d.ts +1 -1
  77. package/build/ViewerScopedEntityLoaderFactory.js +2 -0
  78. package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
  79. package/build/ViewerScopedEntityMutatorFactory.js +2 -0
  80. package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
  81. package/build/__tests__/ComposedCacheAdapter-test.js +2 -0
  82. package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -1
  83. package/build/__tests__/ComposedSecondaryEntityCache-test.js +1 -0
  84. package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -1
  85. package/build/__tests__/EnforcingEntityLoader-test.js +101 -113
  86. package/build/__tests__/EnforcingEntityLoader-test.js.map +1 -1
  87. package/build/__tests__/Entity-test.js +5 -137
  88. package/build/__tests__/Entity-test.js.map +1 -1
  89. package/build/__tests__/EntityAssociationLoader-test.js +37 -65
  90. package/build/__tests__/EntityAssociationLoader-test.js.map +1 -1
  91. package/build/__tests__/EntityCommonUseCases-test.js +31 -37
  92. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  93. package/build/__tests__/EntityCompanion-test.js +26 -3
  94. package/build/__tests__/EntityCompanion-test.js.map +1 -1
  95. package/build/__tests__/EntityConfiguration-test.js +103 -0
  96. package/build/__tests__/EntityConfiguration-test.js.map +1 -0
  97. package/build/__tests__/EntityDatabaseAdapter-test.js +6 -0
  98. package/build/__tests__/EntityDatabaseAdapter-test.js.map +1 -1
  99. package/build/__tests__/EntityEdges-test.js +89 -80
  100. package/build/__tests__/EntityEdges-test.js.map +1 -1
  101. package/build/__tests__/EntityFields-test.js +6 -0
  102. package/build/__tests__/EntityFields-test.js.map +1 -1
  103. package/build/__tests__/EntityLoader-constructor-test.js +17 -18
  104. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
  105. package/build/__tests__/EntityLoader-test.js +93 -41
  106. package/build/__tests__/EntityLoader-test.js.map +1 -1
  107. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js +18 -21
  108. package/build/__tests__/EntityMutator-MutationCacheConsistency-test.js.map +1 -1
  109. package/build/__tests__/EntityMutator-test.js +74 -29
  110. package/build/__tests__/EntityMutator-test.js.map +1 -1
  111. package/build/__tests__/EntityPrivacyPolicy-test.js +77 -59
  112. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  113. package/build/__tests__/EntityQueryContext-test.js +9 -0
  114. package/build/__tests__/EntityQueryContext-test.js.map +1 -1
  115. package/build/__tests__/EntitySecondaryCacheLoader-test.js +10 -10
  116. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  117. package/build/__tests__/EntitySelfReferentialEdges-test.js +59 -74
  118. package/build/__tests__/EntitySelfReferentialEdges-test.js.map +1 -1
  119. package/build/__tests__/ReadonlyEntity-test.js +13 -13
  120. package/build/__tests__/ReadonlyEntity-test.js.map +1 -1
  121. package/build/__tests__/ViewerContext-test.js +2 -2
  122. package/build/__tests__/ViewerContext-test.js.map +1 -1
  123. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
  124. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js +26 -28
  125. package/build/__tests__/cases/TwoEntitySameTableDisjointRows-test.js.map +1 -1
  126. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js +25 -30
  127. package/build/__tests__/cases/TwoEntitySameTableOverlappingRows-test.js.map +1 -1
  128. package/build/entityUtils.d.ts +1 -1
  129. package/build/entityUtils.js.map +1 -1
  130. package/build/errors/EntityCacheAdapterError.js +2 -5
  131. package/build/errors/EntityCacheAdapterError.js.map +1 -1
  132. package/build/errors/EntityDatabaseAdapterError.js +14 -35
  133. package/build/errors/EntityDatabaseAdapterError.js.map +1 -1
  134. package/build/errors/EntityError.js +1 -0
  135. package/build/errors/EntityError.js.map +1 -1
  136. package/build/errors/EntityInvalidFieldValueError.js +2 -2
  137. package/build/errors/EntityInvalidFieldValueError.js.map +1 -1
  138. package/build/errors/EntityNotAuthorizedError.js +3 -2
  139. package/build/errors/EntityNotAuthorizedError.js.map +1 -1
  140. package/build/errors/EntityNotFoundError.js +2 -2
  141. package/build/errors/EntityNotFoundError.js.map +1 -1
  142. package/build/index.d.ts +1 -0
  143. package/build/index.js +1 -0
  144. package/build/index.js.map +1 -1
  145. package/build/internal/EntityDataManager.d.ts +1 -1
  146. package/build/internal/EntityDataManager.js +7 -2
  147. package/build/internal/EntityDataManager.js.map +1 -1
  148. package/build/internal/EntityFieldTransformationUtils.d.ts +5 -5
  149. package/build/internal/EntityFieldTransformationUtils.js +5 -8
  150. package/build/internal/EntityFieldTransformationUtils.js.map +1 -1
  151. package/build/internal/EntityTableDataCoordinator.d.ts +1 -1
  152. package/build/internal/EntityTableDataCoordinator.js +5 -0
  153. package/build/internal/EntityTableDataCoordinator.js.map +1 -1
  154. package/build/internal/ReadThroughEntityCache.d.ts +1 -1
  155. package/build/internal/ReadThroughEntityCache.js +2 -0
  156. package/build/internal/ReadThroughEntityCache.js.map +1 -1
  157. package/build/internal/__tests__/EntityDataManager-test.js +11 -11
  158. package/build/internal/__tests__/EntityDataManager-test.js.map +1 -1
  159. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js +6 -2
  160. package/build/internal/__tests__/EntityFieldTransformationUtils-test.js.map +1 -1
  161. package/build/internal/__tests__/ReadThroughEntityCache-test.js +33 -0
  162. package/build/internal/__tests__/ReadThroughEntityCache-test.js.map +1 -1
  163. package/build/metrics/IEntityMetricsAdapter.d.ts +1 -1
  164. package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +1 -1
  165. package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
  166. package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +1 -1
  167. package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
  168. package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +1 -1
  169. package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
  170. package/build/rules/PrivacyPolicyRule.d.ts +1 -1
  171. package/build/rules/PrivacyPolicyRule.js.map +1 -1
  172. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
  173. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
  174. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
  175. package/build/testfixtures/DateIDTestEntity.js +12 -15
  176. package/build/testfixtures/DateIDTestEntity.js.map +1 -1
  177. package/build/testfixtures/SimpleTestEntity.d.ts +8 -8
  178. package/build/testfixtures/SimpleTestEntity.js +12 -15
  179. package/build/testfixtures/SimpleTestEntity.js.map +1 -1
  180. package/build/testfixtures/TestEntity.d.ts +12 -12
  181. package/build/testfixtures/TestEntity.js +12 -15
  182. package/build/testfixtures/TestEntity.js.map +1 -1
  183. package/build/testfixtures/TestEntity2.d.ts +8 -8
  184. package/build/testfixtures/TestEntity2.js +12 -15
  185. package/build/testfixtures/TestEntity2.js.map +1 -1
  186. package/build/testfixtures/TestEntityNumberKey.js +12 -15
  187. package/build/testfixtures/TestEntityNumberKey.js.map +1 -1
  188. package/build/testfixtures/TestEntityWithMutationTriggers.d.ts +36 -0
  189. package/build/testfixtures/TestEntityWithMutationTriggers.js +82 -0
  190. package/build/testfixtures/TestEntityWithMutationTriggers.js.map +1 -0
  191. package/build/testfixtures/TestViewerContext.d.ts +0 -3
  192. package/build/testfixtures/TestViewerContext.js +0 -6
  193. package/build/testfixtures/TestViewerContext.js.map +1 -1
  194. package/build/utils/EntityPrivacyUtils.d.ts +34 -0
  195. package/build/utils/EntityPrivacyUtils.js +160 -0
  196. package/build/utils/EntityPrivacyUtils.js.map +1 -0
  197. package/build/utils/__tests__/EntityPrivacyUtils-test.d.ts +1 -0
  198. package/build/utils/__tests__/EntityPrivacyUtils-test.js +395 -0
  199. package/build/utils/__tests__/EntityPrivacyUtils-test.js.map +1 -0
  200. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.d.ts +1 -0
  201. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js +26 -0
  202. package/build/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.js.map +1 -0
  203. package/build/utils/collections/maps.js.map +1 -1
  204. package/build/utils/mergeEntityMutationTriggerConfigurations.d.ts +4 -0
  205. package/build/utils/mergeEntityMutationTriggerConfigurations.js +28 -0
  206. package/build/utils/mergeEntityMutationTriggerConfigurations.js.map +1 -0
  207. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +1 -1
  208. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  209. package/build/utils/testing/StubCacheAdapter.d.ts +3 -3
  210. package/build/utils/testing/StubCacheAdapter.js +3 -3
  211. package/build/utils/testing/StubCacheAdapter.js.map +1 -1
  212. package/build/utils/testing/StubDatabaseAdapter.d.ts +2 -2
  213. package/build/utils/testing/StubDatabaseAdapter.js +4 -2
  214. package/build/utils/testing/StubDatabaseAdapter.js.map +1 -1
  215. package/build/utils/testing/StubDatabaseAdapterProvider.d.ts +1 -1
  216. package/build/utils/testing/StubDatabaseAdapterProvider.js +1 -3
  217. package/build/utils/testing/StubDatabaseAdapterProvider.js.map +1 -1
  218. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.d.ts +1 -0
  219. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js +42 -0
  220. package/build/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.js.map +1 -0
  221. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js +53 -0
  222. package/build/utils/testing/__tests__/StubDatabaseAdapter-test.js.map +1 -1
  223. package/build/utils/testing/describeFieldTestCase.js.map +1 -1
  224. package/package.json +4 -3
  225. package/src/AuthorizationResultBasedEntityLoader.ts +297 -0
  226. package/src/ComposedEntityCacheAdapter.ts +6 -6
  227. package/src/ComposedSecondaryEntityCache.ts +8 -8
  228. package/src/EnforcingEntityLoader.ts +20 -19
  229. package/src/Entity.ts +26 -118
  230. package/src/EntityAssociationLoader.ts +56 -41
  231. package/src/EntityCompanion.ts +8 -4
  232. package/src/EntityCompanionProvider.ts +24 -16
  233. package/src/EntityConfiguration.ts +18 -7
  234. package/src/EntityDatabaseAdapter.ts +41 -41
  235. package/src/EntityFieldDefinition.ts +28 -18
  236. package/src/EntityFields.ts +15 -0
  237. package/src/EntityLoader.ts +63 -357
  238. package/src/EntityLoaderFactory.ts +10 -4
  239. package/src/EntityLoaderUtils.ts +149 -0
  240. package/src/EntityMutationInfo.ts +2 -2
  241. package/src/EntityMutationTriggerConfiguration.ts +5 -5
  242. package/src/EntityMutationValidator.ts +2 -2
  243. package/src/EntityMutator.ts +146 -144
  244. package/src/EntityMutatorFactory.ts +8 -8
  245. package/src/EntityPrivacyPolicy.ts +78 -28
  246. package/src/EntityQueryContext.ts +14 -13
  247. package/src/EntityQueryContextProvider.ts +6 -6
  248. package/src/EntitySecondaryCacheLoader.ts +13 -11
  249. package/src/GenericEntityCacheAdapter.ts +10 -10
  250. package/src/GenericSecondaryEntityCache.ts +6 -6
  251. package/src/IEntityCacheAdapter.ts +4 -4
  252. package/src/IEntityCacheAdapterProvider.ts +2 -2
  253. package/src/IEntityDatabaseAdapterProvider.ts +2 -2
  254. package/src/ReadonlyEntity.ts +8 -5
  255. package/src/ViewerContext.ts +10 -10
  256. package/src/ViewerScopedEntityCompanion.ts +4 -4
  257. package/src/ViewerScopedEntityCompanionProvider.ts +4 -5
  258. package/src/ViewerScopedEntityLoaderFactory.ts +10 -4
  259. package/src/ViewerScopedEntityMutatorFactory.ts +5 -5
  260. package/src/__tests__/ComposedCacheAdapter-test.ts +12 -10
  261. package/src/__tests__/ComposedSecondaryEntityCache-test.ts +8 -8
  262. package/src/__tests__/EnforcingEntityLoader-test.ts +236 -159
  263. package/src/__tests__/Entity-test.ts +5 -223
  264. package/src/__tests__/EntityAssociationLoader-test.ts +91 -169
  265. package/src/__tests__/EntityCommonUseCases-test.ts +36 -38
  266. package/src/__tests__/EntityCompanion-test.ts +57 -5
  267. package/src/__tests__/EntityConfiguration-test.ts +118 -0
  268. package/src/__tests__/EntityDatabaseAdapter-test.ts +11 -11
  269. package/src/__tests__/EntityEdges-test.ts +128 -118
  270. package/src/__tests__/EntityFields-test.ts +14 -2
  271. package/src/__tests__/EntityLoader-constructor-test.ts +21 -8
  272. package/src/__tests__/EntityLoader-test.ts +233 -105
  273. package/src/__tests__/EntityMutator-MutationCacheConsistency-test.ts +17 -20
  274. package/src/__tests__/EntityMutator-test.ts +342 -163
  275. package/src/__tests__/EntityPrivacyPolicy-test.ts +166 -53
  276. package/src/__tests__/EntityQueryContext-test.ts +30 -12
  277. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +17 -26
  278. package/src/__tests__/EntitySelfReferentialEdges-test.ts +67 -115
  279. package/src/__tests__/GenericEntityCacheAdapter-test.ts +2 -2
  280. package/src/__tests__/ReadonlyEntity-test.ts +13 -15
  281. package/src/__tests__/ViewerContext-test.ts +3 -4
  282. package/src/__tests__/ViewerScopedEntityCompanion-test.ts +2 -2
  283. package/src/__tests__/ViewerScopedEntityCompanionProvider-test.ts +2 -2
  284. package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +2 -1
  285. package/src/__tests__/cases/TwoEntitySameTableDisjointRows-test.ts +34 -45
  286. package/src/__tests__/cases/TwoEntitySameTableOverlappingRows-test.ts +22 -30
  287. package/src/__tests__/entityUtils-test.ts +2 -2
  288. package/src/entityUtils.ts +4 -4
  289. package/src/errors/EntityError.ts +4 -1
  290. package/src/errors/EntityInvalidFieldValueError.ts +2 -2
  291. package/src/errors/EntityNotAuthorizedError.ts +3 -3
  292. package/src/errors/EntityNotFoundError.ts +2 -2
  293. package/src/index.ts +1 -0
  294. package/src/internal/EntityDataManager.ts +25 -25
  295. package/src/internal/EntityFieldTransformationUtils.ts +39 -32
  296. package/src/internal/EntityTableDataCoordinator.ts +3 -3
  297. package/src/internal/ReadThroughEntityCache.ts +9 -9
  298. package/src/internal/__tests__/EntityDataManager-test.ts +62 -62
  299. package/src/internal/__tests__/EntityFieldTransformationUtils-test.ts +14 -10
  300. package/src/internal/__tests__/ReadThroughEntityCache-test.ts +74 -18
  301. package/src/metrics/EntityMetricsUtils.ts +4 -4
  302. package/src/metrics/IEntityMetricsAdapter.ts +1 -1
  303. package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +9 -3
  304. package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +9 -3
  305. package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +9 -3
  306. package/src/rules/PrivacyPolicyRule.ts +9 -3
  307. package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -1
  308. package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -1
  309. package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -1
  310. package/src/testfixtures/SimpleTestEntity.ts +8 -8
  311. package/src/testfixtures/TestEntity.ts +13 -16
  312. package/src/testfixtures/TestEntity2.ts +8 -8
  313. package/src/testfixtures/TestEntityWithMutationTriggers.ts +156 -0
  314. package/src/testfixtures/TestViewerContext.ts +1 -12
  315. package/src/utils/EntityPrivacyUtils.ts +325 -0
  316. package/src/utils/__tests__/EntityPrivacyUtils-test.ts +570 -0
  317. package/src/utils/__tests__/mergeEntityMutationTriggerConfigurations-test.ts +29 -0
  318. package/src/utils/collections/__tests__/maps-test.ts +2 -2
  319. package/src/utils/collections/maps.ts +11 -11
  320. package/src/utils/mergeEntityMutationTriggerConfigurations.ts +44 -0
  321. package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +25 -22
  322. package/src/utils/testing/StubCacheAdapter.ts +17 -15
  323. package/src/utils/testing/StubDatabaseAdapter.ts +35 -30
  324. package/src/utils/testing/StubDatabaseAdapterProvider.ts +2 -2
  325. package/src/utils/testing/StubQueryContextProvider.ts +2 -2
  326. package/src/utils/testing/__tests__/PrivacyPolicyRuleTestUtils-test.ts +42 -0
  327. package/src/utils/testing/__tests__/StubDatabaseAdapter-test.ts +111 -29
  328. package/src/utils/testing/createUnitTestEntityCompanionProvider.ts +2 -2
  329. package/src/utils/testing/describeFieldTestCase.ts +1 -1
  330. package/build/__tests__/EntityDataConfiguration-test.js +0 -68
  331. package/build/__tests__/EntityDataConfiguration-test.js.map +0 -1
  332. package/src/__tests__/EntityDataConfiguration-test.ts +0 -77
  333. /package/build/__tests__/{EntityDataConfiguration-test.d.ts → EntityConfiguration-test.d.ts} +0 -0
@@ -17,6 +17,7 @@ import EntityConfiguration from '../EntityConfiguration';
17
17
  import EntityDatabaseAdapter from '../EntityDatabaseAdapter';
18
18
  import EntityLoader from '../EntityLoader';
19
19
  import EntityLoaderFactory from '../EntityLoaderFactory';
20
+ import EntityLoaderUtils from '../EntityLoaderUtils';
20
21
  import {
21
22
  EntityMutationType,
22
23
  EntityTriggerMutationInfo,
@@ -31,6 +32,7 @@ import EntityMutatorFactory from '../EntityMutatorFactory';
31
32
  import { EntityPrivacyPolicyEvaluationContext } from '../EntityPrivacyPolicy';
32
33
  import { EntityTransactionalQueryContext, EntityQueryContext } from '../EntityQueryContext';
33
34
  import IEntityDatabaseAdapterProvider from '../IEntityDatabaseAdapterProvider';
35
+ import ViewerContext from '../ViewerContext';
34
36
  import { enforceResultsAsync } from '../entityUtils';
35
37
  import EntityDataManager from '../internal/EntityDataManager';
36
38
  import ReadThroughEntityCache from '../internal/ReadThroughEntityCache';
@@ -46,7 +48,6 @@ import TestEntity, {
46
48
  TestEntityPrivacyPolicy,
47
49
  testEntityConfiguration,
48
50
  } from '../testfixtures/TestEntity';
49
- import TestViewerContext from '../testfixtures/TestViewerContext';
50
51
  import { NoCacheStubCacheAdapterProvider } from '../utils/testing/StubCacheAdapter';
51
52
  import StubDatabaseAdapter from '../utils/testing/StubDatabaseAdapter';
52
53
  import StubQueryContextProvider from '../utils/testing/StubQueryContextProvider';
@@ -54,58 +55,52 @@ import StubQueryContextProvider from '../utils/testing/StubQueryContextProvider'
54
55
  class TestMutationTrigger extends EntityMutationTrigger<
55
56
  TestFields,
56
57
  string,
57
- TestViewerContext,
58
+ ViewerContext,
58
59
  TestEntity,
59
60
  keyof TestFields
60
61
  > {
61
62
  async executeAsync(
62
- _viewerContext: TestViewerContext,
63
+ _viewerContext: ViewerContext,
63
64
  _queryContext: EntityQueryContext,
64
65
  _entity: TestEntity,
65
66
  _mutationInfo: EntityTriggerMutationInfo<
66
67
  TestFields,
67
68
  string,
68
- TestViewerContext,
69
+ ViewerContext,
69
70
  TestEntity,
70
71
  keyof TestFields
71
- >
72
+ >,
72
73
  ): Promise<void> {}
73
74
  }
74
75
 
75
76
  class TestNonTransactionalMutationTrigger extends EntityNonTransactionalMutationTrigger<
76
77
  TestFields,
77
78
  string,
78
- TestViewerContext,
79
+ ViewerContext,
79
80
  TestEntity,
80
81
  keyof TestFields
81
82
  > {
82
- async executeAsync(_viewerContext: TestViewerContext, _entity: TestEntity): Promise<void> {}
83
+ async executeAsync(_viewerContext: ViewerContext, _entity: TestEntity): Promise<void> {}
83
84
  }
84
85
 
85
86
  const setUpMutationValidatorSpies = (
86
87
  mutationValidators: EntityMutationValidator<
87
88
  TestFields,
88
89
  string,
89
- TestViewerContext,
90
+ ViewerContext,
90
91
  TestEntity,
91
92
  keyof TestFields
92
- >[]
93
- ): EntityMutationValidator<
94
- TestFields,
95
- string,
96
- TestViewerContext,
97
- TestEntity,
98
- keyof TestFields
99
- >[] => {
93
+ >[],
94
+ ): EntityMutationValidator<TestFields, string, ViewerContext, TestEntity, keyof TestFields>[] => {
100
95
  return mutationValidators.map((validator) => spy(validator));
101
96
  };
102
97
 
103
98
  const verifyValidatorCounts = (
104
- viewerContext: TestViewerContext,
99
+ viewerContext: ViewerContext,
105
100
  mutationValidatorSpies: EntityMutationValidator<
106
101
  TestFields,
107
102
  string,
108
- TestViewerContext,
103
+ ViewerContext,
109
104
  TestEntity,
110
105
  keyof TestFields
111
106
  >[],
@@ -113,10 +108,10 @@ const verifyValidatorCounts = (
113
108
  mutationInfo: EntityValidatorMutationInfo<
114
109
  TestFields,
115
110
  string,
116
- TestViewerContext,
111
+ ViewerContext,
117
112
  TestEntity,
118
113
  keyof TestFields
119
- >
114
+ >,
120
115
  ): void => {
121
116
  for (const validator of mutationValidatorSpies) {
122
117
  verify(
@@ -124,8 +119,8 @@ const verifyValidatorCounts = (
124
119
  viewerContext,
125
120
  anyOfClass(EntityTransactionalQueryContext),
126
121
  anyOfClass(TestEntity),
127
- deepEqual(mutationInfo)
128
- )
122
+ deepEqual(mutationInfo),
123
+ ),
129
124
  ).times(expectedCalls);
130
125
  }
131
126
  };
@@ -134,14 +129,14 @@ const setUpMutationTriggerSpies = (
134
129
  mutationTriggers: EntityMutationTriggerConfiguration<
135
130
  TestFields,
136
131
  string,
137
- TestViewerContext,
132
+ ViewerContext,
138
133
  TestEntity,
139
134
  keyof TestFields
140
- >
135
+ >,
141
136
  ): EntityMutationTriggerConfiguration<
142
137
  TestFields,
143
138
  string,
144
- TestViewerContext,
139
+ ViewerContext,
145
140
  TestEntity,
146
141
  keyof TestFields
147
142
  > => {
@@ -159,11 +154,11 @@ const setUpMutationTriggerSpies = (
159
154
  };
160
155
 
161
156
  const verifyTriggerCounts = (
162
- viewerContext: TestViewerContext,
157
+ viewerContext: ViewerContext,
163
158
  mutationTriggerSpies: EntityMutationTriggerConfiguration<
164
159
  TestFields,
165
160
  string,
166
- TestViewerContext,
161
+ ViewerContext,
167
162
  TestEntity,
168
163
  keyof TestFields
169
164
  >,
@@ -172,7 +167,7 @@ const verifyTriggerCounts = (
172
167
  EntityMutationTriggerConfiguration<
173
168
  TestFields,
174
169
  string,
175
- TestViewerContext,
170
+ ViewerContext,
176
171
  TestEntity,
177
172
  keyof TestFields
178
173
  >,
@@ -188,10 +183,10 @@ const verifyTriggerCounts = (
188
183
  mutationInfo: EntityTriggerMutationInfo<
189
184
  TestFields,
190
185
  string,
191
- TestViewerContext,
186
+ ViewerContext,
192
187
  TestEntity,
193
188
  keyof TestFields
194
- >
189
+ >,
195
190
  ): void => {
196
191
  Object.keys(executed).forEach((s) => {
197
192
  if ((executed as any)[s]) {
@@ -200,8 +195,8 @@ const verifyTriggerCounts = (
200
195
  viewerContext,
201
196
  anyOfClass(EntityTransactionalQueryContext),
202
197
  anyOfClass(TestEntity),
203
- deepEqual(mutationInfo)
204
- )
198
+ deepEqual(mutationInfo),
199
+ ),
205
200
  ).once();
206
201
  } else {
207
202
  verify(
@@ -209,8 +204,8 @@ const verifyTriggerCounts = (
209
204
  viewerContext,
210
205
  anyOfClass(EntityTransactionalQueryContext),
211
206
  anyOfClass(TestEntity),
212
- deepEqual(mutationInfo)
213
- )
207
+ deepEqual(mutationInfo),
208
+ ),
214
209
  ).never();
215
210
  }
216
211
  });
@@ -220,8 +215,8 @@ const verifyTriggerCounts = (
220
215
  viewerContext,
221
216
  anyOfClass(EntityTransactionalQueryContext),
222
217
  anyOfClass(TestEntity),
223
- deepEqual(mutationInfo)
224
- )
218
+ deepEqual(mutationInfo),
219
+ ),
225
220
  ).once();
226
221
 
227
222
  verify(
@@ -229,27 +224,27 @@ const verifyTriggerCounts = (
229
224
  viewerContext,
230
225
  anyOfClass(EntityTransactionalQueryContext),
231
226
  anyOfClass(TestEntity),
232
- deepEqual(mutationInfo)
233
- )
227
+ deepEqual(mutationInfo),
228
+ ),
234
229
  ).once();
235
230
 
236
231
  verify(
237
232
  mutationTriggerSpies.afterCommit![0]!.executeAsync(
238
233
  viewerContext,
239
234
  anyOfClass(TestEntity),
240
- deepEqual(mutationInfo)
241
- )
235
+ deepEqual(mutationInfo),
236
+ ),
242
237
  ).once();
243
238
  };
244
239
 
245
240
  const createEntityMutatorFactory = (
246
- existingObjects: TestFields[]
241
+ existingObjects: TestFields[],
247
242
  ): {
248
243
  privacyPolicy: TestEntityPrivacyPolicy;
249
244
  entityLoaderFactory: EntityLoaderFactory<
250
245
  TestFields,
251
246
  string,
252
- TestViewerContext,
247
+ ViewerContext,
253
248
  TestEntity,
254
249
  TestEntityPrivacyPolicy,
255
250
  keyof TestFields
@@ -257,7 +252,7 @@ const createEntityMutatorFactory = (
257
252
  entityMutatorFactory: EntityMutatorFactory<
258
253
  TestFields,
259
254
  string,
260
- TestViewerContext,
255
+ ViewerContext,
261
256
  TestEntity,
262
257
  TestEntityPrivacyPolicy
263
258
  >;
@@ -265,14 +260,14 @@ const createEntityMutatorFactory = (
265
260
  mutationValidators: EntityMutationValidator<
266
261
  TestFields,
267
262
  string,
268
- TestViewerContext,
263
+ ViewerContext,
269
264
  TestEntity,
270
265
  keyof TestFields
271
266
  >[];
272
267
  mutationTriggers: EntityMutationTriggerConfiguration<
273
268
  TestFields,
274
269
  string,
275
- TestViewerContext,
270
+ ViewerContext,
276
271
  TestEntity,
277
272
  keyof TestFields
278
273
  >;
@@ -280,14 +275,14 @@ const createEntityMutatorFactory = (
280
275
  const mutationValidators: EntityMutationValidator<
281
276
  TestFields,
282
277
  string,
283
- TestViewerContext,
278
+ ViewerContext,
284
279
  TestEntity,
285
280
  keyof TestFields
286
281
  >[] = [new TestMutationTrigger()];
287
282
  const mutationTriggers: EntityMutationTriggerConfiguration<
288
283
  TestFields,
289
284
  string,
290
- TestViewerContext,
285
+ ViewerContext,
291
286
  TestEntity,
292
287
  keyof TestFields
293
288
  > = {
@@ -301,17 +296,16 @@ const createEntityMutatorFactory = (
301
296
  afterAll: [new TestMutationTrigger()],
302
297
  afterCommit: [new TestNonTransactionalMutationTrigger()],
303
298
  };
304
- const privacyPolicy = new TestEntityPrivacyPolicy();
305
299
  const databaseAdapter = new StubDatabaseAdapter<TestFields>(
306
300
  testEntityConfiguration,
307
301
  StubDatabaseAdapter.convertFieldObjectsToDataStore(
308
302
  testEntityConfiguration,
309
- new Map([[testEntityConfiguration.tableName, existingObjects]])
310
- )
303
+ new Map([[testEntityConfiguration.tableName, existingObjects]]),
304
+ ),
311
305
  );
312
306
  const customStubDatabaseAdapterProvider: IEntityDatabaseAdapterProvider = {
313
- getDatabaseAdapter<TFields>(
314
- _entityConfiguration: EntityConfiguration<TFields>
307
+ getDatabaseAdapter<TFields extends Record<string, any>>(
308
+ _entityConfiguration: EntityConfiguration<TFields>,
315
309
  ): EntityDatabaseAdapter<TFields> {
316
310
  return databaseAdapter as any as EntityDatabaseAdapter<TFields>;
317
311
  },
@@ -339,7 +333,7 @@ const createEntityMutatorFactory = (
339
333
  cacheAdapterProvider,
340
334
  },
341
335
  ],
342
- ])
336
+ ]),
343
337
  );
344
338
 
345
339
  const dataManager = new EntityDataManager(
@@ -347,26 +341,26 @@ const createEntityMutatorFactory = (
347
341
  entityCache,
348
342
  StubQueryContextProvider,
349
343
  metricsAdapter,
350
- TestEntity.name
344
+ TestEntity.name,
351
345
  );
352
346
  const entityLoaderFactory = new EntityLoaderFactory(
353
347
  companionProvider.getCompanionForEntity(TestEntity),
354
348
  dataManager,
355
- metricsAdapter
349
+ metricsAdapter,
356
350
  );
357
351
  const entityMutatorFactory = new EntityMutatorFactory(
358
352
  companionProvider,
359
353
  testEntityConfiguration,
360
354
  TestEntity,
361
- privacyPolicy,
355
+ companionProvider.getCompanionForEntity(TestEntity).privacyPolicy,
362
356
  mutationValidators,
363
357
  mutationTriggers,
364
358
  entityLoaderFactory,
365
359
  databaseAdapter,
366
- metricsAdapter
360
+ metricsAdapter,
367
361
  );
368
362
  return {
369
- privacyPolicy,
363
+ privacyPolicy: companionProvider.getCompanionForEntity(TestEntity).privacyPolicy,
370
364
  entityLoaderFactory,
371
365
  entityMutatorFactory,
372
366
  metricsAdapter,
@@ -378,8 +372,8 @@ const createEntityMutatorFactory = (
378
372
  describe(EntityMutatorFactory, () => {
379
373
  describe('forCreate', () => {
380
374
  it('creates entities', async () => {
381
- const viewerContext = mock<TestViewerContext>();
382
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
375
+ const viewerContext = mock<ViewerContext>();
376
+ const queryContext = StubQueryContextProvider.getQueryContext();
383
377
 
384
378
  const id1 = uuidv4();
385
379
  const id2 = uuidv4();
@@ -409,8 +403,8 @@ describe(EntityMutatorFactory, () => {
409
403
  });
410
404
 
411
405
  it('checks privacy', async () => {
412
- const viewerContext = mock<TestViewerContext>();
413
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
406
+ const viewerContext = mock<ViewerContext>();
407
+ const queryContext = StubQueryContextProvider.getQueryContext();
414
408
 
415
409
  const id1 = uuidv4();
416
410
  const id2 = uuidv4();
@@ -444,16 +438,16 @@ describe(EntityMutatorFactory, () => {
444
438
  spiedPrivacyPolicy.authorizeCreateAsync(
445
439
  viewerContext,
446
440
  anyOfClass(EntityTransactionalQueryContext),
447
- deepEqual({ cascadingDeleteCause: null }),
441
+ deepEqual({ previousValue: null, cascadingDeleteCause: null }),
448
442
  anyOfClass(TestEntity),
449
- anything()
450
- )
443
+ anything(),
444
+ ),
451
445
  ).once();
452
446
  });
453
447
 
454
448
  it('executes triggers', async () => {
455
- const viewerContext = mock<TestViewerContext>();
456
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
449
+ const viewerContext = mock<ViewerContext>();
450
+ const queryContext = StubQueryContextProvider.getQueryContext();
457
451
 
458
452
  const id1 = uuidv4();
459
453
  const id2 = uuidv4();
@@ -494,13 +488,13 @@ describe(EntityMutatorFactory, () => {
494
488
  beforeDelete: false,
495
489
  afterDelete: false,
496
490
  },
497
- { type: EntityMutationType.CREATE }
491
+ { type: EntityMutationType.CREATE },
498
492
  );
499
493
  });
500
494
 
501
495
  it('executes validators', async () => {
502
- const viewerContext = mock<TestViewerContext>();
503
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
496
+ const viewerContext = mock<ViewerContext>();
497
+ const queryContext = StubQueryContextProvider.getQueryContext();
504
498
 
505
499
  const id1 = uuidv4();
506
500
  const id2 = uuidv4();
@@ -536,9 +530,20 @@ describe(EntityMutatorFactory, () => {
536
530
 
537
531
  describe('forUpdate', () => {
538
532
  it('updates entities', async () => {
539
- const viewerContext = mock<TestViewerContext>();
540
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
541
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
533
+ const viewerContext = mock<ViewerContext>();
534
+ const privacyPolicyEvaluationContext =
535
+ instance(
536
+ mock<
537
+ EntityPrivacyPolicyEvaluationContext<
538
+ TestFields,
539
+ string,
540
+ ViewerContext,
541
+ TestEntity,
542
+ keyof TestFields
543
+ >
544
+ >(),
545
+ );
546
+ const queryContext = StubQueryContextProvider.getQueryContext();
542
547
 
543
548
  const id1 = uuidv4();
544
549
  const id2 = uuidv4();
@@ -564,7 +569,8 @@ describe(EntityMutatorFactory, () => {
564
569
  const existingEntity = await enforceAsyncResult(
565
570
  entityLoaderFactory
566
571
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
567
- .loadByIDAsync(id2)
572
+ .withAuthorizationResults()
573
+ .loadByIDAsync(id2),
568
574
  );
569
575
 
570
576
  const updatedEntity = await entityMutatorFactory
@@ -579,15 +585,15 @@ describe(EntityMutatorFactory, () => {
579
585
  const reloadedEntity = await enforceAsyncResult(
580
586
  entityLoaderFactory
581
587
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
582
- .loadByIDAsync(id2)
588
+ .withAuthorizationResults()
589
+ .loadByIDAsync(id2),
583
590
  );
584
591
  expect(reloadedEntity.getAllFields()).toMatchObject(updatedEntity.getAllFields());
585
592
  });
586
593
 
587
594
  it('checks privacy', async () => {
588
- const viewerContext = mock<TestViewerContext>();
589
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
590
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
595
+ const viewerContext = mock<ViewerContext>();
596
+ const queryContext = StubQueryContextProvider.getQueryContext();
591
597
 
592
598
  const id1 = uuidv4();
593
599
  const id2 = uuidv4();
@@ -615,8 +621,9 @@ describe(EntityMutatorFactory, () => {
615
621
 
616
622
  const existingEntity = await enforceAsyncResult(
617
623
  entityLoaderFactory
618
- .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
619
- .loadByIDAsync(id2)
624
+ .forLoad(viewerContext, queryContext, { previousValue: null, cascadingDeleteCause: null })
625
+ .withAuthorizationResults()
626
+ .loadByIDAsync(id2),
620
627
  );
621
628
 
622
629
  await entityMutatorFactory
@@ -628,17 +635,38 @@ describe(EntityMutatorFactory, () => {
628
635
  spiedPrivacyPolicy.authorizeUpdateAsync(
629
636
  viewerContext,
630
637
  anyOfClass(EntityTransactionalQueryContext),
631
- deepEqual({ cascadingDeleteCause: null }),
638
+ deepEqual({ previousValue: existingEntity, cascadingDeleteCause: null }),
632
639
  anyOfClass(TestEntity),
633
- anything()
634
- )
640
+ anything(),
641
+ ),
642
+ ).once();
643
+
644
+ verify(
645
+ spiedPrivacyPolicy.authorizeReadAsync(
646
+ viewerContext,
647
+ anyOfClass(EntityTransactionalQueryContext),
648
+ deepEqual({ previousValue: existingEntity, cascadingDeleteCause: null }),
649
+ anyOfClass(TestEntity),
650
+ anything(),
651
+ ),
635
652
  ).once();
636
653
  });
637
654
 
638
655
  it('executes triggers', async () => {
639
- const viewerContext = mock<TestViewerContext>();
640
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
641
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
656
+ const viewerContext = mock<ViewerContext>();
657
+ const privacyPolicyEvaluationContext =
658
+ instance(
659
+ mock<
660
+ EntityPrivacyPolicyEvaluationContext<
661
+ TestFields,
662
+ string,
663
+ ViewerContext,
664
+ TestEntity,
665
+ keyof TestFields
666
+ >
667
+ >(),
668
+ );
669
+ const queryContext = StubQueryContextProvider.getQueryContext();
642
670
 
643
671
  const id1 = uuidv4();
644
672
  const id2 = uuidv4();
@@ -667,7 +695,8 @@ describe(EntityMutatorFactory, () => {
667
695
  const existingEntity = await enforceAsyncResult(
668
696
  entityLoaderFactory
669
697
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
670
- .loadByIDAsync(id2)
698
+ .withAuthorizationResults()
699
+ .loadByIDAsync(id2),
671
700
  );
672
701
 
673
702
  await entityMutatorFactory
@@ -690,13 +719,25 @@ describe(EntityMutatorFactory, () => {
690
719
  type: EntityMutationType.UPDATE,
691
720
  previousValue: existingEntity,
692
721
  cascadingDeleteCause: null,
693
- }
722
+ },
694
723
  );
695
724
  });
725
+
696
726
  it('executes validators', async () => {
697
- const viewerContext = mock<TestViewerContext>();
698
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
699
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
727
+ const viewerContext = mock<ViewerContext>();
728
+ const privacyPolicyEvaluationContext =
729
+ instance(
730
+ mock<
731
+ EntityPrivacyPolicyEvaluationContext<
732
+ TestFields,
733
+ string,
734
+ ViewerContext,
735
+ TestEntity,
736
+ keyof TestFields
737
+ >
738
+ >(),
739
+ );
740
+ const queryContext = StubQueryContextProvider.getQueryContext();
700
741
 
701
742
  const id1 = uuidv4();
702
743
  const id2 = uuidv4();
@@ -725,7 +766,8 @@ describe(EntityMutatorFactory, () => {
725
766
  const existingEntity = await enforceAsyncResult(
726
767
  entityLoaderFactory
727
768
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
728
- .loadByIDAsync(id2)
769
+ .withAuthorizationResults()
770
+ .loadByIDAsync(id2),
729
771
  );
730
772
 
731
773
  await entityMutatorFactory
@@ -739,13 +781,75 @@ describe(EntityMutatorFactory, () => {
739
781
  cascadingDeleteCause: null,
740
782
  });
741
783
  });
784
+
785
+ it('throws when id field is updated', async () => {
786
+ const viewerContext = mock<ViewerContext>();
787
+ const privacyPolicyEvaluationContext =
788
+ instance(
789
+ mock<
790
+ EntityPrivacyPolicyEvaluationContext<
791
+ TestFields,
792
+ string,
793
+ ViewerContext,
794
+ TestEntity,
795
+ keyof TestFields
796
+ >
797
+ >(),
798
+ );
799
+ const queryContext = StubQueryContextProvider.getQueryContext();
800
+
801
+ const id1 = uuidv4();
802
+ const { entityMutatorFactory, entityLoaderFactory } = createEntityMutatorFactory([
803
+ {
804
+ customIdField: id1,
805
+ stringField: 'huh',
806
+ testIndexedField: '4',
807
+ intField: 3,
808
+ dateField: new Date(),
809
+ nullableField: null,
810
+ },
811
+ ]);
812
+
813
+ const existingEntity = await enforceAsyncResult(
814
+ entityLoaderFactory
815
+ .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
816
+ .withAuthorizationResults()
817
+ .loadByIDAsync(id1),
818
+ );
819
+
820
+ await expect(
821
+ entityMutatorFactory
822
+ .forUpdate(existingEntity, queryContext)
823
+ .setField('customIdField', uuidv4())
824
+ .enforceUpdateAsync(),
825
+ ).rejects.toThrow('id field updates not supported: (entityClass = TestEntity)');
826
+
827
+ const reloadedEntity = await enforceAsyncResult(
828
+ entityLoaderFactory
829
+ .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
830
+ .withAuthorizationResults()
831
+ .loadByIDAsync(id1),
832
+ );
833
+ expect(reloadedEntity.getAllFields()).toMatchObject(existingEntity.getAllFields());
834
+ });
742
835
  });
743
836
 
744
837
  describe('forDelete', () => {
745
838
  it('deletes entities', async () => {
746
- const viewerContext = mock<TestViewerContext>();
747
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
748
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
839
+ const viewerContext = mock<ViewerContext>();
840
+ const privacyPolicyEvaluationContext =
841
+ instance(
842
+ mock<
843
+ EntityPrivacyPolicyEvaluationContext<
844
+ TestFields,
845
+ string,
846
+ ViewerContext,
847
+ TestEntity,
848
+ keyof TestFields
849
+ >
850
+ >(),
851
+ );
852
+ const queryContext = StubQueryContextProvider.getQueryContext();
749
853
 
750
854
  const id1 = uuidv4();
751
855
  const { entityMutatorFactory, entityLoaderFactory } = createEntityMutatorFactory([
@@ -762,7 +866,8 @@ describe(EntityMutatorFactory, () => {
762
866
  const existingEntity = await enforceAsyncResult(
763
867
  entityLoaderFactory
764
868
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
765
- .loadByIDAsync(id1)
869
+ .withAuthorizationResults()
870
+ .loadByIDAsync(id1),
766
871
  );
767
872
  expect(existingEntity).toBeTruthy();
768
873
 
@@ -772,15 +877,27 @@ describe(EntityMutatorFactory, () => {
772
877
  enforceAsyncResult(
773
878
  entityLoaderFactory
774
879
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
775
- .loadByIDAsync(id1)
776
- )
880
+ .withAuthorizationResults()
881
+ .loadByIDAsync(id1),
882
+ ),
777
883
  ).rejects.toBeInstanceOf(Error);
778
884
  });
779
885
 
780
886
  it('checks privacy', async () => {
781
- const viewerContext = mock<TestViewerContext>();
782
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
783
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
887
+ const viewerContext = mock<ViewerContext>();
888
+ const privacyPolicyEvaluationContext =
889
+ instance(
890
+ mock<
891
+ EntityPrivacyPolicyEvaluationContext<
892
+ TestFields,
893
+ string,
894
+ ViewerContext,
895
+ TestEntity,
896
+ keyof TestFields
897
+ >
898
+ >(),
899
+ );
900
+ const queryContext = StubQueryContextProvider.getQueryContext();
784
901
 
785
902
  const id1 = uuidv4();
786
903
  const { privacyPolicy, entityMutatorFactory, entityLoaderFactory } =
@@ -800,7 +917,8 @@ describe(EntityMutatorFactory, () => {
800
917
  const existingEntity = await enforceAsyncResult(
801
918
  entityLoaderFactory
802
919
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
803
- .loadByIDAsync(id1)
920
+ .withAuthorizationResults()
921
+ .loadByIDAsync(id1),
804
922
  );
805
923
 
806
924
  await entityMutatorFactory.forDelete(existingEntity, queryContext).enforceDeleteAsync();
@@ -811,15 +929,26 @@ describe(EntityMutatorFactory, () => {
811
929
  anyOfClass(EntityTransactionalQueryContext),
812
930
  anything(),
813
931
  anyOfClass(TestEntity),
814
- anything()
815
- )
932
+ anything(),
933
+ ),
816
934
  ).once();
817
935
  });
818
936
 
819
937
  it('executes triggers', async () => {
820
- const viewerContext = mock<TestViewerContext>();
821
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
822
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
938
+ const viewerContext = mock<ViewerContext>();
939
+ const privacyPolicyEvaluationContext =
940
+ instance(
941
+ mock<
942
+ EntityPrivacyPolicyEvaluationContext<
943
+ TestFields,
944
+ string,
945
+ ViewerContext,
946
+ TestEntity,
947
+ keyof TestFields
948
+ >
949
+ >(),
950
+ );
951
+ const queryContext = StubQueryContextProvider.getQueryContext();
823
952
 
824
953
  const id1 = uuidv4();
825
954
  const { mutationTriggers, entityMutatorFactory, entityLoaderFactory } =
@@ -839,7 +968,8 @@ describe(EntityMutatorFactory, () => {
839
968
  const existingEntity = await enforceAsyncResult(
840
969
  entityLoaderFactory
841
970
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
842
- .loadByIDAsync(id1)
971
+ .withAuthorizationResults()
972
+ .loadByIDAsync(id1),
843
973
  );
844
974
 
845
975
  await entityMutatorFactory.forDelete(existingEntity, queryContext).enforceDeleteAsync();
@@ -855,14 +985,25 @@ describe(EntityMutatorFactory, () => {
855
985
  beforeDelete: true,
856
986
  afterDelete: true,
857
987
  },
858
- { type: EntityMutationType.DELETE, cascadingDeleteCause: null }
988
+ { type: EntityMutationType.DELETE, cascadingDeleteCause: null },
859
989
  );
860
990
  });
861
991
 
862
992
  it('does not execute validators', async () => {
863
- const viewerContext = mock<TestViewerContext>();
864
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
865
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
993
+ const viewerContext = mock<ViewerContext>();
994
+ const privacyPolicyEvaluationContext =
995
+ instance(
996
+ mock<
997
+ EntityPrivacyPolicyEvaluationContext<
998
+ TestFields,
999
+ string,
1000
+ ViewerContext,
1001
+ TestEntity,
1002
+ keyof TestFields
1003
+ >
1004
+ >(),
1005
+ );
1006
+ const queryContext = StubQueryContextProvider.getQueryContext();
866
1007
 
867
1008
  const id1 = uuidv4();
868
1009
  const { mutationValidators, entityMutatorFactory, entityLoaderFactory } =
@@ -882,7 +1023,8 @@ describe(EntityMutatorFactory, () => {
882
1023
  const existingEntity = await enforceAsyncResult(
883
1024
  entityLoaderFactory
884
1025
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
885
- .loadByIDAsync(id1)
1026
+ .withAuthorizationResults()
1027
+ .loadByIDAsync(id1),
886
1028
  );
887
1029
 
888
1030
  await entityMutatorFactory.forDelete(existingEntity, queryContext).enforceDeleteAsync();
@@ -894,9 +1036,20 @@ describe(EntityMutatorFactory, () => {
894
1036
  });
895
1037
 
896
1038
  it('invalidates cache for fields upon create', async () => {
897
- const viewerContext = mock<TestViewerContext>();
898
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
899
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
1039
+ const viewerContext = mock<ViewerContext>();
1040
+ const privacyPolicyEvaluationContext =
1041
+ instance(
1042
+ mock<
1043
+ EntityPrivacyPolicyEvaluationContext<
1044
+ TestFields,
1045
+ string,
1046
+ ViewerContext,
1047
+ TestEntity,
1048
+ keyof TestFields
1049
+ >
1050
+ >(),
1051
+ );
1052
+ const queryContext = StubQueryContextProvider.getQueryContext();
900
1053
 
901
1054
  const id1 = uuidv4();
902
1055
  const { entityMutatorFactory, entityLoaderFactory } = createEntityMutatorFactory([
@@ -913,7 +1066,8 @@ describe(EntityMutatorFactory, () => {
913
1066
  const entites1 = await enforceResultsAsync(
914
1067
  entityLoaderFactory
915
1068
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
916
- .loadManyByFieldEqualingAsync('stringField', 'huh')
1069
+ .withAuthorizationResults()
1070
+ .loadManyByFieldEqualingAsync('stringField', 'huh'),
917
1071
  );
918
1072
  expect(entites1).toHaveLength(1);
919
1073
 
@@ -921,20 +1075,21 @@ describe(EntityMutatorFactory, () => {
921
1075
  entityMutatorFactory
922
1076
  .forCreate(viewerContext, queryContext)
923
1077
  .setField('stringField', 'huh')
924
- .createAsync()
1078
+ .createAsync(),
925
1079
  );
926
1080
 
927
1081
  const entities2 = await enforceResultsAsync(
928
1082
  entityLoaderFactory
929
1083
  .forLoad(viewerContext, queryContext, privacyPolicyEvaluationContext)
930
- .loadManyByFieldEqualingAsync('stringField', 'huh')
1084
+ .withAuthorizationResults()
1085
+ .loadManyByFieldEqualingAsync('stringField', 'huh'),
931
1086
  );
932
1087
  expect(entities2).toHaveLength(2);
933
1088
  });
934
1089
 
935
1090
  it('throws error when field not valid', async () => {
936
- const viewerContext = mock<TestViewerContext>();
937
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
1091
+ const viewerContext = mock<ViewerContext>();
1092
+ const queryContext = StubQueryContextProvider.getQueryContext();
938
1093
  const id1 = uuidv4();
939
1094
  const { entityMutatorFactory } = createEntityMutatorFactory([
940
1095
  {
@@ -951,7 +1106,7 @@ describe(EntityMutatorFactory, () => {
951
1106
  entityMutatorFactory
952
1107
  .forCreate(viewerContext, queryContext)
953
1108
  .setField('stringField', 10 as any)
954
- .createAsync()
1109
+ .createAsync(),
955
1110
  ).rejects.toThrowError('Entity field not valid: TestEntity (stringField = 10)');
956
1111
 
957
1112
  const createdEntity = await entityMutatorFactory
@@ -963,14 +1118,14 @@ describe(EntityMutatorFactory, () => {
963
1118
  entityMutatorFactory
964
1119
  .forUpdate(createdEntity, queryContext)
965
1120
  .setField('stringField', 10 as any)
966
- .updateAsync()
1121
+ .updateAsync(),
967
1122
  ).rejects.toThrowError('Entity field not valid: TestEntity (stringField = 10)');
968
1123
  });
969
1124
 
970
1125
  it('returns error result when not authorized to create', async () => {
971
1126
  const entityCompanionProvider = instance(mock(EntityCompanionProvider));
972
- const viewerContext = instance(mock(TestViewerContext));
973
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
1127
+ const viewerContext = instance(mock(ViewerContext));
1128
+ const queryContext = StubQueryContextProvider.getQueryContext();
974
1129
  const privacyPolicyMock = mock(SimpleTestEntityPrivacyPolicy);
975
1130
  const databaseAdapter = instance(mock<EntityDatabaseAdapter<SimpleTestFields>>());
976
1131
  const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
@@ -992,13 +1147,25 @@ describe(EntityMutatorFactory, () => {
992
1147
  EntityLoader<
993
1148
  SimpleTestFields,
994
1149
  string,
995
- TestViewerContext,
1150
+ ViewerContext,
996
1151
  SimpleTestEntity,
997
1152
  SimpleTestEntityPrivacyPolicy,
998
1153
  keyof SimpleTestFields
999
1154
  >
1000
1155
  >(EntityLoader);
1001
- when(entityLoaderMock.constructEntity(anything())).thenReturn(fakeEntity);
1156
+ const entityLoaderUtilsMock =
1157
+ mock<
1158
+ EntityLoaderUtils<
1159
+ SimpleTestFields,
1160
+ string,
1161
+ ViewerContext,
1162
+ SimpleTestEntity,
1163
+ SimpleTestEntityPrivacyPolicy,
1164
+ keyof SimpleTestFields
1165
+ >
1166
+ >(EntityLoaderUtils);
1167
+ when(entityLoaderUtilsMock.constructEntity(anything())).thenReturn(fakeEntity);
1168
+ when(entityLoaderMock.utils()).thenReturn(instance(entityLoaderUtilsMock));
1002
1169
  const entityLoader = instance(entityLoaderMock);
1003
1170
 
1004
1171
  const entityLoaderFactoryMock =
@@ -1006,7 +1173,7 @@ describe(EntityMutatorFactory, () => {
1006
1173
  EntityLoaderFactory<
1007
1174
  SimpleTestFields,
1008
1175
  string,
1009
- TestViewerContext,
1176
+ ViewerContext,
1010
1177
  SimpleTestEntity,
1011
1178
  SimpleTestEntityPrivacyPolicy,
1012
1179
  keyof SimpleTestFields
@@ -1016,8 +1183,8 @@ describe(EntityMutatorFactory, () => {
1016
1183
  entityLoaderFactoryMock.forLoad(
1017
1184
  viewerContext,
1018
1185
  anyOfClass(EntityTransactionalQueryContext),
1019
- anything()
1020
- )
1186
+ anything(),
1187
+ ),
1021
1188
  ).thenReturn(entityLoader);
1022
1189
  const entityLoaderFactory = instance(entityLoaderFactoryMock);
1023
1190
 
@@ -1029,8 +1196,8 @@ describe(EntityMutatorFactory, () => {
1029
1196
  anyOfClass(EntityTransactionalQueryContext),
1030
1197
  anything(),
1031
1198
  anyOfClass(SimpleTestEntity),
1032
- anything()
1033
- )
1199
+ anything(),
1200
+ ),
1034
1201
  ).thenReject(rejectionError);
1035
1202
  when(
1036
1203
  privacyPolicyMock.authorizeUpdateAsync(
@@ -1038,8 +1205,8 @@ describe(EntityMutatorFactory, () => {
1038
1205
  anyOfClass(EntityTransactionalQueryContext),
1039
1206
  anything(),
1040
1207
  anyOfClass(SimpleTestEntity),
1041
- anything()
1042
- )
1208
+ anything(),
1209
+ ),
1043
1210
  ).thenReject(rejectionError);
1044
1211
  when(
1045
1212
  privacyPolicyMock.authorizeDeleteAsync(
@@ -1047,8 +1214,8 @@ describe(EntityMutatorFactory, () => {
1047
1214
  anyOfClass(EntityTransactionalQueryContext),
1048
1215
  anything(),
1049
1216
  anyOfClass(SimpleTestEntity),
1050
- anything()
1051
- )
1217
+ anything(),
1218
+ ),
1052
1219
  ).thenReject(rejectionError);
1053
1220
 
1054
1221
  const entityMutatorFactory = new EntityMutatorFactory(
@@ -1060,7 +1227,7 @@ describe(EntityMutatorFactory, () => {
1060
1227
  {},
1061
1228
  entityLoaderFactory,
1062
1229
  databaseAdapter,
1063
- metricsAdapter
1230
+ metricsAdapter,
1064
1231
  );
1065
1232
 
1066
1233
  const entityCreateResult = await entityMutatorFactory
@@ -1093,8 +1260,8 @@ describe(EntityMutatorFactory, () => {
1093
1260
 
1094
1261
  const entityCompanionProvider = instance(entityCompanionProviderMock);
1095
1262
 
1096
- const viewerContext = instance(mock(TestViewerContext));
1097
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
1263
+ const viewerContext = instance(mock(ViewerContext));
1264
+ const queryContext = StubQueryContextProvider.getQueryContext();
1098
1265
  const privacyPolicy = instance(mock(SimpleTestEntityPrivacyPolicy));
1099
1266
  const databaseAdapterMock = mock<EntityDatabaseAdapter<SimpleTestFields>>();
1100
1267
  const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
@@ -1116,13 +1283,25 @@ describe(EntityMutatorFactory, () => {
1116
1283
  EntityLoader<
1117
1284
  SimpleTestFields,
1118
1285
  string,
1119
- TestViewerContext,
1286
+ ViewerContext,
1120
1287
  SimpleTestEntity,
1121
1288
  SimpleTestEntityPrivacyPolicy,
1122
1289
  keyof SimpleTestFields
1123
1290
  >
1124
1291
  >(EntityLoader);
1125
- when(entityLoaderMock.constructEntity(anything())).thenReturn(fakeEntity);
1292
+ const entityLoaderUtilsMock =
1293
+ mock<
1294
+ EntityLoaderUtils<
1295
+ SimpleTestFields,
1296
+ string,
1297
+ ViewerContext,
1298
+ SimpleTestEntity,
1299
+ SimpleTestEntityPrivacyPolicy,
1300
+ keyof SimpleTestFields
1301
+ >
1302
+ >(EntityLoaderUtils);
1303
+ when(entityLoaderUtilsMock.constructEntity(anything())).thenReturn(fakeEntity);
1304
+ when(entityLoaderMock.utils()).thenReturn(instance(entityLoaderUtilsMock));
1126
1305
  const entityLoader = instance(entityLoaderMock);
1127
1306
 
1128
1307
  const entityLoaderFactoryMock =
@@ -1130,7 +1309,7 @@ describe(EntityMutatorFactory, () => {
1130
1309
  EntityLoaderFactory<
1131
1310
  SimpleTestFields,
1132
1311
  string,
1133
- TestViewerContext,
1312
+ ViewerContext,
1134
1313
  SimpleTestEntity,
1135
1314
  SimpleTestEntityPrivacyPolicy,
1136
1315
  keyof SimpleTestFields
@@ -1140,30 +1319,30 @@ describe(EntityMutatorFactory, () => {
1140
1319
  entityLoaderFactoryMock.forLoad(
1141
1320
  viewerContext,
1142
1321
  anyOfClass(EntityTransactionalQueryContext),
1143
- anything()
1144
- )
1322
+ anything(),
1323
+ ),
1145
1324
  ).thenReturn(entityLoader);
1146
1325
  const entityLoaderFactory = instance(entityLoaderFactoryMock);
1147
1326
 
1148
1327
  const rejectionError = new Error();
1149
1328
 
1150
1329
  when(
1151
- databaseAdapterMock.insertAsync(anyOfClass(EntityTransactionalQueryContext), anything())
1330
+ databaseAdapterMock.insertAsync(anyOfClass(EntityTransactionalQueryContext), anything()),
1152
1331
  ).thenReject(rejectionError);
1153
1332
  when(
1154
1333
  databaseAdapterMock.updateAsync(
1155
1334
  anyOfClass(EntityTransactionalQueryContext),
1156
1335
  anything(),
1157
1336
  anything(),
1158
- anything()
1159
- )
1337
+ anything(),
1338
+ ),
1160
1339
  ).thenReject(rejectionError);
1161
1340
  when(
1162
1341
  databaseAdapterMock.deleteAsync(
1163
1342
  anyOfClass(EntityTransactionalQueryContext),
1164
1343
  anything(),
1165
- anything()
1166
- )
1344
+ anything(),
1345
+ ),
1167
1346
  ).thenReject(rejectionError);
1168
1347
 
1169
1348
  const entityMutatorFactory = new EntityMutatorFactory(
@@ -1175,23 +1354,23 @@ describe(EntityMutatorFactory, () => {
1175
1354
  {},
1176
1355
  entityLoaderFactory,
1177
1356
  instance(databaseAdapterMock),
1178
- metricsAdapter
1357
+ metricsAdapter,
1179
1358
  );
1180
1359
 
1181
1360
  await expect(
1182
- entityMutatorFactory.forCreate(viewerContext, queryContext).createAsync()
1361
+ entityMutatorFactory.forCreate(viewerContext, queryContext).createAsync(),
1183
1362
  ).rejects.toEqual(rejectionError);
1184
1363
  await expect(
1185
- entityMutatorFactory.forUpdate(fakeEntity, queryContext).updateAsync()
1364
+ entityMutatorFactory.forUpdate(fakeEntity, queryContext).updateAsync(),
1186
1365
  ).rejects.toEqual(rejectionError);
1187
1366
  await expect(
1188
- entityMutatorFactory.forDelete(fakeEntity, queryContext).deleteAsync()
1367
+ entityMutatorFactory.forDelete(fakeEntity, queryContext).deleteAsync(),
1189
1368
  ).rejects.toEqual(rejectionError);
1190
1369
  });
1191
1370
 
1192
1371
  it('records metrics appropriately', async () => {
1193
- const viewerContext = mock<TestViewerContext>();
1194
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
1372
+ const viewerContext = mock<ViewerContext>();
1373
+ const queryContext = StubQueryContextProvider.getQueryContext();
1195
1374
  const { entityMutatorFactory, metricsAdapter } = createEntityMutatorFactory([]);
1196
1375
  const spiedMetricsAdapter = spy(metricsAdapter);
1197
1376
 
@@ -1199,14 +1378,14 @@ describe(EntityMutatorFactory, () => {
1199
1378
  entityMutatorFactory
1200
1379
  .forCreate(viewerContext, queryContext)
1201
1380
  .setField('stringField', 'huh')
1202
- .createAsync()
1381
+ .createAsync(),
1203
1382
  );
1204
1383
 
1205
1384
  await enforceAsyncResult(
1206
1385
  entityMutatorFactory
1207
1386
  .forUpdate(newEntity, queryContext)
1208
1387
  .setField('stringField', 'wat')
1209
- .updateAsync()
1388
+ .updateAsync(),
1210
1389
  );
1211
1390
 
1212
1391
  await enforceAsyncResult(entityMutatorFactory.forDelete(newEntity, queryContext).deleteAsync());
@@ -1216,24 +1395,24 @@ describe(EntityMutatorFactory, () => {
1216
1395
  objectContaining({
1217
1396
  type: EntityMetricsMutationType.CREATE,
1218
1397
  entityClassName: TestEntity.name,
1219
- })
1220
- )
1398
+ }),
1399
+ ),
1221
1400
  ).once();
1222
1401
  verify(
1223
1402
  spiedMetricsAdapter.logMutatorMutationEvent(
1224
1403
  objectContaining({
1225
1404
  type: EntityMetricsMutationType.UPDATE,
1226
1405
  entityClassName: TestEntity.name,
1227
- })
1228
- )
1406
+ }),
1407
+ ),
1229
1408
  ).once();
1230
1409
  verify(
1231
1410
  spiedMetricsAdapter.logMutatorMutationEvent(
1232
1411
  objectContaining({
1233
1412
  type: EntityMetricsMutationType.DELETE,
1234
1413
  entityClassName: TestEntity.name,
1235
- })
1236
- )
1414
+ }),
1415
+ ),
1237
1416
  ).once();
1238
1417
  verify(spiedMetricsAdapter.logMutatorMutationEvent(anything())).thrice();
1239
1418
  });