go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/pkg/dbmodel/manager_test.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package dbmodel 9 10 import ( 11 "context" 12 "testing" 13 "time" 14 15 "go.charczuk.com/projects/nodes/pkg/types" 16 "go.charczuk.com/sdk/apputil" 17 "go.charczuk.com/sdk/assert" 18 "go.charczuk.com/sdk/uuid" 19 ) 20 21 func Test_Manager_Deserialize(t *testing.T) { 22 ctx := context.Background() 23 appMgr, done := apputil.NewTest(t) 24 defer done() 25 26 u0 := apputil.CreateTestUser(t, appMgr) 27 28 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 29 30 mgr := Manager{ 31 BaseManager: appMgr.BaseManager, 32 } 33 34 tg, err := mgr.Deserialize(ctx, g.ID, false, false) 35 assert.ItsNil(t, err) 36 assert.ItsEqual(t, g.ID, tg.Graph.ID) 37 } 38 39 func Test_Manager_PatchGraph(t *testing.T) { 40 ctx := context.Background() 41 appMgr, done := apputil.NewTest(t) 42 defer done() 43 44 u0 := apputil.CreateTestUser(t, appMgr) 45 46 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 47 48 mgr := Manager{ 49 BaseManager: appMgr.BaseManager, 50 } 51 52 found, err := mgr.PatchGraph(ctx, g.ID, types.PatchSet{ 53 "viewport_x": 2, 54 "viewport_y": 3, 55 "viewport_zoom": 4, 56 }) 57 assert.ItsNil(t, err) 58 assert.ItsEqual(t, true, found) 59 60 verify, found, err := mgr.Graph(ctx, g.ID) 61 assert.ItsNil(t, err) 62 assert.ItsEqual(t, true, found) 63 assert.ItsEqual(t, 2, verify.ViewportX) 64 assert.ItsEqual(t, 3, verify.ViewportY) 65 assert.ItsEqual(t, 4, verify.ViewportZoom) 66 } 67 68 func Test_Manager_TouchGraph(t *testing.T) { 69 ctx := context.Background() 70 appMgr, done := apputil.NewTest(t) 71 defer done() 72 73 u0 := apputil.CreateTestUser(t, appMgr) 74 75 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 76 77 mgr := Manager{ 78 BaseManager: appMgr.BaseManager, 79 } 80 81 err := mgr.TouchGraph(ctx, g.ID) 82 assert.ItsNil(t, err) 83 } 84 85 func Test_Manager_NodeValues_empty(t *testing.T) { 86 ctx := context.Background() 87 appMgr, done := apputil.NewTest(t) 88 defer done() 89 90 u0 := apputil.CreateTestUser(t, appMgr) 91 92 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 93 94 mgr := Manager{ 95 BaseManager: appMgr.BaseManager, 96 } 97 98 nv, err := mgr.NodeValues(ctx, g.ID) 99 assert.ItsNil(t, err) 100 assert.ItsEqual(t, 2, len(nv)) 101 } 102 103 func Test_Manager_NodeValues_specced(t *testing.T) { 104 ctx := context.Background() 105 appMgr, done := apputil.NewTest(t) 106 defer done() 107 108 u0 := apputil.CreateTestUser(t, appMgr) 109 110 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 111 112 mgr := Manager{ 113 BaseManager: appMgr.BaseManager, 114 } 115 116 nv, err := mgr.NodeValues(ctx, g.ID, nodes[TestNodeV0Label].ID) 117 assert.ItsNil(t, err) 118 assert.ItsEqual(t, 1, len(nv)) 119 } 120 121 func Test_Manager_NodeValue(t *testing.T) { 122 ctx := context.Background() 123 appMgr, done := apputil.NewTest(t) 124 defer done() 125 126 u0 := apputil.CreateTestUser(t, appMgr) 127 128 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 129 130 mgr := Manager{ 131 BaseManager: appMgr.BaseManager, 132 } 133 134 nv, found, err := mgr.NodeValue(ctx, g.ID, nodes[TestNodeV0Label].ID) 135 assert.ItsNil(t, err) 136 assert.ItsEqual(t, true, found) 137 assert.ItsEqual(t, "string", nv.ValueType) 138 assert.ItsEqual(t, "hello", nv.Value) 139 } 140 141 func Test_Manager_SetNodeValues(t *testing.T) { 142 ctx := context.Background() 143 appMgr, done := apputil.NewTest(t) 144 defer done() 145 146 u0 := apputil.CreateTestUser(t, appMgr) 147 148 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 149 150 mgr := Manager{ 151 BaseManager: appMgr.BaseManager, 152 } 153 154 err := mgr.SetNodeValues(ctx, g.ID, u0.ID, map[uuid.UUID]any{ 155 nodes[TestNodeV0Label].ID: "not-hello", 156 nodes[TestNodeV1Label].ID: "not-world", 157 nodes[TestNodeM0Label].ID: "not-hello not-world", 158 nodes[TestNodeO0Label].ID: "not-hello not-world", 159 }) 160 assert.ItsNil(t, err) 161 162 values, err := mgr.NodeValues(ctx, g.ID) 163 assert.ItsNil(t, err) 164 assert.ItsEqual(t, 4, len(values)) 165 } 166 167 func Test_Manager_DeleteGraph(t *testing.T) { 168 ctx := context.Background() 169 appMgr, done := apputil.NewTest(t) 170 defer done() 171 172 u0 := apputil.CreateTestUser(t, appMgr) 173 174 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 175 176 mgr := Manager{ 177 BaseManager: appMgr.BaseManager, 178 } 179 180 found, err := mgr.DeleteGraph(ctx, g.ID) 181 assert.ItsNil(t, err) 182 assert.ItsEqual(t, true, found) 183 } 184 185 func Test_Manager_DeleteNode(t *testing.T) { 186 ctx := context.Background() 187 appMgr, done := apputil.NewTest(t) 188 defer done() 189 190 u0 := apputil.CreateTestUser(t, appMgr) 191 192 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 193 194 mgr := Manager{ 195 BaseManager: appMgr.BaseManager, 196 } 197 198 foundNodes, err := mgr.Nodes(ctx, g.ID) 199 assert.ItsNil(t, err) 200 assert.ItsEqual(t, 4, len(foundNodes)) 201 202 found, err := mgr.DeleteNode(ctx, nodes[TestNodeV0Label].ID) 203 assert.ItsNil(t, err) 204 assert.ItsEqual(t, true, found) 205 206 foundNodes, err = mgr.Nodes(ctx, g.ID) 207 assert.ItsNil(t, err) 208 assert.ItsEqual(t, 3, len(foundNodes)) 209 } 210 211 func Test_Manager_DeleteEdge(t *testing.T) { 212 ctx := context.Background() 213 appMgr, done := apputil.NewTest(t) 214 defer done() 215 216 u0 := apputil.CreateTestUser(t, appMgr) 217 218 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 219 220 mgr := Manager{ 221 BaseManager: appMgr.BaseManager, 222 } 223 224 edges, err := mgr.Edges(ctx, g.ID) 225 assert.ItsNil(t, err) 226 assert.ItsEqual(t, 3, len(edges)) 227 228 err = mgr.DeleteEdge(ctx, nodes[TestNodeV0Label].ID, nodes[TestNodeM0Label].ID, "") 229 assert.ItsNil(t, err) 230 231 edges, err = mgr.Edges(ctx, g.ID) 232 assert.ItsNil(t, err) 233 assert.ItsEqual(t, 2, len(edges)) 234 235 assert.ItsNone(t, edges, func(e Edge) bool { 236 return e.ParentID == nodes[TestNodeV0Label].ID 237 }) 238 } 239 240 func Test_Manager_SetViewport(t *testing.T) { 241 ctx := context.Background() 242 appMgr, done := apputil.NewTest(t) 243 defer done() 244 245 u0 := apputil.CreateTestUser(t, appMgr) 246 247 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 248 249 mgr := Manager{ 250 BaseManager: appMgr.BaseManager, 251 } 252 253 err := mgr.SetViewport(ctx, g.ID, types.Viewport{ 254 X: 5, 255 Y: 6, 256 Zoom: 7, 257 }) 258 assert.ItsNil(t, err) 259 260 verify, found, err := mgr.Graph(ctx, g.ID) 261 assert.ItsNil(t, err) 262 assert.ItsEqual(t, true, found) 263 assert.ItsEqual(t, 5, verify.ViewportX) 264 assert.ItsEqual(t, 6, verify.ViewportY) 265 assert.ItsEqual(t, 7, verify.ViewportZoom) 266 } 267 268 func Test_Manager_GraphLogsLatest(t *testing.T) { 269 ctx := context.Background() 270 appMgr, done := apputil.NewTest(t) 271 defer done() 272 273 u0 := apputil.CreateTestUser(t, appMgr) 274 275 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 276 277 mgr := Manager{ 278 BaseManager: appMgr.BaseManager, 279 } 280 281 err := mgr.Invoke(ctx).Create(&GraphLogs{ 282 GraphID: g.ID, 283 UserID: u0.ID, 284 CreatedUTC: time.Now().UTC().Add(-5 * time.Minute), 285 StabilizationNum: 1, 286 Logs: "hello 5", 287 }) 288 assert.ItsNil(t, err) 289 290 err = mgr.Invoke(ctx).Create(&GraphLogs{ 291 GraphID: g.ID, 292 UserID: u0.ID, 293 CreatedUTC: time.Now().UTC().Add(-3 * time.Minute), 294 StabilizationNum: 2, 295 Logs: "hello 4", 296 }) 297 assert.ItsNil(t, err) 298 299 err = mgr.Invoke(ctx).Create(&GraphLogs{ 300 GraphID: g.ID, 301 UserID: u0.ID, 302 CreatedUTC: time.Now().UTC().Add(-2 * time.Minute), 303 StabilizationNum: 3, 304 Logs: "hello 3", 305 }) 306 assert.ItsNil(t, err) 307 308 err = mgr.Invoke(ctx).Create(&GraphLogs{ 309 GraphID: g.ID, 310 UserID: u0.ID, 311 CreatedUTC: time.Now().UTC().Add(-1 * time.Minute), 312 StabilizationNum: 4, 313 Logs: "hello 4", 314 }) 315 assert.ItsNil(t, err) 316 317 err = mgr.Invoke(ctx).Create(&GraphLogs{ 318 GraphID: g.ID, 319 UserID: u0.ID, 320 CreatedUTC: time.Now().UTC().Add(-1 * time.Second), 321 StabilizationNum: 5, 322 Logs: "hello 5", 323 }) 324 assert.ItsNil(t, err) 325 326 latest, found, err := mgr.GraphLogsLatest(ctx, g.ID) 327 assert.ItsNil(t, err) 328 assert.ItsEqual(t, true, found) 329 assert.ItsEqual(t, "hello 5", latest.Logs) 330 } 331 332 func Test_Manager_PatchNodes(t *testing.T) { 333 ctx := context.Background() 334 appMgr, done := apputil.NewTest(t) 335 defer done() 336 337 u0 := apputil.CreateTestUser(t, appMgr) 338 339 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 340 341 mgr := Manager{ 342 BaseManager: appMgr.BaseManager, 343 } 344 345 err := mgr.PatchNodes(ctx, g.ID, types.PatchSet{"collapsed": true, "watched": true}) 346 assert.ItsNil(t, err) 347 348 verify, found, err := mgr.Node(ctx, nodes[TestNodeV0Label].ID) 349 assert.ItsNil(t, err) 350 assert.ItsEqual(t, true, found) 351 assert.ItsEqual(t, true, verify.Collapsed) 352 assert.ItsEqual(t, true, verify.Watched) 353 354 verify, found, err = mgr.Node(ctx, nodes[TestNodeM0Label].ID) 355 assert.ItsNil(t, err) 356 assert.ItsEqual(t, true, found) 357 assert.ItsEqual(t, true, verify.Collapsed) 358 assert.ItsEqual(t, true, verify.Watched) 359 } 360 361 func Test_Manager_PatchNodes_bogusColumn(t *testing.T) { 362 ctx := context.Background() 363 appMgr, done := apputil.NewTest(t) 364 defer done() 365 366 u0 := apputil.CreateTestUser(t, appMgr) 367 368 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 369 370 mgr := Manager{ 371 BaseManager: appMgr.BaseManager, 372 } 373 374 err := mgr.PatchNodes(ctx, g.ID, types.PatchSet{"collapsed'; DROP TABLE users --": true}) 375 assert.ItsNil(t, err) 376 377 verify, found, err := mgr.Node(ctx, nodes[TestNodeV0Label].ID) 378 assert.ItsNil(t, err) 379 assert.ItsEqual(t, true, found) 380 assert.ItsEqual(t, false, verify.Collapsed) 381 382 verify, found, err = mgr.Node(ctx, nodes[TestNodeM0Label].ID) 383 assert.ItsNil(t, err) 384 assert.ItsEqual(t, true, found) 385 assert.ItsEqual(t, false, verify.Collapsed) 386 } 387 388 func Test_Manager_PatchNode(t *testing.T) { 389 ctx := context.Background() 390 appMgr, done := apputil.NewTest(t) 391 defer done() 392 393 u0 := apputil.CreateTestUser(t, appMgr) 394 395 _, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 396 397 mgr := Manager{ 398 BaseManager: appMgr.BaseManager, 399 } 400 401 found, err := mgr.PatchNode(ctx, nodes[TestNodeV0Label].ID, types.PatchSet{"collapsed": true}) 402 assert.ItsNil(t, err) 403 assert.ItsEqual(t, true, found) 404 405 verify, found, err := mgr.Node(ctx, nodes[TestNodeV0Label].ID) 406 assert.ItsNil(t, err) 407 assert.ItsEqual(t, true, found) 408 assert.ItsEqual(t, true, verify.Collapsed) 409 410 verify, found, err = mgr.Node(ctx, nodes[TestNodeM0Label].ID) 411 assert.ItsNil(t, err) 412 assert.ItsEqual(t, true, found) 413 assert.ItsEqual(t, false, verify.Collapsed) 414 } 415 416 func Test_Manager_PatchNode_bogusColumn(t *testing.T) { 417 ctx := context.Background() 418 appMgr, done := apputil.NewTest(t) 419 defer done() 420 421 u0 := apputil.CreateTestUser(t, appMgr) 422 423 _, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 424 425 mgr := Manager{ 426 BaseManager: appMgr.BaseManager, 427 } 428 429 found, err := mgr.PatchNode(ctx, nodes[TestNodeV0Label].ID, types.PatchSet{"collapsed'; DROP TABLE USERS --": true}) 430 assert.ItsNil(t, err) 431 assert.ItsEqual(t, false, found) 432 } 433 434 func Test_Manager_MarkNodeStale(t *testing.T) { 435 ctx := context.Background() 436 appMgr, done := apputil.NewTest(t) 437 defer done() 438 439 u0 := apputil.CreateTestUser(t, appMgr) 440 441 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 442 443 mgr := Manager{ 444 BaseManager: appMgr.BaseManager, 445 } 446 447 err := mgr.UpdateGraphPostStabilization(ctx, g.ID, 123) 448 assert.ItsNil(t, err) 449 450 found, err := mgr.MarkNodeStale(ctx, g.ID, u0.ID, nodes[TestNodeM0Label].ID) 451 assert.ItsNil(t, err) 452 assert.ItsEqual(t, true, found) 453 454 rh, err := mgr.RecomputeHeap(ctx, g.ID) 455 assert.ItsNil(t, err) 456 457 assert.ItsEqual(t, 3, len(rh)) 458 assert.ItsAny(t, rh, func(v GraphRecomputeHeap) bool { 459 return v.NodeID == nodes[TestNodeV0Label].ID 460 }) 461 assert.ItsAny(t, rh, func(v GraphRecomputeHeap) bool { 462 return v.NodeID == nodes[TestNodeV1Label].ID 463 }) 464 assert.ItsAny(t, rh, func(v GraphRecomputeHeap) bool { 465 return v.NodeID == nodes[TestNodeM0Label].ID 466 }) 467 468 verify, found, err := mgr.Node(ctx, nodes[TestNodeM0Label].ID) 469 assert.ItsNil(t, err) 470 assert.ItsEqual(t, true, found) 471 assert.ItsEqual(t, 123, verify.SetAt) 472 } 473 474 func Test_Manager_UpdateGraphPostStabilization(t *testing.T) { 475 ctx := context.Background() 476 appMgr, done := apputil.NewTest(t) 477 defer done() 478 479 u0 := apputil.CreateTestUser(t, appMgr) 480 481 g, _ := CreateTestGraph(t, &appMgr.BaseManager, u0) 482 483 mgr := Manager{ 484 BaseManager: appMgr.BaseManager, 485 } 486 487 err := mgr.UpdateGraphPostStabilization(ctx, g.ID, 123) 488 assert.ItsNil(t, err) 489 490 verify, found, err := mgr.Graph(ctx, g.ID) 491 assert.ItsNil(t, err) 492 assert.ItsEqual(t, true, found) 493 494 assert.ItsEqual(t, 123, verify.StabilizationNum) 495 } 496 497 func Test_Manager_SetRecomputeHeap(t *testing.T) { 498 ctx := context.Background() 499 appMgr, done := apputil.NewTest(t) 500 defer done() 501 502 u0 := apputil.CreateTestUser(t, appMgr) 503 504 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 505 506 mgr := Manager{ 507 BaseManager: appMgr.BaseManager, 508 } 509 510 rh, err := mgr.RecomputeHeap(ctx, g.ID) 511 assert.ItsNil(t, err) 512 513 assert.ItsEqual(t, 2, len(rh)) 514 515 err = mgr.SetRecomputeHeap(ctx, g.ID, u0.ID, nodes[TestNodeV0Label].ID) 516 assert.ItsNil(t, err) 517 518 rh, err = mgr.RecomputeHeap(ctx, g.ID) 519 assert.ItsNil(t, err) 520 521 assert.ItsEqual(t, 1, len(rh)) 522 assert.ItsEqual(t, nodes[TestNodeV0Label].ID, rh[0].NodeID) 523 524 err = mgr.SetRecomputeHeap(ctx, g.ID, u0.ID) 525 assert.ItsNil(t, err) 526 527 rh, err = mgr.RecomputeHeap(ctx, g.ID) 528 assert.ItsNil(t, err) 529 assert.ItsEqual(t, 0, len(rh)) 530 } 531 532 func Test_Manager_SetNodeHeights(t *testing.T) { 533 ctx := context.Background() 534 appMgr, done := apputil.NewTest(t) 535 defer done() 536 537 u0 := apputil.CreateTestUser(t, appMgr) 538 539 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 540 541 mgr := Manager{ 542 BaseManager: appMgr.BaseManager, 543 } 544 545 newHeights := make(map[uuid.UUID]int) 546 for _, node := range nodes { 547 newHeights[node.ID] = len(nodes) + len(newHeights) 548 } 549 550 err := mgr.SetNodeHeights(ctx, g.ID, newHeights) 551 assert.ItsNil(t, err) 552 553 verifyNodes, err := mgr.Nodes(ctx, g.ID) 554 assert.ItsNil(t, err) 555 assert.ItsAll(t, verifyNodes, func(n Node) bool { 556 return n.Height >= len(nodes) 557 }) 558 } 559 560 func Test_Manager_SetNodeMetadata(t *testing.T) { 561 ctx := context.Background() 562 appMgr, done := apputil.NewTest(t) 563 defer done() 564 565 u0 := apputil.CreateTestUser(t, appMgr) 566 567 g, nodes := CreateTestGraph(t, &appMgr.BaseManager, u0) 568 569 mgr := Manager{ 570 BaseManager: appMgr.BaseManager, 571 } 572 573 newMeta := make(map[uuid.UUID]Node) 574 for _, node := range nodes { 575 newMeta[node.ID] = Node{ 576 SetAt: uint64(len(nodes) + 1), 577 ChangedAt: uint64(len(nodes) + 3), 578 RecomputedAt: uint64(len(nodes) + 4), 579 } 580 } 581 582 err := mgr.SetNodeMetadata(ctx, g.ID, newMeta) 583 assert.ItsNil(t, err) 584 585 verifyNodes, err := mgr.Nodes(ctx, g.ID) 586 assert.ItsNil(t, err) 587 assert.ItsAll(t, verifyNodes, func(n Node) bool { 588 return n.SetAt > uint64(len(nodes)) 589 }) 590 assert.ItsAll(t, verifyNodes, func(n Node) bool { 591 return n.ChangedAt > uint64(len(nodes)+2) 592 }) 593 assert.ItsAll(t, verifyNodes, func(n Node) bool { 594 return n.RecomputedAt > uint64(len(nodes)+3) 595 }) 596 }