@diamondslab/diamonds 1.0.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 (229) hide show
  1. package/README.md +618 -0
  2. package/diamonds/README.md +3 -0
  3. package/dist/core/CallbackManager.d.ts +13 -0
  4. package/dist/core/CallbackManager.d.ts.map +1 -0
  5. package/dist/core/CallbackManager.js +95 -0
  6. package/dist/core/CallbackManager.js.map +1 -0
  7. package/dist/core/DeploymentManager.d.ts +10 -0
  8. package/dist/core/DeploymentManager.d.ts.map +1 -0
  9. package/dist/core/DeploymentManager.js +50 -0
  10. package/dist/core/DeploymentManager.js.map +1 -0
  11. package/dist/core/Diamond.d.ts +58 -0
  12. package/dist/core/Diamond.d.ts.map +1 -0
  13. package/dist/core/Diamond.js +146 -0
  14. package/dist/core/Diamond.js.map +1 -0
  15. package/dist/core/DiamondDeployer.d.ts +10 -0
  16. package/dist/core/DiamondDeployer.d.ts.map +1 -0
  17. package/dist/core/DiamondDeployer.js +33 -0
  18. package/dist/core/DiamondDeployer.js.map +1 -0
  19. package/dist/core/index.d.ts +5 -0
  20. package/dist/core/index.d.ts.map +1 -0
  21. package/dist/core/index.js +12 -0
  22. package/dist/core/index.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +22 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/repositories/DBDeploymentRepository.d.ts +1 -0
  28. package/dist/repositories/DBDeploymentRepository.d.ts.map +1 -0
  29. package/dist/repositories/DBDeploymentRepository.js +20 -0
  30. package/dist/repositories/DBDeploymentRepository.js.map +1 -0
  31. package/dist/repositories/DeploymentRepository.d.ts +8 -0
  32. package/dist/repositories/DeploymentRepository.d.ts.map +1 -0
  33. package/dist/repositories/DeploymentRepository.js +7 -0
  34. package/dist/repositories/DeploymentRepository.js.map +1 -0
  35. package/dist/repositories/FileDeploymentRepository.d.ts +18 -0
  36. package/dist/repositories/FileDeploymentRepository.d.ts.map +1 -0
  37. package/dist/repositories/FileDeploymentRepository.js +58 -0
  38. package/dist/repositories/FileDeploymentRepository.js.map +1 -0
  39. package/dist/repositories/databaseHandler.d.ts +1 -0
  40. package/dist/repositories/databaseHandler.d.ts.map +1 -0
  41. package/dist/repositories/databaseHandler.js +13 -0
  42. package/dist/repositories/databaseHandler.js.map +1 -0
  43. package/dist/repositories/index.d.ts +4 -0
  44. package/dist/repositories/index.d.ts.map +1 -0
  45. package/dist/repositories/index.js +20 -0
  46. package/dist/repositories/index.js.map +1 -0
  47. package/dist/repositories/jsonFileHandler.d.ts +81 -0
  48. package/dist/repositories/jsonFileHandler.d.ts.map +1 -0
  49. package/dist/repositories/jsonFileHandler.js +223 -0
  50. package/dist/repositories/jsonFileHandler.js.map +1 -0
  51. package/dist/repositories/prismaDBHandler.d.ts +1 -0
  52. package/dist/repositories/prismaDBHandler.d.ts.map +1 -0
  53. package/dist/repositories/prismaDBHandler.js +11 -0
  54. package/dist/repositories/prismaDBHandler.js.map +1 -0
  55. package/dist/schemas/DeploymentSchema.d.ts +309 -0
  56. package/dist/schemas/DeploymentSchema.d.ts.map +1 -0
  57. package/dist/schemas/DeploymentSchema.js +56 -0
  58. package/dist/schemas/DeploymentSchema.js.map +1 -0
  59. package/dist/schemas/index.d.ts +2 -0
  60. package/dist/schemas/index.d.ts.map +1 -0
  61. package/dist/schemas/index.js +18 -0
  62. package/dist/schemas/index.js.map +1 -0
  63. package/dist/strategies/BaseDeploymentStrategy.d.ts +41 -0
  64. package/dist/strategies/BaseDeploymentStrategy.d.ts.map +1 -0
  65. package/dist/strategies/BaseDeploymentStrategy.js +545 -0
  66. package/dist/strategies/BaseDeploymentStrategy.js.map +1 -0
  67. package/dist/strategies/DeploymentStrategy.d.ts +19 -0
  68. package/dist/strategies/DeploymentStrategy.d.ts.map +1 -0
  69. package/dist/strategies/DeploymentStrategy.js +3 -0
  70. package/dist/strategies/DeploymentStrategy.js.map +1 -0
  71. package/dist/strategies/LocalDeploymentStrategy.d.ts +4 -0
  72. package/dist/strategies/LocalDeploymentStrategy.d.ts.map +1 -0
  73. package/dist/strategies/LocalDeploymentStrategy.js +8 -0
  74. package/dist/strategies/LocalDeploymentStrategy.js.map +1 -0
  75. package/dist/strategies/OZDefenderDeploymentStrategy.d.ts +62 -0
  76. package/dist/strategies/OZDefenderDeploymentStrategy.d.ts.map +1 -0
  77. package/dist/strategies/OZDefenderDeploymentStrategy.js +757 -0
  78. package/dist/strategies/OZDefenderDeploymentStrategy.js.map +1 -0
  79. package/dist/strategies/RPCDeploymentStrategy.d.ts +139 -0
  80. package/dist/strategies/RPCDeploymentStrategy.d.ts.map +1 -0
  81. package/dist/strategies/RPCDeploymentStrategy.js +710 -0
  82. package/dist/strategies/RPCDeploymentStrategy.js.map +1 -0
  83. package/dist/strategies/index.d.ts +6 -0
  84. package/dist/strategies/index.d.ts.map +1 -0
  85. package/dist/strategies/index.js +12 -0
  86. package/dist/strategies/index.js.map +1 -0
  87. package/dist/types/config.d.ts +26 -0
  88. package/dist/types/config.d.ts.map +1 -0
  89. package/dist/types/config.js +3 -0
  90. package/dist/types/config.js.map +1 -0
  91. package/dist/types/defender.d.ts +22 -0
  92. package/dist/types/defender.d.ts.map +1 -0
  93. package/dist/types/defender.js +3 -0
  94. package/dist/types/defender.js.map +1 -0
  95. package/dist/types/deployments.d.ts +71 -0
  96. package/dist/types/deployments.d.ts.map +1 -0
  97. package/dist/types/deployments.js +20 -0
  98. package/dist/types/deployments.js.map +1 -0
  99. package/dist/types/index.d.ts +5 -0
  100. package/dist/types/index.d.ts.map +1 -0
  101. package/dist/types/index.js +21 -0
  102. package/dist/types/index.js.map +1 -0
  103. package/dist/types/rpc.d.ts +35 -0
  104. package/dist/types/rpc.d.ts.map +1 -0
  105. package/dist/types/rpc.js +3 -0
  106. package/dist/types/rpc.js.map +1 -0
  107. package/dist/utils/common.d.ts +20 -0
  108. package/dist/utils/common.d.ts.map +1 -0
  109. package/dist/utils/common.js +45 -0
  110. package/dist/utils/common.js.map +1 -0
  111. package/dist/utils/configurationResolver.d.ts +30 -0
  112. package/dist/utils/configurationResolver.d.ts.map +1 -0
  113. package/dist/utils/configurationResolver.js +151 -0
  114. package/dist/utils/configurationResolver.js.map +1 -0
  115. package/dist/utils/contractMapping.d.ts +29 -0
  116. package/dist/utils/contractMapping.d.ts.map +1 -0
  117. package/dist/utils/contractMapping.js +224 -0
  118. package/dist/utils/contractMapping.js.map +1 -0
  119. package/dist/utils/defenderClients.d.ts +5 -0
  120. package/dist/utils/defenderClients.d.ts.map +1 -0
  121. package/dist/utils/defenderClients.js +21 -0
  122. package/dist/utils/defenderClients.js.map +1 -0
  123. package/dist/utils/defenderStore.d.ts +14 -0
  124. package/dist/utils/defenderStore.d.ts.map +1 -0
  125. package/dist/utils/defenderStore.js +92 -0
  126. package/dist/utils/defenderStore.js.map +1 -0
  127. package/dist/utils/diamondAbiGenerator.d.ts +113 -0
  128. package/dist/utils/diamondAbiGenerator.d.ts.map +1 -0
  129. package/dist/utils/diamondAbiGenerator.js +415 -0
  130. package/dist/utils/diamondAbiGenerator.js.map +1 -0
  131. package/dist/utils/diffDeployedFacets.d.ts +26 -0
  132. package/dist/utils/diffDeployedFacets.d.ts.map +1 -0
  133. package/dist/utils/diffDeployedFacets.js +106 -0
  134. package/dist/utils/diffDeployedFacets.js.map +1 -0
  135. package/dist/utils/index.d.ts +16 -0
  136. package/dist/utils/index.d.ts.map +1 -0
  137. package/dist/utils/index.js +35 -0
  138. package/dist/utils/index.js.map +1 -0
  139. package/dist/utils/loupe.d.ts +44 -0
  140. package/dist/utils/loupe.d.ts.map +1 -0
  141. package/dist/utils/loupe.js +128 -0
  142. package/dist/utils/loupe.js.map +1 -0
  143. package/dist/utils/rpcStore.d.ts +36 -0
  144. package/dist/utils/rpcStore.d.ts.map +1 -0
  145. package/dist/utils/rpcStore.js +166 -0
  146. package/dist/utils/rpcStore.js.map +1 -0
  147. package/dist/utils/signer.d.ts +36 -0
  148. package/dist/utils/signer.d.ts.map +1 -0
  149. package/dist/utils/signer.js +91 -0
  150. package/dist/utils/signer.js.map +1 -0
  151. package/dist/utils/txlogging.d.ts +13 -0
  152. package/dist/utils/txlogging.d.ts.map +1 -0
  153. package/dist/utils/txlogging.js +87 -0
  154. package/dist/utils/txlogging.js.map +1 -0
  155. package/dist/utils/workspaceSetup.d.ts +32 -0
  156. package/dist/utils/workspaceSetup.d.ts.map +1 -0
  157. package/dist/utils/workspaceSetup.js +311 -0
  158. package/dist/utils/workspaceSetup.js.map +1 -0
  159. package/docs/DIAMOND_ABI_CONFIGURATION_SUMMARY.md +40 -0
  160. package/docs/DIAMOND_ABI_GENERATION.md +220 -0
  161. package/docs/DIAMOND_ABI_GENERATOR_EXAMPLES.md +1204 -0
  162. package/docs/DIAMOND_ABI_GENERATOR_IMPLEMENTATION.md +947 -0
  163. package/docs/DIAMOND_ABI_GENERATOR_QUICK_REFERENCE.md +336 -0
  164. package/docs/README-DEFENDER.md +394 -0
  165. package/docs/README_DIAMOND_ABI_GENERATOR.md +303 -0
  166. package/docs/ROADMAP.md +250 -0
  167. package/docs/assets/image.png +0 -0
  168. package/docs/defender-integration.md +451 -0
  169. package/docs/diamond_module-BaseStrategy_design-v2.uxf +247 -0
  170. package/docs/diamond_module-BaseStrategy_design.uxf +272 -0
  171. package/docs/monitoring-troubleshooting.md +556 -0
  172. package/docs/testing-guide.md +713 -0
  173. package/examples/Diamond_Config_and_Deployment_examples/diamonds/ProxyDiamond/callbacks/ERC20ProxyFacet.ts +31 -0
  174. package/examples/Diamond_Config_and_Deployment_examples/diamonds/ProxyDiamond/proxydiamond.config.json +27 -0
  175. package/examples/Local_Hardhat_Deployer_Script_example/LocalDiamondDeployer.ts +180 -0
  176. package/examples/OZ_Defender_Deployer_Script_example/OZDiamondDeployer.ts +107 -0
  177. package/examples/OZ_Defender_Deployer_Script_example/run-oz-deploy.ts +17 -0
  178. package/examples/Test_examples/ProxyDiamondDeployment.test.ts +202 -0
  179. package/examples/defender-deployment/.env.example +35 -0
  180. package/examples/defender-deployment/README.md +415 -0
  181. package/examples/defender-deployment/contracts/ExampleDiamond.sol +41 -0
  182. package/examples/defender-deployment/contracts/ExampleFacet1.sol +84 -0
  183. package/examples/defender-deployment/contracts/ExampleFacet2.sol +104 -0
  184. package/examples/defender-deployment/contracts/UpgradeFacet.sol +92 -0
  185. package/examples/defender-deployment/deploy-script.ts +170 -0
  186. package/examples/defender-deployment/diamond-config.json +36 -0
  187. package/examples/defender-deployment/upgrade-script.ts +237 -0
  188. package/examples/hardhat-diamonds-config.example.ts +41 -0
  189. package/package.json +228 -0
  190. package/src/core/CallbackManager.ts +70 -0
  191. package/src/core/DeploymentManager.ts +64 -0
  192. package/src/core/Diamond.ts +197 -0
  193. package/src/core/DiamondDeployer.ts +36 -0
  194. package/src/core/index.ts +4 -0
  195. package/src/index.ts +5 -0
  196. package/src/repositories/DBDeploymentRepository.ts +22 -0
  197. package/src/repositories/DeploymentRepository.ts +12 -0
  198. package/src/repositories/FileDeploymentRepository.ts +67 -0
  199. package/src/repositories/databaseHandler.ts +14 -0
  200. package/src/repositories/index.ts +4 -0
  201. package/src/repositories/jsonFileHandler.ts +252 -0
  202. package/src/repositories/prismaDBHandler.ts +10 -0
  203. package/src/schemas/DeploymentSchema.ts +71 -0
  204. package/src/schemas/index.ts +1 -0
  205. package/src/strategies/BaseDeploymentStrategy.ts +649 -0
  206. package/src/strategies/DeploymentStrategy.ts +25 -0
  207. package/src/strategies/LocalDeploymentStrategy.ts +5 -0
  208. package/src/strategies/OZDefenderDeploymentStrategy.ts +849 -0
  209. package/src/strategies/RPCDeploymentStrategy.ts +881 -0
  210. package/src/strategies/index.ts +5 -0
  211. package/src/types/config.ts +34 -0
  212. package/src/types/defender.ts +24 -0
  213. package/src/types/deployments.ts +102 -0
  214. package/src/types/index.ts +4 -0
  215. package/src/types/rpc.ts +37 -0
  216. package/src/utils/common.ts +54 -0
  217. package/src/utils/configurationResolver.ts +141 -0
  218. package/src/utils/contractMapping.ts +220 -0
  219. package/src/utils/defenderClients.ts +22 -0
  220. package/src/utils/defenderStore.ts +62 -0
  221. package/src/utils/diamondAbiGenerator.ts +523 -0
  222. package/src/utils/diffDeployedFacets.ts +131 -0
  223. package/src/utils/index.ts +15 -0
  224. package/src/utils/loupe.ts +159 -0
  225. package/src/utils/rpcStore.ts +152 -0
  226. package/src/utils/signer.ts +93 -0
  227. package/src/utils/txlogging.ts +97 -0
  228. package/src/utils/workspaceSetup.ts +315 -0
  229. package/test/README.md +136 -0
@@ -0,0 +1,713 @@
1
+ # Testing Guide for Diamonds Module
2
+
3
+ ## Overview
4
+
5
+ This guide covers comprehensive testing strategies for the Diamonds module, including unit tests, integration tests, and end-to-end testing with OpenZeppelin Defender integration.
6
+
7
+ ## Testing Architecture
8
+
9
+ ### Test Structure
10
+
11
+ ```bash
12
+ test/
13
+ ├── unit/ # Unit tests for individual components
14
+ │ ├── core/ # Core module tests
15
+ │ │ ├── Diamond.test.ts
16
+ │ │ ├── DiamondDeployer.test.ts
17
+ │ │ └── DeploymentManager.test.ts
18
+ │ ├── strategies/ # Strategy pattern tests
19
+ │ │ ├── BaseDeploymentStrategy.test.ts
20
+ │ │ ├── LocalDeploymentStrategy.test.ts
21
+ │ │ └── OZDefenderDeploymentStrategy.test.ts
22
+ │ ├── repositories/ # Repository pattern tests
23
+ │ │ └── FileDeploymentRepository.test.ts
24
+ │ └── utils/ # Utility function tests
25
+ │ ├── common.test.ts
26
+ │ └── loupe.test.ts
27
+ ├── integration/ # Integration tests
28
+ │ ├── defender/ # Defender integration tests
29
+ │ │ ├── setup/ # Test setup utilities
30
+ │ │ │ ├── defender-setup.ts
31
+ │ │ │ ├── hardhat-fork.ts
32
+ │ │ │ └── mock-contracts.ts
33
+ │ │ ├── deployment.test.ts # End-to-end deployment tests
34
+ │ │ ├── upgrade.test.ts # Upgrade scenario tests
35
+ │ │ ├── multi-facet.test.ts # Complex diamond tests
36
+ │ │ └── error-handling.test.ts # Error scenario tests
37
+ │ ├── local/ # Local deployment integration
38
+ │ │ └── localDeployment.test.ts
39
+ │ └── fixtures/ # Test fixtures and data
40
+ │ ├── diamond-configs/
41
+ │ └── mock-facets/
42
+ ├── helpers/ # Test helper utilities
43
+ │ ├── defenderMock.ts
44
+ │ └── contractHelpers.ts
45
+ └── setup.ts # Global test setup
46
+ ```
47
+
48
+ ### Test Categories
49
+
50
+ 1. **Unit Tests**: Test individual components in isolation
51
+ 2. **Integration Tests**: Test component interactions and workflows
52
+ 3. **End-to-End Tests**: Test complete deployment scenarios
53
+ 4. **Performance Tests**: Test deployment speed and resource usage
54
+ 5. **Security Tests**: Test access controls and error handling
55
+
56
+ ## Running Tests
57
+
58
+ ### Prerequisites
59
+
60
+ ```bash
61
+ # Install dependencies
62
+ npm install
63
+
64
+ # Setup environment
65
+ cp .env.example .env
66
+ # Edit .env with your test configuration
67
+ ```
68
+
69
+ ### Basic Test Commands
70
+
71
+ ```bash
72
+ # Run all tests
73
+ npm test
74
+
75
+ # Run unit tests only
76
+ npm run test:unit
77
+
78
+ # Run integration tests only
79
+ npm run test:integration
80
+
81
+ # Run with coverage
82
+ npm run test:coverage
83
+
84
+ # Run specific test file
85
+ npx mocha test/unit/core/Diamond.test.ts
86
+
87
+ # Run tests with verbose output
88
+ npm test -- --reporter spec
89
+
90
+ # Run tests with timeout adjustment
91
+ npm test -- --timeout 300000
92
+ ```
93
+
94
+ ### Environment-Specific Testing
95
+
96
+ ```bash
97
+ # Test against local hardhat network
98
+ TEST_NETWORK=hardhat npm test
99
+
100
+ # Test against Sepolia testnet (requires RPC URL)
101
+ TEST_NETWORK=sepolia npm test
102
+
103
+ # Test with Defender mocking enabled
104
+ ENABLE_DEFENDER_MOCKING=true npm test
105
+
106
+ # Test with real Defender API (requires credentials)
107
+ ENABLE_DEFENDER_MOCKING=false npm test
108
+ ```
109
+
110
+ ## Unit Testing
111
+
112
+ ### Testing Core Components
113
+
114
+ ```typescript
115
+ // Example: Diamond.test.ts
116
+ describe('Diamond', () => {
117
+ let diamond: Diamond;
118
+ let config: DiamondConfig;
119
+ let repository: FileDeploymentRepository;
120
+
121
+ beforeEach(() => {
122
+ config = {
123
+ diamondName: 'TestDiamond',
124
+ networkName: 'hardhat',
125
+ chainId: 31337,
126
+ // ... other config
127
+ };
128
+
129
+ repository = new FileDeploymentRepository(config);
130
+ diamond = new Diamond(config, repository);
131
+ });
132
+
133
+ describe('initialization', () => {
134
+ it('should initialize with correct configuration', () => {
135
+ expect(diamond.diamondName).to.equal('TestDiamond');
136
+ expect(diamond.getDiamondConfig().networkName).to.equal('hardhat');
137
+ });
138
+ });
139
+
140
+ describe('state management', () => {
141
+ it('should update deployed diamond data correctly', () => {
142
+ const testData = {
143
+ DiamondAddress: '0x123...',
144
+ DeployerAddress: '0x456...',
145
+ DeployedFacets: {}
146
+ };
147
+
148
+ diamond.updateDeployedDiamondData(testData);
149
+ const retrieved = diamond.getDeployedDiamondData();
150
+
151
+ expect(retrieved.DiamondAddress).to.equal(testData.DiamondAddress);
152
+ });
153
+ });
154
+ });
155
+ ```
156
+
157
+ ### Testing Strategy Pattern
158
+
159
+ ```typescript
160
+ // Example: OZDefenderDeploymentStrategy.test.ts
161
+ describe('OZDefenderDeploymentStrategy', () => {
162
+ let strategy: OZDefenderDeploymentStrategy;
163
+ let mocks: MockDefenderClients;
164
+
165
+ beforeEach(() => {
166
+ mocks = createDefenderMocks();
167
+
168
+ // Mock the defender clients module
169
+ sinon.stub(defenderClientsModule, 'deployClient').value(mocks.mockDeployClient);
170
+ sinon.stub(defenderClientsModule, 'adminClient').value(mocks.mockDefender);
171
+
172
+ strategy = new OZDefenderDeploymentStrategy(
173
+ 'test-api-key',
174
+ 'test-api-secret',
175
+ '0x123...',
176
+ true, // auto-approve
177
+ '0x456...',
178
+ 'Safe'
179
+ );
180
+ });
181
+
182
+ describe('deployment tasks', () => {
183
+ it('should submit deployments to Defender correctly', async () => {
184
+ setupSuccessfulDeploymentMocks(mocks);
185
+
186
+ await strategy.deployDiamondTasks(diamond);
187
+
188
+ expect(mocks.mockDeployClient.deployContract.callCount).to.equal(2); // DiamondCutFacet + Diamond
189
+ });
190
+ });
191
+ });
192
+ ```
193
+
194
+ ### Testing Repository Pattern
195
+
196
+ ```typescript
197
+ // Example: FileDeploymentRepository.test.ts
198
+ describe('FileDeploymentRepository', () => {
199
+ let repository: FileDeploymentRepository;
200
+ let tempDir: string;
201
+
202
+ beforeEach(async () => {
203
+ tempDir = path.join(__dirname, '.tmp-test');
204
+ await fs.ensureDir(tempDir);
205
+
206
+ const config = {
207
+ diamondName: 'TestDiamond',
208
+ deploymentsPath: tempDir,
209
+ // ... other config
210
+ };
211
+
212
+ repository = new FileDeploymentRepository(config);
213
+ });
214
+
215
+ afterEach(async () => {
216
+ await fs.remove(tempDir);
217
+ });
218
+
219
+ describe('configuration management', () => {
220
+ it('should save and load deploy config correctly', async () => {
221
+ const testConfig = {
222
+ protocolVersion: 1.0,
223
+ facets: {
224
+ TestFacet: {
225
+ priority: 100,
226
+ versions: { "1.0": {} }
227
+ }
228
+ }
229
+ };
230
+
231
+ await repository.saveDeployConfig(testConfig);
232
+ const loaded = repository.loadDeployConfig();
233
+
234
+ expect(loaded.protocolVersion).to.equal(1.0);
235
+ expect(loaded.facets.TestFacet.priority).to.equal(100);
236
+ });
237
+ });
238
+ });
239
+ ```
240
+
241
+ ## Integration Testing
242
+
243
+ ### Defender Integration Tests
244
+
245
+ ```typescript
246
+ // Example: deployment.test.ts
247
+ describe('Integration: Defender Deployment', () => {
248
+ let diamond: Diamond;
249
+ let strategy: OZDefenderDeploymentStrategy;
250
+ let deployer: DiamondDeployer;
251
+ let mocks: MockDefenderClients;
252
+
253
+ beforeEach(async () => {
254
+ // Setup test environment
255
+ mocks = createDefenderMocks();
256
+ setupSuccessfulDeploymentMocks(mocks);
257
+
258
+ // Create diamond and strategy
259
+ diamond = new Diamond(config, repository);
260
+ diamond.setProvider(ethers.provider);
261
+ diamond.setSigner(await ethers.getSigners()[0]);
262
+
263
+ strategy = new OZDefenderDeploymentStrategy(/* config */);
264
+ deployer = new DiamondDeployer(diamond, strategy);
265
+ });
266
+
267
+ describe('complete deployment flow', () => {
268
+ it('should deploy diamond with all facets', async function () {
269
+ this.timeout(60000); // Extended timeout for integration tests
270
+
271
+ await deployer.deployDiamond();
272
+
273
+ // Verify deployment sequence
274
+ expect(mocks.mockDeployClient.deployContract.callCount).to.be.at.least(4);
275
+ expect(mocks.mockProposalClient.create.called).to.be.true;
276
+
277
+ // Verify state persistence
278
+ const deployedData = diamond.getDeployedDiamondData();
279
+ expect(deployedData.DiamondAddress).to.not.be.undefined;
280
+ });
281
+ });
282
+
283
+ describe('upgrade scenarios', () => {
284
+ it('should handle facet upgrades correctly', async () => {
285
+ // Setup existing deployment
286
+ const existingData = {
287
+ DiamondAddress: '0x123...',
288
+ DeployedFacets: {
289
+ TestFacet: { version: 0, address: '0x456...' }
290
+ }
291
+ };
292
+ diamond.updateDeployedDiamondData(existingData);
293
+
294
+ // Update configuration for upgrade
295
+ const config = repository.loadDeployConfig();
296
+ config.protocolVersion = 1.0;
297
+ config.facets.TestFacet.versions["1.0"] = {
298
+ upgradeInit: "upgradeToV1()"
299
+ };
300
+ await repository.saveDeployConfig(config);
301
+
302
+ // Execute upgrade
303
+ await deployer.deployDiamond();
304
+
305
+ // Should only deploy new version
306
+ expect(mocks.mockDeployClient.deployContract.callCount).to.equal(1);
307
+ });
308
+ });
309
+ });
310
+ ```
311
+
312
+ ### Network Fork Testing
313
+
314
+ ```typescript
315
+ // Example: hardhat-fork.ts
316
+ export async function setupForkTest(network: string, blockNumber?: number) {
317
+ const forkConfig = {
318
+ url: getNetworkUrl(network),
319
+ blockNumber
320
+ };
321
+
322
+ await network.provider.request({
323
+ method: "hardhat_reset",
324
+ params: [{
325
+ forking: forkConfig
326
+ }]
327
+ });
328
+
329
+ // Setup test accounts with realistic balances
330
+ const signers = await ethers.getSigners();
331
+ for (const signer of signers.slice(0, 3)) {
332
+ await network.provider.send("hardhat_setBalance", [
333
+ signer.address,
334
+ "0x1000000000000000000000" // 1000 ETH
335
+ ]);
336
+ }
337
+
338
+ return signers;
339
+ }
340
+
341
+ // Usage in tests
342
+ describe('Fork Integration Tests', () => {
343
+ beforeEach(async () => {
344
+ if (process.env.TEST_NETWORK !== 'hardhat') {
345
+ await setupForkTest(process.env.TEST_NETWORK);
346
+ }
347
+ });
348
+
349
+ it('should deploy on forked network', async () => {
350
+ // Test with real network state
351
+ });
352
+ });
353
+ ```
354
+
355
+ ## Mock Testing
356
+
357
+ ### Defender API Mocking
358
+
359
+ ```typescript
360
+ // Example: defenderMock.ts
361
+ export function createRealisticDefenderMocks() {
362
+ const mocks = createDefenderMocks();
363
+
364
+ // Add realistic delays
365
+ addNetworkDelay(mocks, 100);
366
+
367
+ // Add occasional failures for robustness testing
368
+ let callCount = 0;
369
+ const originalDeploy = mocks.mockDeployClient.deployContract;
370
+
371
+ mocks.mockDeployClient.deployContract.callsFake(async (...args) => {
372
+ callCount++;
373
+
374
+ // Simulate 5% failure rate
375
+ if (callCount % 20 === 0) {
376
+ throw new Error('Simulated network error');
377
+ }
378
+
379
+ return originalDeploy.apply(mocks.mockDeployClient, args);
380
+ });
381
+
382
+ return mocks;
383
+ }
384
+ ```
385
+
386
+ ### Contract Mocking
387
+
388
+ ```typescript
389
+ // Example: mock-contracts.ts
390
+ export function createMockFacetContracts() {
391
+ const mockContracts = {
392
+ DiamondCutFacet: {
393
+ interface: new ethers.utils.Interface([
394
+ 'function diamondCut((address,uint8,bytes4[])[],address,bytes)'
395
+ ]),
396
+ address: '0x1234567890123456789012345678901234567890'
397
+ },
398
+
399
+ DiamondLoupeFacet: {
400
+ interface: new ethers.utils.Interface([
401
+ 'function facets() external view returns ((address,bytes4[])[])'
402
+ ]),
403
+ address: '0x2345678901234567890123456789012345678901'
404
+ },
405
+
406
+ TestFacet: {
407
+ interface: new ethers.utils.Interface([
408
+ 'function setValue(uint256)',
409
+ 'function getValue() view returns (uint256)'
410
+ ]),
411
+ address: '0x3456789012345678901234567890123456789012'
412
+ }
413
+ };
414
+
415
+ return mockContracts;
416
+ }
417
+ ```
418
+
419
+ ## Performance Testing
420
+
421
+ ### Deployment Speed Tests
422
+
423
+ ```typescript
424
+ describe('Performance Tests', () => {
425
+ it('should complete deployment within reasonable time', async function () {
426
+ this.timeout(120000); // 2 minutes max
427
+
428
+ const startTime = Date.now();
429
+ await deployer.deployDiamond();
430
+ const endTime = Date.now();
431
+
432
+ const deploymentTime = endTime - startTime;
433
+ expect(deploymentTime).to.be.lessThan(60000); // Should complete in under 1 minute
434
+
435
+ console.log(`Deployment completed in ${deploymentTime}ms`);
436
+ });
437
+
438
+ it('should handle concurrent deployments efficiently', async function () {
439
+ this.timeout(300000); // 5 minutes for concurrent tests
440
+
441
+ const deployments = Array(3).fill(null).map(() =>
442
+ createIndependentDeployer().deployDiamond()
443
+ );
444
+
445
+ const results = await Promise.allSettled(deployments);
446
+ const successCount = results.filter(r => r.status === 'fulfilled').length;
447
+
448
+ expect(successCount).to.equal(3);
449
+ });
450
+ });
451
+ ```
452
+
453
+ ### Memory Usage Tests
454
+
455
+ ```typescript
456
+ describe('Memory Usage Tests', () => {
457
+ it('should not leak memory during large deployments', async () => {
458
+ const initialMemory = process.memoryUsage().heapUsed;
459
+
460
+ // Deploy large diamond with many facets
461
+ await deployLargeDiamond();
462
+
463
+ // Force garbage collection
464
+ if (global.gc) {
465
+ global.gc();
466
+ }
467
+
468
+ const finalMemory = process.memoryUsage().heapUsed;
469
+ const memoryIncrease = finalMemory - initialMemory;
470
+
471
+ // Memory increase should be reasonable
472
+ expect(memoryIncrease).to.be.lessThan(50 * 1024 * 1024); // 50MB max
473
+ });
474
+ });
475
+ ```
476
+
477
+ ## Error Testing
478
+
479
+ ### Network Error Simulation
480
+
481
+ ```typescript
482
+ describe('Error Handling Tests', () => {
483
+ it('should retry on network errors', async () => {
484
+ let attempts = 0;
485
+
486
+ mocks.mockDeployClient.deployContract.callsFake(() => {
487
+ attempts++;
488
+ if (attempts < 3) {
489
+ throw new Error('Network timeout');
490
+ }
491
+ return Promise.resolve({ deploymentId: 'success', status: 'pending' });
492
+ });
493
+
494
+ await deployer.deployDiamond();
495
+
496
+ expect(attempts).to.equal(3);
497
+ });
498
+
499
+ it('should fail gracefully on persistent errors', async () => {
500
+ mocks.mockDeployClient.deployContract.rejects(new Error('Persistent failure'));
501
+
502
+ try {
503
+ await deployer.deployDiamond();
504
+ expect.fail('Expected deployment to fail');
505
+ } catch (error) {
506
+ expect(error.message).to.include('Persistent failure');
507
+ }
508
+ });
509
+ });
510
+ ```
511
+
512
+ ### State Corruption Testing
513
+
514
+ ```typescript
515
+ describe('State Corruption Tests', () => {
516
+ it('should recover from corrupted deployment data', async () => {
517
+ // Simulate corrupted state
518
+ const corruptedData = {
519
+ DiamondAddress: 'invalid-address',
520
+ DeployedFacets: null
521
+ };
522
+
523
+ diamond.updateDeployedDiamondData(corruptedData);
524
+
525
+ // Should detect and recover
526
+ await deployer.deployDiamond();
527
+
528
+ const finalData = diamond.getDeployedDiamondData();
529
+ expect(finalData.DiamondAddress).to.match(/^0x[a-fA-F0-9]{40}$/);
530
+ });
531
+ });
532
+ ```
533
+
534
+ ## Test Configuration
535
+
536
+ ### Environment Variables
537
+
538
+ ```bash
539
+ # .env.test
540
+ TEST_NETWORK=hardhat
541
+ ENABLE_DEFENDER_MOCKING=true
542
+ TEST_TIMEOUT=300000
543
+ VERBOSE_TESTING=true
544
+ LOG_LEVEL=debug
545
+
546
+ # For real API testing
547
+ DEFENDER_API_KEY=test_api_key
548
+ DEFENDER_API_SECRET=test_api_secret
549
+ TEST_SAFE_ADDRESS=0x123...
550
+ ```
551
+
552
+ ### Custom Test Configuration
553
+
554
+ ```typescript
555
+ // test/setup.ts
556
+ import { config } from 'dotenv';
557
+ import chai from 'chai';
558
+ import chaiAsPromised from 'chai-as-promised';
559
+
560
+ // Load test environment
561
+ config({ path: '.env.test' });
562
+
563
+ // Setup chai
564
+ chai.use(chaiAsPromised);
565
+
566
+ // Global test timeout
567
+ const timeout = parseInt(process.env.TEST_TIMEOUT || '60000');
568
+ beforeEach(function() {
569
+ this.timeout(timeout);
570
+ });
571
+
572
+ // Setup global test utilities
573
+ global.testUtils = {
574
+ createTempDir: () => {
575
+ return path.join(__dirname, '.tmp', `test-${Date.now()}`);
576
+ },
577
+
578
+ cleanupTempDirs: async () => {
579
+ const tempBase = path.join(__dirname, '.tmp');
580
+ if (await fs.pathExists(tempBase)) {
581
+ await fs.remove(tempBase);
582
+ }
583
+ }
584
+ };
585
+ ```
586
+
587
+ ## Continuous Integration
588
+
589
+ ### GitHub Actions Configuration
590
+
591
+ ```yaml
592
+ # .github/workflows/test.yml
593
+ name: Test Suite
594
+
595
+ on: [push, pull_request]
596
+
597
+ jobs:
598
+ test:
599
+ runs-on: ubuntu-latest
600
+
601
+ strategy:
602
+ matrix:
603
+ node-version: [16, 18, 20]
604
+ test-type: [unit, integration]
605
+
606
+ steps:
607
+ - uses: actions/checkout@v3
608
+
609
+ - name: Setup Node.js
610
+ uses: actions/setup-node@v3
611
+ with:
612
+ node-version: ${{ matrix.node-version }}
613
+ cache: 'npm'
614
+
615
+ - name: Install dependencies
616
+ run: npm ci
617
+
618
+ - name: Run ${{ matrix.test-type }} tests
619
+ run: npm run test:${{ matrix.test-type }}
620
+ env:
621
+ ENABLE_DEFENDER_MOCKING: true
622
+ TEST_NETWORK: hardhat
623
+
624
+ - name: Upload coverage
625
+ uses: codecov/codecov-action@v3
626
+ if: matrix.test-type == 'unit'
627
+ ```
628
+
629
+ ## Best Practices
630
+
631
+ ### Test Organization
632
+
633
+ 1. **Descriptive Test Names**: Use clear, descriptive test names
634
+ 2. **Test Isolation**: Each test should be independent
635
+ 3. **Setup/Teardown**: Proper cleanup after each test
636
+ 4. **Mock Management**: Restore mocks after each test
637
+
638
+ ### Performance Considerations
639
+
640
+ 1. **Timeout Management**: Set appropriate timeouts for different test types
641
+ 2. **Resource Cleanup**: Clean up temporary files and directories
642
+ 3. **Memory Management**: Monitor memory usage in long-running tests
643
+ 4. **Parallel Execution**: Use parallel test execution where safe
644
+
645
+ ### Security Testing
646
+
647
+ 1. **Access Control**: Test role-based permissions
648
+ 2. **Input Validation**: Test with malformed inputs
649
+ 3. **State Manipulation**: Test with corrupted state
650
+ 4. **Network Security**: Test with simulated attacks
651
+
652
+ ## Troubleshooting Tests
653
+
654
+ ### Common Issues
655
+
656
+ 1. **Timeout Errors**
657
+
658
+ ```bash
659
+ # Increase timeout for specific tests
660
+ npx mocha test/integration/deployment.test.ts --timeout 300000
661
+ ```
662
+
663
+ 2. **Network Connectivity**
664
+
665
+ ```bash
666
+ # Test with local network only
667
+ TEST_NETWORK=hardhat npm test
668
+ ```
669
+
670
+ 3. **Resource Conflicts**
671
+
672
+ ```bash
673
+ # Run tests sequentially
674
+ npm test -- --parallel=false
675
+ ```
676
+
677
+ 4. **Mock State Issues**
678
+
679
+ ```bash
680
+ # Reset all mocks
681
+ beforeEach(() => {
682
+ sinon.restore();
683
+ sinon.resetHistory();
684
+ });
685
+ ```
686
+
687
+ ### Debugging Failed Tests
688
+
689
+ 1. **Enable Verbose Logging**
690
+
691
+ ```typescript
692
+ process.env.DEBUG = 'diamonds:*';
693
+ process.env.VERBOSE_TESTING = 'true';
694
+ ```
695
+
696
+ 2. **Inspect Test State**
697
+
698
+ ```typescript
699
+ // Add debugging output
700
+ console.log('Diamond state:', diamond.getDeployedDiamondData());
701
+ console.log('Mock calls:', mocks.mockDeployClient.deployContract.getCalls());
702
+ ```
703
+
704
+ 3. **Use Test-Specific Timeouts**
705
+
706
+ ```typescript
707
+ it('slow test', async function() {
708
+ this.timeout(120000); // 2 minutes for this specific test
709
+ // ... test code
710
+ });
711
+ ```
712
+
713
+ This comprehensive testing guide ensures robust validation of the Diamonds module functionality across all scenarios and environments.