1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* Tests for system.module.
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
/**
|
9 |
|
|
* Helper class for module test cases.
|
10 |
|
|
*/
|
11 |
|
|
class ModuleTestCase extends DrupalWebTestCase {
|
12 |
|
|
protected $admin_user;
|
13 |
|
|
|
14 |
|
|
function setUp() {
|
15 |
|
|
parent::setUp('system_test');
|
16 |
|
|
|
17 |
|
|
$this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer modules'));
|
18 |
|
|
$this->drupalLogin($this->admin_user);
|
19 |
|
|
}
|
20 |
|
|
|
21 |
|
|
/**
|
22 |
|
|
* Assert there are tables that begin with the specified base table name.
|
23 |
|
|
*
|
24 |
|
|
* @param $base_table
|
25 |
|
|
* Beginning of table name to look for.
|
26 |
|
|
* @param $count
|
27 |
|
|
* (optional) Whether or not to assert that there are tables that match the
|
28 |
|
|
* specified base table. Defaults to TRUE.
|
29 |
|
|
*/
|
30 |
|
|
function assertTableCount($base_table, $count = TRUE) {
|
31 |
|
|
$tables = db_find_tables(Database::getConnection()->prefixTables('{' . $base_table . '}') . '%');
|
32 |
|
|
|
33 |
|
|
if ($count) {
|
34 |
|
|
return $this->assertTrue($tables, format_string('Tables matching "@base_table" found.', array('@base_table' => $base_table)));
|
35 |
|
|
}
|
36 |
|
|
return $this->assertFalse($tables, format_string('Tables matching "@base_table" not found.', array('@base_table' => $base_table)));
|
37 |
|
|
}
|
38 |
|
|
|
39 |
|
|
/**
|
40 |
|
|
* Assert that all tables defined in a module's hook_schema() exist.
|
41 |
|
|
*
|
42 |
|
|
* @param $module
|
43 |
|
|
* The name of the module.
|
44 |
|
|
*/
|
45 |
|
|
function assertModuleTablesExist($module) {
|
46 |
|
|
$tables = array_keys(drupal_get_schema_unprocessed($module));
|
47 |
|
|
$tables_exist = TRUE;
|
48 |
|
|
foreach ($tables as $table) {
|
49 |
|
|
if (!db_table_exists($table)) {
|
50 |
|
|
$tables_exist = FALSE;
|
51 |
|
|
}
|
52 |
|
|
}
|
53 |
|
|
return $this->assertTrue($tables_exist, format_string('All database tables defined by the @module module exist.', array('@module' => $module)));
|
54 |
|
|
}
|
55 |
|
|
|
56 |
|
|
/**
|
57 |
|
|
* Assert that none of the tables defined in a module's hook_schema() exist.
|
58 |
|
|
*
|
59 |
|
|
* @param $module
|
60 |
|
|
* The name of the module.
|
61 |
|
|
*/
|
62 |
|
|
function assertModuleTablesDoNotExist($module) {
|
63 |
|
|
$tables = array_keys(drupal_get_schema_unprocessed($module));
|
64 |
|
|
$tables_exist = FALSE;
|
65 |
|
|
foreach ($tables as $table) {
|
66 |
|
|
if (db_table_exists($table)) {
|
67 |
|
|
$tables_exist = TRUE;
|
68 |
|
|
}
|
69 |
|
|
}
|
70 |
|
|
return $this->assertFalse($tables_exist, format_string('None of the database tables defined by the @module module exist.', array('@module' => $module)));
|
71 |
|
|
}
|
72 |
|
|
|
73 |
|
|
/**
|
74 |
|
|
* Assert the list of modules are enabled or disabled.
|
75 |
|
|
*
|
76 |
|
|
* @param $modules
|
77 |
|
|
* Module list to check.
|
78 |
|
|
* @param $enabled
|
79 |
|
|
* Expected module state.
|
80 |
|
|
*/
|
81 |
|
|
function assertModules(array $modules, $enabled) {
|
82 |
|
|
module_list(TRUE);
|
83 |
|
|
foreach ($modules as $module) {
|
84 |
|
|
if ($enabled) {
|
85 |
|
|
$message = 'Module "@module" is enabled.';
|
86 |
|
|
}
|
87 |
|
|
else {
|
88 |
|
|
$message = 'Module "@module" is not enabled.';
|
89 |
|
|
}
|
90 |
|
|
$this->assertEqual(module_exists($module), $enabled, format_string($message, array('@module' => $module)));
|
91 |
|
|
}
|
92 |
|
|
}
|
93 |
|
|
|
94 |
|
|
/**
|
95 |
|
|
* Verify a log entry was entered for a module's status change.
|
96 |
|
|
* Called in the same way of the expected original watchdog() execution.
|
97 |
|
|
*
|
98 |
|
|
* @param $type
|
99 |
|
|
* The category to which this message belongs.
|
100 |
|
|
* @param $message
|
101 |
|
|
* The message to store in the log. Keep $message translatable
|
102 |
|
|
* by not concatenating dynamic values into it! Variables in the
|
103 |
|
|
* message should be added by using placeholder strings alongside
|
104 |
|
|
* the variables argument to declare the value of the placeholders.
|
105 |
|
|
* See t() for documentation on how $message and $variables interact.
|
106 |
|
|
* @param $variables
|
107 |
|
|
* Array of variables to replace in the message on display or
|
108 |
|
|
* NULL if message is already translated or not possible to
|
109 |
|
|
* translate.
|
110 |
|
|
* @param $severity
|
111 |
|
|
* The severity of the message, as per RFC 3164.
|
112 |
|
|
* @param $link
|
113 |
|
|
* A link to associate with the message.
|
114 |
|
|
*/
|
115 |
|
|
function assertLogMessage($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = '') {
|
116 |
|
|
$count = db_select('watchdog', 'w')
|
117 |
|
|
->condition('type', $type)
|
118 |
|
|
->condition('message', $message)
|
119 |
|
|
->condition('variables', serialize($variables))
|
120 |
|
|
->condition('severity', $severity)
|
121 |
|
|
->condition('link', $link)
|
122 |
|
|
->countQuery()
|
123 |
|
|
->execute()
|
124 |
|
|
->fetchField();
|
125 |
|
|
$this->assertTrue($count > 0, format_string('watchdog table contains @count rows for @message', array('@count' => $count, '@message' => $message)));
|
126 |
|
|
}
|
127 |
|
|
}
|
128 |
|
|
|
129 |
|
|
/**
|
130 |
|
|
* Test module enabling/disabling functionality.
|
131 |
|
|
*/
|
132 |
|
|
class EnableDisableTestCase extends ModuleTestCase {
|
133 |
|
|
protected $profile = 'testing';
|
134 |
|
|
|
135 |
|
|
public static function getInfo() {
|
136 |
|
|
return array(
|
137 |
|
|
'name' => 'Enable/disable modules',
|
138 |
|
|
'description' => 'Enable/disable core module and confirm table creation/deletion.',
|
139 |
|
|
'group' => 'Module',
|
140 |
|
|
);
|
141 |
|
|
}
|
142 |
|
|
|
143 |
|
|
/**
|
144 |
|
|
* Test that all core modules can be enabled, disabled and uninstalled.
|
145 |
|
|
*/
|
146 |
|
|
function testEnableDisable() {
|
147 |
|
|
// Try to enable, disable and uninstall all core modules, unless they are
|
148 |
|
|
// hidden or required.
|
149 |
|
|
$modules = system_rebuild_module_data();
|
150 |
|
|
foreach ($modules as $name => $module) {
|
151 |
|
|
if ($module->info['package'] != 'Core' || !empty($module->info['hidden']) || !empty($module->info['required'])) {
|
152 |
|
|
unset($modules[$name]);
|
153 |
|
|
}
|
154 |
|
|
}
|
155 |
|
|
$this->assertTrue(count($modules), format_string('Found @count core modules that we can try to enable in this test.', array('@count' => count($modules))));
|
156 |
|
|
|
157 |
|
|
// Enable the dblog module first, since we will be asserting the presence
|
158 |
|
|
// of log messages throughout the test.
|
159 |
|
|
if (isset($modules['dblog'])) {
|
160 |
|
|
$modules = array('dblog' => $modules['dblog']) + $modules;
|
161 |
|
|
}
|
162 |
|
|
|
163 |
|
|
// Set a variable so that the hook implementations in system_test.module
|
164 |
|
|
// will display messages via drupal_set_message().
|
165 |
|
|
variable_set('test_verbose_module_hooks', TRUE);
|
166 |
|
|
|
167 |
|
|
// Throughout this test, some modules may be automatically enabled (due to
|
168 |
|
|
// dependencies). We'll keep track of them in an array, so we can handle
|
169 |
|
|
// them separately.
|
170 |
|
|
$automatically_enabled = array();
|
171 |
|
|
|
172 |
|
|
// Go through each module in the list and try to enable it (unless it was
|
173 |
|
|
// already enabled automatically due to a dependency).
|
174 |
|
|
foreach ($modules as $name => $module) {
|
175 |
|
|
if (empty($automatically_enabled[$name])) {
|
176 |
|
|
// Start a list of modules that we expect to be enabled this time.
|
177 |
|
|
$modules_to_enable = array($name);
|
178 |
|
|
|
179 |
|
|
// Find out if the module has any dependencies that aren't enabled yet;
|
180 |
|
|
// if so, add them to the list of modules we expect to be automatically
|
181 |
|
|
// enabled.
|
182 |
|
|
foreach (array_keys($module->requires) as $dependency) {
|
183 |
|
|
if (isset($modules[$dependency]) && empty($automatically_enabled[$dependency])) {
|
184 |
|
|
$modules_to_enable[] = $dependency;
|
185 |
|
|
$automatically_enabled[$dependency] = TRUE;
|
186 |
|
|
}
|
187 |
|
|
}
|
188 |
|
|
|
189 |
|
|
// Check that each module is not yet enabled and does not have any
|
190 |
|
|
// database tables yet.
|
191 |
|
|
foreach ($modules_to_enable as $module_to_enable) {
|
192 |
|
|
$this->assertModules(array($module_to_enable), FALSE);
|
193 |
|
|
$this->assertModuleTablesDoNotExist($module_to_enable);
|
194 |
|
|
}
|
195 |
|
|
|
196 |
|
|
// Install and enable the module.
|
197 |
|
|
$edit = array();
|
198 |
|
|
$edit['modules[Core][' . $name . '][enable]'] = $name;
|
199 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
200 |
|
|
// Handle the case where modules were installed along with this one and
|
201 |
|
|
// where we therefore hit a confirmation screen.
|
202 |
|
|
if (count($modules_to_enable) > 1) {
|
203 |
|
|
$this->drupalPost(NULL, array(), t('Continue'));
|
204 |
|
|
}
|
205 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
206 |
|
|
|
207 |
|
|
// Check that hook_modules_installed() and hook_modules_enabled() were
|
208 |
|
|
// invoked with the expected list of modules, that each module's
|
209 |
|
|
// database tables now exist, and that appropriate messages appear in
|
210 |
|
|
// the logs.
|
211 |
|
|
foreach ($modules_to_enable as $module_to_enable) {
|
212 |
|
|
$this->assertText(t('hook_modules_installed fired for @module', array('@module' => $module_to_enable)));
|
213 |
|
|
$this->assertText(t('hook_modules_enabled fired for @module', array('@module' => $module_to_enable)));
|
214 |
|
|
$this->assertModules(array($module_to_enable), TRUE);
|
215 |
|
|
$this->assertModuleTablesExist($module_to_enable);
|
216 |
|
|
$this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_enable), WATCHDOG_INFO);
|
217 |
|
|
$this->assertLogMessage('system', "%module module enabled.", array('%module' => $module_to_enable), WATCHDOG_INFO);
|
218 |
|
|
}
|
219 |
|
|
|
220 |
|
|
// Disable and uninstall the original module, and check appropriate
|
221 |
|
|
// hooks, tables, and log messages. (Later, we'll go back and do the
|
222 |
|
|
// same thing for modules that were enabled automatically.) Skip this
|
223 |
|
|
// for the dblog module, because that is needed for the test; we'll go
|
224 |
|
|
// back and do that one at the end also.
|
225 |
|
|
if ($name != 'dblog') {
|
226 |
|
|
$this->assertSuccessfulDisableAndUninstall($name);
|
227 |
|
|
}
|
228 |
|
|
}
|
229 |
|
|
}
|
230 |
|
|
|
231 |
|
|
// Go through all modules that were automatically enabled, and try to
|
232 |
|
|
// disable and uninstall them one by one.
|
233 |
|
|
while (!empty($automatically_enabled)) {
|
234 |
|
|
$initial_count = count($automatically_enabled);
|
235 |
|
|
foreach (array_keys($automatically_enabled) as $name) {
|
236 |
|
|
// If the module can't be disabled due to dependencies, skip it and try
|
237 |
|
|
// again the next time. Otherwise, try to disable it.
|
238 |
|
|
$this->drupalGet('admin/modules');
|
239 |
|
|
$disabled_checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Core][' . $name . '][enable]"]');
|
240 |
|
|
if (empty($disabled_checkbox) && $name != 'dblog') {
|
241 |
|
|
unset($automatically_enabled[$name]);
|
242 |
|
|
$this->assertSuccessfulDisableAndUninstall($name);
|
243 |
|
|
}
|
244 |
|
|
}
|
245 |
|
|
$final_count = count($automatically_enabled);
|
246 |
|
|
// If all checkboxes were disabled, something is really wrong with the
|
247 |
|
|
// test. Throw a failure and avoid an infinite loop.
|
248 |
|
|
if ($initial_count == $final_count) {
|
249 |
|
|
$this->fail(t('Remaining modules could not be disabled.'));
|
250 |
|
|
break;
|
251 |
|
|
}
|
252 |
|
|
}
|
253 |
|
|
|
254 |
|
|
// Disable and uninstall the dblog module last, since we needed it for
|
255 |
|
|
// assertions in all the above tests.
|
256 |
|
|
if (isset($modules['dblog'])) {
|
257 |
|
|
$this->assertSuccessfulDisableAndUninstall('dblog');
|
258 |
|
|
}
|
259 |
|
|
|
260 |
|
|
// Now that all modules have been tested, go back and try to enable them
|
261 |
|
|
// all again at once. This tests two things:
|
262 |
|
|
// - That each module can be successfully enabled again after being
|
263 |
|
|
// uninstalled.
|
264 |
|
|
// - That enabling more than one module at the same time does not lead to
|
265 |
|
|
// any errors.
|
266 |
|
|
$edit = array();
|
267 |
|
|
foreach (array_keys($modules) as $name) {
|
268 |
|
|
$edit['modules[Core][' . $name . '][enable]'] = $name;
|
269 |
|
|
}
|
270 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
271 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
272 |
|
|
}
|
273 |
|
|
|
274 |
|
|
/**
|
275 |
|
|
* Ensures entity info cache is updated after changes.
|
276 |
|
|
*/
|
277 |
|
|
function testEntityInfoChanges() {
|
278 |
|
|
module_enable(array('entity_cache_test'));
|
279 |
|
|
$entity_info = entity_get_info();
|
280 |
|
|
$this->assertTrue(isset($entity_info['entity_cache_test']), 'Test entity type found.');
|
281 |
|
|
|
282 |
|
|
// Change the label of the test entity type and make sure changes appear
|
283 |
|
|
// after flushing caches.
|
284 |
|
|
variable_set('entity_cache_test_label', 'New label.');
|
285 |
|
|
drupal_flush_all_caches();
|
286 |
|
|
$info = entity_get_info('entity_cache_test');
|
287 |
|
|
$this->assertEqual($info['label'], 'New label.', 'New label appears in entity info.');
|
288 |
|
|
|
289 |
|
|
// Disable the providing module and make sure the entity type is gone.
|
290 |
|
|
module_disable(array('entity_cache_test', 'entity_cache_test_dependency'));
|
291 |
|
|
$entity_info = entity_get_info();
|
292 |
|
|
$this->assertFalse(isset($entity_info['entity_cache_test']), 'Entity type of the providing module is gone.');
|
293 |
|
|
}
|
294 |
|
|
|
295 |
|
|
/**
|
296 |
|
|
* Tests entity info cache after enabling a module with a dependency on an entity providing module.
|
297 |
|
|
*
|
298 |
|
|
* @see entity_cache_test_watchdog()
|
299 |
|
|
*/
|
300 |
|
|
function testEntityInfoCacheWatchdog() {
|
301 |
|
|
module_enable(array('entity_cache_test'));
|
302 |
|
|
$info = variable_get('entity_cache_test');
|
303 |
|
|
$this->assertEqual($info['label'], 'Entity Cache Test', 'Entity info label is correct.');
|
304 |
|
|
$this->assertEqual($info['controller class'], 'DrupalDefaultEntityController', 'Entity controller class info is correct.');
|
305 |
|
|
}
|
306 |
|
|
|
307 |
|
|
/**
|
308 |
|
|
* Disables and uninstalls a module and asserts that it was done correctly.
|
309 |
|
|
*
|
310 |
|
|
* @param $module
|
311 |
|
|
* The name of the module to disable and uninstall.
|
312 |
|
|
*/
|
313 |
|
|
function assertSuccessfulDisableAndUninstall($module) {
|
314 |
|
|
// Disable the module.
|
315 |
|
|
$edit = array();
|
316 |
|
|
$edit['modules[Core][' . $module . '][enable]'] = FALSE;
|
317 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
318 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
319 |
|
|
$this->assertModules(array($module), FALSE);
|
320 |
|
|
|
321 |
|
|
// Check that the appropriate hook was fired and the appropriate log
|
322 |
|
|
// message appears.
|
323 |
|
|
$this->assertText(t('hook_modules_disabled fired for @module', array('@module' => $module)));
|
324 |
|
|
$this->assertLogMessage('system', "%module module disabled.", array('%module' => $module), WATCHDOG_INFO);
|
325 |
|
|
|
326 |
|
|
// Check that the module's database tables still exist.
|
327 |
|
|
$this->assertModuleTablesExist($module);
|
328 |
|
|
|
329 |
|
|
// Uninstall the module.
|
330 |
|
|
$edit = array();
|
331 |
|
|
$edit['uninstall[' . $module . ']'] = $module;
|
332 |
|
|
$this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
|
333 |
|
|
$this->drupalPost(NULL, NULL, t('Uninstall'));
|
334 |
|
|
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
|
335 |
|
|
$this->assertModules(array($module), FALSE);
|
336 |
|
|
|
337 |
|
|
// Check that the appropriate hook was fired and the appropriate log
|
338 |
|
|
// message appears. (But don't check for the log message if the dblog
|
339 |
|
|
// module was just uninstalled, since the {watchdog} table won't be there
|
340 |
|
|
// anymore.)
|
341 |
|
|
$this->assertText(t('hook_modules_uninstalled fired for @module', array('@module' => $module)));
|
342 |
|
|
if ($module != 'dblog') {
|
343 |
|
|
$this->assertLogMessage('system', "%module module uninstalled.", array('%module' => $module), WATCHDOG_INFO);
|
344 |
|
|
}
|
345 |
|
|
|
346 |
|
|
// Check that the module's database tables no longer exist.
|
347 |
|
|
$this->assertModuleTablesDoNotExist($module);
|
348 |
|
|
}
|
349 |
|
|
}
|
350 |
|
|
|
351 |
|
|
/**
|
352 |
|
|
* Tests failure of hook_requirements('install').
|
353 |
|
|
*/
|
354 |
|
|
class HookRequirementsTestCase extends ModuleTestCase {
|
355 |
|
|
public static function getInfo() {
|
356 |
|
|
return array(
|
357 |
|
|
'name' => 'Requirements hook failure',
|
358 |
|
|
'description' => "Attempts enabling a module that fails hook_requirements('install').",
|
359 |
|
|
'group' => 'Module',
|
360 |
|
|
);
|
361 |
|
|
}
|
362 |
|
|
|
363 |
|
|
/**
|
364 |
|
|
* Assert that a module cannot be installed if it fails hook_requirements().
|
365 |
|
|
*/
|
366 |
|
|
function testHookRequirementsFailure() {
|
367 |
|
|
$this->assertModules(array('requirements1_test'), FALSE);
|
368 |
|
|
|
369 |
|
|
// Attempt to install the requirements1_test module.
|
370 |
|
|
$edit = array();
|
371 |
|
|
$edit['modules[Testing][requirements1_test][enable]'] = 'requirements1_test';
|
372 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
373 |
|
|
|
374 |
|
|
// Makes sure the module was NOT installed.
|
375 |
|
|
$this->assertText(t('Requirements 1 Test failed requirements'), 'Modules status has been updated.');
|
376 |
|
|
$this->assertModules(array('requirements1_test'), FALSE);
|
377 |
|
|
}
|
378 |
|
|
}
|
379 |
|
|
|
380 |
|
|
/**
|
381 |
|
|
* Test module dependency functionality.
|
382 |
|
|
*/
|
383 |
|
|
class ModuleDependencyTestCase extends ModuleTestCase {
|
384 |
|
|
public static function getInfo() {
|
385 |
|
|
return array(
|
386 |
|
|
'name' => 'Module dependencies',
|
387 |
|
|
'description' => 'Enable module without dependency enabled.',
|
388 |
|
|
'group' => 'Module',
|
389 |
|
|
);
|
390 |
|
|
}
|
391 |
|
|
|
392 |
|
|
/**
|
393 |
|
|
* Attempt to enable translation module without locale enabled.
|
394 |
|
|
*/
|
395 |
|
|
function testEnableWithoutDependency() {
|
396 |
|
|
// Attempt to enable content translation without locale enabled.
|
397 |
|
|
$edit = array();
|
398 |
|
|
$edit['modules[Core][translation][enable]'] = 'translation';
|
399 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
400 |
|
|
$this->assertText(t('Some required modules must be enabled'), 'Dependency required.');
|
401 |
|
|
|
402 |
|
|
$this->assertModules(array('translation', 'locale'), FALSE);
|
403 |
|
|
|
404 |
|
|
// Assert that the locale tables weren't enabled.
|
405 |
|
|
$this->assertTableCount('languages', FALSE);
|
406 |
|
|
$this->assertTableCount('locale', FALSE);
|
407 |
|
|
|
408 |
|
|
$this->drupalPost(NULL, NULL, t('Continue'));
|
409 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
410 |
|
|
|
411 |
|
|
$this->assertModules(array('translation', 'locale'), TRUE);
|
412 |
|
|
|
413 |
|
|
// Assert that the locale tables were enabled.
|
414 |
|
|
$this->assertTableCount('languages', TRUE);
|
415 |
|
|
$this->assertTableCount('locale', TRUE);
|
416 |
|
|
}
|
417 |
|
|
|
418 |
|
|
/**
|
419 |
|
|
* Attempt to enable a module with a missing dependency.
|
420 |
|
|
*/
|
421 |
|
|
function testMissingModules() {
|
422 |
|
|
// Test that the system_dependencies_test module is marked
|
423 |
|
|
// as missing a dependency.
|
424 |
|
|
$this->drupalGet('admin/modules');
|
425 |
|
|
$this->assertRaw(t('@module (<span class="admin-missing">missing</span>)', array('@module' => drupal_ucfirst('_missing_dependency'))), 'A module with missing dependencies is marked as such.');
|
426 |
|
|
$checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_dependencies_test][enable]"]');
|
427 |
|
|
$this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
|
428 |
|
|
|
429 |
|
|
// Force enable the system_dependencies_test module.
|
430 |
|
|
module_enable(array('system_dependencies_test'), FALSE);
|
431 |
|
|
|
432 |
|
|
// Verify that the module is forced to be disabled when submitting
|
433 |
|
|
// the module page.
|
434 |
|
|
$this->drupalPost('admin/modules', array(), t('Save configuration'));
|
435 |
|
|
$this->assertText(t('The @module module is missing, so the following module will be disabled: @depends.', array('@module' => '_missing_dependency', '@depends' => 'system_dependencies_test')), 'The module missing dependencies will be disabled.');
|
436 |
|
|
|
437 |
|
|
// Confirm.
|
438 |
|
|
$this->drupalPost(NULL, NULL, t('Continue'));
|
439 |
|
|
|
440 |
|
|
// Verify that the module has been disabled.
|
441 |
|
|
$this->assertModules(array('system_dependencies_test'), FALSE);
|
442 |
|
|
}
|
443 |
|
|
|
444 |
|
|
/**
|
445 |
|
|
* Tests enabling a module that depends on an incompatible version of a module.
|
446 |
|
|
*/
|
447 |
|
|
function testIncompatibleModuleVersionDependency() {
|
448 |
|
|
// Test that the system_incompatible_module_version_dependencies_test is
|
449 |
|
|
// marked as having an incompatible dependency.
|
450 |
|
|
$this->drupalGet('admin/modules');
|
451 |
|
|
$this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
|
452 |
|
|
'@module' => 'System incompatible module version test (>2.0)',
|
453 |
|
|
'@version' => '1.0',
|
454 |
|
|
)), 'A module that depends on an incompatible version of a module is marked as such.');
|
455 |
|
|
$checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_module_version_dependencies_test][enable]"]');
|
456 |
|
|
$this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
|
457 |
|
|
}
|
458 |
|
|
|
459 |
|
|
/**
|
460 |
|
|
* Tests enabling a module that depends on a module with an incompatible core version.
|
461 |
|
|
*/
|
462 |
|
|
function testIncompatibleCoreVersionDependency() {
|
463 |
|
|
// Test that the system_incompatible_core_version_dependencies_test is
|
464 |
|
|
// marked as having an incompatible dependency.
|
465 |
|
|
$this->drupalGet('admin/modules');
|
466 |
|
|
$this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
|
467 |
|
|
'@module' => 'System incompatible core version test',
|
468 |
|
|
)), 'A module that depends on a module with an incompatible core version is marked as such.');
|
469 |
|
|
$checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_core_version_dependencies_test][enable]"]');
|
470 |
|
|
$this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
|
471 |
|
|
}
|
472 |
|
|
|
473 |
|
|
/**
|
474 |
|
|
* Tests enabling a module that depends on a module which fails hook_requirements().
|
475 |
|
|
*/
|
476 |
|
|
function testEnableRequirementsFailureDependency() {
|
477 |
|
|
$this->assertModules(array('requirements1_test'), FALSE);
|
478 |
|
|
$this->assertModules(array('requirements2_test'), FALSE);
|
479 |
|
|
|
480 |
|
|
// Attempt to install both modules at the same time.
|
481 |
|
|
$edit = array();
|
482 |
|
|
$edit['modules[Testing][requirements1_test][enable]'] = 'requirements1_test';
|
483 |
|
|
$edit['modules[Testing][requirements2_test][enable]'] = 'requirements2_test';
|
484 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
485 |
|
|
|
486 |
|
|
// Makes sure the modules were NOT installed.
|
487 |
|
|
$this->assertText(t('Requirements 1 Test failed requirements'), 'Modules status has been updated.');
|
488 |
|
|
$this->assertModules(array('requirements1_test'), FALSE);
|
489 |
|
|
$this->assertModules(array('requirements2_test'), FALSE);
|
490 |
|
|
|
491 |
|
|
// Makes sure that already enabled modules the failing modules depend on
|
492 |
|
|
// were not disabled.
|
493 |
|
|
$this->assertModules(array('comment'), TRUE);
|
494 |
|
|
|
495 |
|
|
}
|
496 |
|
|
|
497 |
|
|
/**
|
498 |
|
|
* Tests that module dependencies are enabled in the correct order via the
|
499 |
|
|
* UI. Dependencies should be enabled before their dependents.
|
500 |
|
|
*/
|
501 |
|
|
function testModuleEnableOrder() {
|
502 |
|
|
module_enable(array('module_test'), FALSE);
|
503 |
|
|
$this->resetAll();
|
504 |
|
|
$this->assertModules(array('module_test'), TRUE);
|
505 |
|
|
variable_set('dependency_test', 'dependency');
|
506 |
|
|
// module_test creates a dependency chain: forum depends on poll, which
|
507 |
|
|
// depends on php. The correct enable order is, php, poll, forum.
|
508 |
|
|
$expected_order = array('php', 'poll', 'forum');
|
509 |
|
|
|
510 |
|
|
// Enable the modules through the UI, verifying that the dependency chain
|
511 |
|
|
// is correct.
|
512 |
|
|
$edit = array();
|
513 |
|
|
$edit['modules[Core][forum][enable]'] = 'forum';
|
514 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
515 |
|
|
$this->assertModules(array('forum'), FALSE);
|
516 |
|
|
$this->assertText(t('You must enable the Poll, PHP filter modules to install Forum.'), t('Dependency chain created.'));
|
517 |
|
|
$edit['modules[Core][poll][enable]'] = 'poll';
|
518 |
|
|
$edit['modules[Core][php][enable]'] = 'php';
|
519 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
520 |
|
|
$this->assertModules(array('forum', 'poll', 'php'), TRUE);
|
521 |
|
|
|
522 |
|
|
// Check the actual order which is saved by module_test_modules_enabled().
|
523 |
|
|
$this->assertIdentical(variable_get('test_module_enable_order', FALSE), $expected_order, t('Modules enabled in the correct order.'));
|
524 |
|
|
}
|
525 |
|
|
|
526 |
|
|
/**
|
527 |
|
|
* Tests attempting to uninstall a module that has installed dependents.
|
528 |
|
|
*/
|
529 |
|
|
function testUninstallDependents() {
|
530 |
|
|
// Enable the forum module.
|
531 |
|
|
$edit = array('modules[Core][forum][enable]' => 'forum');
|
532 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
533 |
|
|
$this->assertModules(array('forum'), TRUE);
|
534 |
|
|
|
535 |
|
|
// Disable forum and comment. Both should now be installed but disabled.
|
536 |
|
|
$edit = array('modules[Core][forum][enable]' => FALSE);
|
537 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
538 |
|
|
$this->assertModules(array('forum'), FALSE);
|
539 |
|
|
$edit = array('modules[Core][comment][enable]' => FALSE);
|
540 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
541 |
|
|
$this->assertModules(array('comment'), FALSE);
|
542 |
|
|
|
543 |
|
|
// Check that the taxonomy module cannot be uninstalled.
|
544 |
|
|
$this->drupalGet('admin/modules/uninstall');
|
545 |
|
|
$checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="uninstall[comment]"]');
|
546 |
|
|
$this->assert(count($checkbox) == 1, 'Checkbox for uninstalling the comment module is disabled.');
|
547 |
|
|
|
548 |
|
|
// Uninstall the forum module, and check that taxonomy now can also be
|
549 |
|
|
// uninstalled.
|
550 |
|
|
$edit = array('uninstall[forum]' => 'forum');
|
551 |
|
|
$this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
|
552 |
|
|
$this->drupalPost(NULL, NULL, t('Uninstall'));
|
553 |
|
|
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
|
554 |
|
|
$edit = array('uninstall[comment]' => 'comment');
|
555 |
|
|
$this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
|
556 |
|
|
$this->drupalPost(NULL, NULL, t('Uninstall'));
|
557 |
|
|
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
|
558 |
|
|
}
|
559 |
b4adf10d
|
Assos Assos
|
|
560 |
|
|
/**
|
561 |
|
|
* Tests whether the correct module metadata is returned.
|
562 |
|
|
*/
|
563 |
|
|
function testModuleMetaData() {
|
564 |
|
|
// Generate the list of available modules.
|
565 |
|
|
$modules = system_rebuild_module_data();
|
566 |
|
|
// Check that the mtime field exists for the system module.
|
567 |
|
|
$this->assertTrue(!empty($modules['system']->info['mtime']), 'The system.info file modification time field is present.');
|
568 |
|
|
// Use 0 if mtime isn't present, to avoid an array index notice.
|
569 |
|
|
$test_mtime = !empty($modules['system']->info['mtime']) ? $modules['system']->info['mtime'] : 0;
|
570 |
|
|
// Ensure the mtime field contains a number that is greater than zero.
|
571 |
|
|
$this->assertTrue(is_numeric($test_mtime) && ($test_mtime > 0), 'The system.info file modification time field contains a timestamp.');
|
572 |
|
|
}
|
573 |
|
|
|
574 |
|
|
/**
|
575 |
|
|
* Tests whether the correct theme metadata is returned.
|
576 |
|
|
*/
|
577 |
|
|
function testThemeMetaData() {
|
578 |
|
|
// Generate the list of available themes.
|
579 |
|
|
$themes = system_rebuild_theme_data();
|
580 |
|
|
// Check that the mtime field exists for the bartik theme.
|
581 |
|
|
$this->assertTrue(!empty($themes['bartik']->info['mtime']), 'The bartik.info file modification time field is present.');
|
582 |
|
|
// Use 0 if mtime isn't present, to avoid an array index notice.
|
583 |
|
|
$test_mtime = !empty($themes['bartik']->info['mtime']) ? $themes['bartik']->info['mtime'] : 0;
|
584 |
|
|
// Ensure the mtime field contains a number that is greater than zero.
|
585 |
|
|
$this->assertTrue(is_numeric($test_mtime) && ($test_mtime > 0), 'The bartik.info file modification time field contains a timestamp.');
|
586 |
|
|
}
|
587 |
85ad3d82
|
Assos Assos
|
}
|
588 |
|
|
|
589 |
|
|
/**
|
590 |
|
|
* Test module dependency on specific versions.
|
591 |
|
|
*/
|
592 |
|
|
class ModuleVersionTestCase extends ModuleTestCase {
|
593 |
|
|
public static function getInfo() {
|
594 |
|
|
return array(
|
595 |
|
|
'name' => 'Module versions',
|
596 |
|
|
'description' => 'Check module version dependencies.',
|
597 |
|
|
'group' => 'Module',
|
598 |
|
|
);
|
599 |
|
|
}
|
600 |
|
|
|
601 |
|
|
function setUp() {
|
602 |
|
|
parent::setUp('module_test');
|
603 |
|
|
}
|
604 |
|
|
|
605 |
|
|
/**
|
606 |
|
|
* Test version dependencies.
|
607 |
|
|
*/
|
608 |
|
|
function testModuleVersions() {
|
609 |
|
|
$dependencies = array(
|
610 |
|
|
// Alternating between being compatible and incompatible with 7.x-2.4-beta3.
|
611 |
|
|
// The first is always a compatible.
|
612 |
|
|
'common_test',
|
613 |
|
|
// Branch incompatibility.
|
614 |
|
|
'common_test (1.x)',
|
615 |
|
|
// Branch compatibility.
|
616 |
|
|
'common_test (2.x)',
|
617 |
|
|
// Another branch incompatibility.
|
618 |
|
|
'common_test (>2.x)',
|
619 |
|
|
// Another branch compatibility.
|
620 |
|
|
'common_test (<=2.x)',
|
621 |
|
|
// Another branch incompatibility.
|
622 |
|
|
'common_test (<2.x)',
|
623 |
|
|
// Another branch compatibility.
|
624 |
|
|
'common_test (>=2.x)',
|
625 |
|
|
// Nonsense, misses a dash. Incompatible with everything.
|
626 |
|
|
'common_test (=7.x2.x, >=2.4)',
|
627 |
|
|
// Core version is optional. Compatible.
|
628 |
|
|
'common_test (=7.x-2.x, >=2.4-alpha2)',
|
629 |
|
|
// Test !=, explicitly incompatible.
|
630 |
|
|
'common_test (=2.x, !=2.4-beta3)',
|
631 |
|
|
// Three operations. Compatible.
|
632 |
|
|
'common_test (=2.x, !=2.3, <2.5)',
|
633 |
|
|
// Testing extra version. Incompatible.
|
634 |
|
|
'common_test (<=2.4-beta2)',
|
635 |
|
|
// Testing extra version. Compatible.
|
636 |
|
|
'common_test (>2.4-beta2)',
|
637 |
|
|
// Testing extra version. Incompatible.
|
638 |
|
|
'common_test (>2.4-rc0)',
|
639 |
|
|
);
|
640 |
|
|
variable_set('dependencies', $dependencies);
|
641 |
|
|
$n = count($dependencies);
|
642 |
|
|
for ($i = 0; $i < $n; $i++) {
|
643 |
|
|
$this->drupalGet('admin/modules');
|
644 |
|
|
$checkbox = $this->xpath('//input[@id="edit-modules-testing-module-test-enable"]');
|
645 |
|
|
$this->assertEqual(!empty($checkbox[0]['disabled']), $i % 2, $dependencies[$i]);
|
646 |
|
|
}
|
647 |
|
|
}
|
648 |
|
|
}
|
649 |
|
|
|
650 |
|
|
/**
|
651 |
|
|
* Test required modules functionality.
|
652 |
|
|
*/
|
653 |
|
|
class ModuleRequiredTestCase extends ModuleTestCase {
|
654 |
|
|
public static function getInfo() {
|
655 |
|
|
return array(
|
656 |
|
|
'name' => 'Required modules',
|
657 |
|
|
'description' => 'Attempt disabling of required modules.',
|
658 |
|
|
'group' => 'Module',
|
659 |
|
|
);
|
660 |
|
|
}
|
661 |
|
|
|
662 |
|
|
/**
|
663 |
|
|
* Assert that core required modules cannot be disabled.
|
664 |
|
|
*/
|
665 |
|
|
function testDisableRequired() {
|
666 |
|
|
$module_info = system_get_info('module');
|
667 |
|
|
$this->drupalGet('admin/modules');
|
668 |
|
|
foreach ($module_info as $module => $info) {
|
669 |
|
|
// Check to make sure the checkbox for each required module is disabled
|
670 |
|
|
// and checked (or absent from the page if the module is also hidden).
|
671 |
|
|
if (!empty($info['required'])) {
|
672 |
|
|
$field_name = "modules[{$info['package']}][$module][enable]";
|
673 |
|
|
if (empty($info['hidden'])) {
|
674 |
|
|
$this->assertFieldByXPath("//input[@name='$field_name' and @disabled='disabled' and @checked='checked']", '', format_string('Field @name was disabled and checked.', array('@name' => $field_name)));
|
675 |
|
|
}
|
676 |
|
|
else {
|
677 |
|
|
$this->assertNoFieldByName($field_name);
|
678 |
|
|
}
|
679 |
|
|
}
|
680 |
|
|
}
|
681 |
|
|
}
|
682 |
|
|
}
|
683 |
|
|
|
684 |
|
|
class IPAddressBlockingTestCase extends DrupalWebTestCase {
|
685 |
|
|
protected $blocking_user;
|
686 |
|
|
|
687 |
|
|
/**
|
688 |
|
|
* Implement getInfo().
|
689 |
|
|
*/
|
690 |
|
|
public static function getInfo() {
|
691 |
|
|
return array(
|
692 |
|
|
'name' => 'IP address blocking',
|
693 |
|
|
'description' => 'Test IP address blocking.',
|
694 |
|
|
'group' => 'System'
|
695 |
|
|
);
|
696 |
|
|
}
|
697 |
|
|
|
698 |
|
|
/**
|
699 |
|
|
* Implement setUp().
|
700 |
|
|
*/
|
701 |
|
|
function setUp() {
|
702 |
|
|
parent::setUp();
|
703 |
|
|
|
704 |
|
|
// Create user.
|
705 |
|
|
$this->blocking_user = $this->drupalCreateUser(array('block IP addresses'));
|
706 |
|
|
$this->drupalLogin($this->blocking_user);
|
707 |
|
|
}
|
708 |
|
|
|
709 |
|
|
/**
|
710 |
|
|
* Test a variety of user input to confirm correct validation and saving of data.
|
711 |
|
|
*/
|
712 |
|
|
function testIPAddressValidation() {
|
713 |
|
|
$this->drupalGet('admin/config/people/ip-blocking');
|
714 |
|
|
|
715 |
|
|
// Block a valid IP address.
|
716 |
|
|
$edit = array();
|
717 |
|
|
$edit['ip'] = '192.168.1.1';
|
718 |
|
|
$this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
|
719 |
|
|
$ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $edit['ip']))->fetchField();
|
720 |
|
|
$this->assertTrue($ip, t('IP address found in database.'));
|
721 |
|
|
$this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $edit['ip'])), t('IP address was blocked.'));
|
722 |
|
|
|
723 |
|
|
// Try to block an IP address that's already blocked.
|
724 |
|
|
$edit = array();
|
725 |
|
|
$edit['ip'] = '192.168.1.1';
|
726 |
|
|
$this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
|
727 |
|
|
$this->assertText(t('This IP address is already blocked.'));
|
728 |
|
|
|
729 |
|
|
// Try to block a reserved IP address.
|
730 |
|
|
$edit = array();
|
731 |
|
|
$edit['ip'] = '255.255.255.255';
|
732 |
|
|
$this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
|
733 |
|
|
$this->assertText(t('Enter a valid IP address.'));
|
734 |
|
|
|
735 |
|
|
// Try to block a reserved IP address.
|
736 |
|
|
$edit = array();
|
737 |
|
|
$edit['ip'] = 'test.example.com';
|
738 |
|
|
$this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
|
739 |
|
|
$this->assertText(t('Enter a valid IP address.'));
|
740 |
|
|
|
741 |
|
|
// Submit an empty form.
|
742 |
|
|
$edit = array();
|
743 |
|
|
$edit['ip'] = '';
|
744 |
|
|
$this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
|
745 |
|
|
$this->assertText(t('Enter a valid IP address.'));
|
746 |
|
|
|
747 |
|
|
// Pass an IP address as a URL parameter and submit it.
|
748 |
|
|
$submit_ip = '1.2.3.4';
|
749 |
|
|
$this->drupalPost('admin/config/people/ip-blocking/' . $submit_ip, NULL, t('Add'));
|
750 |
|
|
$ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $submit_ip))->fetchField();
|
751 |
|
|
$this->assertTrue($ip, t('IP address found in database'));
|
752 |
|
|
$this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $submit_ip)), t('IP address was blocked.'));
|
753 |
|
|
|
754 |
|
|
// Submit your own IP address. This fails, although it works when testing manually.
|
755 |
|
|
// TODO: on some systems this test fails due to a bug or inconsistency in cURL.
|
756 |
|
|
// $edit = array();
|
757 |
|
|
// $edit['ip'] = ip_address();
|
758 |
|
|
// $this->drupalPost('admin/config/people/ip-blocking', $edit, t('Save'));
|
759 |
|
|
// $this->assertText(t('You may not block your own IP address.'));
|
760 |
|
|
}
|
761 |
|
|
}
|
762 |
|
|
|
763 |
|
|
class CronRunTestCase extends DrupalWebTestCase {
|
764 |
|
|
/**
|
765 |
|
|
* Implement getInfo().
|
766 |
|
|
*/
|
767 |
|
|
public static function getInfo() {
|
768 |
|
|
return array(
|
769 |
|
|
'name' => 'Cron run',
|
770 |
|
|
'description' => 'Test cron run.',
|
771 |
|
|
'group' => 'System'
|
772 |
|
|
);
|
773 |
|
|
}
|
774 |
|
|
|
775 |
|
|
function setUp() {
|
776 |
|
|
parent::setUp(array('common_test', 'common_test_cron_helper'));
|
777 |
|
|
}
|
778 |
|
|
|
779 |
|
|
/**
|
780 |
|
|
* Test cron runs.
|
781 |
|
|
*/
|
782 |
|
|
function testCronRun() {
|
783 |
|
|
global $base_url;
|
784 |
|
|
|
785 |
|
|
// Run cron anonymously without any cron key.
|
786 |
|
|
$this->drupalGet($base_url . '/cron.php', array('external' => TRUE));
|
787 |
|
|
$this->assertResponse(403);
|
788 |
|
|
|
789 |
|
|
// Run cron anonymously with a random cron key.
|
790 |
|
|
$key = $this->randomName(16);
|
791 |
|
|
$this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
|
792 |
|
|
$this->assertResponse(403);
|
793 |
|
|
|
794 |
|
|
// Run cron anonymously with the valid cron key.
|
795 |
|
|
$key = variable_get('cron_key', 'drupal');
|
796 |
|
|
$this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
|
797 |
|
|
$this->assertResponse(200);
|
798 |
|
|
}
|
799 |
|
|
|
800 |
|
|
/**
|
801 |
|
|
* Ensure that the automatic cron run feature is working.
|
802 |
|
|
*
|
803 |
|
|
* In these tests we do not use REQUEST_TIME to track start time, because we
|
804 |
|
|
* need the exact time when cron is triggered.
|
805 |
|
|
*/
|
806 |
|
|
function testAutomaticCron() {
|
807 |
|
|
// Ensure cron does not run when the cron threshold is enabled and was
|
808 |
|
|
// not passed.
|
809 |
|
|
$cron_last = time();
|
810 |
|
|
$cron_safe_threshold = 100;
|
811 |
|
|
variable_set('cron_last', $cron_last);
|
812 |
|
|
variable_set('cron_safe_threshold', $cron_safe_threshold);
|
813 |
|
|
$this->drupalGet('');
|
814 |
|
|
$this->assertTrue($cron_last == variable_get('cron_last', NULL), 'Cron does not run when the cron threshold is not passed.');
|
815 |
|
|
|
816 |
|
|
// Test if cron runs when the cron threshold was passed.
|
817 |
|
|
$cron_last = time() - 200;
|
818 |
|
|
variable_set('cron_last', $cron_last);
|
819 |
|
|
$this->drupalGet('');
|
820 |
|
|
sleep(1);
|
821 |
|
|
$this->assertTrue($cron_last < variable_get('cron_last', NULL), 'Cron runs when the cron threshold is passed.');
|
822 |
|
|
|
823 |
|
|
// Disable the cron threshold through the interface.
|
824 |
|
|
$admin_user = $this->drupalCreateUser(array('administer site configuration'));
|
825 |
|
|
$this->drupalLogin($admin_user);
|
826 |
|
|
$this->drupalPost('admin/config/system/cron', array('cron_safe_threshold' => 0), t('Save configuration'));
|
827 |
|
|
$this->assertText(t('The configuration options have been saved.'));
|
828 |
|
|
$this->drupalLogout();
|
829 |
|
|
|
830 |
|
|
// Test if cron does not run when the cron threshold is disabled.
|
831 |
|
|
$cron_last = time() - 200;
|
832 |
|
|
variable_set('cron_last', $cron_last);
|
833 |
|
|
$this->drupalGet('');
|
834 |
|
|
$this->assertTrue($cron_last == variable_get('cron_last', NULL), 'Cron does not run when the cron threshold is disabled.');
|
835 |
|
|
}
|
836 |
|
|
|
837 |
|
|
/**
|
838 |
|
|
* Ensure that temporary files are removed.
|
839 |
|
|
*
|
840 |
|
|
* Create files for all the possible combinations of age and status. We are
|
841 |
|
|
* using UPDATE statements rather than file_save() because it would set the
|
842 |
|
|
* timestamp.
|
843 |
|
|
*/
|
844 |
|
|
function testTempFileCleanup() {
|
845 |
|
|
// Temporary file that is older than DRUPAL_MAXIMUM_TEMP_FILE_AGE.
|
846 |
|
|
$temp_old = file_save_data('');
|
847 |
|
|
db_update('file_managed')
|
848 |
|
|
->fields(array(
|
849 |
|
|
'status' => 0,
|
850 |
|
|
'timestamp' => 1,
|
851 |
|
|
))
|
852 |
|
|
->condition('fid', $temp_old->fid)
|
853 |
|
|
->execute();
|
854 |
|
|
$this->assertTrue(file_exists($temp_old->uri), 'Old temp file was created correctly.');
|
855 |
|
|
|
856 |
|
|
// Temporary file that is less than DRUPAL_MAXIMUM_TEMP_FILE_AGE.
|
857 |
|
|
$temp_new = file_save_data('');
|
858 |
|
|
db_update('file_managed')
|
859 |
|
|
->fields(array('status' => 0))
|
860 |
|
|
->condition('fid', $temp_new->fid)
|
861 |
|
|
->execute();
|
862 |
|
|
$this->assertTrue(file_exists($temp_new->uri), 'New temp file was created correctly.');
|
863 |
|
|
|
864 |
|
|
// Permanent file that is older than DRUPAL_MAXIMUM_TEMP_FILE_AGE.
|
865 |
|
|
$perm_old = file_save_data('');
|
866 |
|
|
db_update('file_managed')
|
867 |
|
|
->fields(array('timestamp' => 1))
|
868 |
|
|
->condition('fid', $temp_old->fid)
|
869 |
|
|
->execute();
|
870 |
|
|
$this->assertTrue(file_exists($perm_old->uri), 'Old permanent file was created correctly.');
|
871 |
|
|
|
872 |
|
|
// Permanent file that is newer than DRUPAL_MAXIMUM_TEMP_FILE_AGE.
|
873 |
|
|
$perm_new = file_save_data('');
|
874 |
|
|
$this->assertTrue(file_exists($perm_new->uri), 'New permanent file was created correctly.');
|
875 |
|
|
|
876 |
|
|
// Run cron and then ensure that only the old, temp file was deleted.
|
877 |
|
|
$this->cronRun();
|
878 |
|
|
$this->assertFalse(file_exists($temp_old->uri), 'Old temp file was correctly removed.');
|
879 |
|
|
$this->assertTrue(file_exists($temp_new->uri), 'New temp file was correctly ignored.');
|
880 |
|
|
$this->assertTrue(file_exists($perm_old->uri), 'Old permanent file was correctly ignored.');
|
881 |
|
|
$this->assertTrue(file_exists($perm_new->uri), 'New permanent file was correctly ignored.');
|
882 |
|
|
}
|
883 |
|
|
|
884 |
|
|
/**
|
885 |
|
|
* Make sure exceptions thrown on hook_cron() don't affect other modules.
|
886 |
|
|
*/
|
887 |
|
|
function testCronExceptions() {
|
888 |
|
|
variable_del('common_test_cron');
|
889 |
|
|
// The common_test module throws an exception. If it isn't caught, the tests
|
890 |
|
|
// won't finish successfully.
|
891 |
|
|
// The common_test_cron_helper module sets the 'common_test_cron' variable.
|
892 |
|
|
$this->cronRun();
|
893 |
|
|
$result = variable_get('common_test_cron');
|
894 |
|
|
$this->assertEqual($result, 'success', 'Cron correctly handles exceptions thrown during hook_cron() invocations.');
|
895 |
|
|
}
|
896 |
|
|
}
|
897 |
|
|
|
898 |
4444412d
|
Julien Enselme
|
/**
|
899 |
|
|
* Test execution of the cron queue.
|
900 |
|
|
*/
|
901 |
|
|
class CronQueueTestCase extends DrupalWebTestCase {
|
902 |
|
|
/**
|
903 |
|
|
* Implement getInfo().
|
904 |
|
|
*/
|
905 |
|
|
public static function getInfo() {
|
906 |
|
|
return array(
|
907 |
|
|
'name' => 'Cron queue functionality',
|
908 |
|
|
'description' => 'Tests the cron queue runner.',
|
909 |
|
|
'group' => 'System'
|
910 |
|
|
);
|
911 |
|
|
}
|
912 |
|
|
|
913 |
|
|
function setUp() {
|
914 |
|
|
parent::setUp(array('common_test', 'common_test_cron_helper'));
|
915 |
|
|
}
|
916 |
|
|
|
917 |
|
|
/**
|
918 |
|
|
* Tests that exceptions thrown by workers are handled properly.
|
919 |
|
|
*/
|
920 |
|
|
function testExceptions() {
|
921 |
|
|
$queue = DrupalQueue::get('cron_queue_test_exception');
|
922 |
|
|
|
923 |
|
|
// Enqueue an item for processing.
|
924 |
|
|
$queue->createItem(array($this->randomName() => $this->randomName()));
|
925 |
|
|
|
926 |
|
|
// Run cron; the worker for this queue should throw an exception and handle
|
927 |
|
|
// it.
|
928 |
|
|
$this->cronRun();
|
929 |
|
|
|
930 |
|
|
// The item should be left in the queue.
|
931 |
|
|
$this->assertEqual($queue->numberOfItems(), 1, 'Failing item still in the queue after throwing an exception.');
|
932 |
|
|
}
|
933 |
|
|
|
934 |
|
|
}
|
935 |
|
|
|
936 |
85ad3d82
|
Assos Assos
|
class AdminMetaTagTestCase extends DrupalWebTestCase {
|
937 |
|
|
/**
|
938 |
|
|
* Implement getInfo().
|
939 |
|
|
*/
|
940 |
|
|
public static function getInfo() {
|
941 |
|
|
return array(
|
942 |
|
|
'name' => 'Fingerprinting meta tag',
|
943 |
|
|
'description' => 'Confirm that the fingerprinting meta tag appears as expected.',
|
944 |
|
|
'group' => 'System'
|
945 |
|
|
);
|
946 |
|
|
}
|
947 |
|
|
|
948 |
|
|
/**
|
949 |
|
|
* Verify that the meta tag HTML is generated correctly.
|
950 |
|
|
*/
|
951 |
|
|
public function testMetaTag() {
|
952 |
|
|
list($version, ) = explode('.', VERSION);
|
953 |
|
|
$string = '<meta name="Generator" content="Drupal ' . $version . ' (http://drupal.org)" />';
|
954 |
|
|
$this->drupalGet('node');
|
955 |
|
|
$this->assertRaw($string, 'Fingerprinting meta tag generated correctly.', 'System');
|
956 |
|
|
}
|
957 |
|
|
}
|
958 |
|
|
|
959 |
|
|
/**
|
960 |
|
|
* Tests custom access denied functionality.
|
961 |
|
|
*/
|
962 |
|
|
class AccessDeniedTestCase extends DrupalWebTestCase {
|
963 |
|
|
protected $admin_user;
|
964 |
|
|
|
965 |
|
|
public static function getInfo() {
|
966 |
|
|
return array(
|
967 |
|
|
'name' => '403 functionality',
|
968 |
|
|
'description' => 'Tests page access denied functionality, including custom 403 pages.',
|
969 |
|
|
'group' => 'System'
|
970 |
|
|
);
|
971 |
|
|
}
|
972 |
|
|
|
973 |
|
|
function setUp() {
|
974 |
|
|
parent::setUp();
|
975 |
|
|
|
976 |
|
|
// Create an administrative user.
|
977 |
|
|
$this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer site configuration', 'administer blocks'));
|
978 |
|
|
}
|
979 |
|
|
|
980 |
|
|
function testAccessDenied() {
|
981 |
|
|
$this->drupalGet('admin');
|
982 |
|
|
$this->assertText(t('Access denied'), 'Found the default 403 page');
|
983 |
|
|
$this->assertResponse(403);
|
984 |
|
|
|
985 |
|
|
$this->drupalLogin($this->admin_user);
|
986 |
|
|
$edit = array(
|
987 |
|
|
'title' => $this->randomName(10),
|
988 |
|
|
'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(100)))),
|
989 |
|
|
);
|
990 |
|
|
$node = $this->drupalCreateNode($edit);
|
991 |
|
|
|
992 |
|
|
// Use a custom 403 page.
|
993 |
|
|
$this->drupalPost('admin/config/system/site-information', array('site_403' => 'node/' . $node->nid), t('Save configuration'));
|
994 |
|
|
|
995 |
|
|
$this->drupalLogout();
|
996 |
|
|
$this->drupalGet('admin');
|
997 |
|
|
$this->assertText($node->title, 'Found the custom 403 page');
|
998 |
|
|
|
999 |
|
|
// Logout and check that the user login block is shown on custom 403 pages.
|
1000 |
|
|
$this->drupalLogout();
|
1001 |
|
|
|
1002 |
|
|
$this->drupalGet('admin');
|
1003 |
|
|
$this->assertText($node->title, 'Found the custom 403 page');
|
1004 |
|
|
$this->assertText(t('User login'), 'Blocks are shown on the custom 403 page');
|
1005 |
|
|
|
1006 |
|
|
// Log back in and remove the custom 403 page.
|
1007 |
|
|
$this->drupalLogin($this->admin_user);
|
1008 |
|
|
$this->drupalPost('admin/config/system/site-information', array('site_403' => ''), t('Save configuration'));
|
1009 |
|
|
|
1010 |
|
|
// Logout and check that the user login block is shown on default 403 pages.
|
1011 |
|
|
$this->drupalLogout();
|
1012 |
|
|
|
1013 |
|
|
$this->drupalGet('admin');
|
1014 |
|
|
$this->assertText(t('Access denied'), 'Found the default 403 page');
|
1015 |
|
|
$this->assertResponse(403);
|
1016 |
|
|
$this->assertText(t('User login'), 'Blocks are shown on the default 403 page');
|
1017 |
|
|
|
1018 |
|
|
// Log back in, set the custom 403 page to /user and remove the block
|
1019 |
|
|
$this->drupalLogin($this->admin_user);
|
1020 |
|
|
variable_set('site_403', 'user');
|
1021 |
|
|
$this->drupalPost('admin/structure/block', array('blocks[user_login][region]' => '-1'), t('Save blocks'));
|
1022 |
|
|
|
1023 |
|
|
// Check that we can log in from the 403 page.
|
1024 |
|
|
$this->drupalLogout();
|
1025 |
|
|
$edit = array(
|
1026 |
|
|
'name' => $this->admin_user->name,
|
1027 |
|
|
'pass' => $this->admin_user->pass_raw,
|
1028 |
|
|
);
|
1029 |
|
|
$this->drupalPost('admin/config/system/site-information', $edit, t('Log in'));
|
1030 |
|
|
|
1031 |
|
|
// Check that we're still on the same page.
|
1032 |
|
|
$this->assertText(t('Site information'));
|
1033 |
|
|
}
|
1034 |
|
|
}
|
1035 |
|
|
|
1036 |
|
|
class PageNotFoundTestCase extends DrupalWebTestCase {
|
1037 |
|
|
protected $admin_user;
|
1038 |
|
|
|
1039 |
|
|
/**
|
1040 |
|
|
* Implement getInfo().
|
1041 |
|
|
*/
|
1042 |
|
|
public static function getInfo() {
|
1043 |
|
|
return array(
|
1044 |
|
|
'name' => '404 functionality',
|
1045 |
|
|
'description' => "Tests page not found functionality, including custom 404 pages.",
|
1046 |
|
|
'group' => 'System'
|
1047 |
|
|
);
|
1048 |
|
|
}
|
1049 |
|
|
|
1050 |
|
|
/**
|
1051 |
|
|
* Implement setUp().
|
1052 |
|
|
*/
|
1053 |
|
|
function setUp() {
|
1054 |
|
|
parent::setUp();
|
1055 |
|
|
|
1056 |
|
|
// Create an administrative user.
|
1057 |
|
|
$this->admin_user = $this->drupalCreateUser(array('administer site configuration'));
|
1058 |
|
|
$this->drupalLogin($this->admin_user);
|
1059 |
|
|
}
|
1060 |
|
|
|
1061 |
|
|
function testPageNotFound() {
|
1062 |
|
|
$this->drupalGet($this->randomName(10));
|
1063 |
|
|
$this->assertText(t('Page not found'), 'Found the default 404 page');
|
1064 |
|
|
|
1065 |
|
|
$edit = array(
|
1066 |
|
|
'title' => $this->randomName(10),
|
1067 |
|
|
'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(100)))),
|
1068 |
|
|
);
|
1069 |
|
|
$node = $this->drupalCreateNode($edit);
|
1070 |
|
|
|
1071 |
|
|
// Use a custom 404 page.
|
1072 |
|
|
$this->drupalPost('admin/config/system/site-information', array('site_404' => 'node/' . $node->nid), t('Save configuration'));
|
1073 |
|
|
|
1074 |
|
|
$this->drupalGet($this->randomName(10));
|
1075 |
|
|
$this->assertText($node->title, 'Found the custom 404 page');
|
1076 |
|
|
}
|
1077 |
|
|
}
|
1078 |
|
|
|
1079 |
|
|
/**
|
1080 |
|
|
* Tests site maintenance functionality.
|
1081 |
|
|
*/
|
1082 |
|
|
class SiteMaintenanceTestCase extends DrupalWebTestCase {
|
1083 |
|
|
protected $admin_user;
|
1084 |
|
|
|
1085 |
|
|
public static function getInfo() {
|
1086 |
|
|
return array(
|
1087 |
|
|
'name' => 'Site maintenance mode functionality',
|
1088 |
|
|
'description' => 'Test access to site while in maintenance mode.',
|
1089 |
|
|
'group' => 'System',
|
1090 |
|
|
);
|
1091 |
|
|
}
|
1092 |
|
|
|
1093 |
|
|
function setUp() {
|
1094 |
|
|
parent::setUp();
|
1095 |
|
|
|
1096 |
|
|
// Create a user allowed to access site in maintenance mode.
|
1097 |
|
|
$this->user = $this->drupalCreateUser(array('access site in maintenance mode'));
|
1098 |
|
|
// Create an administrative user.
|
1099 |
|
|
$this->admin_user = $this->drupalCreateUser(array('administer site configuration', 'access site in maintenance mode'));
|
1100 |
|
|
$this->drupalLogin($this->admin_user);
|
1101 |
|
|
}
|
1102 |
|
|
|
1103 |
|
|
/**
|
1104 |
|
|
* Verify site maintenance mode functionality.
|
1105 |
|
|
*/
|
1106 |
|
|
function testSiteMaintenance() {
|
1107 |
|
|
// Turn on maintenance mode.
|
1108 |
|
|
$edit = array(
|
1109 |
|
|
'maintenance_mode' => 1,
|
1110 |
|
|
);
|
1111 |
|
|
$this->drupalPost('admin/config/development/maintenance', $edit, t('Save configuration'));
|
1112 |
|
|
|
1113 |
|
|
$admin_message = t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance')));
|
1114 |
|
|
$user_message = t('Operating in maintenance mode.');
|
1115 |
|
|
$offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')));
|
1116 |
|
|
|
1117 |
|
|
$this->drupalGet('');
|
1118 |
|
|
$this->assertRaw($admin_message, 'Found the site maintenance mode message.');
|
1119 |
|
|
|
1120 |
|
|
// Logout and verify that offline message is displayed.
|
1121 |
|
|
$this->drupalLogout();
|
1122 |
|
|
$this->drupalGet('');
|
1123 |
|
|
$this->assertText($offline_message);
|
1124 |
|
|
$this->drupalGet('node');
|
1125 |
|
|
$this->assertText($offline_message);
|
1126 |
|
|
$this->drupalGet('user/register');
|
1127 |
|
|
$this->assertText($offline_message);
|
1128 |
|
|
|
1129 |
|
|
// Verify that user is able to log in.
|
1130 |
|
|
$this->drupalGet('user');
|
1131 |
|
|
$this->assertNoText($offline_message);
|
1132 |
|
|
$this->drupalGet('user/login');
|
1133 |
|
|
$this->assertNoText($offline_message);
|
1134 |
|
|
|
1135 |
|
|
// Log in user and verify that maintenance mode message is displayed
|
1136 |
|
|
// directly after login.
|
1137 |
|
|
$edit = array(
|
1138 |
|
|
'name' => $this->user->name,
|
1139 |
|
|
'pass' => $this->user->pass_raw,
|
1140 |
|
|
);
|
1141 |
|
|
$this->drupalPost(NULL, $edit, t('Log in'));
|
1142 |
|
|
$this->assertText($user_message);
|
1143 |
|
|
|
1144 |
|
|
// Log in administrative user and configure a custom site offline message.
|
1145 |
|
|
$this->drupalLogout();
|
1146 |
|
|
$this->drupalLogin($this->admin_user);
|
1147 |
|
|
$this->drupalGet('admin/config/development/maintenance');
|
1148 |
|
|
$this->assertNoRaw($admin_message, 'Site maintenance mode message not displayed.');
|
1149 |
|
|
|
1150 |
|
|
$offline_message = 'Sorry, not online.';
|
1151 |
|
|
$edit = array(
|
1152 |
|
|
'maintenance_mode_message' => $offline_message,
|
1153 |
|
|
);
|
1154 |
|
|
$this->drupalPost(NULL, $edit, t('Save configuration'));
|
1155 |
|
|
|
1156 |
|
|
// Logout and verify that custom site offline message is displayed.
|
1157 |
|
|
$this->drupalLogout();
|
1158 |
|
|
$this->drupalGet('');
|
1159 |
|
|
$this->assertRaw($offline_message, 'Found the site offline message.');
|
1160 |
|
|
|
1161 |
|
|
// Verify that custom site offline message is not displayed on user/password.
|
1162 |
|
|
$this->drupalGet('user/password');
|
1163 |
|
|
$this->assertText(t('Username or e-mail address'), 'Anonymous users can access user/password');
|
1164 |
|
|
|
1165 |
|
|
// Submit password reset form.
|
1166 |
|
|
$edit = array(
|
1167 |
|
|
'name' => $this->user->name,
|
1168 |
|
|
);
|
1169 |
|
|
$this->drupalPost('user/password', $edit, t('E-mail new password'));
|
1170 |
|
|
$mails = $this->drupalGetMails();
|
1171 |
|
|
$start = strpos($mails[0]['body'], 'user/reset/'. $this->user->uid);
|
1172 |
|
|
$path = substr($mails[0]['body'], $start, 66 + strlen($this->user->uid));
|
1173 |
|
|
|
1174 |
|
|
// Log in with temporary login link.
|
1175 |
|
|
$this->drupalPost($path, array(), t('Log in'));
|
1176 |
|
|
$this->assertText($user_message);
|
1177 |
|
|
}
|
1178 |
|
|
}
|
1179 |
|
|
|
1180 |
|
|
/**
|
1181 |
|
|
* Tests generic date and time handling capabilities of Drupal.
|
1182 |
|
|
*/
|
1183 |
|
|
class DateTimeFunctionalTest extends DrupalWebTestCase {
|
1184 |
|
|
public static function getInfo() {
|
1185 |
|
|
return array(
|
1186 |
|
|
'name' => 'Date and time',
|
1187 |
|
|
'description' => 'Configure date and time settings. Test date formatting and time zone handling, including daylight saving time.',
|
1188 |
|
|
'group' => 'System',
|
1189 |
|
|
);
|
1190 |
|
|
}
|
1191 |
|
|
|
1192 |
|
|
function setUp() {
|
1193 |
|
|
parent::setUp(array('locale'));
|
1194 |
|
|
|
1195 |
|
|
// Create admin user and log in admin user.
|
1196 |
|
|
$this->admin_user = $this->drupalCreateUser(array('administer site configuration'));
|
1197 |
|
|
$this->drupalLogin($this->admin_user);
|
1198 |
|
|
}
|
1199 |
|
|
|
1200 |
|
|
|
1201 |
|
|
/**
|
1202 |
|
|
* Test time zones and DST handling.
|
1203 |
|
|
*/
|
1204 |
|
|
function testTimeZoneHandling() {
|
1205 |
|
|
// Setup date/time settings for Honolulu time.
|
1206 |
|
|
variable_set('date_default_timezone', 'Pacific/Honolulu');
|
1207 |
|
|
variable_set('configurable_timezones', 0);
|
1208 |
|
|
variable_set('date_format_medium', 'Y-m-d H:i:s O');
|
1209 |
|
|
|
1210 |
|
|
// Create some nodes with different authored-on dates.
|
1211 |
|
|
$date1 = '2007-01-31 21:00:00 -1000';
|
1212 |
|
|
$date2 = '2007-07-31 21:00:00 -1000';
|
1213 |
|
|
$node1 = $this->drupalCreateNode(array('created' => strtotime($date1), 'type' => 'article'));
|
1214 |
|
|
$node2 = $this->drupalCreateNode(array('created' => strtotime($date2), 'type' => 'article'));
|
1215 |
|
|
|
1216 |
|
|
// Confirm date format and time zone.
|
1217 |
|
|
$this->drupalGet("node/$node1->nid");
|
1218 |
|
|
$this->assertText('2007-01-31 21:00:00 -1000', 'Date should be identical, with GMT offset of -10 hours.');
|
1219 |
|
|
$this->drupalGet("node/$node2->nid");
|
1220 |
|
|
$this->assertText('2007-07-31 21:00:00 -1000', 'Date should be identical, with GMT offset of -10 hours.');
|
1221 |
|
|
|
1222 |
|
|
// Set time zone to Los Angeles time.
|
1223 |
|
|
variable_set('date_default_timezone', 'America/Los_Angeles');
|
1224 |
|
|
|
1225 |
|
|
// Confirm date format and time zone.
|
1226 |
|
|
$this->drupalGet("node/$node1->nid");
|
1227 |
|
|
$this->assertText('2007-01-31 23:00:00 -0800', 'Date should be two hours ahead, with GMT offset of -8 hours.');
|
1228 |
|
|
$this->drupalGet("node/$node2->nid");
|
1229 |
|
|
$this->assertText('2007-08-01 00:00:00 -0700', 'Date should be three hours ahead, with GMT offset of -7 hours.');
|
1230 |
|
|
}
|
1231 |
|
|
|
1232 |
|
|
/**
|
1233 |
|
|
* Test date type configuration.
|
1234 |
|
|
*/
|
1235 |
|
|
function testDateTypeConfiguration() {
|
1236 |
|
|
// Confirm system date types appear.
|
1237 |
|
|
$this->drupalGet('admin/config/regional/date-time');
|
1238 |
|
|
$this->assertText(t('Medium'), 'System date types appear in date type list.');
|
1239 |
|
|
$this->assertNoRaw('href="/admin/config/regional/date-time/types/medium/delete"', 'No delete link appear for system date types.');
|
1240 |
|
|
|
1241 |
|
|
// Add custom date type.
|
1242 |
|
|
$this->clickLink(t('Add date type'));
|
1243 |
|
|
$date_type = strtolower($this->randomName(8));
|
1244 |
|
|
$machine_name = 'machine_' . $date_type;
|
1245 |
|
|
$date_format = 'd.m.Y - H:i';
|
1246 |
|
|
$edit = array(
|
1247 |
|
|
'date_type' => $date_type,
|
1248 |
|
|
'machine_name' => $machine_name,
|
1249 |
|
|
'date_format' => $date_format,
|
1250 |
|
|
);
|
1251 |
|
|
$this->drupalPost('admin/config/regional/date-time/types/add', $edit, t('Add date type'));
|
1252 |
|
|
$this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), 'Correct page redirection.');
|
1253 |
|
|
$this->assertText(t('New date type added successfully.'), 'Date type added confirmation message appears.');
|
1254 |
|
|
$this->assertText($date_type, 'Custom date type appears in the date type list.');
|
1255 |
|
|
$this->assertText(t('delete'), 'Delete link for custom date type appears.');
|
1256 |
|
|
|
1257 |
|
|
// Delete custom date type.
|
1258 |
|
|
$this->clickLink(t('delete'));
|
1259 |
|
|
$this->drupalPost('admin/config/regional/date-time/types/' . $machine_name . '/delete', array(), t('Remove'));
|
1260 |
|
|
$this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), 'Correct page redirection.');
|
1261 |
|
|
$this->assertText(t('Removed date type ' . $date_type), 'Custom date type removed.');
|
1262 |
|
|
}
|
1263 |
|
|
|
1264 |
|
|
/**
|
1265 |
|
|
* Test date format configuration.
|
1266 |
|
|
*/
|
1267 |
|
|
function testDateFormatConfiguration() {
|
1268 |
|
|
// Confirm 'no custom date formats available' message appears.
|
1269 |
|
|
$this->drupalGet('admin/config/regional/date-time/formats');
|
1270 |
|
|
$this->assertText(t('No custom date formats available.'), 'No custom date formats message appears.');
|
1271 |
|
|
|
1272 |
|
|
// Add custom date format.
|
1273 |
|
|
$this->clickLink(t('Add format'));
|
1274 |
|
|
$edit = array(
|
1275 |
|
|
'date_format' => 'Y',
|
1276 |
|
|
);
|
1277 |
|
|
$this->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
1278 |
|
|
$this->assertEqual($this->getUrl(), url('admin/config/regional/date-time/formats', array('absolute' => TRUE)), 'Correct page redirection.');
|
1279 |
|
|
$this->assertNoText(t('No custom date formats available.'), 'No custom date formats message does not appear.');
|
1280 |
|
|
$this->assertText(t('Custom date format added.'), 'Custom date format added.');
|
1281 |
|
|
|
1282 |
|
|
// Ensure custom date format appears in date type configuration options.
|
1283 |
|
|
$this->drupalGet('admin/config/regional/date-time');
|
1284 |
|
|
$this->assertRaw('<option value="Y">', 'Custom date format appears in options.');
|
1285 |
|
|
|
1286 |
|
|
// Edit custom date format.
|
1287 |
|
|
$this->drupalGet('admin/config/regional/date-time/formats');
|
1288 |
|
|
$this->clickLink(t('edit'));
|
1289 |
|
|
$edit = array(
|
1290 |
|
|
'date_format' => 'Y m',
|
1291 |
|
|
);
|
1292 |
|
|
$this->drupalPost($this->getUrl(), $edit, t('Save format'));
|
1293 |
|
|
$this->assertEqual($this->getUrl(), url('admin/config/regional/date-time/formats', array('absolute' => TRUE)), 'Correct page redirection.');
|
1294 |
|
|
$this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
|
1295 |
|
|
|
1296 |
|
|
// Delete custom date format.
|
1297 |
|
|
$this->clickLink(t('delete'));
|
1298 |
|
|
$this->drupalPost($this->getUrl(), array(), t('Remove'));
|
1299 |
|
|
$this->assertEqual($this->getUrl(), url('admin/config/regional/date-time/formats', array('absolute' => TRUE)), 'Correct page redirection.');
|
1300 |
|
|
$this->assertText(t('Removed date format'), 'Custom date format removed successfully.');
|
1301 |
|
|
}
|
1302 |
|
|
|
1303 |
|
|
/**
|
1304 |
|
|
* Test if the date formats are stored properly.
|
1305 |
|
|
*/
|
1306 |
|
|
function testDateFormatStorage() {
|
1307 |
|
|
$date_format = array(
|
1308 |
|
|
'type' => 'short',
|
1309 |
|
|
'format' => 'dmYHis',
|
1310 |
|
|
'locked' => 0,
|
1311 |
|
|
'is_new' => 1,
|
1312 |
|
|
);
|
1313 |
|
|
system_date_format_save($date_format);
|
1314 |
|
|
|
1315 |
|
|
$format = db_select('date_formats', 'df')
|
1316 |
|
|
->fields('df', array('format'))
|
1317 |
|
|
->condition('type', 'short')
|
1318 |
|
|
->condition('format', 'dmYHis')
|
1319 |
|
|
->execute()
|
1320 |
|
|
->fetchField();
|
1321 |
|
|
$this->verbose($format);
|
1322 |
|
|
$this->assertEqual('dmYHis', $format, 'Unlocalized date format resides in general table.');
|
1323 |
|
|
|
1324 |
|
|
$format = db_select('date_format_locale', 'dfl')
|
1325 |
|
|
->fields('dfl', array('format'))
|
1326 |
|
|
->condition('type', 'short')
|
1327 |
|
|
->condition('format', 'dmYHis')
|
1328 |
|
|
->execute()
|
1329 |
|
|
->fetchField();
|
1330 |
|
|
$this->assertFalse($format, 'Unlocalized date format resides not in localized table.');
|
1331 |
|
|
|
1332 |
|
|
// Enable German language
|
1333 |
|
|
locale_add_language('de', NULL, NULL, LANGUAGE_LTR, '', '', TRUE, 'en');
|
1334 |
|
|
|
1335 |
|
|
$date_format = array(
|
1336 |
|
|
'type' => 'short',
|
1337 |
|
|
'format' => 'YMDHis',
|
1338 |
|
|
'locales' => array('de', 'tr'),
|
1339 |
|
|
'locked' => 0,
|
1340 |
|
|
'is_new' => 1,
|
1341 |
|
|
);
|
1342 |
|
|
system_date_format_save($date_format);
|
1343 |
|
|
|
1344 |
|
|
$format = db_select('date_format_locale', 'dfl')
|
1345 |
|
|
->fields('dfl', array('format'))
|
1346 |
|
|
->condition('type', 'short')
|
1347 |
|
|
->condition('format', 'YMDHis')
|
1348 |
|
|
->condition('language', 'de')
|
1349 |
|
|
->execute()
|
1350 |
|
|
->fetchField();
|
1351 |
|
|
$this->assertEqual('YMDHis', $format, 'Localized date format resides in localized table.');
|
1352 |
|
|
|
1353 |
|
|
$format = db_select('date_formats', 'df')
|
1354 |
|
|
->fields('df', array('format'))
|
1355 |
|
|
->condition('type', 'short')
|
1356 |
|
|
->condition('format', 'YMDHis')
|
1357 |
|
|
->execute()
|
1358 |
|
|
->fetchField();
|
1359 |
|
|
$this->assertEqual('YMDHis', $format, 'Localized date format resides in general table too.');
|
1360 |
|
|
|
1361 |
|
|
$format = db_select('date_format_locale', 'dfl')
|
1362 |
|
|
->fields('dfl', array('format'))
|
1363 |
|
|
->condition('type', 'short')
|
1364 |
|
|
->condition('format', 'YMDHis')
|
1365 |
|
|
->condition('language', 'tr')
|
1366 |
|
|
->execute()
|
1367 |
|
|
->fetchColumn();
|
1368 |
|
|
$this->assertFalse($format, 'Localized date format for disabled language is ignored.');
|
1369 |
|
|
}
|
1370 |
|
|
}
|
1371 |
|
|
|
1372 |
|
|
class PageTitleFiltering extends DrupalWebTestCase {
|
1373 |
|
|
protected $content_user;
|
1374 |
|
|
protected $saved_title;
|
1375 |
|
|
|
1376 |
|
|
/**
|
1377 |
|
|
* Implement getInfo().
|
1378 |
|
|
*/
|
1379 |
|
|
public static function getInfo() {
|
1380 |
|
|
return array(
|
1381 |
|
|
'name' => 'HTML in page titles',
|
1382 |
|
|
'description' => 'Tests correct handling or conversion by drupal_set_title() and drupal_get_title() and checks the correct escaping of site name and slogan.',
|
1383 |
|
|
'group' => 'System'
|
1384 |
|
|
);
|
1385 |
|
|
}
|
1386 |
|
|
|
1387 |
|
|
/**
|
1388 |
|
|
* Implement setUp().
|
1389 |
|
|
*/
|
1390 |
|
|
function setUp() {
|
1391 |
|
|
parent::setUp();
|
1392 |
|
|
|
1393 |
|
|
$this->content_user = $this->drupalCreateUser(array('create page content', 'access content', 'administer themes', 'administer site configuration'));
|
1394 |
|
|
$this->drupalLogin($this->content_user);
|
1395 |
|
|
$this->saved_title = drupal_get_title();
|
1396 |
|
|
}
|
1397 |
|
|
|
1398 |
|
|
/**
|
1399 |
|
|
* Reset page title.
|
1400 |
|
|
*/
|
1401 |
|
|
function tearDown() {
|
1402 |
|
|
// Restore the page title.
|
1403 |
|
|
drupal_set_title($this->saved_title, PASS_THROUGH);
|
1404 |
|
|
|
1405 |
|
|
parent::tearDown();
|
1406 |
|
|
}
|
1407 |
|
|
|
1408 |
|
|
/**
|
1409 |
|
|
* Tests the handling of HTML by drupal_set_title() and drupal_get_title()
|
1410 |
|
|
*/
|
1411 |
|
|
function testTitleTags() {
|
1412 |
|
|
$title = "string with <em>HTML</em>";
|
1413 |
|
|
// drupal_set_title's $filter is CHECK_PLAIN by default, so the title should be
|
1414 |
|
|
// returned with check_plain().
|
1415 |
|
|
drupal_set_title($title, CHECK_PLAIN);
|
1416 |
|
|
$this->assertTrue(strpos(drupal_get_title(), '<em>') === FALSE, 'Tags in title converted to entities when $output is CHECK_PLAIN.');
|
1417 |
|
|
// drupal_set_title's $filter is passed as PASS_THROUGH, so the title should be
|
1418 |
|
|
// returned with HTML.
|
1419 |
|
|
drupal_set_title($title, PASS_THROUGH);
|
1420 |
|
|
$this->assertTrue(strpos(drupal_get_title(), '<em>') !== FALSE, 'Tags in title are not converted to entities when $output is PASS_THROUGH.');
|
1421 |
|
|
// Generate node content.
|
1422 |
|
|
$langcode = LANGUAGE_NONE;
|
1423 |
|
|
$edit = array(
|
1424 |
|
|
"title" => '!SimpleTest! ' . $title . $this->randomName(20),
|
1425 |
|
|
"body[$langcode][0][value]" => '!SimpleTest! test body' . $this->randomName(200),
|
1426 |
|
|
);
|
1427 |
|
|
// Create the node with HTML in the title.
|
1428 |
|
|
$this->drupalPost('node/add/page', $edit, t('Save'));
|
1429 |
|
|
|
1430 |
|
|
$node = $this->drupalGetNodeByTitle($edit["title"]);
|
1431 |
|
|
$this->assertNotNull($node, 'Node created and found in database');
|
1432 |
|
|
$this->drupalGet("node/" . $node->nid);
|
1433 |
|
|
$this->assertText(check_plain($edit["title"]), 'Check to make sure tags in the node title are converted.');
|
1434 |
|
|
}
|
1435 |
|
|
/**
|
1436 |
|
|
* Test if the title of the site is XSS proof.
|
1437 |
|
|
*/
|
1438 |
|
|
function testTitleXSS() {
|
1439 |
|
|
// Set some title with JavaScript and HTML chars to escape.
|
1440 |
|
|
$title = '</title><script type="text/javascript">alert("Title XSS!");</script> & < > " \' ';
|
1441 |
|
|
$title_filtered = check_plain($title);
|
1442 |
|
|
|
1443 |
|
|
$slogan = '<script type="text/javascript">alert("Slogan XSS!");</script>';
|
1444 |
|
|
$slogan_filtered = filter_xss_admin($slogan);
|
1445 |
|
|
|
1446 |
|
|
// Activate needed appearance settings.
|
1447 |
|
|
$edit = array(
|
1448 |
|
|
'toggle_name' => TRUE,
|
1449 |
|
|
'toggle_slogan' => TRUE,
|
1450 |
|
|
'toggle_main_menu' => TRUE,
|
1451 |
|
|
'toggle_secondary_menu' => TRUE,
|
1452 |
|
|
);
|
1453 |
|
|
$this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'));
|
1454 |
|
|
|
1455 |
|
|
// Set title and slogan.
|
1456 |
|
|
$edit = array(
|
1457 |
|
|
'site_name' => $title,
|
1458 |
|
|
'site_slogan' => $slogan,
|
1459 |
|
|
);
|
1460 |
|
|
$this->drupalPost('admin/config/system/site-information', $edit, t('Save configuration'));
|
1461 |
|
|
|
1462 |
|
|
// Load frontpage.
|
1463 |
|
|
$this->drupalGet('');
|
1464 |
|
|
|
1465 |
|
|
// Test the title.
|
1466 |
|
|
$this->assertNoRaw($title, 'Check for the unfiltered version of the title.');
|
1467 |
|
|
// Adding </title> so we do not test the escaped version from drupal_set_title().
|
1468 |
|
|
$this->assertRaw($title_filtered . '</title>', 'Check for the filtered version of the title.');
|
1469 |
|
|
|
1470 |
|
|
// Test the slogan.
|
1471 |
|
|
$this->assertNoRaw($slogan, 'Check for the unfiltered version of the slogan.');
|
1472 |
|
|
$this->assertRaw($slogan_filtered, 'Check for the filtered version of the slogan.');
|
1473 |
|
|
}
|
1474 |
|
|
}
|
1475 |
|
|
|
1476 |
|
|
/**
|
1477 |
|
|
* Test front page functionality and administration.
|
1478 |
|
|
*/
|
1479 |
|
|
class FrontPageTestCase extends DrupalWebTestCase {
|
1480 |
|
|
|
1481 |
|
|
public static function getInfo() {
|
1482 |
|
|
return array(
|
1483 |
|
|
'name' => 'Front page',
|
1484 |
|
|
'description' => 'Tests front page functionality and administration.',
|
1485 |
|
|
'group' => 'System',
|
1486 |
|
|
);
|
1487 |
|
|
}
|
1488 |
|
|
|
1489 |
|
|
function setUp() {
|
1490 |
|
|
parent::setUp('system_test');
|
1491 |
|
|
|
1492 |
|
|
// Create admin user, log in admin user, and create one node.
|
1493 |
|
|
$this->admin_user = $this->drupalCreateUser(array('access content', 'administer site configuration'));
|
1494 |
|
|
$this->drupalLogin($this->admin_user);
|
1495 |
|
|
$this->node_path = "node/" . $this->drupalCreateNode(array('promote' => 1))->nid;
|
1496 |
|
|
|
1497 |
|
|
// Enable front page logging in system_test.module.
|
1498 |
|
|
variable_set('front_page_output', 1);
|
1499 |
|
|
}
|
1500 |
|
|
|
1501 |
|
|
/**
|
1502 |
|
|
* Test front page functionality.
|
1503 |
|
|
*/
|
1504 |
|
|
function testDrupalIsFrontPage() {
|
1505 |
|
|
$this->drupalGet('');
|
1506 |
|
|
$this->assertText(t('On front page.'), 'Path is the front page.');
|
1507 |
|
|
$this->drupalGet('node');
|
1508 |
|
|
$this->assertText(t('On front page.'), 'Path is the front page.');
|
1509 |
|
|
$this->drupalGet($this->node_path);
|
1510 |
|
|
$this->assertNoText(t('On front page.'), 'Path is not the front page.');
|
1511 |
|
|
|
1512 |
|
|
// Change the front page to an invalid path.
|
1513 |
|
|
$edit = array('site_frontpage' => 'kittens');
|
1514 |
|
|
$this->drupalPost('admin/config/system/site-information', $edit, t('Save configuration'));
|
1515 |
|
|
$this->assertText(t("The path '@path' is either invalid or you do not have access to it.", array('@path' => $edit['site_frontpage'])));
|
1516 |
|
|
|
1517 |
|
|
// Change the front page to a valid path.
|
1518 |
|
|
$edit['site_frontpage'] = $this->node_path;
|
1519 |
|
|
$this->drupalPost('admin/config/system/site-information', $edit, t('Save configuration'));
|
1520 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'The front page path has been saved.');
|
1521 |
|
|
|
1522 |
|
|
$this->drupalGet('');
|
1523 |
|
|
$this->assertText(t('On front page.'), 'Path is the front page.');
|
1524 |
|
|
$this->drupalGet('node');
|
1525 |
|
|
$this->assertNoText(t('On front page.'), 'Path is not the front page.');
|
1526 |
|
|
$this->drupalGet($this->node_path);
|
1527 |
|
|
$this->assertText(t('On front page.'), 'Path is the front page.');
|
1528 |
|
|
}
|
1529 |
|
|
}
|
1530 |
|
|
|
1531 |
|
|
class SystemBlockTestCase extends DrupalWebTestCase {
|
1532 |
|
|
protected $profile = 'testing';
|
1533 |
|
|
|
1534 |
|
|
public static function getInfo() {
|
1535 |
|
|
return array(
|
1536 |
|
|
'name' => 'Block functionality',
|
1537 |
|
|
'description' => 'Configure and move powered-by block.',
|
1538 |
|
|
'group' => 'System',
|
1539 |
|
|
);
|
1540 |
|
|
}
|
1541 |
|
|
|
1542 |
|
|
function setUp() {
|
1543 |
|
|
parent::setUp('block');
|
1544 |
|
|
|
1545 |
|
|
// Create and login user
|
1546 |
|
|
$admin_user = $this->drupalCreateUser(array('administer blocks', 'access administration pages'));
|
1547 |
|
|
$this->drupalLogin($admin_user);
|
1548 |
|
|
}
|
1549 |
|
|
|
1550 |
|
|
/**
|
1551 |
|
|
* Test displaying and hiding the powered-by and help blocks.
|
1552 |
|
|
*/
|
1553 |
|
|
function testSystemBlocks() {
|
1554 |
|
|
// Set block title and some settings to confirm that the interface is available.
|
1555 |
|
|
$this->drupalPost('admin/structure/block/manage/system/powered-by/configure', array('title' => $this->randomName(8)), t('Save block'));
|
1556 |
|
|
$this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
|
1557 |
|
|
|
1558 |
|
|
// Set the powered-by block to the footer region.
|
1559 |
|
|
$edit = array();
|
1560 |
|
|
$edit['blocks[system_powered-by][region]'] = 'footer';
|
1561 |
|
|
$edit['blocks[system_main][region]'] = 'content';
|
1562 |
|
|
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
1563 |
|
|
$this->assertText(t('The block settings have been updated.'), t('Block successfully moved to footer region.'));
|
1564 |
|
|
|
1565 |
|
|
// Confirm that the block is being displayed.
|
1566 |
|
|
$this->drupalGet('node');
|
1567 |
|
|
$this->assertRaw('id="block-system-powered-by"', t('Block successfully being displayed on the page.'));
|
1568 |
|
|
|
1569 |
|
|
// Set the block to the disabled region.
|
1570 |
|
|
$edit = array();
|
1571 |
|
|
$edit['blocks[system_powered-by][region]'] = '-1';
|
1572 |
|
|
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
1573 |
|
|
|
1574 |
|
|
// Confirm that the block is hidden.
|
1575 |
|
|
$this->assertNoRaw('id="block-system-powered-by"', t('Block no longer appears on page.'));
|
1576 |
|
|
|
1577 |
|
|
// For convenience of developers, set the block to its default settings.
|
1578 |
|
|
$edit = array();
|
1579 |
|
|
$edit['blocks[system_powered-by][region]'] = 'footer';
|
1580 |
|
|
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
1581 |
|
|
$this->drupalPost('admin/structure/block/manage/system/powered-by/configure', array('title' => ''), t('Save block'));
|
1582 |
|
|
|
1583 |
|
|
// Set the help block to the help region.
|
1584 |
|
|
$edit = array();
|
1585 |
|
|
$edit['blocks[system_help][region]'] = 'help';
|
1586 |
|
|
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
1587 |
|
|
|
1588 |
|
|
// Test displaying the help block with block caching enabled.
|
1589 |
|
|
variable_set('block_cache', TRUE);
|
1590 |
|
|
$this->drupalGet('admin/structure/block/add');
|
1591 |
|
|
$this->assertRaw(t('Use this page to create a new custom block.'));
|
1592 |
|
|
$this->drupalGet('admin/index');
|
1593 |
|
|
$this->assertRaw(t('This page shows you all available administration tasks for each module.'));
|
1594 |
|
|
}
|
1595 |
|
|
}
|
1596 |
|
|
|
1597 |
|
|
/**
|
1598 |
|
|
* Test main content rendering fallback provided by system module.
|
1599 |
|
|
*/
|
1600 |
|
|
class SystemMainContentFallback extends DrupalWebTestCase {
|
1601 |
|
|
protected $admin_user;
|
1602 |
|
|
protected $web_user;
|
1603 |
|
|
|
1604 |
|
|
public static function getInfo() {
|
1605 |
|
|
return array(
|
1606 |
|
|
'name' => 'Main content rendering fallback',
|
1607 |
|
|
'description' => ' Test system module main content rendering fallback.',
|
1608 |
|
|
'group' => 'System',
|
1609 |
|
|
);
|
1610 |
|
|
}
|
1611 |
|
|
|
1612 |
|
|
function setUp() {
|
1613 |
|
|
parent::setUp('system_test');
|
1614 |
|
|
|
1615 |
|
|
// Create and login admin user.
|
1616 |
|
|
$this->admin_user = $this->drupalCreateUser(array(
|
1617 |
|
|
'access administration pages',
|
1618 |
|
|
'administer site configuration',
|
1619 |
|
|
'administer modules',
|
1620 |
|
|
'administer blocks',
|
1621 |
|
|
'administer nodes',
|
1622 |
|
|
));
|
1623 |
|
|
$this->drupalLogin($this->admin_user);
|
1624 |
|
|
|
1625 |
|
|
// Create a web user.
|
1626 |
|
|
$this->web_user = $this->drupalCreateUser(array('access user profiles', 'access content'));
|
1627 |
|
|
}
|
1628 |
|
|
|
1629 |
|
|
/**
|
1630 |
|
|
* Test availability of main content.
|
1631 |
|
|
*/
|
1632 |
|
|
function testMainContentFallback() {
|
1633 |
|
|
$edit = array();
|
1634 |
|
|
// Disable the dashboard module, which depends on the block module.
|
1635 |
|
|
$edit['modules[Core][dashboard][enable]'] = FALSE;
|
1636 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
1637 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
1638 |
|
|
// Disable the block module.
|
1639 |
|
|
$edit['modules[Core][block][enable]'] = FALSE;
|
1640 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
1641 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
1642 |
|
|
module_list(TRUE);
|
1643 |
|
|
$this->assertFalse(module_exists('block'), 'Block module disabled.');
|
1644 |
|
|
|
1645 |
|
|
// At this point, no region is filled and fallback should be triggered.
|
1646 |
|
|
$this->drupalGet('admin/config/system/site-information');
|
1647 |
|
|
$this->assertField('site_name', 'Admin interface still available.');
|
1648 |
|
|
|
1649 |
|
|
// Fallback should not trigger when another module is handling content.
|
1650 |
|
|
$this->drupalGet('system-test/main-content-handling');
|
1651 |
|
|
$this->assertRaw('id="system-test-content"', 'Content handled by another module');
|
1652 |
|
|
$this->assertText(t('Content to test main content fallback'), 'Main content still displayed.');
|
1653 |
|
|
|
1654 |
|
|
// Fallback should trigger when another module
|
1655 |
|
|
// indicates that it is not handling the content.
|
1656 |
|
|
$this->drupalGet('system-test/main-content-fallback');
|
1657 |
|
|
$this->assertText(t('Content to test main content fallback'), 'Main content fallback properly triggers.');
|
1658 |
|
|
|
1659 |
|
|
// Fallback should not trigger when another module is handling content.
|
1660 |
|
|
// Note that this test ensures that no duplicate
|
1661 |
|
|
// content gets created by the fallback.
|
1662 |
|
|
$this->drupalGet('system-test/main-content-duplication');
|
1663 |
|
|
$this->assertNoText(t('Content to test main content fallback'), 'Main content not duplicated.');
|
1664 |
|
|
|
1665 |
|
|
// Request a user* page and see if it is displayed.
|
1666 |
|
|
$this->drupalLogin($this->web_user);
|
1667 |
|
|
$this->drupalGet('user/' . $this->web_user->uid . '/edit');
|
1668 |
|
|
$this->assertField('mail', 'User interface still available.');
|
1669 |
|
|
|
1670 |
|
|
// Enable the block module again.
|
1671 |
|
|
$this->drupalLogin($this->admin_user);
|
1672 |
|
|
$edit = array();
|
1673 |
|
|
$edit['modules[Core][block][enable]'] = 'block';
|
1674 |
|
|
$this->drupalPost('admin/modules', $edit, t('Save configuration'));
|
1675 |
|
|
$this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
|
1676 |
|
|
module_list(TRUE);
|
1677 |
|
|
$this->assertTrue(module_exists('block'), 'Block module re-enabled.');
|
1678 |
|
|
}
|
1679 |
|
|
}
|
1680 |
|
|
|
1681 |
|
|
/**
|
1682 |
|
|
* Tests for the theme interface functionality.
|
1683 |
|
|
*/
|
1684 |
|
|
class SystemThemeFunctionalTest extends DrupalWebTestCase {
|
1685 |
|
|
public static function getInfo() {
|
1686 |
|
|
return array(
|
1687 |
|
|
'name' => 'Theme interface functionality',
|
1688 |
|
|
'description' => 'Tests the theme interface functionality by enabling and switching themes, and using an administration theme.',
|
1689 |
|
|
'group' => 'System',
|
1690 |
|
|
);
|
1691 |
|
|
}
|
1692 |
|
|
|
1693 |
|
|
function setUp() {
|
1694 |
|
|
parent::setUp();
|
1695 |
|
|
|
1696 |
|
|
$this->admin_user = $this->drupalCreateUser(array('access administration pages', 'view the administration theme', 'administer themes', 'bypass node access', 'administer blocks'));
|
1697 |
|
|
$this->drupalLogin($this->admin_user);
|
1698 |
|
|
$this->node = $this->drupalCreateNode();
|
1699 |
|
|
}
|
1700 |
|
|
|
1701 |
|
|
/**
|
1702 |
|
|
* Test the theme settings form.
|
1703 |
|
|
*/
|
1704 |
|
|
function testThemeSettings() {
|
1705 |
|
|
// Specify a filesystem path to be used for the logo.
|
1706 |
|
|
$file = current($this->drupalGetTestFiles('image'));
|
1707 |
|
|
$file_relative = strtr($file->uri, array('public:/' => variable_get('file_public_path', conf_path() . '/files')));
|
1708 |
|
|
$default_theme_path = 'themes/stark';
|
1709 |
|
|
|
1710 |
|
|
$supported_paths = array(
|
1711 |
|
|
// Raw stream wrapper URI.
|
1712 |
|
|
$file->uri => array(
|
1713 |
|
|
'form' => file_uri_target($file->uri),
|
1714 |
|
|
'src' => file_create_url($file->uri),
|
1715 |
|
|
),
|
1716 |
|
|
// Relative path within the public filesystem.
|
1717 |
|
|
file_uri_target($file->uri) => array(
|
1718 |
|
|
'form' => file_uri_target($file->uri),
|
1719 |
|
|
'src' => file_create_url($file->uri),
|
1720 |
|
|
),
|
1721 |
|
|
// Relative path to a public file.
|
1722 |
|
|
$file_relative => array(
|
1723 |
|
|
'form' => $file_relative,
|
1724 |
|
|
'src' => file_create_url($file->uri),
|
1725 |
|
|
),
|
1726 |
|
|
// Relative path to an arbitrary file.
|
1727 |
|
|
'misc/druplicon.png' => array(
|
1728 |
|
|
'form' => 'misc/druplicon.png',
|
1729 |
|
|
'src' => $GLOBALS['base_url'] . '/' . 'misc/druplicon.png',
|
1730 |
|
|
),
|
1731 |
|
|
// Relative path to a file in a theme.
|
1732 |
|
|
$default_theme_path . '/logo.png' => array(
|
1733 |
|
|
'form' => $default_theme_path . '/logo.png',
|
1734 |
|
|
'src' => $GLOBALS['base_url'] . '/' . $default_theme_path . '/logo.png',
|
1735 |
|
|
),
|
1736 |
|
|
);
|
1737 |
|
|
foreach ($supported_paths as $input => $expected) {
|
1738 |
|
|
$edit = array(
|
1739 |
|
|
'default_logo' => FALSE,
|
1740 |
|
|
'logo_path' => $input,
|
1741 |
|
|
);
|
1742 |
|
|
$this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'));
|
1743 |
|
|
$this->assertNoText('The custom logo path is invalid.');
|
1744 |
|
|
$this->assertFieldByName('logo_path', $expected['form']);
|
1745 |
|
|
|
1746 |
|
|
// Verify the actual 'src' attribute of the logo being output.
|
1747 |
|
|
$this->drupalGet('');
|
1748 |
|
|
$elements = $this->xpath('//*[@id=:id]/img', array(':id' => 'logo'));
|
1749 |
|
|
$this->assertEqual((string) $elements[0]['src'], $expected['src']);
|
1750 |
|
|
}
|
1751 |
|
|
|
1752 |
|
|
$unsupported_paths = array(
|
1753 |
|
|
// Stream wrapper URI to non-existing file.
|
1754 |
|
|
'public://whatever.png',
|
1755 |
|
|
'private://whatever.png',
|
1756 |
|
|
'temporary://whatever.png',
|
1757 |
|
|
// Bogus stream wrapper URIs.
|
1758 |
|
|
'public:/whatever.png',
|
1759 |
|
|
'://whatever.png',
|
1760 |
|
|
':whatever.png',
|
1761 |
|
|
'public://',
|
1762 |
|
|
// Relative path within the public filesystem to non-existing file.
|
1763 |
|
|
'whatever.png',
|
1764 |
|
|
// Relative path to non-existing file in public filesystem.
|
1765 |
|
|
variable_get('file_public_path', conf_path() . '/files') . '/whatever.png',
|
1766 |
|
|
// Semi-absolute path to non-existing file in public filesystem.
|
1767 |
|
|
'/' . variable_get('file_public_path', conf_path() . '/files') . '/whatever.png',
|
1768 |
|
|
// Relative path to arbitrary non-existing file.
|
1769 |
|
|
'misc/whatever.png',
|
1770 |
|
|
// Semi-absolute path to arbitrary non-existing file.
|
1771 |
|
|
'/misc/whatever.png',
|
1772 |
|
|
// Absolute paths to any local file (even if it exists).
|
1773 |
|
|
drupal_realpath($file->uri),
|
1774 |
|
|
);
|
1775 |
|
|
$this->drupalGet('admin/appearance/settings');
|
1776 |
|
|
foreach ($unsupported_paths as $path) {
|
1777 |
|
|
$edit = array(
|
1778 |
|
|
'default_logo' => FALSE,
|
1779 |
|
|
'logo_path' => $path,
|
1780 |
|
|
);
|
1781 |
|
|
$this->drupalPost(NULL, $edit, t('Save configuration'));
|
1782 |
|
|
$this->assertText('The custom logo path is invalid.');
|
1783 |
|
|
}
|
1784 |
|
|
|
1785 |
|
|
// Upload a file to use for the logo.
|
1786 |
|
|
$edit = array(
|
1787 |
|
|
'default_logo' => FALSE,
|
1788 |
|
|
'logo_path' => '',
|
1789 |
|
|
'files[logo_upload]' => drupal_realpath($file->uri),
|
1790 |
|
|
);
|
1791 |
|
|
$this->drupalPost('admin/appearance/settings', $edit, t('Save configuration'));
|
1792 |
|
|
|
1793 |
|
|
$fields = $this->xpath($this->constructFieldXpath('name', 'logo_path'));
|
1794 |
|
|
$uploaded_filename = 'public://' . $fields[0]['value'];
|
1795 |
|
|
|
1796 |
|
|
$this->drupalGet('');
|
1797 |
|
|
$elements = $this->xpath('//*[@id=:id]/img', array(':id' => 'logo'));
|
1798 |
|
|
$this->assertEqual($elements[0]['src'], file_create_url($uploaded_filename));
|
1799 |
|
|
}
|
1800 |
|
|
|
1801 |
|
|
/**
|
1802 |
|
|
* Test the administration theme functionality.
|
1803 |
|
|
*/
|
1804 |
|
|
function testAdministrationTheme() {
|
1805 |
|
|
theme_enable(array('stark'));
|
1806 |
|
|
variable_set('theme_default', 'stark');
|
1807 |
|
|
// Enable an administration theme and show it on the node admin pages.
|
1808 |
|
|
$edit = array(
|
1809 |
|
|
'admin_theme' => 'seven',
|
1810 |
|
|
'node_admin_theme' => TRUE,
|
1811 |
|
|
);
|
1812 |
|
|
$this->drupalPost('admin/appearance', $edit, t('Save configuration'));
|
1813 |
|
|
|
1814 |
|
|
$this->drupalGet('admin/config');
|
1815 |
|
|
$this->assertRaw('themes/seven', 'Administration theme used on an administration page.');
|
1816 |
|
|
|
1817 |
|
|
$this->drupalGet('node/' . $this->node->nid);
|
1818 |
|
|
$this->assertRaw('themes/stark', 'Site default theme used on node page.');
|
1819 |
|
|
|
1820 |
|
|
$this->drupalGet('node/add');
|
1821 |
|
|
$this->assertRaw('themes/seven', 'Administration theme used on the add content page.');
|
1822 |
|
|
|
1823 |
|
|
$this->drupalGet('node/' . $this->node->nid . '/edit');
|
1824 |
|
|
$this->assertRaw('themes/seven', 'Administration theme used on the edit content page.');
|
1825 |
|
|
|
1826 |
|
|
// Disable the admin theme on the node admin pages.
|
1827 |
|
|
$edit = array(
|
1828 |
|
|
'node_admin_theme' => FALSE,
|
1829 |
|
|
);
|
1830 |
|
|
$this->drupalPost('admin/appearance', $edit, t('Save configuration'));
|
1831 |
|
|
|
1832 |
|
|
$this->drupalGet('admin/config');
|
1833 |
|
|
$this->assertRaw('themes/seven', 'Administration theme used on an administration page.');
|
1834 |
|
|
|
1835 |
|
|
$this->drupalGet('node/add');
|
1836 |
|
|
$this->assertRaw('themes/stark', 'Site default theme used on the add content page.');
|
1837 |
|
|
|
1838 |
|
|
// Reset to the default theme settings.
|
1839 |
|
|
variable_set('theme_default', 'bartik');
|
1840 |
|
|
$edit = array(
|
1841 |
|
|
'admin_theme' => '0',
|
1842 |
|
|
'node_admin_theme' => FALSE,
|
1843 |
|
|
);
|
1844 |
|
|
$this->drupalPost('admin/appearance', $edit, t('Save configuration'));
|
1845 |
|
|
|
1846 |
|
|
$this->drupalGet('admin');
|
1847 |
|
|
$this->assertRaw('themes/bartik', 'Site default theme used on administration page.');
|
1848 |
|
|
|
1849 |
|
|
$this->drupalGet('node/add');
|
1850 |
|
|
$this->assertRaw('themes/bartik', 'Site default theme used on the add content page.');
|
1851 |
|
|
}
|
1852 |
|
|
|
1853 |
|
|
/**
|
1854 |
|
|
* Test switching the default theme.
|
1855 |
|
|
*/
|
1856 |
|
|
function testSwitchDefaultTheme() {
|
1857 |
|
|
// Enable "stark" and set it as the default theme.
|
1858 |
|
|
theme_enable(array('stark'));
|
1859 |
|
|
$this->drupalGet('admin/appearance');
|
1860 |
|
|
$this->clickLink(t('Set default'), 1);
|
1861 |
|
|
$this->assertTrue(variable_get('theme_default', '') == 'stark', 'Site default theme switched successfully.');
|
1862 |
|
|
|
1863 |
|
|
// Test the default theme on the secondary links (blocks admin page).
|
1864 |
|
|
$this->drupalGet('admin/structure/block');
|
1865 |
|
|
$this->assertText('Stark(' . t('active tab') . ')', 'Default local task on blocks admin page is the default theme.');
|
1866 |
|
|
// Switch back to Bartik and test again to test that the menu cache is cleared.
|
1867 |
|
|
$this->drupalGet('admin/appearance');
|
1868 |
|
|
$this->clickLink(t('Set default'), 0);
|
1869 |
|
|
$this->drupalGet('admin/structure/block');
|
1870 |
|
|
$this->assertText('Bartik(' . t('active tab') . ')', 'Default local task on blocks admin page has changed.');
|
1871 |
|
|
}
|
1872 |
|
|
}
|
1873 |
|
|
|
1874 |
|
|
|
1875 |
|
|
/**
|
1876 |
|
|
* Test the basic queue functionality.
|
1877 |
|
|
*/
|
1878 |
|
|
class QueueTestCase extends DrupalWebTestCase {
|
1879 |
|
|
public static function getInfo() {
|
1880 |
|
|
return array(
|
1881 |
|
|
'name' => 'Queue functionality',
|
1882 |
|
|
'description' => 'Queues and dequeues a set of items to check the basic queue functionality.',
|
1883 |
|
|
'group' => 'System',
|
1884 |
|
|
);
|
1885 |
|
|
}
|
1886 |
|
|
|
1887 |
|
|
/**
|
1888 |
|
|
* Queues and dequeues a set of items to check the basic queue functionality.
|
1889 |
|
|
*/
|
1890 |
|
|
function testQueue() {
|
1891 |
|
|
// Create two queues.
|
1892 |
|
|
$queue1 = DrupalQueue::get($this->randomName());
|
1893 |
|
|
$queue1->createQueue();
|
1894 |
|
|
$queue2 = DrupalQueue::get($this->randomName());
|
1895 |
|
|
$queue2->createQueue();
|
1896 |
|
|
|
1897 |
|
|
// Create four items.
|
1898 |
|
|
$data = array();
|
1899 |
|
|
for ($i = 0; $i < 4; $i++) {
|
1900 |
|
|
$data[] = array($this->randomName() => $this->randomName());
|
1901 |
|
|
}
|
1902 |
|
|
|
1903 |
|
|
// Queue items 1 and 2 in the queue1.
|
1904 |
|
|
$queue1->createItem($data[0]);
|
1905 |
|
|
$queue1->createItem($data[1]);
|
1906 |
|
|
|
1907 |
|
|
// Retrieve two items from queue1.
|
1908 |
|
|
$items = array();
|
1909 |
|
|
$new_items = array();
|
1910 |
|
|
|
1911 |
|
|
$items[] = $item = $queue1->claimItem();
|
1912 |
|
|
$new_items[] = $item->data;
|
1913 |
|
|
|
1914 |
|
|
$items[] = $item = $queue1->claimItem();
|
1915 |
|
|
$new_items[] = $item->data;
|
1916 |
|
|
|
1917 |
|
|
// First two dequeued items should match the first two items we queued.
|
1918 |
|
|
$this->assertEqual($this->queueScore($data, $new_items), 2, 'Two items matched');
|
1919 |
|
|
|
1920 |
|
|
// Add two more items.
|
1921 |
|
|
$queue1->createItem($data[2]);
|
1922 |
|
|
$queue1->createItem($data[3]);
|
1923 |
|
|
|
1924 |
|
|
$this->assertTrue($queue1->numberOfItems(), 'Queue 1 is not empty after adding items.');
|
1925 |
|
|
$this->assertFalse($queue2->numberOfItems(), 'Queue 2 is empty while Queue 1 has items');
|
1926 |
|
|
|
1927 |
|
|
$items[] = $item = $queue1->claimItem();
|
1928 |
|
|
$new_items[] = $item->data;
|
1929 |
|
|
|
1930 |
|
|
$items[] = $item = $queue1->claimItem();
|
1931 |
|
|
$new_items[] = $item->data;
|
1932 |
|
|
|
1933 |
|
|
// All dequeued items should match the items we queued exactly once,
|
1934 |
|
|
// therefore the score must be exactly 4.
|
1935 |
|
|
$this->assertEqual($this->queueScore($data, $new_items), 4, 'Four items matched');
|
1936 |
|
|
|
1937 |
|
|
// There should be no duplicate items.
|
1938 |
|
|
$this->assertEqual($this->queueScore($new_items, $new_items), 4, 'Four items matched');
|
1939 |
|
|
|
1940 |
|
|
// Delete all items from queue1.
|
1941 |
|
|
foreach ($items as $item) {
|
1942 |
|
|
$queue1->deleteItem($item);
|
1943 |
|
|
}
|
1944 |
|
|
|
1945 |
|
|
// Check that both queues are empty.
|
1946 |
|
|
$this->assertFalse($queue1->numberOfItems(), 'Queue 1 is empty');
|
1947 |
|
|
$this->assertFalse($queue2->numberOfItems(), 'Queue 2 is empty');
|
1948 |
|
|
}
|
1949 |
|
|
|
1950 |
|
|
/**
|
1951 |
|
|
* This function returns the number of equal items in two arrays.
|
1952 |
|
|
*/
|
1953 |
|
|
function queueScore($items, $new_items) {
|
1954 |
|
|
$score = 0;
|
1955 |
|
|
foreach ($items as $item) {
|
1956 |
|
|
foreach ($new_items as $new_item) {
|
1957 |
|
|
if ($item === $new_item) {
|
1958 |
|
|
$score++;
|
1959 |
|
|
}
|
1960 |
|
|
}
|
1961 |
|
|
}
|
1962 |
|
|
return $score;
|
1963 |
|
|
}
|
1964 |
|
|
}
|
1965 |
|
|
|
1966 |
|
|
/**
|
1967 |
|
|
* Test token replacement in strings.
|
1968 |
|
|
*/
|
1969 |
|
|
class TokenReplaceTestCase extends DrupalWebTestCase {
|
1970 |
|
|
public static function getInfo() {
|
1971 |
|
|
return array(
|
1972 |
|
|
'name' => 'Token replacement',
|
1973 |
|
|
'description' => 'Generates text using placeholders for dummy content to check token replacement.',
|
1974 |
|
|
'group' => 'System',
|
1975 |
|
|
);
|
1976 |
|
|
}
|
1977 |
|
|
|
1978 |
|
|
/**
|
1979 |
|
|
* Creates a user and a node, then tests the tokens generated from them.
|
1980 |
|
|
*/
|
1981 |
|
|
function testTokenReplacement() {
|
1982 |
|
|
// Create the initial objects.
|
1983 |
|
|
$account = $this->drupalCreateUser();
|
1984 |
|
|
$node = $this->drupalCreateNode(array('uid' => $account->uid));
|
1985 |
|
|
$node->title = '<blink>Blinking Text</blink>';
|
1986 |
|
|
global $user, $language;
|
1987 |
|
|
|
1988 |
|
|
$source = '[node:title]'; // Title of the node we passed in
|
1989 |
|
|
$source .= '[node:author:name]'; // Node author's name
|
1990 |
|
|
$source .= '[node:created:since]'; // Time since the node was created
|
1991 |
|
|
$source .= '[current-user:name]'; // Current user's name
|
1992 |
|
|
$source .= '[date:short]'; // Short date format of REQUEST_TIME
|
1993 |
|
|
$source .= '[user:name]'; // No user passed in, should be untouched
|
1994 |
|
|
$source .= '[bogus:token]'; // Non-existent token
|
1995 |
|
|
|
1996 |
|
|
$target = check_plain($node->title);
|
1997 |
|
|
$target .= check_plain($account->name);
|
1998 |
|
|
$target .= format_interval(REQUEST_TIME - $node->created, 2, $language->language);
|
1999 |
|
|
$target .= check_plain($user->name);
|
2000 |
|
|
$target .= format_date(REQUEST_TIME, 'short', '', NULL, $language->language);
|
2001 |
|
|
|
2002 |
|
|
// Test that the clear parameter cleans out non-existent tokens.
|
2003 |
|
|
$result = token_replace($source, array('node' => $node), array('language' => $language, 'clear' => TRUE));
|
2004 |
|
|
$result = $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens cleared out.');
|
2005 |
|
|
|
2006 |
|
|
// Test without using the clear parameter (non-existent token untouched).
|
2007 |
|
|
$target .= '[user:name]';
|
2008 |
|
|
$target .= '[bogus:token]';
|
2009 |
|
|
$result = token_replace($source, array('node' => $node), array('language' => $language));
|
2010 |
|
|
$this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.');
|
2011 |
|
|
|
2012 |
|
|
// Check that the results of token_generate are sanitized properly. This does NOT
|
2013 |
|
|
// test the cleanliness of every token -- just that the $sanitize flag is being
|
2014 |
|
|
// passed properly through the call stack and being handled correctly by a 'known'
|
2015 |
|
|
// token, [node:title].
|
2016 |
|
|
$raw_tokens = array('title' => '[node:title]');
|
2017 |
|
|
$generated = token_generate('node', $raw_tokens, array('node' => $node));
|
2018 |
|
|
$this->assertEqual($generated['[node:title]'], check_plain($node->title), 'Token sanitized.');
|
2019 |
|
|
|
2020 |
|
|
$generated = token_generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE));
|
2021 |
|
|
$this->assertEqual($generated['[node:title]'], $node->title, 'Unsanitized token generated properly.');
|
2022 |
|
|
|
2023 |
|
|
// Test token replacement when the string contains no tokens.
|
2024 |
|
|
$this->assertEqual(token_replace('No tokens here.'), 'No tokens here.');
|
2025 |
|
|
}
|
2026 |
|
|
|
2027 |
|
|
/**
|
2028 |
|
|
* Test whether token-replacement works in various contexts.
|
2029 |
|
|
*/
|
2030 |
|
|
function testSystemTokenRecognition() {
|
2031 |
|
|
global $language;
|
2032 |
|
|
|
2033 |
|
|
// Generate prefixes and suffixes for the token context.
|
2034 |
|
|
$tests = array(
|
2035 |
|
|
array('prefix' => 'this is the ', 'suffix' => ' site'),
|
2036 |
|
|
array('prefix' => 'this is the', 'suffix' => 'site'),
|
2037 |
|
|
array('prefix' => '[', 'suffix' => ']'),
|
2038 |
|
|
array('prefix' => '', 'suffix' => ']]]'),
|
2039 |
|
|
array('prefix' => '[[[', 'suffix' => ''),
|
2040 |
|
|
array('prefix' => ':[:', 'suffix' => '--]'),
|
2041 |
|
|
array('prefix' => '-[-', 'suffix' => ':]:'),
|
2042 |
|
|
array('prefix' => '[:', 'suffix' => ']'),
|
2043 |
|
|
array('prefix' => '[site:', 'suffix' => ':name]'),
|
2044 |
|
|
array('prefix' => '[site:', 'suffix' => ']'),
|
2045 |
|
|
);
|
2046 |
|
|
|
2047 |
|
|
// Check if the token is recognized in each of the contexts.
|
2048 |
|
|
foreach ($tests as $test) {
|
2049 |
|
|
$input = $test['prefix'] . '[site:name]' . $test['suffix'];
|
2050 |
|
|
$expected = $test['prefix'] . 'Drupal' . $test['suffix'];
|
2051 |
|
|
$output = token_replace($input, array(), array('language' => $language));
|
2052 |
|
|
$this->assertTrue($output == $expected, format_string('Token recognized in string %string', array('%string' => $input)));
|
2053 |
|
|
}
|
2054 |
|
|
}
|
2055 |
|
|
|
2056 |
|
|
/**
|
2057 |
|
|
* Tests the generation of all system site information tokens.
|
2058 |
|
|
*/
|
2059 |
|
|
function testSystemSiteTokenReplacement() {
|
2060 |
|
|
global $language;
|
2061 |
|
|
$url_options = array(
|
2062 |
|
|
'absolute' => TRUE,
|
2063 |
|
|
'language' => $language,
|
2064 |
|
|
);
|
2065 |
|
|
|
2066 |
|
|
// Set a few site variables.
|
2067 |
|
|
variable_set('site_name', '<strong>Drupal<strong>');
|
2068 |
|
|
variable_set('site_slogan', '<blink>Slogan</blink>');
|
2069 |
|
|
|
2070 |
|
|
// Generate and test sanitized tokens.
|
2071 |
|
|
$tests = array();
|
2072 |
|
|
$tests['[site:name]'] = check_plain(variable_get('site_name', 'Drupal'));
|
2073 |
|
|
$tests['[site:slogan]'] = check_plain(variable_get('site_slogan', ''));
|
2074 |
|
|
$tests['[site:mail]'] = 'simpletest@example.com';
|
2075 |
|
|
$tests['[site:url]'] = url('<front>', $url_options);
|
2076 |
|
|
$tests['[site:url-brief]'] = preg_replace(array('!^https?://!', '!/$!'), '', url('<front>', $url_options));
|
2077 |
|
|
$tests['[site:login-url]'] = url('user', $url_options);
|
2078 |
|
|
|
2079 |
|
|
// Test to make sure that we generated something for each token.
|
2080 |
|
|
$this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
|
2081 |
|
|
|
2082 |
|
|
foreach ($tests as $input => $expected) {
|
2083 |
|
|
$output = token_replace($input, array(), array('language' => $language));
|
2084 |
|
|
$this->assertEqual($output, $expected, format_string('Sanitized system site information token %token replaced.', array('%token' => $input)));
|
2085 |
|
|
}
|
2086 |
|
|
|
2087 |
|
|
// Generate and test unsanitized tokens.
|
2088 |
|
|
$tests['[site:name]'] = variable_get('site_name', 'Drupal');
|
2089 |
|
|
$tests['[site:slogan]'] = variable_get('site_slogan', '');
|
2090 |
|
|
|
2091 |
|
|
foreach ($tests as $input => $expected) {
|
2092 |
|
|
$output = token_replace($input, array(), array('language' => $language, 'sanitize' => FALSE));
|
2093 |
|
|
$this->assertEqual($output, $expected, format_string('Unsanitized system site information token %token replaced.', array('%token' => $input)));
|
2094 |
|
|
}
|
2095 |
|
|
}
|
2096 |
|
|
|
2097 |
|
|
/**
|
2098 |
|
|
* Tests the generation of all system date tokens.
|
2099 |
|
|
*/
|
2100 |
|
|
function testSystemDateTokenReplacement() {
|
2101 |
|
|
global $language;
|
2102 |
|
|
|
2103 |
|
|
// Set time to one hour before request.
|
2104 |
|
|
$date = REQUEST_TIME - 3600;
|
2105 |
|
|
|
2106 |
|
|
// Generate and test tokens.
|
2107 |
|
|
$tests = array();
|
2108 |
|
|
$tests['[date:short]'] = format_date($date, 'short', '', NULL, $language->language);
|
2109 |
|
|
$tests['[date:medium]'] = format_date($date, 'medium', '', NULL, $language->language);
|
2110 |
|
|
$tests['[date:long]'] = format_date($date, 'long', '', NULL, $language->language);
|
2111 |
|
|
$tests['[date:custom:m/j/Y]'] = format_date($date, 'custom', 'm/j/Y', NULL, $language->language);
|
2112 |
|
|
$tests['[date:since]'] = format_interval((REQUEST_TIME - $date), 2, $language->language);
|
2113 |
|
|
$tests['[date:raw]'] = filter_xss($date);
|
2114 |
|
|
|
2115 |
|
|
// Test to make sure that we generated something for each token.
|
2116 |
|
|
$this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
|
2117 |
|
|
|
2118 |
|
|
foreach ($tests as $input => $expected) {
|
2119 |
|
|
$output = token_replace($input, array('date' => $date), array('language' => $language));
|
2120 |
|
|
$this->assertEqual($output, $expected, format_string('Date token %token replaced.', array('%token' => $input)));
|
2121 |
|
|
}
|
2122 |
|
|
}
|
2123 |
|
|
}
|
2124 |
|
|
|
2125 |
|
|
class InfoFileParserTestCase extends DrupalUnitTestCase {
|
2126 |
|
|
public static function getInfo() {
|
2127 |
|
|
return array(
|
2128 |
|
|
'name' => 'Info file format parser',
|
2129 |
|
|
'description' => 'Tests proper parsing of a .info file formatted string.',
|
2130 |
|
|
'group' => 'System',
|
2131 |
|
|
);
|
2132 |
|
|
}
|
2133 |
|
|
|
2134 |
|
|
/**
|
2135 |
|
|
* Test drupal_parse_info_format().
|
2136 |
|
|
*/
|
2137 |
|
|
function testDrupalParseInfoFormat() {
|
2138 |
|
|
$config = '
|
2139 |
|
|
simple = Value
|
2140 |
|
|
quoted = " Value"
|
2141 |
|
|
multiline = "Value
|
2142 |
|
|
Value"
|
2143 |
|
|
array[] = Value1
|
2144 |
|
|
array[] = Value2
|
2145 |
|
|
array_assoc[a] = Value1
|
2146 |
|
|
array_assoc[b] = Value2
|
2147 |
|
|
array_deep[][][] = Value
|
2148 |
|
|
array_deep_assoc[a][b][c] = Value
|
2149 |
|
|
array_space[a b] = Value';
|
2150 |
|
|
|
2151 |
|
|
$expected = array(
|
2152 |
|
|
'simple' => 'Value',
|
2153 |
|
|
'quoted' => ' Value',
|
2154 |
|
|
'multiline' => "Value\n Value",
|
2155 |
|
|
'array' => array(
|
2156 |
|
|
0 => 'Value1',
|
2157 |
|
|
1 => 'Value2',
|
2158 |
|
|
),
|
2159 |
|
|
'array_assoc' => array(
|
2160 |
|
|
'a' => 'Value1',
|
2161 |
|
|
'b' => 'Value2',
|
2162 |
|
|
),
|
2163 |
|
|
'array_deep' => array(
|
2164 |
|
|
0 => array(
|
2165 |
|
|
0 => array(
|
2166 |
|
|
0 => 'Value',
|
2167 |
|
|
),
|
2168 |
|
|
),
|
2169 |
|
|
),
|
2170 |
|
|
'array_deep_assoc' => array(
|
2171 |
|
|
'a' => array(
|
2172 |
|
|
'b' => array(
|
2173 |
|
|
'c' => 'Value',
|
2174 |
|
|
),
|
2175 |
|
|
),
|
2176 |
|
|
),
|
2177 |
|
|
'array_space' => array(
|
2178 |
|
|
'a b' => 'Value',
|
2179 |
|
|
),
|
2180 |
|
|
);
|
2181 |
|
|
|
2182 |
|
|
$parsed = drupal_parse_info_format($config);
|
2183 |
|
|
|
2184 |
|
|
$this->assertEqual($parsed['simple'], $expected['simple'], 'Set a simple value.');
|
2185 |
|
|
$this->assertEqual($parsed['quoted'], $expected['quoted'], 'Set a simple value in quotes.');
|
2186 |
|
|
$this->assertEqual($parsed['multiline'], $expected['multiline'], 'Set a multiline value.');
|
2187 |
|
|
$this->assertEqual($parsed['array'], $expected['array'], 'Set a simple array.');
|
2188 |
|
|
$this->assertEqual($parsed['array_assoc'], $expected['array_assoc'], 'Set an associative array.');
|
2189 |
|
|
$this->assertEqual($parsed['array_deep'], $expected['array_deep'], 'Set a nested array.');
|
2190 |
|
|
$this->assertEqual($parsed['array_deep_assoc'], $expected['array_deep_assoc'], 'Set a nested associative array.');
|
2191 |
|
|
$this->assertEqual($parsed['array_space'], $expected['array_space'], 'Set an array with a whitespace in the key.');
|
2192 |
|
|
$this->assertEqual($parsed, $expected, 'Entire parsed .info string and expected array are identical.');
|
2193 |
|
|
}
|
2194 |
|
|
}
|
2195 |
|
|
|
2196 |
|
|
/**
|
2197 |
|
|
* Tests the effectiveness of hook_system_info_alter().
|
2198 |
|
|
*/
|
2199 |
|
|
class SystemInfoAlterTestCase extends DrupalWebTestCase {
|
2200 |
|
|
public static function getInfo() {
|
2201 |
|
|
return array(
|
2202 |
|
|
'name' => 'System info alter',
|
2203 |
|
|
'description' => 'Tests the effectiveness of hook_system_info_alter().',
|
2204 |
|
|
'group' => 'System',
|
2205 |
|
|
);
|
2206 |
|
|
}
|
2207 |
|
|
|
2208 |
|
|
/**
|
2209 |
|
|
* Tests that {system}.info is rebuilt after a module that implements
|
2210 |
|
|
* hook_system_info_alter() is enabled. Also tests if core *_list() functions
|
2211 |
|
|
* return freshly altered info.
|
2212 |
|
|
*/
|
2213 |
|
|
function testSystemInfoAlter() {
|
2214 |
|
|
// Enable our test module. Flush all caches, which we assert is the only
|
2215 |
|
|
// thing necessary to use the rebuilt {system}.info.
|
2216 |
|
|
module_enable(array('module_test'), FALSE);
|
2217 |
|
|
drupal_flush_all_caches();
|
2218 |
|
|
$this->assertTrue(module_exists('module_test'), 'Test module is enabled.');
|
2219 |
|
|
|
2220 |
|
|
$info = $this->getSystemInfo('seven', 'theme');
|
2221 |
|
|
$this->assertTrue(isset($info['regions']['test_region']), 'Altered theme info was added to {system}.info.');
|
2222 |
|
|
$seven_regions = system_region_list('seven');
|
2223 |
|
|
$this->assertTrue(isset($seven_regions['test_region']), 'Altered theme info was returned by system_region_list().');
|
2224 |
|
|
$system_list_themes = system_list('theme');
|
2225 |
|
|
$info = $system_list_themes['seven']->info;
|
2226 |
|
|
$this->assertTrue(isset($info['regions']['test_region']), 'Altered theme info was returned by system_list().');
|
2227 |
|
|
$list_themes = list_themes();
|
2228 |
|
|
$this->assertTrue(isset($list_themes['seven']->info['regions']['test_region']), 'Altered theme info was returned by list_themes().');
|
2229 |
|
|
|
2230 |
|
|
// Disable the module and verify that {system}.info is rebuilt without it.
|
2231 |
|
|
module_disable(array('module_test'), FALSE);
|
2232 |
|
|
drupal_flush_all_caches();
|
2233 |
|
|
$this->assertFalse(module_exists('module_test'), 'Test module is disabled.');
|
2234 |
|
|
|
2235 |
|
|
$info = $this->getSystemInfo('seven', 'theme');
|
2236 |
|
|
$this->assertFalse(isset($info['regions']['test_region']), 'Altered theme info was removed from {system}.info.');
|
2237 |
|
|
$seven_regions = system_region_list('seven');
|
2238 |
|
|
$this->assertFalse(isset($seven_regions['test_region']), 'Altered theme info was not returned by system_region_list().');
|
2239 |
|
|
$system_list_themes = system_list('theme');
|
2240 |
|
|
$info = $system_list_themes['seven']->info;
|
2241 |
|
|
$this->assertFalse(isset($info['regions']['test_region']), 'Altered theme info was not returned by system_list().');
|
2242 |
|
|
$list_themes = list_themes();
|
2243 |
|
|
$this->assertFalse(isset($list_themes['seven']->info['regions']['test_region']), 'Altered theme info was not returned by list_themes().');
|
2244 |
|
|
}
|
2245 |
|
|
|
2246 |
|
|
/**
|
2247 |
|
|
* Returns the info array as it is stored in {system}.
|
2248 |
|
|
*
|
2249 |
|
|
* @param $name
|
2250 |
|
|
* The name of the record in {system}.
|
2251 |
|
|
* @param $type
|
2252 |
|
|
* The type of record in {system}.
|
2253 |
|
|
*
|
2254 |
|
|
* @return
|
2255 |
|
|
* Array of info, or FALSE if the record is not found.
|
2256 |
|
|
*/
|
2257 |
|
|
function getSystemInfo($name, $type) {
|
2258 |
|
|
$raw_info = db_query("SELECT info FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
|
2259 |
|
|
return $raw_info ? unserialize($raw_info) : FALSE;
|
2260 |
|
|
}
|
2261 |
|
|
}
|
2262 |
|
|
|
2263 |
|
|
/**
|
2264 |
|
|
* Tests for the update system functionality.
|
2265 |
|
|
*/
|
2266 |
|
|
class UpdateScriptFunctionalTest extends DrupalWebTestCase {
|
2267 |
|
|
private $update_url;
|
2268 |
|
|
private $update_user;
|
2269 |
|
|
|
2270 |
|
|
public static function getInfo() {
|
2271 |
|
|
return array(
|
2272 |
|
|
'name' => 'Update functionality',
|
2273 |
|
|
'description' => 'Tests the update script access and functionality.',
|
2274 |
|
|
'group' => 'System',
|
2275 |
|
|
);
|
2276 |
|
|
}
|
2277 |
|
|
|
2278 |
|
|
function setUp() {
|
2279 |
|
|
parent::setUp('update_script_test');
|
2280 |
|
|
$this->update_url = $GLOBALS['base_url'] . '/update.php';
|
2281 |
|
|
$this->update_user = $this->drupalCreateUser(array('administer software updates'));
|
2282 |
|
|
}
|
2283 |
|
|
|
2284 |
|
|
/**
|
2285 |
|
|
* Tests access to the update script.
|
2286 |
|
|
*/
|
2287 |
|
|
function testUpdateAccess() {
|
2288 |
|
|
// Try accessing update.php without the proper permission.
|
2289 |
|
|
$regular_user = $this->drupalCreateUser();
|
2290 |
|
|
$this->drupalLogin($regular_user);
|
2291 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2292 |
|
|
$this->assertResponse(403);
|
2293 |
|
|
|
2294 |
|
|
// Try accessing update.php as an anonymous user.
|
2295 |
|
|
$this->drupalLogout();
|
2296 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2297 |
|
|
$this->assertResponse(403);
|
2298 |
|
|
|
2299 |
|
|
// Access the update page with the proper permission.
|
2300 |
|
|
$this->drupalLogin($this->update_user);
|
2301 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2302 |
|
|
$this->assertResponse(200);
|
2303 |
|
|
|
2304 |
|
|
// Access the update page as user 1.
|
2305 |
|
|
$user1 = user_load(1);
|
2306 |
|
|
$user1->pass_raw = user_password();
|
2307 |
|
|
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
|
2308 |
|
|
$user1->pass = user_hash_password(trim($user1->pass_raw));
|
2309 |
|
|
db_query("UPDATE {users} SET pass = :pass WHERE uid = :uid", array(':pass' => $user1->pass, ':uid' => $user1->uid));
|
2310 |
|
|
$this->drupalLogin($user1);
|
2311 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2312 |
|
|
$this->assertResponse(200);
|
2313 |
|
|
}
|
2314 |
|
|
|
2315 |
|
|
/**
|
2316 |
|
|
* Tests that requirements warnings and errors are correctly displayed.
|
2317 |
|
|
*/
|
2318 |
|
|
function testRequirements() {
|
2319 |
|
|
$this->drupalLogin($this->update_user);
|
2320 |
|
|
|
2321 |
|
|
// If there are no requirements warnings or errors, we expect to be able to
|
2322 |
|
|
// go through the update process uninterrupted.
|
2323 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2324 |
|
|
$this->drupalPost(NULL, array(), t('Continue'));
|
2325 |
|
|
$this->assertText(t('No pending updates.'), 'End of update process was reached.');
|
2326 |
|
|
// Confirm that all caches were cleared.
|
2327 |
|
|
$this->assertText(t('hook_flush_caches() invoked for update_script_test.module.'), 'Caches were cleared when there were no requirements warnings or errors.');
|
2328 |
|
|
|
2329 |
|
|
// If there is a requirements warning, we expect it to be initially
|
2330 |
|
|
// displayed, but clicking the link to proceed should allow us to go
|
2331 |
|
|
// through the rest of the update process uninterrupted.
|
2332 |
|
|
|
2333 |
|
|
// First, run this test with pending updates to make sure they can be run
|
2334 |
|
|
// successfully.
|
2335 |
|
|
variable_set('update_script_test_requirement_type', REQUIREMENT_WARNING);
|
2336 |
|
|
drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
|
2337 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2338 |
|
|
$this->assertText('This is a requirements warning provided by the update_script_test module.');
|
2339 |
|
|
$this->clickLink('try again');
|
2340 |
|
|
$this->assertNoText('This is a requirements warning provided by the update_script_test module.');
|
2341 |
|
|
$this->drupalPost(NULL, array(), t('Continue'));
|
2342 |
|
|
$this->drupalPost(NULL, array(), t('Apply pending updates'));
|
2343 |
|
|
$this->assertText(t('The update_script_test_update_7000() update was executed successfully.'), 'End of update process was reached.');
|
2344 |
|
|
// Confirm that all caches were cleared.
|
2345 |
|
|
$this->assertText(t('hook_flush_caches() invoked for update_script_test.module.'), 'Caches were cleared after resolving a requirements warning and applying updates.');
|
2346 |
|
|
|
2347 |
|
|
// Now try again without pending updates to make sure that works too.
|
2348 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2349 |
|
|
$this->assertText('This is a requirements warning provided by the update_script_test module.');
|
2350 |
|
|
$this->clickLink('try again');
|
2351 |
|
|
$this->assertNoText('This is a requirements warning provided by the update_script_test module.');
|
2352 |
|
|
$this->drupalPost(NULL, array(), t('Continue'));
|
2353 |
|
|
$this->assertText(t('No pending updates.'), 'End of update process was reached.');
|
2354 |
|
|
// Confirm that all caches were cleared.
|
2355 |
|
|
$this->assertText(t('hook_flush_caches() invoked for update_script_test.module.'), 'Caches were cleared after applying updates and re-running the script.');
|
2356 |
|
|
|
2357 |
|
|
// If there is a requirements error, it should be displayed even after
|
2358 |
|
|
// clicking the link to proceed (since the problem that triggered the error
|
2359 |
|
|
// has not been fixed).
|
2360 |
|
|
variable_set('update_script_test_requirement_type', REQUIREMENT_ERROR);
|
2361 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2362 |
|
|
$this->assertText('This is a requirements error provided by the update_script_test module.');
|
2363 |
|
|
$this->clickLink('try again');
|
2364 |
|
|
$this->assertText('This is a requirements error provided by the update_script_test module.');
|
2365 |
|
|
}
|
2366 |
|
|
|
2367 |
|
|
/**
|
2368 |
|
|
* Tests the effect of using the update script on the theme system.
|
2369 |
|
|
*/
|
2370 |
|
|
function testThemeSystem() {
|
2371 |
|
|
// Since visiting update.php triggers a rebuild of the theme system from an
|
2372 |
|
|
// unusual maintenance mode environment, we check that this rebuild did not
|
2373 |
|
|
// put any incorrect information about the themes into the database.
|
2374 |
|
|
$original_theme_data = db_query("SELECT * FROM {system} WHERE type = 'theme' ORDER BY name")->fetchAll();
|
2375 |
|
|
$this->drupalLogin($this->update_user);
|
2376 |
|
|
$this->drupalGet($this->update_url, array('external' => TRUE));
|
2377 |
|
|
$final_theme_data = db_query("SELECT * FROM {system} WHERE type = 'theme' ORDER BY name")->fetchAll();
|
2378 |
|
|
$this->assertEqual($original_theme_data, $final_theme_data, 'Visiting update.php does not alter the information about themes stored in the database.');
|
2379 |
|
|
}
|
2380 |
|
|
|
2381 |
|
|
/**
|
2382 |
|
|
* Tests update.php when there are no updates to apply.
|
2383 |
|
|
*/
|
2384 |
|
|
function testNoUpdateFunctionality() {
|
2385 |
|
|
// Click through update.php with 'administer software updates' permission.
|
2386 |
|
|
$this->drupalLogin($this->update_user);
|
2387 |
|
|
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
|
2388 |
|
|
$this->assertText(t('No pending updates.'));
|
2389 |
|
|
$this->assertNoLink('Administration pages');
|
2390 |
|
|
$this->clickLink('Front page');
|
2391 |
|
|
$this->assertResponse(200);
|
2392 |
|
|
|
2393 |
|
|
// Click through update.php with 'access administration pages' permission.
|
2394 |
|
|
$admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages'));
|
2395 |
|
|
$this->drupalLogin($admin_user);
|
2396 |
|
|
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
|
2397 |
|
|
$this->assertText(t('No pending updates.'));
|
2398 |
|
|
$this->clickLink('Administration pages');
|
2399 |
|
|
$this->assertResponse(200);
|
2400 |
|
|
}
|
2401 |
|
|
|
2402 |
|
|
/**
|
2403 |
|
|
* Tests update.php after performing a successful update.
|
2404 |
|
|
*/
|
2405 |
|
|
function testSuccessfulUpdateFunctionality() {
|
2406 |
|
|
drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
|
2407 |
|
|
// Click through update.php with 'administer software updates' permission.
|
2408 |
|
|
$this->drupalLogin($this->update_user);
|
2409 |
|
|
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
|
2410 |
|
|
$this->drupalPost(NULL, array(), t('Apply pending updates'));
|
2411 |
|
|
$this->assertText('Updates were attempted.');
|
2412 |
|
|
$this->assertLink('site');
|
2413 |
|
|
$this->assertNoLink('Administration pages');
|
2414 |
|
|
$this->assertNoLink('logged');
|
2415 |
|
|
$this->clickLink('Front page');
|
2416 |
|
|
$this->assertResponse(200);
|
2417 |
|
|
|
2418 |
|
|
drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
|
2419 |
|
|
// Click through update.php with 'access administration pages' and
|
2420 |
|
|
// 'access site reports' permissions.
|
2421 |
|
|
$admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages', 'access site reports'));
|
2422 |
|
|
$this->drupalLogin($admin_user);
|
2423 |
|
|
$this->drupalPost($this->update_url, array(), t('Continue'), array('external' => TRUE));
|
2424 |
|
|
$this->drupalPost(NULL, array(), t('Apply pending updates'));
|
2425 |
|
|
$this->assertText('Updates were attempted.');
|
2426 |
|
|
$this->assertLink('logged');
|
2427 |
|
|
$this->clickLink('Administration pages');
|
2428 |
|
|
$this->assertResponse(200);
|
2429 |
|
|
}
|
2430 |
|
|
}
|
2431 |
|
|
|
2432 |
|
|
/**
|
2433 |
|
|
* Functional tests for the flood control mechanism.
|
2434 |
|
|
*/
|
2435 |
|
|
class FloodFunctionalTest extends DrupalWebTestCase {
|
2436 |
|
|
public static function getInfo() {
|
2437 |
|
|
return array(
|
2438 |
|
|
'name' => 'Flood control mechanism',
|
2439 |
|
|
'description' => 'Functional tests for the flood control mechanism.',
|
2440 |
|
|
'group' => 'System',
|
2441 |
|
|
);
|
2442 |
|
|
}
|
2443 |
|
|
|
2444 |
|
|
/**
|
2445 |
|
|
* Test flood control mechanism clean-up.
|
2446 |
|
|
*/
|
2447 |
|
|
function testCleanUp() {
|
2448 |
|
|
$threshold = 1;
|
2449 |
|
|
$window_expired = -1;
|
2450 |
|
|
$name = 'flood_test_cleanup';
|
2451 |
|
|
|
2452 |
|
|
// Register expired event.
|
2453 |
|
|
flood_register_event($name, $window_expired);
|
2454 |
|
|
// Verify event is not allowed.
|
2455 |
|
|
$this->assertFalse(flood_is_allowed($name, $threshold));
|
2456 |
|
|
// Run cron and verify event is now allowed.
|
2457 |
|
|
$this->cronRun();
|
2458 |
|
|
$this->assertTrue(flood_is_allowed($name, $threshold));
|
2459 |
|
|
|
2460 |
|
|
// Register unexpired event.
|
2461 |
|
|
flood_register_event($name);
|
2462 |
|
|
// Verify event is not allowed.
|
2463 |
|
|
$this->assertFalse(flood_is_allowed($name, $threshold));
|
2464 |
|
|
// Run cron and verify event is still not allowed.
|
2465 |
|
|
$this->cronRun();
|
2466 |
|
|
$this->assertFalse(flood_is_allowed($name, $threshold));
|
2467 |
|
|
}
|
2468 |
|
|
}
|
2469 |
|
|
|
2470 |
|
|
/**
|
2471 |
|
|
* Test HTTP file downloading capability.
|
2472 |
|
|
*/
|
2473 |
|
|
class RetrieveFileTestCase extends DrupalWebTestCase {
|
2474 |
|
|
public static function getInfo() {
|
2475 |
|
|
return array(
|
2476 |
|
|
'name' => 'HTTP file retrieval',
|
2477 |
|
|
'description' => 'Checks HTTP file fetching and error handling.',
|
2478 |
|
|
'group' => 'System',
|
2479 |
|
|
);
|
2480 |
|
|
}
|
2481 |
|
|
|
2482 |
|
|
/**
|
2483 |
|
|
* Invokes system_retrieve_file() in several scenarios.
|
2484 |
|
|
*/
|
2485 |
|
|
function testFileRetrieving() {
|
2486 |
|
|
// Test 404 handling by trying to fetch a randomly named file.
|
2487 |
|
|
drupal_mkdir($sourcedir = 'public://' . $this->randomName());
|
2488 |
|
|
$filename = 'Файл для тестирования ' . $this->randomName();
|
2489 |
|
|
$url = file_create_url($sourcedir . '/' . $filename);
|
2490 |
|
|
$retrieved_file = system_retrieve_file($url);
|
2491 |
|
|
$this->assertFalse($retrieved_file, 'Non-existent file not fetched.');
|
2492 |
|
|
|
2493 |
|
|
// Actually create that file, download it via HTTP and test the returned path.
|
2494 |
|
|
file_put_contents($sourcedir . '/' . $filename, 'testing');
|
2495 |
|
|
$retrieved_file = system_retrieve_file($url);
|
2496 |
|
|
|
2497 |
|
|
// URLs could not contains characters outside the ASCII set so $filename
|
2498 |
|
|
// has to be encoded.
|
2499 |
|
|
$encoded_filename = rawurlencode($filename);
|
2500 |
|
|
|
2501 |
|
|
$this->assertEqual($retrieved_file, 'public://' . $encoded_filename, 'Sane path for downloaded file returned (public:// scheme).');
|
2502 |
|
|
$this->assertTrue(is_file($retrieved_file), 'Downloaded file does exist (public:// scheme).');
|
2503 |
|
|
$this->assertEqual(filesize($retrieved_file), 7, 'File size of downloaded file is correct (public:// scheme).');
|
2504 |
|
|
file_unmanaged_delete($retrieved_file);
|
2505 |
|
|
|
2506 |
|
|
// Test downloading file to a different location.
|
2507 |
|
|
drupal_mkdir($targetdir = 'temporary://' . $this->randomName());
|
2508 |
|
|
$retrieved_file = system_retrieve_file($url, $targetdir);
|
2509 |
|
|
$this->assertEqual($retrieved_file, "$targetdir/$encoded_filename", 'Sane path for downloaded file returned (temporary:// scheme).');
|
2510 |
|
|
$this->assertTrue(is_file($retrieved_file), 'Downloaded file does exist (temporary:// scheme).');
|
2511 |
|
|
$this->assertEqual(filesize($retrieved_file), 7, 'File size of downloaded file is correct (temporary:// scheme).');
|
2512 |
|
|
file_unmanaged_delete($retrieved_file);
|
2513 |
|
|
|
2514 |
|
|
file_unmanaged_delete_recursive($sourcedir);
|
2515 |
|
|
file_unmanaged_delete_recursive($targetdir);
|
2516 |
|
|
}
|
2517 |
|
|
}
|
2518 |
|
|
|
2519 |
|
|
/**
|
2520 |
|
|
* Functional tests shutdown functions.
|
2521 |
|
|
*/
|
2522 |
|
|
class ShutdownFunctionsTest extends DrupalWebTestCase {
|
2523 |
|
|
public static function getInfo() {
|
2524 |
|
|
return array(
|
2525 |
|
|
'name' => 'Shutdown functions',
|
2526 |
|
|
'description' => 'Functional tests for shutdown functions',
|
2527 |
|
|
'group' => 'System',
|
2528 |
|
|
);
|
2529 |
|
|
}
|
2530 |
|
|
|
2531 |
|
|
function setUp() {
|
2532 |
|
|
parent::setUp('system_test');
|
2533 |
|
|
}
|
2534 |
|
|
|
2535 |
|
|
/**
|
2536 |
|
|
* Test shutdown functions.
|
2537 |
|
|
*/
|
2538 |
|
|
function testShutdownFunctions() {
|
2539 |
|
|
$arg1 = $this->randomName();
|
2540 |
|
|
$arg2 = $this->randomName();
|
2541 |
|
|
$this->drupalGet('system-test/shutdown-functions/' . $arg1 . '/' . $arg2);
|
2542 |
|
|
$this->assertText(t('First shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2)));
|
2543 |
|
|
$this->assertText(t('Second shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2)));
|
2544 |
|
|
|
2545 |
|
|
// Make sure exceptions displayed through _drupal_render_exception_safe()
|
2546 |
|
|
// are correctly escaped.
|
2547 |
|
|
$this->assertRaw('Drupal is &lt;blink&gt;awesome&lt;/blink&gt;.');
|
2548 |
|
|
}
|
2549 |
|
|
}
|
2550 |
|
|
|
2551 |
|
|
/**
|
2552 |
|
|
* Tests administrative overview pages.
|
2553 |
|
|
*/
|
2554 |
|
|
class SystemAdminTestCase extends DrupalWebTestCase {
|
2555 |
|
|
public static function getInfo() {
|
2556 |
|
|
return array(
|
2557 |
|
|
'name' => 'Administrative pages',
|
2558 |
|
|
'description' => 'Tests output on administrative pages and compact mode functionality.',
|
2559 |
|
|
'group' => 'System',
|
2560 |
|
|
);
|
2561 |
|
|
}
|
2562 |
|
|
|
2563 |
|
|
function setUp() {
|
2564 |
|
|
// testAdminPages() requires Locale module.
|
2565 |
|
|
parent::setUp(array('locale'));
|
2566 |
|
|
|
2567 |
|
|
// Create an administrator with all permissions, as well as a regular user
|
2568 |
|
|
// who can only access administration pages and perform some Locale module
|
2569 |
|
|
// administrative tasks, but not all of them.
|
2570 |
|
|
$this->admin_user = $this->drupalCreateUser(array_keys(module_invoke_all('permission')));
|
2571 |
|
|
$this->web_user = $this->drupalCreateUser(array(
|
2572 |
|
|
'access administration pages',
|
2573 |
|
|
'translate interface',
|
2574 |
|
|
));
|
2575 |
|
|
$this->drupalLogin($this->admin_user);
|
2576 |
|
|
}
|
2577 |
|
|
|
2578 |
|
|
/**
|
2579 |
|
|
* Tests output on administrative listing pages.
|
2580 |
|
|
*/
|
2581 |
|
|
function testAdminPages() {
|
2582 |
|
|
// Go to Administration.
|
2583 |
|
|
$this->drupalGet('admin');
|
2584 |
|
|
|
2585 |
|
|
// Verify that all visible, top-level administration links are listed on
|
2586 |
|
|
// the main administration page.
|
2587 |
|
|
foreach (menu_get_router() as $path => $item) {
|
2588 |
|
|
if (strpos($path, 'admin/') === 0 && ($item['type'] & MENU_VISIBLE_IN_TREE) && $item['_number_parts'] == 2) {
|
2589 |
|
|
$this->assertLink($item['title']);
|
2590 |
|
|
$this->assertLinkByHref($path);
|
2591 |
|
|
$this->assertText($item['description']);
|
2592 |
|
|
}
|
2593 |
|
|
}
|
2594 |
|
|
|
2595 |
|
|
// For each administrative listing page on which the Locale module appears,
|
2596 |
|
|
// verify that there are links to the module's primary configuration pages,
|
2597 |
|
|
// but no links to its individual sub-configuration pages. Also verify that
|
2598 |
|
|
// a user with access to only some Locale module administration pages only
|
2599 |
|
|
// sees links to the pages they have access to.
|
2600 |
|
|
$admin_list_pages = array(
|
2601 |
|
|
'admin/index',
|
2602 |
|
|
'admin/config',
|
2603 |
|
|
'admin/config/regional',
|
2604 |
|
|
);
|
2605 |
|
|
|
2606 |
|
|
foreach ($admin_list_pages as $page) {
|
2607 |
|
|
// For the administrator, verify that there are links to Locale's primary
|
2608 |
|
|
// configuration pages, but no links to individual sub-configuration
|
2609 |
|
|
// pages.
|
2610 |
|
|
$this->drupalLogin($this->admin_user);
|
2611 |
|
|
$this->drupalGet($page);
|
2612 |
|
|
$this->assertLinkByHref('admin/config');
|
2613 |
|
|
$this->assertLinkByHref('admin/config/regional/settings');
|
2614 |
|
|
$this->assertLinkByHref('admin/config/regional/date-time');
|
2615 |
|
|
$this->assertLinkByHref('admin/config/regional/language');
|
2616 |
|
|
$this->assertNoLinkByHref('admin/config/regional/language/configure/session');
|
2617 |
|
|
$this->assertNoLinkByHref('admin/config/regional/language/configure/url');
|
2618 |
|
|
$this->assertLinkByHref('admin/config/regional/translate');
|
2619 |
|
|
// On admin/index only, the administrator should also see a "Configure
|
2620 |
|
|
// permissions" link for the Locale module.
|
2621 |
|
|
if ($page == 'admin/index') {
|
2622 |
|
|
$this->assertLinkByHref("admin/people/permissions#module-locale");
|
2623 |
|
|
}
|
2624 |
|
|
|
2625 |
|
|
// For a less privileged user, verify that there are no links to Locale's
|
2626 |
|
|
// primary configuration pages, but a link to the translate page exists.
|
2627 |
|
|
$this->drupalLogin($this->web_user);
|
2628 |
|
|
$this->drupalGet($page);
|
2629 |
|
|
$this->assertLinkByHref('admin/config');
|
2630 |
|
|
$this->assertNoLinkByHref('admin/config/regional/settings');
|
2631 |
|
|
$this->assertNoLinkByHref('admin/config/regional/date-time');
|
2632 |
|
|
$this->assertNoLinkByHref('admin/config/regional/language');
|
2633 |
|
|
$this->assertNoLinkByHref('admin/config/regional/language/configure/session');
|
2634 |
|
|
$this->assertNoLinkByHref('admin/config/regional/language/configure/url');
|
2635 |
|
|
$this->assertLinkByHref('admin/config/regional/translate');
|
2636 |
|
|
// This user cannot configure permissions, so even on admin/index should
|
2637 |
|
|
// not see a "Configure permissions" link for the Locale module.
|
2638 |
|
|
if ($page == 'admin/index') {
|
2639 |
|
|
$this->assertNoLinkByHref("admin/people/permissions#module-locale");
|
2640 |
|
|
}
|
2641 |
|
|
}
|
2642 |
|
|
}
|
2643 |
|
|
|
2644 |
|
|
/**
|
2645 |
|
|
* Test compact mode.
|
2646 |
|
|
*/
|
2647 |
|
|
function testCompactMode() {
|
2648 |
|
|
$this->drupalGet('admin/compact/on');
|
2649 |
|
|
$this->assertTrue($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'Compact mode turns on.');
|
2650 |
|
|
$this->drupalGet('admin/compact/on');
|
2651 |
|
|
$this->assertTrue($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'Compact mode remains on after a repeat call.');
|
2652 |
|
|
$this->drupalGet('');
|
2653 |
|
|
$this->assertTrue($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'Compact mode persists on new requests.');
|
2654 |
|
|
|
2655 |
|
|
$this->drupalGet('admin/compact/off');
|
2656 |
|
|
$this->assertEqual($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'deleted', 'Compact mode turns off.');
|
2657 |
|
|
$this->drupalGet('admin/compact/off');
|
2658 |
|
|
$this->assertEqual($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'deleted', 'Compact mode remains off after a repeat call.');
|
2659 |
|
|
$this->drupalGet('');
|
2660 |
|
|
$this->assertTrue($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'Compact mode persists on new requests.');
|
2661 |
|
|
}
|
2662 |
|
|
}
|
2663 |
|
|
|
2664 |
|
|
/**
|
2665 |
|
|
* Tests authorize.php and related hooks.
|
2666 |
|
|
*/
|
2667 |
|
|
class SystemAuthorizeCase extends DrupalWebTestCase {
|
2668 |
|
|
public static function getInfo() {
|
2669 |
|
|
return array(
|
2670 |
|
|
'name' => 'Authorize API',
|
2671 |
|
|
'description' => 'Tests the authorize.php script and related API.',
|
2672 |
|
|
'group' => 'System',
|
2673 |
|
|
);
|
2674 |
|
|
}
|
2675 |
|
|
|
2676 |
|
|
function setUp() {
|
2677 |
|
|
parent::setUp(array('system_test'));
|
2678 |
|
|
|
2679 |
|
|
variable_set('allow_authorize_operations', TRUE);
|
2680 |
|
|
|
2681 |
|
|
// Create an administrator user.
|
2682 |
|
|
$this->admin_user = $this->drupalCreateUser(array('administer software updates'));
|
2683 |
|
|
$this->drupalLogin($this->admin_user);
|
2684 |
|
|
}
|
2685 |
|
|
|
2686 |
|
|
/**
|
2687 |
|
|
* Helper function to initialize authorize.php and load it via drupalGet().
|
2688 |
|
|
*
|
2689 |
|
|
* Initializing authorize.php needs to happen in the child Drupal
|
2690 |
|
|
* installation, not the parent. So, we visit a menu callback provided by
|
2691 |
|
|
* system_test.module which calls system_authorized_init() to initialize the
|
2692 |
|
|
* $_SESSION inside the test site, not the framework site. This callback
|
2693 |
|
|
* redirects to authorize.php when it's done initializing.
|
2694 |
|
|
*
|
2695 |
|
|
* @see system_authorized_init().
|
2696 |
|
|
*/
|
2697 |
|
|
function drupalGetAuthorizePHP($page_title = 'system-test-auth') {
|
2698 |
|
|
$this->drupalGet('system-test/authorize-init/' . $page_title);
|
2699 |
|
|
}
|
2700 |
|
|
|
2701 |
|
|
/**
|
2702 |
|
|
* Tests the FileTransfer hooks
|
2703 |
|
|
*/
|
2704 |
|
|
function testFileTransferHooks() {
|
2705 |
|
|
$page_title = $this->randomName(16);
|
2706 |
|
|
$this->drupalGetAuthorizePHP($page_title);
|
2707 |
|
|
$this->assertTitle(strtr('@title | Drupal', array('@title' => $page_title)), 'authorize.php page title is correct.');
|
2708 |
|
|
$this->assertNoText('It appears you have reached this page in error.');
|
2709 |
|
|
$this->assertText('To continue, provide your server connection details');
|
2710 |
|
|
// Make sure we see the new connection method added by system_test.
|
2711 |
|
|
$this->assertRaw('System Test FileTransfer');
|
2712 |
|
|
// Make sure the settings form callback works.
|
2713 |
|
|
$this->assertText('System Test Username');
|
2714 |
|
|
}
|
2715 |
|
|
}
|
2716 |
|
|
|
2717 |
|
|
/**
|
2718 |
|
|
* Test the handling of requests containing 'index.php'.
|
2719 |
|
|
*/
|
2720 |
|
|
class SystemIndexPhpTest extends DrupalWebTestCase {
|
2721 |
|
|
public static function getInfo() {
|
2722 |
|
|
return array(
|
2723 |
|
|
'name' => 'Index.php handling',
|
2724 |
|
|
'description' => "Test the handling of requests containing 'index.php'.",
|
2725 |
|
|
'group' => 'System',
|
2726 |
|
|
);
|
2727 |
|
|
}
|
2728 |
|
|
|
2729 |
|
|
function setUp() {
|
2730 |
|
|
parent::setUp();
|
2731 |
|
|
}
|
2732 |
|
|
|
2733 |
|
|
/**
|
2734 |
|
|
* Test index.php handling.
|
2735 |
|
|
*/
|
2736 |
|
|
function testIndexPhpHandling() {
|
2737 |
|
|
$index_php = $GLOBALS['base_url'] . '/index.php';
|
2738 |
|
|
|
2739 |
|
|
$this->drupalGet($index_php, array('external' => TRUE));
|
2740 |
|
|
$this->assertResponse(200, 'Make sure index.php returns a valid page.');
|
2741 |
|
|
|
2742 |
|
|
$this->drupalGet($index_php, array('external' => TRUE, 'query' => array('q' => 'user')));
|
2743 |
|
|
$this->assertResponse(200, 'Make sure index.php?q=user returns a valid page.');
|
2744 |
|
|
|
2745 |
|
|
$this->drupalGet($index_php .'/user', array('external' => TRUE));
|
2746 |
|
|
$this->assertResponse(404, "Make sure index.php/user returns a 'page not found'.");
|
2747 |
|
|
}
|
2748 |
|
|
}
|
2749 |
|
|
|
2750 |
|
|
/**
|
2751 |
|
|
* Test token replacement in strings.
|
2752 |
|
|
*/
|
2753 |
|
|
class TokenScanTest extends DrupalWebTestCase {
|
2754 |
|
|
|
2755 |
|
|
public static function getInfo() {
|
2756 |
|
|
return array(
|
2757 |
|
|
'name' => 'Token scanning',
|
2758 |
|
|
'description' => 'Scan token-like patterns in a dummy text to check token scanning.',
|
2759 |
|
|
'group' => 'System',
|
2760 |
|
|
);
|
2761 |
|
|
}
|
2762 |
|
|
|
2763 |
|
|
/**
|
2764 |
|
|
* Scans dummy text, then tests the output.
|
2765 |
|
|
*/
|
2766 |
|
|
function testTokenScan() {
|
2767 |
|
|
// Define text with valid and not valid, fake and existing token-like
|
2768 |
|
|
// strings.
|
2769 |
|
|
$text = 'First a [valid:simple], but dummy token, and a dummy [valid:token with: spaces].';
|
2770 |
|
|
$text .= 'Then a [not valid:token].';
|
2771 |
|
|
$text .= 'Last an existing token: [node:author:name].';
|
2772 |
|
|
$token_wannabes = token_scan($text);
|
2773 |
|
|
|
2774 |
|
|
$this->assertTrue(isset($token_wannabes['valid']['simple']), 'A simple valid token has been matched.');
|
2775 |
|
|
$this->assertTrue(isset($token_wannabes['valid']['token with: spaces']), 'A valid token with space characters in the token name has been matched.');
|
2776 |
|
|
$this->assertFalse(isset($token_wannabes['not valid']), 'An invalid token with spaces in the token type has not been matched.');
|
2777 |
|
|
$this->assertTrue(isset($token_wannabes['node']), 'An existing valid token has been matched.');
|
2778 |
|
|
}
|
2779 |
|
|
}
|
2780 |
|
|
|
2781 |
|
|
/**
|
2782 |
|
|
* Test case for drupal_valid_token().
|
2783 |
|
|
*/
|
2784 |
|
|
class SystemValidTokenTest extends DrupalUnitTestCase {
|
2785 |
|
|
|
2786 |
|
|
/**
|
2787 |
|
|
* Flag to indicate whether PHP error reportings should be asserted.
|
2788 |
|
|
*
|
2789 |
|
|
* @var bool
|
2790 |
|
|
*/
|
2791 |
|
|
protected $assertErrors = TRUE;
|
2792 |
|
|
|
2793 |
|
|
public static function getInfo() {
|
2794 |
|
|
return array(
|
2795 |
|
|
'name' => 'Token validation',
|
2796 |
|
|
'description' => 'Test the security token validation.',
|
2797 |
|
|
'group' => 'System',
|
2798 |
|
|
);
|
2799 |
|
|
}
|
2800 |
|
|
|
2801 |
|
|
/**
|
2802 |
|
|
* Tests invalid invocations of drupal_valid_token() that must return FALSE.
|
2803 |
|
|
*/
|
2804 |
|
|
public function testTokenValidation() {
|
2805 |
|
|
// The following checks will throw PHP notices, so we disable error
|
2806 |
|
|
// assertions.
|
2807 |
|
|
$this->assertErrors = FALSE;
|
2808 |
|
|
$this->assertFalse(drupal_valid_token(NULL, new stdClass()), 'Token NULL, value object returns FALSE.');
|
2809 |
|
|
$this->assertFalse(drupal_valid_token(0, array()), 'Token 0, value array returns FALSE.');
|
2810 |
|
|
$this->assertFalse(drupal_valid_token('', array()), "Token '', value array returns FALSE.");
|
2811 |
|
|
$this->assertFalse('' === drupal_get_token(array()), 'Token generation does not return an empty string on invalid parameters.');
|
2812 |
|
|
$this->assertErrors = TRUE;
|
2813 |
|
|
|
2814 |
|
|
$this->assertFalse(drupal_valid_token(TRUE, 'foo'), 'Token TRUE, value foo returns FALSE.');
|
2815 |
|
|
$this->assertFalse(drupal_valid_token(0, 'foo'), 'Token 0, value foo returns FALSE.');
|
2816 |
|
|
}
|
2817 |
|
|
|
2818 |
|
|
/**
|
2819 |
|
|
* Overrides DrupalTestCase::errorHandler().
|
2820 |
|
|
*/
|
2821 |
|
|
public function errorHandler($severity, $message, $file = NULL, $line = NULL) {
|
2822 |
|
|
if ($this->assertErrors) {
|
2823 |
|
|
return parent::errorHandler($severity, $message, $file, $line);
|
2824 |
|
|
}
|
2825 |
|
|
return TRUE;
|
2826 |
|
|
}
|
2827 |
|
|
} |