From 1a893da04746b5bc59487975c95ff91290218497 Mon Sep 17 00:00:00 2001
From: Bernd Oliver Suenderhauf <bos@suenderhauf.de>
Date: Mon, 25 Mar 2019 17:20:49 +0100
Subject: [PATCH] Issue #3043096 by Pancho: Refactor and expand template upload
 tests

---
 ...UploadTest.php => FillPdfFormFormTest.php} |  65 +-------
 .../Functional/FillPdfOverviewFormTest.php    |  44 ++---
 .../src/Functional/FillPdfUploadTestBase.php  | 156 ++++++++++++++++++
 3 files changed, 190 insertions(+), 75 deletions(-)
 rename tests/src/Functional/{TemplateUploadTest.php => FillPdfFormFormTest.php} (54%)
 create mode 100644 tests/src/Functional/FillPdfUploadTestBase.php

diff --git a/tests/src/Functional/TemplateUploadTest.php b/tests/src/Functional/FillPdfFormFormTest.php
similarity index 54%
rename from tests/src/Functional/TemplateUploadTest.php
rename to tests/src/Functional/FillPdfFormFormTest.php
index e6695c5..43de9da 100644
--- a/tests/src/Functional/TemplateUploadTest.php
+++ b/tests/src/Functional/FillPdfFormFormTest.php
@@ -5,63 +5,17 @@ namespace Drupal\Tests\fillpdf\Functional;
 use Drupal\file\Entity\File;
 use Drupal\fillpdf\Entity\FillPdfForm;
 use Drupal\user\Entity\Role;
-use Drupal\Tests\BrowserTestBase;
-use Drupal\Tests\TestFileCreationTrait;
-use Drupal\Tests\fillpdf\Traits\TestFillPdfTrait;
 
 /**
- * Test everything around uploading PDF template files.
- *
+ * @coversDefaultClass \Drupal\fillpdf\Form\FillPdfFormForm
  * @group fillpdf
  */
-class TemplateUploadTest extends BrowserTestBase {
-
-  use TestFileCreationTrait;
-  use TestFillPdfTrait;
-
-  static public $modules = ['fillpdf_test'];
-  protected $profile = 'minimal';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->configureBackend();
-    $this->initializeUser();
-  }
-
-  /**
-   * Tests the overview form's PDF file upload functionality.
-   */
-  public function testFillPdfOverviewFormUpload() {
-    $this->drupalGet('admin/structure/fillpdf');
-
-    // Check if the 'accept' attribute is correctly set.
-    $this->assertSession()->elementAttributeContains('css', 'input#edit-upload-pdf-upload', 'accept', 'application/pdf');
-
-    // Without a PDF file being supplied, no FillPdfForm should be created.
-    $this->uploadTestPdf(NULL);
-    $this->assertSession()->pageTextNotContains('New FillPDF form has been created.');
-
-    // With a .txt file being supplied, validation should set an error.
-    $files = $this->getTestFiles('text');
-    $file = reset($files);
-    $this->drupalPostForm(NULL, ['files[upload_pdf]' => $file->uri], 'Upload');
-    $this->assertSession()->statusCodeEquals(200);
-    $this->assertSession()->pageTextNotContains('New FillPDF form has been created.');
-    $this->assertSession()->pageTextContains('Only files with the following extensions are allowed: pdf.');
-
-    // With a PDF file being supplied, a new FillPdfForm should be created.
-    $this->uploadTestPdf('fillpdf_test_v3.pdf');
-    $this->assertSession()->pageTextContains('New FillPDF form has been created.');
-  }
+class FillPdfFormFormTest extends FillPdfUploadTestBase {
 
   /**
    * Tests the FillPdfForm entity's edit form.
    */
-  public function testFillPdfFormFormUpload() {
+  public function testFormFormUpload() {
     $this->uploadTestPdf('fillpdf_test_v3.pdf');
 
     $latest_fid = $this->getLatestFillPdfForm();
@@ -73,12 +27,11 @@ class TemplateUploadTest extends BrowserTestBase {
     // Check if the 'accept' attribute is correctly set.
     $this->assertSession()->elementAttributeContains('css', 'input#edit-upload-pdf-upload', 'accept', 'application/pdf');
 
-    // When trying to upload a .txt file, validation should set an error.
-    $files = $this->getTestFiles('text');
-    $file = reset($files);
-    $this->drupalPostForm(NULL, ['files[upload_pdf]' => $file->uri], 'Save');
-    $this->assertSession()->statusCodeEquals(200);
-    $this->assertSession()->pageTextContains('Only files with the following extensions are allowed: pdf.');
+    // Run all upload tests.
+    $this->assertNotUploadTextFile(self::OP_UPLOAD);
+    $this->assertNotUploadTextFile(self::OP_SAVE);
+    $this->assertUploadPdfFile(self::OP_UPLOAD, TRUE);
+    $this->assertUploadPdfFile(self::OP_SAVE, TRUE);
   }
 
   /**
@@ -89,7 +42,7 @@ class TemplateUploadTest extends BrowserTestBase {
 
     // Set the administrative title and check if it has been successfully set.
     $admin_title = 'Example form';
-    $this->drupalPostForm(NULL, ['admin_title[0][value]' => $admin_title], 'Save');
+    $this->drupalPostForm(NULL, ['admin_title[0][value]' => $admin_title], self::OP_SAVE);
     $this->assertSession()->pageTextContains("FillPDF Form $admin_title has been updated.");
     $this->assertSession()->fieldValueEquals('edit-admin-title-0-value', $admin_title);
 
diff --git a/tests/src/Functional/FillPdfOverviewFormTest.php b/tests/src/Functional/FillPdfOverviewFormTest.php
index 5f9a3e3..4e3ad07 100644
--- a/tests/src/Functional/FillPdfOverviewFormTest.php
+++ b/tests/src/Functional/FillPdfOverviewFormTest.php
@@ -4,40 +4,44 @@ namespace Drupal\Tests\fillpdf\Functional;
 
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
 use Drupal\fillpdf\Entity\FillPdfForm;
-use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
 use Drupal\user\Entity\Role;
 use Drupal\Core\Url;
-use Drupal\Tests\BrowserTestBase;
-use Drupal\Tests\fillpdf\Traits\TestFillPdfTrait;
 
 /**
  * @coversDefaultClass \Drupal\fillpdf\Form\FillPdfOverviewForm
  * @group fillpdf
  */
-class FillPdfOverviewFormTest extends BrowserTestBase {
+class FillPdfOverviewFormTest extends FillPdfUploadTestBase {
 
   use ContentTypeCreationTrait;
   use EntityReferenceTestTrait;
-  use TestFillPdfTrait;
-
-  static public $modules = ['fillpdf_test'];
-  protected $profile = 'minimal';
 
   /**
-   * {@inheritdoc}
+   * Tests the overview form is accessible.
    */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->configureBackend();
-    $this->initializeUser();
+  public function testOverviewForm() {
+    $this->drupalGet(Url::fromRoute('fillpdf.forms_admin'));
   }
 
   /**
-   * Tests the overview form is accessible.
+   * Tests the overview form's PDF file upload functionality.
    */
-  public function testOverviewForm() {
-    $this->drupalGet(Url::fromRoute('fillpdf.forms_admin'));
+  public function testOverviewFormUpload() {
+    // Without any file being supplied, nothing should happen at all,
+    // particularly no FillPdfForm should be created.
+    $this->uploadTestPdf(NULL);
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->pageTextNotContains('New FillPDF form has been created.');
+
+    // Check if the 'accept' attribute is correctly set.
+    $this->assertSession()->elementAttributeContains('css', 'input#edit-upload-pdf-upload', 'accept', 'application/pdf');
+
+    // Run all upload tests.
+    $this->assertNotUploadTextFile(self::OP_UPLOAD);
+    $this->assertNotUploadTextFile(self::OP_CREATE);
+    $this->assertUploadPdfFile(self::OP_UPLOAD, FALSE);
+    $this->assertUploadPdfFile(self::OP_CREATE, FALSE);
   }
 
   /**
@@ -48,7 +52,7 @@ class FillPdfOverviewFormTest extends BrowserTestBase {
 
     // Set the administrative title and check if it has been successfully set.
     $admin_title = 'Example form';
-    $this->drupalPostForm(NULL, ['admin_title[0][value]' => $admin_title], 'Save');
+    $this->drupalPostForm(NULL, ['admin_title[0][value]' => $admin_title], self::OP_SAVE);
     $this->assertSession()->pageTextContains("FillPDF Form $admin_title has been updated.");
     $this->assertSession()->fieldValueEquals('edit-admin-title-0-value', $admin_title);
 
@@ -69,6 +73,8 @@ class FillPdfOverviewFormTest extends BrowserTestBase {
 
   /**
    * Tests an entity reference to a FillPdfForm.
+   *
+   * @todo: This doesn't belong here.
    */
   public function testEntityReference() {
     // Create new FillPdfForm.
@@ -77,7 +83,7 @@ class FillPdfOverviewFormTest extends BrowserTestBase {
 
     // Set the administrative title.
     $admin_title = 'Example form';
-    $this->drupalPostForm("admin/structure/fillpdf/{$fid}", ['admin_title[0][value]' => $admin_title], 'Save');
+    $this->drupalPostForm("admin/structure/fillpdf/{$fid}", ['admin_title[0][value]' => $admin_title], self::OP_SAVE);
     $this->assertSession()->statusCodeEquals(200);
 
     // Create host content type.
diff --git a/tests/src/Functional/FillPdfUploadTestBase.php b/tests/src/Functional/FillPdfUploadTestBase.php
new file mode 100644
index 0000000..c17a977
--- /dev/null
+++ b/tests/src/Functional/FillPdfUploadTestBase.php
@@ -0,0 +1,156 @@
+<?php
+
+namespace Drupal\Tests\fillpdf\Functional;
+
+use Drupal\file\Entity\File;
+use Drupal\fillpdf\Component\Utility\FillPdf;
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Tests\file\Functional\FileFieldTestBase;
+use Drupal\Tests\fillpdf\Traits\TestFillPdfTrait;
+
+/**
+ * Allows testing everything around uploading PDF template files.
+ *
+ * @group fillpdf
+ * @todo Switch to a trait or FileManagedTestBase once it contains a more robust
+ *   set of tools. See: https://www.drupal.org/project/drupal/issues/3043024.
+ */
+abstract class FillPdfUploadTestBase extends FileFieldTestBase {
+
+  use TestFillPdfTrait;
+
+  static public $modules = ['fillpdf_test'];
+  protected $profile = 'minimal';
+
+  /**
+   * @var Upload a file in the managed file widget.
+   */
+  const OP_UPLOAD = 'Upload';
+
+  /**
+   * @var Remove a file from the managed file widget.
+   */
+  const OP_REMOVE = 'Remove';
+
+  /**
+   * @var Create a new FillPdfForm. Submit button on FillPdfOverviewForm.
+   */
+  const OP_CREATE = 'Create';
+
+  /**
+   * @var Save and update the FillPdfForm. Submit button on FillPdfFormForm.
+   */
+  const OP_SAVE = 'Save';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->configureBackend();
+    $this->initializeUser();
+  }
+
+  /**
+   * Asserts that a text file may not be uploaded.
+   *
+   * @param string $op
+   *   (optional) Operation to perform. May be either of:
+   *   - FillPdfUploadTestBase::OP_UPLOAD (default),
+   *   - FillPdfUploadTestBase::OP_CREATE, or
+   *   - FillPdfUploadTestBase::OP_SAVE.
+   */
+  protected function assertNotUploadTextFile($op = self::OP_UPLOAD) {
+    $previous_file_id = $this->getLastFileId();
+
+    // Try uploading a text file in the managed file widget.
+    $edit = ['files[upload_pdf]' => $this->getTestFile('text')->getFileUri()];
+    $this->drupalPostForm(NULL, $edit, $op);
+
+    // Whether submitted or just uploaded, the validation should set an error
+    // and the file shouldn't end up being uploaded.
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->pageTextContains('Only files with the following extensions are allowed: pdf.');
+    $this->assertEquals($previous_file_id, $this->getLastFileId());
+
+    // Make sure FillPdf Forms were not affected.
+    $this->assertSession()->pageTextNotContains('New FillPDF form has been created.');
+    $this->assertSession()->pageTextNotContains('Your previous field mappings have been transferred to the new PDF template you uploaded.');
+
+  }
+
+  /**
+   * Asserts that a PDF file may be properly uploaded as a template.
+   *
+   * @param string $op
+   *   (optional) Operation to perform. May be either of:
+   *   - FillPdfUploadTestBase::OP_UPLOAD (default),
+   *   - FillPdfUploadTestBase::OP_CREATE, or
+   *   - FillPdfUploadTestBase::OP_SAVE.
+   * @param boolean $filename_preexists
+   *   (optional) Whether the testfile has previously been uploaded, so a file
+   *   with the same filename preexists. Defaults to FALSE.
+   */
+  protected function assertUploadPdfFile($op = self::OP_UPLOAD, $filename_preexists = FALSE) {
+    $previous_file_id = $this->getLastFileId();
+
+    // Upload PDF test file.
+    $edit = ['files[upload_pdf]' => $this->getTestPdfPath('fillpdf_test_v3.pdf')];
+    $this->drupalPostForm(NULL, $edit, $op);
+
+    // Whether submitted or just uploaded, at least temporarily the file should
+    // exist now both as an object and physically on the disk.
+    $new_file = File::load($this->getLastFileId());
+    $new_filename = $new_file->getFilename();
+    $this->assertFileExists($new_file);
+    $this->assertLessThan((int) $new_file->id(), $previous_file_id);
+
+    // If the same file was previously uploaded, it should have a "_0" appendix.
+    $this->assertEquals($new_filename, $filename_preexists ? 'fillpdf_test_v3_0.pdf' : 'fillpdf_test_v3.pdf');
+
+    switch ($op) {
+      case self::OP_UPLOAD:
+        // We only uploaded, so make sure FillPdf Forms were not affected.
+        $this->assertSession()->pageTextNotContains('New FillPDF form has been created.');
+        $this->assertSession()->pageTextNotContains('Your previous field mappings have been transferred to the new PDF template you uploaded.');
+
+        // Make sure the file is temporary only.
+        // @todo Simplify once there is an assertFileIsTemporary().
+        //   See: https://www.drupal.org/project/drupal/issues/3043129.
+        $this->assertTrue($new_file->isTemporary(), new FormattableMarkup('File %file is temporary.', ['%file' => $new_file->getFileUri()]));
+
+        // Now remove the PDF file again. The temporary file should now be
+        // removed both from the disk and the database.
+        $this->drupalPostForm(NULL, NULL, self::OP_REMOVE);
+        $this->assertFileNotExists($new_file);
+        // @todo Simplify once Core bug gets fixed.
+        //   See: https://www.drupal.org/project/drupal/issues/3043127.
+        $this->assertFileEntryNotExists($new_file, NULL);
+        break;
+
+      case self::OP_CREATE:
+        // A new FillPdfForm should be created.
+        $this->assertSession()->pageTextContains('New FillPDF form has been created.');
+        $this->assertSession()->pageTextNotContains('Your previous field mappings have been transferred to the new PDF template you uploaded.');
+
+        // Make sure the file is permanent and correctly placed.
+        $this->assertFileIsPermanent($new_file);
+        $expected_file_uri = FillPdf::buildFileUri($this->config('fillpdf.settings')->get('scheme'), "fillpdf/{$new_filename}");
+        $this->assertEquals($new_file->getFileUri(), $expected_file_uri);
+        break;
+
+      case self::OP_SAVE:
+        // The current FillPdfForm should be updated with the new file.
+        $this->assertSession()->pageTextNotContains('New FillPDF form has been created.');
+        $this->assertSession()->pageTextContains('Your previous field mappings have been transferred to the new PDF template you uploaded.');
+
+        // Make sure the file is permanent and correctly placed.
+        $this->assertFileIsPermanent($new_file);
+        $expected_file_uri = FillPdf::buildFileUri($this->config('fillpdf.settings')->get('scheme'), "fillpdf/{$new_filename}");
+        $this->assertEquals($new_file->getFileUri(), $expected_file_uri);
+        break;
+    }
+  }
+
+}
-- 
GitLab