Index: modules/simpletest/drupal_web_test_case.php =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v retrieving revision 1.206 diff -u -r1.206 drupal_web_test_case.php --- modules/simpletest/drupal_web_test_case.php 27 Mar 2010 18:32:06 -0000 1.206 +++ modules/simpletest/drupal_web_test_case.php 31 Mar 2010 19:02:00 -0000 @@ -2811,6 +2811,150 @@ } /** + * Base class used for writing atomic staging tests. + * + * The test cases are written in such a way that they can be run against a + * staging or live environment and will clean up after themselves by reverting + * all peformed actions. The tests should be performed through a set of actions + * defined in the test method. For example: + * + * protected function testFoo() { + * $this->actions[] = 'login'; + * } + * + * protected function performLogin(); + * protected function revertLogin(); + * + * + * When the variable 'simpletest_staging_url' is set the setUp() and tearDown() + * methods will not create an environment, but instead direct the internal + * browser to the staging URL. The tests will then against the specified URL + * instead of the local machine. + * + * The test can also be run against a standard development environment just as + * and other test using the DrupalCloneTestCase. If the staging ULR is not + * specified the test will attempt to clone the local development database and + * perform the actions against it. + */ +class DrupalStageTestCase extends DrupalCloneTestCase { + + /** + * URL variables that need to be changed when running against staging. + * + * @var array + */ + protected static $URL_VARIABLES = array('base_url', 'base_secure_url', 'base_insecure_url'); + + /** + * URL of the staging server if specified, otherwise FALSE. + * + * @var string + */ + protected $stagingUrl; + + /** + * Associative array of original values for the URL variables. + * + * @var array + */ + protected $originalUrls = array(); + + /** + * List of actions to perform. + * + * @var array + */ + protected $actions = array(); + + /** + * Determine when to run against staging or clone environment. + */ + protected function setUp() { + if ($this->stagingUrl = variable_get('simpletest_staging_url', FALSE)) { + // Point the internal browser to the staging site. + foreach (self::$URL_VARIABLES as $variable) { + $this->originalUrls[$variable] = $GLOBALS[$variable]; + $GLOBALS[$variable] = $this->stagingUrl; + } + $GLOBALS['base_secure_url'] = str_replace('http://', 'https://', $GLOBALS['base_secure_url']); + + // Set to that verbose mode works properly. + $this->originalFileDirectory = file_directory_path(); + } + else { + parent::setUp(); + } + } + + /** + * Perform and revert actions, then tear down based on what setUp() did. + */ + protected function tearDown() { + // Perform all actions as part of the test and revert them. + $this->performActions(); + $this->revertActions(); + + if ($this->stagingUrl) { + // Revert all URL variables to their original values. + foreach (self::$URL_VARIABLES as $variable) { + $GLOBALS[$variable] = $this->originalUrls[$variable]; + } + } + else { + parent::tearDown(); + } + } + + /** + * Perform all actions listed in the $actions array. + */ + protected function performActions() { + foreach ($this->actions as $action) { + call_user_func(array($this, 'perform' . ucfirst($action))); + } + } + + /** + * Revert all actions listed in the $actions array. + */ + protected function revertActions() { + foreach ($this->actions as $action) { + if (method_exists($this, 'revert' . ucfirst($action))) { + call_user_func(array($this, 'revert' . ucfirst($action))); + } + } + } + + /** + * Set the user agent to Drupal. + */ + protected function curlInitialize() { + parent::curlInitialize(); + curl_setopt($this->curlHandle, CURLOPT_USERAGENT, 'Drupal (+http://drupal.org/)'); + } + + /** + * Temporarily revert the global URL variables so verbose links will print. + */ + protected function verbose($message) { + if ($this->stagingUrl) { + foreach (self::$URL_VARIABLES as $variable) { + $GLOBALS[$variable] = $this->originalUrls[$variable]; + } + } + + parent::verbose($message); + + if ($this->stagingUrl) { + foreach (self::$URL_VARIABLES as $variable) { + $GLOBALS[$variable] = $this->stagingUrl; + } + $GLOBALS['base_secure_url'] = str_replace('http://', 'https://', $GLOBALS['base_secure_url']); + } + } +} + +/** * Log verbose message in a text file. * * If verbose mode is enabled then page requests will be dumped to a file and