From b6ed742ba32e1cf70b4ba74868879309636ac5f9 Mon Sep 17 00:00:00 2001
From: Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>
Date: Wed, 1 Dec 2021 09:07:33 +0100
Subject: [PATCH] Use the correct filter method in `children` relationship.

Closes #445.
---
 .../BookmarkedStructuralElementsIndex.php     |   1 +
 .../Courseware/StructuralElementsIndex.php    |   1 +
 .../Courseware/StructuralElementsShow.php     |   1 +
 .../Schemas/Courseware/StructuralElement.php  |   3 +-
 tests/jsonapi/StructuralElementsShowTest.php  | 105 ++++++++++++++++++
 5 files changed, 109 insertions(+), 2 deletions(-)
 create mode 100644 tests/jsonapi/StructuralElementsShowTest.php

diff --git a/lib/classes/JsonApi/Routes/Courseware/BookmarkedStructuralElementsIndex.php b/lib/classes/JsonApi/Routes/Courseware/BookmarkedStructuralElementsIndex.php
index c715d395d36..a9b3c094d3e 100755
--- a/lib/classes/JsonApi/Routes/Courseware/BookmarkedStructuralElementsIndex.php
+++ b/lib/classes/JsonApi/Routes/Courseware/BookmarkedStructuralElementsIndex.php
@@ -17,6 +17,7 @@ class BookmarkedStructuralElementsIndex extends JsonApiController
 
     protected $allowedIncludePaths = [
         'ancestors',
+        'children',
         'containers',
         'containers.blocks',
         'containers.blocks.edit-blocker',
diff --git a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsIndex.php b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsIndex.php
index 73795fe96a0..ace8b18f17c 100755
--- a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsIndex.php
+++ b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsIndex.php
@@ -17,6 +17,7 @@ class StructuralElementsIndex extends JsonApiController
 
     protected $allowedIncludePaths = [
         'ancestors',
+        'children',
         'containers',
         'containers.blocks',
         'containers.blocks.edit-blocker',
diff --git a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php
index 9589dd38618..1c527e45712 100755
--- a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php
+++ b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php
@@ -17,6 +17,7 @@ class StructuralElementsShow extends JsonApiController
 {
     protected $allowedIncludePaths = [
         'ancestors',
+        'children',
         'containers',
         'containers.blocks',
         'containers.blocks.edit-blocker',
diff --git a/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php b/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
index af09f009439..15c5ee2427d 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
@@ -158,8 +158,7 @@ class StructuralElement extends SchemaProvider
 
         if ($includeData) {
             $user = $this->currentUser;
-            $relation[self::RELATIONSHIP_DATA] = array_filter(
-                $resource->children,
+            $relation[self::RELATIONSHIP_DATA] = $resource->children->filter(
                 function ($child) use ($user) {
                     return $child->canRead($user);
                 }
diff --git a/tests/jsonapi/StructuralElementsShowTest.php b/tests/jsonapi/StructuralElementsShowTest.php
new file mode 100644
index 00000000000..231a4495f4c
--- /dev/null
+++ b/tests/jsonapi/StructuralElementsShowTest.php
@@ -0,0 +1,105 @@
+<?php
+
+use Courseware\Instance;
+use Courseware\StructuralElement;
+use JsonApi\Routes\Courseware\StructuralElementsShow;
+use JsonApi\Schemas\Courseware\StructuralElement as Schema;
+use WoohooLabs\Yang\JsonApi\Response\JsonApiResponse;
+
+class StructuralElementsShowTest extends \Codeception\Test\Unit
+{
+    /**
+     * @var \JsonapiTester
+     */
+    protected $tester;
+
+    protected function _before()
+    {
+        \DBManager::getInstance()->setConnection('studip', $this->getModule('\\Helper\\StudipDb')->dbh);
+    }
+
+    protected function _after()
+    {
+    }
+
+    // tests
+    public function testShouldShowStructuralElement()
+    {
+        $credentials = $this->tester->getCredentialsForTestAutor();
+        $structuralElement = $this->createCourseware($credentials, 5);
+
+        $response = $this->fetchStructuralElement($credentials, $structuralElement);
+        $this->assertTrue($response->isSuccessfulDocument([200]));
+
+        $document = $response->document();
+        $this->assertSame($structuralElement->id, $document->primaryResource()->id());
+        $this->assertFalse($document->hasAnyIncludedResources());
+    }
+
+    public function testShouldIncludeChildren()
+    {
+        $credentials = $this->tester->getCredentialsForTestAutor();
+        $structuralElement = $this->createCourseware($credentials, 5);
+
+        $response = $this->fetchStructuralElement($credentials, $structuralElement, ['include' => 'children']);
+        $this->assertTrue($response->isSuccessfulDocument([200]));
+
+        $document = $response->document();
+        $this->assertSame($structuralElement->id, $document->primaryResource()->id());
+        $this->assertTrue($document->hasAnyIncludedResources());
+
+        $includedResources = $document->includedResources();
+        $childIDs = $structuralElement->children->pluck('id');
+        $this->assertCount(count($childIDs), $includedResources);
+        foreach ($includedResources as $included) {
+            $this->assertContains($included->id(), $childIDs);
+        }
+    }
+
+    // **** helper functions ****
+    private function createCourseware(iterable $credentials, int $numberOfChildren): StructuralElement
+    {
+        $instance = StructuralElement::createEmptyCourseware($credentials['id'], 'user');
+        $root = $instance->getRoot();
+
+        for ($i = 0; $i < $numberOfChildren; $i++) {
+            $child = StructuralElement::build([
+                'range_id' => $root['range_id'],
+                'range_type' => $root['range_type'],
+                'owner_id' => $root['owner_id'],
+                'editor_id' => $root['editor_id'],
+                'title' => _('neue Seite'),
+            ]);
+
+            $root->children[] = $child;
+        }
+
+        $root->store();
+
+        return $root;
+    }
+
+    private function fetchStructuralElement(
+        iterable $credentials,
+        StructuralElement $resource,
+        iterable $options = []
+    ): JsonApiResponse {
+        $app = $this->tester->createApp(
+            $credentials,
+            'get',
+            '/courseware-structural-elements/{id}',
+            StructuralElementsShow::class
+        );
+
+        $requestBuilder = $this->tester
+            ->createRequestBuilder($credentials)
+            ->setUri('/courseware-structural-elements/' . $resource->id)
+            ->fetch();
+
+        if (array_key_exists('include', $options)) {
+            $requestBuilder->setJsonApiIncludes($options['include']);
+        }
+
+        return $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+    }
+}
-- 
GitLab