|
24 | 24 | use Laudis\Neo4j\Contracts\TransactionInterface;
|
25 | 25 | use Laudis\Neo4j\Databags\SummarizedResult;
|
26 | 26 | use Laudis\Neo4j\Databags\SummaryCounters;
|
| 27 | +use Laudis\Neo4j\Formatter\Specialised\BoltOGMTranslator; |
| 28 | +use Laudis\Neo4j\Formatter\SummarizedResultFormatter; |
27 | 29 | use Laudis\Neo4j\Tests\EnvironmentAwareIntegrationTest;
|
28 | 30 | use Laudis\Neo4j\Types\CartesianPoint;
|
29 | 31 | use Laudis\Neo4j\Types\CypherList;
|
@@ -521,4 +523,98 @@ private function articlesQuery(): string
|
521 | 523 | article.readingTime = duration(articleProperties.readingTime)
|
522 | 524 | CYPHER;
|
523 | 525 | }
|
| 526 | + |
| 527 | + public function testFormatBoltStatsWithFalseSystemUpdates(): void |
| 528 | + { |
| 529 | + $formatter = new SummarizedResultFormatter(new BoltOGMTranslator()); |
| 530 | + |
| 531 | + $response = [ |
| 532 | + 'stats' => [ |
| 533 | + 'nodes-created' => 1, |
| 534 | + 'nodes-deleted' => 0, |
| 535 | + 'relationships-created' => 0, |
| 536 | + 'relationships-deleted' => 0, |
| 537 | + 'properties-set' => 2, |
| 538 | + 'labels-added' => 1, |
| 539 | + 'labels-removed' => 0, |
| 540 | + 'indexes-added' => 0, |
| 541 | + 'indexes-removed' => 0, |
| 542 | + 'constraints-added' => 0, |
| 543 | + 'constraints-removed' => 0, |
| 544 | + 'contains-updates' => true, |
| 545 | + 'contains-system-updates' => false, |
| 546 | + 'system-updates' => false, |
| 547 | + ], |
| 548 | + ]; |
| 549 | + |
| 550 | + $counters = $formatter->formatBoltStats($response); |
| 551 | + |
| 552 | + self::assertInstanceOf(SummaryCounters::class, $counters); |
| 553 | + self::assertEquals(1, $counters->nodesCreated()); |
| 554 | + self::assertEquals(2, $counters->propertiesSet()); |
| 555 | + self::assertSame(0, $counters->systemUpdates()); |
| 556 | + } |
| 557 | + |
| 558 | + public function testSystemUpdatesWithPotentialFalseValues(): void |
| 559 | + { |
| 560 | + $this->getSession()->run('CREATE INDEX duplicate_test_index IF NOT EXISTS FOR (n:TestSystemUpdates) ON (n.duplicateProperty)'); |
| 561 | + $result = $this->getSession()->run('CREATE INDEX duplicate_test_index IF NOT EXISTS FOR (n:TestSystemUpdates) ON (n.duplicateProperty)'); |
| 562 | + |
| 563 | + $summary = $result->getSummary(); |
| 564 | + $counters = $summary->getCounters(); |
| 565 | + |
| 566 | + // For duplicate index creation (IF NOT EXISTS), might not create system updates |
| 567 | + $this->assertGreaterThanOrEqual(0, $counters->systemUpdates()); |
| 568 | + // containsSystemUpdates should be consistent with systemUpdates count |
| 569 | + $this->assertEquals($counters->systemUpdates() > 0, $counters->containsSystemUpdates()); |
| 570 | + |
| 571 | + $result2 = $this->getSession()->run('DROP INDEX non_existent_test_index IF EXISTS'); |
| 572 | + |
| 573 | + $summary2 = $result2->getSummary(); |
| 574 | + $counters2 = $summary2->getCounters(); |
| 575 | + |
| 576 | + // Dropping non-existent index should not create system updates |
| 577 | + $this->assertEquals(0, $counters2->systemUpdates()); |
| 578 | + $this->assertFalse($counters2->containsSystemUpdates()); |
| 579 | + |
| 580 | + $this->getSession()->run('DROP INDEX duplicate_test_index IF EXISTS'); |
| 581 | + } |
| 582 | + |
| 583 | + public function testMultipleSystemOperationsForBug(): void |
| 584 | + { |
| 585 | + $operations = [ |
| 586 | + 'CREATE INDEX multi_test_1 IF NOT EXISTS FOR (n:MultiTestNode) ON (n.prop1)', |
| 587 | + 'CREATE INDEX multi_test_2 IF NOT EXISTS FOR (n:MultiTestNode) ON (n.prop2)', |
| 588 | + 'CREATE CONSTRAINT multi_test_constraint IF NOT EXISTS FOR (n:MultiTestNode) REQUIRE n.id IS UNIQUE', |
| 589 | + 'DROP INDEX multi_test_1 IF EXISTS', |
| 590 | + 'DROP INDEX multi_test_2 IF EXISTS', |
| 591 | + 'DROP CONSTRAINT multi_test_constraint IF EXISTS', |
| 592 | + ]; |
| 593 | + |
| 594 | + foreach ($operations as $operation) { |
| 595 | + $result = $this->getSession()->run($operation); |
| 596 | + |
| 597 | + $summary = $result->getSummary(); |
| 598 | + $counters = $summary->getCounters(); |
| 599 | + |
| 600 | + // Test that system operations properly track system updates |
| 601 | + $this->assertGreaterThanOrEqual(0, $counters->systemUpdates()); |
| 602 | + // Verify consistency between systemUpdates count and containsSystemUpdates flag |
| 603 | + $this->assertEquals($counters->systemUpdates() > 0, $counters->containsSystemUpdates()); |
| 604 | + } |
| 605 | + } |
| 606 | + |
| 607 | + public function testRegularDataOperationsStillWork(): void |
| 608 | + { |
| 609 | + $result = $this->getSession()->run('CREATE (n:RegularTestNode {name: "test", id: $id}) RETURN n', ['id' => bin2hex(random_bytes(8))]); |
| 610 | + |
| 611 | + $summary = $result->getSummary(); |
| 612 | + $counters = $summary->getCounters(); |
| 613 | + |
| 614 | + // Regular data operations should not involve system updates |
| 615 | + $this->assertEquals(0, $counters->systemUpdates()); |
| 616 | + $this->assertFalse($counters->containsSystemUpdates()); |
| 617 | + |
| 618 | + $this->getSession()->run('MATCH (n:RegularTestNode) DELETE n'); |
| 619 | + } |
524 | 620 | }
|
0 commit comments