|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Tests for path.inc. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Unit tests for the drupal_match_path() function in path.inc. |
|
10 * |
|
11 * @see drupal_match_path(). |
|
12 */ |
|
13 class DrupalMatchPathTestCase extends DrupalWebTestCase { |
|
14 protected $front; |
|
15 |
|
16 public static function getInfo() { |
|
17 return array( |
|
18 'name' => 'Drupal match path', |
|
19 'description' => 'Tests the drupal_match_path() function to make sure it works properly.', |
|
20 'group' => 'Path API', |
|
21 ); |
|
22 } |
|
23 |
|
24 function setUp() { |
|
25 // Set up the database and testing environment. |
|
26 parent::setUp(); |
|
27 |
|
28 // Set up a random site front page to test the '<front>' placeholder. |
|
29 $this->front = $this->randomName(); |
|
30 variable_set('site_frontpage', $this->front); |
|
31 // Refresh our static variables from the database. |
|
32 $this->refreshVariables(); |
|
33 } |
|
34 |
|
35 /** |
|
36 * Run through our test cases, making sure each one works as expected. |
|
37 */ |
|
38 function testDrupalMatchPath() { |
|
39 // Set up our test cases. |
|
40 $tests = $this->drupalMatchPathTests(); |
|
41 foreach ($tests as $patterns => $cases) { |
|
42 foreach ($cases as $path => $expected_result) { |
|
43 $actual_result = drupal_match_path($path, $patterns); |
|
44 $this->assertIdentical($actual_result, $expected_result, format_string('Tried matching the path <code>@path</code> to the pattern <pre>@patterns</pre> - expected @expected, got @actual.', array('@path' => $path, '@patterns' => $patterns, '@expected' => var_export($expected_result, TRUE), '@actual' => var_export($actual_result, TRUE)))); |
|
45 } |
|
46 } |
|
47 } |
|
48 |
|
49 /** |
|
50 * Helper function for testDrupalMatchPath(): set up an array of test cases. |
|
51 * |
|
52 * @return |
|
53 * An array of test cases to cycle through. |
|
54 */ |
|
55 private function drupalMatchPathTests() { |
|
56 return array( |
|
57 // Single absolute paths. |
|
58 'blog/1' => array( |
|
59 'blog/1' => TRUE, |
|
60 'blog/2' => FALSE, |
|
61 'test' => FALSE, |
|
62 ), |
|
63 // Single paths with wildcards. |
|
64 'blog/*' => array( |
|
65 'blog/1' => TRUE, |
|
66 'blog/2' => TRUE, |
|
67 'blog/3/edit' => TRUE, |
|
68 'blog/' => TRUE, |
|
69 'blog' => FALSE, |
|
70 'test' => FALSE, |
|
71 ), |
|
72 // Single paths with multiple wildcards. |
|
73 'node/*/revisions/*' => array( |
|
74 'node/1/revisions/3' => TRUE, |
|
75 'node/345/revisions/test' => TRUE, |
|
76 'node/23/edit' => FALSE, |
|
77 'test' => FALSE, |
|
78 ), |
|
79 // Single paths with '<front>'. |
|
80 '<front>' => array( |
|
81 $this->front => TRUE, |
|
82 "$this->front/" => FALSE, |
|
83 "$this->front/edit" => FALSE, |
|
84 'node' => FALSE, |
|
85 '' => FALSE, |
|
86 ), |
|
87 // Paths with both '<front>' and wildcards (should not work). |
|
88 '<front>/*' => array( |
|
89 $this->front => FALSE, |
|
90 "$this->front/" => FALSE, |
|
91 "$this->front/edit" => FALSE, |
|
92 'node/12' => FALSE, |
|
93 '' => FALSE, |
|
94 ), |
|
95 // Multiple paths with the \n delimiter. |
|
96 "node/*\nnode/*/edit" => array( |
|
97 'node/1' => TRUE, |
|
98 'node/view' => TRUE, |
|
99 'node/32/edit' => TRUE, |
|
100 'node/delete/edit' => TRUE, |
|
101 'node/50/delete' => TRUE, |
|
102 'test/example' => FALSE, |
|
103 ), |
|
104 // Multiple paths with the \r delimiter. |
|
105 "user/*\rblog/*" => array( |
|
106 'user/1' => TRUE, |
|
107 'blog/1' => TRUE, |
|
108 'user/1/blog/1' => TRUE, |
|
109 'user/blog' => TRUE, |
|
110 'test/example' => FALSE, |
|
111 'user' => FALSE, |
|
112 'blog' => FALSE, |
|
113 ), |
|
114 // Multiple paths with the \r\n delimiter. |
|
115 "test\r\n<front>" => array( |
|
116 'test' => TRUE, |
|
117 $this->front => TRUE, |
|
118 'example' => FALSE, |
|
119 ), |
|
120 // Test existing regular expressions (should be escaped). |
|
121 '[^/]+?/[0-9]' => array( |
|
122 'test/1' => FALSE, |
|
123 '[^/]+?/[0-9]' => TRUE, |
|
124 ), |
|
125 ); |
|
126 } |
|
127 } |
|
128 |
|
129 /** |
|
130 * Tests hook_url_alter functions. |
|
131 */ |
|
132 class UrlAlterFunctionalTest extends DrupalWebTestCase { |
|
133 public static function getInfo() { |
|
134 return array( |
|
135 'name' => t('URL altering'), |
|
136 'description' => t('Tests hook_url_inbound_alter() and hook_url_outbound_alter().'), |
|
137 'group' => t('Path API'), |
|
138 ); |
|
139 } |
|
140 |
|
141 function setUp() { |
|
142 parent::setUp('path', 'forum', 'url_alter_test'); |
|
143 } |
|
144 |
|
145 /** |
|
146 * Test that URL altering works and that it occurs in the correct order. |
|
147 */ |
|
148 function testUrlAlter() { |
|
149 $account = $this->drupalCreateUser(array('administer url aliases')); |
|
150 $this->drupalLogin($account); |
|
151 |
|
152 $uid = $account->uid; |
|
153 $name = $account->name; |
|
154 |
|
155 // Test a single altered path. |
|
156 $this->assertUrlInboundAlter("user/$name", "user/$uid"); |
|
157 $this->assertUrlOutboundAlter("user/$uid", "user/$name"); |
|
158 |
|
159 // Test that a path always uses its alias. |
|
160 $path = array('source' => "user/$uid/test1", 'alias' => 'alias/test1'); |
|
161 path_save($path); |
|
162 $this->assertUrlInboundAlter('alias/test1', "user/$uid/test1"); |
|
163 $this->assertUrlOutboundAlter("user/$uid/test1", 'alias/test1'); |
|
164 |
|
165 // Test that alias source paths are normalized in the interface. |
|
166 $edit = array('source' => "user/$name/edit", 'alias' => 'alias/test2'); |
|
167 $this->drupalPost('admin/config/search/path/add', $edit, t('Save')); |
|
168 $this->assertText(t('The alias has been saved.')); |
|
169 |
|
170 // Test that a path always uses its alias. |
|
171 $this->assertUrlInboundAlter('alias/test2', "user/$uid/edit"); |
|
172 $this->assertUrlOutboundAlter("user/$uid/edit", 'alias/test2'); |
|
173 |
|
174 // Test a non-existent user is not altered. |
|
175 $uid++; |
|
176 $this->assertUrlInboundAlter("user/$uid", "user/$uid"); |
|
177 $this->assertUrlOutboundAlter("user/$uid", "user/$uid"); |
|
178 |
|
179 // Test that 'forum' is altered to 'community' correctly, both at the root |
|
180 // level and for a specific existing forum. |
|
181 $this->assertUrlInboundAlter('community', 'forum'); |
|
182 $this->assertUrlOutboundAlter('forum', 'community'); |
|
183 $forum_vid = db_query("SELECT vid FROM {taxonomy_vocabulary} WHERE module = 'forum'")->fetchField(); |
|
184 $tid = db_insert('taxonomy_term_data') |
|
185 ->fields(array( |
|
186 'name' => $this->randomName(), |
|
187 'vid' => $forum_vid, |
|
188 )) |
|
189 ->execute(); |
|
190 $this->assertUrlInboundAlter("community/$tid", "forum/$tid"); |
|
191 $this->assertUrlOutboundAlter("forum/$tid", "community/$tid"); |
|
192 } |
|
193 |
|
194 /** |
|
195 * Test current_path() and request_path(). |
|
196 */ |
|
197 function testCurrentUrlRequestedPath() { |
|
198 $this->drupalGet('url-alter-test/bar'); |
|
199 $this->assertRaw('request_path=url-alter-test/bar', 'request_path() returns the requested path.'); |
|
200 $this->assertRaw('current_path=url-alter-test/foo', 'current_path() returns the internal path.'); |
|
201 } |
|
202 |
|
203 /** |
|
204 * Tests that $_GET['q'] is initialized when the request path is empty. |
|
205 */ |
|
206 function testGetQInitialized() { |
|
207 $this->drupalGet(''); |
|
208 $this->assertText("\$_GET['q'] is non-empty with an empty request path.", "\$_GET['q'] is initialized with an empty request path."); |
|
209 } |
|
210 |
|
211 /** |
|
212 * Assert that an outbound path is altered to an expected value. |
|
213 * |
|
214 * @param $original |
|
215 * A string with the original path that is run through url(). |
|
216 * @param $final |
|
217 * A string with the expected result after url(). |
|
218 * @return |
|
219 * TRUE if $original was correctly altered to $final, FALSE otherwise. |
|
220 */ |
|
221 protected function assertUrlOutboundAlter($original, $final) { |
|
222 // Test outbound altering. |
|
223 $result = url($original); |
|
224 $base_path = base_path() . (variable_get('clean_url', '0') ? '' : '?q='); |
|
225 $result = substr($result, strlen($base_path)); |
|
226 $this->assertIdentical($result, $final, format_string('Altered outbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result))); |
|
227 } |
|
228 |
|
229 /** |
|
230 * Assert that a inbound path is altered to an expected value. |
|
231 * |
|
232 * @param $original |
|
233 * A string with the aliased or un-normal path that is run through |
|
234 * drupal_get_normal_path(). |
|
235 * @param $final |
|
236 * A string with the expected result after url(). |
|
237 * @return |
|
238 * TRUE if $original was correctly altered to $final, FALSE otherwise. |
|
239 */ |
|
240 protected function assertUrlInboundAlter($original, $final) { |
|
241 // Test inbound altering. |
|
242 $result = drupal_get_normal_path($original); |
|
243 $this->assertIdentical($result, $final, format_string('Altered inbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result))); |
|
244 } |
|
245 } |
|
246 |
|
247 /** |
|
248 * Unit test for drupal_lookup_path(). |
|
249 */ |
|
250 class PathLookupTest extends DrupalWebTestCase { |
|
251 public static function getInfo() { |
|
252 return array( |
|
253 'name' => t('Path lookup'), |
|
254 'description' => t('Tests that drupal_lookup_path() returns correct paths.'), |
|
255 'group' => t('Path API'), |
|
256 ); |
|
257 } |
|
258 |
|
259 /** |
|
260 * Test that drupal_lookup_path() returns the correct path. |
|
261 */ |
|
262 function testDrupalLookupPath() { |
|
263 $account = $this->drupalCreateUser(); |
|
264 $uid = $account->uid; |
|
265 $name = $account->name; |
|
266 |
|
267 // Test the situation where the source is the same for multiple aliases. |
|
268 // Start with a language-neutral alias, which we will override. |
|
269 $path = array( |
|
270 'source' => "user/$uid", |
|
271 'alias' => 'foo', |
|
272 ); |
|
273 path_save($path); |
|
274 $this->assertEqual(drupal_lookup_path('alias', $path['source']), $path['alias'], 'Basic alias lookup works.'); |
|
275 $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], 'Basic source lookup works.'); |
|
276 |
|
277 // Create a language specific alias for the default language (English). |
|
278 $path = array( |
|
279 'source' => "user/$uid", |
|
280 'alias' => "users/$name", |
|
281 'language' => 'en', |
|
282 ); |
|
283 path_save($path); |
|
284 $this->assertEqual(drupal_lookup_path('alias', $path['source']), $path['alias'], 'English alias overrides language-neutral alias.'); |
|
285 $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], 'English source overrides language-neutral source.'); |
|
286 |
|
287 // Create a language-neutral alias for the same path, again. |
|
288 $path = array( |
|
289 'source' => "user/$uid", |
|
290 'alias' => 'bar', |
|
291 ); |
|
292 path_save($path); |
|
293 $this->assertEqual(drupal_lookup_path('alias', $path['source']), "users/$name", 'English alias still returned after entering a language-neutral alias.'); |
|
294 |
|
295 // Create a language-specific (xx-lolspeak) alias for the same path. |
|
296 $path = array( |
|
297 'source' => "user/$uid", |
|
298 'alias' => 'LOL', |
|
299 'language' => 'xx-lolspeak', |
|
300 ); |
|
301 path_save($path); |
|
302 $this->assertEqual(drupal_lookup_path('alias', $path['source']), "users/$name", 'English alias still returned after entering a LOLspeak alias.'); |
|
303 // The LOLspeak alias should be returned if we really want LOLspeak. |
|
304 $this->assertEqual(drupal_lookup_path('alias', $path['source'], 'xx-lolspeak'), 'LOL', 'LOLspeak alias returned if we specify xx-lolspeak to drupal_lookup_path().'); |
|
305 |
|
306 // Create a new alias for this path in English, which should override the |
|
307 // previous alias for "user/$uid". |
|
308 $path = array( |
|
309 'source' => "user/$uid", |
|
310 'alias' => 'users/my-new-path', |
|
311 'language' => 'en', |
|
312 ); |
|
313 path_save($path); |
|
314 $this->assertEqual(drupal_lookup_path('alias', $path['source']), $path['alias'], 'Recently created English alias returned.'); |
|
315 $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], 'Recently created English source returned.'); |
|
316 |
|
317 // Remove the English aliases, which should cause a fallback to the most |
|
318 // recently created language-neutral alias, 'bar'. |
|
319 db_delete('url_alias') |
|
320 ->condition('language', 'en') |
|
321 ->execute(); |
|
322 drupal_clear_path_cache(); |
|
323 $this->assertEqual(drupal_lookup_path('alias', $path['source']), 'bar', 'Path lookup falls back to recently created language-neutral alias.'); |
|
324 |
|
325 // Test the situation where the alias and language are the same, but |
|
326 // the source differs. The newer alias record should be returned. |
|
327 $account2 = $this->drupalCreateUser(); |
|
328 $path = array( |
|
329 'source' => 'user/' . $account2->uid, |
|
330 'alias' => 'bar', |
|
331 ); |
|
332 path_save($path); |
|
333 $this->assertEqual(drupal_lookup_path('source', $path['alias']), $path['source'], 'Newer alias record is returned when comparing two LANGUAGE_NONE paths with the same alias.'); |
|
334 } |
|
335 } |
|
336 |
|
337 /** |
|
338 * Tests the path_save() function. |
|
339 */ |
|
340 class PathSaveTest extends DrupalWebTestCase { |
|
341 public static function getInfo() { |
|
342 return array( |
|
343 'name' => t('Path save'), |
|
344 'description' => t('Tests that path_save() exposes the previous alias value.'), |
|
345 'group' => t('Path API'), |
|
346 ); |
|
347 } |
|
348 |
|
349 function setUp() { |
|
350 // Enable a helper module that implements hook_path_update(). |
|
351 parent::setUp('path_test'); |
|
352 path_test_reset(); |
|
353 } |
|
354 |
|
355 /** |
|
356 * Tests that path_save() makes the original path available to modules. |
|
357 */ |
|
358 function testDrupalSaveOriginalPath() { |
|
359 $account = $this->drupalCreateUser(); |
|
360 $uid = $account->uid; |
|
361 $name = $account->name; |
|
362 |
|
363 // Create a language-neutral alias. |
|
364 $path = array( |
|
365 'source' => "user/$uid", |
|
366 'alias' => 'foo', |
|
367 ); |
|
368 $path_original = $path; |
|
369 path_save($path); |
|
370 |
|
371 // Alter the path. |
|
372 $path['alias'] = 'bar'; |
|
373 path_save($path); |
|
374 |
|
375 // Test to see if the original alias is available to modules during |
|
376 // hook_path_update(). |
|
377 $results = variable_get('path_test_results', array()); |
|
378 $this->assertIdentical($results['hook_path_update']['original']['alias'], $path_original['alias'], 'Old path alias available to modules during hook_path_update.'); |
|
379 $this->assertIdentical($results['hook_path_update']['original']['source'], $path_original['source'], 'Old path alias available to modules during hook_path_update.'); |
|
380 } |
|
381 } |