diff --git a/.env b/.env index 5e98b218..fdfdcfe3 100755 --- a/.env +++ b/.env @@ -28,4 +28,4 @@ ELASTIC_AUTH=ember-nexus-elasticsearch:9200 REDIS_AUTH=tcp://ember-nexus-redis?password=redis-password RABBITMQ_AUTH=amqp://user:password@ember-nexus-rabbitmq:5672 -REFERENCE_DATASET_VERSION=0.0.13 +REFERENCE_DATASET_VERSION=0.0.16 diff --git a/CHANGELOG.md b/CHANGELOG.md index 902e1b2e..9649dbec 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +### Added +- Add explicit feature tests for parents, children and related endpoints to (not) include non-OWNS-relations, related + to #163. ### Changed - Update readme and docker image labels. +- Increase reference dataset version to 0.0.16, skipped 0.0.15 and 0.0.14 due to erroneous releases. +### Fixed +- Fix index endpoint to include elements which are directly owned or are accessible. Fixes #163. ## 0.0.35 - 2023-10-26 diff --git a/docs/api-endpoints/element/get-index/200-response-body.json b/docs/api-endpoints/element/get-index/200-response-body.json index db08be6b..f42bde4b 100644 --- a/docs/api-endpoints/element/get-index/200-response-body.json +++ b/docs/api-endpoints/element/get-index/200-response-body.json @@ -1,7 +1,7 @@ { "type": "_PartialCollection", "id": "/", - "totalNodes": 2, + "totalNodes": 3, "links": { "first": "/", "previous": null, @@ -9,12 +9,21 @@ "last": "/" }, "nodes": [ + { + "type": "Sphere", + "id": "56fda20c-b238-4034-b555-1df47c47e17a", + "data": { + "created": "2023-10-28T21:03:25+00:00", + "updated": "2023-10-28T21:03:25+00:00", + "name": "Tag" + } + }, { "type": "Sphere", "id": "7b80b203-2b82-40f5-accd-c7089fe6114e", "data": { - "created": "2023-10-06T20:04:04+00:00", - "updated": "2023-10-06T20:04:04+00:00", + "created": "2023-10-28T21:03:25+00:00", + "updated": "2023-10-28T21:03:25+00:00", "name": "Comment" } }, @@ -22,8 +31,8 @@ "type": "Token", "id": "e3b81351-fe0c-4f8f-ad22-78b6157edde8", "data": { - "created": "2023-10-06T20:04:04+00:00", - "updated": "2023-10-06T20:04:04+00:00", + "created": "2023-10-28T21:03:25+00:00", + "updated": "2023-10-28T21:03:25+00:00", "note": "Token contains token only due to testing purposes." } } diff --git a/docs/security/test/02-basic-positive-tests/02-01-immediate-node-ownership.md b/docs/security/test/02-basic-positive-tests/02-01-immediate-node-ownership.md index b7c411e2..5fe878ba 100644 --- a/docs/security/test/02-basic-positive-tests/02-01-immediate-node-ownership.md +++ b/docs/security/test/02-basic-positive-tests/02-01-immediate-node-ownership.md @@ -14,9 +14,9 @@ Users which immediately own a node, have full access to it. | `2-01-03-03` | `User` | `🔵 GET //children` | - | ✔️ 200 | yes | ✔️ implemented | | `2-01-03-04` | `User` | `🔵 GET //related` | - | ✔️ 200 | yes | ✔️ implemented | | `2-01-03-05` | `User` | `🟢 POST /` | Valid request body. | ✔️ 201 | no | ✔️ implemented | -| `2-01-03-06` | `User` | `🟠 PUT /` | Valid request body. | ✔️ 204 | no | ❌ todo | -| `2-01-03-07` | `User` | `🟠 PATCH /` | Valid request body. | ✔️ 204 | no | ❌ todo | -| `2-01-03-08` | `User` | `🔴 DELETE /` | - | ✔️ ? | no | ❌ todo | +| `2-01-03-06` | `User` | `🟠 PUT /` | Valid request body. | ✔️ 204 | no | ✔️ implemented | +| `2-01-03-07` | `User` | `🟠 PATCH /` | Valid request body. | ✔️ 204 | no | ✔️ implemented | +| `2-01-03-08` | `User` | `🔴 DELETE /` | - | ✔️ 204 | no | ✔️ implemented | | `2-01-03-20` | `User` | `🔵 GET //file` | - | ✔️ 200 | yes | ❌ todo v0.2.0 | | `2-01-03-21` | `User` | `🟢 POST //file` | Valid request body. | ✔️ 201 | no | ❌ todo v0.2.0 | | `2-01-03-22` | `User` | `🟠 PUT //file` | Valid request body. | ✔️ 204 | no | ❌ todo v0.2.0 | diff --git a/src/Controller/Element/GetIndexController.php b/src/Controller/Element/GetIndexController.php index 3e4e89e9..bc7589ec 100644 --- a/src/Controller/Element/GetIndexController.php +++ b/src/Controller/Element/GetIndexController.php @@ -31,7 +31,7 @@ public function getIndex(): Response $cypherClient = $this->cypherEntityManager->getClient(); $res = $cypherClient->runStatement(Statement::create( "MATCH (user:User {id: \$userId})\n". - "MATCH (user)-[:PART_OF_GROUP*0..]->()-[:OWNS]->(element)\n". + "MATCH (user)-[:OWNS|IS_IN_GROUP|HAS_READ_ACCESS]->(element)\n". "RETURN element.id\n". "ORDER BY element.id\n". "SKIP \$skip\n". diff --git a/tests/ExampleGenerationController/Element/GetIndexTest.php b/tests/ExampleGenerationController/Element/GetIndexTest.php index 92176060..229ad248 100644 --- a/tests/ExampleGenerationController/Element/GetIndexTest.php +++ b/tests/ExampleGenerationController/Element/GetIndexTest.php @@ -12,7 +12,7 @@ class GetIndexTest extends BaseRequestTestCase public function testGetIndexSuccess(): void { $response = $this->runGetRequest('/', self::TOKEN); - $this->assertIsCollectionResponse($response, 2); + $this->assertIsCollectionResponse($response, 3); $documentationHeadersPath = 'docs/api-endpoints/element/get-index/200-response-header.txt'; $documentationBodyPath = 'docs/api-endpoints/element/get-index/200-response-body.json'; $this->assertHeadersInDocumentationAreIdenticalToHeadersFromRequest( diff --git a/tests/FeatureTests/General/OwnershipModel/OwnershipModelTest.php b/tests/FeatureTests/General/OwnershipModel/OwnershipModelTest.php new file mode 100644 index 00000000..91aed077 --- /dev/null +++ b/tests/FeatureTests/General/OwnershipModel/OwnershipModelTest.php @@ -0,0 +1,110 @@ +runGetRequest('/', self::TOKEN); + $this->assertIsCollectionResponse($response, 2, 0); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::GROUP_1_UUID); + $this->assertSame($body['nodes'][1]['id'], self::TOKEN_UUID); + } + + public function testUserChildren(): void + { + $response = $this->runGetRequest(sprintf('/%s/children', self::USER_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 1, 1); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::TOKEN_UUID); + } + + public function testUserRelated(): void + { + $response = $this->runGetRequest(sprintf('/%s/related', self::USER_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 2, 2); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::GROUP_1_UUID); + $this->assertSame($body['nodes'][1]['id'], self::TOKEN_UUID); + } + + public function testGroup1Children(): void + { + $response = $this->runGetRequest(sprintf('/%s/children', self::GROUP_1_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 0, 0); + } + + public function testGroup1Parents(): void + { + $response = $this->runGetRequest(sprintf('/%s/parents', self::GROUP_1_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 0, 0); + } + + public function testGroup1Related(): void + { + $response = $this->runGetRequest(sprintf('/%s/related', self::GROUP_1_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 2, 2); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::GROUP_2_UUID); + $this->assertSame($body['nodes'][1]['id'], self::USER_UUID); + } + + public function testGroup2Children(): void + { + $response = $this->runGetRequest(sprintf('/%s/children', self::GROUP_2_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 1, 1); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::DATA_UUID); + } + + public function testGroup2Parents(): void + { + $response = $this->runGetRequest(sprintf('/%s/parents', self::GROUP_2_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 0, 0); + } + + public function testGroup2Related(): void + { + $response = $this->runGetRequest(sprintf('/%s/related', self::GROUP_2_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 2, 2); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::GROUP_1_UUID); + $this->assertSame($body['nodes'][1]['id'], self::DATA_UUID); + } + + public function testDataParents(): void + { + $response = $this->runGetRequest(sprintf('/%s/parents', self::DATA_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 1, 1); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::GROUP_2_UUID); + } + + public function testDataRelated(): void + { + $response = $this->runGetRequest(sprintf('/%s/related', self::DATA_UUID), self::TOKEN); + $this->assertIsCollectionResponse($response, 1, 1); + + $body = $this->getBody($response); + $this->assertSame($body['nodes'][0]['id'], self::GROUP_2_UUID); + } +} diff --git a/tests/FeatureTests/Security/Scenario02BasicPositiveTests/_02_01_ImmediateNodeOwnershipTest.php b/tests/FeatureTests/Security/Scenario02BasicPositiveTests/_02_01_ImmediateNodeOwnershipTest.php index e537cc6d..9d267b79 100644 --- a/tests/FeatureTests/Security/Scenario02BasicPositiveTests/_02_01_ImmediateNodeOwnershipTest.php +++ b/tests/FeatureTests/Security/Scenario02BasicPositiveTests/_02_01_ImmediateNodeOwnershipTest.php @@ -108,15 +108,14 @@ public function test2010305(): void */ public function test2010306(): void { - $this->markTestSkipped(); $response = $this->runPutRequest( sprintf('/%s', self::DATA), self::TOKEN, [ - 'name' => 'I shall not be updated.', + 'name' => 'I shall be updated.', ] ); - $this->assertIsProblemResponse($response, 404); + $this->assertNoContentResponse($response); } /** @@ -124,15 +123,14 @@ public function test2010306(): void */ public function test2010307(): void { - $this->markTestSkipped(); $response = $this->runPatchRequest( sprintf('/%s', self::DATA), self::TOKEN, [ - 'name' => 'I shall not be updated.', + 'name' => 'I shall be updated, again! :P', ] ); - $this->assertIsProblemResponse($response, 404); + $this->assertNoContentResponse($response); } /** @@ -140,9 +138,8 @@ public function test2010307(): void */ public function test2010308(): void { - $this->markTestSkipped(); $response = $this->runDeleteRequest(sprintf('/%s', self::DATA), self::TOKEN); - $this->assertIsProblemResponse($response, 404); + $this->assertIsDeletedResponse($response); } /** @@ -202,6 +199,8 @@ public function test2010323(): void /** * @description test 2-01-03-24 + * + * @todo refactor in v0.2.0 with actual request required */ public function test2010324(): void {