@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
@@ -18,12 +18,17 @@ import TestViewerContext from '../testfixtures/TestViewerContext';
18
18
  import { InMemoryFullCacheStubCacheAdapter } from '../utils/testing/StubCacheAdapter';
19
19
  import { createUnitTestEntityCompanionProvider } from '../utils/testing/createUnitTestEntityCompanionProvider';
20
20
 
21
+ interface OtherFields {
22
+ id: string;
23
+ }
24
+
21
25
  interface ParentFields {
22
26
  id: string;
23
27
  }
24
28
 
25
29
  interface ChildFields {
26
30
  id: string;
31
+ unused_other_edge_id: string | null;
27
32
  parent_id: string;
28
33
  }
29
34
 
@@ -80,12 +85,18 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
80
85
  async evaluateAsync(
81
86
  _viewerContext: TestViewerContext,
82
87
  _queryContext: EntityQueryContext,
83
- evaluationContext: EntityPrivacyPolicyEvaluationContext,
84
- entity: any
88
+ evaluationContext: EntityPrivacyPolicyEvaluationContext<
89
+ any,
90
+ string,
91
+ TestViewerContext,
92
+ any,
93
+ any
94
+ >,
95
+ entity: any,
85
96
  ): Promise<RuleEvaluationResult> {
86
97
  if (privacyPolicyEvaluationRecords.shouldRecord) {
87
98
  (privacyPolicyEvaluationRecords as any)[entity.constructor.name][this.action].push(
88
- evaluationContext
99
+ evaluationContext,
89
100
  );
90
101
  }
91
102
  return RuleEvaluationResult.ALLOW;
@@ -123,7 +134,12 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
123
134
  _viewerContext: TestViewerContext,
124
135
  _queryContext: EntityTransactionalQueryContext,
125
136
  _entity: ParentEntity,
126
- mutationInfo: EntityTriggerMutationInfo<ParentFields, string, TestViewerContext, ParentEntity>
137
+ mutationInfo: EntityTriggerMutationInfo<
138
+ ParentFields,
139
+ string,
140
+ TestViewerContext,
141
+ ParentEntity
142
+ >,
127
143
  ): Promise<void> {
128
144
  invariant(mutationInfo.type === EntityMutationType.DELETE, 'invalid EntityMutationType');
129
145
  if (mutationInfo.cascadingDeleteCause !== null) {
@@ -144,7 +160,12 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
144
160
  _viewerContext: TestViewerContext,
145
161
  _queryContext: EntityTransactionalQueryContext,
146
162
  _entity: ParentEntity,
147
- mutationInfo: EntityTriggerMutationInfo<ParentFields, string, TestViewerContext, ParentEntity>
163
+ mutationInfo: EntityTriggerMutationInfo<
164
+ ParentFields,
165
+ string,
166
+ TestViewerContext,
167
+ ParentEntity
168
+ >,
148
169
  ): Promise<void> {
149
170
  invariant(mutationInfo.type === EntityMutationType.UPDATE, 'invalid EntityMutationType');
150
171
  if (mutationInfo.cascadingDeleteCause !== null) {
@@ -165,7 +186,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
165
186
  _viewerContext: TestViewerContext,
166
187
  _queryContext: EntityTransactionalQueryContext,
167
188
  _entity: ChildEntity,
168
- mutationInfo: EntityTriggerMutationInfo<ChildFields, string, TestViewerContext, ChildEntity>
189
+ mutationInfo: EntityTriggerMutationInfo<ChildFields, string, TestViewerContext, ChildEntity>,
169
190
  ): Promise<void> {
170
191
  invariant(mutationInfo.type === EntityMutationType.DELETE, 'invalid EntityMutationType');
171
192
  if (mutationInfo.cascadingDeleteCause === null) {
@@ -197,7 +218,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
197
218
  _viewerContext: TestViewerContext,
198
219
  _queryContext: EntityTransactionalQueryContext,
199
220
  _entity: ChildEntity,
200
- mutationInfo: EntityTriggerMutationInfo<ChildFields, string, TestViewerContext, ChildEntity>
221
+ mutationInfo: EntityTriggerMutationInfo<ChildFields, string, TestViewerContext, ChildEntity>,
201
222
  ): Promise<void> {
202
223
  invariant(mutationInfo.type === EntityMutationType.UPDATE, 'invalid EntityMutationType');
203
224
  if (mutationInfo.cascadingDeleteCause === null) {
@@ -234,7 +255,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
234
255
  string,
235
256
  TestViewerContext,
236
257
  GrandChildEntity
237
- >
258
+ >,
238
259
  ): Promise<void> {
239
260
  invariant(mutationInfo.type === EntityMutationType.DELETE, 'invalid EntityMutationType');
240
261
  if (mutationInfo.cascadingDeleteCause === null) {
@@ -244,7 +265,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
244
265
  const cascadingDeleteCauseEntity = mutationInfo.cascadingDeleteCause.entity;
245
266
  if (!(cascadingDeleteCauseEntity instanceof ChildEntity)) {
246
267
  throw new Error(
247
- 'GrandChild entity should have cascade delete cause entity of type ChildEntity'
268
+ 'GrandChild entity should have cascade delete cause entity of type ChildEntity',
248
269
  );
249
270
  }
250
271
 
@@ -257,7 +278,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
257
278
  const secondLevelCascadingDeleteCauseEntity = secondLevelCascadingDeleteCause.entity;
258
279
  if (!(secondLevelCascadingDeleteCauseEntity instanceof ParentEntity)) {
259
280
  throw new Error(
260
- 'GrandChild entity should have second level casade delete cause entity of type ParentEntity'
281
+ 'GrandChild entity should have second level casade delete cause entity of type ParentEntity',
261
282
  );
262
283
  }
263
284
 
@@ -285,7 +306,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
285
306
  string,
286
307
  TestViewerContext,
287
308
  GrandChildEntity
288
- >
309
+ >,
289
310
  ): Promise<void> {
290
311
  invariant(mutationInfo.type === EntityMutationType.UPDATE, 'invalid EntityMutationType');
291
312
  if (mutationInfo.cascadingDeleteCause === null) {
@@ -295,7 +316,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
295
316
  const cascadingDeleteCauseEntity = mutationInfo.cascadingDeleteCause.entity;
296
317
  if (!(cascadingDeleteCauseEntity instanceof ChildEntity)) {
297
318
  throw new Error(
298
- 'GrandChild entity should have cascade delete cause entity of type ChildEntity'
319
+ 'GrandChild entity should have cascade delete cause entity of type ChildEntity',
299
320
  );
300
321
  }
301
322
 
@@ -308,7 +329,7 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
308
329
  const secondLevelCascadingDeleteCauseEntity = secondLevelCascadingDeleteCause.entity;
309
330
  if (!(secondLevelCascadingDeleteCauseEntity instanceof ParentEntity)) {
310
331
  throw new Error(
311
- 'GrandChild entity should have second level casade delete cause entity of type ParentEntity'
332
+ 'GrandChild entity should have second level casade delete cause entity of type ParentEntity',
312
333
  );
313
334
  }
314
335
 
@@ -321,6 +342,22 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
321
342
  }
322
343
  }
323
344
 
345
+ class OtherEntity extends Entity<OtherFields, string, TestViewerContext> {
346
+ static defineCompanionDefinition(): EntityCompanionDefinition<
347
+ OtherFields,
348
+ string,
349
+ TestViewerContext,
350
+ OtherEntity,
351
+ TestEntityPrivacyPolicy
352
+ > {
353
+ return {
354
+ entityClass: ParentEntity,
355
+ entityConfiguration: otherEntityConfiguration,
356
+ privacyPolicyClass: TestEntityPrivacyPolicy,
357
+ };
358
+ }
359
+ }
360
+
324
361
  class ParentEntity extends Entity<ParentFields, string, TestViewerContext> {
325
362
  static defineCompanionDefinition(): EntityCompanionDefinition<
326
363
  ParentFields,
@@ -390,6 +427,19 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
390
427
  }
391
428
  }
392
429
 
430
+ const otherEntityConfiguration = new EntityConfiguration<OtherFields>({
431
+ idField: 'id',
432
+ tableName: 'others',
433
+ schema: {
434
+ id: new UUIDField({
435
+ columnName: 'id',
436
+ cache: true,
437
+ }),
438
+ },
439
+ databaseAdapterFlavor: 'postgres',
440
+ cacheAdapterFlavor: 'redis',
441
+ });
442
+
393
443
  const parentEntityConfiguration = new EntityConfiguration<ParentFields>({
394
444
  idField: 'id',
395
445
  tableName: 'parents',
@@ -413,11 +463,19 @@ const makeEntityClasses = (edgeDeletionBehavior: EntityEdgeDeletionBehavior) =>
413
463
  columnName: 'id',
414
464
  cache: true,
415
465
  }),
466
+ unused_other_edge_id: new UUIDField({
467
+ columnName: 'unused_other_edge_id',
468
+ association: {
469
+ associatedEntityClass: OtherEntity,
470
+ edgeDeletionBehavior,
471
+ },
472
+ }),
416
473
  parent_id: new UUIDField({
417
474
  columnName: 'parent_id',
418
475
  cache: true,
419
476
  association: {
420
477
  associatedEntityClass: ParentEntity,
478
+ associatedEntityLookupByField: 'id', // sanity check that this functionality works by using it for one edge
421
479
  edgeDeletionBehavior,
422
480
  },
423
481
  }),
@@ -469,54 +527,40 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
469
527
  const companionProvider = createUnitTestEntityCompanionProvider();
470
528
  const viewerContext = new TestViewerContext(companionProvider);
471
529
 
472
- const parent = await ParentEntity.creator(
473
- viewerContext,
474
- viewerContext.getQueryContext()
475
- ).enforceCreateAsync();
476
- const child = await ChildEntity.creator(viewerContext, viewerContext.getQueryContext())
530
+ const parent = await ParentEntity.creator(viewerContext).enforceCreateAsync();
531
+ const child = await ChildEntity.creator(viewerContext)
477
532
  .setField('parent_id', parent.getID())
478
533
  .enforceCreateAsync();
479
- const grandchild = await GrandChildEntity.creator(
480
- viewerContext,
481
- viewerContext.getQueryContext()
482
- )
534
+ const grandchild = await GrandChildEntity.creator(viewerContext)
483
535
  .setField('parent_id', child.getID())
484
536
  .enforceCreateAsync();
485
537
 
486
538
  await expect(
487
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
488
- .enforcing()
489
- .loadByIDNullableAsync(parent.getID())
539
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
490
540
  ).resolves.not.toBeNull();
491
541
  await expect(
492
- ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
493
- .enforcing()
494
- .loadByIDNullableAsync(child.getID())
542
+ ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()),
495
543
  ).resolves.not.toBeNull();
496
544
  await expect(
497
- GrandChildEntity.loader(viewerContext, viewerContext.getQueryContext())
545
+ GrandChildEntity.loader(viewerContext)
498
546
  .enforcing()
499
- .loadByIDNullableAsync(grandchild.getID())
547
+ .loadByIDNullableAsync(grandchild.getID()),
500
548
  ).resolves.not.toBeNull();
501
549
 
502
550
  privacyPolicyEvaluationRecords.shouldRecord = true;
503
- await ParentEntity.enforceDeleteAsync(parent, viewerContext.getQueryContext());
551
+ await ParentEntity.enforceDeleteAsync(parent);
504
552
  privacyPolicyEvaluationRecords.shouldRecord = false;
505
553
 
506
554
  await expect(
507
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
508
- .enforcing()
509
- .loadByIDNullableAsync(parent.getID())
555
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
510
556
  ).resolves.toBeNull();
511
557
  await expect(
512
- ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
513
- .enforcing()
514
- .loadByIDNullableAsync(child.getID())
558
+ ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()),
515
559
  ).resolves.toBeNull();
516
560
  await expect(
517
- GrandChildEntity.loader(viewerContext, viewerContext.getQueryContext())
561
+ GrandChildEntity.loader(viewerContext)
518
562
  .enforcing()
519
- .loadByIDNullableAsync(grandchild.getID())
563
+ .loadByIDNullableAsync(grandchild.getID()),
520
564
  ).resolves.toBeNull();
521
565
 
522
566
  // two calls for each trigger, one beforeDelete, one afterDelete
@@ -605,55 +649,40 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
605
649
  const companionProvider = createUnitTestEntityCompanionProvider();
606
650
  const viewerContext = new TestViewerContext(companionProvider);
607
651
 
608
- const parent = await ParentEntity.creator(
609
- viewerContext,
610
- viewerContext.getQueryContext()
611
- ).enforceCreateAsync();
612
- const child = await ChildEntity.creator(viewerContext, viewerContext.getQueryContext())
652
+ const parent = await ParentEntity.creator(viewerContext).enforceCreateAsync();
653
+ const child = await ChildEntity.creator(viewerContext)
613
654
  .setField('parent_id', parent.getID())
614
655
  .enforceCreateAsync();
615
- const grandchild = await GrandChildEntity.creator(
616
- viewerContext,
617
- viewerContext.getQueryContext()
618
- )
656
+ const grandchild = await GrandChildEntity.creator(viewerContext)
619
657
  .setField('parent_id', child.getID())
620
658
  .enforceCreateAsync();
621
659
 
622
660
  await expect(
623
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
624
- .enforcing()
625
- .loadByIDNullableAsync(parent.getID())
661
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
626
662
  ).resolves.not.toBeNull();
627
663
  await expect(
628
- ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
629
- .enforcing()
630
- .loadByIDNullableAsync(child.getID())
664
+ ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()),
631
665
  ).resolves.not.toBeNull();
632
666
  await expect(
633
- GrandChildEntity.loader(viewerContext, viewerContext.getQueryContext())
667
+ GrandChildEntity.loader(viewerContext)
634
668
  .enforcing()
635
- .loadByIDNullableAsync(grandchild.getID())
669
+ .loadByIDNullableAsync(grandchild.getID()),
636
670
  ).resolves.not.toBeNull();
637
671
 
638
672
  privacyPolicyEvaluationRecords.shouldRecord = true;
639
- await ParentEntity.enforceDeleteAsync(parent, viewerContext.getQueryContext());
673
+ await ParentEntity.enforceDeleteAsync(parent);
640
674
  privacyPolicyEvaluationRecords.shouldRecord = false;
641
675
 
642
676
  await expect(
643
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
644
- .enforcing()
645
- .loadByIDNullableAsync(parent.getID())
677
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
646
678
  ).resolves.toBeNull();
647
679
 
648
- const loadedChild = await ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
680
+ const loadedChild = await ChildEntity.loader(viewerContext)
649
681
  .enforcing()
650
682
  .loadByIDAsync(child.getID());
651
683
  expect(loadedChild.getField('parent_id')).toBeNull();
652
684
 
653
- const loadedGrandchild = await GrandChildEntity.loader(
654
- viewerContext,
655
- viewerContext.getQueryContext()
656
- )
685
+ const loadedGrandchild = await GrandChildEntity.loader(viewerContext)
657
686
  .enforcing()
658
687
  .loadByIDAsync(grandchild.getID());
659
688
  expect(loadedGrandchild.getField('parent_id')).toEqual(loadedChild.getID());
@@ -733,34 +762,26 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
733
762
  const companionProvider = createUnitTestEntityCompanionProvider();
734
763
  const viewerContext = new TestViewerContext(companionProvider);
735
764
 
736
- const parent = await ParentEntity.creator(
737
- viewerContext,
738
- viewerContext.getQueryContext()
739
- ).enforceCreateAsync();
740
- const child = await ChildEntity.creator(viewerContext, viewerContext.getQueryContext())
765
+ const parent = await ParentEntity.creator(viewerContext).enforceCreateAsync();
766
+ const child = await ChildEntity.creator(viewerContext)
741
767
  .setField('parent_id', parent.getID())
742
768
  .enforceCreateAsync();
743
- const grandchild = await GrandChildEntity.creator(
744
- viewerContext,
745
- viewerContext.getQueryContext()
746
- )
769
+ const grandchild = await GrandChildEntity.creator(viewerContext)
747
770
  .setField('parent_id', child.getID())
748
771
  .enforceCreateAsync();
749
772
 
750
773
  await expect(
751
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
752
- .enforcing()
753
- .loadByIDNullableAsync(parent.getID())
774
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
754
775
  ).resolves.not.toBeNull();
755
776
  await expect(
756
- ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
777
+ ChildEntity.loader(viewerContext)
757
778
  .enforcing()
758
- .loadByFieldEqualingAsync('parent_id', parent.getID())
779
+ .loadByFieldEqualingAsync('parent_id', parent.getID()),
759
780
  ).resolves.not.toBeNull();
760
781
  await expect(
761
- GrandChildEntity.loader(viewerContext, viewerContext.getQueryContext())
782
+ GrandChildEntity.loader(viewerContext)
762
783
  .enforcing()
763
- .loadByFieldEqualingAsync('parent_id', child.getID())
784
+ .loadByFieldEqualingAsync('parent_id', child.getID()),
764
785
  ).resolves.not.toBeNull();
765
786
 
766
787
  const childCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass(ChildEntity)[
@@ -772,7 +793,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
772
793
  expect(childCachedBefore.get(parent.getID())?.status).toEqual(CacheStatus.HIT);
773
794
 
774
795
  const grandChildCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass(
775
- GrandChildEntity
796
+ GrandChildEntity,
776
797
  )['entityCompanion']['tableDataCoordinator'][
777
798
  'cacheAdapter'
778
799
  ] as InMemoryFullCacheStubCacheAdapter<ChildFields>;
@@ -782,7 +803,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
782
803
  expect(grandChildCachedBefore.get(child.getID())?.status).toEqual(CacheStatus.HIT);
783
804
 
784
805
  privacyPolicyEvaluationRecords.shouldRecord = true;
785
- await ParentEntity.enforceDeleteAsync(parent, viewerContext.getQueryContext());
806
+ await ParentEntity.enforceDeleteAsync(parent);
786
807
  privacyPolicyEvaluationRecords.shouldRecord = false;
787
808
 
788
809
  const childCachedAfter = await childCacheAdapter.loadManyAsync('parent_id', [parent.getID()]);
@@ -794,20 +815,15 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
794
815
  expect(grandChildCachedAfter.get(child.getID())?.status).toEqual(CacheStatus.HIT);
795
816
 
796
817
  await expect(
797
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
798
- .enforcing()
799
- .loadByIDNullableAsync(parent.getID())
818
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
800
819
  ).resolves.toBeNull();
801
820
 
802
- const loadedChild = await ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
821
+ const loadedChild = await ChildEntity.loader(viewerContext)
803
822
  .enforcing()
804
823
  .loadByIDAsync(child.getID());
805
824
  expect(loadedChild).not.toBeNull();
806
825
 
807
- const loadedGrandchild = await GrandChildEntity.loader(
808
- viewerContext,
809
- viewerContext.getQueryContext()
810
- )
826
+ const loadedGrandchild = await GrandChildEntity.loader(viewerContext)
811
827
  .enforcing()
812
828
  .loadByIDAsync(grandchild.getID());
813
829
  expect(loadedGrandchild.getField('parent_id')).toEqual(loadedChild.getID());
@@ -835,7 +851,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
835
851
  ChildEntity: {
836
852
  [EntityAuthorizationAction.CREATE]: [],
837
853
 
838
- // one READ auth action for child in order to update via cascade
854
+ // two READs auth action for child in order to update via cascade
839
855
  // no other entities are read since it is not cascaded past first entity
840
856
  [EntityAuthorizationAction.READ]: [
841
857
  {
@@ -844,6 +860,12 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
844
860
  cascadingDeleteCause: null,
845
861
  },
846
862
  },
863
+ {
864
+ cascadingDeleteCause: {
865
+ entity: expect.any(ParentEntity),
866
+ cascadingDeleteCause: null,
867
+ },
868
+ },
847
869
  ],
848
870
  // one UPDATE to set null
849
871
  [EntityAuthorizationAction.UPDATE]: [
@@ -879,34 +901,26 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
879
901
  const companionProvider = createUnitTestEntityCompanionProvider();
880
902
  const viewerContext = new TestViewerContext(companionProvider);
881
903
 
882
- const parent = await ParentEntity.creator(
883
- viewerContext,
884
- viewerContext.getQueryContext()
885
- ).enforceCreateAsync();
886
- const child = await ChildEntity.creator(viewerContext, viewerContext.getQueryContext())
904
+ const parent = await ParentEntity.creator(viewerContext).enforceCreateAsync();
905
+ const child = await ChildEntity.creator(viewerContext)
887
906
  .setField('parent_id', parent.getID())
888
907
  .enforceCreateAsync();
889
- const grandchild = await GrandChildEntity.creator(
890
- viewerContext,
891
- viewerContext.getQueryContext()
892
- )
908
+ const grandchild = await GrandChildEntity.creator(viewerContext)
893
909
  .setField('parent_id', child.getID())
894
910
  .enforceCreateAsync();
895
911
 
896
912
  await expect(
897
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
898
- .enforcing()
899
- .loadByIDNullableAsync(parent.getID())
913
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
900
914
  ).resolves.not.toBeNull();
901
915
  await expect(
902
- ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
916
+ ChildEntity.loader(viewerContext)
903
917
  .enforcing()
904
- .loadByFieldEqualingAsync('parent_id', parent.getID())
918
+ .loadByFieldEqualingAsync('parent_id', parent.getID()),
905
919
  ).resolves.not.toBeNull();
906
920
  await expect(
907
- GrandChildEntity.loader(viewerContext, viewerContext.getQueryContext())
921
+ GrandChildEntity.loader(viewerContext)
908
922
  .enforcing()
909
- .loadByFieldEqualingAsync('parent_id', child.getID())
923
+ .loadByFieldEqualingAsync('parent_id', child.getID()),
910
924
  ).resolves.not.toBeNull();
911
925
 
912
926
  const childCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass(ChildEntity)[
@@ -918,7 +932,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
918
932
  expect(childCachedBefore.get(parent.getID())?.status).toEqual(CacheStatus.HIT);
919
933
 
920
934
  const grandChildCacheAdapter = viewerContext.getViewerScopedEntityCompanionForClass(
921
- GrandChildEntity
935
+ GrandChildEntity,
922
936
  )['entityCompanion']['tableDataCoordinator'][
923
937
  'cacheAdapter'
924
938
  ] as InMemoryFullCacheStubCacheAdapter<ChildFields>;
@@ -928,7 +942,7 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
928
942
  expect(grandChildCachedBefore.get(child.getID())?.status).toEqual(CacheStatus.HIT);
929
943
 
930
944
  privacyPolicyEvaluationRecords.shouldRecord = true;
931
- await ParentEntity.enforceDeleteAsync(parent, viewerContext.getQueryContext());
945
+ await ParentEntity.enforceDeleteAsync(parent);
932
946
  privacyPolicyEvaluationRecords.shouldRecord = false;
933
947
 
934
948
  const childCachedAfter = await childCacheAdapter.loadManyAsync('parent_id', [parent.getID()]);
@@ -940,19 +954,15 @@ describe('EntityMutator.processEntityDeletionForInboundEdgesAsync', () => {
940
954
  expect(grandChildCachedAfter.get(child.getID())?.status).toEqual(CacheStatus.MISS);
941
955
 
942
956
  await expect(
943
- ParentEntity.loader(viewerContext, viewerContext.getQueryContext())
944
- .enforcing()
945
- .loadByIDNullableAsync(parent.getID())
957
+ ParentEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(parent.getID()),
946
958
  ).resolves.toBeNull();
947
959
  await expect(
948
- ChildEntity.loader(viewerContext, viewerContext.getQueryContext())
949
- .enforcing()
950
- .loadByIDNullableAsync(child.getID())
960
+ ChildEntity.loader(viewerContext).enforcing().loadByIDNullableAsync(child.getID()),
951
961
  ).resolves.not.toBeNull();
952
962
  await expect(
953
- GrandChildEntity.loader(viewerContext, viewerContext.getQueryContext())
963
+ GrandChildEntity.loader(viewerContext)
954
964
  .enforcing()
955
- .loadByIDNullableAsync(grandchild.getID())
965
+ .loadByIDNullableAsync(grandchild.getID()),
956
966
  ).resolves.not.toBeNull();
957
967
 
958
968
  // two calls for each trigger, one beforeDelete, one afterDelete
@@ -11,6 +11,7 @@ import {
11
11
  StringArrayField,
12
12
  JSONObjectField,
13
13
  EnumField,
14
+ StrictEnumField,
14
15
  } from '../EntityFields';
15
16
  import describeFieldTestCase from '../utils/testing/describeFieldTestCase';
16
17
 
@@ -62,7 +63,7 @@ describeFieldTestCase(
62
63
  uuidv5('wat', uuidv5.DNS),
63
64
  /* UUIDv7 */ '018ebfda-dc80-782d-a891-22a0aa057d52',
64
65
  ],
65
- [uuidv4().replace('-', ''), '', 'hello']
66
+ [uuidv4().replace('-', ''), '', 'hello'],
66
67
  );
67
68
  describeFieldTestCase(new DateField({ columnName: 'wat' }), [new Date()], [Date.now()]);
68
69
  describeFieldTestCase(new BooleanField({ columnName: 'wat' }), [true, false], [0, 1, '']);
@@ -71,7 +72,18 @@ describeFieldTestCase(new FloatField({ columnName: 'wat' }), [1, 0.5, -0.5], ['1
71
72
  describeFieldTestCase(
72
73
  new StringArrayField({ columnName: 'wat' }),
73
74
  [[['what']] as any, [[]] as any], // jest test cases need extra wrapping array
74
- ['hello']
75
+ ['hello'],
75
76
  );
76
77
  describeFieldTestCase(new JSONObjectField({ columnName: 'wat' }), [{}], [true, 'hello']);
77
78
  describeFieldTestCase(new EnumField({ columnName: 'wat' }), ['hello', 1], [true]);
79
+
80
+ enum TestEnum {
81
+ HELLO = 'world',
82
+ WHO = 'wat',
83
+ }
84
+
85
+ describeFieldTestCase(
86
+ new StrictEnumField({ columnName: 'wat', enum: TestEnum }),
87
+ [TestEnum.HELLO, TestEnum.WHO, 'world'],
88
+ ['what', 1, true],
89
+ );
@@ -121,9 +121,20 @@ export default class TestEntity extends Entity<
121
121
  describe(EntityLoader, () => {
122
122
  it('handles thrown errors and literals from constructor', async () => {
123
123
  const viewerContext = instance(mock(ViewerContext));
124
- const privacyPolicyEvaluationContext = instance(mock<EntityPrivacyPolicyEvaluationContext>());
124
+ const privacyPolicyEvaluationContext =
125
+ instance(
126
+ mock<
127
+ EntityPrivacyPolicyEvaluationContext<
128
+ TestFields,
129
+ string,
130
+ ViewerContext,
131
+ TestEntity,
132
+ TestFieldSelection
133
+ >
134
+ >(),
135
+ );
125
136
  const metricsAdapter = instance(mock<IEntityMetricsAdapter>());
126
- const queryContext = StubQueryContextProvider.getNonTransactionalQueryContext();
137
+ const queryContext = StubQueryContextProvider.getQueryContext();
127
138
 
128
139
  const databaseAdapter = new StubDatabaseAdapter<TestFields>(
129
140
  testEntityConfiguration,
@@ -141,8 +152,8 @@ describe(EntityLoader, () => {
141
152
  },
142
153
  ],
143
154
  ],
144
- ])
145
- )
155
+ ]),
156
+ ),
146
157
  );
147
158
  const privacyPolicy = new TestEntityPrivacyPolicy();
148
159
  const cacheAdapterProvider = new NoCacheStubCacheAdapterProvider();
@@ -153,7 +164,7 @@ describe(EntityLoader, () => {
153
164
  entityCache,
154
165
  StubQueryContextProvider,
155
166
  metricsAdapter,
156
- TestEntity.name
167
+ TestEntity.name,
157
168
  );
158
169
  const entityLoader = new EntityLoader(
159
170
  viewerContext,
@@ -164,19 +175,21 @@ describe(EntityLoader, () => {
164
175
  /* entitySelectedFields */ undefined,
165
176
  privacyPolicy,
166
177
  dataManager,
167
- metricsAdapter
178
+ metricsAdapter,
168
179
  );
169
180
 
170
181
  let capturedThrownThing1: any;
171
182
  try {
172
- await entityLoader.loadByIDAsync(ID_SENTINEL_THROW_LITERAL);
183
+ await entityLoader.withAuthorizationResults().loadByIDAsync(ID_SENTINEL_THROW_LITERAL);
173
184
  } catch (e) {
174
185
  capturedThrownThing1 = e;
175
186
  }
176
187
  expect(capturedThrownThing1).not.toBeInstanceOf(Error);
177
188
  expect(capturedThrownThing1).toEqual('hello');
178
189
 
179
- const result = await entityLoader.loadByIDAsync(ID_SENTINEL_THROW_ERROR);
190
+ const result = await entityLoader
191
+ .withAuthorizationResults()
192
+ .loadByIDAsync(ID_SENTINEL_THROW_ERROR);
180
193
  expect(result.ok).toBe(false);
181
194
  expect(result.enforceError().message).toEqual('world');
182
195
  });