From 673bfc74770ba56c3431b70166c462386bd61987 Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Sun, 6 Jun 2021 19:28:11 +0200 Subject: [PATCH] Tests: Add jwt test keys + add CDocument phpunit create folder test. --- .env.test | 7 +- config/jwt-test/private-test.pem | 54 +++++++++++ config/jwt-test/public-test.pem | 14 +++ .../test/lexik_jwt_authentication.yaml | 5 + .../Controller/Api/BaseResourceFileAction.php | 9 +- .../Api/CreateDocumentFileAction.php | 2 +- .../EventListener/ExceptionListener.php | 2 +- tests/AbstractApiTest.php | 83 +++++++++++++++++ .../Repository/Node/CourseRepositoryTest.php | 9 +- .../Repository/CDocumentRepositoryTest.php | 93 +++++++++++++++++++ tests/datafiller/index.html | 8 -- 11 files changed, 270 insertions(+), 16 deletions(-) create mode 100644 config/jwt-test/private-test.pem create mode 100644 config/jwt-test/public-test.pem create mode 100644 config/packages/test/lexik_jwt_authentication.yaml create mode 100644 tests/AbstractApiTest.php create mode 100644 tests/CourseBundle/Repository/CDocumentRepositoryTest.php delete mode 100755 tests/datafiller/index.html diff --git a/.env.test b/.env.test index 3b3e9abab8..a686aec569 100644 --- a/.env.test +++ b/.env.test @@ -9,4 +9,9 @@ DATABASE_HOST='127.0.0.1' DATABASE_PORT='3306' DATABASE_NAME='chamilo_test' DATABASE_USER='root' -DATABASE_PASSWORD='root' \ No newline at end of file +DATABASE_PASSWORD='root' + +APP_ENV='test' +APP_DEBUG='1' +APP_LOCALE='en' +APP_MULTIPLE_ACCESS_URL='' \ No newline at end of file diff --git a/config/jwt-test/private-test.pem b/config/jwt-test/private-test.pem new file mode 100644 index 0000000000..1897493577 --- /dev/null +++ b/config/jwt-test/private-test.pem @@ -0,0 +1,54 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,1D5840ABD70AE2EC6C39CE34371077B4 + +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 +-----END RSA PRIVATE KEY----- diff --git a/config/jwt-test/public-test.pem b/config/jwt-test/public-test.pem new file mode 100644 index 0000000000..c5d8246b37 --- /dev/null +++ b/config/jwt-test/public-test.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqLjExtq7xWdyCQaRUZCx +3pS7vRZlqMdVPv/4kDB1zgVRIEfPIjKA9iwQNS/R3CYLg6m69TBRPpedujEWyeVm +/YGrTG2o7V9Pf95qnL73fR00fOtlTsc30y2BN1HG5HHe5hwwk1dZRrVyPu9n0Hib +36en+A/ZKhtL7Ikrrxwh7SYxfNVx902DabhrZSuJhocIZvQlL3Ci9MueGAPGMSy8 +MnY+J4XDmxb1c2DaLn7Bo/sWRZ9+j+H4uJwEjM/+duVFjWMekvflarePcMUB+rmy +qiS/8cp4/ak2gCmg8eCx5FK5EO5IaE++Q7aI4F12c13mHi9BnN6B1/nHnLX78672 +9sjvgKWvjn1vcxBmyQERR3Ja4IbC/CZ8d+5nI4Oo9pvo53zsHVVh3PWlQxu753Yy +9aeaesHN3Cn5ZIdhWdCA7j3X+vlkALa1m6YBFlftStfQutiKr1OE4VFhvyenhTrz +sFO0tkDtUsCzIxd6wJxTVujkikd1ybkGD8KFXBsTv6d3L90wScSRHyAR7wbmgZWK +s6do8M+mvd+MMFZk+vBDSBo9ER7OvblqfcsOONr+OA3DlDimsmfggkzvXzeY3qG8 +sBmF1IFycy/W+sl8m2/m2+OR+SFu0vFg2fgkAYQWIQaCkmJhxz9WEqbnXveDoajR +JuQr1AtxAWiggPbVJLKJbLECAwEAAQ== +-----END PUBLIC KEY----- diff --git a/config/packages/test/lexik_jwt_authentication.yaml b/config/packages/test/lexik_jwt_authentication.yaml new file mode 100644 index 0000000000..96174bb761 --- /dev/null +++ b/config/packages/test/lexik_jwt_authentication.yaml @@ -0,0 +1,5 @@ +lexik_jwt_authentication: + secret_key: '%kernel.project_dir%/config/jwt-test/private-test.pem' + public_key: '%kernel.project_dir%/config/jwt-test/public-test.pem' + pass_phrase: 'test' + token_ttl: 3600 diff --git a/src/CoreBundle/Controller/Api/BaseResourceFileAction.php b/src/CoreBundle/Controller/Api/BaseResourceFileAction.php index 1679e528c8..ff3274795f 100644 --- a/src/CoreBundle/Controller/Api/BaseResourceFileAction.php +++ b/src/CoreBundle/Controller/Api/BaseResourceFileAction.php @@ -24,11 +24,13 @@ class BaseResourceFileAction if (!empty($contentData)) { $contentData = json_decode($contentData, true); var_dump($contentData); - $title = $contentData['title']; - $comment = $contentData['comment']; + $title = $contentData['title'] ?? ''; + $comment = $contentData['comment'] ?? ''; + $nodeId = $contentData['parentResourceNodeId'] ?? 0; } else { $title = $request->get('title'); $comment = $request->get('comment'); + $nodeId = (int) $request->get('parentResourceNodeId'); } $fileType = 'folder'; @@ -40,14 +42,13 @@ class BaseResourceFileAction throw new Exception('filetype needed: folder or file'); } - $nodeId = (int) $request->get('parentResourceNodeId'); - if (0 === $nodeId) { throw new Exception('parentResourceNodeId int value needed'); } $resource->setParentResourceNode($nodeId); + error_log("fileType: $fileType"); switch ($fileType) { case 'file': $content = ''; diff --git a/src/CoreBundle/Controller/Api/CreateDocumentFileAction.php b/src/CoreBundle/Controller/Api/CreateDocumentFileAction.php index 0f667e0283..da3f2123e8 100644 --- a/src/CoreBundle/Controller/Api/CreateDocumentFileAction.php +++ b/src/CoreBundle/Controller/Api/CreateDocumentFileAction.php @@ -14,7 +14,7 @@ class CreateDocumentFileAction extends BaseResourceFileAction { public function __invoke(Request $request): CDocument { - error_log('CreateResourceNodeFileAction __invoke'); + error_log('CreateDocumentFileAction __invoke'); $document = new CDocument(); $this->handleCreateRequest($document, $request); diff --git a/src/CoreBundle/EventListener/ExceptionListener.php b/src/CoreBundle/EventListener/ExceptionListener.php index bf74d8fc2e..ef993386a7 100644 --- a/src/CoreBundle/EventListener/ExceptionListener.php +++ b/src/CoreBundle/EventListener/ExceptionListener.php @@ -22,7 +22,7 @@ class ExceptionListener public function onKernelException(ExceptionEvent $event): void { - if (isset($_SERVER['APP_ENV']) && in_array($_SERVER['APP_ENV'], ['dev', 'test'], true)) { + if (isset($_SERVER['APP_ENV']) && \in_array($_SERVER['APP_ENV'], ['dev', 'test'], true)) { return; } diff --git a/tests/AbstractApiTest.php b/tests/AbstractApiTest.php new file mode 100644 index 0000000000..18e3aacf06 --- /dev/null +++ b/tests/AbstractApiTest.php @@ -0,0 +1,83 @@ + $username, + 'password' => $password, + ]; + + $response = static::createClient()->request( + 'POST', + '/api/authentication_token', + [ + 'headers' => ['Content-Type' => 'application/json'], + 'body' => json_encode($params), + ] + ); + + $this->assertResponseIsSuccessful(); + $data = json_decode($response->getContent()); + //$this->token = $data->access_token; + + $this->assertEquals('admin', $data->username); + + return $response; + } + + protected function createClientWithCredentials($token = null): Client + { + $token = $token ?: $this->getToken(); + + return static::createClient([], ['headers' => ['authorization' => 'Bearer '.$token]]); + } + + /** + * Use credentials with token. + */ + protected function getToken($body = []): string + { + if ($this->token) { + return $this->token; + } + + $response = static::createClient()->request( + 'POST', + '/api/authentication_token', + [ + /*'body' => $body ?: [ + 'username' => 'admin', + 'password' => 'admin', + ],*/ + 'headers' => ['Content-Type' => 'application/json'], + 'body' => json_encode([ + 'username' => 'admin', + 'password' => 'admin', + ]) + ], + ); + + $this->assertResponseIsSuccessful(); + $data = json_decode($response->getContent()); + $this->token = $data->token; + + return $data->token; + } +} diff --git a/tests/CoreBundle/Repository/Node/CourseRepositoryTest.php b/tests/CoreBundle/Repository/Node/CourseRepositoryTest.php index c5894097a5..d595db3748 100644 --- a/tests/CoreBundle/Repository/Node/CourseRepositoryTest.php +++ b/tests/CoreBundle/Repository/Node/CourseRepositoryTest.php @@ -10,11 +10,15 @@ use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository; use Chamilo\CoreBundle\Repository\Node\CourseRepository; use Chamilo\CoreBundle\Repository\Node\UserRepository; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; + use Symfony\Component\Security\Core\Exception\UserNotFoundException; class CourseRepositoryTest extends WebTestCase { - public function testCreateNoLogin() + /** + * Create a course with no creator. + */ + public function testCreateNoCreator() { self::bootKernel(); $urlRepo = self::getContainer()->get(AccessUrlRepository::class); @@ -33,6 +37,9 @@ class CourseRepositoryTest extends WebTestCase $this->assertEquals(1, $count); } + /** + * Create a course with a creator. + */ public function testCreate() { /** @var UserRepository $userRepository */ diff --git a/tests/CourseBundle/Repository/CDocumentRepositoryTest.php b/tests/CourseBundle/Repository/CDocumentRepositoryTest.php new file mode 100644 index 0000000000..35408041d3 --- /dev/null +++ b/tests/CourseBundle/Repository/CDocumentRepositoryTest.php @@ -0,0 +1,93 @@ +createClientWithCredentials($token)->request('GET', '/account/edit'); + $this->assertResponseStatusCodeSame('200'); + }*/ + + public function testGetDocuments() + { + $token = $this->getToken([]); + $response = $this->createClientWithCredentials($token)->request('GET', '/api/documents'); + $this->assertResponseIsSuccessful(); + + // Asserts that the returned content type is JSON-LD (the default) + $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8'); + + // Asserts that the returned JSON is a superset of this one + $this->assertJsonContains([ + '@context' => '/api/contexts/Documents', + '@id' => '/api/documents', + '@type' => 'hydra:Collection', + 'hydra:totalItems' => 0, + /*'hydra:view' => [ + '@id' => '/api/documents?page=1', + '@type' => 'hydra:PartialCollectionView', + ],*/ + ]); + + $this->assertCount(0, $response->toArray()['hydra:member']); + $this->assertMatchesResourceCollectionJsonSchema(CDocument::class); + } + + public function testCreateFolder(): void + { + $userRepository = self::getContainer()->get(UserRepository::class); + $urlRepo = self::getContainer()->get(AccessUrlRepository::class); + $courseRepo = self::getContainer()->get(CourseRepository::class); + + // Get admin. + $admin = $userRepository->findByUsername('admin'); + // Get access url. + $accessUrl = $urlRepo->findOneBy(['url' => AccessUrl::DEFAULT_ACCESS_URL]); + + // Create course. @todo move in a function? + $course = (new Course()) + ->setTitle('Test course') + ->setCode('test_course') + ->addAccessUrl($accessUrl) + ->setCreator($admin) + ; + $courseRepo->create($course); + + // Create folder. + $resourceLinkList = [ + 'cid' => $course->getId(), + 'visibility' => 2, + ]; + + $token = $this->getToken([]); + $response = $this->createClientWithCredentials($token)->request( + 'POST', + '/api/documents', + [ + 'json' => [ + 'title' => 'folder1', + 'parentResourceNodeId' => $course->getResourceNode()->getId(), + 'resourceLinkList' => json_encode($resourceLinkList), + ], + ] + ); + + $this->assertResponseIsSuccessful(); + + $this->assertResponseStatusCodeSame(201); + $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8'); + } +} diff --git a/tests/datafiller/index.html b/tests/datafiller/index.html deleted file mode 100755 index 8e464d8ce3..0000000000 --- a/tests/datafiller/index.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - -
- - \ No newline at end of file