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

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

namespace Drupal\Tests\webform_civicrm\FunctionalJavascript;

use Civi\Api4\Contribution;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Url;

/**
 * Tests submitting a Webform with CiviCRM: Contribution with Pay later
 *
 * @group webform_civicrm
 */
final class ContributionPayLaterTest extends WebformCivicrmTestBase {

  private $_customGroup = [];
  private $_customFields = [];

  /**
   * @var string
   */
  private $country;

  /**
   * @var string
   */
  private $state;

  public function testReceiptParams() {
    $this->drupalLogin($this->rootUser);
    $this->redirectEmailsToDB();
    $this->setOrgInfo();

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

    $params = [
      'payment_processor_id' => 'Pay Later',
      'financial_type_id' => 'create_civicrm_webform_element',
      'receipt' => [
        'receipt_from_name' => 'Admin',
        'receipt_from_email' => 'admin@example.com',
        'pay_later_receipt' => 'Payment by Direct Credit to: ABC. Please quote invoice number and name.',
        'receipt_text' => 'Thank you for your contribution.',
      ],
    ];
    $this->configureContributionTab($params);
    $this->getSession()->getPage()->selectFieldOption('Enable Billing Address?', 'No');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->checkField('Contribution Amount');
    $this->getSession()->getPage()->checkField('Contribution Receive Date');

    $this->saveCiviCRMSettings();

    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertPageNoErrorMessages();
    $this->getSession()->getPage()->fillField('First Name', 'Frederick');
    $this->getSession()->getPage()->fillField('Last Name', 'Pabst');
    $this->getSession()->getPage()->fillField('Email', 'fred@example.com');

    $this->getSession()->getPage()->pressButton('Next >');
    $this->assertPageNoErrorMessages();
    $this->getSession()->getPage()->fillField('Contribution Amount', '30');

    $futureReceiveDate = new DrupalDateTime('+1 month');
    $this->getSession()->getPage()->fillField('civicrm_1_contribution_1_contribution_receive_date[date]', $futureReceiveDate->format('m-d-Y'));
    $this->getSession()->getPage()->fillField('civicrm_1_contribution_1_contribution_receive_date[time]', '07:15:00');

    $this->assertSession()->elementExists('css', '#wf-crm-billing-items');
    $this->htmlOutput();
    $this->assertSession()->elementTextContains('css', '#wf-crm-billing-total', '30.00');
    $this->getSession()->getPage()->selectFieldOption('civicrm_1_contribution_1_contribution_financial_type_id', 2);

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

    $contribution = Contribution::get()
      ->addSelect('source', 'total_amount', 'contribution_status_id:label', 'currency', 'financial_type_id:label', 'receive_date')
      ->setLimit(1)
      ->execute()
      ->first();
    $this->assertEquals('30.00', $contribution['total_amount']);
    $this->assertEquals('Pending', $contribution['contribution_status_id:label']);
    $this->assertEquals('Member Dues', $contribution['financial_type_id:label']);
    $this->assertEquals('USD', $contribution['currency']);
    $verifyDate = $futureReceiveDate->format('Y-m-d');
    $contributionDate = date('Y-m-d', strtotime($contribution['receive_date']));
    $this->assertEquals("{$verifyDate} 07:15:00", "{$contributionDate} 07:15:00");

    $sent_email = $this->getMostRecentEmail();
    $this->assertStringContainsString('From: Admin <admin@example.com>', $sent_email);
    $this->assertStringContainsString('To: Frederick Pabst <fred@example.com>', $sent_email);
    $this->assertStringContainsString('Payment by Direct Credit to: ABC. Please quote invoice number and name.', $sent_email);
    $this->assertStringContainsString('Thank you for your contribution', $sent_email);

    // "Hack" for versions before 5.54 - it doesn't pick up the setting we set earlier.
    if (version_compare(\CRM_Core_BAO_Domain::version(), '5.54.alpha1', '<')) {
      $mb = \Civi::settings()->get('mailing_backend');
      $mb['outBound_option'] = \CRM_Mailing_Config::OUTBOUND_OPTION_REDIRECT_TO_DB;
      \Civi::settings()->set('mailing_backend', $mb);
    }

    // Complete the contribution and recheck receipt.
    civicrm_api3('Contribution', 'completetransaction', [
      'id' => $contribution['id'],
      'is_email_receipt' => 1,
    ]);
    $sent_email = $this->getMostRecentEmail();
    $this->assertStringContainsString('From: Pay Laterers <pay.later@example.org>', $sent_email);
    $this->assertStringContainsString('To: Frederick Pabst <fred@example.com>', $sent_email);
    // Adjust for fix in core - since status is now completed, it shouldn't say invoice.
    if (version_compare(\CRM_Core_BAO_Domain::version(), '5.63.alpha1', '<')) {
      $this->assertStringContainsString('Subject: Invoice - Contribution - Frederick Pabst', $sent_email);
    }
    else {
      $this->assertStringContainsString('Subject: Receipt - Contribution - Frederick Pabst', $sent_email);
    }
  }

  public function testSubmitContribution() {
    $this->createFinancialCustomGroup();
    $this->createFinancialCustomGroup('Donation');
    $this->createFinancialCustomGroup('Member Dues');

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

    // 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');

    $params = [
      'payment_processor_id' => 'Pay Later',
    ];
    $this->configureContributionTab($params);
    $this->getSession()->getPage()->checkField('Contribution Amount');

    // Change financial type to Member Dues and confirm if its custom field is loaded.
    $this->getSession()->getPage()->selectFieldOption('Financial Type', 'Member Dues');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->verifyFTCustomSet('Member Dues');

    $this->getSession()->getPage()->selectFieldOption('Financial Type', 'Donation');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->verifyFTCustomSet('Donation');
    $this->getSession()->getPage()->checkField($this->_customFields['Donation']['label']);

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

    $this->country = 'United Kingdom';
    $this->state = 'Newport';
    // Change widget of Amount element to checkbox.
    $this->changeTypeOfAmountElement('checkboxes', TRUE);
    $this->submitWebform('checkboxes');
    $this->verifyResult();

    // Change widget of Amount element to radios.
    $this->changeTypeOfAmountElement('radios');
    $this->submitWebform('radios');
    $this->verifyResult();

    $this->country = 'Malaysia';
    $this->state = 'Selangor';
    // Change widget of Amount element to radio + other.
    $this->changeTypeOfAmountElement('webform-radios-other');
    $this->submitWebform('webform_radios_other');
    $this->verifyResult();
  }

  /**
   * Submit the form
   *
   * @param string $amountType
   */
  protected function submitWebform($amountType) {
    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertPageNoErrorMessages();
    $this->getSession()->getPage()->fillField('First Name', 'Frederick');
    $this->getSession()->getPage()->fillField('Last Name', 'Pabst');
    $this->getSession()->getPage()->fillField('Email', 'fred@example.com');
    $this->getSession()->getPage()->selectFieldOption("Country", $this->country);
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->selectFieldOption('State/Province', $this->state);

    $this->getSession()->getPage()->pressButton('Next >');
    $this->assertSession()->waitForField('civicrm_1_contribution_1_contribution_total_amount');
    $this->assertPageNoErrorMessages();

    if ($amountType == 'radios') {
      $this->getSession()->getPage()->selectFieldOption("civicrm_1_contribution_1_contribution_total_amount", 30);
    }
    elseif ($amountType == 'webform_radios_other') {
      $this->getSession()->getPage()->selectFieldOption("civicrm_1_contribution_1_contribution_total_amount[radios]", '_other_');
      $this->assertSession()->waitForField('civicrm_1_contribution_1_contribution_total_amount[other]');
      $this->getSession()->getPage()->fillField('civicrm_1_contribution_1_contribution_total_amount[other]', '30');
    }
    else {
      $this->getSession()->getPage()->checkField('10');
      $this->getSession()->getPage()->checkField('20');
    }

    $this->assertSession()->elementExists('css', '#wf-crm-billing-items');
    $this->htmlOutput();
    $this->assertSession()->elementTextContains('css', '#wf-crm-billing-total', '30.00');
    $this->getSession()->getPage()->fillField('Donation Custom Field', 'Donation for xyz');

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

  /**
   * Create custom sets for financial type.
   *
   * @param string $ftName
   */
  public function createFinancialCustomGroup($ftName = NULL) {
    $params = [
      'title' => "{$ftName} Custom Group",
      'extends' => "Contribution",
    ];
    if ($ftName) {
      $ftId = civicrm_api3('FinancialType', 'get', [
        'return' => ["id"],
        'name' => $ftName,
      ])['id'];
      $params['extends_entity_column_value'] = $ftId;
    }
    $key = $ftName ?? 'all';
    $this->_customGroup[$key] = reset($this->createCustomGroup($params)['values']);

    // Add custom field.
    $params = [
      'custom_group_id' => $this->_customGroup[$key]['id'],
      'label' => "{$ftName} Custom Field",
      'data_type' => 'String',
      'html_type' => 'Text',
    ];
    $cf = $this->utils->wf_civicrm_api('CustomField', 'create', $params);
    $this->assertEquals(0, $cf['is_error']);
    $this->assertEquals(1, $cf['count']);
    $this->_customFields[$key] = reset($cf['values']);
  }

  /**
   * Confirm custom sets are loaded as per financial type.
   *
   * @param string $ftName
   */
  public function verifyFTCustomSet($ftName) {
    $this->assertSession()->elementTextContains('css', '[id="civicrm-ajax-contribution-sets-custom"]', $this->_customGroup[$ftName]['title']);
    $this->assertSession()->elementTextContains('css', '[id="civicrm-ajax-contribution-sets-custom"]', $this->_customGroup['all']['title']);
  }

  /**
   * Check submission results.
   */
  private function verifyResult() {
    $cfName = $this->_customGroup['Donation']['name'] . '.' . $this->_customFields['Donation']['name'];
    $contribution = Contribution::get()
      ->addSelect('source', 'total_amount', 'contribution_status_id:label', 'currency', $cfName)
      ->setLimit(1)
      ->execute()
      ->first();

    $this->assertEquals($this->webform->label(), $contribution['source']);
    $this->assertEquals('30.00', $contribution['total_amount']);
    $this->assertEquals('Pending', $contribution['contribution_status_id:label']);
    $this->assertEquals('USD', $contribution['currency']);
    // Check if financial custom field value is pushed to civi.
    $this->assertEquals('Donation for xyz', $contribution[$cfName]);
    $this->utils->wf_civicrm_api('contribution', 'delete', [
      'id' => $contribution['id'],
    ]);

    $address = $this->utils->wf_civicrm_api('Address', 'get', [
      'sequential' => 1,
    ])['values'][0];
    $country = $this->utils->wf_civicrm_api('Country', 'get', [
      'name' => $this->country,
    ]);
    $state = $this->utils->wf_civicrm_api('StateProvince', 'get', [
      'name' => $this->state,
    ]);
    $this->assertEquals($country['id'], $address['country_id']);
    $this->assertEquals($state['id'], $address['state_province_id']);
  }

  /**
   * Change contribution amount widget
   * to radio or checkbox.
   */
  private function changeTypeOfAmountElement($type, $changeTypeToOption = FALSE) {
    $this->drupalGet($this->webform->toUrl('edit-form'));
    $this->assertPageNoErrorMessages();

    if ($type == 'webform-radios-other' && !$changeTypeToOption) {
      $this->editCivicrmOptionElement('edit-webform-ui-elements-civicrm-1-contribution-1-contribution-total-amount-operations', FALSE, FALSE, NULL, 'webform-radios-other');
      return;
    }

    $checkbox_edit_button = $this->assertSession()->elementExists('css', '[data-drupal-selector="edit-webform-ui-elements-civicrm-1-contribution-1-contribution-total-amount-operations"] a.webform-ajax-link');
    $checkbox_edit_button->click();
    $this->assertSession()->waitForField('drupal-off-canvas');
    $this->htmlOutput();

    if ($changeTypeToOption) {
      $this->assertSession()->elementExists('css', '[data-drupal-selector="edit-change-type"]')->click();
      $this->assertSession()->assertWaitOnAjaxRequest();
      $this->assertSession()->waitForElementVisible('css', "[data-drupal-selector='edit-elements-civicrm-options-operation']", 3000)->click();
      $this->assertSession()->waitForElementVisible('css', "[data-drupal-selector='edit-cancel']", 3000);
    }

    $this->getSession()->getPage()->fillField('properties[options][custom][options][items][0][value]', 10);
    $this->getSession()->getPage()->fillField('properties[options][custom][options][items][1][value]', 20);
    $this->getSession()->getPage()->fillField('properties[options][custom][options][items][2][value]', 30);

    if ($type == 'checkboxes') {
      $this->getSession()->getPage()->checkField('properties[extra][multiple]');
    }
    else {
      $this->getSession()->getPage()->uncheckField('properties[extra][multiple]');
    }

    $this->getSession()->getPage()->pressButton('Save');
    $this->assertSession()->waitForText('has been updated.');
  }

  /**
   * Set the info at Administer - Communications - Organization Info
   */
  private function setOrgInfo() {
    // This fails - see https://lab.civicrm.org/dev/drupal/-/issues/133
    // $this->drupalGet(\CRM_Utils_System::url('civicrm/admin/domain', 'action=update&reset=1', TRUE, NULL, FALSE));
    // $this->getSession()->getPage()->fillField('name', 'Pay Laterers');
    // $this->getSession()->getPage()->fillField('email_1_email', 'pay.later@example.org');
    // $this->getSession()->getPage()->pressButton('_qf_Domain_next_view-bottom');

    civicrm_api3('Domain', 'create', ['id' => 1, 'name' => 'Pay Laterers']);
    $option_value = civicrm_api3('OptionValue', 'get', [
      'option_group_id' => 'from_email_address',
      'is_default' => 1,
    ]);
    civicrm_api3('OptionValue', 'create', [
      'id' => $option_value['id'],
      'label' => '"Pay Laterers" <pay.later@example.org>',
    ]);
  }

  /**
   * Test if default value on the civicrm option element
   * is not passed to civicrm on webform submit.
   */
  public function testCivicrmOptionsDefaultSubmission() {
    $this->drupalLogin($this->rootUser);
    $this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
      'webform' => $this->webform->id(),
    ]));
    $this->enableCivicrmOnWebform();
    $this->getSession()->getPage()->checkField('Gender');

    $params = [
      'payment_processor_id' => 'Pay Later',
    ];
    $this->configureContributionTab($params);

    $this->getSession()->getPage()->selectFieldOption('Enable Billing Address?', 'No');
    $this->assertSession()->assertWaitOnAjaxRequest();
    $this->getSession()->getPage()->checkField('Contribution Amount');

    $this->saveCiviCRMSettings();

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

    // Set Male to be the default option.
    $maleID = $this->utils->wf_crm_apivalues('OptionValue', 'get', [
      'sequential' => 1,
      'option_group_id' => "gender",
      'name' => "Male",
    ], 'value')[0] ?? NULL;
    $this->editCivicrmOptionElement('edit-webform-ui-elements-civicrm-1-contact-1-contact-gender-id-operations', FALSE, FALSE, $maleID);

    $this->drupalLogout();

    $this->drupalGet($this->webform->toUrl('canonical'));
    $this->assertPageNoErrorMessages();
    $this->getSession()->getPage()->fillField('First Name', 'Mei');
    $this->getSession()->getPage()->fillField('Last Name', 'Parker');
    $this->getSession()->getPage()->fillField('Email', 'meiparker@example.com');
    $femaleID = $this->utils->wf_crm_apivalues('OptionValue', 'get', [
      'sequential' => 1,
      'option_group_id' => "gender",
      'name' => "Female",
    ], 'value')[0] ?? NULL;
    $this->getSession()->getPage()->selectFieldOption("civicrm_1_contact_1_contact_gender_id", $femaleID);

    $this->getSession()->getPage()->pressButton('Next >');
    $this->assertPageNoErrorMessages();
    $this->getSession()->getPage()->fillField('Contribution Amount', '20');

    $this->assertSession()->elementExists('css', '#wf-crm-billing-items');
    $this->htmlOutput();
    $this->assertSession()->elementTextContains('css', '#wf-crm-billing-total', '20.00');

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

    $contact = $this->utils->wf_crm_apivalues('Contact', 'get', [
      'sequential' => 1,
      'first_name' => "Mei",
      'last_name' => "Parker",
    ])[0] ?? [];
    $this->assertEquals('Female', $contact['gender']);
  }

}

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

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