Error message

  • Notice: Undefined property: stdClass::$preferred in _api_make_match_link() (line 1075 of /home/projects/api/www/sites/all/modules/api/api.formatting.inc).
  • Notice: Undefined property: stdClass::$preferred in _api_make_match_link() (line 1079 of /home/projects/api/www/sites/all/modules/api/api.formatting.inc).
  • Notice: Undefined property: stdClass::$preferred in _api_make_match_link() (line 1075 of /home/projects/api/www/sites/all/modules/api/api.formatting.inc).
  • Notice: Undefined property: stdClass::$preferred in _api_make_match_link() (line 1079 of /home/projects/api/www/sites/all/modules/api/api.formatting.inc).

public function ParagraphsLibraryTest::testLibraryItems

Tests the library items workflow for paragraphs.

File

paragraphs/modules/paragraphs_library/tests/src/Functional/ParagraphsLibraryTest.php, line 36

Class

ParagraphsLibraryTest
Tests paragraphs library functionality.

Namespace

Drupal\Tests\paragraphs_library\Functional

Code

public function testLibraryItems() {

  // Set default theme.
  \Drupal::service('theme_installer')
    ->install([
    'claro',
  ]);
  $this
    ->config('system.theme')
    ->set('default', 'claro')
    ->save();
  $this
    ->loginAsAdmin([
    'create paragraphed_test content',
    'edit any paragraphed_test content',
    'administer paragraphs library',
  ]);

  // Add a Paragraph type with a text field.
  $paragraph_type = 'text_paragraph';
  $this
    ->addParagraphsType($paragraph_type);
  static::fieldUIAddNewField('admin/structure/paragraphs_type/' . $paragraph_type, 'text', 'Text', 'text_long', [], []);

  // Add a new library item.
  $this
    ->drupalGet('admin/content/paragraphs');
  $this
    ->clickLink('Add library item');
  $this
    ->submitForm([], 'paragraphs_text_paragraph_add_more');
  $edit = [
    'label[0][value]' => 're usable paragraph label',
    'paragraphs[0][subform][field_text][0][value]' => 're_usable_text',
  ];
  $this
    ->submitForm($edit, 'Save');
  $this
    ->clickLink('re usable paragraph label');
  $this
    ->assertSession()
    ->responseContains('claro/css/base/elements.css');
  $this
    ->clickLink('Edit');
  $this
    ->assertSession()
    ->responseNotContains('class="messages messages--warning"');
  $items = \Drupal::entityQuery('paragraphs_library_item')
    ->accessCheck(TRUE)
    ->sort('id', 'DESC')
    ->range(0, 1)
    ->execute();
  $library_item_id = reset($items);

  // Assert local tasks and URLs.
  $this
    ->assertSession()
    ->linkExists('Edit');
  $this
    ->assertSession()
    ->pageTextContains('Delete');
  $this
    ->clickLink('View');
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.paragraphs_library_item.canonical', [
    'paragraphs_library_item' => $library_item_id,
  ]));
  $this
    ->drupalGet('admin/content/paragraphs/' . $library_item_id . '/delete');
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.paragraphs_library_item.delete_form', [
    'paragraphs_library_item' => $library_item_id,
  ]));
  $this
    ->clickLink('Edit');
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.paragraphs_library_item.edit_form', [
    'paragraphs_library_item' => $library_item_id,
  ]));

  // Check that the data is correctly stored.
  $this
    ->drupalGet('admin/content/paragraphs');
  $this
    ->assertSession()
    ->pageTextContains('Used');
  $this
    ->assertSession()
    ->pageTextContains('Changed');
  $result = $this
    ->cssSelect('.views-field-count');
  $this
    ->assertEquals(trim($result[1]
    ->getText()), '0', 'Usage info is correctly displayed.');
  $this
    ->assertSession()
    ->pageTextContains('Delete');

  // Check the changed field.
  $result = $this
    ->cssSelect('.views-field-changed');
  $this
    ->assertNotNull(trim($result[1]
    ->getText()));
  $this
    ->clickLink('Edit');
  $this
    ->assertSession()
    ->fieldExists('label[0][value]');
  $this
    ->assertSession()
    ->fieldExists('paragraphs[0][subform][field_text][0][value]');

  // Create a node with the library paragraph.
  $this
    ->drupalGet('node/add/paragraphed_test');
  $this
    ->submitForm([], 'field_paragraphs_from_library_add_more');
  $edit = [
    'title[0][value]' => 'library_test',
    'field_paragraphs[0][subform][field_reusable_paragraph][0][target_id]' => 're usable paragraph label (1)',
  ];
  $this
    ->submitForm($edit, 'Save');
  $library_items = \Drupal::entityTypeManager()
    ->getStorage('paragraphs_library_item')
    ->loadByProperties([
    'label' => 're usable paragraph label',
  ]);
  $this
    ->drupalGet('admin/content/paragraphs/' . current($library_items)
    ->id() . '/edit');
  $this
    ->assertSession()
    ->pageTextContains('Modifications on this form will affect all existing usages of this entity.');
  $this
    ->assertSession()
    ->pageTextContains('Delete');
  $this
    ->drupalGet('admin/content/paragraphs');
  $result = $this
    ->cssSelect('.views-field-count');
  $this
    ->assertEquals(trim($result[1]
    ->getText()), '1', 'Usage info is correctly displayed.');

  // Assert that the paragraph is shown correctly.
  $node_one = $this
    ->getNodeByTitle('library_test');
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text');

  // Assert that the correct view mode is used.
  $notext_view_mode = \Drupal::entityTypeManager()
    ->getStorage('entity_view_mode')
    ->create([
    'id' => "paragraph.notext",
    'label' => 'No label view mode',
    'targetEntityType' => 'paragraph',
    'cache' => FALSE,
  ]);
  $notext_view_mode
    ->enable();
  $notext_view_mode
    ->save();
  $display_storage = \Drupal::entityTypeManager()
    ->getStorage('entity_view_display');
  $notest_display = $display_storage
    ->create([
    'status' => TRUE,
    'id' => "paragraph.{$paragraph_type}.notext",
    'targetEntityType' => 'paragraph',
    'bundle' => $paragraph_type,
    'mode' => 'notext',
    'content' => [],
  ]);
  $notest_display
    ->save();
  $alternative_view_mode = \Drupal::entityTypeManager()
    ->getStorage('entity_view_mode')
    ->create([
    'id' => 'paragraphs_library_item.alternative',
    'label' => 'Alternative view mode',
    'targetEntityType' => 'paragraphs_library_item',
    'cache' => FALSE,
  ]);
  $alternative_view_mode
    ->enable();
  $alternative_view_mode
    ->save();
  $display_storage = \Drupal::entityTypeManager()
    ->getStorage('entity_view_display');
  $alternative_display = $display_storage
    ->create([
    'status' => TRUE,
    'id' => 'paragraphs_library_item.paragraphs_library_item.alternative',
    'targetEntityType' => 'paragraphs_library_item',
    'bundle' => 'paragraphs_library_item',
    'mode' => 'alternative',
    'content' => [
      'paragraphs' => [
        'label' => 'hidden',
        'type' => 'entity_reference_revisions_entity_view',
        'region' => 'content',
        'settings' => [
          'view_mode' => 'notext',
        ],
        'third_party_settings' => [],
        'weight' => 0,
      ],
    ],
  ]);
  $alternative_display
    ->save();
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text');

  /** @var \Drupal\Core\Entity\Entity\EntityViewDisplay $from_library_view_display */
  $from_library_view_display = $display_storage
    ->load('paragraph.from_library.default');
  $field_reusable_paragraph_component = $from_library_view_display
    ->getComponent('field_reusable_paragraph');
  $field_reusable_paragraph_component['settings']['view_mode'] = 'alternative';
  $from_library_view_display
    ->setComponent('field_reusable_paragraph', $field_reusable_paragraph_component);
  $from_library_view_display
    ->save();
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextNotContains('re_usable_text');
  $from_library_view_display = $display_storage
    ->load('paragraph.from_library.default');
  $field_reusable_paragraph_component = $from_library_view_display
    ->getComponent('field_reusable_paragraph');
  $field_reusable_paragraph_component['settings']['view_mode'] = 'default';
  $from_library_view_display
    ->setComponent('field_reusable_paragraph', $field_reusable_paragraph_component);
  $from_library_view_display
    ->save();

  // Create a new node with the library paragraph.
  $this
    ->drupalGet('node/add/paragraphed_test');
  $this
    ->submitForm([], 'field_paragraphs_from_library_add_more');
  $edit = [
    'title[0][value]' => 'library_test_new',
    'field_paragraphs[0][subform][field_reusable_paragraph][0][target_id]' => 're usable paragraph label (1)',
  ];
  $this
    ->submitForm($edit, 'Save');

  // Assert that the paragraph is shown correctly.
  $node_two = $this
    ->getNodeByTitle('library_test_new');
  $this
    ->assertSession()
    ->addressEquals('node/' . $node_two
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text');
  $this
    ->assertSession()
    ->pageTextNotContains('Reusable paragraph');
  $this
    ->assertSession()
    ->pageTextNotContains('re usable paragraph label');
  $this
    ->assertSession()
    ->elementTextNotContains('css', '.paragraph--type--from-library', 'Paragraphs');
  $this
    ->drupalGet('node/' . $node_two
    ->id() . '/edit');
  $this
    ->submitForm([], 'field_paragraphs_from_library_add_more');
  $edit = [
    'title[0][value]' => 'library_test_new',
    'field_paragraphs[0][subform][field_reusable_paragraph][0][target_id]' => 're usable paragraph label (1)',
    'field_paragraphs[1][subform][field_reusable_paragraph][0][target_id]' => 're usable paragraph label (1)',
  ];
  $this
    ->submitForm($edit, 'Save');
  $reusable_paragraphs_text = $this
    ->xpath('//div[contains(@class, "field--name-field-paragraphs")]/div[@class="field__items"]/div[1]//div[@class="field__item"]/p');
  $this
    ->assertEquals($reusable_paragraphs_text[0]
    ->getText(), 're_usable_text');
  $second_reusable_paragraphs_text = $this
    ->xpath('//div[contains(@class, "field--name-field-paragraphs")]/div[@class="field__items"]/div[2]//div[@class="field__item"]/p');
  $this
    ->assertEquals($second_reusable_paragraphs_text[0]
    ->getText(), 're_usable_text');

  // Edit the paragraph and change the text.
  $this
    ->drupalGet('admin/content/paragraphs');
  $this
    ->assertSession()
    ->pageTextContains('Used');
  $result = $this
    ->cssSelect('.views-field-count');
  $this
    ->assertEquals(trim($result[1]
    ->getText()), '4', 'Usage info is correctly displayed.');
  $this
    ->assertSession()
    ->linkNotExists('4');
  $this
    ->clickLink('Edit');
  $this
    ->assertSession()
    ->pageTextContains('Modifications on this form will affect all existing usages of this entity.');
  $edit = [
    'paragraphs[0][subform][field_text][0][value]' => 're_usable_text_new',
  ];
  $this
    ->submitForm($edit, 'Save');

  // Check in both nodes that the text is updated. Test as anonymous user, so
  // that the cache is populated.
  $this
    ->drupalLogout();
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text_new');
  $this
    ->drupalGet('node/' . $node_two
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text_new');
  $this
    ->loginAsAdmin([
    'create paragraphed_test content',
    'edit any paragraphed_test content',
    'administer paragraphs library',
  ]);

  // Unpublish the library item, make sure it still shows up for the curent
  // user but not for an anonymous user.
  $this
    ->drupalGet('admin/content/paragraphs');
  $this
    ->clickLink('Edit');
  $edit = [
    'status[value]' => FALSE,
  ];
  $this
    ->submitForm($edit, 'Save');
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text_new');
  $this
    ->drupalLogout();
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextNotContains('re_usable_text_new');

  // Log in again, publish again, make sure it shows up again.
  $this
    ->loginAsAdmin([
    'create paragraphed_test content',
    'edit any paragraphed_test content',
    'administer paragraphs library',
  ]);
  $this
    ->drupalGet('admin/content/paragraphs');
  $this
    ->clickLink('Edit');
  $edit = [
    'status[value]' => TRUE,
  ];
  $this
    ->submitForm($edit, 'Save');
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text_new');
  $this
    ->drupalLogout();
  $this
    ->drupalGet('node/' . $node_one
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('re_usable_text_new');
  $this
    ->loginAsAdmin([
    'administer paragraphs library',
    'access entity usage statistics',
  ]);
  $this
    ->drupalGet('admin/content/paragraphs');
  $this
    ->assertSession()
    ->linkExists('4', 0, 'Link to usage statistics is available for user with permission.');
  $element = $this
    ->cssSelect('th.views-field-paragraphs__target-id');
  $this
    ->assertEquals($element[0]
    ->getText(), 'Paragraphs', 'Paragraphs column is available.');
  $element = $this
    ->cssSelect('.paragraphs-description .paragraphs-content-wrapper .summary-content');
  $this
    ->assertEquals(trim($element[0]
    ->getText()), 're_usable_text_new', 'Paragraphs summary available.');

  // Check that the deletion of library items does not cause errors.
  current($library_items)
    ->delete();
  $this
    ->drupalGet('node/' . $node_one
    ->id());

  // Test paragraphs library item field UI.
  $this
    ->loginAsAdmin([
    'administer paragraphs library',
    'administer paragraphs_library_item fields',
    'administer paragraphs_library_item form display',
    'administer paragraphs_library_item display',
    'access administration pages',
  ]);
  $this
    ->drupalGet('admin/config/content/paragraphs_library_item');
  $this
    ->assertSession()
    ->linkExists('Manage fields');
  $this
    ->assertSession()
    ->linkExists('Manage form display');
  $this
    ->assertSession()
    ->linkExists('Manage display');
  $this
    ->assertSession()
    ->buttonExists('Save configuration');

  // Assert that users can create fields to
  $this
    ->clickLink('Manage fields');
  if (version_compare(\Drupal::VERSION, '10.1', '>=')) {
    $this
      ->clickLink('Create a new field');
  }
  else {
    $this
      ->clickLink('Add field');
  }
  $this
    ->assertSession()
    ->statusCodeEquals(200);
  $this
    ->assertSession()
    ->pageTextNotContains('plugin does not exist');
  $this
    ->drupalGet('admin/config/content');
  $this
    ->clickLink('Paragraphs library item settings');
}