diff --git a/legacy/62b16d26-aee1-4dc3-8dd7-83c57063e8e1project.xml b/legacy/62b16d26-aee1-4dc3-8dd7-83c57063e8e1project.xml deleted file mode 100644 index 5bf60377233412d6d502479ed89fb1f0d3c584e0..0000000000000000000000000000000000000000 --- a/legacy/62b16d26-aee1-4dc3-8dd7-83c57063e8e1project.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE rekall> -<project> - <video url="https://youtu.be/Ssm_mm8zyS0"/> - <document key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d"> - <meta ctg="Rekall->Author" cnt=""/> - <meta ctg="Rekall->Date/Time" cnt="2015:08:31 18:06:16"/> - <meta ctg="Rekall->Import Date" cnt="2015:08:31 18:06:16"/> - <meta ctg="Rekall User Infos->User Name" cnt=""/> - <meta ctg="Rekall->Location Name" cnt="48.867359621322265, 2.3618561655447228"/> - <meta ctg="Rekall->Location GPS" cnt="48.867359621322265, 2.3618561655447228"/> - <meta ctg="Rekall User Infos->User IP" cnt="127.0.0.1"/> - <meta ctg="Rekall->Comments" cnt=""/> - <meta ctg="Rekall->Keywords" cnt=""/> - <meta ctg="Rekall->Group" cnt=""/> - <meta ctg="Rekall->Visibility" cnt=""/> - <meta ctg="Rekall->Type" cnt="rekall/marker"/> - <meta ctg="Rekall->Flag" cnt="Marker"/> - <meta ctg="Rekall->Name" cnt="New note"/> - </document> - <tag key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" timeStart="0" timeEnd="10" version="0"/> -</project> diff --git a/tests/files_for_tests/image_for_test.jpeg b/tests/files_for_tests/image_for_test.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..639529067e09340f8af5eaf6d4da7bd4b8d85679 Binary files /dev/null and b/tests/files_for_tests/image_for_test.jpeg differ diff --git a/tests/files_for_tests/projext.xml b/tests/files_for_tests/projext.xml new file mode 100644 index 0000000000000000000000000000000000000000..115a167f035c43af6f85aa0152ea7305d2b17226 --- /dev/null +++ b/tests/files_for_tests/projext.xml @@ -0,0 +1,78 @@ +<?xml version="1.0"?> +<!DOCTYPE rekall> +<project> + <video url="https://youtu.be/dQw4w9WgXcQ"/> + <document key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d"> + <meta ctg="Rekall->Author" cnt=""/> + <meta ctg="Rekall->Date/Time" cnt="2015:08:31 18:06:16"/> + <meta ctg="Rekall->Import Date" cnt="2015:08:31 18:06:16"/> + <meta ctg="Rekall User Infos->User Name" cnt=""/> + <meta ctg="Rekall->Location Name" cnt="48.867359621322265, 2.3618561655447228"/> + <meta ctg="Rekall->Location GPS" cnt="48.867359621322265, 2.3618561655447228"/> + <meta ctg="Rekall User Infos->User IP" cnt="127.0.0.1"/> + <meta ctg="Rekall->Comments" cnt=""/> + <meta ctg="Rekall->Keywords" cnt=""/> + <meta ctg="Rekall->Group" cnt=""/> + <meta ctg="Rekall->Visibility" cnt=""/> + <meta ctg="Rekall->Type" cnt="rekall/marker"/> + <meta ctg="Rekall->Flag" cnt="Marker"/> + <meta ctg="Rekall->Name" cnt="New note"/> + </document> + <tag key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" timeStart="0" timeEnd="10" version="0"/> + <edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall->Name" metadataValue="First note" version="0"/> + <edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall->Comments" metadataValue="This is a note for tests purpose." version="0"/> + <edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall->Link" metadataValue="https://youtu.be/dQw4w9WgXcQ" version="0"/> + <edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall->Author" metadataValue="Rick Astley" version="0"/> + <document key="marker-45f08bfa88924f466539f2ae41b509f7823929db"> + <meta ctg="Rekall->Author" cnt=""/> + <meta ctg="Rekall->Date/Time" cnt="2022:01:21 14:09:09"/> + <meta ctg="Rekall->Import Date" cnt="2022:01:21 14:09:09"/> + <meta ctg="Rekall->Location Name" cnt=""/> + <meta ctg="Rekall->Location GPS" cnt=""/> + <meta ctg="Rekall User Infos->User Name" cnt=""/> + <meta ctg="Rekall User Infos->User IP" cnt="192.168.176.3"/> + <meta ctg="Rekall->Comments" cnt=""/> + <meta ctg="Rekall->Type" cnt="rekall/marker"/> + <meta ctg="Rekall->Flag" cnt="Marker"/> + <meta ctg="Rekall->Name" cnt="New note"/> + <meta ctg="key" cnt="marker-45f08bfa88924f466539f2ae41b509f7823929db"/> + </document> + <tag key="marker-45f08bfa88924f466539f2ae41b509f7823929db" timeStart="0" timeEnd="15" version="0"/> + <edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall->Name" metadataValue="Second note" version="0"/> + <edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall->Author" metadataValue="Bob" version="0"/> + <edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall->Comments" metadataValue="Empty" version="0"/> + <tag key="marker-45f08bfa88924f466539f2ae41b509f7823929db" timeStart="30" timeEnd="75" version="0"/> + <edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall->Link" metadataValue="http://undefined" version="0"/> + <tag key="marker-45f08bfa88924f466539f2ae41b509f7823929db" timeStart="30" timeEnd="75" version="0"/> + <edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall->Highlight" metadataValue="true" version="0"/> + <document> + <meta ctg="Rekall->Author" cnt=""/> + <meta ctg="File->File Access Date/Time" cnt="2022:01:21 15:10:38"/> + <meta ctg="File->File Creation Date/Time" cnt="2022:01:21 15:10:38"/> + <meta ctg="File->File Modification Date/Time" cnt="2022:01:21 15:10:38"/> + <meta ctg="Rekall->Date/Time" cnt="2022:01:21 15:10:38"/> + <meta ctg="Rekall->Import Date" cnt="2022:01:21 14:10:39"/> + <meta ctg="Rekall->Location Name" cnt=""/> + <meta ctg="Rekall->Location GPS" cnt=""/> + <meta ctg="Rekall User Infos->User Name" cnt=""/> + <meta ctg="Rekall User Infos->User IP" cnt="192.168.176.3"/> + <meta ctg="Rekall->Comments" cnt=""/> + <meta ctg="File->Hash" cnt="2B0F9FA5055C514A9464616416A1EA63A72FD88B"/> + <meta ctg="Rekall->Flag" cnt="File"/> + <meta ctg="File->Thumbnail" cnt=""/> + <meta ctg="File->Owner" cnt="www-data"/> + <meta ctg="File->MIME Type" cnt="image/jpeg"/> + <meta ctg="File->File Type" cnt="image/jpeg"/> + <meta ctg="Rekall->Type" cnt="image/jpeg"/> + <meta ctg="File->File Name" cnt="image_for_test.jpeg"/> + <meta ctg="File->Extension" cnt="jpeg"/> + <meta ctg="File->Basename" cnt="image_for_test"/> + <meta ctg="Rekall->Name" cnt="image_for_test"/> + <meta ctg="Rekall->Extension" cnt="JPEG"/> + <meta ctg="Rekall->Folder" cnt=""/> + <meta ctg="Rekall->File Size" cnt="5591"/> + <meta ctg="Rekall->File Size (MB)" cnt="0.0053319931030273"/> + <meta ctg="key" cnt="/image_for_test.jpeg"/> + </document> + <tag key="/image_for_test.jpeg" timeStart="0" timeEnd="15" version="0"/> +</project> diff --git a/tests/functional/ProjectControllerTest.php b/tests/functional/ProjectControllerTest.php index 45d2830bc0ce78bd636c70bdfb674763c642cc7e..5b2ef487374db5b2bb54319d74e955c60e03f8f3 100644 --- a/tests/functional/ProjectControllerTest.php +++ b/tests/functional/ProjectControllerTest.php @@ -17,6 +17,7 @@ class ProjectControllerTest extends WebTestCase private Form $form; private const TEST_DIR_PATH = __DIR__ . '/../../legacy/'; private const CAPSULE_NAME = 'TestCapsuleName'; + private const TEST_FILES_DIRECTORY = "../tests/files_for_tests/"; protected function setUp(): void { @@ -39,32 +40,20 @@ class ProjectControllerTest extends WebTestCase } $this->client->loginUser($verified_user); - - $crawler = $this->client->request('GET', '/create'); - $this->assertResponseIsSuccessful(); - - $this->client->enableProfiler(); - - $submit_button = $crawler->selectButton('Create a capsule'); - $this->form = $submit_button->form(); } protected function tearDown(): void { parent::tearDown(); - $file_system = new Filesystem(); - $file_system->remove(self::TEST_DIR_PATH . self::CAPSULE_NAME); $capsule_repository = $this->object_manager->getRepository(Capsule::class); - $detached_last_capsule = $capsule_repository->findOneBy(['name' => self::CAPSULE_NAME]); + $capsule = $capsule_repository->findOneBy(['name' => self::CAPSULE_NAME]); - if (! $detached_last_capsule instanceof Capsule) { + if (! $capsule instanceof Capsule) { throw new \Exception("Capsule does not exist."); } - $last_capsule = $this->object_manager->merge($detached_last_capsule); - $this->object_manager->remove($last_capsule); - $this->object_manager->flush(); + $this->deleteCapsuleDirectoryAndInDatabase($capsule); } /** @phpstan-ignore-next-line */ @@ -94,6 +83,14 @@ class ProjectControllerTest extends WebTestCase public function testProjectDirectoryWithCorrespondingXMLFileIsCreatedWhenCapsuleCreationIsSuccessful(): void { + $crawler = $this->client->request('GET', '/create'); + $this->assertResponseIsSuccessful(); + + $this->client->enableProfiler(); + + $submit_button = $crawler->selectButton('Create a capsule'); + $this->form = $submit_button->form(); + $video_url = "https://TestUrl"; $this->form['create_capsule_form[name]'] = self::CAPSULE_NAME; $this->form['create_capsule_form[video_url]'] = $video_url; @@ -137,11 +134,7 @@ class ProjectControllerTest extends WebTestCase public function testProjectDirectoryWithCorrespondingPasswordFileIsCreatedWhenCapsuleCreationIsSuccessful(): void { - $video_url = "https://TestUrl"; - $this->form['create_capsule_form[name]'] = self::CAPSULE_NAME; - $this->form['create_capsule_form[video_url]'] = $video_url; - - $this->client->submit($this->form); + $this->createCapsule(); $this->assertResponseRedirects( '/my_capsules', @@ -159,7 +152,6 @@ class ProjectControllerTest extends WebTestCase throw new \Exception("Capsule does not exist."); } - $capsule_name_in_db = $capsule_in_db->getName(); $capsule_directory = $capsule_in_db->getLinkPath(); $this->assertDirectoryExists($capsule_directory); @@ -175,4 +167,135 @@ class ProjectControllerTest extends WebTestCase "The password should be saved in projectPassword.txt file" ); } + + public function testDuplicatedDirectoryDuplicatedFilesFromParentWhenCapsuleDuplicationIsSuccessful(): void + { + $duplicated_capsule_name = 'duplicated ' . self::CAPSULE_NAME; + $this->createCapsule(); + + $capsule_repository = $this->object_manager->getRepository(Capsule::class); + $parent_capsule = $capsule_repository->findOneBy(['name' => self::CAPSULE_NAME]); + + if (! $parent_capsule instanceof Capsule) { + throw new \Exception("Capsule does not exist."); + } + + $parent_capsule_directory = $parent_capsule->getLinkPath(); + + $crawler = $this->client->request('GET', '/capsule/duplicate/' . $parent_capsule->getId()); + $this->assertResponseIsSuccessful(); + + $this->client->enableProfiler(); + + $submit_button = $crawler->selectButton('Validate'); + $this->form = $submit_button->form(); + $this->form['duplicate_capsule_form[name]'] = $duplicated_capsule_name; + $this->client->submit($this->form); + + $this->assertResponseRedirects( + '/my_capsules', + 302, + 'Once the capsule is duplicated, the user should be redirected to its capsules lists' + ); + + $this->client->followRedirect(); + $this->assertResponseIsSuccessful('/my_capsules'); + + $capsule_repository = $this->object_manager->getRepository(Capsule::class); + $duplicated_capsule_in_db = $capsule_repository->findOneBy(['name' => $duplicated_capsule_name]); + + if (! $duplicated_capsule_in_db instanceof Capsule) { + throw new \Exception("Capsule does not exist."); + } + + $duplicated_capsule_directory = $duplicated_capsule_in_db->getLinkPath(); + + $this->assertDirectoryExists($duplicated_capsule_directory); + $this->assertDirectoryIsReadable($duplicated_capsule_directory); + $this->assertXmlFileEqualsXmlFile( + $this->getXmlFilePath($duplicated_capsule_directory), + $this->getXmlFilePath($duplicated_capsule_directory) + ); + $this->assertAllFilesOfFileDirectoryAreSameExceptPasswordOne( + $parent_capsule_directory, + $duplicated_capsule_directory + ); + + $password_file_path = $this->getPasswordFilePath($duplicated_capsule_directory); + $password = file_get_contents($password_file_path, true); + + $this->assertTrue(false !== $password, "The projectPassword.txt should be readable"); + $this->assertSame( + $duplicated_capsule_in_db->getPassword(), + $password, + "The password should be saved in projectPassword.txt file" + ); + + $this->deleteCapsuleDirectoryAndInDatabase($duplicated_capsule_in_db); + } + + private function assertAllFilesOfFileDirectoryAreSameExceptPasswordOne( + string $parent_capsule_directory, + string $duplicated_capsule_directory + ): void { + $parent_capsule_files = scandir($parent_capsule_directory . "/file/"); + + if (! is_array($parent_capsule_files)) { + return; + } + + foreach ($parent_capsule_files as $key => $file) { + if ($file === "projectPassword.txt" || is_dir($file)) { + return; + } + + $this->assertFileExists($duplicated_capsule_directory . "/file/" . $file); + $this->assertFileEquals($file, $duplicated_capsule_directory . "/file/" . $file); + } + } + + private function createCapsule(): void + { + $crawler = $this->client->request('GET', '/create'); + $this->assertResponseIsSuccessful(); + + $this->client->enableProfiler(); + + $submit_button = $crawler->selectButton('Create a capsule'); + $this->form = $submit_button->form(); + + $video_url = "https://TestUrl"; + $this->form['create_capsule_form[name]'] = self::CAPSULE_NAME; + $this->form['create_capsule_form[video_url]'] = $video_url; + + $this->client->submit($this->form); + + $capsule_repository = $this->object_manager->getRepository(Capsule::class); + $capsule = $capsule_repository->findOneBy(['name' => self::CAPSULE_NAME]); + + if (! $capsule instanceof Capsule) { + throw new \Exception("Capsule does not exist."); + } + + $capsule_directory_path = $capsule->getLinkPath(); + $file_system = new Filesystem(); + $file_system->mirror( + self::TEST_FILES_DIRECTORY, + $capsule_directory_path . '/file/', + null, + ['override' => true] + ); + } + + private function deleteCapsuleDirectoryAndInDatabase(Capsule $capsule): void + { + $file_system = new Filesystem(); + + $capsule_directory_path = $capsule->getLinkPath(); + $file_system->remove(self::TEST_DIR_PATH . $capsule_directory_path); + + $capsule_to_delete = $this->object_manager->merge($capsule); + $this->object_manager->remove($capsule_to_delete); + $this->object_manager->flush(); + } }