View source
<?php
namespace Drupal\Tests\like_and_dislike\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Entity\Comment;
use Drupal\comment\CommentInterface;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Tests\EntityViewTrait;
class LikeAndDislikeTest extends WebDriverTestBase {
protected $defaultTheme = 'stark';
use CommentTestTrait;
use EntityViewTrait {
buildEntityView as drupalBuildEntityView;
}
public static $modules = [
'like_and_dislike',
'node',
'field_ui',
'comment',
];
protected $adminUser;
protected function setUp() {
parent::setUp();
$node_type = NodeType::create([
'type' => 'article',
'name' => 'Article',
]);
$node_type
->save();
$comment_type = CommentType::create([
'id' => 'comment',
'label' => 'Default comments',
'description' => 'Default comment field',
'target_entity_type_id' => 'article',
]);
$comment_type
->save();
$this
->addDefaultCommentField('node', 'article', 'test_comment_field', CommentItemInterface::OPEN, 'test_comment_type');
$admin_permissions = [
'administer like and dislike',
'administer node display',
'administer user display',
'administer comment display',
'administer display modes',
'access comments',
'administer permissions',
];
$this->adminUser = $this
->drupalCreateUser($admin_permissions);
$this
->drupalLogin($this->adminUser);
}
public function testVisibility() {
$node = Node::create([
'title' => 'Test node title',
'type' => 'article',
]);
$node
->save();
$this
->drupalGet('admin/structure/types/manage/article/display');
$this
->click('#edit-modes summary');
$edit = [
'display_modes_custom[teaser]' => TRUE,
];
$this
->drupalPostForm(NULL, $edit, 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$edit = [
'enabled_types[node][enabled]' => TRUE,
'enabled_types[node][bundle_info][bundles][article]' => TRUE,
'enabled_types[comment][enabled]' => TRUE,
'enabled_types[comment][bundle_info][bundles][test_comment_type]' => TRUE,
'allow_cancel_vote' => TRUE,
'hide_vote_widget' => FALSE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$this
->assertFieldChecked('edit-enabled-types-node-enabled');
$this
->assertFieldChecked('edit-enabled-types-comment-enabled');
$this
->assertFieldChecked('edit-enabled-types-node-bundle-info-bundles-article');
$this
->assertNoFieldChecked('edit-enabled-types-comment-bundle-info-bundles-comment');
$this
->assertFieldChecked('edit-enabled-types-comment-bundle-info-bundles-test-comment-type');
$this
->assertFieldChecked('edit-allow-cancel-vote');
$this
->assertNoFieldChecked('edit-hide-vote-widget');
$this
->drupalGet('admin/people/permissions');
$this
->assertSession()
->pageTextContains('Content (Article): add/remove Like vote');
$this
->assertSession()
->pageTextContains('Content (Article): add/remove Dislike vote');
$this
->assertSession()
->pageTextNotContains('Comment (Default comments): add/remove Like vote');
$this
->assertSession()
->pageTextNotContains('Comment (Default comments): add/remove Dislike vote');
$this
->assertSession()
->pageTextContains('Comment (Test_comment_type): add/remove Like vote');
$this
->assertSession()
->pageTextContains('Comment (Test_comment_type): add/remove Dislike vote');
$user_roles = $this->adminUser
->getRoles();
$user_role = end($user_roles);
$edit = [
$user_role . '[add or remove like votes on article of node]' => TRUE,
$user_role . '[add or remove dislike votes on article of node]' => TRUE,
$user_role . '[add or remove like votes on test_comment_type of comment]' => TRUE,
$user_role . '[add or remove dislike votes on test_comment_type of comment]' => TRUE,
];
$this
->drupalPostForm(NULL, $edit, 'Save permissions');
$this
->drupalGet('admin/structure/types/manage/article/display');
$this
->assertSession()
->pageTextContains('Like and dislike');
$this
->assertOptionSelected('edit-fields-like-and-dislike-region', 'hidden');
$this
->drupalGet('admin/structure/types/manage/article/display/teaser');
$this
->assertSession()
->pageTextContains('Like and dislike');
$this
->assertOptionSelected('edit-fields-like-and-dislike-region', 'hidden');
$this
->drupalGet('admin/structure/types/manage/article/display');
$this
->assertSession()
->waitForElementVisible('css', '[name="fields[like_and_dislike][region]"]');
$this
->getSession()
->getPage()
->pressButton('Show row weights');
$this
->getSession()
->getPage()
->selectFieldOption('fields[like_and_dislike][region]', 'content');
$this
->assertSession()
->assertWaitOnAjaxRequest();
$this
->assertTrue($this
->assertSession()
->optionExists('fields[like_and_dislike][region]', 'content')
->isSelected());
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->assertFalse($this
->assertSession()
->optionExists('edit-fields-like-and-dislike-region', 'hidden')
->isSelected());
$node_id = $node
->id();
$this
->drupalGet('node/' . $node_id);
$this
->assertLikesAndDislikes('node', $node_id);
$teaser_render_array = $this
->drupalBuildEntityView($node, 'teaser');
$this
->assertFalse(isset($teaser_render_array['like_and_dislike']));
$this
->drupalGet('admin/structure/types/manage/article/display');
$this
->getSession()
->getPage()
->selectFieldOption('fields[like_and_dislike][region]', 'hidden');
$this
->assertSession()
->assertWaitOnAjaxRequest();
$this
->assertTrue($this
->assertSession()
->optionExists('fields[like_and_dislike][region]', 'hidden')
->isSelected());
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->assertOptionSelected('edit-fields-like-and-dislike-region', 'hidden');
$this
->drupalPostForm('admin/structure/types/manage/article/display/teaser', [
'fields[like_and_dislike][region]' => 'content',
], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->assertFalse($this
->assertSession()
->optionExists('edit-fields-like-and-dislike-region', 'hidden')
->isSelected());
$this
->drupalGet('node/' . $node_id);
$this
->assertSession()
->pageTextNotContains('Like');
$this
->assertSession()
->pageTextNotContains('Dislike');
$teaser_render_array = $this
->drupalBuildEntityView($node, 'teaser');
$this
->assertTrue(isset($teaser_render_array['like_and_dislike']));
$comment = Comment::create([
'subject' => 'Test subject',
'comment_body' => 'Test body',
'entity_id' => $node_id,
'entity_type' => 'node',
'node_type' => 'article',
'field_name' => 'test_comment_field',
'status' => CommentInterface::PUBLISHED,
'uid' => $this->adminUser
->id(),
]);
$comment
->save();
$comment_id = $comment
->id();
$this
->drupalGet('node/' . $node_id);
$this
->assertSession()
->pageTextNotContains('Like');
$this
->assertSession()
->pageTextNotContains('Dislike');
$edit = [
'enabled_types[node][enabled]' => FALSE,
'enabled_types[comment][enabled]' => TRUE,
'enabled_types[comment][bundle_info][bundles][test_comment_type]' => TRUE,
'allow_cancel_vote' => TRUE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$teaser_render_array = $this
->drupalBuildEntityView($node, 'teaser');
$this
->assertFalse(isset($teaser_render_array['like_and_dislike']));
$this
->drupalGet('node/' . $node_id);
$this
->assertSession()
->pageTextNotContains('Like');
$this
->assertSession()
->pageTextNotContains('Dislike');
$this
->drupalGet('admin/structure/comment/manage/test_comment_type/display');
$this
->getSession()
->getPage()
->selectFieldOption('fields[like_and_dislike][region]', 'content');
$this
->assertSession()
->assertWaitOnAjaxRequest();
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->drupalGet('node/' . $node_id);
$this
->assertLikesAndDislikes('comment', $comment_id);
$edit = [
'enabled_types[node][enabled]' => TRUE,
'enabled_types[node][bundle_info][bundles][article]' => TRUE,
'allow_cancel_vote' => TRUE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$this
->drupalGet('admin/structure/types/manage/article/display');
$this
->getSession()
->getPage()
->selectFieldOption('fields[like_and_dislike][region]', 'content');
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->drupalGet('node/' . $node_id);
$this
->assertLikesAndDislikes('node', $node_id);
$this
->assertLikesAndDislikes('comment', $comment_id);
$edit = [
'hide_vote_widget' => TRUE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$this
->assertFieldChecked('edit-hide-vote-widget');
$this
->drupalGet('admin/people/permissions');
$edit = [
$user_role . '[add or remove dislike votes on article of node]' => FALSE,
$user_role . '[add or remove dislike votes on test_comment_type of comment]' => FALSE,
];
$this
->drupalPostForm(NULL, $edit, 'Save permissions');
$this
->drupalGet('node/' . $node_id);
$this
->assertVotingIconExistence('node', $node_id, 'like', TRUE);
$this
->assertVotingIconExistence('node', $node_id, 'dislike', FALSE);
$this
->assertVotingIconExistence('comment', $comment_id, 'like', TRUE);
$this
->assertVotingIconExistence('comment', $comment_id, 'dislike', FALSE);
$this
->drupalGet('admin/people/permissions');
$edit = [
$user_role . '[add or remove like votes on article of node]' => FALSE,
$user_role . '[add or remove like votes on test_comment_type of comment]' => FALSE,
];
$this
->drupalPostForm(NULL, $edit, 'Save permissions');
$this
->drupalGet('node/' . $node_id);
$this
->assertVotingIconExistence('node', $node_id, 'like', FALSE);
$this
->assertVotingIconExistence('node', $node_id, 'dislike', FALSE);
$this
->assertVotingIconExistence('node', $comment_id, 'dislike', FALSE);
$this
->assertVotingIconExistence('comment', $comment_id, 'dislike', FALSE);
}
public function testUserEntity() {
$edit = [
'enabled_types[user][enabled]' => TRUE,
'allow_cancel_vote' => TRUE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$this
->assertFieldChecked('edit-enabled-types-user-enabled');
$this
->drupalGet('admin/config/people/accounts/display');
$this
->getSession()
->getPage()
->pressButton('Show row weights');
$this
->assertSession()
->waitForElementVisible('css', '[name="fields[like_and_dislike][region]"]');
$this
->submitForm([
'fields[like_and_dislike][region]' => 'content',
], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$user_id = $this->adminUser
->id();
$this
->drupalGet('user/' . $user_id);
$this
->assertLikesAndDislikes('user', $user_id, '0', '0', TRUE);
$user_roles = $this->adminUser
->getRoles();
$user_role = end($user_roles);
$edit = [
$user_role . '[add or remove like votes on user]' => TRUE,
];
$this
->drupalPostForm('admin/people/permissions', $edit, 'Save permissions');
$this
->drupalGet('user/' . $user_id);
$xpath = $this
->xpath('//*[@id="like-container-user-' . $user_id . '"]/a')[0];
$this
->assertFalse($xpath
->hasAttribute('class'));
$this
->assertEquals($this
->cssSelect('#dislike-container-user-' . $user_id . ' a[class]')[0]
->getAttribute('class'), 'disable-status');
$enabled_types = \Drupal::config('like_and_dislike.settings')
->get('enabled_types');
$this
->assertEquals($enabled_types['user'], []);
}
public function testVoting() {
$node = Node::create([
'title' => 'Test node title',
'type' => 'article',
]);
$node
->save();
$node_id = $node
->id();
$comment = Comment::create([
'subject' => 'Test subject',
'comment_body' => 'Test body',
'entity_id' => $node_id,
'entity_type' => 'node',
'node_type' => 'article',
'field_name' => 'test_comment_field',
'status' => CommentInterface::PUBLISHED,
'uid' => $this->adminUser
->id(),
]);
$comment
->save();
$comment_id = $comment
->id();
$edit = [
'enabled_types[node][enabled]' => TRUE,
'enabled_types[node][bundle_info][bundles][article]' => TRUE,
'enabled_types[comment][enabled]' => TRUE,
'enabled_types[comment][bundle_info][bundles][test_comment_type]' => TRUE,
'allow_cancel_vote' => TRUE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$user_roles = $this->adminUser
->getRoles();
$user_role = end($user_roles);
$edit = [
$user_role . '[add or remove like votes on article of node]' => TRUE,
$user_role . '[add or remove dislike votes on article of node]' => TRUE,
$user_role . '[add or remove like votes on test_comment_type of comment]' => TRUE,
$user_role . '[add or remove dislike votes on test_comment_type of comment]' => TRUE,
];
$this
->drupalPostForm('admin/people/permissions', $edit, 'Save permissions');
$this
->drupalGet('admin/structure/types/manage/article/display');
$this
->getSession()
->getPage()
->pressButton('Show row weights');
$this
->getSession()
->getPage()
->selectFieldOption('fields[like_and_dislike][region]', 'content');
$this
->assertSession()
->assertWaitOnAjaxRequest();
$this
->assertTrue($this
->assertSession()
->optionExists('fields[like_and_dislike][region]', 'content')
->isSelected());
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->drupalGet('admin/structure/comment/manage/test_comment_type/display');
$this
->getSession()
->getPage()
->selectFieldOption('fields[like_and_dislike][region]', 'content');
$this
->assertSession()
->assertWaitOnAjaxRequest();
$this
->assertTrue($this
->assertSession()
->optionExists('fields[like_and_dislike][region]', 'content')
->isSelected());
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains('Your settings have been saved.');
$this
->drupalGet('node/' . $node_id);
$this
->assertLikesAndDislikes('node', $node_id);
$this
->assertLikesAndDislikes('comment', $comment_id);
$this
->drupalGet('node/' . $node_id);
$this
->vote('like', 'node', $node_id, 'Your like vote was added.');
$xpath = $this
->xpath('//*[@id="like-container-node-' . $node_id . '"]/a')[0];
$this
->assertTrue($xpath
->hasAttribute('class'));
$this
->assertLikesAndDislikes('node', $node_id, '1');
$this
->assertLikesAndDislikes('comment', $comment_id);
$this
->vote('dislike', 'comment', $comment_id, 'Your dislike vote was added.');
$xpath = $this
->xpath('//*[@id="like-container-comment-' . $comment_id . '"]/a')[0];
$this
->assertFalse($xpath
->hasAttribute('class'));
$this
->assertLikesAndDislikes('node', $node_id, '1');
$this
->assertLikesAndDislikes('comment', $comment_id, '0', '1');
$user2_permissions = [
'access comments',
'add or remove like votes on article of node',
'add or remove dislike votes on article of node',
'add or remove like votes on test_comment_type of comment',
'add or remove dislike votes on test_comment_type of comment',
];
$user2 = $this
->drupalCreateUser($user2_permissions);
$this
->drupalLogin($user2);
$this
->drupalGet('node/' . $node_id);
$xpath = $this
->xpath('//*[@id="like-container-node-' . $node_id . '"]/a')[0];
$this
->assertFalse($xpath
->hasAttribute('class'));
$xpath = $this
->xpath('//*[@id="dislike-container-comment-' . $comment_id . '"]/a')[0];
$this
->assertFalse($xpath
->hasAttribute('class'));
$this
->vote('like', 'node', $node_id);
$this
->assertLikesAndDislikes('node', $node_id, '2');
$this
->assertLikesAndDislikes('comment', $comment_id, '0', '1');
$this
->vote('like', 'comment', $comment_id);
$this
->assertLikesAndDislikes('node', $node_id, '2');
$this
->assertLikesAndDislikes('comment', $comment_id, '1', '1');
$this
->vote('dislike', 'node', $node_id);
$xpath = $this
->xpath('//*[@id="like-container-node-' . $node_id . '"]/a')[0];
$this
->assertEquals('', $xpath
->getAttribute('class'));
$this
->assertLikesAndDislikes('node', $node_id, '1', '1');
$this
->assertLikesAndDislikes('comment', $comment_id, '1', '1');
$this
->vote('dislike', 'node', $node_id, NULL, TRUE);
$xpath = $this
->xpath('//*[@id="like-container-node-' . $node_id . '"]/a')[0];
$this
->assertEquals('', $xpath
->getAttribute('class'));
$this
->assertLikesAndDislikes('node', $node_id, '1');
$this
->assertLikesAndDislikes('comment', $comment_id, '1', '1');
$this
->drupalLogin($this->adminUser);
$edit = [
'enabled_types[node][enabled]' => TRUE,
'enabled_types[comment][enabled]' => TRUE,
'enabled_types[comment][bundle_info][bundles][test_comment_type]' => TRUE,
'allow_cancel_vote' => FALSE,
];
$this
->drupalPostForm('admin/config/search/votingapi/like_and_dislike', $edit, t('Save configuration'));
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$this
->drupalLogin($user2);
$this
->drupalGet('node/' . $node_id);
$this
->vote('like', 'comment', $comment_id, 'You are not allowed to vote the same way multiple times.', TRUE);
$this
->assertLikesAndDislikes('node', $node_id, '1');
$this
->assertLikesAndDislikes('comment', $comment_id, '1', '1');
$user3_permissions = [
'access comments',
];
$user3 = $this
->drupalCreateUser($user3_permissions);
$this
->drupalLogin($user3);
$this
->drupalGet('node/' . $node_id);
$this
->assertLikesAndDislikes('node', $node_id, '1', '0', TRUE);
$this
->assertLikesAndDislikes('comment', $comment_id, '1', '1', TRUE);
}
protected function vote($vote_type, $entity_type_id, $entity_id, $message = NULL, $cancel = FALSE) {
$page = $this
->getSession()
->getPage();
$container_id = "{$vote_type}-container-{$entity_type_id}-{$entity_id}";
$link = $page
->find('css', "#{$container_id} a");
$link
->click();
$this
->assertSession()
->assertWaitOnAjaxRequest();
if ($message) {
}
if (!$cancel) {
$this
->assertEquals('voted', $link
->getAttribute('class'));
}
}
protected function assertLikesAndDislikes($entity_type_id, $entity_id, $likes = '0', $dislikes = '0', $disabled = FALSE) {
$like_container_id = '#like-container-' . $entity_type_id . '-' . $entity_id;
$this
->assertSession()
->elementAttributeContains('css', $like_container_id . ' a', 'data-entity-type', $entity_type_id);
$this
->assertSession()
->elementAttributeContains('css', $like_container_id . ' a', 'data-entity-id', $entity_id);
$this
->assertSession()
->elementContains('css', $like_container_id . ' span.count', $likes);
$dislike_container_id = '#dislike-container-' . $entity_type_id . '-' . $entity_id;
$this
->assertSession()
->elementAttributeContains('css', $dislike_container_id . ' a', 'data-entity-type', $entity_type_id);
$this
->assertSession()
->elementAttributeContains('css', $dislike_container_id . ' a', 'data-entity-id', $entity_id);
$this
->assertSession()
->elementContains('css', $dislike_container_id . ' span.count', $dislikes);
if ($disabled) {
$this
->assertSession()
->elementExists('css', $like_container_id . ' a.disable-status');
$this
->assertSession()
->elementExists('css', $dislike_container_id . ' a.disable-status');
}
}
protected function assertVotingIconExistence($entity_type_id, $entity_id, $type, $exist) {
$container_id = $type . '-container-' . $entity_type_id . '-' . $entity_id;
$css_selector = "#{$container_id} a[data-entity-type]";
if ($exist) {
$this
->assertSession()
->elementExists('css', $css_selector);
}
else {
$this
->assertSession()
->elementNotExists('css', $css_selector);
}
}
}