You are here

public function AddressDefaultWidgetTest::testCountries in Address 8

Tests the country field.

Checked:

  • required/optional status.
  • available_countries instance setting.

File

tests/src/FunctionalJavascript/AddressDefaultWidgetTest.php, line 165

Class

AddressDefaultWidgetTest
Tests the default address widget.

Namespace

Drupal\Tests\address\FunctionalJavascript

Code

public function testCountries() {
  $field_name = $this->field
    ->getName();

  // Optional field: Country should be optional and set to default_country.
  $this
    ->drupalGet($this->nodeAddUrl);
  $this
    ->assertEmpty((bool) $this
    ->xpath('//select[@name="' . $field_name . '[0][address][country_code]" and boolean(@required)]'), 'Country is shown as optional.');
  $this
    ->assertOptionSelected($field_name . '[0][address][country_code]', 'US', 'The configured default_country is selected.');

  // Required field: Country should be required and set to default_country.
  $this->field
    ->setRequired(TRUE);
  $this->field
    ->save();
  $this
    ->drupalGet($this->nodeAddUrl);
  $this
    ->assertNotEmpty((bool) $this
    ->xpath('//select[@name="' . $field_name . '[0][address][country_code]" and boolean(@required)]'), 'Country is shown as required.');
  $this
    ->assertOptionSelected($field_name . '[0][address][country_code]', 'US', 'The configured default_country is selected.');

  // All countries should be present in the form.
  $countries = array_keys($this->countryRepository
    ->getList());
  $this
    ->assertOptions($field_name . '[0][address][country_code]', $countries, 'All countries are present.');

  // Limit the list of available countries.
  $countries = [
    'US',
    'FR',
    'BR',
    'JP',
  ];
  $edit = [];
  $edit['settings[available_countries][]'] = array_map(function ($country) {
    return $country;
  }, $countries);
  $this
    ->drupalGet($this->fieldConfigUrl);
  $this
    ->submitForm($edit, t('Save settings'));
  $this
    ->drupalGet($this->nodeAddUrl);
  $this
    ->assertOptions($field_name . '[0][address][country_code]', $countries, 'The restricted list of available countries is present.');

  // Create an article with one of them.
  $country_code = 'US';
  $this
    ->getSession()
    ->getPage()
    ->fillField($field_name . '[0][address][country_code]', 'US');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $address = [
    'given_name' => 'John',
    'family_name' => 'Smith',
    'organization' => 'Some Organization',
    'address_line1' => '1098 Alta Ave',
    'locality' => 'Mountain View',
    'administrative_area' => 'CA',
    'postal_code' => '94043',
  ];
  $edit = [];
  $edit['title[0][value]'] = $this
    ->randomMachineName(8);
  foreach ($address as $property => $value) {
    $path = $field_name . '[0][address][' . $property . ']';
    $edit[$path] = $value;
  }
  $this
    ->submitForm($edit, t('Save'));

  // Check that the article has been created.
  $node = $this
    ->getNodeByTitle($edit['title[0][value]']);
  $this
    ->assertNotEmpty($node, 'Created article ' . $edit['title[0][value]']);

  // Now remove 'US' from the list of available countries.
  $countries = [
    'FR',
  ];
  $edit = [];
  $edit['settings[available_countries][]'] = array_map(function ($country) {
    return $country;
  }, $countries);
  $this
    ->drupalGet($this->fieldConfigUrl);
  $this
    ->submitForm($edit, 'Save settings');

  // Access the article's edit form and confirm the values are unchanged.
  // 'US' should be in the list along with the available countries and should
  // be selected.
  $this
    ->drupalGet('node/' . $node
    ->id() . '/edit');
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][given_name]', $address['given_name']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][family_name]', $address['family_name']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][organization]', $address['organization']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][address_line1]', $address['address_line1']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][locality]', $address['locality']);
  $this
    ->assertOptionSelected($field_name . '[0][address][administrative_area]', $address['administrative_area']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][postal_code]', $address['postal_code']);
  $this
    ->assertOptionSelected($field_name . '[0][address][country_code]', $country_code);

  // Confirm that it is possible to switch the country to France, and back.
  $this
    ->getSession()
    ->getPage()
    ->fillField($field_name . '[0][address][country_code]', 'FR');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $this
    ->assertSession()
    ->fieldNotExists($field_name . '[0][address][administrative_area]');
  $this
    ->getSession()
    ->getPage()
    ->fillField($field_name . '[0][address][country_code]', 'US');
  $this
    ->assertSession()
    ->assertWaitOnAjaxRequest();
  $this
    ->assertSession()
    ->fieldExists($field_name . '[0][address][administrative_area]');

  // Test the widget with only one available country.
  // Since the field is required, the country selector should be hidden.
  $countries = [
    'US',
  ];
  $edit = [];
  $edit['settings[available_countries][]'] = array_map(function ($country) {
    return $country;
  }, $countries);
  $this
    ->drupalGet($this->fieldConfigUrl);
  $this
    ->submitForm($edit, 'Save settings');
  $this
    ->drupalGet('node/' . $node
    ->id() . '/edit');
  $this
    ->assertSession()
    ->fieldNotExists($field_name . '[0][address][country_code]');

  // Submitting the form should result in no data loss.
  $this
    ->submitForm([], t('Save'));
  $this
    ->drupalGet('node/' . $node
    ->id() . '/edit');
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][given_name]', $address['given_name']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][family_name]', $address['family_name']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][organization]', $address['organization']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][address_line1]', $address['address_line1']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][locality]', $address['locality']);
  $this
    ->assertOptionSelected($field_name . '[0][address][administrative_area]', $address['administrative_area']);
  $this
    ->assertSession()
    ->fieldValueEquals($field_name . '[0][address][postal_code]', $address['postal_code']);
}