diff --git a/src/Controller/CapsuleController.php b/src/Controller/CapsuleController.php
index 6cc1a15a128f578d3a569eba2781d2f2219b1fc8..b169c9f4fc4eaedd9d4035c34513e45f1a36d189 100644
--- a/src/Controller/CapsuleController.php
+++ b/src/Controller/CapsuleController.php
@@ -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;
+    }
 }
diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php
index e386f3936f420add02bc1d06041eeaaf0f27a6d3..6fded99a76649dbe77e4ccf3e7c2883a39228478 100644
--- a/src/Controller/ProjectController.php
+++ b/src/Controller/ProjectController.php
@@ -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]
+        );
+    }
 }
diff --git a/src/Form/DuplicateCapsuleFormType.php b/src/Form/DuplicateCapsuleFormType.php
new file mode 100644
index 0000000000000000000000000000000000000000..7dc94cfe27e13b8a9a12dfffd17be38394b791b5
--- /dev/null
+++ b/src/Form/DuplicateCapsuleFormType.php
@@ -0,0 +1,35 @@
+<?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,
+        ]);
+    }
+}
diff --git a/src/Repository/CapsuleRepository.php b/src/Repository/CapsuleRepository.php
index 245b86803d8301c7165a8a445a6ec42551f44e23..7e5cd9f9e9820c23e9b5eda5685c5c3772130af8 100644
--- a/src/Repository/CapsuleRepository.php
+++ b/src/Repository/CapsuleRepository.php
@@ -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;
+    }
 }
diff --git a/templates/capsule/duplicate.html.twig b/templates/capsule/duplicate.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..af7f795b7d63fa3eeb4cb28b1b358eb2ad941450
--- /dev/null
+++ b/templates/capsule/duplicate.html.twig
@@ -0,0 +1,27 @@
+{% 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
diff --git a/templates/capsule/index.html.twig b/templates/capsule/index.html.twig
index e99a2dacc7dc0aa74482fd24276964f5187e3387..c18fa5a17306da3c14718cc9a186e3e0704b011e 100644
--- a/templates/capsule/index.html.twig
+++ b/templates/capsule/index.html.twig
@@ -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>
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-&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>
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();
+    }
 }
diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml
index 54613c726b86293981af8c8fd55550921ed8ac97..b6e3029b3d13c41d03059eed90d7f7ca774c477f 100644
--- a/translations/messages.en.yaml
+++ b/translations/messages.en.yaml
@@ -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
diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml
index 527684ea05abe05593a5f057d58f6a5cd536513a..9fff9516c6726f3625dc8882cd317b063f54b269 100644
--- a/translations/messages.fr.yaml
+++ b/translations/messages.fr.yaml
@@ -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
diff --git a/translations/validators.en.yaml b/translations/validators.en.yaml
index 6b1f331119ea7c9406e35ae28f9294b10a490b5f..2a4c7e79c671ce31e50ed4099f7d3074a7fafabb 100644
--- a/translations/validators.en.yaml
+++ b/translations/validators.en.yaml
@@ -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
diff --git a/translations/validators.fr.yaml b/translations/validators.fr.yaml
index 899af067c83d99a6b2d4bb519d918c6898f8edd6..e6aa6050801f11f164ce603c6e01fd58177644a6 100644
--- a/translations/validators.fr.yaml
+++ b/translations/validators.fr.yaml
@@ -14,4 +14,11 @@ password:
   match: Les champs mots de passe doivent être identiques
   invalid: Mot de passe incorrect
 
-agreeTerms: Veuillez accepter les termes et conditions
\ No newline at end of file
+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