|
| 1 | +// SPDX-License-Identifier: BUSL 1.1 |
| 2 | +pragma solidity 0.8.26; |
| 3 | + |
| 4 | +import {WorkflowRegistry} from "../../WorkflowRegistry.sol"; |
| 5 | +import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; |
| 6 | + |
| 7 | +contract WorkflowRegistry_getWorkflowListByDON is WorkflowRegistrySetup { |
| 8 | + address private s_owner1 = makeAddr("owner1"); |
| 9 | + address private s_owner2 = makeAddr("owner2"); |
| 10 | + string private s_donFamily1 = "DON-Family-1"; |
| 11 | + string private s_donFamily2 = "DON-Family-2"; |
| 12 | + |
| 13 | + function test_getWorkflowListByDON_WhenTheDONFamilyHasNoWorkflowsRegistered() external view { |
| 14 | + // it should return an empty array |
| 15 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 10); |
| 16 | + assertEq(workflows.length, 0, "Expected no workflows"); |
| 17 | + |
| 18 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 1); |
| 19 | + assertEq(workflows.length, 0, "Expected no workflows"); |
| 20 | + |
| 21 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 5, 10); |
| 22 | + assertEq(workflows.length, 0, "Expected no workflows"); |
| 23 | + } |
| 24 | + |
| 25 | + modifier whenTheDONFamilyHasWorkflowsRegistered() { |
| 26 | + // Set up DON limits for both families |
| 27 | + vm.startPrank(s_owner); |
| 28 | + s_registry.setDONLimit(s_donFamily1, 10, true); |
| 29 | + s_registry.setDONLimit(s_donFamily2, 5, true); |
| 30 | + vm.stopPrank(); |
| 31 | + |
| 32 | + // Link owners and create workflows for DON Family 1 |
| 33 | + _linkOwner(s_owner1); |
| 34 | + _linkOwner(s_owner2); |
| 35 | + |
| 36 | + // Create 5 workflows for DON Family 1 |
| 37 | + vm.startPrank(s_owner1); |
| 38 | + _createWorkflowForDON("Workflow-1", "tag1", keccak256("id1"), s_donFamily1); |
| 39 | + _createWorkflowForDON("Workflow-2", "tag2", keccak256("id2"), s_donFamily1); |
| 40 | + _createWorkflowForDON("Workflow-3", "tag3", keccak256("id3"), s_donFamily1); |
| 41 | + vm.stopPrank(); |
| 42 | + |
| 43 | + vm.startPrank(s_owner2); |
| 44 | + _createWorkflowForDON("Workflow-4", "tag4", keccak256("id4"), s_donFamily1); |
| 45 | + _createWorkflowForDON("Workflow-5", "tag5", keccak256("id5"), s_donFamily1); |
| 46 | + vm.stopPrank(); |
| 47 | + |
| 48 | + // Create 2 workflows for DON Family 2 (different DON) |
| 49 | + vm.startPrank(s_owner1); |
| 50 | + _createWorkflowForDON("Other-Workflow-1", "other1", keccak256("other1"), s_donFamily2); |
| 51 | + _createWorkflowForDON("Other-Workflow-2", "other2", keccak256("other2"), s_donFamily2); |
| 52 | + vm.stopPrank(); |
| 53 | + _; |
| 54 | + } |
| 55 | + |
| 56 | + function test_getWorkflowListByDON_WhenStartIsGreaterThanOrEqualToTotalWorkflows() |
| 57 | + external |
| 58 | + whenTheDONFamilyHasWorkflowsRegistered |
| 59 | + { |
| 60 | + // it should return an empty array |
| 61 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 5, 10); |
| 62 | + assertEq(workflows.length, 0, "Expected no workflows when start equals total"); |
| 63 | + |
| 64 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 6, 5); |
| 65 | + assertEq(workflows.length, 0, "Expected no workflows when start is greater than total"); |
| 66 | + |
| 67 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 10, 1); |
| 68 | + assertEq(workflows.length, 0, "Expected no workflows when start is much greater than total"); |
| 69 | + } |
| 70 | + |
| 71 | + modifier whenStartIsLessThanTotalWorkflows() { |
| 72 | + _; |
| 73 | + } |
| 74 | + |
| 75 | + function test_getWorkflowListByDON_WhenLimitIsZero() |
| 76 | + external |
| 77 | + whenTheDONFamilyHasWorkflowsRegistered |
| 78 | + whenStartIsLessThanTotalWorkflows |
| 79 | + { |
| 80 | + // it should return an empty array |
| 81 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 0); |
| 82 | + assertEq(workflows.length, 0, "Expected no workflows when limit is 0"); |
| 83 | + |
| 84 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 2, 0); |
| 85 | + assertEq(workflows.length, 0, "Expected no workflows when limit is 0"); |
| 86 | + } |
| 87 | + |
| 88 | + function test_getWorkflowListByDON_WhenLimitIsLessThanTotalMinusStart() |
| 89 | + external |
| 90 | + whenTheDONFamilyHasWorkflowsRegistered |
| 91 | + whenStartIsLessThanTotalWorkflows |
| 92 | + { |
| 93 | + // it should return exactly limit workflows starting from start index |
| 94 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 2); |
| 95 | + assertEq(workflows.length, 2, "Expected exactly 2 workflows"); |
| 96 | + assertEq(workflows[0].workflowName, "Workflow-1", "Expected first workflow"); |
| 97 | + assertEq(workflows[1].workflowName, "Workflow-2", "Expected second workflow"); |
| 98 | + |
| 99 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 1, 2); |
| 100 | + assertEq(workflows.length, 2, "Expected exactly 2 workflows starting from index 1"); |
| 101 | + assertEq(workflows[0].workflowName, "Workflow-2", "Expected second workflow at index 0"); |
| 102 | + assertEq(workflows[1].workflowName, "Workflow-3", "Expected third workflow at index 1"); |
| 103 | + |
| 104 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 3, 1); |
| 105 | + assertEq(workflows.length, 1, "Expected exactly 1 workflow"); |
| 106 | + assertEq(workflows[0].workflowName, "Workflow-4", "Expected fourth workflow"); |
| 107 | + } |
| 108 | + |
| 109 | + function test_getWorkflowListByDON_WhenLimitIsGreaterThanOrEqualToTotalMinusStart() |
| 110 | + external |
| 111 | + whenTheDONFamilyHasWorkflowsRegistered |
| 112 | + whenStartIsLessThanTotalWorkflows |
| 113 | + { |
| 114 | + // it should return all workflows from start index to the end |
| 115 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 5); |
| 116 | + assertEq(workflows.length, 5, "Expected all 5 workflows"); |
| 117 | + assertEq(workflows[0].workflowName, "Workflow-1", "Expected first workflow"); |
| 118 | + assertEq(workflows[1].workflowName, "Workflow-2", "Expected second workflow"); |
| 119 | + assertEq(workflows[2].workflowName, "Workflow-3", "Expected third workflow"); |
| 120 | + assertEq(workflows[3].workflowName, "Workflow-4", "Expected fourth workflow"); |
| 121 | + assertEq(workflows[4].workflowName, "Workflow-5", "Expected fifth workflow"); |
| 122 | + |
| 123 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 10); |
| 124 | + assertEq(workflows.length, 5, "Expected all 5 workflows when limit exceeds total"); |
| 125 | + |
| 126 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 2, 10); |
| 127 | + assertEq(workflows.length, 3, "Expected last 3 workflows"); |
| 128 | + assertEq(workflows[0].workflowName, "Workflow-3", "Expected third workflow"); |
| 129 | + assertEq(workflows[1].workflowName, "Workflow-4", "Expected fourth workflow"); |
| 130 | + assertEq(workflows[2].workflowName, "Workflow-5", "Expected fifth workflow"); |
| 131 | + |
| 132 | + workflows = s_registry.getWorkflowListByDON(s_donFamily1, 4, 5); |
| 133 | + assertEq(workflows.length, 1, "Expected last workflow"); |
| 134 | + assertEq(workflows[0].workflowName, "Workflow-5", "Expected fifth workflow"); |
| 135 | + } |
| 136 | + |
| 137 | + function test_getWorkflowListByDON_ShouldOnlyReturnWorkflowsFromSpecifiedDON() |
| 138 | + external |
| 139 | + whenTheDONFamilyHasWorkflowsRegistered |
| 140 | + { |
| 141 | + // Verify DON Family 1 workflows |
| 142 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows1 = s_registry.getWorkflowListByDON(s_donFamily1, 0, 10); |
| 143 | + assertEq(workflows1.length, 5, "Expected 5 workflows for DON Family 1"); |
| 144 | + |
| 145 | + // Verify DON Family 2 workflows |
| 146 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows2 = s_registry.getWorkflowListByDON(s_donFamily2, 0, 10); |
| 147 | + assertEq(workflows2.length, 2, "Expected 2 workflows for DON Family 2"); |
| 148 | + assertEq(workflows2[0].workflowName, "Other-Workflow-1", "Expected first other workflow"); |
| 149 | + assertEq(workflows2[1].workflowName, "Other-Workflow-2", "Expected second other workflow"); |
| 150 | + |
| 151 | + // Verify workflow names don't overlap |
| 152 | + for (uint256 i = 0; i < workflows1.length; i++) { |
| 153 | + for (uint256 j = 0; j < workflows2.length; j++) { |
| 154 | + assertTrue( |
| 155 | + keccak256(bytes(workflows1[i].workflowName)) != keccak256(bytes(workflows2[j].workflowName)), |
| 156 | + "Workflows from different DONs should not have the same name" |
| 157 | + ); |
| 158 | + } |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + function test_getWorkflowListByDON_ShouldReturnWorkflowsWithCorrectStatus() |
| 163 | + external |
| 164 | + whenTheDONFamilyHasWorkflowsRegistered |
| 165 | + { |
| 166 | + // All workflows should be PAUSED by default from our setup |
| 167 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 10); |
| 168 | + |
| 169 | + for (uint256 i = 0; i < workflows.length; i++) { |
| 170 | + assertEq( |
| 171 | + uint256(workflows[i].status), uint256(WorkflowRegistry.WorkflowStatus.PAUSED), "Expected workflow to be PAUSED" |
| 172 | + ); |
| 173 | + } |
| 174 | + } |
| 175 | + |
| 176 | + function test_getWorkflowListByDON_ShouldIncludeBothActiveAndPausedWorkflows() external { |
| 177 | + // Set up DON limit |
| 178 | + vm.prank(s_owner); |
| 179 | + s_registry.setDONLimit(s_donFamily1, 10, true); |
| 180 | + |
| 181 | + // Link owner and create workflows |
| 182 | + _linkOwner(s_owner1); |
| 183 | + |
| 184 | + vm.startPrank(s_owner1); |
| 185 | + // Create PAUSED workflow |
| 186 | + _createWorkflowForDON("Paused-Workflow", "paused", keccak256("paused"), s_donFamily1); |
| 187 | + |
| 188 | + // Create ACTIVE workflow |
| 189 | + bytes32 activeId = keccak256("active"); |
| 190 | + s_registry.upsertWorkflow( |
| 191 | + "Active-Workflow", |
| 192 | + "active", |
| 193 | + activeId, |
| 194 | + WorkflowRegistry.WorkflowStatus.ACTIVE, |
| 195 | + s_donFamily1, |
| 196 | + s_binaryUrl, |
| 197 | + s_configUrl, |
| 198 | + s_attributes, |
| 199 | + true |
| 200 | + ); |
| 201 | + vm.stopPrank(); |
| 202 | + |
| 203 | + WorkflowRegistry.WorkflowMetadataView[] memory workflows = s_registry.getWorkflowListByDON(s_donFamily1, 0, 10); |
| 204 | + assertEq(workflows.length, 2, "Expected 2 workflows (ACTIVE and PAUSED)"); |
| 205 | + |
| 206 | + // Verify we have both statuses |
| 207 | + bool hasPaused = false; |
| 208 | + bool hasActive = false; |
| 209 | + for (uint256 i = 0; i < workflows.length; i++) { |
| 210 | + if (workflows[i].status == WorkflowRegistry.WorkflowStatus.PAUSED) { |
| 211 | + hasPaused = true; |
| 212 | + } |
| 213 | + if (workflows[i].status == WorkflowRegistry.WorkflowStatus.ACTIVE) { |
| 214 | + hasActive = true; |
| 215 | + } |
| 216 | + } |
| 217 | + assertTrue(hasPaused, "Expected to find PAUSED workflow"); |
| 218 | + assertTrue(hasActive, "Expected to find ACTIVE workflow"); |
| 219 | + } |
| 220 | + |
| 221 | + // Helper function to create a workflow for a specific DON |
| 222 | + function _createWorkflowForDON( |
| 223 | + string memory workflowName, |
| 224 | + string memory tag, |
| 225 | + bytes32 workflowId, |
| 226 | + string memory donFamily |
| 227 | + ) internal { |
| 228 | + s_registry.upsertWorkflow( |
| 229 | + workflowName, |
| 230 | + tag, |
| 231 | + workflowId, |
| 232 | + WorkflowRegistry.WorkflowStatus.PAUSED, |
| 233 | + donFamily, |
| 234 | + s_binaryUrl, |
| 235 | + s_configUrl, |
| 236 | + s_attributes, |
| 237 | + true |
| 238 | + ); |
| 239 | + } |
| 240 | +} |
0 commit comments