Skip to content

Commit b46c1dc

Browse files
committed
Merge branch 'ISSUE-198' of github.com:neo4j-php/neo4j-php-client into ISSUE-198
2 parents 0420bc7 + 2a11d50 commit b46c1dc

9 files changed

+67
-71
lines changed

.github/workflows/integration-test-aura.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ jobs:
2525
- uses: php-actions/composer@v6
2626
with:
2727
progress: yes
28-
php_version: 8.0
28+
php_version: 8.1
2929
version: 2
3030
- name: clean database
3131
run: CONNECTION=$CONNECTION php tests/clean-database.php
3232
- uses: php-actions/phpunit@v3
3333
with:
3434
configuration: phpunit.xml.dist
35-
php_version: 8.0
35+
php_version: 8.1
3636
memory_limit: 1024M
3737
version: composer
3838
testsuite: Integration

.github/workflows/integration-test-cluster-neo4j-4.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
runs-on: ubuntu-latest
1414
env:
1515
CONNECTION: neo4j://neo4j:testtest@localhost:7688
16-
name: "Running on PHP 8.0 in a Neo4j 4.4 cluster"
16+
name: "Running on PHP 8.1 in a Neo4j 4.4 cluster"
1717

1818
steps:
1919
- uses: actions/checkout@v2
@@ -25,12 +25,12 @@ jobs:
2525
- uses: php-actions/composer@v6
2626
with:
2727
progress: yes
28-
php_version: 8.0
28+
php_version: 8.1
2929
version: 2
3030
- uses: php-actions/phpunit@v3
3131
with:
3232
configuration: phpunit.xml.dist
33-
php_version: 8.0
33+
php_version: 8.1
3434
memory_limit: 1024M
3535
version: composer
3636
testsuite: Integration

.github/workflows/integration-test-cluster-neo4j-5.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
runs-on: ubuntu-latest
1414
env:
1515
CONNECTION: neo4j://neo4j:testtest@localhost:7687
16-
name: "Running on PHP 8.0 with a Neo4j 5.10-enterprise cluster"
16+
name: "Running on PHP 8.1 with a Neo4j 5.10-enterprise cluster"
1717

1818
steps:
1919
- uses: actions/checkout@v2
@@ -25,12 +25,12 @@ jobs:
2525
- uses: php-actions/composer@v6
2626
with:
2727
progress: yes
28-
php_version: 8.0
28+
php_version: 8.1
2929
version: 2
3030
- uses: php-actions/phpunit@v3
3131
with:
3232
configuration: phpunit.xml.dist
33-
php_version: 8.0
33+
php_version: 8.1
3434
memory_limit: 1024M
3535
version: composer
3636
testsuite: Integration

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"psr/http-factory": "^1.0",
2929
"psr/http-client": "^1.0",
3030
"php-http/message": "^1.0",
31-
"stefanak-michal/bolt": "^7.0",
31+
"stefanak-michal/bolt": "^7.0.1",
3232
"symfony/polyfill-php80": "^1.2",
3333
"psr/simple-cache": ">=2.0",
3434
"ext-json": "*",

src/Bolt/BoltConnection.php

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Laudis\Neo4j\Contracts\FormatterInterface;
2727
use Laudis\Neo4j\Databags\BookmarkHolder;
2828
use Laudis\Neo4j\Databags\DatabaseInfo;
29+
use Laudis\Neo4j\Databags\Neo4jError;
2930
use Laudis\Neo4j\Enum\AccessMode;
3031
use Laudis\Neo4j\Enum\ConnectionProtocol;
3132
use Laudis\Neo4j\Exception\Neo4jException;
@@ -166,11 +167,10 @@ public function consumeResults(): void
166167
*/
167168
public function reset(): void
168169
{
169-
$response = $this->protocol()->reset()
170+
$response = $this->protocol()
171+
->reset()
170172
->getResponse();
171-
172173
$this->assertNoFailure($response);
173-
174174
$this->subscribedResults = [];
175175
}
176176

@@ -182,12 +182,15 @@ public function reset(): void
182182
public function begin(?string $database, ?float $timeout, BookmarkHolder $holder): void
183183
{
184184
$this->consumeResults();
185-
$extra = $this->buildRunExtra($database, $timeout, $holder, AccessMode::WRITE());
186185

186+
if ($this->protocol()->serverState !== ServerState::READY) {
187+
throw new Neo4jException([Neo4jError::fromMessageAndCode('Neo.ClientError.Request.Invalid', 'Message \'BEGIN\' cannot be handled by a session which isn\'t in the READY state.')]);
188+
}
189+
190+
$extra = $this->buildRunExtra($database, $timeout, $holder, AccessMode::WRITE());
187191
$response = $this->protocol()
188192
->begin($extra)
189193
->getResponse();
190-
191194
$this->assertNoFailure($response);
192195
}
193196

@@ -198,12 +201,14 @@ public function begin(?string $database, ?float $timeout, BookmarkHolder $holder
198201
*/
199202
public function discard(?int $qid): void
200203
{
201-
$extra = $this->buildResultExtra(null, $qid);
202-
$bolt = $this->protocol();
204+
if (!in_array($this->protocol()->serverState, [ServerState::STREAMING, ServerState::TX_STREAMING], true)) {
205+
throw new Neo4jException([Neo4jError::fromMessageAndCode('Neo.ClientError.Request.Invalid', 'Message \'DISCARD\' cannot be handled by a session which isn\'t in the STREAMING|TX_STREAMING state.')]);
206+
}
203207

204-
$response = $bolt->discard($extra)
208+
$extra = $this->buildResultExtra(null, $qid);
209+
$response = $this->protocol()
210+
->discard($extra)
205211
->getResponse();
206-
207212
$this->assertNoFailure($response);
208213
}
209214

@@ -216,12 +221,15 @@ public function discard(?int $qid): void
216221
*/
217222
public function run(string $text, array $parameters, ?string $database, ?float $timeout, BookmarkHolder $holder, ?AccessMode $mode): array
218223
{
224+
if (!in_array($this->protocol()->serverState, [ServerState::READY, ServerState::TX_READY, ServerState::TX_STREAMING], true)) {
225+
throw new Neo4jException([Neo4jError::fromMessageAndCode('Neo.ClientError.Request.Invalid', 'Message \'RUN\' cannot be handled by a session which isn\'t in the READY|TX_READY|TX_STREAMING state.')]);
226+
}
227+
219228
$extra = $this->buildRunExtra($database, $timeout, $holder, $mode);
220-
$response = $this->protocol()->run($text, $parameters, $extra)
229+
$response = $this->protocol()
230+
->run($text, $parameters, $extra)
221231
->getResponse();
222-
223232
$this->assertNoFailure($response);
224-
225233
/** @var BoltMeta */
226234
return $response->content;
227235
}
@@ -234,10 +242,14 @@ public function run(string $text, array $parameters, ?string $database, ?float $
234242
public function commit(): void
235243
{
236244
$this->consumeResults();
245+
246+
if ($this->protocol()->serverState !== ServerState::TX_READY) {
247+
throw new Neo4jException([Neo4jError::fromMessageAndCode('Neo.ClientError.Request.Invalid', 'Message \'COMMIT\' cannot be handled by a session which isn\'t in the TX_READY state.')]);
248+
}
249+
237250
$response = $this->protocol()
238251
->commit()
239252
->getResponse();
240-
241253
$this->assertNoFailure($response);
242254
}
243255

@@ -249,10 +261,14 @@ public function commit(): void
249261
public function rollback(): void
250262
{
251263
$this->consumeResults();
264+
265+
if ($this->protocol()->serverState !== ServerState::TX_READY) {
266+
throw new Neo4jException([Neo4jError::fromMessageAndCode('Neo.ClientError.Request.Invalid', 'Message \'ROLLBACK\' cannot be handled by a session which isn\'t in the TX_READY state.')]);
267+
}
268+
252269
$response = $this->protocol()
253270
->rollback()
254271
->getResponse();
255-
256272
$this->assertNoFailure($response);
257273
}
258274

@@ -270,13 +286,16 @@ public function protocol(): V4_4|V5|V5_3|V5_4
270286
*/
271287
public function pull(?int $qid, ?int $fetchSize): array
272288
{
289+
if (!in_array($this->protocol()->serverState, [ServerState::STREAMING, ServerState::TX_STREAMING], true)) {
290+
throw new Neo4jException([Neo4jError::fromMessageAndCode('Neo.ClientError.Request.Invalid', 'Message \'PULL\' cannot be handled by a session which isn\'t in the STREAMING|TX_STREAMING state.')]);
291+
}
292+
273293
$extra = $this->buildResultExtra($fetchSize, $qid);
274294

275295
$tbr = [];
276296
/** @var Response $response */
277297
foreach ($this->protocol()->pull($extra)->getResponses() as $response) {
278298
$this->assertNoFailure($response);
279-
280299
$tbr[] = $response->content;
281300
}
282301

@@ -353,6 +372,7 @@ public function getUserAgent(): string
353372
private function assertNoFailure(Response $response): void
354373
{
355374
if ($response->signature === Signature::FAILURE) {
375+
$this->protocol()->reset()->getResponse(); //what if the reset fails? what should be expected behaviour?
356376
throw Neo4jException::fromBoltResponse($response);
357377
}
358378
}

tests/Integration/ClientIntegrationTest.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,8 @@ public function testValidRun(): void
8787

8888
public function testInvalidRun(): void
8989
{
90-
$exception = false;
91-
try {
92-
$this->getSession()->transaction(static fn (TransactionInterface $tsx) => $tsx->run('MERGE (x:Tes0342hdm21.())', ['test' => 'a', 'otherTest' => 'b']));
93-
} catch (Neo4jException) {
94-
$exception = true;
95-
}
96-
self::assertTrue($exception);
90+
$this->expectException(Neo4jException::class);
91+
$this->getSession()->transaction(static fn (TransactionInterface $tsx) => $tsx->run('MERGE (x:Tes0342hdm21.())', ['test' => 'a', 'otherTest' => 'b']));
9792
}
9893

9994
public function testInvalidRunRetry(): void
@@ -106,7 +101,8 @@ public function testInvalidRunRetry(): void
106101
}
107102
self::assertTrue($exception);
108103

109-
$this->getSession()->run('RETURN 1 AS one');
104+
$response = $this->getSession()->run('RETURN 1 AS one');
105+
$this->assertEquals(1, $response->first()->get('one'));
110106
}
111107

112108
public function testValidStatement(): void
@@ -142,7 +138,7 @@ public function testStatements(): void
142138
$response = $this->getSession()->runStatements([
143139
Statement::create('MERGE (x:TestNode {test: $test})', $params),
144140
Statement::create('MERGE (x:OtherTestNode {test: $otherTest})', $params),
145-
Statement::create('RETURN 1 AS x', []),
141+
Statement::create('RETURN 1 AS x'),
146142
]);
147143

148144
self::assertEquals(3, $response->count());

tests/Integration/ComplexQueryTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,14 @@ public function testPeriodicCommit(): void
198198
self::markTestSkipped('Only local environment has access to local files');
199199
}
200200

201+
$this->getSession()->run('MATCH (n:File) DELETE n');
202+
201203
$this->getSession()->run(<<<CYPHER
202-
USING PERIODIC COMMIT 10
203204
LOAD CSV FROM 'file:///csv-example.csv' AS line
204-
MERGE (n:File {name: line[0]});
205+
CALL {
206+
WITH line
207+
MERGE (n:File {name: line[0]})
208+
} IN TRANSACTIONS OF 10 ROWS;
205209
CYPHER, []);
206210

207211
$result = $this->getSession()->run('MATCH (n:File) RETURN count(n) AS count');
@@ -218,9 +222,11 @@ public function testPeriodicCommitFail(): void
218222

219223
$tsx = $this->getSession(['neo4j', 'bolt'])->beginTransaction([]);
220224
$tsx->run(<<<CYPHER
221-
USING PERIODIC COMMIT 10
222225
LOAD CSV FROM 'file:///csv-example.csv' AS line
223-
MERGE (n:File {name: line[0]});
226+
CALL {
227+
WITH line
228+
MERGE (n:File {name: line[0]})
229+
} IN TRANSACTIONS OF 10 ROWS;
224230
CYPHER
225231
);
226232
$tsx->commit();

tests/Integration/OGMFormatterIntegrationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ public function testPath(): void
365365
public function testPath2(): void
366366
{
367367
$results = $this->getSession()->transaction(static fn (TransactionInterface $tsx) => $tsx->run(<<<'CYPHER'
368-
CREATE path = ((a:Node {x:$x}) - [b:HasNode {attribute: $xy}] -> (c:Node {y:$y}) - [d:HasNode {attribute: $yz}] -> (e:Node {z:$z}))
368+
CREATE path = (a:Node {x:$x}) - [b:HasNode {attribute: $xy}] -> (c:Node {y:$y}) - [d:HasNode {attribute: $yz}] -> (e:Node {z:$z})
369369
RETURN path
370370
CYPHER, ['x' => 'x', 'xy' => 'xy', 'y' => 'y', 'yz' => 'yz', 'z' => 'z']));
371371

tests/Integration/TransactionIntegrationTest.php

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,9 @@
1313

1414
namespace Laudis\Neo4j\Tests\Integration;
1515

16-
use Laudis\Neo4j\Bolt\BoltDriver;
17-
use Laudis\Neo4j\Bolt\Connection;
18-
use Laudis\Neo4j\Bolt\ConnectionPool;
1916
use Laudis\Neo4j\Databags\Statement;
2017
use Laudis\Neo4j\Exception\Neo4jException;
21-
use ReflectionClass;
22-
use Throwable;
18+
use PHPUnit\Framework\Attributes\DoesNotPerformAssertions;
2319

2420
final class TransactionIntegrationTest extends EnvironmentAwareIntegrationTest
2521
{
@@ -224,17 +220,8 @@ public function testCommitInvalid(): void
224220
self::assertFalse($tsx->isRolledBack());
225221
self::assertTrue($tsx->isCommitted());
226222

227-
$exception = false;
228-
try {
229-
$tsx->commit();
230-
} catch (Throwable) {
231-
$exception = true;
232-
}
233-
self::assertTrue($exception);
234-
235-
self::assertTrue($tsx->isFinished());
236-
self::assertFalse($tsx->isRolledBack());
237-
self::assertTrue($tsx->isCommitted());
223+
$this->expectException(Neo4jException::class);
224+
$tsx->commit();
238225
}
239226

240227
public function testRollbackValid(): void
@@ -256,17 +243,8 @@ public function testRollbackInvalid(): void
256243
self::assertTrue($tsx->isRolledBack());
257244
self::assertFalse($tsx->isCommitted());
258245

259-
$exception = false;
260-
try {
261-
$tsx->rollback();
262-
} catch (Throwable) {
263-
$exception = true;
264-
}
265-
self::assertTrue($exception);
266-
267-
self::assertTrue($tsx->isFinished());
268-
self::assertTrue($tsx->isRolledBack());
269-
self::assertFalse($tsx->isCommitted());
246+
$this->expectException(Neo4jException::class);
247+
$tsx->rollback();
270248
}
271249

272250
// /**
@@ -304,9 +282,7 @@ public function testRollbackInvalid(): void
304282
// self::assertCount(3, $cache[$key]);
305283
// }
306284

307-
/**
308-
* @doesNotPerformAssertions
309-
*/
285+
#[DoesNotPerformAssertions]
310286
public function testTransactionRunNoConsumeResult(): void
311287
{
312288
$tsx = $this->getSession()->beginTransaction([]);
@@ -315,9 +291,7 @@ public function testTransactionRunNoConsumeResult(): void
315291
$tsx->commit();
316292
}
317293

318-
/**
319-
* @doesNotPerformAssertions
320-
*/
294+
#[DoesNotPerformAssertions]
321295
public function testTransactionRunNoConsumeButSaveResult(): void
322296
{
323297
$tsx = $this->getSession()->beginTransaction([]);

0 commit comments

Comments
 (0)