@itwin/core-backend 5.15.0-dev.7 → 5.16.0-dev.2

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 (200) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/lib/cjs/BriefcaseManager.d.ts +2 -1
  3. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  4. package/lib/cjs/BriefcaseManager.js +39 -9
  5. package/lib/cjs/BriefcaseManager.js.map +1 -1
  6. package/lib/cjs/ChangeUnifier.d.ts +82 -0
  7. package/lib/cjs/ChangeUnifier.d.ts.map +1 -0
  8. package/lib/cjs/ChangeUnifier.js +163 -0
  9. package/lib/cjs/ChangeUnifier.js.map +1 -0
  10. package/lib/cjs/ChangesetReader.d.ts +21 -2
  11. package/lib/cjs/ChangesetReader.d.ts.map +1 -1
  12. package/lib/cjs/ChangesetReader.js +37 -1
  13. package/lib/cjs/ChangesetReader.js.map +1 -1
  14. package/lib/cjs/CloudSqlite.d.ts +15 -0
  15. package/lib/cjs/CloudSqlite.d.ts.map +1 -1
  16. package/lib/cjs/CloudSqlite.js.map +1 -1
  17. package/lib/cjs/ECDb.d.ts +1 -0
  18. package/lib/cjs/ECDb.d.ts.map +1 -1
  19. package/lib/cjs/ECDb.js +4 -1
  20. package/lib/cjs/ECDb.js.map +1 -1
  21. package/lib/cjs/EditTxn.d.ts +5 -0
  22. package/lib/cjs/EditTxn.d.ts.map +1 -1
  23. package/lib/cjs/EditTxn.js +30 -10
  24. package/lib/cjs/EditTxn.js.map +1 -1
  25. package/lib/cjs/GeoCoordConfig.d.ts +1 -0
  26. package/lib/cjs/GeoCoordConfig.d.ts.map +1 -1
  27. package/lib/cjs/GeoCoordConfig.js +12 -8
  28. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  29. package/lib/cjs/IModelDb.d.ts +19 -6
  30. package/lib/cjs/IModelDb.d.ts.map +1 -1
  31. package/lib/cjs/IModelDb.js +50 -9
  32. package/lib/cjs/IModelDb.js.map +1 -1
  33. package/lib/cjs/NativeHost.d.ts.map +1 -1
  34. package/lib/cjs/NativeHost.js +5 -1
  35. package/lib/cjs/NativeHost.js.map +1 -1
  36. package/lib/cjs/Relationship.d.ts +28 -0
  37. package/lib/cjs/Relationship.d.ts.map +1 -1
  38. package/lib/cjs/Relationship.js +78 -0
  39. package/lib/cjs/Relationship.js.map +1 -1
  40. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  41. package/lib/cjs/SchemaSync.js +1 -0
  42. package/lib/cjs/SchemaSync.js.map +1 -1
  43. package/lib/cjs/TxnManager.d.ts +126 -89
  44. package/lib/cjs/TxnManager.d.ts.map +1 -1
  45. package/lib/cjs/TxnManager.js +114 -76
  46. package/lib/cjs/TxnManager.js.map +1 -1
  47. package/lib/cjs/ViewStateHydrator.d.ts.map +1 -1
  48. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  49. package/lib/cjs/ViewStore.d.ts.map +1 -1
  50. package/lib/cjs/ViewStore.js +62 -19
  51. package/lib/cjs/ViewStore.js.map +1 -1
  52. package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
  53. package/lib/cjs/annotations/LeaderGeometry.js +3 -0
  54. package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
  55. package/lib/cjs/core-backend.d.ts +1 -0
  56. package/lib/cjs/core-backend.d.ts.map +1 -1
  57. package/lib/cjs/core-backend.js +1 -0
  58. package/lib/cjs/core-backend.js.map +1 -1
  59. package/lib/cjs/internal/BriefcaseUtils.d.ts +19 -0
  60. package/lib/cjs/internal/BriefcaseUtils.d.ts.map +1 -0
  61. package/lib/cjs/internal/BriefcaseUtils.js +65 -0
  62. package/lib/cjs/internal/BriefcaseUtils.js.map +1 -0
  63. package/lib/cjs/internal/QueryMetadataCache.d.ts +44 -0
  64. package/lib/cjs/internal/QueryMetadataCache.d.ts.map +1 -0
  65. package/lib/cjs/internal/QueryMetadataCache.js +107 -0
  66. package/lib/cjs/internal/QueryMetadataCache.js.map +1 -0
  67. package/lib/cjs/internal/Symbols.d.ts +9 -0
  68. package/lib/cjs/internal/Symbols.d.ts.map +1 -1
  69. package/lib/cjs/internal/Symbols.js +10 -1
  70. package/lib/cjs/internal/Symbols.js.map +1 -1
  71. package/lib/cjs/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  72. package/lib/cjs/internal/workspace/WorkspaceImpl.js +20 -6
  73. package/lib/cjs/internal/workspace/WorkspaceImpl.js.map +1 -1
  74. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts +6 -6
  75. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -1
  76. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  77. package/lib/esm/BriefcaseManager.d.ts +2 -1
  78. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  79. package/lib/esm/BriefcaseManager.js +40 -10
  80. package/lib/esm/BriefcaseManager.js.map +1 -1
  81. package/lib/esm/ChangeUnifier.d.ts +82 -0
  82. package/lib/esm/ChangeUnifier.d.ts.map +1 -0
  83. package/lib/esm/ChangeUnifier.js +159 -0
  84. package/lib/esm/ChangeUnifier.js.map +1 -0
  85. package/lib/esm/ChangesetReader.d.ts +21 -2
  86. package/lib/esm/ChangesetReader.d.ts.map +1 -1
  87. package/lib/esm/ChangesetReader.js +38 -2
  88. package/lib/esm/ChangesetReader.js.map +1 -1
  89. package/lib/esm/CloudSqlite.d.ts +15 -0
  90. package/lib/esm/CloudSqlite.d.ts.map +1 -1
  91. package/lib/esm/CloudSqlite.js.map +1 -1
  92. package/lib/esm/ECDb.d.ts +1 -0
  93. package/lib/esm/ECDb.d.ts.map +1 -1
  94. package/lib/esm/ECDb.js +4 -1
  95. package/lib/esm/ECDb.js.map +1 -1
  96. package/lib/esm/EditTxn.d.ts +5 -0
  97. package/lib/esm/EditTxn.d.ts.map +1 -1
  98. package/lib/esm/EditTxn.js +32 -12
  99. package/lib/esm/EditTxn.js.map +1 -1
  100. package/lib/esm/GeoCoordConfig.d.ts +1 -0
  101. package/lib/esm/GeoCoordConfig.d.ts.map +1 -1
  102. package/lib/esm/GeoCoordConfig.js +12 -8
  103. package/lib/esm/GeoCoordConfig.js.map +1 -1
  104. package/lib/esm/IModelDb.d.ts +19 -6
  105. package/lib/esm/IModelDb.d.ts.map +1 -1
  106. package/lib/esm/IModelDb.js +52 -11
  107. package/lib/esm/IModelDb.js.map +1 -1
  108. package/lib/esm/NativeHost.d.ts.map +1 -1
  109. package/lib/esm/NativeHost.js +5 -1
  110. package/lib/esm/NativeHost.js.map +1 -1
  111. package/lib/esm/Relationship.d.ts +28 -0
  112. package/lib/esm/Relationship.d.ts.map +1 -1
  113. package/lib/esm/Relationship.js +78 -0
  114. package/lib/esm/Relationship.js.map +1 -1
  115. package/lib/esm/SchemaSync.d.ts.map +1 -1
  116. package/lib/esm/SchemaSync.js +1 -0
  117. package/lib/esm/SchemaSync.js.map +1 -1
  118. package/lib/esm/TxnManager.d.ts +126 -89
  119. package/lib/esm/TxnManager.d.ts.map +1 -1
  120. package/lib/esm/TxnManager.js +116 -78
  121. package/lib/esm/TxnManager.js.map +1 -1
  122. package/lib/esm/ViewStateHydrator.d.ts.map +1 -1
  123. package/lib/esm/ViewStateHydrator.js.map +1 -1
  124. package/lib/esm/ViewStore.d.ts.map +1 -1
  125. package/lib/esm/ViewStore.js +62 -19
  126. package/lib/esm/ViewStore.js.map +1 -1
  127. package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
  128. package/lib/esm/annotations/LeaderGeometry.js +3 -0
  129. package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
  130. package/lib/esm/core-backend.d.ts +1 -0
  131. package/lib/esm/core-backend.d.ts.map +1 -1
  132. package/lib/esm/core-backend.js +1 -0
  133. package/lib/esm/core-backend.js.map +1 -1
  134. package/lib/esm/internal/BriefcaseUtils.d.ts +19 -0
  135. package/lib/esm/internal/BriefcaseUtils.d.ts.map +1 -0
  136. package/lib/esm/internal/BriefcaseUtils.js +61 -0
  137. package/lib/esm/internal/BriefcaseUtils.js.map +1 -0
  138. package/lib/esm/internal/QueryMetadataCache.d.ts +44 -0
  139. package/lib/esm/internal/QueryMetadataCache.d.ts.map +1 -0
  140. package/lib/esm/internal/QueryMetadataCache.js +103 -0
  141. package/lib/esm/internal/QueryMetadataCache.js.map +1 -0
  142. package/lib/esm/internal/Symbols.d.ts +9 -0
  143. package/lib/esm/internal/Symbols.d.ts.map +1 -1
  144. package/lib/esm/internal/Symbols.js +9 -0
  145. package/lib/esm/internal/Symbols.js.map +1 -1
  146. package/lib/esm/internal/workspace/WorkspaceImpl.d.ts.map +1 -1
  147. package/lib/esm/internal/workspace/WorkspaceImpl.js +20 -6
  148. package/lib/esm/internal/workspace/WorkspaceImpl.js.map +1 -1
  149. package/lib/esm/rpc-impl/IModelReadRpcImpl.d.ts +6 -6
  150. package/lib/esm/rpc-impl/IModelReadRpcImpl.d.ts.map +1 -1
  151. package/lib/esm/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  152. package/lib/esm/test/annotations/LeaderGeometry.test.js +15 -1
  153. package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
  154. package/lib/esm/test/ecdb/CTE.test.js +21 -0
  155. package/lib/esm/test/ecdb/CTE.test.js.map +1 -1
  156. package/lib/esm/test/ecdb/ConcurrentQuery.test.js +144 -30
  157. package/lib/esm/test/ecdb/ConcurrentQuery.test.js.map +1 -1
  158. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts +2 -0
  159. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts.map +1 -0
  160. package/lib/esm/test/ecdb/QueryMetadataCache.test.js +630 -0
  161. package/lib/esm/test/ecdb/QueryMetadataCache.test.js.map +1 -0
  162. package/lib/esm/test/element/RelationshipBatchLookup.test.d.ts +2 -0
  163. package/lib/esm/test/element/RelationshipBatchLookup.test.d.ts.map +1 -0
  164. package/lib/esm/test/element/RelationshipBatchLookup.test.js +202 -0
  165. package/lib/esm/test/element/RelationshipBatchLookup.test.js.map +1 -0
  166. package/lib/esm/test/hubaccess/BriefcaseManager.test.js +187 -1
  167. package/lib/esm/test/hubaccess/BriefcaseManager.test.js.map +1 -1
  168. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts +2 -0
  169. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.d.ts.map +1 -0
  170. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js +142 -0
  171. package/lib/esm/test/hubaccess/SchemaImportOrphanColumns.test.js.map +1 -0
  172. package/lib/esm/test/imodel/IModelGeolocation.test.js +8 -6
  173. package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -1
  174. package/lib/esm/test/imodel/IModelProps.test.d.ts +2 -0
  175. package/lib/esm/test/imodel/IModelProps.test.d.ts.map +1 -0
  176. package/lib/esm/test/imodel/IModelProps.test.js +411 -0
  177. package/lib/esm/test/imodel/IModelProps.test.js.map +1 -0
  178. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts +2 -0
  179. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts.map +1 -0
  180. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js +240 -0
  181. package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js.map +1 -0
  182. package/lib/esm/test/schema/SchemaViewValidation.test.js +2 -8
  183. package/lib/esm/test/schema/SchemaViewValidation.test.js.map +1 -1
  184. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.d.ts +2 -0
  185. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.d.ts.map +1 -0
  186. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.js +159 -0
  187. package/lib/esm/test/standalone/BriefcaseManagerDelete.test.js.map +1 -0
  188. package/lib/esm/test/standalone/ChangeUnifier.test.d.ts +2 -0
  189. package/lib/esm/test/standalone/ChangeUnifier.test.d.ts.map +1 -0
  190. package/lib/esm/test/standalone/ChangeUnifier.test.js +732 -0
  191. package/lib/esm/test/standalone/ChangeUnifier.test.js.map +1 -0
  192. package/lib/esm/test/standalone/EditTxn.test.js +72 -1
  193. package/lib/esm/test/standalone/EditTxn.test.js.map +1 -1
  194. package/lib/esm/test/standalone/GeoCoordConfig.test.d.ts +2 -0
  195. package/lib/esm/test/standalone/GeoCoordConfig.test.d.ts.map +1 -0
  196. package/lib/esm/test/standalone/GeoCoordConfig.test.js +158 -0
  197. package/lib/esm/test/standalone/GeoCoordConfig.test.js.map +1 -0
  198. package/lib/esm/test/standalone/ViewStoreDb.test.js +53 -0
  199. package/lib/esm/test/standalone/ViewStoreDb.test.js.map +1 -1
  200. package/package.json +18 -18
@@ -1 +1 @@
1
- {"version":3,"file":"BriefcaseManager.test.js","sourceRoot":"","sources":["../../../../src/test/hubaccess/BriefcaseManager.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { assert } from \"chai\";\r\nimport { Guid } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue } from \"@itwin/core-common\";\r\nimport { Element } from \"../../Element\";\r\nimport { HubWrappers, IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { HubMock } from \"../../internal/HubMock\";\r\nimport { TestChangeSetUtility } from \"../TestChangeSetUtility\";\r\nimport { _nativeDb, ChannelControl, ProgressStatus } from \"../../core-backend\";\r\nimport { withEditTxn } from \"../../EditTxn\";\r\n\r\ndescribe(\"BriefcaseManager\", async () => {\r\n const testITwinId: string = Guid.createValue();\r\n const managerAccessToken = \"manager mock token\";\r\n const accessToken = \"access token\";\r\n\r\n // contested version0 files can cause errors that cause tests to not call shutdown, so always do it here\r\n afterEach(() => HubMock.shutdown());\r\n\r\n it(\"Open iModels with various names causing potential issues on Windows/Unix\", async () => {\r\n HubMock.startup(\"bad names\", KnownTestLocations.outputDir);\r\n let iModelName = \"iModel Name With Spaces\";\r\n let iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);\r\n const args = { accessToken, iTwinId: testITwinId, iModelId };\r\n assert.isDefined(iModelId);\r\n let iModel = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.isDefined(iModel);\r\n\r\n iModelName = \"iModel Name With :\\/<>?* Characters\";\r\n iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);\r\n assert.isDefined(iModelId);\r\n iModel = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.isDefined(iModel);\r\n\r\n iModelName = \"iModel Name Thats Excessively Long \" +\r\n \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\" +\r\n \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\" +\r\n \"01234567890123456789\"; // 35 + 2*100 + 20 = 255\r\n // Note: iModelHub does not accept a name that's longer than 255 characters.\r\n assert.equal(255, iModelName.length);\r\n iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);\r\n assert.isDefined(iModelId);\r\n iModel = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.isDefined(iModel);\r\n iModel.close();\r\n });\r\n\r\n it(\"should set appropriate briefcase ids for FixedVersion, PullOnly and PullAndPush workflows\", async () => {\r\n HubMock.startup(\"briefcaseIds\", KnownTestLocations.outputDir);\r\n const iModelId = await HubWrappers.createIModel(accessToken, testITwinId, \"imodel1\");\r\n const args = { accessToken, iTwinId: testITwinId, iModelId, deleteFirst: true };\r\n const iModel1 = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.equal(BriefcaseIdValue.Unassigned, iModel1.getBriefcaseId(), \"checkpoint should be 0\");\r\n\r\n try {\r\n const iModelFailure = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModelFailure);\r\n assert.fail(\"iModelFailure should fail due to iModel1 already being open as a SnapshotDb\");\r\n } catch (err: any) {\r\n assert.isTrue(err.message.includes(\"iModel is already open as a SnapshotDb\"), \"iModelFailure failure must be due to db being open as a SnapshotDb\");\r\n }\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel1);\r\n const iModel2 = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n assert.equal(BriefcaseIdValue.Unassigned, iModel2.briefcaseId, \"pullOnly should be 0\");\r\n\r\n const iModel2Dup = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n\r\n const iModel3 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n assert.isTrue(iModel3.briefcaseId >= BriefcaseIdValue.FirstValid && iModel3.briefcaseId <= BriefcaseIdValue.LastValid, \"valid briefcaseId\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel2);\r\n try {\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel2Dup);\r\n assert.fail(\"iModel2Dup failure should fail due to already being closed when iModel2 closed\");\r\n } catch (err: any) {\r\n assert.isTrue(err.message.includes(\"db not open\"), \"iModel2Dup failure must be due to db not being open\");\r\n }\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel3);\r\n });\r\n\r\n it(\"should reuse a briefcaseId when re-opening iModels for pullAndPush workflows\", async () => {\r\n HubMock.startup(\"briefcaseIdsReopen\", KnownTestLocations.outputDir);\r\n const iModelId = await HubWrappers.createIModel(accessToken, testITwinId, \"imodel1\");\r\n\r\n const args = { accessToken, iTwinId: testITwinId, iModelId, deleteFirst: false };\r\n const iModel1 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseId1 = iModel1.briefcaseId;\r\n iModel1.close(); // Keeps the briefcase by default\r\n\r\n const iModel3 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseId3 = iModel3.briefcaseId;\r\n assert.strictEqual(briefcaseId3, briefcaseId1);\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel3);\r\n });\r\n\r\n it(\"should reuse a briefcaseId when re-opening iModels of different versions for pullAndPush and pullOnly workflows\", async () => {\r\n HubMock.startup(\"workflow\", KnownTestLocations.outputDir);\r\n const userToken1 = \"manager token\";\r\n const userToken2 = \"super manager token\";\r\n\r\n // User1 creates an iModel on the Hub\r\n const testUtility = new TestChangeSetUtility(userToken1, IModelTestUtils.generateUniqueName(\"BriefcaseReuseTest\"));\r\n await testUtility.createTestIModel();\r\n\r\n // User2 opens and then closes the iModel pullOnly/pullPush, keeping the briefcase\r\n const args = { accessToken: userToken2, iTwinId: testUtility.iTwinId, iModelId: testUtility.iModelId };\r\n const iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseIdPullAndPush: number = iModelPullAndPush.briefcaseId;\r\n const changesetPullAndPush = iModelPullAndPush.changeset;\r\n iModelPullAndPush.close();\r\n\r\n const iModelPullOnly = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n const briefcaseIdPullOnly: number = iModelPullOnly.briefcaseId;\r\n const changesetPullOnly = iModelPullOnly.changeset;\r\n iModelPullOnly.close();\r\n\r\n // User1 pushes a change set\r\n await testUtility.pushTestChangeSet();\r\n\r\n // User 2 reopens the iModel pullOnly/pullPush => Expect the same briefcase to be re-used, but the changeset should have been updated!!\r\n const iModelPullAndPush2 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseIdPullAndPush2: number = iModelPullAndPush2.briefcaseId;\r\n assert.strictEqual(briefcaseIdPullAndPush2, briefcaseIdPullAndPush);\r\n const changesetPullAndPush2 = iModelPullAndPush2.changeset;\r\n assert.notStrictEqual(changesetPullAndPush2, changesetPullAndPush);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(userToken2, iModelPullAndPush2);\r\n\r\n const iModelPullOnly2 = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n const briefcaseIdPullOnly2: number = iModelPullOnly2.briefcaseId;\r\n assert.strictEqual(briefcaseIdPullOnly2, briefcaseIdPullOnly);\r\n const changesetPullOnly2 = iModelPullOnly2.changeset;\r\n assert.notStrictEqual(changesetPullOnly2, changesetPullOnly);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(userToken2, iModelPullOnly2);\r\n\r\n // Delete iModel from the Hub and disk\r\n await testUtility.deleteTestIModel();\r\n });\r\n\r\n it(\"should be able to edit a PullAndPush briefcase, reopen it as of a new version, and then push changes\", async () => {\r\n HubMock.startup(\"pullPush\", KnownTestLocations.outputDir);\r\n const userToken1 = \"manager token\"; // User1 is just used to create and update the iModel\r\n const userToken2 = \"super manager token\"; // User2 is used for the test\r\n\r\n // User1 creates an iModel on the Hub\r\n const testUtility = new TestChangeSetUtility(userToken1, \"PullAndPushTest\");\r\n await testUtility.createTestIModel();\r\n\r\n // User2 opens the iModel pullAndPush and is able to edit and save changes\r\n const args = { accessToken: userToken2, iTwinId: testUtility.iTwinId, iModelId: testUtility.iModelId };\r\n let iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n assert.exists(iModelPullAndPush);\r\n const briefcaseId = iModelPullAndPush.briefcaseId;\r\n const pathname = iModelPullAndPush.pathName;\r\n\r\n iModelPullAndPush.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n const rootEl: Element = iModelPullAndPush.elements.getRootSubject();\r\n rootEl.userLabel = `${rootEl.userLabel}changed`;\r\n withEditTxn(iModelPullAndPush, (txn) => txn.updateElement(rootEl.toJSON()));\r\n\r\n assert.isFalse(iModelPullAndPush[_nativeDb].hasUnsavedChanges());\r\n assert.isTrue(iModelPullAndPush[_nativeDb].hasPendingTxns());\r\n\r\n iModelPullAndPush.close();\r\n\r\n // User2 should be able to re-open the iModel pullAndPush again\r\n // - the changes will still be there\r\n iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const changesetPullAndPush = iModelPullAndPush.changeset;\r\n assert.strictEqual(iModelPullAndPush.briefcaseId, briefcaseId);\r\n assert.strictEqual(iModelPullAndPush.pathName, pathname);\r\n assert.isFalse(iModelPullAndPush[_nativeDb].hasUnsavedChanges());\r\n assert.isTrue(iModelPullAndPush[_nativeDb].hasPendingTxns());\r\n\r\n // User1 pushes a change set\r\n await testUtility.pushTestChangeSet();\r\n\r\n // User2 should be able to re-open the iModel\r\n await HubWrappers.openBriefcaseUsingRpc(args);\r\n\r\n // User2 closes and reopens the iModel pullAndPush as of the newer version\r\n // - the changes will still be there, AND\r\n // - the briefcase will be upgraded to the newer version since it was closed and re-opened.\r\n iModelPullAndPush.close();\r\n iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const changesetPullAndPush3 = iModelPullAndPush.changeset;\r\n assert.notStrictEqual(changesetPullAndPush3, changesetPullAndPush);\r\n assert.strictEqual(iModelPullAndPush.briefcaseId, briefcaseId);\r\n assert.strictEqual(iModelPullAndPush.pathName, pathname);\r\n assert.isFalse(iModelPullAndPush[_nativeDb].hasUnsavedChanges());\r\n assert.isTrue(iModelPullAndPush[_nativeDb].hasPendingTxns());\r\n\r\n // User2 should be able to push the changes now\r\n await iModelPullAndPush.pushChanges({ accessToken: userToken2, description: \"test change\" });\r\n const changesetPullAndPush4 = iModelPullAndPush.changeset;\r\n assert.notStrictEqual(changesetPullAndPush4, changesetPullAndPush3);\r\n\r\n // Delete iModel from the Hub and disk\r\n await HubWrappers.closeAndDeleteBriefcaseDb(userToken2, iModelPullAndPush);\r\n await testUtility.deleteTestIModel();\r\n });\r\n\r\n describe(\"pushChanges download progress\", () => {\r\n const user1 = \"user1 mock token\";\r\n const user2 = \"user2 mock token\";\r\n\r\n /** Creates an iModel owned by user1, opens a briefcase for user2, then pushes another changeset as user1 so\r\n * that user2's briefcase is behind by one changeset and must pull-and-merge before it can push.\r\n */\r\n async function setupOutdatedBriefcase(testName: string) {\r\n HubMock.startup(testName, KnownTestLocations.outputDir);\r\n\r\n const testUtility = new TestChangeSetUtility(user1, testName);\r\n await testUtility.createTestIModel();\r\n\r\n const briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user2, iTwinId: testUtility.iTwinId, iModelId: testUtility.iModelId });\r\n briefcase.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n\r\n await testUtility.pushTestChangeSet();\r\n\r\n // Make a local change so that this briefcase actually has something to push.\r\n const rootEl: Element = briefcase.elements.getRootSubject();\r\n rootEl.userLabel = `${rootEl.userLabel} changed`;\r\n withEditTxn(briefcase, (txn) => txn.updateElement(rootEl.toJSON()));\r\n\r\n return { testUtility, briefcase };\r\n }\r\n\r\n it(\"reports download progress for the changesets pulled before pushing\", async () => {\r\n const { testUtility, briefcase } = await setupOutdatedBriefcase(\"pushProgress\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n const progress: { loaded: number, total: number }[] = [];\r\n await briefcase.pushChanges({\r\n accessToken: user2,\r\n description: \"push with progress\",\r\n onDownloadProgress: (loaded, total) => {\r\n progress.push({ loaded, total });\r\n return ProgressStatus.Continue;\r\n },\r\n });\r\n\r\n assert.isTrue(progress.every((p) => p.loaded <= p.total), \"loaded should never exceed total\");\r\n\r\n // A push performs more than one pull, and the later ones have nothing left to download. Only the first\r\n // sequence actually transfers bytes.\r\n const downloaded = progress.filter((p) => p.total > 0);\r\n assert.isNotEmpty(downloaded, \"expected progress to be reported while pulling changesets\");\r\n for (let i = 1; i < downloaded.length; ++i)\r\n assert.isAtLeast(downloaded[i].loaded, downloaded[i - 1].loaded, \"loaded should be monotonically increasing\");\r\n assert.strictEqual(downloaded[downloaded.length - 1].loaded, downloaded[downloaded.length - 1].total, \"the last report should indicate the download completed\");\r\n\r\n assert.notStrictEqual(briefcase.changeset.id, changesetBeforePush, \"briefcase should have pulled and pushed\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n await testUtility.deleteTestIModel();\r\n });\r\n\r\n it(\"aborts the push when the download progress callback requests it\", async () => {\r\n const { testUtility, briefcase } = await setupOutdatedBriefcase(\"pushProgressAbort\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n let error: Error | undefined;\r\n try {\r\n await briefcase.pushChanges({\r\n accessToken: user2,\r\n description: \"push that gets aborted\",\r\n onDownloadProgress: () => ProgressStatus.Abort,\r\n });\r\n } catch (err) {\r\n error = err as Error;\r\n }\r\n\r\n assert.isDefined(error, \"aborting the download should cause pushChanges to throw\");\r\n assert.strictEqual(briefcase.changeset.id, changesetBeforePush, \"briefcase should not have advanced\");\r\n assert.isTrue(briefcase[_nativeDb].hasPendingTxns(), \"local changes should still be pending\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n await testUtility.deleteTestIModel();\r\n });\r\n });\r\n});\r\n"]}
1
+ {"version":3,"file":"BriefcaseManager.test.js","sourceRoot":"","sources":["../../../../src/test/hubaccess/BriefcaseManager.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as chai from \"chai\";\r\nimport * as chaiAsPromised from \"chai-as-promised\";\r\nimport { Guid } from \"@itwin/core-bentley\";\r\nimport { BriefcaseIdValue } from \"@itwin/core-common\";\r\nimport { Range3d } from \"@itwin/core-geometry\";\r\nimport { Element } from \"../../Element\";\r\nimport { HubWrappers, IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { HubMock } from \"../../internal/HubMock\";\r\nimport { TestChangeSetUtility } from \"../TestChangeSetUtility\";\r\nimport { _nativeDb, ChannelControl, ProgressStatus } from \"../../core-backend\";\r\nimport { withEditTxn } from \"../../EditTxn\";\r\n\r\nchai.use(chaiAsPromised);\r\nconst assert = chai.assert;\r\n\r\ndescribe(\"BriefcaseManager\", async () => {\r\n const testITwinId: string = Guid.createValue();\r\n const managerAccessToken = \"manager mock token\";\r\n const accessToken = \"access token\";\r\n\r\n // contested version0 files can cause errors that cause tests to not call shutdown, so always do it here\r\n afterEach(() => HubMock.shutdown());\r\n\r\n it(\"Open iModels with various names causing potential issues on Windows/Unix\", async () => {\r\n HubMock.startup(\"bad names\", KnownTestLocations.outputDir);\r\n let iModelName = \"iModel Name With Spaces\";\r\n let iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);\r\n const args = { accessToken, iTwinId: testITwinId, iModelId };\r\n assert.isDefined(iModelId);\r\n let iModel = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.isDefined(iModel);\r\n\r\n iModelName = \"iModel Name With :\\/<>?* Characters\";\r\n iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);\r\n assert.isDefined(iModelId);\r\n iModel = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.isDefined(iModel);\r\n\r\n iModelName = \"iModel Name Thats Excessively Long \" +\r\n \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\" +\r\n \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\" +\r\n \"01234567890123456789\"; // 35 + 2*100 + 20 = 255\r\n // Note: iModelHub does not accept a name that's longer than 255 characters.\r\n assert.equal(255, iModelName.length);\r\n iModelId = await HubWrappers.createIModel(managerAccessToken, testITwinId, iModelName);\r\n assert.isDefined(iModelId);\r\n iModel = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.isDefined(iModel);\r\n iModel.close();\r\n });\r\n\r\n it(\"should set appropriate briefcase ids for FixedVersion, PullOnly and PullAndPush workflows\", async () => {\r\n HubMock.startup(\"briefcaseIds\", KnownTestLocations.outputDir);\r\n const iModelId = await HubWrappers.createIModel(accessToken, testITwinId, \"imodel1\");\r\n const args = { accessToken, iTwinId: testITwinId, iModelId, deleteFirst: true };\r\n const iModel1 = await HubWrappers.openCheckpointUsingRpc(args);\r\n assert.equal(BriefcaseIdValue.Unassigned, iModel1.getBriefcaseId(), \"checkpoint should be 0\");\r\n\r\n try {\r\n const iModelFailure = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModelFailure);\r\n assert.fail(\"iModelFailure should fail due to iModel1 already being open as a SnapshotDb\");\r\n } catch (err: any) {\r\n assert.isTrue(err.message.includes(\"iModel is already open as a SnapshotDb\"), \"iModelFailure failure must be due to db being open as a SnapshotDb\");\r\n }\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel1);\r\n const iModel2 = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n assert.equal(BriefcaseIdValue.Unassigned, iModel2.briefcaseId, \"pullOnly should be 0\");\r\n\r\n const iModel2Dup = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n\r\n const iModel3 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n assert.isTrue(iModel3.briefcaseId >= BriefcaseIdValue.FirstValid && iModel3.briefcaseId <= BriefcaseIdValue.LastValid, \"valid briefcaseId\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel2);\r\n try {\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel2Dup);\r\n assert.fail(\"iModel2Dup failure should fail due to already being closed when iModel2 closed\");\r\n } catch (err: any) {\r\n assert.isTrue(err.message.includes(\"db not open\"), \"iModel2Dup failure must be due to db not being open\");\r\n }\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel3);\r\n });\r\n\r\n it(\"should reuse a briefcaseId when re-opening iModels for pullAndPush workflows\", async () => {\r\n HubMock.startup(\"briefcaseIdsReopen\", KnownTestLocations.outputDir);\r\n const iModelId = await HubWrappers.createIModel(accessToken, testITwinId, \"imodel1\");\r\n\r\n const args = { accessToken, iTwinId: testITwinId, iModelId, deleteFirst: false };\r\n const iModel1 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseId1 = iModel1.briefcaseId;\r\n iModel1.close(); // Keeps the briefcase by default\r\n\r\n const iModel3 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseId3 = iModel3.briefcaseId;\r\n assert.strictEqual(briefcaseId3, briefcaseId1);\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(accessToken, iModel3);\r\n });\r\n\r\n it(\"should reuse a briefcaseId when re-opening iModels of different versions for pullAndPush and pullOnly workflows\", async () => {\r\n HubMock.startup(\"workflow\", KnownTestLocations.outputDir);\r\n const userToken1 = \"manager token\";\r\n const userToken2 = \"super manager token\";\r\n\r\n // User1 creates an iModel on the Hub\r\n const testUtility = new TestChangeSetUtility(userToken1, IModelTestUtils.generateUniqueName(\"BriefcaseReuseTest\"));\r\n await testUtility.createTestIModel();\r\n\r\n // User2 opens and then closes the iModel pullOnly/pullPush, keeping the briefcase\r\n const args = { accessToken: userToken2, iTwinId: testUtility.iTwinId, iModelId: testUtility.iModelId };\r\n const iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseIdPullAndPush: number = iModelPullAndPush.briefcaseId;\r\n const changesetPullAndPush = iModelPullAndPush.changeset;\r\n iModelPullAndPush.close();\r\n\r\n const iModelPullOnly = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n const briefcaseIdPullOnly: number = iModelPullOnly.briefcaseId;\r\n const changesetPullOnly = iModelPullOnly.changeset;\r\n iModelPullOnly.close();\r\n\r\n // User1 pushes a change set\r\n await testUtility.pushTestChangeSet();\r\n\r\n // User 2 reopens the iModel pullOnly/pullPush => Expect the same briefcase to be re-used, but the changeset should have been updated!!\r\n const iModelPullAndPush2 = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const briefcaseIdPullAndPush2: number = iModelPullAndPush2.briefcaseId;\r\n assert.strictEqual(briefcaseIdPullAndPush2, briefcaseIdPullAndPush);\r\n const changesetPullAndPush2 = iModelPullAndPush2.changeset;\r\n assert.notStrictEqual(changesetPullAndPush2, changesetPullAndPush);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(userToken2, iModelPullAndPush2);\r\n\r\n const iModelPullOnly2 = await HubWrappers.openBriefcaseUsingRpc({ ...args, briefcaseId: 0 });\r\n const briefcaseIdPullOnly2: number = iModelPullOnly2.briefcaseId;\r\n assert.strictEqual(briefcaseIdPullOnly2, briefcaseIdPullOnly);\r\n const changesetPullOnly2 = iModelPullOnly2.changeset;\r\n assert.notStrictEqual(changesetPullOnly2, changesetPullOnly);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(userToken2, iModelPullOnly2);\r\n\r\n // Delete iModel from the Hub and disk\r\n await testUtility.deleteTestIModel();\r\n });\r\n\r\n it(\"should be able to edit a PullAndPush briefcase, reopen it as of a new version, and then push changes\", async () => {\r\n HubMock.startup(\"pullPush\", KnownTestLocations.outputDir);\r\n const userToken1 = \"manager token\"; // User1 is just used to create and update the iModel\r\n const userToken2 = \"super manager token\"; // User2 is used for the test\r\n\r\n // User1 creates an iModel on the Hub\r\n const testUtility = new TestChangeSetUtility(userToken1, \"PullAndPushTest\");\r\n await testUtility.createTestIModel();\r\n\r\n // User2 opens the iModel pullAndPush and is able to edit and save changes\r\n const args = { accessToken: userToken2, iTwinId: testUtility.iTwinId, iModelId: testUtility.iModelId };\r\n let iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n assert.exists(iModelPullAndPush);\r\n const briefcaseId = iModelPullAndPush.briefcaseId;\r\n const pathname = iModelPullAndPush.pathName;\r\n\r\n iModelPullAndPush.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n const rootEl: Element = iModelPullAndPush.elements.getRootSubject();\r\n rootEl.userLabel = `${rootEl.userLabel}changed`;\r\n withEditTxn(iModelPullAndPush, (txn) => txn.updateElement(rootEl.toJSON()));\r\n\r\n assert.isFalse(iModelPullAndPush[_nativeDb].hasUnsavedChanges());\r\n assert.isTrue(iModelPullAndPush[_nativeDb].hasPendingTxns());\r\n\r\n iModelPullAndPush.close();\r\n\r\n // User2 should be able to re-open the iModel pullAndPush again\r\n // - the changes will still be there\r\n iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const changesetPullAndPush = iModelPullAndPush.changeset;\r\n assert.strictEqual(iModelPullAndPush.briefcaseId, briefcaseId);\r\n assert.strictEqual(iModelPullAndPush.pathName, pathname);\r\n assert.isFalse(iModelPullAndPush[_nativeDb].hasUnsavedChanges());\r\n assert.isTrue(iModelPullAndPush[_nativeDb].hasPendingTxns());\r\n\r\n // User1 pushes a change set\r\n await testUtility.pushTestChangeSet();\r\n\r\n // User2 should be able to re-open the iModel\r\n await HubWrappers.openBriefcaseUsingRpc(args);\r\n\r\n // User2 closes and reopens the iModel pullAndPush as of the newer version\r\n // - the changes will still be there, AND\r\n // - the briefcase will be upgraded to the newer version since it was closed and re-opened.\r\n iModelPullAndPush.close();\r\n iModelPullAndPush = await HubWrappers.openBriefcaseUsingRpc(args);\r\n const changesetPullAndPush3 = iModelPullAndPush.changeset;\r\n assert.notStrictEqual(changesetPullAndPush3, changesetPullAndPush);\r\n assert.strictEqual(iModelPullAndPush.briefcaseId, briefcaseId);\r\n assert.strictEqual(iModelPullAndPush.pathName, pathname);\r\n assert.isFalse(iModelPullAndPush[_nativeDb].hasUnsavedChanges());\r\n assert.isTrue(iModelPullAndPush[_nativeDb].hasPendingTxns());\r\n\r\n // User2 should be able to push the changes now\r\n await iModelPullAndPush.pushChanges({ accessToken: userToken2, description: \"test change\" });\r\n const changesetPullAndPush4 = iModelPullAndPush.changeset;\r\n assert.notStrictEqual(changesetPullAndPush4, changesetPullAndPush3);\r\n\r\n // Delete iModel from the Hub and disk\r\n await HubWrappers.closeAndDeleteBriefcaseDb(userToken2, iModelPullAndPush);\r\n await testUtility.deleteTestIModel();\r\n });\r\n\r\n describe(\"pushChanges download progress\", () => {\r\n const user1 = \"user1 mock token\";\r\n const user2 = \"user2 mock token\";\r\n\r\n /** Creates an iModel owned by user1, opens a briefcase for user2, then pushes another changeset as user1 so\r\n * that user2's briefcase is behind by one changeset and must pull-and-merge before it can push.\r\n */\r\n async function setupOutdatedBriefcase(testName: string) {\r\n HubMock.startup(testName, KnownTestLocations.outputDir);\r\n\r\n const testUtility = new TestChangeSetUtility(user1, testName);\r\n await testUtility.createTestIModel();\r\n\r\n const briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user2, iTwinId: testUtility.iTwinId, iModelId: testUtility.iModelId });\r\n briefcase.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n\r\n await testUtility.pushTestChangeSet();\r\n\r\n // Make a local change so that this briefcase actually has something to push.\r\n const rootEl: Element = briefcase.elements.getRootSubject();\r\n rootEl.userLabel = `${rootEl.userLabel} changed`;\r\n withEditTxn(briefcase, (txn) => txn.updateElement(rootEl.toJSON()));\r\n\r\n return { testUtility, briefcase };\r\n }\r\n\r\n it(\"reports download progress for the changesets pulled before pushing\", async () => {\r\n const { testUtility, briefcase } = await setupOutdatedBriefcase(\"pushProgress\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n const progress: { loaded: number, total: number }[] = [];\r\n await briefcase.pushChanges({\r\n accessToken: user2,\r\n description: \"push with progress\",\r\n onDownloadProgress: (loaded, total) => {\r\n progress.push({ loaded, total });\r\n return ProgressStatus.Continue;\r\n },\r\n });\r\n\r\n assert.isTrue(progress.every((p) => p.loaded <= p.total), \"loaded should never exceed total\");\r\n\r\n // A push performs more than one pull, and the later ones have nothing left to download. Only the first\r\n // sequence actually transfers bytes.\r\n const downloaded = progress.filter((p) => p.total > 0);\r\n assert.isNotEmpty(downloaded, \"expected progress to be reported while pulling changesets\");\r\n for (let i = 1; i < downloaded.length; ++i)\r\n assert.isAtLeast(downloaded[i].loaded, downloaded[i - 1].loaded, \"loaded should be monotonically increasing\");\r\n assert.strictEqual(downloaded[downloaded.length - 1].loaded, downloaded[downloaded.length - 1].total, \"the last report should indicate the download completed\");\r\n\r\n assert.notStrictEqual(briefcase.changeset.id, changesetBeforePush, \"briefcase should have pulled and pushed\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n await testUtility.deleteTestIModel();\r\n });\r\n\r\n it(\"aborts the push when the download progress callback requests it\", async () => {\r\n const { testUtility, briefcase } = await setupOutdatedBriefcase(\"pushProgressAbort\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n let error: Error | undefined;\r\n try {\r\n await briefcase.pushChanges({\r\n accessToken: user2,\r\n description: \"push that gets aborted\",\r\n onDownloadProgress: () => ProgressStatus.Abort,\r\n });\r\n } catch (err) {\r\n error = err as Error;\r\n }\r\n\r\n assert.isDefined(error, \"aborting the download should cause pushChanges to throw\");\r\n assert.strictEqual(briefcase.changeset.id, changesetBeforePush, \"briefcase should not have advanced\");\r\n assert.isTrue(briefcase[_nativeDb].hasPendingTxns(), \"local changes should still be pending\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n await testUtility.deleteTestIModel();\r\n });\r\n });\r\n\r\n describe(\"TxnManager.onPrePushValidation\", () => {\r\n const user2 = \"user2 mock token\";\r\n const user3 = \"user3 mock token\";\r\n\r\n /** Creates an empty iModel and opens a briefcase with one local, unpushed change to the root subject's user label. */\r\n async function setupBriefcaseWithLocalChange(testName: string) {\r\n HubMock.startup(testName, KnownTestLocations.outputDir);\r\n\r\n const iTwinId = HubMock.iTwinId;\r\n const iModelId = await HubWrappers.recreateIModel({ accessToken: user2, iTwinId, iModelName: testName, noLocks: true });\r\n\r\n const briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user2, iTwinId, iModelId });\r\n briefcase.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n\r\n const rootEl = briefcase.elements.getRootSubject();\r\n rootEl.userLabel = \"local change\";\r\n withEditTxn(briefcase, (txn) => txn.updateElement(rootEl.toJSON()));\r\n assert.isTrue(briefcase.txns.hasPendingTxns);\r\n\r\n return { iTwinId, iModelId, briefcase };\r\n }\r\n\r\n it(\"delays the push until the listener's promise resolves\", async () => {\r\n const { briefcase } = await setupBriefcaseWithLocalChange(\"prePushDelay\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n const events: string[] = [];\r\n let changesetWhenListenerFinished: string | undefined;\r\n let releaseListener!: () => void;\r\n const gate = new Promise<void>((resolve) => { releaseListener = resolve; });\r\n let listenerStarted!: () => void;\r\n const started = new Promise<void>((resolve) => { listenerStarted = resolve; });\r\n\r\n const removeListener = briefcase.txns.onPrePushValidation.addListener(async () => {\r\n events.push(\"listener started\");\r\n listenerStarted();\r\n await gate;\r\n changesetWhenListenerFinished = briefcase.changeset.id;\r\n events.push(\"listener finished\");\r\n });\r\n\r\n try {\r\n const pushPromise = briefcase.pushChanges({ accessToken: user2, description: \"delayed push\" }).then(() => { events.push(\"push settled\"); });\r\n\r\n await started;\r\n events.push(\"listener released\");\r\n releaseListener();\r\n await pushPromise;\r\n\r\n assert.deepEqual(events, [\"listener started\", \"listener released\", \"listener finished\", \"push settled\"]);\r\n assert.strictEqual(changesetWhenListenerFinished, changesetBeforePush, \"nothing should be pushed before the listener resolves\");\r\n assert.notStrictEqual(briefcase.changeset.id, changesetBeforePush, \"push should complete once the listener resolves\");\r\n assert.isFalse(briefcase.txns.hasPendingTxns);\r\n } finally {\r\n releaseListener();\r\n removeListener();\r\n }\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n });\r\n\r\n it(\"includes a Txn written by the listener in the pushed changeset\", async () => {\r\n const { iTwinId, iModelId, briefcase } = await setupBriefcaseWithLocalChange(\"prePushWriteTxn\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n const txnCountBeforePush = Array.from(briefcase.txns.queryTxns()).length;\r\n let txnCountInListener = 0;\r\n\r\n const removeListener = briefcase.txns.onPrePushValidation.addListener(async () => {\r\n const rootEl = briefcase.elements.getRootSubject();\r\n rootEl.description = \"written during pre-push validation\";\r\n withEditTxn(briefcase, (txn) => txn.updateElement(rootEl.toJSON()));\r\n txnCountInListener = Array.from(briefcase.txns.queryTxns()).length;\r\n });\r\n\r\n try {\r\n await briefcase.pushChanges({ accessToken: user2, description: \"push with pre-push txn\" });\r\n } finally {\r\n removeListener();\r\n }\r\n\r\n assert.isAbove(txnCountInListener, txnCountBeforePush, \"listener should have written a new Txn\");\r\n assert.notStrictEqual(briefcase.changeset.id, changesetBeforePush);\r\n assert.isFalse(briefcase.txns.hasPendingTxns, \"the listener's Txn should have been pushed, not left pending\");\r\n\r\n // A fresh briefcase at the tip only sees the listener's change if it was part of the pushed changeset.\r\n const verifier = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user3, iTwinId, iModelId });\r\n const pushedRoot = verifier.elements.getRootSubject();\r\n assert.strictEqual(pushedRoot.userLabel, \"local change\");\r\n assert.strictEqual(pushedRoot.description, \"written during pre-push validation\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user3, verifier);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n });\r\n\r\n it(\"aborts the push when the listener rejects\", async () => {\r\n const { briefcase } = await setupBriefcaseWithLocalChange(\"prePushReject\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n const removeListener = briefcase.txns.onPrePushValidation.addListener(async () => {\r\n throw new Error(\"validation failed\");\r\n });\r\n\r\n try {\r\n await assert.isRejected(briefcase.pushChanges({ accessToken: user2, description: \"rejected push\" }), \"validation failed\");\r\n } finally {\r\n removeListener();\r\n }\r\n\r\n assert.strictEqual(briefcase.changeset.id, changesetBeforePush, \"briefcase should not have advanced\");\r\n assert.isTrue(briefcase.txns.hasPendingTxns, \"local changes should still be pending\");\r\n\r\n // With the listener removed, the same changes can still be pushed.\r\n await briefcase.pushChanges({ accessToken: user2, description: \"retry push\" });\r\n assert.notStrictEqual(briefcase.changeset.id, changesetBeforePush);\r\n assert.isFalse(briefcase.txns.hasPendingTxns);\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n });\r\n\r\n it(\"handles a listener that calls pushChanges, recursing asynchronously\", async () => {\r\n const { briefcase } = await setupBriefcaseWithLocalChange(\"prePushRecursion\");\r\n const changesetBeforePush = briefcase.changeset.id;\r\n\r\n let listenerCalls = 0;\r\n let changesetAfterNestedPush: string | undefined;\r\n // addOnce removes the listener before invoking it, so the nested push does not re-enter it endlessly.\r\n const removeListener = briefcase.txns.onPrePushValidation.addOnce(async () => {\r\n ++listenerCalls;\r\n await briefcase.pushChanges({ accessToken: user2, description: \"nested push\" });\r\n changesetAfterNestedPush = briefcase.changeset.id;\r\n });\r\n\r\n try {\r\n // The nested push consumes all pending Txns, so the outer push has nothing left to push and completes quietly.\r\n await briefcase.pushChanges({ accessToken: user2, description: \"outer push\" });\r\n } finally {\r\n removeListener();\r\n }\r\n\r\n assert.strictEqual(listenerCalls, 1, \"listener should only run for the outer push\");\r\n assert.isDefined(changesetAfterNestedPush);\r\n assert.notStrictEqual(changesetAfterNestedPush, changesetBeforePush, \"nested push should have pushed the changes\");\r\n assert.strictEqual(briefcase.changeset.id, changesetAfterNestedPush);\r\n assert.isFalse(briefcase.txns.hasPendingTxns);\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, briefcase);\r\n });\r\n\r\n describe(\"after pull/merge\", () => {\r\n const incomingExtents = new Range3d(-100, -200, -300, 400, 500, 600);\r\n\r\n // Note: only project extents are covered. The native getIModelProps(\"pullMerge\") does not reload geolocation (ECEF location, global origin) after a merge.\r\n /** user2 has a local unpushed change; user3 then pushes new project extents that user2 has not yet pulled. */\r\n async function setup(testName: string) {\r\n HubMock.startup(testName, KnownTestLocations.outputDir);\r\n const iTwinId = HubMock.iTwinId;\r\n const iModelId = await HubWrappers.recreateIModel({ accessToken: user2, iTwinId, iModelName: testName, noLocks: true });\r\n\r\n const local = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user2, iTwinId, iModelId });\r\n local.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n const rootEl = local.elements.getRootSubject();\r\n rootEl.userLabel = \"local change\";\r\n withEditTxn(local, (txn) => txn.updateElement(rootEl.toJSON()));\r\n\r\n const remote = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user3, iTwinId, iModelId });\r\n remote.channels.addAllowedChannel(ChannelControl.sharedChannelName);\r\n withEditTxn(remote, (txn) => txn.updateProjectExtents(incomingExtents));\r\n await remote.pushChanges({ accessToken: user3, description: \"project extents\" });\r\n\r\n return { iTwinId, iModelId, local, remote };\r\n }\r\n\r\n it(\"exposes the merged project extents to listeners\", async () => {\r\n const { local, remote } = await setup(\"prePushMergedProps\");\r\n\r\n let seenExtents: Range3d | undefined;\r\n const removeListener = local.txns.onPrePushValidation.addListener(async () => {\r\n seenExtents = local.projectExtents.clone();\r\n });\r\n\r\n try {\r\n await local.pushChanges({ accessToken: user2, description: \"push after merge\" });\r\n } finally {\r\n removeListener();\r\n }\r\n\r\n assert.isDefined(seenExtents);\r\n assert.isTrue(seenExtents!.isAlmostEqual(incomingExtents), \"listener should see the merged project extents\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user3, remote);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, local);\r\n });\r\n\r\n it(\"lets a listener extend the merged project extents\", async () => {\r\n const { iTwinId, iModelId, local, remote } = await setup(\"prePushExtendExtents\");\r\n\r\n const extra = new Range3d(500, 600, 700, 800, 900, 1000);\r\n const expected = incomingExtents.clone();\r\n expected.extendRange(extra);\r\n const removeListener = local.txns.onPrePushValidation.addListener(async () => {\r\n const extended = local.projectExtents.clone();\r\n extended.extendRange(extra);\r\n withEditTxn(local, (txn) => txn.updateProjectExtents(extended));\r\n });\r\n\r\n try {\r\n await local.pushChanges({ accessToken: user2, description: \"push after merge\" });\r\n } finally {\r\n removeListener();\r\n }\r\n\r\n const verifier = await HubWrappers.downloadAndOpenBriefcase({ accessToken: user3, iTwinId, iModelId, briefcaseId: BriefcaseIdValue.Unassigned });\r\n assert.isTrue(verifier.projectExtents.isAlmostEqual(expected), \"pushed extents should extend the merged extents, not the stale pre-merge extents\");\r\n\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user3, verifier);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user3, remote);\r\n await HubWrappers.closeAndDeleteBriefcaseDb(user2, local);\r\n });\r\n });\r\n });\r\n});\r\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SchemaImportOrphanColumns.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaImportOrphanColumns.test.d.ts","sourceRoot":"","sources":["../../../../src/test/hubaccess/SchemaImportOrphanColumns.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,142 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { DbResult } from "@itwin/core-bentley";
6
+ import * as chai from "chai";
7
+ import * as chaiAsPromised from "chai-as-promised";
8
+ import { HubWrappers, KnownTestLocations } from "..";
9
+ import { HubMock } from "../../internal/HubMock";
10
+ chai.use(chaiAsPromised);
11
+ /**
12
+ * Repro for Bug 2115705: "DbTable 'bis_ElementMultiAspect' has N non-virtual columns, but the physical table has M columns."
13
+ *
14
+ * No semantic rebase, schema sync or dynamic schema involved. A schema adds an ElementMultiAspect subclass wide enough to
15
+ * ALTER TABLE ADD shared columns to bis_ElementMultiAspect. discardChanges() then reverses the EcSchema txn (ec_* rows)
16
+ * but skips the Ddl txn (TxnManager::ApplyTxnChanges returns early for TxnType::Ddl), so the physical columns remain
17
+ * with no ec_Column rows. The next regular schema import used to fail the strict column-count check; it must now succeed.
18
+ *
19
+ * The dynamic-schema tests show that deleting properties/classes (allowed for dynamic schemas) is not a cause.
20
+ */
21
+ describe("Schema import discard leaves orphan physical columns (Bug 2115705)", function () {
22
+ this.timeout(90000);
23
+ const tableName = "bis_ElementMultiAspect";
24
+ const extraColumns = 6;
25
+ let briefcase;
26
+ before(() => HubMock.startup("SchemaImportOrphanColumns", KnownTestLocations.outputDir));
27
+ after(() => HubMock.shutdown());
28
+ afterEach(() => {
29
+ briefcase?.close();
30
+ briefcase = undefined;
31
+ });
32
+ const physicalColumns = (db) => db.withSqliteStatement(`PRAGMA table_info([${tableName}])`, (stmt) => {
33
+ const names = [];
34
+ while (stmt.step() === DbResult.BE_SQLITE_ROW)
35
+ names.push(stmt.getValue(1).getString());
36
+ return names;
37
+ });
38
+ const mappedNonVirtualColumnCount = (db) => db.withSqliteStatement(`SELECT COUNT(*) FROM ec_Column c JOIN ec_Table t ON t.Id = c.TableId WHERE t.Name = '${tableName}' AND c.IsVirtual = 0`, (stmt) => {
39
+ chai.expect(stmt.step()).to.equal(DbResult.BE_SQLITE_ROW);
40
+ return stmt.getValue(0).getInteger();
41
+ });
42
+ const schemaWithWideMultiAspect = (propCount) => `<?xml version="1.0" encoding="UTF-8"?>
43
+ <ECSchema schemaName="WideAspect" alias="wa" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
44
+ <ECSchemaReference name="BisCore" version="01.00.00" alias="bis"/>
45
+ <ECEntityClass typeName="WideMultiAspect">
46
+ <BaseClass>bis:ElementMultiAspect</BaseClass>
47
+ ${Array.from({ length: propCount }, (_, i) => `<ECProperty propertyName="P${i + 1}" typeName="string"/>`).join("\n ")}
48
+ </ECEntityClass>
49
+ </ECSchema>`;
50
+ const unrelatedSchema = `<?xml version="1.0" encoding="UTF-8"?>
51
+ <ECSchema schemaName="Unrelated" alias="unr" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
52
+ <ECSchemaReference name="BisCore" version="01.00.00" alias="bis"/>
53
+ <ECEntityClass typeName="Thing">
54
+ <BaseClass>bis:GraphicalElement2d</BaseClass>
55
+ <ECProperty propertyName="Name" typeName="string"/>
56
+ </ECEntityClass>
57
+ </ECSchema>`;
58
+ const dynamicSchema = (version, propCount) => `<?xml version="1.0" encoding="UTF-8"?>
59
+ <ECSchema schemaName="DynTest" alias="dyn" version="${version}" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
60
+ <ECSchemaReference name="BisCore" version="01.00.00" alias="bis"/>
61
+ <ECSchemaReference name="CoreCustomAttributes" version="01.00.03" alias="CoreCA"/>
62
+ <ECCustomAttributes>
63
+ <DynamicSchema xmlns="CoreCustomAttributes.01.00.03"/>
64
+ </ECCustomAttributes>
65
+ ${propCount === undefined ? "" : `<ECEntityClass typeName="WideMultiAspect">
66
+ <BaseClass>bis:ElementMultiAspect</BaseClass>
67
+ ${Array.from({ length: propCount }, (_, i) => `<ECProperty propertyName="P${i + 1}" typeName="string"/>`).join("\n ")}
68
+ </ECEntityClass>`}
69
+ </ECSchema>`;
70
+ it("deleting dynamic-schema properties/classes keeps ec_Column and physical columns in sync", async () => {
71
+ const accessToken = "user1";
72
+ const iModelId = await HubMock.createNewIModel({ accessToken, iTwinId: HubMock.iTwinId, iModelName: "DynDelete" });
73
+ briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken, iTwinId: HubMock.iTwinId, iModelId });
74
+ const db = briefcase;
75
+ const assertInSync = (step) => chai.expect(physicalColumns(db).length).to.equal(mappedNonVirtualColumnCount(db), `out of sync after ${step}`);
76
+ const sharedColumnCount = physicalColumns(db).filter((name) => /^ps\d+$/i.test(name)).length;
77
+ const wide = sharedColumnCount + extraColumns;
78
+ await db.importSchemaStrings([dynamicSchema("01.00.00", wide)]);
79
+ assertInSync("wide import");
80
+ await db.importSchemaStrings([dynamicSchema("02.00.00", 1)]); // delete P2..Pn
81
+ assertInSync("property deletion");
82
+ await db.importSchemaStrings([dynamicSchema("03.00.00", undefined)]); // delete the class
83
+ assertInSync("class deletion");
84
+ await db.importSchemaStrings([unrelatedSchema]); // strict validation passes
85
+ assertInSync("unrelated import");
86
+ });
87
+ it("dynamic-schema deletions pushed and pulled keep the pulling briefcase in sync", async () => {
88
+ const iModelId = await HubMock.createNewIModel({ accessToken: "user1", iTwinId: HubMock.iTwinId, iModelName: "DynDeletePull" });
89
+ const writer = await HubWrappers.downloadAndOpenBriefcase({ accessToken: "user1", iTwinId: HubMock.iTwinId, iModelId });
90
+ const reader = await HubWrappers.downloadAndOpenBriefcase({ accessToken: "user2", iTwinId: HubMock.iTwinId, iModelId });
91
+ try {
92
+ const assertInSync = (db, step) => chai.expect(physicalColumns(db).length).to.equal(mappedNonVirtualColumnCount(db), `${db === writer ? "writer" : "reader"} out of sync after ${step}`);
93
+ const wide = physicalColumns(writer).filter((name) => /^ps\d+$/i.test(name)).length + extraColumns;
94
+ const steps = [
95
+ ["wide import", dynamicSchema("01.00.00", wide)],
96
+ ["property deletion", dynamicSchema("02.00.00", 1)],
97
+ ["class deletion", dynamicSchema("03.00.00", undefined)],
98
+ ];
99
+ for (const [step, xml] of steps) {
100
+ await writer.importSchemaStrings([xml]);
101
+ await writer.pushChanges({ description: step });
102
+ assertInSync(writer, step);
103
+ await reader.pullChanges();
104
+ assertInSync(reader, step);
105
+ }
106
+ // Strict validation on the pulling briefcase passes.
107
+ await reader.importSchemaStrings([unrelatedSchema]);
108
+ assertInSync(reader, "unrelated import");
109
+ }
110
+ finally {
111
+ writer.close();
112
+ reader.close();
113
+ }
114
+ });
115
+ it("schema import succeeds after discarding a schema import that added columns", async () => {
116
+ const accessToken = "user1";
117
+ const iModelId = await HubMock.createNewIModel({ accessToken, iTwinId: HubMock.iTwinId, iModelName: "DiscardOrphan" });
118
+ briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken, iTwinId: HubMock.iTwinId, iModelId });
119
+ const baselineColumns = physicalColumns(briefcase);
120
+ chai.expect(baselineColumns.length).to.equal(mappedNonVirtualColumnCount(briefcase), "baseline must be consistent");
121
+ // Plain (non-dynamic) schema whose aspect needs more shared columns than the table has -> ALTER TABLE ADD COLUMN.
122
+ const sharedColumnCount = baselineColumns.filter((name) => /^ps\d+$/i.test(name)).length;
123
+ await briefcase.importSchemaStrings([schemaWithWideMultiAspect(sharedColumnCount + extraColumns)]);
124
+ chai.expect(physicalColumns(briefcase).length).to.equal(baselineColumns.length + extraColumns, "import should add physical columns");
125
+ chai.expect(mappedNonVirtualColumnCount(briefcase)).to.equal(baselineColumns.length + extraColumns);
126
+ // Abandon the un-pushed schema import: ec_* is reverted, the DDL is not.
127
+ await briefcase.discardChanges();
128
+ const schemaCount = briefcase.withSqliteStatement("SELECT COUNT(*) FROM ec_Schema WHERE Name = 'WideAspect'", (stmt) => {
129
+ stmt.step();
130
+ return stmt.getValue(0).getInteger();
131
+ });
132
+ chai.expect(schemaCount).to.equal(0, "schema should be gone after discardChanges");
133
+ const mapped = mappedNonVirtualColumnCount(briefcase);
134
+ const physical = physicalColumns(briefcase).length;
135
+ chai.expect(mapped).to.equal(baselineColumns.length);
136
+ chai.expect(physical - mapped).to.equal(extraColumns, `orphan columns left in ${tableName}`);
137
+ // A subsequent regular schema import must tolerate the unused shared columns left behind.
138
+ await briefcase.importSchemaStrings([unrelatedSchema]);
139
+ chai.expect(physicalColumns(briefcase).length).to.equal(physical);
140
+ });
141
+ });
142
+ //# sourceMappingURL=SchemaImportOrphanColumns.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaImportOrphanColumns.test.js","sourceRoot":"","sources":["../../../../src/test/hubaccess/SchemaImportOrphanColumns.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license information.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { DbResult } from \"@itwin/core-bentley\";\r\nimport * as chai from \"chai\";\r\nimport * as chaiAsPromised from \"chai-as-promised\";\r\nimport { Suite } from \"mocha\";\r\nimport { HubWrappers, KnownTestLocations } from \"..\";\r\nimport { BriefcaseDb } from \"../../core-backend\";\r\nimport { HubMock } from \"../../internal/HubMock\";\r\n\r\nchai.use(chaiAsPromised);\r\n\r\n/**\r\n * Repro for Bug 2115705: \"DbTable 'bis_ElementMultiAspect' has N non-virtual columns, but the physical table has M columns.\"\r\n *\r\n * No semantic rebase, schema sync or dynamic schema involved. A schema adds an ElementMultiAspect subclass wide enough to\r\n * ALTER TABLE ADD shared columns to bis_ElementMultiAspect. discardChanges() then reverses the EcSchema txn (ec_* rows)\r\n * but skips the Ddl txn (TxnManager::ApplyTxnChanges returns early for TxnType::Ddl), so the physical columns remain\r\n * with no ec_Column rows. The next regular schema import used to fail the strict column-count check; it must now succeed.\r\n *\r\n * The dynamic-schema tests show that deleting properties/classes (allowed for dynamic schemas) is not a cause.\r\n */\r\ndescribe(\"Schema import discard leaves orphan physical columns (Bug 2115705)\", function (this: Suite) {\r\n this.timeout(90000);\r\n const tableName = \"bis_ElementMultiAspect\";\r\n const extraColumns = 6;\r\n let briefcase: BriefcaseDb | undefined;\r\n\r\n before(() => HubMock.startup(\"SchemaImportOrphanColumns\", KnownTestLocations.outputDir));\r\n after(() => HubMock.shutdown());\r\n afterEach(() => {\r\n briefcase?.close();\r\n briefcase = undefined;\r\n });\r\n\r\n const physicalColumns = (db: BriefcaseDb): string[] =>\r\n db.withSqliteStatement(`PRAGMA table_info([${tableName}])`, (stmt) => {\r\n const names: string[] = [];\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n names.push(stmt.getValue(1).getString());\r\n return names;\r\n });\r\n\r\n const mappedNonVirtualColumnCount = (db: BriefcaseDb): number =>\r\n db.withSqliteStatement(\r\n `SELECT COUNT(*) FROM ec_Column c JOIN ec_Table t ON t.Id = c.TableId WHERE t.Name = '${tableName}' AND c.IsVirtual = 0`,\r\n (stmt) => {\r\n chai.expect(stmt.step()).to.equal(DbResult.BE_SQLITE_ROW);\r\n return stmt.getValue(0).getInteger();\r\n });\r\n\r\n const schemaWithWideMultiAspect = (propCount: number) => `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n <ECSchema schemaName=\"WideAspect\" alias=\"wa\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\r\n <ECEntityClass typeName=\"WideMultiAspect\">\r\n <BaseClass>bis:ElementMultiAspect</BaseClass>\r\n ${Array.from({ length: propCount }, (_, i) => `<ECProperty propertyName=\"P${i + 1}\" typeName=\"string\"/>`).join(\"\\n \")}\r\n </ECEntityClass>\r\n </ECSchema>`;\r\n\r\n const unrelatedSchema = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n <ECSchema schemaName=\"Unrelated\" alias=\"unr\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\r\n <ECEntityClass typeName=\"Thing\">\r\n <BaseClass>bis:GraphicalElement2d</BaseClass>\r\n <ECProperty propertyName=\"Name\" typeName=\"string\"/>\r\n </ECEntityClass>\r\n </ECSchema>`;\r\n\r\n const dynamicSchema = (version: string, propCount: number | undefined) => `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n <ECSchema schemaName=\"DynTest\" alias=\"dyn\" version=\"${version}\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\r\n <ECSchemaReference name=\"CoreCustomAttributes\" version=\"01.00.03\" alias=\"CoreCA\"/>\r\n <ECCustomAttributes>\r\n <DynamicSchema xmlns=\"CoreCustomAttributes.01.00.03\"/>\r\n </ECCustomAttributes>\r\n ${propCount === undefined ? \"\" : `<ECEntityClass typeName=\"WideMultiAspect\">\r\n <BaseClass>bis:ElementMultiAspect</BaseClass>\r\n ${Array.from({ length: propCount }, (_, i) => `<ECProperty propertyName=\"P${i + 1}\" typeName=\"string\"/>`).join(\"\\n \")}\r\n </ECEntityClass>`}\r\n </ECSchema>`;\r\n\r\n it(\"deleting dynamic-schema properties/classes keeps ec_Column and physical columns in sync\", async () => {\r\n const accessToken = \"user1\";\r\n const iModelId = await HubMock.createNewIModel({ accessToken, iTwinId: HubMock.iTwinId, iModelName: \"DynDelete\" });\r\n briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken, iTwinId: HubMock.iTwinId, iModelId });\r\n const db = briefcase;\r\n const assertInSync = (step: string) =>\r\n chai.expect(physicalColumns(db).length).to.equal(mappedNonVirtualColumnCount(db), `out of sync after ${step}`);\r\n\r\n const sharedColumnCount = physicalColumns(db).filter((name) => /^ps\\d+$/i.test(name)).length;\r\n const wide = sharedColumnCount + extraColumns;\r\n\r\n await db.importSchemaStrings([dynamicSchema(\"01.00.00\", wide)]);\r\n assertInSync(\"wide import\");\r\n await db.importSchemaStrings([dynamicSchema(\"02.00.00\", 1)]); // delete P2..Pn\r\n assertInSync(\"property deletion\");\r\n await db.importSchemaStrings([dynamicSchema(\"03.00.00\", undefined)]); // delete the class\r\n assertInSync(\"class deletion\");\r\n await db.importSchemaStrings([unrelatedSchema]); // strict validation passes\r\n assertInSync(\"unrelated import\");\r\n });\r\n\r\n it(\"dynamic-schema deletions pushed and pulled keep the pulling briefcase in sync\", async () => {\r\n const iModelId = await HubMock.createNewIModel({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelName: \"DynDeletePull\" });\r\n const writer = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user1\", iTwinId: HubMock.iTwinId, iModelId });\r\n const reader = await HubWrappers.downloadAndOpenBriefcase({ accessToken: \"user2\", iTwinId: HubMock.iTwinId, iModelId });\r\n try {\r\n const assertInSync = (db: BriefcaseDb, step: string) =>\r\n chai.expect(physicalColumns(db).length).to.equal(mappedNonVirtualColumnCount(db), `${db === writer ? \"writer\" : \"reader\"} out of sync after ${step}`);\r\n\r\n const wide = physicalColumns(writer).filter((name) => /^ps\\d+$/i.test(name)).length + extraColumns;\r\n const steps: Array<[string, string]> = [\r\n [\"wide import\", dynamicSchema(\"01.00.00\", wide)],\r\n [\"property deletion\", dynamicSchema(\"02.00.00\", 1)],\r\n [\"class deletion\", dynamicSchema(\"03.00.00\", undefined)],\r\n ];\r\n for (const [step, xml] of steps) {\r\n await writer.importSchemaStrings([xml]);\r\n await writer.pushChanges({ description: step });\r\n assertInSync(writer, step);\r\n await reader.pullChanges();\r\n assertInSync(reader, step);\r\n }\r\n\r\n // Strict validation on the pulling briefcase passes.\r\n await reader.importSchemaStrings([unrelatedSchema]);\r\n assertInSync(reader, \"unrelated import\");\r\n } finally {\r\n writer.close();\r\n reader.close();\r\n }\r\n });\r\n\r\n it(\"schema import succeeds after discarding a schema import that added columns\", async () => {\r\n const accessToken = \"user1\";\r\n const iModelId = await HubMock.createNewIModel({ accessToken, iTwinId: HubMock.iTwinId, iModelName: \"DiscardOrphan\" });\r\n briefcase = await HubWrappers.downloadAndOpenBriefcase({ accessToken, iTwinId: HubMock.iTwinId, iModelId });\r\n\r\n const baselineColumns = physicalColumns(briefcase);\r\n chai.expect(baselineColumns.length).to.equal(mappedNonVirtualColumnCount(briefcase), \"baseline must be consistent\");\r\n\r\n // Plain (non-dynamic) schema whose aspect needs more shared columns than the table has -> ALTER TABLE ADD COLUMN.\r\n const sharedColumnCount = baselineColumns.filter((name) => /^ps\\d+$/i.test(name)).length;\r\n await briefcase.importSchemaStrings([schemaWithWideMultiAspect(sharedColumnCount + extraColumns)]);\r\n chai.expect(physicalColumns(briefcase).length).to.equal(baselineColumns.length + extraColumns, \"import should add physical columns\");\r\n chai.expect(mappedNonVirtualColumnCount(briefcase)).to.equal(baselineColumns.length + extraColumns);\r\n\r\n // Abandon the un-pushed schema import: ec_* is reverted, the DDL is not.\r\n await briefcase.discardChanges();\r\n const schemaCount = briefcase.withSqliteStatement(\"SELECT COUNT(*) FROM ec_Schema WHERE Name = 'WideAspect'\", (stmt) => {\r\n stmt.step();\r\n return stmt.getValue(0).getInteger();\r\n });\r\n chai.expect(schemaCount).to.equal(0, \"schema should be gone after discardChanges\");\r\n\r\n const mapped = mappedNonVirtualColumnCount(briefcase);\r\n const physical = physicalColumns(briefcase).length;\r\n chai.expect(mapped).to.equal(baselineColumns.length);\r\n chai.expect(physical - mapped).to.equal(extraColumns, `orphan columns left in ${tableName}`);\r\n\r\n // A subsequent regular schema import must tolerate the unused shared columns left behind.\r\n await briefcase.importSchemaStrings([unrelatedSchema]);\r\n chai.expect(physicalColumns(briefcase).length).to.equal(physical);\r\n });\r\n});\r\n"]}
@@ -174,10 +174,12 @@ describe("iModel geolocation", () => {
174
174
  datumOrGCS = datum;
175
175
  const testFile = IModelTestUtils.prepareOutputFile("IModel", fileName);
176
176
  const iModel = SnapshotDb.createEmpty(testFile, args);
177
- withEditTxn(iModel, (txn) => {
178
- iModel.setGeographicCoordinateSystem(fileGCS);
179
- txn.updateIModelProps();
180
- });
177
+ if (fileGCS) {
178
+ withEditTxn(iModel, (txn) => {
179
+ iModel.setGeographicCoordinateSystem(fileGCS);
180
+ txn.updateIModelProps();
181
+ });
182
+ }
181
183
  const testPoint1 = [];
182
184
  testPoint1.push(inputCoord);
183
185
  const requestProps1 = { target: datumOrGCS, iModelCoords: testPoint1 };
@@ -412,8 +414,8 @@ describe("iModel geolocation", () => {
412
414
  }, verticalCRS: { id: "ELLIPSOID" },
413
415
  };
414
416
  await convertTest("Error3.bim", userGCSWithinexistentGridFile, "WGS84", { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoDatumConverter });
415
- // The model GCS is not valid
416
- await convertTest("Error4.bim", { horizontalCRS: { id: "badfood" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "OSGB-GPS-2015" }, verticalCRS: { id: "GEOID" } }, { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoGCSDefined });
417
+ // The model has no GCS.
418
+ await convertTest("Error4.bim", undefined, { horizontalCRS: { id: "OSGB-GPS-2015" }, verticalCRS: { id: "GEOID" } }, { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoGCSDefined });
417
419
  // The given GCS is not valid
418
420
  await convertTest("Error5.bim", { horizontalCRS: { id: "UTM84-17N" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "badfood" }, verticalCRS: { id: "GEOID" } }, { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoGCSDefined });
419
421
  });