Project

General

Profile

Paste
Download (34.8 KB) Statistics
| Branch: | Revision:

root / drupal7 / modules / rdf / rdf.test @ 175ce36f

1
<?php
2

    
3
/**
4
 * @file
5
 * Tests for rdf.module.
6
 */
7

    
8
class RdfMappingHookTestCase extends DrupalWebTestCase {
9
  public static function getInfo() {
10
    return array(
11
      'name' => 'RDF mapping hook',
12
      'description' => 'Test hook_rdf_mapping().',
13
      'group' => 'RDF',
14
    );
15
  }
16

    
17
  function setUp() {
18
    parent::setUp('rdf', 'rdf_test', 'field_test');
19
  }
20

    
21
  /**
22
   * Test that hook_rdf_mapping() correctly returns and processes mapping.
23
   */
24
  function testMapping() {
25
    // Test that the mapping is returned correctly by the hook.
26
    $mapping = rdf_mapping_load('test_entity', 'test_bundle');
27
    $this->assertIdentical($mapping['rdftype'], array('sioc:Post'), 'Mapping for rdftype is sioc:Post.');
28
    $this->assertIdentical($mapping['title'], array('predicates' => array('dc:title')), 'Mapping for title is dc:title.');
29
    $this->assertIdentical($mapping['created'], array(
30
      'predicates' => array('dc:created'),
31
      'datatype' => 'xsd:dateTime',
32
      'callback' => 'date_iso8601',
33
    ), t('Mapping for created is dc:created with datatype xsd:dateTime and callback date_iso8601.'));
34
    $this->assertIdentical($mapping['uid'], array('predicates' => array('sioc:has_creator', 'dc:creator'), 'type' => 'rel'), 'Mapping for uid is sioc:has_creator and dc:creator, and type is rel.');
35

    
36
    $mapping = rdf_mapping_load('test_entity', 'test_bundle_no_mapping');
37
    $this->assertEqual($mapping, array(), 'Empty array returned when an entity type, bundle pair has no mapping.');
38
  }
39
}
40

    
41
/**
42
 * Test RDFa markup generation.
43
 */
44
class RdfRdfaMarkupTestCase extends DrupalWebTestCase {
45
  public static function getInfo() {
46
    return array(
47
      'name' => 'RDFa markup',
48
      'description' => 'Test RDFa markup generation.',
49
      'group' => 'RDF',
50
    );
51
  }
52

    
53
  function setUp() {
54
    parent::setUp('rdf', 'field_test', 'rdf_test');
55
  }
56

    
57
  /**
58
   * Test rdf_rdfa_attributes().
59
   */
60
  function testDrupalRdfaAttributes() {
61
    // Same value as the one in the HTML tag (no callback function).
62
    $expected_attributes = array(
63
      'property' => array('dc:title'),
64
    );
65
    $mapping = rdf_mapping_load('test_entity', 'test_bundle');
66
    $attributes = rdf_rdfa_attributes($mapping['title']);
67
    ksort($expected_attributes);
68
    ksort($attributes);
69
    $this->assertEqual($expected_attributes, $attributes);
70

    
71
    // Value different from the one in the HTML tag (callback function).
72
    $date = 1252750327;
73
    $isoDate = date('c', $date);
74
    $expected_attributes = array(
75
      'datatype' => 'xsd:dateTime',
76
      'property' => array('dc:created'),
77
      'content' => $isoDate,
78
    );
79
    $mapping = rdf_mapping_load('test_entity', 'test_bundle');
80
    $attributes = rdf_rdfa_attributes($mapping['created'], $date);
81
    ksort($expected_attributes);
82
    ksort($attributes);
83
    $this->assertEqual($expected_attributes, $attributes);
84

    
85
    // Same value as the one in the HTML tag with datatype.
86
    $expected_attributes = array(
87
      'datatype' => 'foo:bar1type',
88
      'property' => array('foo:bar1'),
89
    );
90
    $mapping = rdf_mapping_load('test_entity', 'test_bundle');
91
    $attributes = rdf_rdfa_attributes($mapping['foobar1']);
92
    ksort($expected_attributes);
93
    ksort($attributes);
94
    $this->assertEqual($expected_attributes, $attributes);
95

    
96
    // ObjectProperty mapping (rel).
97
    $expected_attributes = array(
98
      'rel' => array('sioc:has_creator', 'dc:creator'),
99
    );
100
    $mapping = rdf_mapping_load('test_entity', 'test_bundle');
101
    $attributes = rdf_rdfa_attributes($mapping['foobar_objproperty1']);
102
    ksort($expected_attributes);
103
    ksort($attributes);
104
    $this->assertEqual($expected_attributes, $attributes);
105

    
106
    // Inverse ObjectProperty mapping (rev).
107
    $expected_attributes = array(
108
      'rev' => array('sioc:reply_of'),
109
    );
110
    $mapping = rdf_mapping_load('test_entity', 'test_bundle');
111
    $attributes = rdf_rdfa_attributes($mapping['foobar_objproperty2']);
112
    ksort($expected_attributes);
113
    ksort($attributes);
114
    $this->assertEqual($expected_attributes, $attributes);
115
  }
116

    
117
  /**
118
   * Ensure that file fields have the correct resource as the object in RDFa
119
   * when displayed as a teaser.
120
   */
121
  function testAttributesInMarkupFile() {
122
    // Create a user to post the image.
123
    $admin_user = $this->drupalCreateUser(array('edit own article content', 'revert revisions', 'administer content types'));
124
    $this->drupalLogin($admin_user);
125

    
126
    $langcode = LANGUAGE_NONE;
127
    $bundle_name = "article";
128

    
129
    $field_name = 'file_test';
130
    $field = array(
131
      'field_name' => $field_name,
132
      'type' => 'file',
133
    );
134
    field_create_field($field);
135
    $instance = array(
136
      'field_name' => $field_name,
137
      'entity_type' => 'node',
138
      'bundle' => $bundle_name,
139
      'display' => array(
140
        'teaser' => array(
141
          'type' => 'file_default',
142
        ),
143
      ),
144
    );
145
    field_create_instance($instance);
146

    
147
    // Set the RDF mapping for the new field.
148
    $rdf_mapping = rdf_mapping_load('node', $bundle_name);
149
    $rdf_mapping += array($field_name => array('predicates' => array('rdfs:seeAlso'), 'type' => 'rel'));
150
    $rdf_mapping_save = array('mapping' => $rdf_mapping, 'type' => 'node', 'bundle' => $bundle_name);
151
    rdf_mapping_save($rdf_mapping_save);
152

    
153
    // Get the test file that simpletest provides.
154
    $file = current($this->drupalGetTestFiles('text'));
155

    
156
    // Prepare image variables.
157
    $image_field = "field_image";
158
    // Get the test image that simpletest provides.
159
    $image = current($this->drupalGetTestFiles('image'));
160

    
161
    // Create an array for drupalPost with the field names as the keys and
162
    // the URIs for the test files as the values.
163
    $edit = array("files[" . $field_name . "_" . $langcode . "_0]" => drupal_realpath($file->uri),
164
                  "files[" . $image_field . "_" . $langcode . "_0]" => drupal_realpath($image->uri));
165

    
166
    // Create node and save, then edit node to upload files.
167
    $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
168
    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
169

    
170
    // Get filenames and nid for comparison with HTML output.
171
    $file_filename = $file->filename;
172
    $image_filename = $image->filename;
173
    $nid = $node->nid;
174
    // Navigate to front page, where node is displayed in teaser form.
175
    $this->drupalGet('node');
176

    
177
    // We only check to make sure that the resource attribute contains '.txt'
178
    // instead of the full file name because the filename is altered on upload.
179
    $file_rel = $this->xpath('//div[contains(@about, :node-uri)]//div[contains(@rel, "rdfs:seeAlso") and contains(@resource, ".txt")]', array(
180
      ':node-uri' => 'node/' . $nid,
181
    ));
182
    $this->assertTrue(!empty($file_rel), "Attribute 'rel' set on file field. Attribute 'resource' is also set.");
183
    $image_rel = $this->xpath('//div[contains(@about, :node-uri)]//div[contains(@rel, "rdfs:seeAlso") and contains(@resource, :image)]//img[contains(@typeof, "foaf:Image")]', array(
184
      ':node-uri' => 'node/' . $nid,
185
      ':image' => $image_filename,
186
    ));
187

    
188
    $this->assertTrue(!empty($image_rel), "Attribute 'rel' set on image field. Attribute 'resource' is also set.");
189

    
190
    // Edits the node to add tags.
191
    $tag1 = $this->randomName(8);
192
    $tag2 = $this->randomName(8);
193
    $edit = array();
194
    $edit['field_tags[' . LANGUAGE_NONE . ']'] = "$tag1, $tag2";
195
    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
196
    // Ensures the RDFa markup for the relationship between the node and its
197
    // tags is correct.
198
    $term_rdfa_meta = $this->xpath('//div[@about=:node-url and contains(@typeof, "sioc:Item") and contains(@typeof, "foaf:Document")]//ul[@class="links"]/li[@rel="dc:subject"]/a[@typeof="skos:Concept" and @datatype="" and text()=:term-name]', array(
199
      ':node-url' => url('node/' . $node->nid),
200
      ':term-name' => $tag1,
201
    ));
202
    $this->assertTrue(!empty($term_rdfa_meta), 'Property dc:subject is present for the tag1 field item.');
203
    $term_rdfa_meta = $this->xpath('//div[@about=:node-url and contains(@typeof, "sioc:Item") and contains(@typeof, "foaf:Document")]//ul[@class="links"]/li[@rel="dc:subject"]/a[@typeof="skos:Concept" and @datatype="" and text()=:term-name]', array(
204
      ':node-url' => url('node/' . $node->nid),
205
      ':term-name' => $tag2,
206
    ));
207
    $this->assertTrue(!empty($term_rdfa_meta), 'Property dc:subject is present for the tag2 field item.');
208
  }
209
}
210

    
211
class RdfCrudTestCase extends DrupalWebTestCase {
212
  public static function getInfo() {
213
    return array(
214
      'name' => 'RDF mapping CRUD functions',
215
      'description' => 'Test the RDF mapping CRUD functions.',
216
      'group' => 'RDF',
217
    );
218
  }
219

    
220
  function setUp() {
221
    parent::setUp('rdf', 'rdf_test');
222
  }
223

    
224
  /**
225
   * Test inserting, loading, updating, and deleting RDF mappings.
226
   */
227
  function testCRUD() {
228
    // Verify loading of a default mapping.
229
    $mapping = _rdf_mapping_load('test_entity', 'test_bundle');
230
    $this->assertTrue(count($mapping), 'Default mapping was found.');
231

    
232
    // Verify saving a mapping.
233
    $mapping = array(
234
      'type' => 'crud_test_entity',
235
      'bundle' => 'crud_test_bundle',
236
      'mapping' => array(
237
        'rdftype' => array('sioc:Post'),
238
        'title' => array(
239
          'predicates' => array('dc:title'),
240
        ),
241
        'uid' => array(
242
          'predicates' => array('sioc:has_creator', 'dc:creator'),
243
          'type' => 'rel',
244
        ),
245
      ),
246
    );
247
    $this->assertTrue(rdf_mapping_save($mapping) === SAVED_NEW, 'Mapping was saved.');
248

    
249
    // Read the raw record from the {rdf_mapping} table.
250
    $result = db_query('SELECT * FROM {rdf_mapping} WHERE type = :type AND bundle = :bundle', array(':type' => $mapping['type'], ':bundle' => $mapping['bundle']));
251
    $stored_mapping = $result->fetchAssoc();
252
    $stored_mapping['mapping'] = unserialize($stored_mapping['mapping']);
253
    $this->assertEqual($mapping, $stored_mapping, 'Mapping was stored properly in the {rdf_mapping} table.');
254

    
255
    // Verify loading of saved mapping.
256
    $this->assertEqual($mapping['mapping'], _rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Saved mapping loaded successfully.');
257

    
258
    // Verify updating of mapping.
259
    $mapping['mapping']['title'] = array(
260
      'predicates' => array('dc2:bar2'),
261
    );
262
    $this->assertTrue(rdf_mapping_save($mapping) === SAVED_UPDATED, 'Mapping was updated.');
263

    
264
    // Read the raw record from the {rdf_mapping} table.
265
    $result = db_query('SELECT * FROM {rdf_mapping} WHERE type = :type AND bundle = :bundle', array(':type' => $mapping['type'], ':bundle' => $mapping['bundle']));
266
    $stored_mapping = $result->fetchAssoc();
267
    $stored_mapping['mapping'] = unserialize($stored_mapping['mapping']);
268
    $this->assertEqual($mapping, $stored_mapping, 'Updated mapping was stored properly in the {rdf_mapping} table.');
269

    
270
    // Verify loading of saved mapping.
271
    $this->assertEqual($mapping['mapping'], _rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Saved mapping loaded successfully.');
272

    
273
    // Verify deleting of mapping.
274
    $this->assertTrue(rdf_mapping_delete($mapping['type'], $mapping['bundle']), 'Mapping was deleted.');
275
    $this->assertFalse(_rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Deleted mapping is no longer found in the database.');
276
  }
277
}
278

    
279
class RdfMappingDefinitionTestCase extends TaxonomyWebTestCase {
280
  public static function getInfo() {
281
    return array(
282
      'name' => 'RDF mapping definition functionality',
283
      'description' => 'Test the different types of RDF mappings and ensure the proper RDFa markup in included in nodes and user profile pages.',
284
      'group' => 'RDF',
285
    );
286
  }
287

    
288
  function setUp() {
289
    parent::setUp('rdf', 'rdf_test', 'blog');
290
  }
291

    
292
  /**
293
   * Create a node of type blog and test whether the RDF mapping defined for
294
   * this node type in rdf_test.module is used in the node page.
295
   */
296
  function testAttributesInMarkup1() {
297
    $node = $this->drupalCreateNode(array('type' => 'blog'));
298
    $isoDate = date('c', $node->changed);
299
    $url = url('node/' . $node->nid);
300
    $this->drupalGet('node/' . $node->nid);
301

    
302
    // Ensure the default bundle mapping for node is used. These attributes come
303
    // from the node default bundle definition.
304
    $blog_title = $this->xpath("//div[@about='$url']/span[@property='dc:title' and @content='$node->title']");
305
    $blog_meta = $this->xpath("//div[(@about='$url') and (@typeof='sioct:Weblog')]//span[contains(@property, 'dc:date') and contains(@property, 'dc:created') and @datatype='xsd:dateTime' and @content='$isoDate']");
306
    $this->assertTrue(!empty($blog_title), 'Property dc:title is present in meta tag.');
307
    $this->assertTrue(!empty($blog_meta), 'RDF type is present on post. Properties dc:date and dc:created are present on post date.');
308
  }
309

    
310
  /**
311
   * Create a content type and a node of type test_bundle_hook_install and test
312
   * whether the RDF mapping defined in rdf_test.install is used.
313
   */
314
  function testAttributesInMarkup2() {
315
    $type = $this->drupalCreateContentType(array('type' => 'test_bundle_hook_install'));
316
    // Create node with single quotation mark title to ensure it does not get
317
    // escaped more than once.
318
    $node = $this->drupalCreateNode(array(
319
      'type' => 'test_bundle_hook_install',
320
      'title' => $this->randomName(8) . "'",
321
    ));
322
    $isoDate = date('c', $node->changed);
323
    $url = url('node/' . $node->nid);
324
    $this->drupalGet('node/' . $node->nid);
325

    
326
    // Ensure the mapping defined in rdf_module.test is used.
327
    $test_bundle_title = $this->xpath("//div[@about='$url']/span[@property='dc:title' and @content=\"$node->title\"]");
328
    $test_bundle_meta = $this->xpath("//div[(@about='$url') and contains(@typeof, 'foo:mapping_install1') and contains(@typeof, 'bar:mapping_install2')]//span[contains(@property, 'dc:date') and contains(@property, 'dc:created') and @datatype='xsd:dateTime' and @content='$isoDate']");
329
    $this->assertTrue(!empty($test_bundle_title), 'Property dc:title is present in meta tag.');
330
    $this->assertTrue(!empty($test_bundle_meta), 'RDF type is present on post. Properties dc:date and dc:created are present on post date.');
331
  }
332

    
333
  /**
334
   * Create a random content type and node and ensure the default mapping for
335
   * node is used.
336
   */
337
  function testAttributesInMarkup3() {
338
    $type = $this->drupalCreateContentType();
339
    $node = $this->drupalCreateNode(array('type' => $type->type));
340
    $isoDate = date('c', $node->changed);
341
    $url = url('node/' . $node->nid);
342
    $this->drupalGet('node/' . $node->nid);
343

    
344
    // Ensure the default bundle mapping for node is used. These attributes come
345
    // from the node default bundle definition.
346
    $random_bundle_title = $this->xpath("//div[@about='$url']/span[@property='dc:title' and @content='$node->title']");
347
    $random_bundle_meta = $this->xpath("//div[(@about='$url') and contains(@typeof, 'sioc:Item') and contains(@typeof, 'foaf:Document')]//span[contains(@property, 'dc:date') and contains(@property, 'dc:created') and @datatype='xsd:dateTime' and @content='$isoDate']");
348
    $this->assertTrue(!empty($random_bundle_title), 'Property dc:title is present in meta tag.');
349
    $this->assertTrue(!empty($random_bundle_meta), 'RDF type is present on post. Properties dc:date and dc:created are present on post date.');
350
  }
351

    
352
  /**
353
   * Create a random user and ensure the default mapping for user is used.
354
   */
355
  function testUserAttributesInMarkup() {
356
    // Create two users, one with access to user profiles.
357
    $user1 = $this->drupalCreateUser(array('access user profiles'));
358
    $user2 = $this->drupalCreateUser();
359
    $username = $user2->name;
360
    $this->drupalLogin($user1);
361
    // Browse to the user profile page.
362
    $this->drupalGet('user/' . $user2->uid);
363
    // Ensure the default bundle mapping for user is used on the user profile
364
    // page. These attributes come from the user default bundle definition.
365
    $account_uri = url('user/' . $user2->uid);
366
    $person_uri = url('user/' . $user2->uid, array('fragment' => 'me'));
367

    
368
    $user2_profile_about = $this->xpath('//div[@class="profile" and @typeof="sioc:UserAccount" and @about=:account-uri]', array(
369
      ':account-uri' => $account_uri,
370
    ));
371
    $this->assertTrue(!empty($user2_profile_about), 'RDFa markup found on user profile page');
372

    
373
    $user_account_holder = $this->xpath('//meta[contains(@typeof, "foaf:Person") and @about=:person-uri and @resource=:account-uri and contains(@rel, "foaf:account")]', array(
374
      ':person-uri' => $person_uri,
375
      ':account-uri' => $account_uri,
376
    ));
377
    $this->assertTrue(!empty($user_account_holder), 'URI created for account holder and username set on sioc:UserAccount.');
378

    
379
    $user_username = $this->xpath('//meta[@about=:account-uri and contains(@property, "foaf:name") and @content=:username]', array(
380
      ':account-uri' => $account_uri,
381
      ':username' => $username,
382
    ));
383
    $this->assertTrue(!empty($user_username), 'foaf:name set on username.');
384

    
385
    // User 2 creates node.
386
    $this->drupalLogin($user2);
387
    $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
388
    $this->drupalLogin($user1);
389
    $this->drupalGet('node/' . $node->nid);
390
    // Ensures the default bundle mapping for user is used on the Authored By
391
    // information on the node.
392
    $author_about = $this->xpath('//a[@typeof="sioc:UserAccount" and @about=:account-uri and @property="foaf:name" and @datatype="" and contains(@xml:lang, "")]', array(
393
      ':account-uri' => $account_uri,
394
    ));
395
    $this->assertTrue(!empty($author_about), 'RDFa markup found on author information on post. xml:lang on username is set to empty string.');
396
  }
397

    
398
  /**
399
   * Creates a random term and ensures the right RDFa markup is used.
400
   */
401
  function testTaxonomyTermRdfaAttributes() {
402
    $vocabulary = $this->createVocabulary();
403
    $term = $this->createTerm($vocabulary);
404

    
405
    // Views the term and checks that the RDFa markup is correct.
406
    $this->drupalGet('taxonomy/term/' . $term->tid);
407
    $term_url = url('taxonomy/term/' . $term->tid);
408
    $term_name = $term->name;
409
    $term_rdfa_meta = $this->xpath('//meta[@typeof="skos:Concept" and @about=:term-url and contains(@property, "rdfs:label") and contains(@property, "skos:prefLabel") and @content=:term-name]', array(
410
      ':term-url' => $term_url,
411
      ':term-name' => $term_name,
412
    ));
413
    $this->assertTrue(!empty($term_rdfa_meta), 'RDFa markup found on term page.');
414
  }
415
}
416

    
417
class RdfCommentAttributesTestCase extends CommentHelperCase {
418

    
419
  public static function getInfo() {
420
    return array(
421
      'name' => 'RDF comment mapping',
422
      'description' => 'Tests the RDFa markup of comments.',
423
      'group' => 'RDF',
424
    );
425
  }
426

    
427
  public function setUp() {
428
    parent::setUp('comment', 'rdf', 'rdf_test');
429

    
430
    $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer permissions', 'administer blocks'));
431
    $this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'access user profiles'));
432

    
433
    // Enables anonymous user comments.
434
    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
435
      'access comments' => TRUE,
436
      'post comments' => TRUE,
437
      'skip comment approval' => TRUE,
438
    ));
439
    // Allows anonymous to leave their contact information.
440
    $this->setCommentAnonymous(COMMENT_ANONYMOUS_MAY_CONTACT);
441
    $this->setCommentPreview(DRUPAL_OPTIONAL);
442
    $this->setCommentForm(TRUE);
443
    $this->setCommentSubject(TRUE);
444
    $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
445

    
446
    // Creates the nodes on which the test comments will be posted.
447
    $this->drupalLogin($this->web_user);
448
    $this->node1 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
449
    $this->node2 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
450
    $this->drupalLogout();
451
  }
452

    
453
  /**
454
   * Tests the presence of the RDFa markup for the number of comments.
455
   */
456
  public function testNumberOfCommentsRdfaMarkup() {
457
    // Posts 2 comments as a registered user.
458
    $this->drupalLogin($this->web_user);
459
    $this->postComment($this->node1, $this->randomName(), $this->randomName());
460
    $this->postComment($this->node1, $this->randomName(), $this->randomName());
461

    
462
    // Tests number of comments in teaser view.
463
    $this->drupalGet('node');
464
    $node_url = url('node/' . $this->node1->nid);
465
    $comment_count_teaser = $this->xpath('//div[@about=:node-url]/span[@property="sioc:num_replies" and @content="2" and @datatype="xsd:integer"]', array(':node-url' => $node_url));
466
    $this->assertTrue(!empty($comment_count_teaser), 'RDFa markup for the number of comments found on teaser view.');
467

    
468
    // Tests number of comments in full node view.
469
    $this->drupalGet('node/' . $this->node1->nid);
470
    $comment_count_teaser = $this->xpath('//div[@about=:node-url]/span[@property="sioc:num_replies" and @content="2" and @datatype="xsd:integer"]', array(':node-url' => $node_url));
471
    $this->assertTrue(!empty($comment_count_teaser), 'RDFa markup for the number of comments found on full node view.');
472
  }
473

    
474
  /**
475
   * Tests the presence of the RDFa markup for the title, date and author and
476
   * homepage on registered users and anonymous comments.
477
   */
478
  public function testCommentRdfaMarkup() {
479

    
480
    // Posts comment #1 as a registered user.
481
    $this->drupalLogin($this->web_user);
482
    $comment1_subject = $this->randomName();
483
    $comment1_body = $this->randomName();
484
    $comment1 = $this->postComment($this->node1, $comment1_body, $comment1_subject);
485

    
486
    // Tests comment #1 with access to the user profile.
487
    $this->drupalGet('node/' . $this->node1->nid);
488
    $this->_testBasicCommentRdfaMarkup($comment1);
489

    
490
    // Tests comment #1 with no access to the user profile (as anonymous user).
491
    $this->drupalLogout();
492
    $this->drupalGet('node/' . $this->node1->nid);
493
    $this->_testBasicCommentRdfaMarkup($comment1);
494

    
495
    // Posts comment #2 as anonymous user.
496
    $comment2_subject = $this->randomName();
497
    $comment2_body = $this->randomName();
498
    $anonymous_user = array();
499
    $anonymous_user['name'] = $this->randomName();
500
    $anonymous_user['mail'] = 'tester@simpletest.org';
501
    $anonymous_user['homepage'] = 'http://example.org/';
502
    $comment2 = $this->postComment($this->node2, $comment2_body, $comment2_subject, $anonymous_user);
503
    $this->drupalGet('node/' . $this->node2->nid);
504

    
505
    // Tests comment #2 as anonymous user.
506
    $this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
507
    // Tests the RDFa markup for the homepage (specific to anonymous comments).
508
    $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[contains(@class, "username") and @typeof="sioc:UserAccount" and @property="foaf:name" and @datatype="" and @href="http://example.org/" and contains(@rel, "foaf:page")]');
509
    $this->assertTrue(!empty($comment_homepage), 'RDFa markup for the homepage of anonymous user found.');
510
    // There should be no about attribute on anonymous comments.
511
    $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[@about]');
512
    $this->assertTrue(empty($comment_homepage), 'No about attribute is present on anonymous user comment.');
513

    
514
    // Tests comment #2 as logged in user.
515
    $this->drupalLogin($this->web_user);
516
    $this->drupalGet('node/' . $this->node2->nid);
517
    $this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
518
    // Tests the RDFa markup for the homepage (specific to anonymous comments).
519
    $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[contains(@class, "username") and @typeof="sioc:UserAccount" and @property="foaf:name" and @datatype="" and @href="http://example.org/" and contains(@rel, "foaf:page")]');
520
    $this->assertTrue(!empty($comment_homepage), "RDFa markup for the homepage of anonymous user found.");
521
    // There should be no about attribute on anonymous comments.
522
    $comment_homepage = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/a[@about]');
523
    $this->assertTrue(empty($comment_homepage), "No about attribute is present on anonymous user comment.");
524
  }
525

    
526
  /**
527
   * Test RDF comment replies.
528
   */
529
  public function testCommentReplyOfRdfaMarkup() {
530
    // Posts comment #1 as a registered user.
531
    $this->drupalLogin($this->web_user);
532
    $comments[] = $this->postComment($this->node1, $this->randomName(), $this->randomName());
533

    
534
    // Tests the reply_of relationship of a first level comment.
535
    $result = $this->xpath("(id('comments')//div[contains(@class,'comment ')])[position()=1]//span[@rel='sioc:reply_of' and @resource=:node]", array(':node' => url("node/{$this->node1->nid}")));
536
    $this->assertEqual(1, count($result), 'RDFa markup referring to the node is present.');
537
    $result = $this->xpath("(id('comments')//div[contains(@class,'comment ')])[position()=1]//span[@rel='sioc:reply_of' and @resource=:comment]", array(':comment' => url('comment/1#comment-1')));
538
    $this->assertFalse($result, 'No RDFa markup referring to the comment itself is present.');
539

    
540
    // Posts a reply to the first comment.
541
    $this->drupalGet('comment/reply/' . $this->node1->nid . '/' . $comments[0]->id);
542
    $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
543

    
544
    // Tests the reply_of relationship of a second level comment.
545
    $result = $this->xpath("(id('comments')//div[contains(@class,'comment ')])[position()=2]//span[@rel='sioc:reply_of' and @resource=:node]", array(':node' => url("node/{$this->node1->nid}")));
546
    $this->assertEqual(1, count($result), 'RDFa markup referring to the node is present.');
547
    $result = $this->xpath("(id('comments')//div[contains(@class,'comment ')])[position()=2]//span[@rel='sioc:reply_of' and @resource=:comment]", array(':comment' => url('comment/1', array('fragment' => 'comment-1'))));
548
    $this->assertEqual(1, count($result), 'RDFa markup referring to the parent comment is present.');
549
    $comments = $this->xpath("(id('comments')//div[contains(@class,'comment ')])[position()=2]");
550
  }
551

    
552
  /**
553
   * Helper function for testCommentRdfaMarkup().
554
   *
555
   * Tests the current page for basic comment RDFa markup.
556
   *
557
   * @param $comment
558
   *   Comment object.
559
   * @param $account
560
   *   An array containing information about an anonymous user.
561
   */
562
  function _testBasicCommentRdfaMarkup($comment, $account = array()) {
563
    $comment_container = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]');
564
    $this->assertTrue(!empty($comment_container), "Comment RDF type for comment found.");
565
    $comment_title = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//h3[@property="dc:title"]');
566
    $this->assertEqual((string)$comment_title[0]->a, $comment->subject, "RDFa markup for the comment title found.");
567
    $comment_date = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//*[contains(@property, "dc:date") and contains(@property, "dc:created")]');
568
    $this->assertTrue(!empty($comment_date), "RDFa markup for the date of the comment found.");
569
    // The author tag can be either a or span
570
    $comment_author = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//span[@rel="sioc:has_creator"]/*[contains(@class, "username") and @typeof="sioc:UserAccount" and @property="foaf:name" and @datatype=""]');
571
    $name = empty($account["name"]) ? $this->web_user->name : $account["name"] . " (not verified)";
572
    $this->assertEqual((string)$comment_author[0], $name, "RDFa markup for the comment author found.");
573
    $comment_body = $this->xpath('//div[contains(@class, "comment") and contains(@typeof, "sioct:Comment")]//div[@class="content"]//div[contains(@class, "comment-body")]//div[@property="content:encoded"]');
574
    $this->assertEqual((string)$comment_body[0]->p, $comment->comment, "RDFa markup for the comment body found.");
575
  }
576
}
577

    
578
class RdfTrackerAttributesTestCase extends DrupalWebTestCase {
579
  public static function getInfo() {
580
    return array(
581
      'name' => 'RDF tracker page mapping',
582
      'description' => 'Test the mapping for the tracker page and ensure the proper RDFa markup in included.',
583
      'group' => 'RDF',
584
    );
585
  }
586

    
587
  function setUp() {
588
    parent::setUp('rdf', 'rdf_test', 'tracker');
589
    // Enable anonymous posting of content.
590
    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
591
      'create article content' => TRUE,
592
      'access comments' => TRUE,
593
      'post comments' => TRUE,
594
      'skip comment approval' => TRUE,
595
    ));
596
  }
597

    
598
  /**
599
   * Create nodes as both admin and anonymous user and test for correct RDFa
600
   * markup on the tracker page for those nodes and their comments.
601
   */
602
  function testAttributesInTracker() {
603
    // Create node as anonymous user.
604
    $node_anon = $this->drupalCreateNode(array('type' => 'article', 'uid' => 0));
605
    // Create node as admin user.
606
    $node_admin = $this->drupalCreateNode(array('type' => 'article', 'uid' => 1));
607

    
608
    // Pass both the anonymously posted node and the administrator posted node
609
    // through to test for the RDF attributes.
610
    $this->_testBasicTrackerRdfaMarkup($node_anon);
611
    $this->_testBasicTrackerRdfaMarkup($node_admin);
612

    
613
  }
614

    
615
  /**
616
   * Helper function for testAttributesInTracker().
617
   *
618
   * Tests the tracker page for RDFa markup.
619
   *
620
   * @param $node
621
   * The node just created.
622
   */
623
  function _testBasicTrackerRdfaMarkup($node) {
624
    $url = url('node/' . $node->nid);
625

    
626
    $user = ($node->uid == 0) ? 'Anonymous user' : 'Registered user';
627

    
628
    // Navigate to tracker page.
629
    $this->drupalGet('tracker');
630

    
631
    // Tests whether the about property is applied. This is implicit in the
632
    // success of the following tests, but making it explicit will make
633
    // debugging easier in case of failure.
634
    $tracker_about = $this->xpath('//tr[@about=:url]', array(':url' => $url));
635
    $this->assertTrue(!empty($tracker_about), format_string('About attribute found on table row for @user content.', array('@user'=> $user)));
636

    
637
    // Tests whether the title has the correct property attribute.
638
    $tracker_title = $this->xpath('//tr[@about=:url]/td[@property="dc:title" and @datatype=""]', array(':url' => $url));
639
    $this->assertTrue(!empty($tracker_title), format_string('Title property attribute found on @user content.', array('@user'=> $user)));
640

    
641
    // Tests whether the relationship between the content and user has been set.
642
    $tracker_user = $this->xpath('//tr[@about=:url]//td[contains(@rel, "sioc:has_creator")]//*[contains(@typeof, "sioc:UserAccount") and contains(@property, "foaf:name")]', array(':url' => $url));
643
    $this->assertTrue(!empty($tracker_user), format_string('Typeof and name property attributes found on @user.', array('@user'=> $user)));
644
    // There should be an about attribute on logged in users and no about
645
    // attribute for anonymous users.
646
    $tracker_user = $this->xpath('//tr[@about=:url]//td[@rel="sioc:has_creator"]/*[@about]', array(':url' => $url));
647
    if ($node->uid == 0) {
648
      $this->assertTrue(empty($tracker_user), format_string('No about attribute is present on @user.', array('@user'=> $user)));
649
    }
650
    elseif ($node->uid > 0) {
651
      $this->assertTrue(!empty($tracker_user), format_string('About attribute is present on @user.', array('@user'=> $user)));
652
    }
653

    
654
    // Tests whether the property has been set for number of comments.
655
    $tracker_replies = $this->xpath('//tr[@about=:url]//td[contains(@property, "sioc:num_replies") and contains(@content, "0") and @datatype="xsd:integer"]', array(':url' => $url));
656
    $this->assertTrue($tracker_replies, format_string('Num replies property and content attributes found on @user content.', array('@user'=> $user)));
657

    
658
    // Tests that the appropriate RDFa markup to annotate the latest activity
659
    // date has been added to the tracker output before comments have been
660
    // posted, meaning the latest activity reflects changes to the node itself.
661
    $isoDate = date('c', $node->changed);
662
    $tracker_activity = $this->xpath('//tr[@about=:url]//td[contains(@property, "dc:modified") and contains(@property, "sioc:last_activity_date") and contains(@datatype, "xsd:dateTime") and @content=:date]', array(':url' => $url, ':date' => $isoDate));
663
    $this->assertTrue(!empty($tracker_activity), format_string('Latest activity date and changed properties found when there are no comments on @user content. Latest activity date content is correct.', array('@user'=> $user)));
664

    
665
    // Tests that the appropriate RDFa markup to annotate the latest activity
666
    // date has been added to the tracker output after a comment is posted.
667
    $comment = array(
668
      'subject' => $this->randomName(),
669
      'comment_body[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(),
670
    );
671
    $this->drupalPost('comment/reply/' . $node->nid, $comment, t('Save'));
672
    $this->drupalGet('tracker');
673

    
674
    // Tests whether the property has been set for number of comments.
675
    $tracker_replies = $this->xpath('//tr[@about=:url]//td[contains(@property, "sioc:num_replies") and contains(@content, "1") and @datatype="xsd:integer"]', array(':url' => $url));
676
    $this->assertTrue($tracker_replies, format_string('Num replies property and content attributes found on @user content.', array('@user'=> $user)));
677

    
678
    // Need to query database directly to obtain last_activity_date because
679
    // it cannot be accessed via node_load().
680
    $result = db_query('SELECT t.changed FROM {tracker_node} t WHERE t.nid = (:nid)', array(':nid' => $node->nid));
681
    foreach ($result as $node) {
682
      $expected_last_activity_date = $node->changed;
683
    }
684
    $isoDate = date('c', $expected_last_activity_date);
685
    $tracker_activity = $this->xpath('//tr[@about=:url]//td[@property="sioc:last_activity_date" and @datatype="xsd:dateTime" and @content=:date]', array(':url' => $url, ':date' => $isoDate));
686
    $this->assertTrue(!empty($tracker_activity), format_string('Latest activity date found when there are comments on @user content. Latest activity date content is correct.', array('@user'=> $user)));
687
  }
688
}
689

    
690
/**
691
 * Tests for RDF namespaces declaration with hook_rdf_namespaces().
692
 */
693
class RdfGetRdfNamespacesTestCase extends DrupalWebTestCase {
694
  public static function getInfo() {
695
    return array(
696
      'name' => 'RDF namespaces',
697
      'description' => 'Test hook_rdf_namespaces() and ensure only "safe" namespaces are returned.',
698
      'group' => 'RDF',
699
    );
700
  }
701

    
702
  function setUp() {
703
    parent::setUp('rdf', 'rdf_test');
704
  }
705

    
706
  /**
707
   * Test getting RDF namesapces.
708
   */
709
  function testGetRdfNamespaces() {
710
    // Get all RDF namespaces.
711
    $ns = rdf_get_namespaces();
712

    
713
    $this->assertEqual($ns['rdfs'], 'http://www.w3.org/2000/01/rdf-schema#', 'A prefix declared once is included.');
714
    $this->assertEqual($ns['foaf'], 'http://xmlns.com/foaf/0.1/', 'The same prefix declared in several implementations of hook_rdf_namespaces() is valid as long as all the namespaces are the same.');
715
    $this->assertEqual($ns['foaf1'], 'http://xmlns.com/foaf/0.1/', 'Two prefixes can be assigned the same namespace.');
716
    $this->assertTrue(!isset($ns['dc']), 'A prefix with conflicting namespaces is discarded.');
717
  }
718
}