webform_civicrm-8.x-5.0-beta3/tests/src/FunctionalJavascript/ExistingContactElementTest.php

tests/src/FunctionalJavascript/ExistingContactElementTest.php
<?php

namespace Drupal\Tests\webform_civicrm\FunctionalJavascript;

use Drupal\Core\Url;
use Drupal\Core\Test\AssertMailTrait;
use Drupal\webform\Entity\WebformSubmission;
use Drupal\webform\Entity\Webform;
use Drupal\Core\Serialization\Yaml;

/**
 * Tests submitting a Webform with CiviCRM: existing contact element.
 *
 * @group webform_civicrm
 */
final class ExistingContactElementTest extends WebformCivicrmTestBase {

  use AssertMailTrait;

  private function addcontactinfo() {
    $currentUserUF = $this->getUFMatchRecord($this->rootUser->id());
    $params = [
      'contact_id' => $currentUserUF['contact_id'],
      'first_name' => 'Maarten',
      'last_name' => 'van der Weijden',
    ];
    $utils = \Drupal::service('webform_civicrm.utils');
    $result = $utils->wf_civicrm_api('Contact', 'create', $params);
    $this->assertEquals(0, $result['is_error']);
    $this->assertEquals(1, $result['count']);
  }

  public function testSubmitWebform() {

    $this->addcontactinfo();

    $this->drupalLogin($this->rootUser);
    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    // The label has a <div> in it which can cause weird failures here.
    $this->enableCivicrmOnWebform();
    $this->saveCiviCRMSettings();

    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertPageNoErrorMessages();

    $this->assertSession()->waitForField('First Name');

    // The Default Existing Contact Element behaviour is: load logged in User
    // The test here is to check if the fields on the form populate with Contact details belonging to the logged in User:
    $this->assertSession()->fieldValueEquals('First Name', 'Maarten');
    $this->assertSession()->fieldValueEquals('Last Name', 'van der Weijden');

    $this->getSession()->getPage()->pressButton('Submit');
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');
  }


  /**
   * Verify if existing contact element is loaded as expected.
   */
  function testRenderingOfExistingContactElement() {
    $this->addcontactinfo();
    $childContact = [
      'first_name' => 'Fred',
      'last_name' => 'Pinto',
    ];
    $childContactId = $this->createIndividual($childContact)['id'];
    $this->utils->wf_civicrm_api('Relationship', 'create', [
      'contact_id_a' => $childContactId,
      'contact_id_b' => $this->rootUserCid,
      'relationship_type_id' => "Child of",
    ]);

    $this->drupalLogin($this->rootUser);

    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    // The label has a <div> in it which can cause weird failures here.
    $this->enableCivicrmOnWebform();
    $this->getSession()->getPage()->selectFieldOption('contact_1_number_of_email', 1);
    $this->assertSession()->assertWaitOnAjaxRequest();

    $this->getSession()->getPage()->selectFieldOption("number_of_contacts", 4);
    $this->htmlOutput();

    foreach ([2, 3, 4] as $c) {
      $this->getSession()->getPage()->clickLink("Contact {$c}");
      //Make second contact as household contact.
      if ($c == 2) {
        $this->getSession()->getPage()->selectFieldOption("{$c}_contact_type", 'Household');
        $this->assertSession()->assertWaitOnAjaxRequest();
      }
      elseif ($c == 3) {
        $this->getSession()->getPage()->checkField("edit-civicrm-{$c}-contact-1-contact-job-title");
        $this->assertSession()->checkboxChecked("edit-civicrm-{$c}-contact-1-contact-job-title");
      }
      $this->getSession()->getPage()->checkField("civicrm_{$c}_contact_1_contact_existing");
      $this->assertSession()->checkboxChecked("civicrm_{$c}_contact_1_contact_existing");
    }

    $this->saveCiviCRMSettings();

    $this->drupalGet($this->webform->toUrl('edit-form'));
    // Edit contact element 1.
    $editContact = [
      'title' => 'Primary Contact',
      'selector' => 'edit-webform-ui-elements-civicrm-1-contact-1-contact-existing-operations',
      'widget' => 'Static',
      'description' => 'Description of the static contact element.',
      'hide_fields' => 'Email',
    ];
    $this->editContactElement($editContact);

    // Edit contact element 2.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-2-contact-1-contact-existing-operations',
      'widget' => 'Static',
    ];
    $this->editContactElement($editContact);

    // Edit contact element 3.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-3-contact-1-contact-existing-operations',
      'widget' => 'Autocomplete',
    ];
    $this->editContactElement($editContact);

    $this->drupalGet($this->webform->toUrl('edit-form'));
    // Set a default value for Job title.
    $this->setDefaultValue('edit-webform-ui-elements-civicrm-3-contact-1-contact-job-title-operations', 'Accountant');

    $this->drupalGet($this->webform->toUrl('edit-form'));
    // Edit contact element 4.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-4-contact-1-contact-existing-operations',
      'widget' => 'Static',
      'default' => 'relationship',
      'default_relationship' => [
        'default_relationship_to' => 'Contact 3',
        'default_relationship' => 'Child of Contact 3',
      ],
    ];
    $this->editContactElement($editContact);

    // Visit the webform.
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertPageNoErrorMessages();
    $this->htmlOutput();

    // Check if static title is displayed.
    $this->assertSession()->pageTextContains('Primary Contact');
    $this->assertSession()->pageTextContains('Description of the static contact element');
    //Make sure email field is not loaded.
    $this->assertFalse($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath('.form-type-email')));

    // Check if "None Found" text is present in the static element.
    $this->assertSession()->elementTextContains('css', '[id="edit-civicrm-2-contact-1-fieldset-fieldset"]', '- None Found -');

    // Check if c4 contains the text for "create new".
    $this->assertSession()->elementTextContains('css', '[id="edit-civicrm-4-contact-1-fieldset-fieldset"]', '+ Create new +');

    // Enter contact 3.
    $this->fillContactAutocomplete('token-input-edit-civicrm-3-contact-1-contact-existing', 'Maarten');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertFieldValue('edit-civicrm-3-contact-1-contact-job-title', 'Accountant');

    // Check if related contact is loaded on c4.
    $this->htmlOutput();
    $this->assertSession()->elementTextContains('css', '[id="edit-civicrm-4-contact-1-fieldset-fieldset"]', 'Fred Pinto');
  }

  /**
   * Check if autocomplete widget results is
   * searchable with all display field values.
   */
  public function testDisplayFields() {
    $this->createIndividual([
      'first_name' => 'James',
      'last_name' => 'Doe',
      'source' => 'Webform Testing',
    ]);

    $this->drupalLogin($this->rootUser);
    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    $this->enableCivicrmOnWebform();
    $this->saveCiviCRMSettings();
    $this->drupalGet($this->webform->toUrl('edit-form'));

    // Edit contact element and add source to display fields.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-1-contact-1-contact-existing-operations',
      'widget' => 'Autocomplete',
      'results_display' => ['display_name', 'source'],
      'default' => '- None -',
    ];
    $this->editContactElement($editContact);

    // Search on first name and verify if the contact is selected.
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->fillContactAutocomplete('token-input-edit-civicrm-1-contact-1-contact-existing', 'James');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertFieldValue('edit-civicrm-1-contact-1-contact-first-name', 'James');
    $this->assertFieldValue('edit-civicrm-1-contact-1-contact-last-name', 'Doe');

    // Search on source value and verify if the contact is selected.
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->fillContactAutocomplete('token-input-edit-civicrm-1-contact-1-contact-existing', 'Webform Testing');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertFieldValue('edit-civicrm-1-contact-1-contact-first-name', 'James');
    $this->assertFieldValue('edit-civicrm-1-contact-1-contact-last-name', 'Doe');
  }

  /**
   * Test submission of hidden fields.
   */
  public function testHiddenField() {
    $this->drupalLogin($this->rootUser);
    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    $this->enableCivicrmOnWebform();

     // Enable Email address
     $this->getSession()->getPage()->selectFieldOption('contact_1_number_of_email', 1);
     $this->assertSession()->assertWaitOnAjaxRequest();
     $this->assertSession()->checkboxChecked("civicrm_1_contact_1_email_email");
     $this->getSession()->getPage()->selectFieldOption('civicrm_1_contact_1_email_location_type_id', 'Main');

     $this->saveCiviCRMSettings();
     $this->drupalGet($this->webform->toUrl('edit-form'));

    // Edit contact element and hide email field.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-1-contact-1-contact-existing-operations',
      'widget' => 'Autocomplete',
      'hide_fields' => 'Email',
      'no_hide_blank' => TRUE,
      'submit_disabled' => TRUE,
      'default' => '- None -',
    ];
    $this->editContactElement($editContact);

    $this->setDefaultValue('edit-webform-ui-elements-civicrm-1-contact-1-email-email-operations', 'email@example.com');

    $contact = $this->createIndividual();
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->fillContactAutocomplete('token-input-edit-civicrm-1-contact-1-contact-existing', $contact['first_name']);

    //Ensure email field is not visible.
    $this->assertFalse($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath('.form-type-email')));

    $this->getSession()->getPage()->pressButton('Submit');
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');

    $result = $this->utils->wf_civicrm_api('Contact', 'get', [
      'first_name' => $contact['first_name'],
      'last_name' => $contact['last_name'],
      'email' => "email@example.com",
    ]);
    $this->assertEquals(0, $result['is_error']);
    $this->assertEquals(1, $result['count']);

    //Update contact email to something else.
    $this->utils->wf_civicrm_api('Email', 'create', [
      'contact_id' => $contact['id'],
      'email' => "updated_email@example.com",
      'is_primary' => 1,
    ]);

    // Load the webform.
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->fillContactAutocomplete('token-input-edit-civicrm-1-contact-1-contact-existing', $contact['first_name']);
    $this->getSession()->wait(5000);
    $this->getSession()->getPage()->pressButton('Submit');
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');

    // Ensure existing contact email is not overwritten.
    $result = $this->utils->wf_civicrm_api('Contact', 'get', [
      'first_name' => $contact['first_name'],
      'last_name' => $contact['last_name'],
      'email' => "updated_email@example.com",
    ]);
    $this->assertEquals(0, $result['is_error']);
    $this->assertEquals(1, $result['count']);
  }

  /**
   * Test Tokens in Email.
   */
  public function testTokensInEmail() {
    // Create 2 meeting activities for the contact.
    $actID1 = $this->utils->wf_civicrm_api('Activity', 'create', [
      'source_contact_id' => $this->rootUserCid,
      'activity_type_id' => "Meeting",
      'target_id' => $this->rootUserCid,
    ])['id'];
    $actID2 = $this->utils->wf_civicrm_api('Activity', 'create', [
      'source_contact_id' => $this->rootUserCid,
      'activity_type_id' => "Meeting",
      'target_id' => $this->rootUserCid,
    ])['id'];

    $this->drupalLogin($this->rootUser);
    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    $this->enableCivicrmOnWebform();

    // Enable Email address
    $this->getSession()->getPage()->selectFieldOption('contact_1_number_of_email', 1);
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->assertSession()->checkboxChecked("civicrm_1_contact_1_email_email");
    $this->getSession()->getPage()->selectFieldOption('civicrm_1_contact_1_email_location_type_id', 'Main');

    // Enable Address fields.
    $this->getSession()->getPage()->selectFieldOption('contact_1_number_of_address', 1);
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->checkField('Country');
    $this->assertSession()->checkboxChecked('Country');

    $this->getSession()->getPage()->clickLink('Activities');
    $this->getSession()->getPage()->selectFieldOption('activity_number_of_activity', 2);
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->htmlOutput();

    $this->saveCiviCRMSettings();

    $email = [
      'to_mail' => '[webform_submission:values:civicrm_1_contact_1_email_email:raw]',
      'body' => 'Submitted Values Are - [webform_submission:values] Existing Contact - [webform_submission:values:civicrm_1_contact_1_contact_existing]. Activity 1 ID - [webform_submission:activity-id:1]. Activity 2 ID - [webform_submission:activity-id:2]. Webform CiviCRM Contacts IDs - [webform_submission:contact-id:1]. Webform CiviCRM Contacts Links - [webform_submission:contact-link:1] Country - [webform_submission:values:civicrm_1_contact_1_address_country_id]. State/Province - [webform_submission:values:civicrm_1_contact_1_address_state_province_id].',
    ];
    $this->addEmailHandler($email);
    $this->drupalGet($this->webform->toUrl('handlers'));
    // tabledrag results into a console js error, possibly a drupal core bug.
    // $civicrm_handler = $this->assertSession()->elementExists('css', '[data-webform-key="webform_civicrm"] a.tabledrag-handle');
    // Move up to be the top-most handler.
    // $this->sendKeyPress($civicrm_handler, 38);
    $this->getSession()->getPage()->pressButton('Save handlers');
    $this->assertSession()->assertWaitOnAjaxRequest();

    $this->drupalGet($this->webform->toUrl('canonical', ['query' => ['activity1' => $actID1, 'activity2' => $actID2]]));
    $this->getSession()->getPage()->fillField('First Name', 'Frederick');
    $this->getSession()->getPage()->fillField('Last Name', 'Pabst');
    $this->getSession()->getPage()->fillField('Email', 'frederick@pabst.io');

    $countryID = $this->utils->wf_civicrm_api4('Country', 'get', [
      'where' => [
        ['name', '=', 'United States'],
      ],
    ], 0)['id'];
    $stateProvinceID = $this->utils->wf_civicrm_api4('StateProvince', 'get', [
      'where' => [
        ['abbreviation', '=', 'NJ'],
        ['country_id', '=', $countryID],
      ],
    ], 0)['id'];
    $this->getSession()->getPage()->fillField('Street Address', '123 Milwaukee Ave');
    $this->getSession()->getPage()->fillField('City', 'Milwaukee');
    $this->getSession()->getPage()->fillField('Postal Code', '53177');
    $this->getSession()->getPage()->selectFieldOption('Country', $countryID);
    $this->getSession()->wait(1000);
    $this->getSession()->getPage()->selectFieldOption('State/Province', $stateProvinceID);

    $this->getSession()->getPage()->pressButton('Submit');
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');
    $sent_email = $this->getMails();

    $cidURL = Url::fromUri('internal:/civicrm/contact/view', [
      'absolute' => TRUE,
      'query' => ['reset' => 1, 'cid' => $this->rootUserCid]
    ])->toString();
    // Check if email was sent to contact 1.
    $this->assertStringContainsString('frederick@pabst.io', $sent_email[0]['to']);

    // Something new in 10.3
    $weirdoExtraSpaces = version_compare(\Drupal::VERSION, '10.3.2', '>=') ? '  ' : '';
    // And now there is no longer a newline
    $weirdoNewline = version_compare(\Drupal::VERSION, '10.3.2', '<') ? "\n" : '';

    // Verify tokens are rendered correctly.
    // We ignore newlines so that the length of the website's URL (appearing in
    // $this->cidURL) doesn't cause a failure due to variations in line
    // wrapping.
    $this->assertEquals(strtr("Submitted Values Are -

-------- Contact 1 {$weirdoNewline}-----------------------------------------------------------

*Existing Contact*
Frederick Pabst
*First Name*
Frederick
*Last Name*
Pabst
*Street Address*
123 Milwaukee Ave
*City*
Milwaukee
*Postal Code*
53177
*Country*
United States
*State/Province*
New Jersey
*Email*
frederick@pabst.io [1]
Existing Contact - Frederick Pabst. Activity 1 ID - {$actID1}. Activity 2 ID - {$actID2}.{$weirdoExtraSpaces}
Webform CiviCRM Contacts IDs - {$this->rootUserCid}. Webform CiviCRM Contacts Links -{$weirdoExtraSpaces}
{$cidURL} Country - United{$weirdoExtraSpaces}
States. State/Province - New Jersey.

[1] mailto:frederick@pabst.io
", "\n", ' '), strtr($sent_email[0]['body'], "\n", ' '));
  }

  /**
   *  Define test-contact parameters and create a subset of them in Civi.
   *
   *  @return array
   *    contains parameter arrays for each test-contact
   */
  private function addcontactinfo2() {
    $contact = [
      0 => [ // cid = 3 (will overwrite existing contact)
        'contact_id' => 3,
        'first_name' => 'Jimmy',
        'last_name' => 'Page',
        'job_title' => "Guitarist",
        'contact_type' => 'Individual'
      ],
      1 => [ // cid = 4
        'first_name' => 'Robert',
        'last_name' => 'Plant',
        'job_title' => "Vocalist",
        'contact_type' => 'Individual'
      ],
      2 => [ // cid = 5
        'first_name' => 'John Paul',
        'last_name' => 'Jones',
        'job_title' => "Bassist",
        'contact_type' => 'Individual'
      ],
      3 => [ // cid = 6
        'first_name' => 'John',
        'last_name' => 'Bonham',
        'job_title' => "Drummer",
        'contact_type' => 'Individual'
      ],
      4 => [ // cid = 7
        'first_name' => 'Janis',
        'last_name' => 'Joplin',
        'job_title' => "Singer",
        'contact_type' => 'Individual'
      ],
      5 => [ // not initiallly created
        'first_name' => 'Marvin',
        'last_name' => 'Gaye',
        'job_title' => "Vocals",
        'contact_type' => 'Individual'
      ],
      6 => [ // not initiallly created
        'first_name' => 'Bob',
        'last_name' => 'Dylan',
        'job_title' => "Vocals, Harmonica",
        'contact_type' => 'Individual'
      ],
      7 => [ // null contact, not initiallly created
        'first_name' => '',
        'last_name' => '',
        'job_title' => '',
        'contact_type' => 'Individual'
      ],
      8 => [ // cid = 8
        'first_name' => 'Prince',
        'last_name' => '',
        'job_title' => "Guitar, vocals",
        'contact_type' => 'Individual'
      ],
      9 => [ // cid = 9
        'first_name' => 'Madona',
        'last_name' => '',
        'job_title' => "Vocals, drummer",
        'contact_type' => 'Individual'
      ],
    ];
    $utils = \Drupal::service('webform_civicrm.utils');
    foreach ($contact as $key => $c) {
      if (in_array($key, [0, 1, 2, 3, 4, 8, 9])) {
        $result = $utils->wf_civicrm_api('Contact', 'create', $c);
        $this->assertEquals(0, $result['is_error']);
        $this->assertEquals(1, $result['count']);
      }
    }
    return $contact;
  }

  /**
   * Sets the contact fields used by testNextPrevSaveLoad()
   *
   * @param array $contact
   *   contact parameters to be set
   */
  private function setContactFields($contact) {
    $this->getSession()->getPage()->fillField('First Name', $contact['first_name']);
    $this->getSession()->getPage()->fillField('Last Name',  $contact['last_name']);
    $this->getSession()->getPage()->fillField('Job Title',  $contact['job_title']);
  }

  /**
   * Checks the contact fields used by testNextPrevSaveLoad()
   *
   * @param array $contact
   *   contact parameters to be checked
   */
  private function checkContactFields($contact) {
    $this->assertSession()->fieldValueEquals('First Name', $contact['first_name']);
    $this->assertSession()->fieldValueEquals('Last Name',  $contact['last_name']);
    $this->assertSession()->fieldValueEquals('Job Title',  $contact['job_title']);
  }

  /**
  * Test locked/unlocked and blank/filled fields during Next/Previous/Save Draft/Load Draft/Submit operations
  */
  public function testNextPrevSaveLoad() {
    if (version_compare(\Drupal::VERSION, '10.3', '>=')) {
      $this->markTestSkipped('retrieving $elements gives blank in 10.3 for some reason');
      return;
    }

    $contact = $this->addcontactinfo2();

    $this->drupalLogin($this->rootUser);

    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    $this->enableCivicrmOnWebform();

    // Enable 3 contacts each with first name, last name, job title
    $this->getSession()->getPage()->selectFieldOption("number_of_contacts", 3);
    foreach ([1, 2, 3] as $c) {
      $this->getSession()->getPage()->clickLink("Contact {$c}");
      $this->getSession()->getPage()->checkField("civicrm_{$c}_contact_1_contact_existing");
      $this->assertSession()->checkboxChecked("civicrm_{$c}_contact_1_contact_existing");
      $this->getSession()->getPage()->checkField("civicrm_{$c}_contact_1_contact_job_title");
      $this->assertSession()->checkboxChecked("civicrm_{$c}_contact_1_contact_job_title");
    }

    $this->saveCiviCRMSettings();

    $this->drupalGet($this->webform->toUrl('edit-form'));

    // Edit contact element 1.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-1-contact-1-contact-existing-operations',
      'title' => 'Contact 1',
      'widget' => 'Select List',
      'hide_fields' => 'Name',
      'hide_method' => 'Disabled',
      'no_hide_blank' => TRUE,
      'submit_disabled' => TRUE,
      'default' => 'Specified Contact',
      'default_contact_id' => 3
    ];
    $this->editContactElement($editContact);

    // Edit contact element 2.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-2-contact-1-contact-existing-operations',
      'title' => 'Contact 2',
      'widget' => 'Select List',
      'hide_fields' => 'Name',
      'hide_method' => 'Disabled',
      'no_hide_blank' => TRUE,
      'submit_disabled' => TRUE,
      'default' => 'None',
      //'default_contact_id' => 4
    ];
    $this->editContactElement($editContact);

    // Edit contact element 3.
    $editContact = [
      'selector' => 'edit-webform-ui-elements-civicrm-3-contact-1-contact-existing-operations',
      'title' => 'Contact 3',
      'widget' => 'Select List',
      'hide_fields' => 'Name',
      'hide_method' => 'Disabled',
      'no_hide_blank' => TRUE,
      'submit_disabled' => TRUE,
      'default' => 'Specified Contact',
      'default_contact_id' => 5
    ];
    $this->editContactElement($editContact);

    // Make first/last name required for all contacts
    $this->getSession()->getPage()->checkField("webform_ui_elements[civicrm_1_contact_1_contact_first_name][required]");
    $this->getSession()->getPage()->checkField("webform_ui_elements[civicrm_2_contact_1_contact_first_name][required]");
    $this->getSession()->getPage()->checkField("webform_ui_elements[civicrm_3_contact_1_contact_first_name][required]");
    $this->getSession()->getPage()->checkField("webform_ui_elements[civicrm_1_contact_1_contact_last_name][required]");
    $this->getSession()->getPage()->checkField("webform_ui_elements[civicrm_2_contact_1_contact_last_name][required]");
    $this->getSession()->getPage()->checkField("webform_ui_elements[civicrm_3_contact_1_contact_last_name][required]");
    $this->getSession()->getPage()->pressButton('Save elements');
    $this->assertSession()->assertWaitOnAjaxRequest();

    $this->drupalGet($this->webform->toUrl('edit-form'));
    $this->htmlOutput();

    // Place fields for each contact on their own page and enable saving drafts
    $webform =  Webform::load($this->webform->getOriginalId());
    $elements = Yaml::decode($webform->get('elements'));
    $elements_new = [
      'page1' => ['#type' => 'webform_wizard_page', '#title' => 'Page 1', 'civicrm_1_contact_1_fieldset_fieldset' => $elements["civicrm_1_contact_1_fieldset_fieldset"]],
      'page2' => ['#type' => 'webform_wizard_page', '#title' => 'Page 2', 'civicrm_2_contact_1_fieldset_fieldset' => $elements["civicrm_2_contact_1_fieldset_fieldset"]],
      'page3' => ['#type' => 'webform_wizard_page', '#title' => 'Page 3', 'civicrm_3_contact_1_fieldset_fieldset' => $elements["civicrm_3_contact_1_fieldset_fieldset"]],
    ];
    $webform->set('elements', Yaml::encode($elements_new));
    $webform->setSetting('draft', 'all');
    $webform->save();

    $this->drupalGet($this->webform->toUrl('edit-form'));
    $this->htmlOutput();

    $this->drupalGet($this->webform->toUrl('canonical'));

    $this->assertPageNoErrorMessages();
    $this->htmlOutput();


    //** Setup complete Begin tests. **
    // "{Contacts: x, y, z}" below refers to the current form contents (three elements of $contacts[] array)

    // Page 1 {Contacts: 0, none, 2}: Check initial values.
    $this->checkContactFields($contact[0]);

    // Confirm first name is disabled
    $field_disabled = $this->getSession()->evaluateScript("document.getElementById('edit-civicrm-1-contact-1-contact-first-name').disabled");
    $this->assertEquals(true, $field_disabled, 'First name is disabled');
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 0, none, 2}: Check initial values.
    $this->checkContactFields($contact[7]); // 7 is the blank contact

    // Page 2 {Contacts: 0, none, 2}: Confirm that locked blank fields can be modified
    $this->getSession()->getPage()->fillField('First Name', 'FIRST');
    $this->assertSession()->fieldValueEquals('First Name', 'FIRST');

    // Page 2 {Contacts: 0, none, 2}: Select $contact[1].
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[1]['first_name']} {$contact[1]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[1]);

    // Page 2 {Contacts: 0, 1, 2}: Test that locked nonblank fields are disabled.
    $field_disabled = $this->getSession()->evaluateScript("document.getElementById('edit-civicrm-2-contact-1-contact-first-name').disabled");
    $this->assertEquals(true, $field_disabled, 'First name is disabled');
    $this->getSession()->getPage()->pressButton('Next >');
    return; // @TODO: Additional parts of this test will be enabled in susbequent PRs
    $this->assertPageNoErrorMessages();

    // Page 3 {Contacts: 0, 1, 2}: Check initial values.
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 2 {Contacts: 0, 1, 2}: Check entered contact data ($contact[1]).
    $this->checkContactFields($contact[1]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 0, 1, 2}: check initial values.
    $this->checkContactFields($contact[0]);

    // Page 1 {Contacts: 0, 1, 2}: Select $contact[3]
    $this->getSession()->getPage()->selectFieldOption('civicrm_1_contact_1_contact_existing', "{$contact[3]['first_name']} {$contact[3]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 3, 1, 2}: Check still has $contact[1]
    $this->checkContactFields($contact[1]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1: {Contacts: 3, 1, 2}: Check still has $contact[3]
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 3, 1, 2}: Check still has $contact[1]
    $this->checkContactFields($contact[1]);

    // Page 2 {Contacts: 3, 1, 2}: Create a new contact ($contact[4])
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "+ Create new +");
    $this->setContactFields($contact[4]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 3, 4, 2}: check still has $contact[3]
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 3, 4, 2}: Check still has $contact[4]
    $this->checkContactFields($contact[4]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 3, 4, 2}: Check initial state
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 2 {Contacts: 3, 4, 2}: check still has $contact[4]
    $this->checkContactFields($contact[4]);

    // Page 2 {Contacts: 3, 4, 2}: Create a new contact ($contact[5])
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "+ Create new +");
    $this->setContactFields($contact[5]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 3, 5, 2}: Check initial state
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 2 {Contacts: 3, 5, 2}: check still has $contact[5]
    $this->checkContactFields($contact[5]);

    // Page 2 {Contacts: 3, 5, 2}: Create a new contact ($contact[6])
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "+ Create new +");
    $this->setContactFields($contact[6]);

    // Page 2 {Contacts: 3, 6, 2}: Save draft
    $this->getSession()->getPage()->pressButton('Save Draft');
    $this->assertSession()->pageTextContains('Submission saved. You may return to this form later and it will restore the current values.');

    // Page 2 {Contacts: 3, 6, 2}: Reload form, check still has $contact[6]
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertSession()->pageTextContains('A partially-completed form was found. Please complete the remaining portions.');
    $this->checkContactFields($contact[6]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 3, 6, 2}: Check still has $contact[3]
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 3, 6, 2}: Check still has $contact[6]
    $this->checkContactFields($contact[6]);


    //*** Test sequence: modify, prev, save draft, load, next, next, ***
    // Page 2 {Contacts: 3, 6, 2}: Select $contact[1]
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[1]['first_name']} {$contact[1]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[1]);

    // Page 2 {Contacts: 3, 6, 2}: Modify the job field
    $contact['1m'] = $contact[1];
    $contact['1m']['job_title'] = 'MODIFIED JOB TITLE 1';
    $this->getSession()->getPage()->fillField('Job Title', $contact['1m']['job_title']);
    $this->getSession()->getPage()->pressButton('< Prev');
    $this->checkContactFields($contact[3]);

    // Page 1 {Contacts: 3, 1m, 2}: Save/load the draft
    $this->getSession()->getPage()->pressButton('Save Draft');
    $this->assertSession()->pageTextContains('Submission saved. You may return to this form later and it will restore the current values.');
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertSession()->pageTextContains('A partially-completed form was found. Please complete the remaining portions.');

    // Page 1 {Contacts: 3, 1m, 2}: Confirm contact
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 3, 1m, 2}: Confirm modified contact
    $this->checkContactFields($contact['1m']);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 3, 1m, 2}: Confirm the job is still modified
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 2 {Contacts: 3, 1m, 2}: Confirm the contact
    $this->checkContactFields($contact['1m']);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 3, 1m, 2}: Confirm the contact
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');


    //*** Test sequence: modify, next, save, load draft, prev, prev, next, next  ***
    // Page 2 {Contacts: 3, 6, 2}: Select $contact[1] (must first select a different $contact)
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[0]['first_name']} {$contact[0]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[1]['first_name']} {$contact[1]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[1]);

    // Page 2 {Contacts: 3, 6, 2}: Modify the job field
    $contact['1m'] = $contact[1];
    $contact['1m']['job_title'] = 'MODIFIED JOB TITLE 1A';
    $this->getSession()->getPage()->fillField('Job Title', $contact['1m']['job_title']);
    $this->getSession()->getPage()->pressButton('Next >');
    $this->checkContactFields($contact[2]);

    // Page 3 {Contacts: 3, 1m, 2}: Save/load the draft
    $this->getSession()->getPage()->pressButton('Save Draft');
    $this->assertSession()->pageTextContains('Submission saved. You may return to this form later and it will restore the current values.');
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertSession()->pageTextContains('A partially-completed form was found. Please complete the remaining portions.');

    // Page 3 {Contacts: 3, 1m, 2}: Confirm contact
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 2 {Contacts: 3, 1m, 2}: Confirm modified contact
    $this->checkContactFields($contact['1m']);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 3, 1m, 2}: Confirm the job is still modified
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 3, 1m, 2}: Confirm the contact
    $this->checkContactFields($contact['1m']);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 3, 1m, 2}: Confirm the job is still modified
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');


    // Page 2 {Contacts: 3, 6, 2}: Select $contact[4]
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[4]['first_name']} {$contact[4]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[4]);

    // Page 2 {Contacts: 3, 4, 2}: Save draft
    $this->getSession()->getPage()->pressButton('Save Draft');
    $this->assertSession()->pageTextContains('Submission saved. You may return to this form later and it will restore the current values.');

    // Page 2 {Contacts: 3, 4, 2}: Reload form, check still has $contact[4]
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertSession()->pageTextContains('A partially-completed form was found. Please complete the remaining portions.');
    $this->checkContactFields($contact[4]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 3, 4, 2}: Check initial state
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 2  {Contacts: 3, 4, 2}: Check still has $contact[4]
    $this->checkContactFields($contact[4]);

    // Page 2 {Contacts: 3, 4, 2}: Create a new contact ($contact[5])
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "+ Create new +");
    $this->setContactFields($contact[5]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 3, 5, 2}: Check initial state
    $this->checkContactFields($contact[2]);

    // Page 3  {Contacts: 3, 5, 2}: create a new contact ($contact[6])
    $this->getSession()->getPage()->selectFieldOption('civicrm_3_contact_1_contact_existing', "+ Create new +");
    $this->setContactFields($contact[6]);

    // Page 3  {Contacts: 3, 5, 6}: Submit
    $this->getSession()->getPage()->pressButton('Submit');
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');

    // Confirm existing $contact[3] is unchanged, and $contact[5,6] have been created in Civi
    foreach ([3,5,6] as $key) {
      $result = $this->utils->wf_civicrm_api('Contact', 'get', [
        'first_name' => $contact[$key]['first_name'],
        'last_name' => $contact[$key]['last_name'],
        'job_title' => $contact[$key]['job_title'],
      ]);
      $this->assertEquals(0, $result['is_error']);
      $this->assertEquals(1, $result['count']);
    }


    //*** Check handling of existing contact with blank required field ***
    $this->drupalGet($this->webform->toUrl('canonical'));

    // Page 1 {Contacts: 0, none, 2}: Check initial values.
    $this->assertSession()->pageTextContains('You have already submitted this webform. View your previous submission.');
    $this->checkContactFields($contact[0]);

    // Page 1 {Contacts: 0, none, 2}: Select $contact[8] (no last name)
    $this->getSession()->getPage()->selectFieldOption('civicrm_1_contact_1_contact_existing', "{$contact[8]['first_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[8]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 1 {Contacts: 8, none, 2}: Still on Page 1 because Last Name is blank and required
    $this->checkContactFields($contact[8]);
    $field_valid = $this->getSession()->evaluateScript("document.getElementById('edit-civicrm-1-contact-1-contact-last-name').reportValidity()");
    $this->assertEquals(false, $field_valid, 'Last Name field is not invalid.');

    $contact['8m'] = $contact[8];
    $contact['8m']['last_name'] = 'CONTACT 8 LAST NAME';
    $this->getSession()->getPage()->fillField('Last Name', $contact['8m']['last_name']);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 8m, none, 2}: Check $contact[7] (null contact)
    $this->checkContactFields($contact[7]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 8m, none, 2}: Check $contact[8m]
    $this->checkContactFields($contact['8m']);


    //*** Check Draft Save/Load with blank required field ***
    $this->drupalGet($this->webform->toUrl('canonical'));

    // Page 1 {Contacts: 0, none, 2}: Check initial values.
    $this->assertSession()->pageTextContains('You have already submitted this webform. View your previous submission.');
    $this->checkContactFields($contact[0]);

    // Page 1 {Contacts: 0, none, 2}: Select $contact[8] (no last name)
    $this->getSession()->getPage()->selectFieldOption('civicrm_1_contact_1_contact_existing', "{$contact[8]['first_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[8]);
    $this->getSession()->getPage()->pressButton('Save Draft');
    $this->assertSession()->pageTextContains('Submission saved. You may return to this form later and it will restore the current values.');

    // Page 1 {Contacts: 8, none, 2}: Reload form, check still has $contact[8]
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertSession()->pageTextContains('A partially-completed form was found. Please complete the remaining portions.');
    $this->checkContactFields($contact[8]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 1 {Contacts: 8, none, 2}: Still on Page 1 because Last Name is blank and required
    $this->checkContactFields($contact[8]);
    $field_valid = $this->getSession()->evaluateScript("document.getElementById('edit-civicrm-1-contact-1-contact-last-name').reportValidity()");
    $this->assertEquals(false, $field_valid, 'Last Name field is not invalid.');

    // Page 1 {Contacts: 8, none, 2}: Add last name to $contact[8]
    $contact['8m'] = $contact[8];
    $contact['8m']['last_name'] = 'CONTACT 8 LAST NAME';
    $this->getSession()->getPage()->fillField('Last Name', $contact['8m']['last_name']);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 8m, none, 2}: Check $contact[7] (null contact)
    $this->checkContactFields($contact[7]);
    $this->getSession()->getPage()->pressButton('< Prev');

    // Page 1 {Contacts: 8m, none, 2}: Check $contact[8m]
    $this->checkContactFields($contact['8m']);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 8m, none, 2}: Check $contact[7] (null contact)
    $this->checkContactFields($contact[7]);

    // Page 2 {Contacts: 8m, none, 2}: Select $contact[5]
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[5]['first_name']} {$contact[5]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 8m, 5, 2}: Check initial state
    $this->checkContactFields($contact[2]);

    // Page 3 {Contacts: 8m, 5, 2}: Select $contact[9] and submit
    $this->getSession()->getPage()->selectFieldOption('civicrm_3_contact_1_contact_existing', "{$contact[9]['first_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact['9']);
    $this->getSession()->getPage()->pressButton('Submit');

    // Page 3 {Contacts: 8m, 5, 9}: Still on Page 3 because Last Name is blank and required
    $this->checkContactFields($contact['9']);
    $field_valid = $this->getSession()->evaluateScript("document.getElementById('edit-civicrm-3-contact-1-contact-last-name').reportValidity()");
    $this->assertEquals(false, $field_valid, 'Last Name field is not invalid.');

    // Page 3 {Contacts: 8m, 5, 9}: Add last name and submit
    $contact['9m'] = $contact[9];
    $contact['9m']['last_name'] = 'CONTACT 9 LAST NAME';
    $this->getSession()->getPage()->fillField('Last Name', $contact['9m']['last_name']);
    $this->getSession()->getPage()->pressButton('Submit');
    $this->htmlOutput();

    // Page 3 {Contacts: 8m, 5, 9m}: Confirm submit OK
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');

    // Confirm existing $contact[5] is unchanged, and $contact[8,9] now have a last name.
    foreach (['8m', 5, '9m'] as $key) {
      $result = $this->utils->wf_civicrm_api('Contact', 'get', [
        'first_name' => $contact[$key]['first_name'],
        'last_name' => $contact[$key]['last_name'],
        'job_title' => $contact[$key]['job_title'],
      ]);
      $this->assertEquals(0, $result['is_error']);
      $this->assertEquals(1, $result['count']);
    }


    //*** Check Draft Save/Load, change selected contact, Submit ***
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertPageNoErrorMessages();

    // Page 1 {Contacts: 0, none, 2}: Check initial values.
    $this->checkContactFields($contact[0]);
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 2 {Contacts: 0, none, 2}: Check initial values.
    $this->checkContactFields($contact[7]);

    // Page 2 {Contacts: 0, none, 2}: Select $contact[5]
    $this->getSession()->getPage()->selectFieldOption('civicrm_2_contact_1_contact_existing', "{$contact[5]['first_name']} {$contact[5]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->pressButton('Next >');

    // Page 3 {Contacts: 0, 5, 2}: Check initial state, select $contact[3], save draft
    $this->checkContactFields($contact[2]);
    $this->getSession()->getPage()->selectFieldOption('civicrm_3_contact_1_contact_existing', "{$contact[3]['first_name']} {$contact[3]['last_name']}");
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Save Draft');
    $this->checkContactFields($contact[3]);
    $this->assertSession()->pageTextContains('Submission saved. You may return to this form later and it will restore the current values.');
    $this->htmlOutput();

    // Page 3 {Contacts: 0, 5, 3}: Reload form, check still has $contact[3] and submit
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertSession()->pageTextContains('A partially-completed form was found. Please complete the remaining portions.');
    $this->checkContactFields($contact[3]);
    $this->getSession()->getPage()->pressButton('Submit');
    $this->assertPageNoErrorMessages();
    $this->assertSession()->pageTextContains('New submission added to CiviCRM Webform Test.');

    $submission = WebformSubmission::load($this->getLastSubmissionId($this->webform));
    $sub_data = $submission->getData();
    $this->assertEquals($contact[3]['first_name'], $sub_data['civicrm_3_contact_1_contact_first_name'], 'Submission first name');
    $this->assertEquals($contact[3]['last_name'], $sub_data['civicrm_3_contact_1_contact_last_name'], 'Submission last name');
    $this->assertEquals($contact[3]['job_title'], $sub_data['civicrm_3_contact_1_contact_job_title'], 'Submission job title name');
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc