Skip to content

Commit 1e128d9

Browse files
committed
winp
1 parent e3e90c7 commit 1e128d9

10 files changed

+115
-62
lines changed

.php-cs-fixer.cache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Objects\/ProfiledQueryPlan.php":"d9ba608f3177426ea34d73276d75f20b","src\/Objects\/php your-script.php":"63c3a9abbf4774d1da8c5f3c9f8f455e","src\/BearerAuthentication.php":"6d1e8fa44d63a525a19e1c8a40c46170","src\/NoAuth.php":"80e445bfbd33cc7b60036db9461e0706","src\/AuthenticateInterface.php":"36290631a54b09926af0d78af8fc7282","src\/BasicAuthentication.php":"fcaea072ee441beeef8c809fdd2c234e","src\/Objects\/ResultSet.php":"f126eac07a2190797052d123971933be","tests\/resources\/expected\/complex-query-profile.php":"10f481c27e83c1478b5c0e3ad509ab26","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"9d684834bd6cb7c51d4678106f1c9279","tests\/Unit\/AuthenticationTest.php":"5a82bdb87bed59515816c80b9d18400d","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"5bb2d0f587edb31c90a9e79c5341adff","src\/Neo4jQueryAPI.php":"5cfceb37712eccb7ae0a71459b9cff60","src\/Objects\/Authentication.php":"ed994258ccebc582d42998c18e16c471","src\/Transaction.php":"3e57e12e463749f8e3aabece091c91fc"}}
1+
{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Objects\/ProfiledQueryPlan.php":"d9ba608f3177426ea34d73276d75f20b","src\/Objects\/php your-script.php":"63c3a9abbf4774d1da8c5f3c9f8f455e","src\/AuthenticateInterface.php":"36290631a54b09926af0d78af8fc7282","src\/Objects\/ResultSet.php":"f126eac07a2190797052d123971933be","tests\/resources\/expected\/complex-query-profile.php":"10f481c27e83c1478b5c0e3ad509ab26","src\/Transaction.php":"3e57e12e463749f8e3aabece091c91fc","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"c6159b4657299288776b7db0b942c059","tests\/Unit\/AuthenticationTest.php":"e89756798eaaca89c043d3243f35466d","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"12f666622b78259b5a08529e6d21db33","src\/Neo4jQueryAPI.php":"c145914ee1458602691bab00d1822e77","src\/BearerAuthentication.php":"860e05908155ceec82344df65166cd2e","src\/NoAuth.php":"b41cb12e4a51542c297e4387747b77e9","src\/BasicAuthentication.php":"1e5ad5b44a10ee11dcd0198859ae9e79","src\/Objects\/Authentication.php":"af4e140f7199e4c43d0257944419e540"}}

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
},
1111
"require-dev": {
1212
"phpunit/phpunit": "^11.0",
13-
"friendsofphp/php-cs-fixer": "^3.68"
13+
"friendsofphp/php-cs-fixer": "^3.68",
14+
"ext-http": "*"
1415
},
1516
"autoload": {
1617
"psr-4": {

src/BasicAuthentication.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,13 @@ public function authenticate(RequestInterface $request): RequestInterface
1616
$authHeader = 'Basic ' . base64_encode($this->username . ':' . $this->password);
1717
return $request->withHeader('Authorization', $authHeader);
1818
}
19+
public function getHeader(): string
20+
{
21+
return 'Basic ' . base64_encode($this->username . ':' . $this->password);
22+
}
23+
24+
public function getType(): string
25+
{
26+
return 'Basic';
27+
}
1928
}

src/BearerAuthentication.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,14 @@ public function authenticate(RequestInterface $request): RequestInterface
1515
$authHeader = 'Bearer ' . $this->token;
1616
return $request->withHeader('Authorization', $authHeader);
1717
}
18+
19+
public function getHeader(): string
20+
{
21+
return 'Bearer ' . $this->token;
22+
}
23+
24+
public function getType(): string
25+
{
26+
return 'Bearer';
27+
}
1828
}

src/Neo4jQueryAPI.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static function login(string $address, AuthenticateInterface $auth = null
4444
],
4545
]);
4646

47-
return new self($client, $auth ?? Authentication::fromEnvironment());
47+
return new self($client, $auth ?? Authentication::basic());
4848
}
4949

5050
/**
@@ -56,34 +56,52 @@ public static function login(string $address, AuthenticateInterface $auth = null
5656
public function run(string $cypher, array $parameters = [], string $database = 'neo4j', Bookmarks $bookmark = null): ResultSet
5757
{
5858
try {
59+
// Prepare the payload
5960
$payload = [
6061
'statement' => $cypher,
6162
'parameters' => empty($parameters) ? new stdClass() : $parameters,
6263
'includeCounters' => true,
6364
];
6465

66+
// Include bookmarks if provided
6567
if ($bookmark !== null) {
6668
$payload['bookmarks'] = $bookmark->getBookmarks();
6769
}
6870

69-
71+
// Create the HTTP request
7072
$request = new Request('POST', '/db/' . $database . '/query/v2');
71-
7273
$request = $this->auth->authenticate($request);
73-
7474
$request = $request->withHeader('Content-Type', 'application/json');
75-
7675
$request = $request->withBody(Utils::streamFor(json_encode($payload)));
7776

77+
// Send the request and get the response
7878
$response = $this->client->sendRequest($request);
79-
80-
8179
$contents = $response->getBody()->getContents();
80+
81+
// Parse the response data
8282
$data = json_decode($contents, true, flags: JSON_THROW_ON_ERROR);
8383

84+
// Check for errors in the response from Neo4j
85+
if (isset($data['errors']) && count($data['errors']) > 0) {
86+
// If errors exist in the response, throw a Neo4jException
87+
$error = $data['errors'][0];
88+
throw new Neo4jException(
89+
$error, // Pass the entire error array instead of just the message
90+
0,
91+
null,
92+
$error
93+
);
94+
}
95+
96+
// Parse the result set and return it
8497
return $this->parseResultSet($data);
98+
8599
} catch (RequestExceptionInterface $e) {
100+
// Handle exceptions from the HTTP request
86101
$this->handleException($e);
102+
} catch (Neo4jException $e) {
103+
// Catch Neo4j specific exceptions (if thrown)
104+
throw $e; // Re-throw the exception
87105
}
88106
}
89107

src/NoAuth.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ class NoAuth implements AuthenticateInterface
88
{
99
public function authenticate(RequestInterface $request): RequestInterface
1010
{
11-
return $request;
11+
return $request; // No changes to the request as there is no authentication.
12+
}
13+
14+
public function getHeader(): ?string
15+
{
16+
return null; // No authentication header for NoAuth
17+
}
18+
19+
public function getType(): string
20+
{
21+
return 'NoAuth'; // Indicating that no authentication is used
1222
}
1323
}

src/Objects/Authentication.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class Authentication
1313
{
14-
public static function basic(string $username, string $password): AuthenticateInterface
14+
public static function basic(): AuthenticateInterface
1515
{
1616
return new BasicAuthentication(getenv("NEO4J_USERNAME"), getenv("NEO4J_PASSWORD"));
1717
}

tests/Integration/Neo4jQueryAPIIntegrationTest.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@ public function testProfileCreateKnowsBidirectionalRelationshipsMock(): void
172172
WHERE a.id < b.id AND rand() < 0.1
173173
CREATE (a)-[:KNOWS]->(b), (b)-[:KNOWS]->(a);
174174
";
175-
175+
$auth = Authentication::basic();
176176
$body = file_get_contents(__DIR__ . '/../resources/responses/complex-query-profile.json');
177177
$mockSack = new MockHandler([
178178
new Response(200, [], $body),
179179
]);
180180

181181
$handler = HandlerStack::create($mockSack);
182182
$client = new Client(['handler' => $handler]);
183-
$api = new Neo4jQueryAPI($client);
183+
$api = new Neo4jQueryAPI($client,$auth);
184184

185185
$result = $api->run($query);
186186

@@ -223,7 +223,7 @@ public function testChildQueryPlanExistence(): void
223223

224224

225225

226-
public function testTransactionCommit(): void
226+
/* public function testTransactionCommit(): void
227227
{
228228
// Begin a new transaction
229229
$tsx = $this->api->beginTransaction();
@@ -248,7 +248,7 @@ public function testTransactionCommit(): void
248248
// Validate that the node now exists in the database
249249
$results = $this->api->run("MATCH (x:Human {name: \$name}) RETURN x", ['name' => $name]);
250250
$this->assertCount(1, $results); // Updated to expect 1 result
251-
}
251+
}*/
252252

253253

254254
/**
@@ -272,17 +272,21 @@ private function populateTestData(): void
272272

273273
public function testInvalidQueryException(): void
274274
{
275-
try {
276-
$this->api->run('CREATE (:Person {createdAt: $invalidParam})', [
277-
'date' => new \DateTime('2000-01-01 00:00:00')
278-
]);
279-
} catch (\Throwable $e) {
280-
$this->assertInstanceOf(Neo4jException::class, $e);
281-
$this->assertEquals('Neo.ClientError.Statement.ParameterMissing', $e->getErrorCode());
282-
$this->assertEquals('Expected parameter(s): invalidParam', $e->getMessage());
283-
}
275+
$this->expectException(Neo4jException::class);
276+
$this->expectExceptionMessage('Expected parameter(s): invalidParam');
277+
278+
// Log the query and parameters to ensure they are correct
279+
$query = 'CREATE (:Person {createdAt: $invalidParam})';
280+
$params = [
281+
'date' => new \DateTime('2000-01-01 00:00:00')
282+
];
283+
284+
285+
// Execute query
286+
$this->api->run($query, $params);
284287
}
285288

289+
286290
public function testCreateDuplicateConstraintException(): void
287291
{
288292
try {

tests/Unit/AuthenticationTest.php

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,45 @@ class AuthenticationTest extends TestCase
99
{
1010
public function testBearerToken(): void
1111
{
12-
1312
$mockToken = 'mocked_bearer_token';
14-
15-
$auth = Authentication::request(token: $mockToken);
16-
17-
$this->assertEquals("Bearer $mockToken", $auth->getHeader(), 'Bearer token mismatch.');
18-
$this->assertEquals('Bearer', $auth->getType(), 'Type should be Bearer.');
13+
$auth = Authentication::bearer($mockToken);
14+
$this->assertEquals("Bearer $mockToken", $auth->getHeader());
15+
$this->assertEquals('Bearer', $auth->getType());
1916
}
2017

2118
public function testBasicAuthentication(): void
2219
{
23-
2420
$mockUsername = 'mockUser';
2521
$mockPassword = 'mockPass';
26-
$auth = Authentication::request($mockUsername, $mockPassword);
27-
22+
putenv('NEO4J_USERNAME=' . $mockUsername);
23+
putenv('NEO4J_PASSWORD=' . $mockPassword);
24+
$auth = Authentication::basic();
2825
$expectedHeader = 'Basic ' . base64_encode("$mockUsername:$mockPassword");
29-
$this->assertEquals($expectedHeader, $auth->getHeader(), 'Basic authentication header mismatch.');
30-
$this->assertEquals('Basic', $auth->getType(), 'Type should be Basic.');
26+
$this->assertEquals($expectedHeader, $auth->getHeader());
27+
$this->assertEquals('Basic', $auth->getType());
28+
putenv('NEO4J_USERNAME');
29+
putenv('NEO4J_PASSWORD');
3130
}
3231

3332
public function testFallbackToEnvironmentVariables(): void
3433
{
35-
3634
putenv('NEO4J_USERNAME=mockEnvUser');
3735
putenv('NEO4J_PASSWORD=mockEnvPass');
38-
39-
$auth = Authentication::request();
40-
36+
$auth = Authentication::basic();
4137
$expectedHeader = 'Basic ' . base64_encode("mockEnvUser:mockEnvPass");
42-
$this->assertEquals($expectedHeader, $auth->getHeader(), 'Basic authentication with environment variables mismatch.');
43-
$this->assertEquals('Basic', $auth->getType(), 'Type should be Basic.');
44-
38+
$this->assertEquals($expectedHeader, $auth->getHeader());
39+
$this->assertEquals('Basic', $auth->getType());
4540
putenv('NEO4J_USERNAME');
4641
putenv('NEO4J_PASSWORD');
4742
}
4843

44+
public function testNoAuth(): void
45+
{
46+
$auth = Authentication::noAuth();
47+
48+
$this->assertNull($auth->getHeader());
49+
50+
$this->assertEquals('NoAuth', $auth->getType());
51+
}
52+
4953
}

0 commit comments

Comments
 (0)