You are here

public function CustomerProfileTest::testMultipleExisting in Commerce Core 8.2

Tests the address book in "multiple" mode, on an existing profile entity.

File

modules/order/tests/src/FunctionalJavascript/CustomerProfileTest.php, line 255

Class

CustomerProfileTest
Tests the customer_profile inline form.

Namespace

Drupal\Tests\commerce_order\FunctionalJavascript

Code

public function testMultipleExisting() {

  // One-off profile, with no address book profiles available.
  $profile = Profile::create([
    'type' => 'customer',
    'uid' => 0,
    'address' => $this->frenchAddress,
  ]);
  $profile
    ->save();
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->assertSession()
    ->fieldNotExists('select_address');

  // Confirm that the french address is shown rendered.
  $this
    ->assertRenderedAddress($this->frenchAddress);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to edit the profile.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->pressButton('billing_edit');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ($this->frenchAddress as $property => $value) {
    $this
      ->assertSession()
      ->fieldValueEquals("profile[address][0][address][{$property}]", $value);
  }

  // Confirm that since the profile was never copied to the address book,
  // it is still possible to do so.
  $this
    ->assertSession()
    ->checkboxNotChecked('profile[copy_to_address_book]');
  $this
    ->assertSession()
    ->pageTextContains('Save to my address book');
  $this
    ->submitForm([
    'profile[address][0][address][address_line1]' => '37 Rue du Sentier',
  ], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "37 Rue du Sentier" and the country code is FR. Address book: No');

  // Profile that is flagged for copying (simulating edit within checkout).
  $profile
    ->setData('copy_to_address_book', TRUE);
  $profile
    ->save();
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->assertRenderedAddress($this->frenchAddress);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: Yes');

  // Confirm that it is possible to edit the copy checkbox.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->pressButton('billing_edit');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $this
    ->assertSession()
    ->checkboxChecked('profile[copy_to_address_book]');
  $this
    ->assertSession()
    ->pageTextContains('Save to my address book');
  $this
    ->submitForm([
    'profile[copy_to_address_book]' => FALSE,
  ], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');
  $us_profile = Profile::create([
    'type' => 'customer',
    'uid' => $this->adminUser
      ->id(),
    'address' => $this->usAddress,
  ]);
  $us_profile
    ->save();
  sleep(1);
  $french_profile = Profile::create([
    'type' => 'customer',
    'uid' => $this->adminUser
      ->id(),
    'address' => $this->frenchAddress,
  ]);
  $french_profile
    ->save();

  // Populated from the French profile, which is still identical.
  $profile = Profile::create([
    'type' => 'customer',
    'uid' => 0,
    'address' => $this->frenchAddress,
  ]);
  $profile
    ->populateFromProfile($french_profile);
  $profile
    ->setData('address_book_profile_id', $french_profile
    ->id());
  $profile
    ->save();
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());

  // Confirm that there is no _original option, since the profile still
  // matches the address book profile.
  $options = $this
    ->xpath('//select[@name="profile[select_address]"]/option');
  $this
    ->assertCount(3, $options);
  $this
    ->assertEquals($this->usAddress['address_line1'], $options[0]
    ->getText());
  $this
    ->assertEquals($this->frenchAddress['address_line1'], $options[1]
    ->getText());
  $this
    ->assertEquals('+ Enter a new address', $options[2]
    ->getText());

  // Confirm that the address book profile is selected.
  $this
    ->assertNotEmpty($options[1]
    ->getAttribute('selected'));
  $this
    ->assertRenderedAddress($this->frenchAddress);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to edit the profile.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->pressButton('billing_edit');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ($this->frenchAddress as $property => $value) {
    $this
      ->assertSession()
      ->fieldValueEquals("profile[address][0][address][{$property}]", $value);
  }
  $this
    ->assertSession()
    ->fieldNotExists('profile[copy_to_address_book]');
  $this
    ->submitForm([
    'profile[address][0][address][address_line1]' => '37 Rue du Sentier',
  ], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "37 Rue du Sentier" and the country code is FR. Address book: Yes');

  // Populated from the French profile, which has changed since, and has
  // a different street address.
  $profile = Profile::create([
    'type' => 'customer',
    'uid' => 0,
    'address' => $this->frenchAddress,
  ]);
  $profile
    ->setData('address_book_profile_id', $french_profile
    ->id());
  $profile
    ->save();
  $new_french_address = [
    'country_code' => 'FR',
    'locality' => 'Paris',
    'postal_code' => '75002',
    'address_line1' => '39 Rue du Sentier',
    'given_name' => 'Leon',
    'family_name' => 'Blum',
  ];
  $french_profile
    ->set('address', $new_french_address);
  $french_profile
    ->save();
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());

  // Confirm that the _original option is present and selected.
  $options = $this
    ->xpath('//select[@name="profile[select_address]"]/option');
  $this
    ->assertCount(4, $options);
  $this
    ->assertEquals($this->usAddress['address_line1'], $options[0]
    ->getText());
  $this
    ->assertEquals($new_french_address['address_line1'], $options[1]
    ->getText());
  $this
    ->assertEquals($this->frenchAddress['address_line1'], $options[2]
    ->getText());
  $this
    ->assertEquals('+ Enter a new address', $options[3]
    ->getText());
  $this
    ->assertNotEmpty($options[2]
    ->getAttribute('selected'));
  $this
    ->assertEquals('_original', $options[2]
    ->getValue());
  $this
    ->assertRenderedAddress($this->frenchAddress);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to switch to a different profile.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->fillField('profile[select_address]', $french_profile
    ->id());
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $this
    ->assertRenderedAddress($new_french_address);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "39 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to switch to a different profile, and back.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->fillField('profile[select_address]', $french_profile
    ->id());
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $this
    ->assertRenderedAddress($new_french_address);
  $this
    ->getSession()
    ->getPage()
    ->fillField('profile[select_address]', '_original');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $this
    ->assertRenderedAddress($this->frenchAddress);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to edit the profile.
  // Editing the profile should not result in an address book copy, since
  // the source address book profile is now out of sync.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->pressButton('billing_edit');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ($this->frenchAddress as $property => $value) {
    $this
      ->assertSession()
      ->fieldValueEquals("profile[address][0][address][{$property}]", $value);
  }
  $this
    ->assertSession()
    ->fieldNotExists('profile[copy_to_address_book]');
  $this
    ->submitForm([
    'profile[address][0][address][address_line1]' => '37 Rue du Sentier',
  ], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "37 Rue du Sentier" and the country code is FR. Address book: No');

  // Populated from the French profile, which has changed since, but has
  // the same street address / label.
  $profile = Profile::create([
    'type' => 'customer',
    'uid' => 0,
    'address' => $this->frenchAddress,
  ]);
  $profile
    ->setData('address_book_profile_id', $french_profile
    ->id());
  $profile
    ->save();
  $new_french_address = [
    'country_code' => 'FR',
    'locality' => 'Paris',
    'postal_code' => '75002',
    'address_line1' => '38 Rue du Sentier',
    'given_name' => 'Leon',
    'family_name' => 'Leon',
  ];
  $french_profile
    ->set('address', $new_french_address);
  $french_profile
    ->save();
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());

  // Confirm that the _original option is present and selected, and that it
  // has the expected suffix.
  $options = $this
    ->xpath('//select[@name="profile[select_address]"]/option');
  $this
    ->assertCount(4, $options);
  $this
    ->assertEquals($this->usAddress['address_line1'], $options[0]
    ->getText());
  $this
    ->assertEquals($this->frenchAddress['address_line1'], $options[1]
    ->getText());
  $this
    ->assertEquals($this->frenchAddress['address_line1'] . ' (current version)', $options[2]
    ->getText());
  $this
    ->assertEquals('+ Enter a new address', $options[3]
    ->getText());
  $this
    ->assertNotEmpty($options[2]
    ->getAttribute('selected'));
  $this
    ->assertEquals('_original', $options[2]
    ->getValue());
  $this
    ->assertRenderedAddress($new_french_address);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to edit the profile.
  // Editing the profile should not result in an address book copy, since
  // the source address book profile is now out of sync.
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->pressButton('billing_edit');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ($this->frenchAddress as $property => $value) {
    $this
      ->assertSession()
      ->fieldValueEquals("profile[address][0][address][{$property}]", $value);
  }
  $this
    ->assertSession()
    ->fieldNotExists('profile[copy_to_address_book]');
  $this
    ->submitForm([
    'profile[address][0][address][address_line1]' => '37 Rue du Sentier',
  ], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "37 Rue du Sentier" and the country code is FR. Address book: No');

  // Populated from a deleted address book profile.
  $profile = Profile::create([
    'type' => 'customer',
    'uid' => 0,
    'address' => $this->frenchAddress,
  ]);
  $profile
    ->setData('address_book_profile_id', '999');
  $profile
    ->save();
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->assertSession()
    ->fieldValueEquals('profile[select_address]', '_original');
  $this
    ->assertRenderedAddress($this->frenchAddress);
  $this
    ->submitForm([], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "38 Rue du Sentier" and the country code is FR. Address book: No');

  // Confirm that it is possible to edit the profile.
  // Since there's no matching address book profile ID, the profile should
  // be treated as a one-off (with the checkbox shown to allow copying again).
  $this
    ->drupalGet('/commerce_order_test/customer_profile_test_form/' . $profile
    ->id());
  $this
    ->getSession()
    ->getPage()
    ->pressButton('billing_edit');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  foreach ($this->frenchAddress as $property => $value) {
    $this
      ->assertSession()
      ->fieldValueEquals("profile[address][0][address][{$property}]", $value);
  }
  $this
    ->assertSession()
    ->checkboxNotChecked('profile[copy_to_address_book]');
  $this
    ->assertSession()
    ->pageTextContains('Save to my address book');
  $this
    ->submitForm([
    'profile[address][0][address][address_line1]' => '37 Rue du Sentier',
  ], 'Submit');
  $this
    ->assertSession()
    ->pageTextContains('The street is "37 Rue du Sentier" and the country code is FR. Address book: No');
}