Newer
Older
<?php
namespace Drupal\Tests\comment\Unit;
use Drupal\comment\CommentLinkBuilder;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;
Alex Pott
committed
use Drupal\Tests\Traits\Core\GeneratePermutationsTrait;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\comment\CommentLinkBuilder
* @group comment
*/
class CommentLinkBuilderTest extends UnitTestCase {
Alex Pott
committed
use GeneratePermutationsTrait;
/**
* Comment manager mock.
*
* @var \Drupal\comment\CommentManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $commentManager;
/**
* String translation mock.
*
* @var \Drupal\Core\StringTranslation\TranslationInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $stringTranslation;
/**
* The entity manager service.
*
* @var \Drupal\Core\Entity\EntityManagerInterface
*/
protected $entityManager;
/**
* Module handler mock.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $moduleHandler;
/**
* Current user proxy mock.
*
* @var \Drupal\Core\Session\AccountProxyInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $currentUser;
/**
* Timestamp used in test.
*
* @var int
*/
protected $timestamp;
/**
Lee Rowlands
committed
* @var \Drupal\comment\CommentLinkBuilderInterface
*/
protected $commentLinkBuilder;
/**
* Prepares mocks for the test.
*/
protected function setUp() {
$this->commentManager = $this->getMock('\Drupal\comment\CommentManagerInterface');
$this->stringTranslation = $this->getStringTranslationStub();
$this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
$this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
$this->currentUser = $this->getMock('\Drupal\Core\Session\AccountProxyInterface');
$this->commentLinkBuilder = new CommentLinkBuilder($this->currentUser, $this->commentManager, $this->moduleHandler, $this->stringTranslation, $this->entityManager);
$this->commentManager->expects($this->any())
->method('getFields')
->with('node')
->willReturn([
'comment' => [],
]);
$this->commentManager->expects($this->any())
->method('forbiddenMessage')
->willReturn("Can't let you do that Dave.");
$this->stringTranslation->expects($this->any())
->method('formatPlural')
->willReturnArgument(1);
}
/**
* Test the buildCommentedEntityLinks method.
*
* @param \Drupal\node\NodeInterface|\PHPUnit_Framework_MockObject_MockObject $node
* Mock node.
* @param array $context
* Context for the links.
* @param bool $has_access_comments
* TRUE if the user has 'access comments' permission.
* @param bool $history_exists
* TRUE if the history module exists.
* @param bool $has_post_comments
* TRUE if the use has 'post comments' permission.
* @param bool $is_anonymous
* TRUE if the user is anonymous.
* @param array $expected
* Array of expected links keyed by link ID. Can be either string (link
* title) or array of link properties.
*
* @dataProvider getLinkCombinations
*
* @covers ::buildCommentedEntityLinks
*/
public function testCommentLinkBuilder(NodeInterface $node, $context, $has_access_comments, $history_exists, $has_post_comments, $is_anonymous, $expected) {
$this->moduleHandler->expects($this->any())
->method('moduleExists')
->with('history')
->willReturn($history_exists);
$this->currentUser->expects($this->any())
->method('hasPermission')
->willReturnMap([
['access comments', $has_access_comments],
['post comments', $has_post_comments],
]);
$this->currentUser->expects($this->any())
->method('isAuthenticated')
->willReturn(!$is_anonymous);
$this->currentUser->expects($this->any())
->method('isAnonymous')
->willReturn($is_anonymous);
$links = $this->commentLinkBuilder->buildCommentedEntityLinks($node, $context);
if (!empty($expected)) {
if (!empty($links)) {
foreach ($expected as $link => $detail) {
if (is_array($detail)) {
// Array of link attributes.
foreach ($detail as $key => $value) {
$this->assertEquals($value, $links['comment__comment']['#links'][$link][$key]);
}
}
else {
// Just the title.
$this->assertEquals($detail, $links['comment__comment']['#links'][$link]['title']);
}
}
}
else {
$this->fail('Expected links but found none.');
}
}
else {
$this->assertSame($links, $expected);
}
}
/**
* Data provider for ::testCommentLinkBuilder.
*/
public function getLinkCombinations() {
$cases = [];
// No links should be created if the entity doesn't have the field.
$cases[] = [
$this->getMockNode(FALSE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1),
['view_mode' => 'teaser'],
TRUE,
TRUE,
TRUE,
TRUE,
[],
];
foreach (['search_result', 'search_index', 'print'] as $view_mode) {
// Nothing should be output in these view modes.
$cases[] = [
$this->getMockNode(TRUE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1),
['view_mode' => $view_mode],
TRUE,
TRUE,
TRUE,
TRUE,
[],
];
}
// All other combinations.
$combinations = [
'is_anonymous' => [FALSE, TRUE],
'comment_count' => [0, 1],
'has_access_comments' => [0, 1],
'history_exists' => [FALSE, TRUE],
'has_post_comments' => [0, 1],
'form_location' => [CommentItemInterface::FORM_BELOW, CommentItemInterface::FORM_SEPARATE_PAGE],
'comments' => [
CommentItemInterface::OPEN,
CommentItemInterface::CLOSED,
CommentItemInterface::HIDDEN,
],
'view_mode' => [
'teaser', 'rss', 'full',
],
];
Alex Pott
committed
$permutations = $this->generatePermutations($combinations);
foreach ($permutations as $combination) {
$case = [
$this->getMockNode(TRUE, $combination['comments'], $combination['form_location'], $combination['comment_count']),
['view_mode' => $combination['view_mode']],
$combination['has_access_comments'],
$combination['history_exists'],
$combination['has_post_comments'],
$combination['is_anonymous'],
];
$expected = [];
// When comments are enabled in teaser mode, and comments exist, and the
// user has access - we can output the comment count.
if ($combination['comments'] && $combination['view_mode'] == 'teaser' && $combination['comment_count'] && $combination['has_access_comments']) {
$expected['comment-comments'] = '1 comment';
// And if history module exists, we can show a 'new comments' link.
if ($combination['history_exists']) {
$expected['comment-new-comments'] = '';
}
}
// All view modes other than RSS.
if ($combination['view_mode'] != 'rss') {
// Where commenting is open.
if ($combination['comments'] == CommentItemInterface::OPEN) {
// And the user has post-comments permission.
if ($combination['has_post_comments']) {
// If the view mode is teaser, or the user can access comments and
// comments exist or the form is on a separate page.
if ($combination['view_mode'] == 'teaser' || ($combination['has_access_comments'] && $combination['comment_count']) || $combination['form_location'] == CommentItemInterface::FORM_SEPARATE_PAGE) {
// There should be a add comment link.
$expected['comment-add'] = ['title' => 'Add new comment'];
if ($combination['form_location'] == CommentItemInterface::FORM_BELOW) {
// On the same page.
$expected['comment-add']['url'] = Url::fromRoute('node.view');
}
else {
// On a separate page.
$expected['comment-add']['url'] = Url::fromRoute('comment.reply', ['entity_type' => 'node', 'entity' => 1, 'field_name' => 'comment']);
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
}
}
}
elseif ($combination['is_anonymous']) {
// Anonymous users get the forbidden message if the can't post
// comments.
$expected['comment-forbidden'] = "Can't let you do that Dave.";
}
}
}
$case[] = $expected;
$cases[] = $case;
}
return $cases;
}
/**
* Builds a mock node based on given scenario.
*
* @param bool $has_field
* TRUE if the node has the 'comment' field.
* @param int $comment_status
* One of CommentItemInterface::OPEN|HIDDEN|CLOSED
* @param int $form_location
* One of CommentItemInterface::FORM_BELOW|FORM_SEPARATE_PAGE
* @param int $comment_count
* Number of comments against the field.
*
* @return \Drupal\node\NodeInterface|\PHPUnit_Framework_MockObject_MockObject
* Mock node for testing.
*/
protected function getMockNode($has_field, $comment_status, $form_location, $comment_count) {
$node = $this->getMock('\Drupal\node\NodeInterface');
$node->expects($this->any())
->method('hasField')
->willReturn($has_field);
if (empty($this->timestamp)) {
$this->timestamp = time();
}
$field_item = (object) [
'status' => $comment_status,
'comment_count' => $comment_count,
'last_comment_timestamp' => $this->timestamp,
];
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
$node->expects($this->any())
->method('get')
->with('comment')
->willReturn($field_item);
$field_definition = $this->getMock('\Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->any())
->method('getSetting')
->with('form_location')
->willReturn($form_location);
$node->expects($this->any())
->method('getFieldDefinition')
->with('comment')
->willReturn($field_definition);
$node->expects($this->any())
->method('language')
->willReturn('und');
$node->expects($this->any())
->method('getEntityTypeId')
->willReturn('node');
$node->expects($this->any())
->method('id')
->willReturn(1);
$url = Url::fromRoute('node.view');
$node->expects($this->any())
->method('toUrl')
->willReturn($url);
$node->expects($this->any())
->method('url')
->willReturn(['route_name' => 'node.view']);
return $node;
}
}
namespace Drupal\comment;
if (!function_exists('history_read')) {
function history_read() {
return 0;
}