Skip to content
Snippets Groups Projects
Commit 944a6507 authored by Sebastien's avatar Sebastien
Browse files

Merge branch 'tuleap-80-duplicate-a-capsule' into 'main'

tuleap-80-duplicate-a-capsule

See merge request !44
parents e625c874 678d5d13
No related branches found
No related tags found
1 merge request!44tuleap-80-duplicate-a-capsule
Pipeline #734 passed
......@@ -5,12 +5,15 @@ namespace App\Controller;
use App\Entity\Capsule;
use App\Entity\User;
use App\Form\DeleteCapsuleFormType;
use App\Form\DuplicateCapsuleFormType;
use App\Helper\StringHelper;
use App\Repository\CapsuleRepository;
use App\Builder\CapsuleBuilder;
use App\Form\CreateCapsuleFormType;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
......@@ -24,7 +27,7 @@ class CapsuleController extends AbstractController
* @Route("/", name="home")
*/
public function index(
CapsuleRepository $capsuleRepository,
CapsuleRepository $capsule_repository,
PaginatorInterface $paginator,
Request $request
): Response {
......@@ -34,7 +37,7 @@ class CapsuleController extends AbstractController
return $this->redirectToRoute('app_logout');
}
$all_capsules = $capsuleRepository->findBy(['creation_author' => $current_user]);
$all_capsules = $capsule_repository->findBy(['creation_author' => $current_user]);
$capsules = $paginator->paginate(
$all_capsules,
......@@ -62,25 +65,9 @@ class CapsuleController extends AbstractController
}
if ($form->isSubmitted() && $form->isValid()) {
$new_date_time = new \DateTime();
$capsule_name = $form->get('name')->getData();
$video_url = htmlspecialchars($form->get('video_url')->getData());
$password = StringHelper::generateRandomHashedString();
$preview_link = Uuid::v4();
$entityManager = $this->getDoctrine()->getManager();
$capsule_builder = new CapsuleBuilder();
$capsule = $capsule_builder
->withName($capsule_name)
->withCreationAuthor($current_user)
->withCreationDate($new_date_time)
->withLinkPath($preview_link)
->withUpdateDate($new_date_time)
->withPassword($password)
->createCapsule();
$entityManager->persist($capsule);
$entityManager->flush();
$capsule = $this->createCapsuleInDB($form, $current_user);
return $this->forward('App\Controller\ProjectController::create', [
'capsule' => $capsule,
......@@ -147,7 +134,8 @@ class CapsuleController extends AbstractController
public function delete(
int $id,
Request $request,
TranslatorInterface $translator
TranslatorInterface $translator,
CapsuleRepository $capsule_repository
): Response {
$form = $this->createForm(DeleteCapsuleFormType::class);
$form->handleRequest($request);
......@@ -167,12 +155,28 @@ class CapsuleController extends AbstractController
}
$capsule_name = $capsule->getName();
$do_capsule_belongs_to_user = $capsule_repository->doCapsuleBelongsToUser($capsule, $current_user);
if (! $do_capsule_belongs_to_user) {
$this->addFlash(
'warning',
$translator->trans(
'capsule.delete.error',
[
'capsule_name' => $capsule_name
]
)
);
return $this->redirectToRoute('capsule_list');
}
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->remove($capsule);
$entityManager->flush();
$this->addFlash(
'capsule_deleted_success',
'success',
$translator->trans(
'capsule.delete.success',
[
......@@ -189,4 +193,99 @@ class CapsuleController extends AbstractController
'capsule_name' => $capsule_name
]);
}
/**
* @Route("/capsule/duplicate/{id}", name="duplicate_capsule")
*/
public function duplicate(
int $id,
Request $request,
Filesystem $file_system,
TranslatorInterface $translator,
CapsuleRepository $capsule_repository
): Response {
$form = $this->createForm(DuplicateCapsuleFormType::class);
$form->handleRequest($request);
$current_user = $this->getUser();
if (! $current_user instanceof User) {
return $this->redirectToRoute('app_logout');
}
$entityManager = $this->getDoctrine()->getManager();
$parent_capsule = $entityManager->getRepository(Capsule::class)->find($id);
if (! $parent_capsule instanceof Capsule) {
throw new \Exception('The retrieved capsule is not an instance of Capsule.');
}
if (! $capsule_repository->doCapsuleBelongsToUser($parent_capsule, $current_user)) {
$this->addFlash(
'warning',
$translator->trans(
'capsule.duplicate.error',
[
'capsule_name' => $parent_capsule->getName()
]
)
);
return $this->redirectToRoute('capsule_list');
}
$parent_directory_name = $parent_capsule->getLinkPath();
$parent_directory_exists = $file_system->exists('../legacy/' . $parent_directory_name);
if (! $parent_directory_exists) {
$this->addFlash(
'warning',
$translator->trans(
'project.not_exist',
[
'capsule_name' => $parent_capsule->getName()
]
)
);
return $this->redirectToRoute('capsule_list');
}
if ($form->isSubmitted() && $form->isValid()) {
$capsule = $this->createCapsuleInDB($form, $current_user);
return $this->forward('App\Controller\ProjectController::duplicate', [
'capsule' => $capsule,
'parent_directory' => $parent_directory_name
]);
}
return $this->render('capsule/duplicate.html.twig', [
'duplicateCapsuleForm' => $form->createView(),
'capsule_name' => $parent_capsule->getName()
]);
}
private function createCapsuleInDB(FormInterface $form, User $current_user): Capsule
{
$new_date_time = new \DateTime();
$capsule_name = $form->get('name')->getData();
$password = StringHelper::generateRandomHashedString();
$preview_link = Uuid::v4();
$entityManager = $this->getDoctrine()->getManager();
$capsule_builder = new CapsuleBuilder();
$capsule = $capsule_builder
->withName($capsule_name)
->withCreationAuthor($current_user)
->withCreationDate($new_date_time)
->withLinkPath($preview_link)
->withUpdateDate($new_date_time)
->withPassword($password)
->createCapsule();
$entityManager->persist($capsule);
$entityManager->flush();
return $capsule;
}
}
......@@ -7,6 +7,7 @@ use App\Exception\ZipArchiveNotOpeningException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Config\Util\Exception\XmlParsingException;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
......@@ -50,7 +51,7 @@ class ProjectController extends AbstractController
$this->createOrUpdatePasswordFile($capsule_directory, $capsule->getPassword());
$this->addFlash(
'capsule_created_success',
'success',
$translator->trans(
'capsule.created_success',
[
......@@ -62,6 +63,52 @@ class ProjectController extends AbstractController
return $this->redirectToRoute('capsule_list');
}
/**
* @Route("/project/duplicate", name="duplicate_project", methods={"POST"})
* @throws ZipArchiveNotOpeningException
*/
public function duplicate(
TranslatorInterface $translator,
Capsule $capsule,
string $parent_directory,
Filesystem $file_system
): Response {
chdir('../legacy/');
$capsule_name = $capsule->getName();
$capsule_directory = $capsule->getLinkPath();
if (file_exists($capsule_directory)) {
$this->addFlash(
'warning',
$translator->trans(
'project.already_exists',
[
'capsule_name' => $capsule_name
]
)
);
return $this->redirectToRoute('capsule_list');
}
$this->extractZipArchiveInNewCapsuleDirectory($capsule_directory);
$this->replaceTheWholeFileDirectoryWithParentOne($file_system, $parent_directory, $capsule_directory);
$this->createOrUpdatePasswordFile($capsule_directory, $capsule->getPassword());
$this->addFlash(
'success',
$translator->trans(
'capsule.duplicate.success',
[
'capsule_name' => $capsule_name
]
)
);
return $this->redirectToRoute('capsule_list');
}
/**
* @throws ZipArchiveNotOpeningException The archive file doesn't exist.
*/
......@@ -101,4 +148,18 @@ class ProjectController extends AbstractController
$project_password_file = $capsule_directory . "/file/projectPassword.txt";
file_put_contents($project_password_file, $password);
}
private function replaceTheWholeFileDirectoryWithParentOne(
FileSystem $file_system,
string $parent_directory,
string $child_directory
): void {
$file_directory_path = '/file/';
$file_system->mirror(
$parent_directory . $file_directory_path,
$child_directory . $file_directory_path,
null,
['override' => true]
);
}
}
<?php
namespace App\Form;
use App\Entity\Capsule;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DuplicateCapsuleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add(
'name',
TextType::class,
['label' => 'capsule.duplicate.new_name']
)
->add(
'validate',
SubmitType::class,
['label' => 'general.validate']
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Capsule::class,
]);
}
}
......@@ -3,6 +3,7 @@
namespace App\Repository;
use App\Entity\Capsule;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
......@@ -20,4 +21,11 @@ class CapsuleRepository extends ServiceEntityRepository
{
parent::__construct($registry, Capsule::class);
}
public function doCapsuleBelongsToUser(Capsule $capsule, User $user): bool
{
return
$capsule->getCreationAuthor() === $user ||
$capsule->getUpdateAuthor() === $user;
}
}
{% extends 'layout.html.twig' %}
{% block title %}
{{ 'capsule.duplicate.title'|trans }}
-
{{ parent() }}
{% endblock %}
{% block body %}
<div>
<div class="row w-100 gx-0">
<div class="row-title-box">
<h3 class="row-title">
{{ 'capsule.duplicate.title_name'|trans({'%capsule_name%': capsule_name}) }}
</h3>
</div>
</div>
{{ form_start(duplicateCapsuleForm, {'attr': {novalidate: 'novalidate', 'class': 'd-flex flex-column justify-content-center'}}) }}
{{ form_row(duplicateCapsuleForm.name, {'row_attr': {'class' : 'm-auto mb-4 col-6'}}) }}
{{ form_row(duplicateCapsuleForm.validate, {'row_attr': {'class' : 'm-auto mb-5 col-2'}}) }}
{{ form_end(duplicateCapsuleForm) }}
</div>
{% endblock %}
\ No newline at end of file
......@@ -29,17 +29,12 @@
</div>
{% endfor %}
{% for flashSuccess in app.flashes('capsule_created_success') %}
{% for flashSuccess in app.flashes('success') %}
<div class="text-center alert alert-success col-5 mx-auto my-5" role="alert">
{{ flashSuccess }}
</div>
{% endfor %}
{% for flashSuccess in app.flashes('capsule_deleted_success') %}
<div class="text-center alert alert-success col-5 mx-auto my-5" role="alert">
{{ flashSuccess }}
</div>
{% endfor %}
</div>
<div class="capsules-list d-flex flex-column m-6">
......@@ -75,7 +70,7 @@
</a>
</div>
<div class="list-item text-nowrap">
<a href="" class="links text-decoration-none">
<a href="/capsule/duplicate/{{ capsule.getId() }}" class="links text-decoration-none">
<i class="far fa-clone m-2"></i>
{{ 'capsule.duplicate.link'|trans }}
</a>
......
tests/files_for_tests/image_for_test.jpeg

5.46 KiB

<?xml version="1.0"?>
<!DOCTYPE rekall>
<project>
<video url="https://youtu.be/dQw4w9WgXcQ"/>
<document key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d">
<meta ctg="Rekall-&gt;Author" cnt=""/>
<meta ctg="Rekall-&gt;Date/Time" cnt="2015:08:31 18:06:16"/>
<meta ctg="Rekall-&gt;Import Date" cnt="2015:08:31 18:06:16"/>
<meta ctg="Rekall User Infos-&gt;User Name" cnt=""/>
<meta ctg="Rekall-&gt;Location Name" cnt="48.867359621322265, 2.3618561655447228"/>
<meta ctg="Rekall-&gt;Location GPS" cnt="48.867359621322265, 2.3618561655447228"/>
<meta ctg="Rekall User Infos-&gt;User IP" cnt="127.0.0.1"/>
<meta ctg="Rekall-&gt;Comments" cnt=""/>
<meta ctg="Rekall-&gt;Keywords" cnt=""/>
<meta ctg="Rekall-&gt;Group" cnt=""/>
<meta ctg="Rekall-&gt;Visibility" cnt=""/>
<meta ctg="Rekall-&gt;Type" cnt="rekall/marker"/>
<meta ctg="Rekall-&gt;Flag" cnt="Marker"/>
<meta ctg="Rekall-&gt;Name" cnt="New note"/>
</document>
<tag key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" timeStart="0" timeEnd="10" version="0"/>
<edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall-&gt;Name" metadataValue="First note" version="0"/>
<edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall-&gt;Comments" metadataValue="This is a note for tests purpose." version="0"/>
<edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall-&gt;Link" metadataValue="https://youtu.be/dQw4w9WgXcQ" version="0"/>
<edition key="marker-1f10323d5f4a1c119e777e59c2f00dcc650e750d" metadataKey="Rekall-&gt;Author" metadataValue="Rick Astley" version="0"/>
<document key="marker-45f08bfa88924f466539f2ae41b509f7823929db">
<meta ctg="Rekall-&gt;Author" cnt=""/>
<meta ctg="Rekall-&gt;Date/Time" cnt="2022:01:21 14:09:09"/>
<meta ctg="Rekall-&gt;Import Date" cnt="2022:01:21 14:09:09"/>
<meta ctg="Rekall-&gt;Location Name" cnt=""/>
<meta ctg="Rekall-&gt;Location GPS" cnt=""/>
<meta ctg="Rekall User Infos-&gt;User Name" cnt=""/>
<meta ctg="Rekall User Infos-&gt;User IP" cnt="192.168.176.3"/>
<meta ctg="Rekall-&gt;Comments" cnt=""/>
<meta ctg="Rekall-&gt;Type" cnt="rekall/marker"/>
<meta ctg="Rekall-&gt;Flag" cnt="Marker"/>
<meta ctg="Rekall-&gt;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-&gt;Name" metadataValue="Second note" version="0"/>
<edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall-&gt;Author" metadataValue="Bob" version="0"/>
<edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall-&gt;Comments" metadataValue="Empty" version="0"/>
<tag key="marker-45f08bfa88924f466539f2ae41b509f7823929db" timeStart="30" timeEnd="75" version="0"/>
<edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall-&gt;Link" metadataValue="http://undefined" version="0"/>
<tag key="marker-45f08bfa88924f466539f2ae41b509f7823929db" timeStart="30" timeEnd="75" version="0"/>
<edition key="marker-45f08bfa88924f466539f2ae41b509f7823929db" metadataKey="Rekall-&gt;Highlight" metadataValue="true" version="0"/>
<document>
<meta ctg="Rekall-&gt;Author" cnt=""/>
<meta ctg="File-&gt;File Access Date/Time" cnt="2022:01:21 15:10:38"/>
<meta ctg="File-&gt;File Creation Date/Time" cnt="2022:01:21 15:10:38"/>
<meta ctg="File-&gt;File Modification Date/Time" cnt="2022:01:21 15:10:38"/>
<meta ctg="Rekall-&gt;Date/Time" cnt="2022:01:21 15:10:38"/>
<meta ctg="Rekall-&gt;Import Date" cnt="2022:01:21 14:10:39"/>
<meta ctg="Rekall-&gt;Location Name" cnt=""/>
<meta ctg="Rekall-&gt;Location GPS" cnt=""/>
<meta ctg="Rekall User Infos-&gt;User Name" cnt=""/>
<meta ctg="Rekall User Infos-&gt;User IP" cnt="192.168.176.3"/>
<meta ctg="Rekall-&gt;Comments" cnt=""/>
<meta ctg="File-&gt;Hash" cnt="2B0F9FA5055C514A9464616416A1EA63A72FD88B"/>
<meta ctg="Rekall-&gt;Flag" cnt="File"/>
<meta ctg="File-&gt;Thumbnail" cnt=""/>
<meta ctg="File-&gt;Owner" cnt="www-data"/>
<meta ctg="File-&gt;MIME Type" cnt="image/jpeg"/>
<meta ctg="File-&gt;File Type" cnt="image/jpeg"/>
<meta ctg="Rekall-&gt;Type" cnt="image/jpeg"/>
<meta ctg="File-&gt;File Name" cnt="image_for_test.jpeg"/>
<meta ctg="File-&gt;Extension" cnt="jpeg"/>
<meta ctg="File-&gt;Basename" cnt="image_for_test"/>
<meta ctg="Rekall-&gt;Name" cnt="image_for_test"/>
<meta ctg="Rekall-&gt;Extension" cnt="JPEG"/>
<meta ctg="Rekall-&gt;Folder" cnt=""/>
<meta ctg="Rekall-&gt;File Size" cnt="5591"/>
<meta ctg="Rekall-&gt;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>
......@@ -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();
}
}
......@@ -7,6 +7,7 @@ general:
cancel_button: Cancel
link_expire: This link will expire in %expirationDuration%
greeting: Cheers!
validate: Validate
login:
account_disabled_feedback: Your user account is disabled. Please click on the link your receive by email to validate your registration.
......@@ -70,15 +71,22 @@ capsule:
link: Edit capsule
duplicate:
link: Duplicate capsule
title: Duplicate capsule
title_name: Duplicate capsule %capsule_name%
new_name: Enter the name of the new capsule
success: The capsule has been successfully duplicated into capsule_name. You can see it at the end of your list
error: You don't have the permission to duplicate this capsule
delete:
link: Delete capsule
button: Delete
title: Delete capsule
text: Do you really want to delete the capsule %capsule_name%?
success: Capsule capsule_name was deleted successfully
error: You don't have the permission to delete this capsule
project:
already_exists: Project capsule_name already exists so the capsule could not be created
not_exist: The project to duplicate does not exist
preview:
loading: Project loading
......
......@@ -7,6 +7,7 @@ general:
greeting: Salutation !
go_back_to_home_page: Page d'accueil
cancel_button: Annuler
validate: Valider
login:
account_disabled_feedback: Le compte utilisateur a été désactivé. Veuillez cliquer sur le lien pour recevoir un courriel de validation
......@@ -67,6 +68,11 @@ capsule:
link: Modifier la capsule
duplicate:
link: Dupliquer la capsule
title: Dupliquer la capsule
title_name: Dupliquer la capsule %capsule_name%
new_name: Saisissez le nom de la nouvelle capsule
success: La capsule a bien été dupliquée en capsule_name. Vous la retrouverez à la suite des capsules
error: Vous n'avez pas les droits nécessaires pour dupliquer cette capsule
delete:
link: Supprimer la capsule
not_found: Le projet n'existe pas
......@@ -74,9 +80,11 @@ capsule:
title: Supprimer la capsule
text: Souhaitez-vous vraiment supprimer la capsule %capsule_name% ?
success: La capsule capsule_name a bien été supprimée
error: Vous n'avez pas les droits nécessaires pour supprimer cette capsule
project:
already_exists: Le projet capsule_name existe déjà. La capsule n'a pas pu être créée
not_exist: Le projet a dupliquer n'existe pas
preview:
loading: Projet en cours de chargement
......
......@@ -19,6 +19,6 @@ agreeTerms: You must agree with our terms
capsule:
name:
not_blank: Please enter a capsule name
unique: There is already a project with this name
unique: There is already a capsule with this name
video_url:
not_blank: Please enter a video URL
\ No newline at end of file
......@@ -15,3 +15,10 @@ password:
invalid: Mot de passe incorrect
agreeTerms: Veuillez accepter les termes et conditions
capsule:
name:
not_blank: Veuillez saisir le nom de la capsule
unique: Il existe déjà une capsule avec ce nom
video_url:
not_blank: Veuillez saisir l'URL de votre vidéo
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment