Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\comment\Unit;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\comment\CommentLinkBuilder;
|
Chris@0
|
6 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
|
Chris@18
|
7 use Drupal\Core\Entity\EntityTypeManagerInterface;
|
Chris@0
|
8 use Drupal\Core\Url;
|
Chris@0
|
9 use Drupal\node\NodeInterface;
|
Chris@0
|
10 use Drupal\Tests\Traits\Core\GeneratePermutationsTrait;
|
Chris@0
|
11 use Drupal\Tests\UnitTestCase;
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * @coversDefaultClass \Drupal\comment\CommentLinkBuilder
|
Chris@0
|
15 * @group comment
|
Chris@0
|
16 */
|
Chris@0
|
17 class CommentLinkBuilderTest extends UnitTestCase {
|
Chris@0
|
18
|
Chris@0
|
19 use GeneratePermutationsTrait;
|
Chris@0
|
20
|
Chris@0
|
21 /**
|
Chris@0
|
22 * Comment manager mock.
|
Chris@0
|
23 *
|
Chris@0
|
24 * @var \Drupal\comment\CommentManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
Chris@0
|
25 */
|
Chris@0
|
26 protected $commentManager;
|
Chris@0
|
27
|
Chris@0
|
28 /**
|
Chris@0
|
29 * String translation mock.
|
Chris@0
|
30 *
|
Chris@0
|
31 * @var \Drupal\Core\StringTranslation\TranslationInterface|\PHPUnit_Framework_MockObject_MockObject
|
Chris@0
|
32 */
|
Chris@0
|
33 protected $stringTranslation;
|
Chris@0
|
34
|
Chris@0
|
35 /**
|
Chris@18
|
36 * The entity type manager.
|
Chris@0
|
37 *
|
Chris@18
|
38 * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
Chris@0
|
39 */
|
Chris@18
|
40 protected $entityTypeManager;
|
Chris@0
|
41
|
Chris@0
|
42 /**
|
Chris@0
|
43 * Module handler mock.
|
Chris@0
|
44 *
|
Chris@0
|
45 * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
|
Chris@0
|
46 */
|
Chris@0
|
47 protected $moduleHandler;
|
Chris@0
|
48
|
Chris@0
|
49 /**
|
Chris@0
|
50 * Current user proxy mock.
|
Chris@0
|
51 *
|
Chris@0
|
52 * @var \Drupal\Core\Session\AccountProxyInterface|\PHPUnit_Framework_MockObject_MockObject
|
Chris@0
|
53 */
|
Chris@0
|
54 protected $currentUser;
|
Chris@0
|
55
|
Chris@0
|
56 /**
|
Chris@0
|
57 * Timestamp used in test.
|
Chris@0
|
58 *
|
Chris@0
|
59 * @var int
|
Chris@0
|
60 */
|
Chris@0
|
61 protected $timestamp;
|
Chris@0
|
62
|
Chris@0
|
63 /**
|
Chris@17
|
64 * @var \Drupal\comment\CommentLinkBuilderInterface
|
Chris@0
|
65 */
|
Chris@0
|
66 protected $commentLinkBuilder;
|
Chris@0
|
67
|
Chris@0
|
68 /**
|
Chris@0
|
69 * Prepares mocks for the test.
|
Chris@0
|
70 */
|
Chris@0
|
71 protected function setUp() {
|
Chris@0
|
72 $this->commentManager = $this->getMock('\Drupal\comment\CommentManagerInterface');
|
Chris@0
|
73 $this->stringTranslation = $this->getStringTranslationStub();
|
Chris@18
|
74 $this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
|
Chris@0
|
75 $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
|
Chris@0
|
76 $this->currentUser = $this->getMock('\Drupal\Core\Session\AccountProxyInterface');
|
Chris@18
|
77 $this->commentLinkBuilder = new CommentLinkBuilder($this->currentUser, $this->commentManager, $this->moduleHandler, $this->stringTranslation, $this->entityTypeManager);
|
Chris@0
|
78 $this->commentManager->expects($this->any())
|
Chris@0
|
79 ->method('getFields')
|
Chris@0
|
80 ->with('node')
|
Chris@0
|
81 ->willReturn([
|
Chris@0
|
82 'comment' => [],
|
Chris@0
|
83 ]);
|
Chris@0
|
84 $this->commentManager->expects($this->any())
|
Chris@0
|
85 ->method('forbiddenMessage')
|
Chris@0
|
86 ->willReturn("Can't let you do that Dave.");
|
Chris@0
|
87 $this->stringTranslation->expects($this->any())
|
Chris@0
|
88 ->method('formatPlural')
|
Chris@0
|
89 ->willReturnArgument(1);
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 /**
|
Chris@0
|
93 * Test the buildCommentedEntityLinks method.
|
Chris@0
|
94 *
|
Chris@0
|
95 * @param \Drupal\node\NodeInterface|\PHPUnit_Framework_MockObject_MockObject $node
|
Chris@0
|
96 * Mock node.
|
Chris@0
|
97 * @param array $context
|
Chris@0
|
98 * Context for the links.
|
Chris@0
|
99 * @param bool $has_access_comments
|
Chris@0
|
100 * TRUE if the user has 'access comments' permission.
|
Chris@0
|
101 * @param bool $history_exists
|
Chris@0
|
102 * TRUE if the history module exists.
|
Chris@0
|
103 * @param bool $has_post_comments
|
Chris@0
|
104 * TRUE if the use has 'post comments' permission.
|
Chris@0
|
105 * @param bool $is_anonymous
|
Chris@0
|
106 * TRUE if the user is anonymous.
|
Chris@0
|
107 * @param array $expected
|
Chris@0
|
108 * Array of expected links keyed by link ID. Can be either string (link
|
Chris@0
|
109 * title) or array of link properties.
|
Chris@0
|
110 *
|
Chris@0
|
111 * @dataProvider getLinkCombinations
|
Chris@0
|
112 *
|
Chris@0
|
113 * @covers ::buildCommentedEntityLinks
|
Chris@0
|
114 */
|
Chris@0
|
115 public function testCommentLinkBuilder(NodeInterface $node, $context, $has_access_comments, $history_exists, $has_post_comments, $is_anonymous, $expected) {
|
Chris@0
|
116 $this->moduleHandler->expects($this->any())
|
Chris@0
|
117 ->method('moduleExists')
|
Chris@0
|
118 ->with('history')
|
Chris@0
|
119 ->willReturn($history_exists);
|
Chris@0
|
120 $this->currentUser->expects($this->any())
|
Chris@0
|
121 ->method('hasPermission')
|
Chris@0
|
122 ->willReturnMap([
|
Chris@0
|
123 ['access comments', $has_access_comments],
|
Chris@0
|
124 ['post comments', $has_post_comments],
|
Chris@0
|
125 ]);
|
Chris@0
|
126 $this->currentUser->expects($this->any())
|
Chris@0
|
127 ->method('isAuthenticated')
|
Chris@0
|
128 ->willReturn(!$is_anonymous);
|
Chris@0
|
129 $this->currentUser->expects($this->any())
|
Chris@0
|
130 ->method('isAnonymous')
|
Chris@0
|
131 ->willReturn($is_anonymous);
|
Chris@0
|
132 $links = $this->commentLinkBuilder->buildCommentedEntityLinks($node, $context);
|
Chris@0
|
133 if (!empty($expected)) {
|
Chris@0
|
134 if (!empty($links)) {
|
Chris@0
|
135 foreach ($expected as $link => $detail) {
|
Chris@0
|
136 if (is_array($detail)) {
|
Chris@0
|
137 // Array of link attributes.
|
Chris@0
|
138 foreach ($detail as $key => $value) {
|
Chris@0
|
139 $this->assertEquals($value, $links['comment__comment']['#links'][$link][$key]);
|
Chris@0
|
140 }
|
Chris@0
|
141 }
|
Chris@0
|
142 else {
|
Chris@0
|
143 // Just the title.
|
Chris@0
|
144 $this->assertEquals($detail, $links['comment__comment']['#links'][$link]['title']);
|
Chris@0
|
145 }
|
Chris@0
|
146 }
|
Chris@0
|
147 }
|
Chris@0
|
148 else {
|
Chris@0
|
149 $this->fail('Expected links but found none.');
|
Chris@0
|
150 }
|
Chris@0
|
151 }
|
Chris@0
|
152 else {
|
Chris@0
|
153 $this->assertSame($links, $expected);
|
Chris@0
|
154 }
|
Chris@0
|
155 }
|
Chris@0
|
156
|
Chris@0
|
157 /**
|
Chris@0
|
158 * Data provider for ::testCommentLinkBuilder.
|
Chris@0
|
159 */
|
Chris@0
|
160 public function getLinkCombinations() {
|
Chris@0
|
161 $cases = [];
|
Chris@0
|
162 // No links should be created if the entity doesn't have the field.
|
Chris@0
|
163 $cases[] = [
|
Chris@0
|
164 $this->getMockNode(FALSE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1),
|
Chris@0
|
165 ['view_mode' => 'teaser'],
|
Chris@0
|
166 TRUE,
|
Chris@0
|
167 TRUE,
|
Chris@0
|
168 TRUE,
|
Chris@0
|
169 TRUE,
|
Chris@0
|
170 [],
|
Chris@0
|
171 ];
|
Chris@0
|
172 foreach (['search_result', 'search_index', 'print'] as $view_mode) {
|
Chris@0
|
173 // Nothing should be output in these view modes.
|
Chris@0
|
174 $cases[] = [
|
Chris@0
|
175 $this->getMockNode(TRUE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1),
|
Chris@0
|
176 ['view_mode' => $view_mode],
|
Chris@0
|
177 TRUE,
|
Chris@0
|
178 TRUE,
|
Chris@0
|
179 TRUE,
|
Chris@0
|
180 TRUE,
|
Chris@0
|
181 [],
|
Chris@0
|
182 ];
|
Chris@0
|
183 }
|
Chris@0
|
184 // All other combinations.
|
Chris@0
|
185 $combinations = [
|
Chris@0
|
186 'is_anonymous' => [FALSE, TRUE],
|
Chris@0
|
187 'comment_count' => [0, 1],
|
Chris@0
|
188 'has_access_comments' => [0, 1],
|
Chris@0
|
189 'history_exists' => [FALSE, TRUE],
|
Chris@0
|
190 'has_post_comments' => [0, 1],
|
Chris@0
|
191 'form_location' => [CommentItemInterface::FORM_BELOW, CommentItemInterface::FORM_SEPARATE_PAGE],
|
Chris@0
|
192 'comments' => [
|
Chris@0
|
193 CommentItemInterface::OPEN,
|
Chris@0
|
194 CommentItemInterface::CLOSED,
|
Chris@0
|
195 CommentItemInterface::HIDDEN,
|
Chris@0
|
196 ],
|
Chris@0
|
197 'view_mode' => [
|
Chris@0
|
198 'teaser', 'rss', 'full',
|
Chris@0
|
199 ],
|
Chris@0
|
200 ];
|
Chris@0
|
201 $permutations = $this->generatePermutations($combinations);
|
Chris@0
|
202 foreach ($permutations as $combination) {
|
Chris@0
|
203 $case = [
|
Chris@0
|
204 $this->getMockNode(TRUE, $combination['comments'], $combination['form_location'], $combination['comment_count']),
|
Chris@0
|
205 ['view_mode' => $combination['view_mode']],
|
Chris@0
|
206 $combination['has_access_comments'],
|
Chris@0
|
207 $combination['history_exists'],
|
Chris@0
|
208 $combination['has_post_comments'],
|
Chris@0
|
209 $combination['is_anonymous'],
|
Chris@0
|
210 ];
|
Chris@0
|
211 $expected = [];
|
Chris@0
|
212 // When comments are enabled in teaser mode, and comments exist, and the
|
Chris@0
|
213 // user has access - we can output the comment count.
|
Chris@0
|
214 if ($combination['comments'] && $combination['view_mode'] == 'teaser' && $combination['comment_count'] && $combination['has_access_comments']) {
|
Chris@0
|
215 $expected['comment-comments'] = '1 comment';
|
Chris@0
|
216 // And if history module exists, we can show a 'new comments' link.
|
Chris@0
|
217 if ($combination['history_exists']) {
|
Chris@0
|
218 $expected['comment-new-comments'] = '';
|
Chris@0
|
219 }
|
Chris@0
|
220 }
|
Chris@0
|
221 // All view modes other than RSS.
|
Chris@0
|
222 if ($combination['view_mode'] != 'rss') {
|
Chris@0
|
223 // Where commenting is open.
|
Chris@0
|
224 if ($combination['comments'] == CommentItemInterface::OPEN) {
|
Chris@0
|
225 // And the user has post-comments permission.
|
Chris@0
|
226 if ($combination['has_post_comments']) {
|
Chris@0
|
227 // If the view mode is teaser, or the user can access comments and
|
Chris@0
|
228 // comments exist or the form is on a separate page.
|
Chris@0
|
229 if ($combination['view_mode'] == 'teaser' || ($combination['has_access_comments'] && $combination['comment_count']) || $combination['form_location'] == CommentItemInterface::FORM_SEPARATE_PAGE) {
|
Chris@0
|
230 // There should be a add comment link.
|
Chris@0
|
231 $expected['comment-add'] = ['title' => 'Add new comment'];
|
Chris@0
|
232 if ($combination['form_location'] == CommentItemInterface::FORM_BELOW) {
|
Chris@0
|
233 // On the same page.
|
Chris@0
|
234 $expected['comment-add']['url'] = Url::fromRoute('node.view');
|
Chris@0
|
235 }
|
Chris@0
|
236 else {
|
Chris@0
|
237 // On a separate page.
|
Chris@0
|
238 $expected['comment-add']['url'] = Url::fromRoute('comment.reply', ['entity_type' => 'node', 'entity' => 1, 'field_name' => 'comment']);
|
Chris@0
|
239 }
|
Chris@0
|
240 }
|
Chris@0
|
241 }
|
Chris@0
|
242 elseif ($combination['is_anonymous']) {
|
Chris@0
|
243 // Anonymous users get the forbidden message if the can't post
|
Chris@0
|
244 // comments.
|
Chris@0
|
245 $expected['comment-forbidden'] = "Can't let you do that Dave.";
|
Chris@0
|
246 }
|
Chris@0
|
247 }
|
Chris@0
|
248 }
|
Chris@0
|
249
|
Chris@0
|
250 $case[] = $expected;
|
Chris@0
|
251 $cases[] = $case;
|
Chris@0
|
252 }
|
Chris@0
|
253 return $cases;
|
Chris@0
|
254 }
|
Chris@0
|
255
|
Chris@0
|
256 /**
|
Chris@0
|
257 * Builds a mock node based on given scenario.
|
Chris@0
|
258 *
|
Chris@0
|
259 * @param bool $has_field
|
Chris@0
|
260 * TRUE if the node has the 'comment' field.
|
Chris@0
|
261 * @param int $comment_status
|
Chris@0
|
262 * One of CommentItemInterface::OPEN|HIDDEN|CLOSED
|
Chris@0
|
263 * @param int $form_location
|
Chris@0
|
264 * One of CommentItemInterface::FORM_BELOW|FORM_SEPARATE_PAGE
|
Chris@0
|
265 * @param int $comment_count
|
Chris@0
|
266 * Number of comments against the field.
|
Chris@0
|
267 *
|
Chris@0
|
268 * @return \Drupal\node\NodeInterface|\PHPUnit_Framework_MockObject_MockObject
|
Chris@0
|
269 * Mock node for testing.
|
Chris@0
|
270 */
|
Chris@0
|
271 protected function getMockNode($has_field, $comment_status, $form_location, $comment_count) {
|
Chris@0
|
272 $node = $this->getMock('\Drupal\node\NodeInterface');
|
Chris@14
|
273 $node->expects($this->any())
|
Chris@0
|
274 ->method('hasField')
|
Chris@0
|
275 ->willReturn($has_field);
|
Chris@0
|
276
|
Chris@0
|
277 if (empty($this->timestamp)) {
|
Chris@0
|
278 $this->timestamp = time();
|
Chris@0
|
279 }
|
Chris@0
|
280 $field_item = (object) [
|
Chris@0
|
281 'status' => $comment_status,
|
Chris@0
|
282 'comment_count' => $comment_count,
|
Chris@0
|
283 'last_comment_timestamp' => $this->timestamp,
|
Chris@0
|
284 ];
|
Chris@0
|
285 $node->expects($this->any())
|
Chris@0
|
286 ->method('get')
|
Chris@0
|
287 ->with('comment')
|
Chris@0
|
288 ->willReturn($field_item);
|
Chris@0
|
289
|
Chris@0
|
290 $field_definition = $this->getMock('\Drupal\Core\Field\FieldDefinitionInterface');
|
Chris@0
|
291 $field_definition->expects($this->any())
|
Chris@0
|
292 ->method('getSetting')
|
Chris@0
|
293 ->with('form_location')
|
Chris@0
|
294 ->willReturn($form_location);
|
Chris@0
|
295 $node->expects($this->any())
|
Chris@0
|
296 ->method('getFieldDefinition')
|
Chris@0
|
297 ->with('comment')
|
Chris@0
|
298 ->willReturn($field_definition);
|
Chris@0
|
299
|
Chris@0
|
300 $node->expects($this->any())
|
Chris@0
|
301 ->method('language')
|
Chris@0
|
302 ->willReturn('und');
|
Chris@0
|
303
|
Chris@0
|
304 $node->expects($this->any())
|
Chris@0
|
305 ->method('getEntityTypeId')
|
Chris@0
|
306 ->willReturn('node');
|
Chris@0
|
307
|
Chris@0
|
308 $node->expects($this->any())
|
Chris@0
|
309 ->method('id')
|
Chris@0
|
310 ->willReturn(1);
|
Chris@0
|
311
|
Chris@0
|
312 $url = Url::fromRoute('node.view');
|
Chris@0
|
313 $node->expects($this->any())
|
Chris@17
|
314 ->method('toUrl')
|
Chris@0
|
315 ->willReturn($url);
|
Chris@0
|
316 $node->expects($this->any())
|
Chris@0
|
317 ->method('url')
|
Chris@0
|
318 ->willReturn(['route_name' => 'node.view']);
|
Chris@0
|
319
|
Chris@0
|
320 return $node;
|
Chris@0
|
321 }
|
Chris@0
|
322
|
Chris@0
|
323 }
|
Chris@0
|
324
|
Chris@0
|
325 namespace Drupal\comment;
|
Chris@0
|
326
|
Chris@0
|
327 if (!function_exists('history_read')) {
|
Chris@17
|
328
|
Chris@0
|
329 function history_read() {
|
Chris@0
|
330 return 0;
|
Chris@0
|
331 }
|
Chris@17
|
332
|
Chris@0
|
333 }
|