/[drupal]/drupal/modules/update/update.test
ViewVC logotype

Contents of /drupal/modules/update/update.test

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.10 - (show annotations) (download) (as text)
Thu Oct 15 21:19:31 2009 UTC (5 weeks, 6 days ago) by webchick
Branch: MAIN
CVS Tags: DRUPAL-7-0-UNSTABLE-10, HEAD
Changes since 1.9: +1 -2 lines
File MIME type: text/x-php
#538660 by JacobSingh, dww, JoshuaRogers, adrian, Crell, chx, anarcat, and cwgordon7: Add a functioning Plugin Manager to core. Can you say module installation and updates through the UI? I knew you could! :D
1 <?php
2 // $Id: update.test,v 1.9 2009/10/13 08:02:49 webchick Exp $
3
4 /**
5 * @file
6 * This file contains tests for the update module. The overarching methodology
7 * of these tests is we need to compare a given state of installed modules and
8 * themes (e.g. version, project grouping, timestamps, etc) vs. a current
9 * state of what the release history XML files we fetch say is available. We
10 * have dummy XML files (in the 'tests' subdirectory) that describe various
11 * scenarios of what's available for different test projects, and we have
12 * dummy .info file data (specified via hook_system_info_alter() in the
13 * update_test helper module) describing what's currently installed. Each
14 * test case defines a set of projects to install, their current state (via
15 * the 'update_test_system_info' variable) and the desired availabile update
16 * data (via the 'update_test_xml_map' variable), and then performs a series
17 * of assertions that the report matches our expectations given the specific
18 * initial state and availability scenario.
19 */
20
21 /**
22 * Base class to define some shared functions used by all update tests.
23 */
24 class UpdateTestHelper extends DrupalWebTestCase {
25 /**
26 * Refresh the update status based on the desired available update scenario.
27 *
28 * @param $xml_map
29 * Array that maps project names to availability scenarios to fetch.
30 * The key '#all' is used if a project-specific mapping is not defined.
31 *
32 * @see update_test_mock_page()
33 */
34 protected function refreshUpdateStatus($xml_map) {
35 // Tell update module to fetch from the URL provided by update_test module.
36 variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
37 // Save the map for update_test_mock_page() to use.
38 variable_set('update_test_xml_map', $xml_map);
39 // Manually check the update status.
40 $this->drupalGet('admin/reports/updates/check');
41 }
42
43 /**
44 * Run a series of assertions that are applicable for all update statuses.
45 */
46 protected function standardTests() {
47 $this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
48 $this->assertRaw(l(t('Drupal'), 'http://example.com/project/drupal'), t('Link to the Drupal project appears.'));
49 $this->assertNoText(t('No available releases found'));
50 }
51
52 }
53
54 class UpdateCoreTestCase extends UpdateTestHelper {
55
56 public static function getInfo() {
57 return array(
58 'name' => 'Update core functionality',
59 'description' => 'Tests the update module through a series of functional tests using mock XML data.',
60 'group' => 'Update',
61 );
62 }
63
64 function setUp() {
65 parent::setUp('update_test', 'update');
66 $admin_user = $this->drupalCreateUser(array('administer site configuration'));
67 $this->drupalLogin($admin_user);
68 }
69
70 /**
71 * Tests the update module when no updates are available.
72 */
73 function testNoUpdatesAvailable() {
74 $this->setSystemInfo7_0();
75 $this->refreshUpdateStatus(array('drupal' => '0'));
76 $this->standardTests();
77 $this->assertText(t('Up to date'));
78 $this->assertNoText(t('Update available'));
79 $this->assertNoText(t('Security update required!'));
80 }
81
82 /**
83 * Tests the update module when one normal update ("7.1") is available.
84 */
85 function testNormalUpdateAvailable() {
86 $this->setSystemInfo7_0();
87 $this->refreshUpdateStatus(array('drupal' => '1'));
88 $this->standardTests();
89 $this->assertNoText(t('Up to date'));
90 $this->assertText(t('Update available'));
91 $this->assertNoText(t('Security update required!'));
92 $this->assertRaw(l('7.1', 'http://example.com/drupal-7-1-release'), t('Link to release appears.'));
93 $this->assertRaw(l(t('Download'), 'http://example.com/drupal-7-1.tar.gz'), t('Link to download appears.'));
94 $this->assertRaw(l(t('Release notes'), 'http://example.com/drupal-7-1-release'), t('Link to release notes appears.'));
95 }
96
97 /**
98 * Tests the update module when a security update ("7.2") is available.
99 */
100 function testSecurityUpdateAvailable() {
101 $this->setSystemInfo7_0();
102 $this->refreshUpdateStatus(array('drupal' => '2-sec'));
103 $this->standardTests();
104 $this->assertNoText(t('Up to date'));
105 $this->assertNoText(t('Update available'));
106 $this->assertText(t('Security update required!'));
107 $this->assertRaw(l('7.2', 'http://example.com/drupal-7-2-release'), t('Link to release appears.'));
108 $this->assertRaw(l(t('Download'), 'http://example.com/drupal-7-2.tar.gz'), t('Link to download appears.'));
109 $this->assertRaw(l(t('Release notes'), 'http://example.com/drupal-7-2-release'), t('Link to release notes appears.'));
110 }
111
112 /**
113 * Ensure proper results where there are date mismatches among modules.
114 */
115 function testDatestampMismatch() {
116 $system_info = array(
117 '#all' => array(
118 // We need to think we're running a -dev snapshot to see dates.
119 'version' => '7.0-dev',
120 'datestamp' => time(),
121 ),
122 'block' => array(
123 // This is 2001-09-09 01:46:40 GMT, so test for "2001-Sep-".
124 'datestamp' => '1000000000',
125 ),
126 );
127 variable_set('update_test_system_info', $system_info);
128 $this->refreshUpdateStatus(array('drupal' => 'dev'));
129 $this->assertNoText(t('2001-Sep-'));
130 $this->assertText(t('Up to date'));
131 $this->assertNoText(t('Update available'));
132 $this->assertNoText(t('Security update required!'));
133 }
134
135 /**
136 * Check the messages at admin/config/modules when the site is up to date.
137 */
138 function testModulePageUpToDate() {
139 $this->setSystemInfo7_0();
140 // Instead of using refreshUpdateStatus(), set these manually.
141 variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
142 variable_set('update_test_xml_map', array('drupal' => '0'));
143
144 $this->drupalGet('admin/config/modules');
145 $this->assertText(t('No information is available about potential new releases for currently installed modules and themes.'));
146 $this->clickLink(t('check manually'));
147 $this->assertText(t('Checked available update data for one project.'));
148 $this->assertNoText(t('There are updates available for your version of Drupal.'));
149 $this->assertNoText(t('There is a security update available for your version of Drupal.'));
150 }
151
152 /**
153 * Check the messages at admin/config/modules when missing an update.
154 */
155 function testModulePageRegularUpdate() {
156 $this->setSystemInfo7_0();
157 // Instead of using refreshUpdateStatus(), set these manually.
158 variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
159 variable_set('update_test_xml_map', array('drupal' => '1'));
160
161 $this->drupalGet('admin/config/modules');
162 $this->assertText(t('No information is available about potential new releases for currently installed modules and themes.'));
163 $this->clickLink(t('check manually'));
164 $this->assertText(t('Checked available update data for one project.'));
165 $this->assertText(t('There are updates available for your version of Drupal.'));
166 $this->assertNoText(t('There is a security update available for your version of Drupal.'));
167 }
168
169 /**
170 * Check the messages at admin/config/modules when missing a security update.
171 */
172 function testModulePageSecurityUpdate() {
173 $this->setSystemInfo7_0();
174 // Instead of using refreshUpdateStatus(), set these manually.
175 variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
176 variable_set('update_test_xml_map', array('drupal' => '2-sec'));
177
178 $this->drupalGet('admin/config/modules');
179 $this->assertText(t('No information is available about potential new releases for currently installed modules and themes.'));
180 $this->clickLink(t('check manually'));
181 $this->assertText(t('Checked available update data for one project.'));
182 $this->assertNoText(t('There are updates available for your version of Drupal.'));
183 $this->assertText(t('There is a security update available for your version of Drupal.'));
184 }
185
186 protected function setSystemInfo7_0() {
187 $setting = array(
188 '#all' => array(
189 'version' => '7.0',
190 ),
191 );
192 variable_set('update_test_system_info', $setting);
193 }
194
195 }
196
197 class UpdateTestContribCase extends UpdateTestHelper {
198
199 public static function getInfo() {
200 return array(
201 'name' => 'Update contrib functionality',
202 'description' => 'Tests how the update module handles contributed modules and themes in a series of functional tests using mock XML data.',
203 'group' => 'Update',
204 );
205 }
206
207 function setUp() {
208 parent::setUp('update_test', 'update', 'aaa_update_test', 'bbb_update_test', 'ccc_update_test');
209 $admin_user = $this->drupalCreateUser(array('administer site configuration'));
210 $this->drupalLogin($admin_user);
211 }
212
213 /**
214 * Tests when there is no available release data for a contrib module.
215 */
216 function testNoReleasesAvailable() {
217 $system_info = array(
218 '#all' => array(
219 'version' => '7.0',
220 ),
221 'aaa_update_test' => array(
222 'project' => 'aaa_update_test',
223 'version' => '7.x-1.0',
224 'hidden' => FALSE,
225 ),
226 );
227 variable_set('update_test_system_info', $system_info);
228 $this->refreshUpdateStatus(array('drupal' => '0', 'aaa_update_test' => 'no-releases'));
229 $this->drupalGet('admin/reports/updates');
230 // Cannot use $this->standardTests() because we need to check for the
231 // 'No available releases found' string.
232 $this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
233 $this->assertRaw(l(t('Drupal'), 'http://example.com/project/drupal'));
234 $this->assertText(t('Up to date'));
235 $this->assertRaw('<h3>' . t('Modules') . '</h3>');
236 $this->assertNoText(t('Update available'));
237 $this->assertText(t('No available releases found'));
238 $this->assertNoRaw(l(t('AAA Update test'), 'http://example.com/project/aaa_update_test'));
239 }
240
241 /**
242 * Test the basic functionality of a contrib module on the status report.
243 */
244 function testUpdateContribBasic() {
245 $system_info = array(
246 '#all' => array(
247 'version' => '7.0',
248 ),
249 'aaa_update_test' => array(
250 'project' => 'aaa_update_test',
251 'version' => '7.x-1.0',
252 'hidden' => FALSE,
253 ),
254 );
255 variable_set('update_test_system_info', $system_info);
256 $this->refreshUpdateStatus(
257 array(
258 'drupal' => '0',
259 'aaa_update_test' => '1_0',
260 )
261 );
262 $this->standardTests();
263 $this->assertText(t('Up to date'));
264 $this->assertRaw('<h3>' . t('Modules') . '</h3>');
265 $this->assertNoText(t('Update available'));
266 $this->assertRaw(l(t('AAA Update test'), 'http://example.com/project/aaa_update_test'), t('Link to aaa_update_test project appears.'));
267 }
268
269 /**
270 * Test that contrib projects are ordered by project name.
271 *
272 * If a project contains multiple modules, we want to make sure that the
273 * available updates report is sorted by the parent project names, not by
274 * the names of the modules included in each project. In this test case, we
275 * have 2 contrib projects, "BBB Update test" and "CCC Update test".
276 * However, we have a module called "aaa_update_test" that's part of the
277 * "CCC Update test" project. We need to make sure that we see the "BBB"
278 * project before the "CCC" project, even though "CCC" includes a module
279 * that's processed first if you sort alphabetically by module name (which
280 * is the order we see things inside system_rebuild_module_data() for example).
281 */
282 function testUpdateContribOrder() {
283 // We want core to be version 7.0.
284 $system_info = array(
285 '#all' => array(
286 'version' => '7.0',
287 ),
288 // All the rest should be visible as contrib modules at version 7.x-1.0.
289
290 // aaa_update_test needs to be part of the "CCC Update test" project,
291 // which would throw off the report if we weren't properly sorting by
292 // the project names.
293 'aaa_update_test' => array(
294 'project' => 'ccc_update_test',
295 'version' => '7.x-1.0',
296 'hidden' => FALSE,
297 ),
298
299 // This should be its own project, and listed first on the report.
300 'bbb_update_test' => array(
301 'project' => 'bbb_update_test',
302 'version' => '7.x-1.0',
303 'hidden' => FALSE,
304 ),
305
306 // This will contain both aaa_update_test and ccc_update_test, and
307 // should come after the bbb_update_test project.
308 'ccc_update_test' => array(
309 'project' => 'ccc_update_test',
310 'version' => '7.x-1.0',
311 'hidden' => FALSE,
312 ),
313 );
314 variable_set('update_test_system_info', $system_info);
315 $this->refreshUpdateStatus(array('drupal' => '0', '#all' => '1_0'));
316 $this->standardTests();
317 // We're expecting the report to say all projects are up to date.
318 $this->assertText(t('Up to date'));
319 $this->assertNoText(t('Update available'));
320 // We want to see all 3 module names listed, since they'll show up either
321 // as project names or as modules under the "Includes" listing.
322 $this->assertText(t('AAA Update test'));
323 $this->assertText(t('BBB Update test'));
324 $this->assertText(t('CCC Update test'));
325 // We want aaa_update_test included in the ccc_update_test project, not as
326 // its own project on the report.
327 $this->assertNoRaw(l(t('AAA Update test'), 'http://example.com/project/aaa_update_test'), t('Link to aaa_update_test project does not appear.'));
328 // The other two should be listed as projects.
329 $this->assertRaw(l(t('BBB Update test'), 'http://example.com/project/bbb_update_test'), t('Link to bbb_update_test project appears.'));
330 $this->assertRaw(l(t('CCC Update test'), 'http://example.com/project/ccc_update_test'), t('Link to bbb_update_test project appears.'));
331
332 // We want to make sure we see the BBB project before the CCC project.
333 // Instead of just searching for 'BBB Update test' or something, we want
334 // to use the full markup that starts the project entry itself, so that
335 // we're really testing that the project listings are in the right order.
336 $bbb_project_link = '<div class="project"><a href="http://example.com/project/bbb_update_test">BBB Update test</a>';
337 $ccc_project_link = '<div class="project"><a href="http://example.com/project/ccc_update_test">CCC Update test</a>';
338 $this->assertTrue(strpos($this->drupalGetContent(), $bbb_project_link) < strpos($this->drupalGetContent(), $ccc_project_link), "'BBB Update test' project is listed before the 'CCC Update test' project");
339 }
340
341 /**
342 * Test that subthemes are notified about security updates for base themes.
343 */
344 function testUpdateBaseThemeSecurityUpdate() {
345 // Only enable the subtheme, not the base theme.
346 db_update('system')
347 ->fields(array('status' => 1))
348 ->condition('type', 'theme')
349 ->condition('name', 'update_test_subtheme')
350 ->execute();
351
352 // Define the initial state for core and the subtheme.
353 $system_info = array(
354 // We want core to be version 7.0.
355 '#all' => array(
356 'version' => '7.0',
357 ),
358 // Show the update_test_basetheme
359 'update_test_basetheme' => array(
360 'project' => 'update_test_basetheme',
361 'version' => '7.x-1.0',
362 'hidden' => FALSE,
363 ),
364 // Show the update_test_subtheme
365 'update_test_subtheme' => array(
366 'project' => 'update_test_subtheme',
367 'version' => '7.x-1.0',
368 'hidden' => FALSE,
369 ),
370 );
371 variable_set('update_test_system_info', $system_info);
372 $xml_mapping = array(
373 'drupal' => '0',
374 'update_test_subtheme' => '1_0',
375 'update_test_basetheme' => '1_1-sec',
376 );
377 $this->refreshUpdateStatus($xml_mapping);
378 $this->assertText(t('Security update required!'));
379 $this->assertRaw(l(t('Update test base theme'), 'http://example.com/project/update_test_basetheme'), t('Link to the Update test base theme project appears.'));
380 }
381
382 /**
383 * Test that disabled themes are only shown when desired.
384 */
385 function testUpdateShowDisabledThemes() {
386 // Make sure all the update_test_* themes are disabled.
387 db_update('system')
388 ->fields(array('status' => 0))
389 ->condition('type', 'theme')
390 ->condition('name', 'update_test_%', 'LIKE')
391 ->execute();
392
393 // Define the initial state for core and the test contrib themes.
394 $system_info = array(
395 // We want core to be version 7.0.
396 '#all' => array(
397 'version' => '7.0',
398 ),
399 // The update_test_basetheme should be visible and up to date.
400 'update_test_basetheme' => array(
401 'project' => 'update_test_basetheme',
402 'version' => '7.x-1.1',
403 'hidden' => FALSE,
404 ),
405 // The update_test_subtheme should be visible and up to date.
406 'update_test_subtheme' => array(
407 'project' => 'update_test_subtheme',
408 'version' => '7.x-1.0',
409 'hidden' => FALSE,
410 ),
411 );
412 variable_set('update_test_system_info', $system_info);
413 $xml_mapping = array(
414 'drupal' => '0',
415 'update_test_subtheme' => '1_0',
416 'update_test_basetheme' => '1_1-sec',
417 );
418 $base_theme_project_link = l(t('Update test base theme'), 'http://example.com/project/update_test_basetheme');
419 $sub_theme_project_link = l(t('Update test subtheme'), 'http://example.com/project/update_test_subtheme');
420 foreach (array(TRUE, FALSE) as $check_disabled) {
421 variable_set('update_check_disabled', $check_disabled);
422 $this->refreshUpdateStatus($xml_mapping);
423 // In neither case should we see the "Themes" heading for enabled themes.
424 $this->assertNoText(t('Themes'));
425 if ($check_disabled) {
426 $this->assertText(t('Disabled themes'));
427 $this->assertRaw($base_theme_project_link, t('Link to the Update test base theme project appears.'));
428 $this->assertRaw($sub_theme_project_link, t('Link to the Update test subtheme project appears.'));
429 }
430 else {
431 $this->assertNoText(t('Disabled themes'));
432 $this->assertNoRaw($base_theme_project_link, t('Link to the Update test base theme project does not appear.'));
433 $this->assertNoRaw($sub_theme_project_link, t('Link to the Update test subtheme project does not appear.'));
434 }
435 }
436 }
437
438 /**
439 * Make sure that if we fetch from a broken URL, sane things happen.
440 */
441 function testUpdateBrokenFetchURL() {
442 $system_info = array(
443 '#all' => array(
444 'version' => '7.0',
445 ),
446 'aaa_update_test' => array(
447 'project' => 'aaa_update_test',
448 'version' => '7.x-1.0',
449 'hidden' => FALSE,
450 ),
451 'bbb_update_test' => array(
452 'project' => 'bbb_update_test',
453 'version' => '7.x-1.0',
454 'hidden' => FALSE,
455 ),
456 'ccc_update_test' => array(
457 'project' => 'ccc_update_test',
458 'version' => '7.x-1.0',
459 'hidden' => FALSE,
460 ),
461 );
462 variable_set('update_test_system_info', $system_info);
463
464 $xml_mapping = array(
465 'drupal' => '0',
466 'aaa_update_test' => '1_0',
467 'bbb_update_test' => 'does-not-exist',
468 'ccc_update_test' => '1_0',
469 );
470 $this->refreshUpdateStatus($xml_mapping);
471
472 $this->assertText(t('Up to date'));
473 // We're expecting the report to say most projects are up to date, so we
474 // hope that 'Up to date' is not unique.
475 $this->assertNoUniqueText(t('Up to date'));
476 // It should say we failed to get data, not that we're missing an update.
477 $this->assertNoText(t('Update available'));
478
479 // We need to check that this string is found as part of a project row,
480 // not just in the "Failed to get available update data for ..." message
481 // at the top of the page.
482 $this->assertRaw('<div class="version-status">' . t('Failed to get available update data'));
483
484 // We should see the output messages from fetching manually.
485 $this->assertUniqueText(t('Checked available update data for 3 projects.'));
486 $this->assertUniqueText(t('Failed to get available update data for one project.'));
487
488 // The other two should be listed as projects.
489 $this->assertRaw(l(t('AAA Update test'), 'http://example.com/project/aaa_update_test'), t('Link to aaa_update_test project appears.'));
490 $this->assertNoRaw(l(t('BBB Update test'), 'http://example.com/project/bbb_update_test'), t('Link to bbb_update_test project does not appear.'));
491 $this->assertRaw(l(t('CCC Update test'), 'http://example.com/project/ccc_update_test'), t('Link to bbb_update_test project appears.'));
492 }
493
494 }
495

  ViewVC Help
Powered by ViewVC 1.1.2