View source  
  <?php
namespace Drupal\Tests\link\Functional;
use Drupal\Core\Url;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\link\LinkItemInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
class LinkFieldUITest extends BrowserTestBase {
  use FieldUiTestTrait;
  
  public static $modules = [
    'node',
    'link',
    'field_ui',
    'block',
  ];
  
  protected $defaultTheme = 'classy';
  
  protected $adminUser;
  
  protected $helpTextUser;
  
  protected $firstContentType;
  
  protected $secondContentType;
  
  protected function setUp() {
    parent::setUp();
    $this->firstContentType = $this
      ->drupalCreateContentType();
    $this->secondContentType = $this
      ->drupalCreateContentType();
    $this->adminUser = $this
      ->drupalCreateUser([
      'administer content types',
      'administer node fields',
      'administer node display',
    ]);
    $this->helpTextUser = $this
      ->drupalCreateUser([
      'create ' . $this->secondContentType
        ->id() . ' content',
    ]);
    $this
      ->drupalPlaceBlock('system_breadcrumb_block');
  }
  
  public function testFieldUI() {
    foreach ($this
      ->providerTestFieldUI() as $item) {
      list($cardinality, $link_type, $title, $label, $field_name) = $item;
      $this
        ->runFieldUIItem($cardinality, $link_type, $title, $label, $field_name);
    }
  }
  
  protected function providerTestFieldUI() {
    
    $cardinalities = [
      1,
      2,
    ];
    $title_settings = [
      DRUPAL_DISABLED,
      DRUPAL_OPTIONAL,
    ];
    $link_types = [
      LinkItemInterface::LINK_EXTERNAL,
      LinkItemInterface::LINK_GENERIC,
      LinkItemInterface::LINK_INTERNAL,
    ];
    
    foreach ($cardinalities as $cardinality) {
      foreach ($link_types as $link_type) {
        
        foreach ($title_settings as $title_setting) {
          
          foreach ([
            TRUE,
            FALSE,
          ] as $label_provided) {
            
            $id = implode('_', [
              'link',
              $cardinality,
              $link_type,
              $title_setting,
              (int) $label_provided,
            ]);
            
            $label = '<img src="http://example.com">' . $id;
            (yield [
              $cardinality,
              $link_type,
              $title_setting,
              $label_provided ? $label : '',
              $id,
            ]);
          }
        }
      }
    }
  }
  
  public function runFieldUIItem($cardinality, $link_type, $title, $label, $field_name) {
    $this
      ->drupalLogin($this->adminUser);
    $type_path = 'admin/structure/types/manage/' . $this->firstContentType
      ->id();
    
    $field_label = str_replace('_', ' ', $field_name);
    $description = 'link field description';
    $field_edit = [
      'description' => $description,
    ];
    $this
      ->fieldUIAddNewField($type_path, $field_name, $field_label, 'link', [], $field_edit);
    
    $this
      ->drupalGet("{$type_path}/display");
    $this
      ->assertText(t('Link text trimmed to @limit characters', [
      '@limit' => 80,
    ]));
    $storage = FieldStorageConfig::create([
      'field_name' => $field_name,
      'entity_type' => 'node',
      'type' => 'link',
      'cardinality' => $cardinality,
    ]);
    $storage
      ->save();
    FieldConfig::create([
      'field_storage' => $storage,
      'label' => $label,
      'bundle' => $this->secondContentType
        ->id(),
      'settings' => [
        'title' => $title,
        'link_type' => $link_type,
      ],
    ])
      ->save();
    
    $form_display_id = implode('.', [
      'node',
      $this->secondContentType
        ->id(),
      'default',
    ]);
    $form_display = EntityFormDisplay::load($form_display_id);
    $form_display
      ->setComponent($field_name, [
      'region' => 'content',
    ]);
    $form_display
      ->save();
    
    $this
      ->drupalLogin($this->helpTextUser);
    $add_path = 'node/add/' . $this->secondContentType
      ->id();
    $this
      ->drupalGet($add_path);
    $expected_help_texts = [
      LinkItemInterface::LINK_EXTERNAL => 'This must be an external URL such as <em class="placeholder">http://example.com</em>.',
      LinkItemInterface::LINK_GENERIC => 'You can also enter an internal path such as <em class="placeholder">/node/add</em> or an external URL such as <em class="placeholder">http://example.com</em>. Enter <em class="placeholder"><front></em> to link to the front page. Enter <em class="placeholder"><nolink></em> to display link text only',
      LinkItemInterface::LINK_INTERNAL => rtrim(Url::fromRoute('<front>', [], [
        'absolute' => TRUE,
      ])
        ->toString(), '/'),
    ];
    
    $this
      ->assertFieldContainsRawText($field_name, $expected_help_texts[$link_type]);
    if ($link_type === LinkItemInterface::LINK_INTERNAL) {
      
      $this
        ->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_EXTERNAL]);
      $this
        ->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_GENERIC]);
    }
    
    if (!empty($label)) {
      $this
        ->assertFieldContainsRawText($field_name, $label);
    }
  }
  
  protected function assertFieldContainsRawText($field_name, $text) {
    $this
      ->assertTrue((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this
      ->getFieldHtml($field_name)));
  }
  
  protected function assertNoFieldContainsRawText($field_name, $text) {
    $this
      ->assertFalse((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this
      ->getFieldHtml($field_name)));
  }
  
  protected function getFieldHtml($field_name) {
    $css_id = Html::cleanCssIdentifier('edit-' . $field_name . '-wrapper');
    return $this
      ->xpath('//*[@id=:id]', [
      ':id' => $css_id,
    ])[0]
      ->getHtml();
  }
}