Skip to content

Commit 731fc0c

Browse files
committed
Restore and fix tests according to architectural changes
1 parent 630f12c commit 731fc0c

File tree

7 files changed

+120
-26
lines changed

7 files changed

+120
-26
lines changed

src/Bolt/Session.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public function readTransaction(callable $tsxHandler, ?TransactionConfiguration
113113

114114
return $this->retry($tsxHandler, false, $config);
115115
}
116+
116117
/**
117118
* @template U
118119
*
@@ -149,12 +150,14 @@ private function retry(callable $tsxHandler, bool $read, TransactionConfiguratio
149150
}
150151
}
151152
}
153+
152154
private static function triggerLazyResult(mixed $tbr): void
153155
{
154156
if ($tbr instanceof CypherSequence) {
155157
$tbr->preload();
156158
}
157159
}
160+
158161
public function transaction(callable $tsxHandler, ?TransactionConfiguration $config = null)
159162
{
160163
return $this->writeTransaction($tsxHandler, $config);

testkit-backend/src/Handlers/SessionBeginTransaction.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
use Laudis\Neo4j\TestkitBackend\Requests\SessionBeginTransactionRequest;
2222
use Laudis\Neo4j\TestkitBackend\Responses\DriverErrorResponse;
2323
use Laudis\Neo4j\TestkitBackend\Responses\TransactionResponse;
24-
use Laudis\Neo4j\Types\AbstractCypherObject;
25-
use Laudis\Neo4j\Types\CypherList;
26-
use Laudis\Neo4j\Types\CypherMap;
2724
use Psr\Log\LoggerInterface;
2825
use Symfony\Component\Uid\Uuid;
2926

testkit-backend/src/Handlers/SessionReadTransaction.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
use Laudis\Neo4j\TestkitBackend\Requests\SessionReadTransactionRequest;
2222
use Laudis\Neo4j\TestkitBackend\Responses\DriverErrorResponse;
2323
use Laudis\Neo4j\TestkitBackend\Responses\RetryableTryResponse;
24-
use Laudis\Neo4j\Types\CypherList;
25-
use Laudis\Neo4j\Types\CypherMap;
2624
use Symfony\Component\Uid\Uuid;
2725

2826
/**

testkit-backend/src/Handlers/SessionWriteTransaction.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
use Laudis\Neo4j\TestkitBackend\Requests\SessionWriteTransactionRequest;
2222
use Laudis\Neo4j\TestkitBackend\Responses\DriverErrorResponse;
2323
use Laudis\Neo4j\TestkitBackend\Responses\RetryableTryResponse;
24-
use Laudis\Neo4j\Types\CypherList;
25-
use Laudis\Neo4j\Types\CypherMap;
2624
use Symfony\Component\Uid\Uuid;
2725

2826
/**

tests/Integration/SummarizedResultFormatterTest.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use Laudis\Neo4j\Contracts\TransactionInterface;
2525
use Laudis\Neo4j\Databags\SummarizedResult;
2626
use Laudis\Neo4j\Databags\SummaryCounters;
27+
use Laudis\Neo4j\Formatter\Specialised\BoltOGMTranslator;
28+
use Laudis\Neo4j\Formatter\SummarizedResultFormatter;
2729
use Laudis\Neo4j\Tests\EnvironmentAwareIntegrationTest;
2830
use Laudis\Neo4j\Types\CartesianPoint;
2931
use Laudis\Neo4j\Types\CypherList;
@@ -521,4 +523,93 @@ private function articlesQuery(): string
521523
article.readingTime = duration(articleProperties.readingTime)
522524
CYPHER;
523525
}
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' => 0,
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+
$this->assertGreaterThanOrEqual(0, $counters->systemUpdates());
567+
$this->assertEquals($counters->systemUpdates() > 0, $counters->containsSystemUpdates());
568+
569+
$result2 = $this->getSession()->run('DROP INDEX non_existent_test_index IF EXISTS');
570+
571+
$summary2 = $result2->getSummary();
572+
$counters2 = $summary2->getCounters();
573+
574+
$this->assertEquals(0, $counters2->systemUpdates());
575+
$this->assertFalse($counters2->containsSystemUpdates());
576+
577+
$this->getSession()->run('DROP INDEX duplicate_test_index IF EXISTS');
578+
}
579+
580+
public function testMultipleSystemOperationsForBug(): void
581+
{
582+
$operations = [
583+
'CREATE INDEX multi_test_1 IF NOT EXISTS FOR (n:MultiTestNode) ON (n.prop1)',
584+
'CREATE INDEX multi_test_2 IF NOT EXISTS FOR (n:MultiTestNode) ON (n.prop2)',
585+
'CREATE CONSTRAINT multi_test_constraint IF NOT EXISTS FOR (n:MultiTestNode) REQUIRE n.id IS UNIQUE',
586+
'DROP INDEX multi_test_1 IF EXISTS',
587+
'DROP INDEX multi_test_2 IF EXISTS',
588+
'DROP CONSTRAINT multi_test_constraint IF EXISTS',
589+
];
590+
591+
foreach ($operations as $operation) {
592+
$result = $this->getSession()->run($operation);
593+
594+
$summary = $result->getSummary();
595+
$counters = $summary->getCounters();
596+
597+
// Test that system operations properly track system updates
598+
$this->assertGreaterThanOrEqual(0, $counters->systemUpdates());
599+
$this->assertEquals($counters->systemUpdates() > 0, $counters->containsSystemUpdates());
600+
}
601+
}
602+
603+
public function testRegularDataOperationsStillWork(): void
604+
{
605+
$result = $this->getSession()->run('CREATE (n:RegularTestNode {name: "test", id: $id}) RETURN n', ['id' => bin2hex(random_bytes(8))]);
606+
607+
$summary = $result->getSummary();
608+
$counters = $summary->getCounters();
609+
610+
$this->assertEquals(0, $counters->systemUpdates());
611+
$this->assertFalse($counters->containsSystemUpdates());
612+
613+
$this->getSession()->run('MATCH (n:RegularTestNode) DELETE n');
614+
}
524615
}

tests/Unit/BasicAuthTest.php

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Laudis\Neo4j\Authentication\BasicAuth;
2121
use Laudis\Neo4j\Bolt\BoltConnection;
2222
use Laudis\Neo4j\Common\Neo4jLogger;
23+
use Laudis\Neo4j\Databags\Neo4jError;
2324
use Laudis\Neo4j\Exception\Neo4jException;
2425
use PHPUnit\Framework\MockObject\Exception;
2526
use PHPUnit\Framework\TestCase;
@@ -56,19 +57,18 @@ public function testAuthenticateBoltSuccess(): void
5657
{
5758
$userAgent = 'neo4j-client/1.0';
5859

59-
$protocol = $this->createMock(BoltConnection::class);
60-
61-
$response = new Response(
60+
$mockProtocol = $this->createMock(V5::class);
61+
$mockProtocol->method('hello');
62+
$mockProtocol->method('getResponse')->willReturn(new Response(
6263
Message::HELLO,
6364
Signature::SUCCESS,
6465
['server' => 'neo4j-server', 'connection_id' => '12345', 'hints' => []]
65-
);
66+
));
6667

67-
$protocol->expects($this->once())
68-
->method('getResponse')
69-
->willReturn($response);
68+
$mockConnection = $this->createMock(BoltConnection::class);
69+
$mockConnection->method('protocol')->willReturn($mockProtocol);
7070

71-
$result = $this->auth->authenticateBolt($protocol, $userAgent);
71+
$result = $this->auth->authenticateBolt($mockConnection, $userAgent);
7272
$this->assertArrayHasKey('server', $result);
7373
$this->assertSame('neo4j-server', $result['server']);
7474
$this->assertSame('12345', $result['connection_id']);
@@ -78,16 +78,22 @@ public function testAuthenticateBoltFailure(): void
7878
{
7979
$this->expectException(Neo4jException::class);
8080

81-
$protocol = $this->createMock(V5::class);
82-
$response = new Response(
81+
$mockProtocol = $this->createMock(V5::class);
82+
$mockProtocol->method('hello');
83+
$mockProtocol->method('getResponse')->willReturn(new Response(
8384
Message::HELLO,
8485
Signature::FAILURE,
8586
['code' => 'Neo.ClientError.Security.Unauthorized', 'message' => 'Invalid credentials']
86-
);
87+
));
88+
89+
$mockConnection = $this->createMock(BoltConnection::class);
90+
$mockConnection->method('protocol')->willReturn($mockProtocol);
8791

88-
$protocol->method('getResponse')->willReturn($response);
92+
$error = Neo4jError::fromMessageAndCode('Neo.ClientError.Security.Unauthorized', 'Invalid credentials');
93+
$exception = new Neo4jException([$error]);
94+
$mockConnection->method('assertNoFailure')->will($this->throwException($exception));
8995

90-
$this->auth->authenticateBolt($protocol, 'neo4j-client/1.0');
96+
$this->auth->authenticateBolt($mockConnection, 'neo4j-client/1.0');
9197
}
9298

9399
public function testEmptyCredentials(): void

tests/Unit/BoltFactoryTest.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
use Bolt\connection\IConnection;
1717
use Bolt\enum\ServerState;
1818
use Bolt\protocol\V5;
19-
use Laudis\Neo4j\Authentication\Authenticate;
2019
use Laudis\Neo4j\Bolt\BoltConnection;
2120
use Laudis\Neo4j\Bolt\Connection;
2221
use Laudis\Neo4j\Bolt\ProtocolFactory;
2322
use Laudis\Neo4j\Bolt\SslConfigurationFactory;
2423
use Laudis\Neo4j\BoltFactory;
2524
use Laudis\Neo4j\Common\Uri;
25+
use Laudis\Neo4j\Contracts\AuthenticateInterface;
2626
use Laudis\Neo4j\Contracts\BasicConnectionFactoryInterface;
2727
use Laudis\Neo4j\Databags\ConnectionRequestData;
2828
use Laudis\Neo4j\Databags\SessionConfiguration;
@@ -46,10 +46,7 @@ protected function setUp(): void
4646
$protocol = new V5(1, $connection);
4747
$protocol->serverState = ServerState::READY;
4848

49-
return [
50-
$protocol,
51-
['server' => 'abc', 'connection_id' => 'i'],
52-
];
49+
return $protocol;
5350
});
5451

5552
$this->factory = new BoltFactory(
@@ -61,8 +58,12 @@ protected function setUp(): void
6158

6259
public function testCreateBasic(): void
6360
{
61+
$auth = $this->createMock(AuthenticateInterface::class);
62+
$auth->method('authenticateBolt')
63+
->willReturn(['server' => 'abc', 'connection_id' => 'i', 'hints' => []]);
64+
6465
$connection = $this->factory->createConnection(
65-
new ConnectionRequestData('', Uri::create(''), Authenticate::disabled(), '', SslConfiguration::default()),
66+
new ConnectionRequestData('', Uri::create(''), $auth, '', SslConfiguration::default()),
6667
SessionConfiguration::default()
6768
);
6869

0 commit comments

Comments
 (0)