diff --git a/src/PathSegment/Key.php b/src/PathSegment/Key.php index 413655164..1e18e93f9 100644 --- a/src/PathSegment/Key.php +++ b/src/PathSegment/Key.php @@ -25,6 +25,13 @@ public static function pipe( ?string $nextSegment, ?PipeInterface $argument ): ?PipeInterface { + // A navigation property that resolves to a collection arrives here wrapped in a + // PropertyValue (e.g. People('id')/Trips/0). Unwrap it so a following key segment + // selects a single related entity, mirroring the People('id')/Trips(0) form. + if ($argument instanceof PropertyValue && $argument->getValue() instanceof EntitySet) { + $argument = $argument->getValue(); + } + if (!$argument instanceof EntitySet) { throw new PathNotHandledException(); } diff --git a/tests/Navigation/Navigation.php b/tests/Navigation/Navigation.php index bdd3fc6b6..35de87be3 100644 --- a/tests/Navigation/Navigation.php +++ b/tests/Navigation/Navigation.php @@ -630,4 +630,50 @@ public function test_create_deep_metadata() $this->urlToReq($response->passengers[0]->{'MyPets@navigationLink'}) ); } + + public function test_read_navigation_property_entity() + { + $this->assertJsonResponseSnapshot( + (new Request) + ->path($this->flightEntitySetPath.'(1)/passengers(3)') + ); + } + + public function test_read_navigation_property_entity_key_as_segment() + { + $this->assertJsonResponseSnapshot( + (new Request) + ->path($this->flightEntitySetPath.'/1/passengers/3') + ); + } + + public function test_update_navigation_property_entity_key_as_segment() + { + $this->assertJsonResponseSnapshot( + (new Request) + ->patch() + ->path($this->flightEntitySetPath.'/1/passengers/3') + ->body([ + 'name' => 'Renamed Passenger', + ]) + ); + } + + public function test_delete_navigation_property_entity() + { + $this->assertNoContent( + (new Request) + ->delete() + ->path($this->flightEntitySetPath.'(1)/passengers(3)') + ); + } + + public function test_delete_navigation_property_entity_key_as_segment() + { + $this->assertNoContent( + (new Request) + ->delete() + ->path($this->flightEntitySetPath.'/1/passengers/3') + ); + } } diff --git a/tests/__snapshots__/Navigation/EloquentTest__test_delete_navigation_property_entity__1.txt b/tests/__snapshots__/Navigation/EloquentTest__test_delete_navigation_property_entity__1.txt new file mode 100644 index 000000000..c28806d09 --- /dev/null +++ b/tests/__snapshots__/Navigation/EloquentTest__test_delete_navigation_property_entity__1.txt @@ -0,0 +1,23 @@ +@@ @@ + "emails": null + }, + { +- "id": 3, +- "flight_id": 1, +- "name": "Gamma", +- "dob": "2002-03-03 06:06:06", +- "age": 2, +- "chips": true, +- "dq": "2002-03-03", +- "in_role": 347561, +- "open_time": "07:07:07", +- "colour": 4, +- "sock_colours": 7, +- "emails": [ +- "gamma@example.com" +- ] +- }, +- { + "id": 4, + "flight_id": null, + "name": "Delta", diff --git a/tests/__snapshots__/Navigation/EloquentTest__test_delete_navigation_property_entity_key_as_segment__1.txt b/tests/__snapshots__/Navigation/EloquentTest__test_delete_navigation_property_entity_key_as_segment__1.txt new file mode 100644 index 000000000..c28806d09 --- /dev/null +++ b/tests/__snapshots__/Navigation/EloquentTest__test_delete_navigation_property_entity_key_as_segment__1.txt @@ -0,0 +1,23 @@ +@@ @@ + "emails": null + }, + { +- "id": 3, +- "flight_id": 1, +- "name": "Gamma", +- "dob": "2002-03-03 06:06:06", +- "age": 2, +- "chips": true, +- "dq": "2002-03-03", +- "in_role": 347561, +- "open_time": "07:07:07", +- "colour": 4, +- "sock_colours": 7, +- "emails": [ +- "gamma@example.com" +- ] +- }, +- { + "id": 4, + "flight_id": null, + "name": "Delta", diff --git a/tests/__snapshots__/Navigation/EloquentTest__test_read_navigation_property_entity__1.json b/tests/__snapshots__/Navigation/EloquentTest__test_read_navigation_property_entity__1.json new file mode 100644 index 000000000..682c3ae8f --- /dev/null +++ b/tests/__snapshots__/Navigation/EloquentTest__test_read_navigation_property_entity__1.json @@ -0,0 +1,17 @@ +{ + "@context": "http://localhost/odata/$metadata#Passengers/$entity", + "id": 3, + "flight_id": 1, + "name": "Gamma", + "dob": "2002-03-03T06:06:06+00:00", + "age": 2, + "chips": true, + "dq": "2002-03-03", + "in_role": "P4DT32M41S", + "open_time": "07:07:07.000000", + "colour": "Blue", + "sock_colours": "Red,Green,Blue", + "emails": [ + "gamma@example.com" + ] +} diff --git a/tests/__snapshots__/Navigation/EloquentTest__test_read_navigation_property_entity_key_as_segment__1.json b/tests/__snapshots__/Navigation/EloquentTest__test_read_navigation_property_entity_key_as_segment__1.json new file mode 100644 index 000000000..682c3ae8f --- /dev/null +++ b/tests/__snapshots__/Navigation/EloquentTest__test_read_navigation_property_entity_key_as_segment__1.json @@ -0,0 +1,17 @@ +{ + "@context": "http://localhost/odata/$metadata#Passengers/$entity", + "id": 3, + "flight_id": 1, + "name": "Gamma", + "dob": "2002-03-03T06:06:06+00:00", + "age": 2, + "chips": true, + "dq": "2002-03-03", + "in_role": "P4DT32M41S", + "open_time": "07:07:07.000000", + "colour": "Blue", + "sock_colours": "Red,Green,Blue", + "emails": [ + "gamma@example.com" + ] +} diff --git a/tests/__snapshots__/Navigation/EloquentTest__test_update_navigation_property_entity_key_as_segment__1.json b/tests/__snapshots__/Navigation/EloquentTest__test_update_navigation_property_entity_key_as_segment__1.json new file mode 100644 index 000000000..cb7e2a1cc --- /dev/null +++ b/tests/__snapshots__/Navigation/EloquentTest__test_update_navigation_property_entity_key_as_segment__1.json @@ -0,0 +1,17 @@ +{ + "@context": "http://localhost/odata/$metadata#Passengers/$entity", + "id": 3, + "flight_id": 1, + "name": "Renamed Passenger", + "dob": "2002-03-03T06:06:06+00:00", + "age": 2, + "chips": true, + "dq": "2002-03-03", + "in_role": "P4DT32M41S", + "open_time": "07:07:07.000000", + "colour": "Blue", + "sock_colours": "Red,Green,Blue", + "emails": [ + "gamma@example.com" + ] +} diff --git a/tests/__snapshots__/Navigation/EloquentTest__test_update_navigation_property_entity_key_as_segment__2.txt b/tests/__snapshots__/Navigation/EloquentTest__test_update_navigation_property_entity_key_as_segment__2.txt new file mode 100644 index 000000000..e43d21ae7 --- /dev/null +++ b/tests/__snapshots__/Navigation/EloquentTest__test_update_navigation_property_entity_key_as_segment__2.txt @@ -0,0 +1,9 @@ +@@ @@ + { + "id": 3, + "flight_id": 1, +- "name": "Gamma", ++ "name": "Renamed Passenger", + "dob": "2002-03-03 06:06:06", + "age": 2, + "chips": true, diff --git a/tests/__snapshots__/Navigation/SQLTest__test_delete_navigation_property_entity__1.txt b/tests/__snapshots__/Navigation/SQLTest__test_delete_navigation_property_entity__1.txt new file mode 100644 index 000000000..c28806d09 --- /dev/null +++ b/tests/__snapshots__/Navigation/SQLTest__test_delete_navigation_property_entity__1.txt @@ -0,0 +1,23 @@ +@@ @@ + "emails": null + }, + { +- "id": 3, +- "flight_id": 1, +- "name": "Gamma", +- "dob": "2002-03-03 06:06:06", +- "age": 2, +- "chips": true, +- "dq": "2002-03-03", +- "in_role": 347561, +- "open_time": "07:07:07", +- "colour": 4, +- "sock_colours": 7, +- "emails": [ +- "gamma@example.com" +- ] +- }, +- { + "id": 4, + "flight_id": null, + "name": "Delta", diff --git a/tests/__snapshots__/Navigation/SQLTest__test_delete_navigation_property_entity_key_as_segment__1.txt b/tests/__snapshots__/Navigation/SQLTest__test_delete_navigation_property_entity_key_as_segment__1.txt new file mode 100644 index 000000000..c28806d09 --- /dev/null +++ b/tests/__snapshots__/Navigation/SQLTest__test_delete_navigation_property_entity_key_as_segment__1.txt @@ -0,0 +1,23 @@ +@@ @@ + "emails": null + }, + { +- "id": 3, +- "flight_id": 1, +- "name": "Gamma", +- "dob": "2002-03-03 06:06:06", +- "age": 2, +- "chips": true, +- "dq": "2002-03-03", +- "in_role": 347561, +- "open_time": "07:07:07", +- "colour": 4, +- "sock_colours": 7, +- "emails": [ +- "gamma@example.com" +- ] +- }, +- { + "id": 4, + "flight_id": null, + "name": "Delta", diff --git a/tests/__snapshots__/Navigation/SQLTest__test_read_navigation_property_entity__1.json b/tests/__snapshots__/Navigation/SQLTest__test_read_navigation_property_entity__1.json new file mode 100644 index 000000000..1f7f83573 --- /dev/null +++ b/tests/__snapshots__/Navigation/SQLTest__test_read_navigation_property_entity__1.json @@ -0,0 +1,17 @@ +{ + "@context": "http://localhost/odata/$metadata#passengers/$entity", + "id": 3, + "name": "Gamma", + "age": 2, + "dob": "2002-03-03T06:06:06+00:00", + "chips": true, + "dq": "2002-03-03", + "in_role": "P4DT32M41S", + "open_time": "07:07:07.000000", + "flight_id": 1, + "colour": "Blue", + "sock_colours": "Red,Green,Blue", + "emails": [ + "gamma@example.com" + ] +} diff --git a/tests/__snapshots__/Navigation/SQLTest__test_read_navigation_property_entity_key_as_segment__1.json b/tests/__snapshots__/Navigation/SQLTest__test_read_navigation_property_entity_key_as_segment__1.json new file mode 100644 index 000000000..1f7f83573 --- /dev/null +++ b/tests/__snapshots__/Navigation/SQLTest__test_read_navigation_property_entity_key_as_segment__1.json @@ -0,0 +1,17 @@ +{ + "@context": "http://localhost/odata/$metadata#passengers/$entity", + "id": 3, + "name": "Gamma", + "age": 2, + "dob": "2002-03-03T06:06:06+00:00", + "chips": true, + "dq": "2002-03-03", + "in_role": "P4DT32M41S", + "open_time": "07:07:07.000000", + "flight_id": 1, + "colour": "Blue", + "sock_colours": "Red,Green,Blue", + "emails": [ + "gamma@example.com" + ] +} diff --git a/tests/__snapshots__/Navigation/SQLTest__test_update_navigation_property_entity_key_as_segment__1.json b/tests/__snapshots__/Navigation/SQLTest__test_update_navigation_property_entity_key_as_segment__1.json new file mode 100644 index 000000000..2b6e3c1df --- /dev/null +++ b/tests/__snapshots__/Navigation/SQLTest__test_update_navigation_property_entity_key_as_segment__1.json @@ -0,0 +1,17 @@ +{ + "@context": "http://localhost/odata/$metadata#passengers/$entity", + "id": 3, + "name": "Renamed Passenger", + "age": 2, + "dob": "2002-03-03T06:06:06+00:00", + "chips": true, + "dq": "2002-03-03", + "in_role": "P4DT32M41S", + "open_time": "07:07:07.000000", + "flight_id": 1, + "colour": "Blue", + "sock_colours": "Red,Green,Blue", + "emails": [ + "gamma@example.com" + ] +} diff --git a/tests/__snapshots__/Navigation/SQLTest__test_update_navigation_property_entity_key_as_segment__2.txt b/tests/__snapshots__/Navigation/SQLTest__test_update_navigation_property_entity_key_as_segment__2.txt new file mode 100644 index 000000000..e43d21ae7 --- /dev/null +++ b/tests/__snapshots__/Navigation/SQLTest__test_update_navigation_property_entity_key_as_segment__2.txt @@ -0,0 +1,9 @@ +@@ @@ + { + "id": 3, + "flight_id": 1, +- "name": "Gamma", ++ "name": "Renamed Passenger", + "dob": "2002-03-03 06:06:06", + "age": 2, + "chips": true,