Projet

Général

Profil

Paste
Télécharger (19,7 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / path / path.test @ b75b6b8b

1
<?php
2

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

    
8
/**
9
 * Provides a base class for testing the Path module.
10
 */
11
class PathTestCase extends DrupalWebTestCase {
12
  public static function getInfo() {
13
    return array(
14
      'name' => 'Path alias functionality',
15
      'description' => 'Add, edit, delete, and change alias and verify its consistency in the database.',
16
      'group' => 'Path',
17
    );
18
  }
19

    
20
  function setUp() {
21
    parent::setUp('path');
22

    
23
    // Create test user and login.
24
    $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases'));
25
    $this->drupalLogin($web_user);
26
  }
27

    
28
  /**
29
   * Tests the path cache.
30
   */
31
  function testPathCache() {
32
    // Create test node.
33
    $node1 = $this->drupalCreateNode();
34

    
35
    // Create alias.
36
    $edit = array();
37
    $edit['source'] = 'node/' . $node1->nid;
38
    $edit['alias'] = $this->randomName(8);
39
    $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
40

    
41
    // Visit the system path for the node and confirm a cache entry is
42
    // created.
43
    cache_clear_all('*', 'cache_path', TRUE);
44
    $this->drupalGet($edit['source']);
45
    $this->assertTrue(cache_get($edit['source'], 'cache_path'), 'Cache entry was created.');
46

    
47
    // Visit the alias for the node and confirm a cache entry is created.
48
    cache_clear_all('*', 'cache_path', TRUE);
49
    $this->drupalGet($edit['alias']);
50
    $this->assertTrue(cache_get($edit['source'], 'cache_path'), 'Cache entry was created.');
51
  }
52

    
53
  /**
54
   * Tests alias functionality through the admin interfaces.
55
   */
56
  function testAdminAlias() {
57
    // Create test node.
58
    $node1 = $this->drupalCreateNode();
59

    
60
    // Create alias.
61
    $edit = array();
62
    $edit['source'] = 'node/' . $node1->nid;
63
    $edit['alias'] = $this->randomName(8);
64
    $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
65

    
66
    // Confirm that the alias works.
67
    $this->drupalGet($edit['alias']);
68
    $this->assertText($node1->title, 'Alias works.');
69
    $this->assertResponse(200);
70

    
71
    // Change alias to one containing "exotic" characters.
72
    $pid = $this->getPID($edit['alias']);
73

    
74
    $previous = $edit['alias'];
75
    $edit['alias'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
76
      "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
77
      "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
78
    $this->drupalPost('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
79

    
80
    // Confirm that the alias works.
81
    $this->drupalGet($edit['alias']);
82
    $this->assertText($node1->title, 'Changed alias works.');
83
    $this->assertResponse(200);
84

    
85
    drupal_static_reset('drupal_lookup_path');
86
    // Confirm that previous alias no longer works.
87
    $this->drupalGet($previous);
88
    $this->assertNoText($node1->title, 'Previous alias no longer works.');
89
    $this->assertResponse(404);
90

    
91
    // Create second test node.
92
    $node2 = $this->drupalCreateNode();
93

    
94
    // Set alias to second test node.
95
    $edit['source'] = 'node/' . $node2->nid;
96
    // leave $edit['alias'] the same
97
    $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
98

    
99
    // Confirm no duplicate was created.
100
    $this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])), 'Attempt to move alias was rejected.');
101

    
102
    // Delete alias.
103
    $this->drupalPost('admin/config/search/path/edit/' . $pid, array(), t('Delete'));
104
    $this->drupalPost(NULL, array(), t('Confirm'));
105

    
106
    // Confirm that the alias no longer works.
107
    $this->drupalGet($edit['alias']);
108
    $this->assertNoText($node1->title, 'Alias was successfully deleted.');
109
    $this->assertResponse(404);
110
  }
111

    
112
  /**
113
   * Tests alias functionality through the node interfaces.
114
   */
115
  function testNodeAlias() {
116
    // Create test node.
117
    $node1 = $this->drupalCreateNode();
118

    
119
    // Create alias.
120
    $edit = array();
121
    $edit['path[alias]'] = $this->randomName(8);
122
    $this->drupalPost('node/' . $node1->nid . '/edit', $edit, t('Save'));
123

    
124
    // Confirm that the alias works.
125
    $this->drupalGet($edit['path[alias]']);
126
    $this->assertText($node1->title, 'Alias works.');
127
    $this->assertResponse(200);
128

    
129
    // Change alias to one containing "exotic" characters.
130
    $previous = $edit['path[alias]'];
131
    $edit['path[alias]'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
132
      "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
133
      "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
134
    $this->drupalPost('node/' . $node1->nid . '/edit', $edit, t('Save'));
135

    
136
    // Confirm that the alias works.
137
    $this->drupalGet($edit['path[alias]']);
138
    $this->assertText($node1->title, 'Changed alias works.');
139
    $this->assertResponse(200);
140

    
141
    // Make sure that previous alias no longer works.
142
    $this->drupalGet($previous);
143
    $this->assertNoText($node1->title, 'Previous alias no longer works.');
144
    $this->assertResponse(404);
145

    
146
    // Create second test node.
147
    $node2 = $this->drupalCreateNode();
148

    
149
    // Set alias to second test node.
150
    // Leave $edit['path[alias]'] the same.
151
    $this->drupalPost('node/' . $node2->nid . '/edit', $edit, t('Save'));
152

    
153
    // Confirm that the alias didn't make a duplicate.
154
    $this->assertText(t('The alias is already in use.'), 'Attempt to moved alias was rejected.');
155

    
156
    // Delete alias.
157
    $this->drupalPost('node/' . $node1->nid . '/edit', array('path[alias]' => ''), t('Save'));
158

    
159
    // Confirm that the alias no longer works.
160
    $this->drupalGet($edit['path[alias]']);
161
    $this->assertNoText($node1->title, 'Alias was successfully deleted.');
162
    $this->assertResponse(404);
163
  }
164

    
165
  /**
166
   * Returns the path ID.
167
   *
168
   * @param $alias
169
   *   A string containing an aliased path.
170
   *
171
   * @return int
172
   *   Integer representing the path ID.
173
   */
174
  function getPID($alias) {
175
    return db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", array(':alias' => $alias))->fetchField();
176
  }
177

    
178
  /**
179
   * Tests that duplicate aliases fail validation.
180
   */
181
  function testDuplicateNodeAlias() {
182
    // Create one node with a random alias.
183
    $node_one = $this->drupalCreateNode();
184
    $edit = array();
185
    $edit['path[alias]'] = $this->randomName();
186
    $this->drupalPost('node/' . $node_one->nid . '/edit', $edit, t('Save'));
187

    
188
    // Now create another node and try to set the same alias.
189
    $node_two = $this->drupalCreateNode();
190
    $this->drupalPost('node/' . $node_two->nid . '/edit', $edit, t('Save'));
191
    $this->assertText(t('The alias is already in use.'));
192
    $this->assertFieldByXPath("//input[@name='path[alias]' and contains(@class, 'error')]", $edit['path[alias]'], 'Textfield exists and has the error class.');
193
  }
194
}
195

    
196
/**
197
 * Tests URL aliases for taxonomy terms.
198
 */
199
class PathTaxonomyTermTestCase extends DrupalWebTestCase {
200
  public static function getInfo() {
201
    return array(
202
      'name' => 'Taxonomy term URL aliases',
203
      'description' => 'Tests URL aliases for taxonomy terms.',
204
      'group' => 'Path',
205
    );
206
  }
207

    
208
  function setUp() {
209
    parent::setUp('path', 'taxonomy');
210

    
211
    // Create and login user.
212
    $web_user = $this->drupalCreateUser(array('administer url aliases', 'administer taxonomy', 'access administration pages'));
213
    $this->drupalLogin($web_user);
214
  }
215

    
216
  /**
217
   * Tests alias functionality through the admin interfaces.
218
   */
219
  function testTermAlias() {
220
    // Create a term in the default 'Tags' vocabulary with URL alias.
221
    $vocabulary = taxonomy_vocabulary_load(1);
222
    $description = $this->randomName();;
223
    $edit = array();
224
    $edit['name'] = $this->randomName();
225
    $edit['description[value]'] = $description;
226
    $edit['path[alias]'] = $this->randomName();
227
    $this->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add', $edit, t('Save'));
228

    
229
    // Confirm that the alias works.
230
    $this->drupalGet($edit['path[alias]']);
231
    $this->assertText($description, 'Term can be accessed on URL alias.');
232

    
233
    // Change the term's URL alias.
234
    $tid = db_query("SELECT tid FROM {taxonomy_term_data} WHERE name = :name", array(':name' => $edit['name']))->fetchField();
235
    $edit2 = array();
236
    $edit2['path[alias]'] = $this->randomName();
237
    $this->drupalPost('taxonomy/term/' . $tid . '/edit', $edit2, t('Save'));
238

    
239
    // Confirm that the changed alias works.
240
    $this->drupalGet($edit2['path[alias]']);
241
    $this->assertText($description, 'Term can be accessed on changed URL alias.');
242

    
243
    // Confirm that the old alias no longer works.
244
    $this->drupalGet($edit['path[alias]']);
245
    $this->assertNoText($description, 'Old URL alias has been removed after altering.');
246
    $this->assertResponse(404, 'Old URL alias returns 404.');
247

    
248
    // Remove the term's URL alias.
249
    $edit3 = array();
250
    $edit3['path[alias]'] = '';
251
    $this->drupalPost('taxonomy/term/' . $tid . '/edit', $edit3, t('Save'));
252

    
253
    // Confirm that the alias no longer works.
254
    $this->drupalGet($edit2['path[alias]']);
255
    $this->assertNoText($description, 'Old URL alias has been removed after altering.');
256
    $this->assertResponse(404, 'Old URL alias returns 404.');
257
  }
258
}
259

    
260
/**
261
 * Tests URL aliases for translated nodes.
262
 */
263
class PathLanguageTestCase extends DrupalWebTestCase {
264
  public static function getInfo() {
265
    return array(
266
      'name' => 'Path aliases with translated nodes',
267
      'description' => 'Confirm that paths work with translated nodes',
268
      'group' => 'Path',
269
    );
270
  }
271

    
272
  function setUp() {
273
    parent::setUp('path', 'locale', 'translation');
274

    
275
    // Create and login user.
276
    $this->web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'translate content', 'access administration pages'));
277
    $this->drupalLogin($this->web_user);
278

    
279
    // Enable French language.
280
    $edit = array();
281
    $edit['langcode'] = 'fr';
282

    
283
    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
284

    
285
    // Enable URL language detection and selection.
286
    $edit = array('language[enabled][locale-url]' => 1);
287
    $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
288
  }
289

    
290
  /**
291
   * Test alias functionality through the admin interfaces.
292
   */
293
  function testAliasTranslation() {
294
    // Set 'page' content type to enable translation.
295
    variable_set('language_content_type_page', 2);
296

    
297
    $english_node = $this->drupalCreateNode(array('type' => 'page'));
298
    $english_alias = $this->randomName();
299

    
300
    // Edit the node to set language and path.
301
    $edit = array();
302
    $edit['language'] = 'en';
303
    $edit['path[alias]'] = $english_alias;
304
    $this->drupalPost('node/' . $english_node->nid . '/edit', $edit, t('Save'));
305

    
306
    // Confirm that the alias works.
307
    $this->drupalGet($english_alias);
308
    $this->assertText($english_node->title, 'Alias works.');
309

    
310
    // Translate the node into French.
311
    $this->drupalGet('node/' . $english_node->nid . '/translate');
312
    $this->clickLink(t('add translation'));
313
    $edit = array();
314
    $langcode = LANGUAGE_NONE;
315
    $edit["title"] = $this->randomName();
316
    $edit["body[$langcode][0][value]"] = $this->randomName();
317
    $french_alias = $this->randomName();
318
    $edit['path[alias]'] = $french_alias;
319
    $this->drupalPost(NULL, $edit, t('Save'));
320

    
321
    // Clear the path lookup cache.
322
    drupal_lookup_path('wipe');
323

    
324
    // Ensure the node was created.
325
    $french_node = $this->drupalGetNodeByTitle($edit["title"]);
326
    $this->assertTrue(($french_node), 'Node found in database.');
327

    
328
    // Confirm that the alias works.
329
    $this->drupalGet('fr/' . $edit['path[alias]']);
330
    $this->assertText($french_node->title, 'Alias for French translation works.');
331

    
332
    // Confirm that the alias is returned by url().
333
    drupal_static_reset('language_list');
334
    drupal_static_reset('locale_url_outbound_alter');
335
    $languages = language_list();
336
    $url = url('node/' . $french_node->nid, array('language' => $languages[$french_node->language]));
337
    $this->assertTrue(strpos($url, $edit['path[alias]']), 'URL contains the path alias.');
338

    
339
    // Confirm that the alias works even when changing language negotiation
340
    // options. Enable User language detection and selection over URL one.
341
    $edit = array(
342
      'language[enabled][locale-user]' => 1,
343
      'language[weight][locale-user]' => -9,
344
      'language[enabled][locale-url]' => 1,
345
      'language[weight][locale-url]' => -8,
346
    );
347
    $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
348

    
349
    // Change user language preference.
350
    $edit = array('language' => 'fr');
351
    $this->drupalPost("user/{$this->web_user->uid}/edit", $edit, t('Save'));
352

    
353
    // Check that the English alias works. In this situation French is the
354
    // current UI and content language, while URL language is English (since we
355
    // do not have a path prefix we fall back to the site's default language).
356
    // We need to ensure that the user language preference is not taken into
357
    // account while determining the path alias language, because if this
358
    // happens we have no way to check that the path alias is valid: there is no
359
    // path alias for French matching the english alias. So drupal_lookup_path()
360
    // needs to use the URL language to check whether the alias is valid.
361
    $this->drupalGet($english_alias);
362
    $this->assertText($english_node->title, 'Alias for English translation works.');
363

    
364
    // Check that the French alias works.
365
    $this->drupalGet("fr/$french_alias");
366
    $this->assertText($french_node->title, 'Alias for French translation works.');
367

    
368
    // Disable URL language negotiation.
369
    $edit = array('language[enabled][locale-url]' => FALSE);
370
    $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
371

    
372
    // Check that the English alias still works.
373
    $this->drupalGet($english_alias);
374
    $this->assertText($english_node->title, 'Alias for English translation works.');
375

    
376
    // Check that the French alias is not available. We check the unprefixed
377
    // alias because we disabled URL language negotiation above. In this
378
    // situation only aliases in the default language and language neutral ones
379
    // should keep working.
380
    $this->drupalGet($french_alias);
381
    $this->assertResponse(404, 'Alias for French translation is unavailable when URL language negotiation is disabled.');
382

    
383
    // drupal_lookup_path() has an internal static cache. Check to see that
384
    // it has the appropriate contents at this point.
385
    drupal_lookup_path('wipe');
386
    $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->language);
387
    $this->assertEqual($french_node_path, 'node/' . $french_node->nid, 'Normal path works.');
388
    // Second call should return the same path.
389
    $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->language);
390
    $this->assertEqual($french_node_path, 'node/' . $french_node->nid, 'Normal path is the same.');
391

    
392
    // Confirm that the alias works.
393
    $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
394
    $this->assertEqual($french_node_alias, $french_alias, 'Alias works.');
395
    // Second call should return the same alias.
396
    $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
397
    $this->assertEqual($french_node_alias, $french_alias, 'Alias is the same.');
398
  }
399
}
400

    
401
/**
402
 * Tests the user interface for creating path aliases, with languages.
403
 */
404
class PathLanguageUITestCase extends DrupalWebTestCase {
405
  public static function getInfo() {
406
    return array(
407
      'name' => 'Path aliases with languages',
408
      'description' => 'Confirm that the Path module user interface works with languages.',
409
      'group' => 'Path',
410
    );
411
  }
412

    
413
  function setUp() {
414
    parent::setUp('path', 'locale');
415

    
416
    // Create and login user.
417
    $web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'access administration pages'));
418
    $this->drupalLogin($web_user);
419

    
420
    // Enable French language.
421
    $edit = array();
422
    $edit['langcode'] = 'fr';
423

    
424
    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
425

    
426
    // Enable URL language detection and selection.
427
    $edit = array('language[enabled][locale-url]' => 1);
428
    $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
429
  }
430

    
431
  /**
432
   * Tests that a language-neutral URL alias works.
433
   */
434
  function testLanguageNeutralURLs() {
435
    $name = $this->randomName(8);
436
    $edit = array();
437
    $edit['source'] = 'admin/config/search/path';
438
    $edit['alias'] = $name;
439
    $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
440

    
441
    $this->drupalGet($name);
442
    $this->assertText(t('Filter aliases'), 'Language-neutral URL alias works');
443
  }
444

    
445
  /**
446
   * Tests that a default language URL alias works.
447
   */
448
  function testDefaultLanguageURLs() {
449
    $name = $this->randomName(8);
450
    $edit = array();
451
    $edit['source'] = 'admin/config/search/path';
452
    $edit['alias'] = $name;
453
    $edit['language'] = 'en';
454
    $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
455

    
456
    $this->drupalGet($name);
457
    $this->assertText(t('Filter aliases'), 'English URL alias works');
458
  }
459

    
460
  /**
461
   * Tests that a non-default language URL alias works.
462
   */
463
  function testNonDefaultURLs() {
464
    $name = $this->randomName(8);
465
    $edit = array();
466
    $edit['source'] = 'admin/config/search/path';
467
    $edit['alias'] = $name;
468
    $edit['language'] = 'fr';
469
    $this->drupalPost('admin/config/search/path/add', $edit, t('Save'));
470

    
471
    $this->drupalGet('fr/' . $name);
472
    $this->assertText(t('Filter aliases'), 'Foreign URL alias works');
473
  }
474

    
475
}
476

    
477
/**
478
 * Tests that paths are not prefixed on a monolingual site.
479
 */
480
class PathMonolingualTestCase extends DrupalWebTestCase {
481
  public static function getInfo() {
482
    return array(
483
      'name' => 'Paths on non-English monolingual sites',
484
      'description' => 'Confirm that paths are not changed on monolingual non-English sites',
485
      'group' => 'Path',
486
    );
487
  }
488

    
489
  function setUp() {
490
    global $language;
491
    parent::setUp('path', 'locale', 'translation');
492

    
493
    // Create and login user.
494
    $web_user = $this->drupalCreateUser(array('administer languages', 'access administration pages'));
495
    $this->drupalLogin($web_user);
496

    
497
    // Enable French language.
498
    $edit = array();
499
    $edit['langcode'] = 'fr';
500
    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
501

    
502
    // Make French the default language.
503
    $edit = array('site_default' => 'fr');
504
    $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
505

    
506
    // Disable English.
507
    $edit = array('enabled[en]' => FALSE);
508
    $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
509

    
510
    // Verify that French is the only language.
511
    $this->assertFalse(drupal_multilingual(), 'Site is mono-lingual');
512
    $this->assertEqual(language_default('language'), 'fr', 'French is the default language');
513

    
514
    // Set language detection to URL.
515
    $edit = array('language[enabled][locale-url]' => TRUE);
516
    $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
517

    
518
    // Force languages to be initialized.
519
    drupal_language_initialize();
520
  }
521

    
522
  /**
523
   * Verifies that links do not have language prefixes in them.
524
   */
525
  function testPageLinks() {
526
    // Navigate to 'admin/config' path.
527
    $this->drupalGet('admin/config');
528

    
529
    // Verify that links in this page do not have a 'fr/' prefix.
530
    $this->assertNoLinkByHref('/fr/', 'Links do not contain language prefix');
531

    
532
    // Verify that links in this page can be followed and work.
533
    $this->clickLink(t('Languages'));
534
    $this->assertResponse(200, 'Clicked link results in a valid page');
535
    $this->assertText(t('Add language'), 'Page contains the add language text');
536
  }
537
}