github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/utils/dashboardEventHandlers.test.ts (about) 1 import { 2 controlsUpdatedEventHandler, 3 leafNodesUpdatedEventHandler, 4 } from "./dashboardEventHandlers"; 5 import { EXECUTION_SCHEMA_VERSION_20221222 } from "../constants/versions"; 6 7 describe("dashboard event handlers", () => { 8 describe("controlsUpdatedEventHandler", () => { 9 test("ignore complete events", () => { 10 const state = { state: "complete" }; 11 expect(controlsUpdatedEventHandler(null, state)).toEqual(state); 12 }); 13 14 test("no event controls", () => { 15 const state = { state: "running" }; 16 expect(controlsUpdatedEventHandler({ controls: null }, state)).toEqual( 17 state 18 ); 19 }); 20 21 test("empty event controls", () => { 22 const state = { state: "running" }; 23 expect(controlsUpdatedEventHandler({ controls: [] }, state)).toEqual( 24 state 25 ); 26 }); 27 28 test("control for different execution", () => { 29 const state = { 30 state: "running", 31 execution_id: "1", 32 panelsMap: {}, 33 progress: 100, 34 }; 35 expect( 36 controlsUpdatedEventHandler( 37 { controls: [{ execution_id: "2" }] }, 38 state 39 ) 40 ).toEqual(state); 41 }); 42 43 test("single control complete", () => { 44 const state = { 45 state: "running", 46 execution_id: "1", 47 panelsMap: { 48 control_a: { 49 name: "control_a", 50 panel_type: "control", 51 status: "running", 52 }, 53 control_b: { 54 name: "control_b", 55 panel_type: "control", 56 status: "running", 57 }, 58 }, 59 progress: 0, 60 }; 61 const updatedControl = { 62 name: "control_b", 63 panel_type: "control", 64 status: "complete", 65 }; 66 expect( 67 controlsUpdatedEventHandler( 68 { 69 controls: [ 70 { 71 control: updatedControl, 72 execution_id: "1", 73 }, 74 ], 75 }, 76 state 77 ) 78 ).toEqual({ 79 ...state, 80 panelsMap: { 81 ...state.panelsMap, 82 [updatedControl.name]: updatedControl, 83 }, 84 progress: 50, 85 }); 86 }); 87 88 test("single control error", () => { 89 const state = { 90 state: "running", 91 execution_id: "1", 92 panelsMap: { 93 control_a: { 94 name: "control_a", 95 panel_type: "control", 96 status: "running", 97 }, 98 control_b: { 99 name: "control_b", 100 panel_type: "control", 101 status: "running", 102 }, 103 }, 104 progress: 0, 105 }; 106 const updatedControl = { 107 name: "control_b", 108 panel_type: "control", 109 status: "error", 110 }; 111 expect( 112 controlsUpdatedEventHandler( 113 { 114 controls: [ 115 { 116 control: updatedControl, 117 execution_id: "1", 118 }, 119 ], 120 }, 121 state 122 ) 123 ).toEqual({ 124 ...state, 125 panelsMap: { 126 ...state.panelsMap, 127 [updatedControl.name]: updatedControl, 128 }, 129 progress: 50, 130 }); 131 }); 132 133 test("multiple controls", () => { 134 const state = { 135 state: "running", 136 execution_id: "1", 137 panelsMap: { 138 control_a: { 139 name: "control_a", 140 panel_type: "control", 141 status: "running", 142 }, 143 control_b: { 144 name: "control_b", 145 panel_type: "control", 146 status: "running", 147 }, 148 control_c: { 149 name: "control_c", 150 panel_type: "control", 151 status: "running", 152 }, 153 control_d: { 154 name: "control_d", 155 panel_type: "control", 156 status: "running", 157 }, 158 }, 159 progress: 0, 160 }; 161 const updatedControl1 = { 162 name: "control_a", 163 panel_type: "control", 164 status: "complete", 165 }; 166 const updatedControl2 = { 167 name: "control_b", 168 panel_type: "control", 169 status: "error", 170 }; 171 const updatedControl3 = { 172 name: "control_d", 173 panel_type: "control", 174 status: "complete", 175 }; 176 expect( 177 controlsUpdatedEventHandler( 178 { 179 controls: [ 180 { 181 control: updatedControl1, 182 execution_id: "1", 183 }, 184 { 185 control: updatedControl2, 186 execution_id: "1", 187 }, 188 { 189 control: updatedControl3, 190 execution_id: "1", 191 }, 192 ], 193 }, 194 state 195 ) 196 ).toEqual({ 197 ...state, 198 panelsMap: { 199 ...state.panelsMap, 200 [updatedControl1.name]: updatedControl1, 201 [updatedControl2.name]: updatedControl2, 202 [updatedControl3.name]: updatedControl3, 203 }, 204 progress: 75, 205 }); 206 }); 207 }); 208 209 describe("leafNodesUpdatedEventHandler", () => { 210 test("ignore complete events", () => { 211 const state = { state: "complete" }; 212 expect( 213 leafNodesUpdatedEventHandler( 214 null, 215 EXECUTION_SCHEMA_VERSION_20221222, 216 state 217 ) 218 ).toEqual(state); 219 }); 220 221 test("no event nodes", () => { 222 const state = { state: "running" }; 223 expect( 224 leafNodesUpdatedEventHandler( 225 { nodes: null }, 226 EXECUTION_SCHEMA_VERSION_20221222, 227 state 228 ) 229 ).toEqual(state); 230 }); 231 232 test("empty event nodes", () => { 233 const state = { state: "running" }; 234 expect( 235 leafNodesUpdatedEventHandler( 236 { nodes: [] }, 237 EXECUTION_SCHEMA_VERSION_20221222, 238 state 239 ) 240 ).toEqual(state); 241 }); 242 243 test("node for different execution", () => { 244 const state = { 245 state: "running", 246 execution_id: "1", 247 panelsLog: {}, 248 panelsMap: {}, 249 progress: 100, 250 }; 251 expect( 252 leafNodesUpdatedEventHandler( 253 { nodes: [{ execution_id: "2" }] }, 254 EXECUTION_SCHEMA_VERSION_20221222, 255 state 256 ) 257 ).toEqual(state); 258 }); 259 260 test("single node blocked", () => { 261 const readyAt = new Date(); 262 const blockedAt = new Date(readyAt); 263 blockedAt.setSeconds(readyAt.getSeconds() + 1); 264 const state = { 265 state: "running", 266 execution_id: "1", 267 panelsLog: { 268 panel_a: [ 269 { 270 error: null, 271 status: "running", 272 timestamp: readyAt.toString(), 273 title: "panel_a", 274 }, 275 ], 276 }, 277 panelsMap: { panel_a: { name: "panel_a", sql: "", status: "running" } }, 278 progress: 0, 279 }; 280 const updatedDashboardNode = { 281 name: "panel_a", 282 panel_type: "node", 283 sql: "", 284 status: "blocked", 285 error: null, 286 }; 287 expect( 288 leafNodesUpdatedEventHandler( 289 { 290 nodes: [ 291 { 292 dashboard_node: updatedDashboardNode, 293 execution_id: "1", 294 timestamp: blockedAt.toString(), 295 }, 296 ], 297 }, 298 EXECUTION_SCHEMA_VERSION_20221222, 299 state 300 ) 301 ).toEqual({ 302 ...state, 303 panelsLog: { 304 ...state.panelsLog, 305 panel_a: [ 306 ...state.panelsLog.panel_a, 307 { 308 error: null, 309 status: "blocked", 310 timestamp: blockedAt.toString(), 311 title: "panel_a", 312 }, 313 ], 314 }, 315 panelsMap: { 316 ...state.panelsMap, 317 [updatedDashboardNode.name]: updatedDashboardNode, 318 }, 319 progress: 0, 320 }); 321 }); 322 323 test("single node running", () => { 324 const readyAt = new Date(); 325 const runningAt = new Date(readyAt); 326 runningAt.setSeconds(readyAt.getSeconds() + 1); 327 const state = { 328 state: "initialized", 329 execution_id: "1", 330 panelsLog: { 331 panel_a: [ 332 { 333 error: null, 334 status: "initialized", 335 timestamp: readyAt.toString(), 336 title: "panel_a", 337 }, 338 ], 339 }, 340 panelsMap: { 341 panel_a: { name: "panel_a", sql: "", status: "initialized" }, 342 }, 343 progress: 0, 344 }; 345 const updatedDashboardNode = { 346 name: "panel_a", 347 panel_type: "node", 348 sql: "", 349 status: "running", 350 error: null, 351 }; 352 expect( 353 leafNodesUpdatedEventHandler( 354 { 355 nodes: [ 356 { 357 dashboard_node: updatedDashboardNode, 358 execution_id: "1", 359 timestamp: runningAt.toString(), 360 }, 361 ], 362 }, 363 EXECUTION_SCHEMA_VERSION_20221222, 364 state 365 ) 366 ).toEqual({ 367 ...state, 368 panelsLog: { 369 ...state.panelsLog, 370 panel_a: [ 371 ...state.panelsLog.panel_a, 372 { 373 error: null, 374 status: "running", 375 timestamp: runningAt.toString(), 376 title: "panel_a", 377 }, 378 ], 379 }, 380 panelsMap: { 381 ...state.panelsMap, 382 [updatedDashboardNode.name]: updatedDashboardNode, 383 }, 384 progress: 0, 385 }); 386 }); 387 388 test("single node error", () => { 389 const readyAt = new Date(); 390 const erroredAt = new Date(readyAt); 391 erroredAt.setSeconds(readyAt.getSeconds() + 1); 392 const state = { 393 state: "running", 394 execution_id: "1", 395 panelsLog: { 396 panel_a: [ 397 { 398 error: null, 399 status: "running", 400 timestamp: readyAt.toString(), 401 title: "panel_a", 402 }, 403 ], 404 }, 405 panelsMap: { panel_a: { name: "panel_a", sql: "", status: "running" } }, 406 progress: 0, 407 }; 408 const updatedDashboardNode = { 409 name: "panel_a", 410 panel_type: "node", 411 sql: "", 412 status: "error", 413 error: "BOOM!", 414 }; 415 expect( 416 leafNodesUpdatedEventHandler( 417 { 418 nodes: [ 419 { 420 dashboard_node: updatedDashboardNode, 421 execution_id: "1", 422 timestamp: erroredAt.toString(), 423 }, 424 ], 425 }, 426 EXECUTION_SCHEMA_VERSION_20221222, 427 state 428 ) 429 ).toEqual({ 430 ...state, 431 panelsLog: { 432 ...state.panelsLog, 433 panel_a: [ 434 ...state.panelsLog.panel_a, 435 { 436 error: "BOOM!", 437 status: "error", 438 timestamp: erroredAt.toString(), 439 title: "panel_a", 440 }, 441 ], 442 }, 443 panelsMap: { 444 ...state.panelsMap, 445 [updatedDashboardNode.name]: updatedDashboardNode, 446 }, 447 progress: 100, 448 }); 449 }); 450 451 test("single node complete", () => { 452 const readyAt = new Date(); 453 const completeAt = new Date(readyAt); 454 completeAt.setSeconds(readyAt.getSeconds() + 1); 455 const state = { 456 state: "running", 457 execution_id: "1", 458 panelsLog: { 459 panel_a: [ 460 { 461 error: null, 462 status: "running", 463 timestamp: readyAt.toString(), 464 title: "panel_a", 465 }, 466 ], 467 }, 468 panelsMap: { panel_a: { name: "panel_a", sql: "", status: "running" } }, 469 progress: 0, 470 }; 471 const updatedDashboardNode = { 472 name: "panel_a", 473 panel_type: "node", 474 sql: "", 475 status: "complete", 476 error: null, 477 }; 478 expect( 479 leafNodesUpdatedEventHandler( 480 { 481 nodes: [ 482 { 483 dashboard_node: updatedDashboardNode, 484 execution_id: "1", 485 timestamp: completeAt.toString(), 486 }, 487 ], 488 }, 489 EXECUTION_SCHEMA_VERSION_20221222, 490 state 491 ) 492 ).toEqual({ 493 ...state, 494 panelsLog: { 495 ...state.panelsLog, 496 panel_a: [ 497 ...state.panelsLog.panel_a, 498 { 499 error: null, 500 executionTime: 1000, 501 status: "complete", 502 timestamp: completeAt.toString(), 503 title: "panel_a", 504 }, 505 ], 506 }, 507 panelsMap: { 508 ...state.panelsMap, 509 [updatedDashboardNode.name]: updatedDashboardNode, 510 }, 511 progress: 100, 512 }); 513 }); 514 515 test("multiple node complete", () => { 516 const readyAt = new Date(); 517 const panelACompleteAt = new Date(readyAt); 518 panelACompleteAt.setSeconds(readyAt.getSeconds() + 1); 519 const panelBCompleteAt = new Date(readyAt); 520 panelBCompleteAt.setSeconds(readyAt.getSeconds() + 2); 521 const state = { 522 state: "running", 523 execution_id: "1", 524 panelsLog: { 525 panel_a: [ 526 { 527 error: null, 528 status: "running", 529 timestamp: readyAt.toString(), 530 title: "panel_a", 531 }, 532 ], 533 panel_b: [ 534 { 535 error: null, 536 status: "running", 537 timestamp: readyAt.toString(), 538 title: "panel_b", 539 }, 540 ], 541 panel_c: [ 542 { 543 error: null, 544 status: "running", 545 timestamp: readyAt.toString(), 546 title: "panel_c", 547 }, 548 ], 549 panel_d: [ 550 { 551 error: null, 552 status: "running", 553 timestamp: readyAt.toString(), 554 title: "panel_d", 555 }, 556 ], 557 }, 558 panelsMap: { 559 panel_a: { name: "panel_a", sql: "", status: "running" }, 560 panel_b: { name: "panel_b", sql: "", status: "running" }, 561 panel_c: { name: "panel_c", sql: "", status: "running" }, 562 panel_d: { name: "panel_d", sql: "", status: "running" }, 563 }, 564 progress: 0, 565 }; 566 const updatedDashboardNode1 = { 567 name: "panel_a", 568 panel_type: "node", 569 sql: "", 570 status: "complete", 571 error: null, 572 }; 573 const updatedDashboardNode2 = { 574 name: "panel_b", 575 panel_type: "edge", 576 sql: "", 577 status: "complete", 578 error: null, 579 }; 580 expect( 581 leafNodesUpdatedEventHandler( 582 { 583 nodes: [ 584 { 585 dashboard_node: updatedDashboardNode1, 586 execution_id: "1", 587 timestamp: panelACompleteAt.toString(), 588 }, 589 { 590 dashboard_node: updatedDashboardNode2, 591 execution_id: "1", 592 timestamp: panelBCompleteAt.toString(), 593 }, 594 ], 595 }, 596 EXECUTION_SCHEMA_VERSION_20221222, 597 state 598 ) 599 ).toEqual({ 600 ...state, 601 panelsLog: { 602 ...state.panelsLog, 603 panel_a: [ 604 ...state.panelsLog.panel_a, 605 { 606 error: null, 607 executionTime: 1000, 608 status: "complete", 609 timestamp: panelACompleteAt.toString(), 610 title: "panel_a", 611 }, 612 ], 613 panel_b: [ 614 ...state.panelsLog.panel_b, 615 { 616 error: null, 617 executionTime: 2000, 618 status: "complete", 619 timestamp: panelBCompleteAt.toString(), 620 title: "panel_b", 621 }, 622 ], 623 }, 624 panelsMap: { 625 ...state.panelsMap, 626 [updatedDashboardNode1.name]: updatedDashboardNode1, 627 [updatedDashboardNode2.name]: updatedDashboardNode2, 628 }, 629 progress: 50, 630 }); 631 }); 632 }); 633 });