From 63f2c1dc4b01f44c3f41b2abda01b1140f60d1c6 Mon Sep 17 00:00:00 2001
From: Bernd Oliver Suenderhauf <bos@suenderhauf.de>
Date: Thu, 4 Apr 2019 01:32:40 +0200
Subject: [PATCH] Issue #3045691 by Pancho: Properly test scheme options on the
 settings form

---
 .../modules/fillpdf_test/fillpdf_test.module  |  8 +-
 .../Functional/FillPdfSettingsFormTest.php    | 76 +++++++++++++------
 tests/src/Traits/TestFillPdfTrait.php         | 20 +++--
 3 files changed, 70 insertions(+), 34 deletions(-)

diff --git a/tests/modules/fillpdf_test/fillpdf_test.module b/tests/modules/fillpdf_test/fillpdf_test.module
index 535c6c2..1897fa5 100644
--- a/tests/modules/fillpdf_test/fillpdf_test.module
+++ b/tests/modules/fillpdf_test/fillpdf_test.module
@@ -37,8 +37,12 @@ function fillpdf_test_form_fillpdf_settings_alter(array &$form, FormStateInterfa
  * Custom validation for fillpdf_test_form_fillpdf_settings_alter().
  */
 function fillpdf_test_form_fillpdf_settings_validate($form, FormStateInterface &$form_state) {
-  if ($form_state->getValue('backend') == 'test' && strlen($form_state->getValue('example_setting')) < 2) {
-    $form_state->setErrorByName('example_setting', t('Not a valid value.'));
+  if ($form_state->getValue('backend') == 'test') {
+    // Only validate if a value is set.
+    $value = $form_state->getValue('example_setting');
+    if (!empty($value) && strlen($value) < 2) {
+      $form_state->setErrorByName('example_setting', t('Not a valid value.'));
+    }
   }
 }
 
diff --git a/tests/src/Functional/FillPdfSettingsFormTest.php b/tests/src/Functional/FillPdfSettingsFormTest.php
index dd793bf..4026d3d 100644
--- a/tests/src/Functional/FillPdfSettingsFormTest.php
+++ b/tests/src/Functional/FillPdfSettingsFormTest.php
@@ -33,11 +33,13 @@ class FillPdfSettingsFormTest extends BrowserTestBase {
   }
 
   /**
-   * Tests the settings form.
+   * Tests the scheme settings with the site default.
    */
-  public function testSettingsForm() {
-    // FillPDF is not yet configured. Scheme should be initialized with the site
-    // default. Backend should be set to 'fillpdf_service'.
+  public function testSettingsFormDefaults() {
+    // FillPDF is not yet configured.
+    // Verify the settings form is however initialized with the site default
+    // scheme, which at this point should be 'public', and with the
+    // 'fillpdf_service' backend.
     $this->drupalGet(Url::fromRoute('fillpdf.settings'));
     $this->assertSession()->pageTextContains('Public files (site default)');
     $this->assertSession()->checkboxChecked('edit-scheme-public');
@@ -49,21 +51,27 @@ class FillPdfSettingsFormTest extends BrowserTestBase {
       ->set('default_scheme', 'private');
     $config->save();
 
-    // Scheme should now be initialized with the new site default. Backend
-    // should still be 'fillpdf_service'.
+    // The form should now be initialized with the new site default scheme,
+    // while the backend should remain unchanged.
     $this->drupalGet(Url::fromRoute('fillpdf.settings'));
     $this->assertSession()->pageTextContains('Private files (site default)');
     $this->assertSession()->checkboxChecked('edit-scheme-private');
     $this->assertSession()->checkboxChecked('edit-backend-fillpdf-service');
+  }
 
-    // Select 'dummy_remote://' as new default scheme.
-    $this->configureBackend('dummy_remote');
-
-    // Verify that the default 'dummy_remote' stream wrapper is present.
+  /**
+   * Tests the scheme settings with the 'dummy_remote' stream wrapper.
+   */
+  public function testSettingsFormSchemeDummyRemote() {
+    // FillPDF is not yet configured.
+    // Verify the 'dummy_remote' stream wrapper is present on the form.
     $this->drupalGet(Url::fromRoute('fillpdf.settings'));
     $this->assertSession()->elementExists('css', '#edit-scheme-dummy-remote');
 
-    // Now uninstall the test module with the dummy stream wrappers.
+    // Programmatically configure 'dummy_remote' as new default scheme.
+    $this->configureBackend('dummy_remote');
+
+    // Now uninstall the file_test module with the dummy stream wrappers.
     $this->assertTrue(\Drupal::service('module_installer')->uninstall(['file_test']), "Module 'file_test' has been uninstalled.");
     $this->assertFalse(\Drupal::moduleHandler()->moduleExists('file_test'), "Module 'file_test' is no longer present.");
 
@@ -71,27 +79,45 @@ class FillPdfSettingsFormTest extends BrowserTestBase {
     $this->drupalGet(Url::fromRoute('fillpdf.settings'));
     $this->assertSession()->elementNotExists('css', '#edit-scheme-dummy-remote');
     $this->assertSession()->pageTextContains('Your previously used file scheme dummy_remote:// is no longer available');
+  }
 
-    // Select 'private://' as new default scheme.
-    // @todo Once https://www.drupal.org/project/fillpdf/issues/3040901 is in,
-    // this should be set via the UI:
-    // $this->drupalPostForm(NULL, ['scheme' => 'private'], 'Save configuration');
-    // $this->assertSession()->pageTextNotContains('An illegal choice has been detected.');
-    $this->configureBackend('private');
-
-    // Now remove the private path and rebuild the container.
-    $settings['settings']['file_private_path'] = (object) [
-      'value' => '',
-      'required' => TRUE,
-    ];
-    $this->writeSettings($settings);
+  /**
+   * Tests the scheme settings with the 'private' stream wrapper.
+   */
+  public function testSettingsFormSchemePrivate() {
+    // FillPDF is not yet configured.
+    // Configure FillPDF with the 'test' backend and the site default scheme,
+    // which at this point is 'public'.
+    $this->configureBackend();
+
+    // Now on the settings form, switch to the 'private' scheme.
+    $this->drupalPostForm(Url::fromRoute('fillpdf.settings'), ['scheme' => 'private'], 'Save configuration');
+
+    // Verify the new values have been submitted *and* successfully saved.
+    $this->assertSession()->pageTextContains('The configuration options have been saved.');
+    $this->assertSession()->fieldValueEquals('scheme', 'private');
+    $this->assertEqual($this->config('fillpdf.settings')->get('scheme'), 'private');
+
+    // Now remove the private path from settings.php and rebuild the container.
+    $this->writeSettings([
+      'settings' => [
+        'file_private_path' => (object) [
+          'value' => '',
+          'required' => TRUE,
+        ],
+      ],
+    ]);
     $this->rebuildContainer();
 
-    // Reload the page and and verify that 'private' is gone, too.
+    // Reload the page to verify the 'private' scheme is gone.
     $this->drupalGet(Url::fromRoute('fillpdf.settings'));
     $this->assertSession()->elementNotExists('css', '#edit-scheme-private');
     $this->assertSession()->pageTextContains('Your previously used file scheme private:// is no longer available');
 
+    // Verify that the site default scheme, which at this point is 'public', is
+    // preselected but not yet saved in config.
+    $this->assertSession()->fieldValueEquals('scheme', \Drupal::config('system.file')->get('default_scheme'));
+    $this->assertEqual($this->config('fillpdf.settings')->get('scheme'), 'private');
   }
 
   /**
diff --git a/tests/src/Traits/TestFillPdfTrait.php b/tests/src/Traits/TestFillPdfTrait.php
index 874f4a0..3252e39 100644
--- a/tests/src/Traits/TestFillPdfTrait.php
+++ b/tests/src/Traits/TestFillPdfTrait.php
@@ -10,19 +10,25 @@ namespace Drupal\Tests\fillpdf\Traits;
 trait TestFillPdfTrait {
 
   /**
-   * Configures the FillPdf test backend.
+   * Configures the FillPdf test scheme and backend.
    *
    * @param string $scheme
    *   (optional) The file system scheme to use for PDF templates. Defaults
-   *   to 'public'.
+   *   to the site default, which initially is 'public'.
    * @param string $backend
    *   (optional) The backend to use. Defaults to 'test'.
    */
-  protected function configureBackend($scheme = 'public', $backend = 'test') {
-    // FillPDF needs to be configured.
-    /** @var \Drupal\Core\Config\Config $fillpdf_settings */
-    $fillpdf_settings = $this->container->get('config.factory')
-      ->getEditable('fillpdf.settings')
+  protected function configureBackend($scheme = 'default', $backend = 'test') {
+    /** @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory */
+    $config_factory = $this->container->get('config.factory');
+
+    // Get the site default scheme.
+    if ($scheme == 'default') {
+      $scheme = $config_factory->get('system.file')->get('default_scheme');
+    }
+
+    // Set FillPDF backend and scheme.
+    $fillpdf_settings = $config_factory->getEditable('fillpdf.settings')
       ->set('scheme', $scheme)
       ->set('backend', $backend);
     $fillpdf_settings->save();
-- 
GitLab