comparison core/modules/rdf/tests/src/Functional/StandardProfileTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace Drupal\Tests\rdf\Functional;
4
5 use Drupal\Core\Url;
6 use Drupal\file\Entity\File;
7 use Drupal\image\Entity\ImageStyle;
8 use Drupal\node\Entity\NodeType;
9 use Drupal\node\NodeInterface;
10 use Drupal\Tests\BrowserTestBase;
11 use Drupal\comment\Entity\Comment;
12 use Drupal\taxonomy\Entity\Term;
13
14 /**
15 * Tests the RDF mappings and RDFa markup of the standard profile.
16 *
17 * @group rdf
18 */
19 class StandardProfileTest extends BrowserTestBase {
20
21 /**
22 * The profile used during tests.
23 *
24 * This purposefully uses the standard profile.
25 *
26 * @var string
27 */
28 public $profile = 'standard';
29
30 /**
31 * @var string
32 */
33 protected $baseUri;
34
35 /**
36 * @var \Drupal\user\UserInterface
37 */
38 protected $adminUser;
39
40 /**
41 * @var \Drupal\user\UserInterface
42 */
43 protected $webUser;
44
45 /**
46 * @var \Drupal\taxonomy\TermInterface
47 */
48 protected $term;
49
50 /**
51 * @var \Drupal\file\FileInterface
52 */
53 protected $image;
54
55 /**
56 * @var \Drupal\node\NodeInterface
57 */
58 protected $article;
59
60 /**
61 * @var \Drupal\comment\CommentInterface
62 */
63 protected $articleComment;
64
65 /**
66 * @var \Drupal\node\NodeInterface
67 */
68 protected $page;
69
70 /**
71 * @var string
72 */
73 protected $imageUri;
74
75 /**
76 * @var string
77 */
78 protected $termUri;
79
80 /**
81 * @var string
82 */
83 protected $articleUri;
84
85 /**
86 * @var string
87 */
88 protected $pageUri;
89
90 /**
91 * @var string
92 */
93 protected $authorUri;
94
95 /**
96 * @var string
97 */
98 protected $articleCommentUri;
99
100 /**
101 * @var string
102 */
103 protected $commenterUri;
104
105 protected function setUp() {
106 parent::setUp();
107
108 // Use Classy theme for testing markup output.
109 \Drupal::service('theme_handler')->install(['classy']);
110 $this->config('system.theme')->set('default', 'classy')->save();
111
112 $this->baseUri = \Drupal::url('<front>', [], ['absolute' => TRUE]);
113
114 // Create two test users.
115 $this->adminUser = $this->drupalCreateUser([
116 'administer content types',
117 'administer comments',
118 'access comments',
119 'access content',
120 ]);
121 $this->webUser = $this->drupalCreateUser([
122 'access comments',
123 'post comments',
124 'skip comment approval',
125 'access content',
126 ]);
127
128 $this->drupalLogin($this->adminUser);
129
130 // Create term.
131 $this->term = Term::create([
132 'name' => $this->randomMachineName(),
133 'description' => $this->randomMachineName(),
134 'vid' => 'tags',
135 ]);
136 $this->term->save();
137
138 // Create image.
139 file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
140 $this->image = File::create(['uri' => 'public://example.jpg']);
141 $this->image->save();
142
143 // Create article.
144 $article_settings = [
145 'type' => 'article',
146 'promote' => NodeInterface::PROMOTED,
147 'field_image' => [
148 [
149 'target_id' => $this->image->id(),
150 ],
151 ],
152 'field_tags' => [
153 [
154 'target_id' => $this->term->id(),
155 ],
156 ],
157 ];
158 $this->article = $this->drupalCreateNode($article_settings);
159 // Create second article to test teaser list.
160 $this->drupalCreateNode(['type' => 'article', 'promote' => NodeInterface::PROMOTED]);
161
162 // Create article comment.
163 $this->articleComment = $this->saveComment($this->article->id(), $this->webUser->id(), NULL, 0);
164
165 // Create page.
166 $this->page = $this->drupalCreateNode(['type' => 'page']);
167
168 // Set URIs.
169 // Image.
170 $image_file = $this->article->get('field_image')->entity;
171 $this->imageUri = ImageStyle::load('large')->buildUrl($image_file->getFileUri());
172 // Term.
173 $this->termUri = $this->term->url('canonical', ['absolute' => TRUE]);
174 // Article.
175 $this->articleUri = $this->article->url('canonical', ['absolute' => TRUE]);
176 // Page.
177 $this->pageUri = $this->page->url('canonical', ['absolute' => TRUE]);
178 // Author.
179 $this->authorUri = $this->adminUser->url('canonical', ['absolute' => TRUE]);
180 // Comment.
181 $this->articleCommentUri = $this->articleComment->url('canonical', ['absolute' => TRUE]);
182 // Commenter.
183 $this->commenterUri = $this->webUser->url('canonical', ['absolute' => TRUE]);
184
185 $this->drupalLogout();
186 }
187
188 /**
189 * Tests that data is exposed correctly when using standard profile.
190 *
191 * Because tests using standard profile take a very long time to run, and
192 * because there is no manipulation of config or data within the test, simply
193 * run all the tests from within this function.
194 */
195 public function testRdfaOutput() {
196 $this->doFrontPageRdfaTests();
197 $this->doArticleRdfaTests();
198 $this->doPageRdfaTests();
199 $this->doUserRdfaTests();
200 $this->doTermRdfaTests();
201 }
202
203 /**
204 * Tests that data is exposed in the front page teasers.
205 */
206 protected function doFrontPageRdfaTests() {
207 // Feed the HTML into the parser.
208 $graph = $this->getRdfGraph(Url::fromRoute('<front>'));
209
210 // Ensure that both articles are listed.
211 $this->assertEqual(2, count($graph->allOfType('http://schema.org/Article')), 'Two articles found on front page.');
212
213 // Test interaction count.
214 $expected_value = [
215 'type' => 'literal',
216 'value' => 'UserComments:1',
217 'lang' => 'en',
218 ];
219 $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/interactionCount', $expected_value), "Teaser comment count was found (schema:interactionCount).");
220
221 // Test the properties that are common between pages and articles and are
222 // displayed in full and teaser mode.
223 $this->assertRdfaCommonNodeProperties($graph, $this->article, "Teaser");
224 // Test properties that are displayed in both teaser and full mode.
225 $this->assertRdfaArticleProperties($graph, "Teaser");
226
227 // @todo Once the image points to the original instead of the processed
228 // image, move this to testArticleProperties().
229 $image_file = $this->article->get('field_image')->entity;
230 $image_uri = ImageStyle::load('medium')->buildUrl($image_file->getFileUri());
231 $expected_value = [
232 'type' => 'uri',
233 'value' => $image_uri,
234 ];
235 $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/image', $expected_value), "Teaser image was found (schema:image).");
236 }
237
238 /**
239 * Tests that article data is exposed using RDFa.
240 *
241 * Two fields are not tested for output here. Changed date is not displayed
242 * on the page, so there is no test for output in node view. Comment count is
243 * displayed in teaser view, so it is tested in the front article tests.
244 */
245 protected function doArticleRdfaTests() {
246 // Feed the HTML into the parser.
247 $graph = $this->getRdfGraph($this->article->urlInfo());
248
249 // Type.
250 $this->assertEqual($graph->type($this->articleUri), 'schema:Article', 'Article type was found (schema:Article).');
251
252 // Test the properties that are common between pages and articles.
253 $this->assertRdfaCommonNodeProperties($graph, $this->article, "Article");
254 // Test properties that are displayed in both teaser and full mode.
255 $this->assertRdfaArticleProperties($graph, "Article");
256 // Test the comment properties displayed on articles.
257 $this->assertRdfaNodeCommentProperties($graph);
258
259 // @todo Once the image points to the original instead of the processed
260 // image, move this to testArticleProperties().
261 $expected_value = [
262 'type' => 'uri',
263 'value' => $this->imageUri,
264 ];
265 $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/image', $expected_value), "Article image was found (schema:image).");
266 }
267
268 /**
269 * Tests that page data is exposed using RDFa.
270 *
271 * Two fields are not tested for output here. Changed date is not displayed
272 * on the page, so there is no test for output in node view. Comment count is
273 * displayed in teaser view, so it is tested in the front page tests.
274 */
275 protected function doPageRdfaTests() {
276 // The standard profile hides the created date on pages. Revert display to
277 // true for testing.
278 // @todo Clean-up standard profile defaults.
279 $node_type = NodeType::load('page');
280 $node_type->setDisplaySubmitted(TRUE);
281 $node_type->save();
282
283 // Feed the HTML into the parser.
284 $graph = $this->getRdfGraph($this->page->urlInfo());
285
286 // Type.
287 $this->assertEqual($graph->type($this->pageUri), 'schema:WebPage', 'Page type was found (schema:WebPage).');
288
289 // Test the properties that are common between pages and articles.
290 $this->assertRdfaCommonNodeProperties($graph, $this->page, "Page");
291 }
292
293 /**
294 * Tests that user data is exposed on user page.
295 */
296 protected function doUserRdfaTests() {
297 $this->drupalLogin($this->rootUser);
298
299 // Feed the HTML into the parser.
300 $graph = $this->getRdfGraph($this->adminUser->urlInfo());
301
302 // User type.
303 $this->assertEqual($graph->type($this->authorUri), 'schema:Person', "User type was found (schema:Person) on user page.");
304
305 // User name.
306 $expected_value = [
307 'type' => 'literal',
308 'value' => $this->adminUser->label(),
309 ];
310 $this->assertTrue($graph->hasProperty($this->authorUri, 'http://schema.org/name', $expected_value), "User name was found (schema:name) on user page.");
311
312 $this->drupalLogout();
313 }
314
315 /**
316 * Tests that term data is exposed on term page.
317 */
318 protected function doTermRdfaTests() {
319 // Feed the HTML into the parser.
320 $graph = $this->getRdfGraph($this->term->urlInfo());
321
322 // Term type.
323 $this->assertEqual($graph->type($this->termUri), 'schema:Thing', "Term type was found (schema:Thing) on term page.");
324
325 // Term name.
326 $expected_value = [
327 'type' => 'literal',
328 'value' => $this->term->getName(),
329 'lang' => 'en',
330 ];
331 $this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "Term name was found (schema:name) on term page.");
332
333 // @todo Add test for term description once it is a field:
334 // https://www.drupal.org/node/569434.
335 }
336
337 /**
338 * Tests output for properties held in common between articles and pages.
339 *
340 * @param \EasyRdf_Graph $graph
341 * The EasyRDF graph object.
342 * @param \Drupal\node\NodeInterface $node
343 * The node being displayed.
344 * @param string $message_prefix
345 * The word to use in the test assertion message.
346 */
347 protected function assertRdfaCommonNodeProperties($graph, NodeInterface $node, $message_prefix) {
348 $uri = $node->url('canonical', ['absolute' => TRUE]);
349
350 // Title.
351 $expected_value = [
352 'type' => 'literal',
353 'value' => $node->get('title')->value,
354 'lang' => 'en',
355 ];
356 $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/name', $expected_value), "$message_prefix title was found (schema:name).");
357
358 // Created date.
359 $expected_value = [
360 'type' => 'literal',
361 'value' => format_date($node->get('created')->value, 'custom', 'c', 'UTC'),
362 'lang' => 'en',
363 ];
364 $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/dateCreated', $expected_value), "$message_prefix created date was found (schema:dateCreated) in teaser.");
365
366 // Body.
367 $expected_value = [
368 'type' => 'literal',
369 'value' => $node->get('body')->value,
370 'lang' => 'en',
371 ];
372 $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/text', $expected_value), "$message_prefix body was found (schema:text) in teaser.");
373
374 // Author.
375 $expected_value = [
376 'type' => 'uri',
377 'value' => $this->authorUri,
378 ];
379 $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/author', $expected_value), "$message_prefix author was found (schema:author) in teaser.");
380
381 // Author type.
382 $this->assertEqual($graph->type($this->authorUri), 'schema:Person', "$message_prefix author type was found (schema:Person).");
383
384 // Author name.
385 $expected_value = [
386 'type' => 'literal',
387 'value' => $this->adminUser->label(),
388 ];
389 $this->assertTrue($graph->hasProperty($this->authorUri, 'http://schema.org/name', $expected_value), "$message_prefix author name was found (schema:name).");
390 }
391
392 /**
393 * Tests output for article properties displayed in both view modes.
394 *
395 * @param \EasyRdf_Graph $graph
396 * The EasyRDF graph object.
397 * @param string $message_prefix
398 * The word to use in the test assertion message.
399 */
400 protected function assertRdfaArticleProperties($graph, $message_prefix) {
401 // Tags.
402 $expected_value = [
403 'type' => 'uri',
404 'value' => $this->termUri,
405 ];
406 $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/about', $expected_value), "$message_prefix tag was found (schema:about).");
407
408 // Tag type.
409 // @todo Enable with https://www.drupal.org/node/2072791.
410 // $this->assertEqual($graph->type($this->termUri), 'schema:Thing', 'Tag type was found (schema:Thing).');
411
412 // Tag name.
413 $expected_value = [
414 'type' => 'literal',
415 'value' => $this->term->getName(),
416 'lang' => 'en',
417 ];
418 // @todo Enable with https://www.drupal.org/node/2072791.
419 // $this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "$message_prefix name was found (schema:name).");
420 }
421
422 /**
423 * Tests output for comment properties on nodes in full page view mode.
424 *
425 * @param \EasyRdf_Graph $graph
426 * The EasyRDF graph object.
427 */
428 protected function assertRdfaNodeCommentProperties($graph) {
429 // Relationship between node and comment.
430 $expected_value = [
431 'type' => 'uri',
432 'value' => $this->articleCommentUri,
433 ];
434 $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/comment', $expected_value), 'Relationship between node and comment found (schema:comment).');
435
436 // Comment type.
437 $this->assertEqual($graph->type($this->articleCommentUri), 'schema:Comment', 'Comment type was found (schema:Comment).');
438
439 // Comment title.
440 $expected_value = [
441 'type' => 'literal',
442 'value' => $this->articleComment->get('subject')->value,
443 'lang' => 'en',
444 ];
445 $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/name', $expected_value), 'Article comment title was found (schema:name).');
446
447 // Comment created date.
448 $expected_value = [
449 'type' => 'literal',
450 'value' => format_date($this->articleComment->get('created')->value, 'custom', 'c', 'UTC'),
451 'lang' => 'en',
452 ];
453 $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/dateCreated', $expected_value), 'Article comment created date was found (schema:dateCreated).');
454
455 // Comment body.
456 $text = $this->articleComment->get('comment_body')->value;
457 $expected_value = [
458 'type' => 'literal',
459 // There is an extra carriage return in the when parsing comments as
460 // output by Bartik, so it must be added to the expected value.
461 'value' => "$text
462 ",
463 'lang' => 'en',
464 ];
465 $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/text', $expected_value), 'Article comment body was found (schema:text).');
466
467 // Comment uid.
468 $expected_value = [
469 'type' => 'uri',
470 'value' => $this->commenterUri,
471 ];
472 $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/author', $expected_value), 'Article comment author was found (schema:author).');
473
474 // Comment author type.
475 $this->assertEqual($graph->type($this->commenterUri), 'schema:Person', 'Comment author type was found (schema:Person).');
476
477 // Comment author name.
478 $expected_value = [
479 'type' => 'literal',
480 'value' => $this->webUser->getUsername(),
481 ];
482 $this->assertTrue($graph->hasProperty($this->commenterUri, 'http://schema.org/name', $expected_value), 'Comment author name was found (schema:name).');
483 }
484
485 /**
486 * Creates a comment entity.
487 *
488 * @param int $nid
489 * Node id which will hold the comment.
490 * @param int $uid
491 * User id of the author of the comment. Can be NULL if $contact provided.
492 * @param mixed $contact
493 * Set to NULL for no contact info, TRUE to ignore success checking, and
494 * array of values to set contact info.
495 * @param int $pid
496 * Comment id of the parent comment in a thread.
497 *
498 * @return \Drupal\comment\Entity\Comment
499 * The saved comment.
500 */
501 protected function saveComment($nid, $uid, $contact = NULL, $pid = 0) {
502 $values = [
503 'entity_id' => $nid,
504 'entity_type' => 'node',
505 'field_name' => 'comment',
506 'uid' => $uid,
507 'pid' => $pid,
508 'subject' => $this->randomMachineName(),
509 'comment_body' => $this->randomMachineName(),
510 'status' => 1,
511 ];
512 if ($contact) {
513 $values += $contact;
514 }
515
516 $comment = Comment::create($values);
517 $comment->save();
518 return $comment;
519 }
520
521 /**
522 * Get the EasyRdf_Graph object for a page.
523 *
524 * @param \Drupal\Core\Url $url
525 * The URL object for the page.
526 *
527 * @return \EasyRdf_Graph
528 * The RDF graph object.
529 */
530 protected function getRdfGraph(Url $url) {
531 $parser = new \EasyRdf_Parser_Rdfa();
532 $graph = new \EasyRdf_Graph();
533 $parser->parse($graph, $this->drupalGet($url), 'rdfa', $this->baseUri);
534 return $graph;
535 }
536
537 }