cms/drupal/modules/simpletest/simpletest.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Tests for simpletest.module.
       
     6  */
       
     7 
       
     8 class SimpleTestFunctionalTest extends DrupalWebTestCase {
       
     9   /**
       
    10    * The results array that has been parsed by getTestResults().
       
    11    */
       
    12   protected $childTestResults;
       
    13 
       
    14   /**
       
    15    * Store the test ID from each test run for comparison, to ensure they are
       
    16    * incrementing.
       
    17    */
       
    18   protected $test_ids = array();
       
    19 
       
    20   public static function getInfo() {
       
    21     return array(
       
    22       'name' => 'SimpleTest functionality',
       
    23       'description' => "Test SimpleTest's web interface: check that the intended tests were run and ensure that test reports display the intended results. Also test SimpleTest's internal browser and API's both explicitly and implicitly.",
       
    24       'group' => 'SimpleTest'
       
    25     );
       
    26   }
       
    27 
       
    28   function setUp() {
       
    29     if (!$this->inCURL()) {
       
    30       parent::setUp('simpletest');
       
    31 
       
    32       // Create and login user
       
    33       $admin_user = $this->drupalCreateUser(array('administer unit tests'));
       
    34       $this->drupalLogin($admin_user);
       
    35     }
       
    36     else {
       
    37       parent::setUp('non_existent_module');
       
    38     }
       
    39   }
       
    40 
       
    41   /**
       
    42    * Test the internal browsers functionality.
       
    43    */
       
    44   function testInternalBrowser() {
       
    45     global $conf;
       
    46     if (!$this->inCURL()) {
       
    47       $this->drupalGet('node');
       
    48       $this->assertTrue($this->drupalGetHeader('Date'), 'An HTTP header was received.');
       
    49       $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), 'Site title matches.');
       
    50       $this->assertNoTitle('Foo', 'Site title does not match.');
       
    51       // Make sure that we are locked out of the installer when prefixing
       
    52       // using the user-agent header. This is an important security check.
       
    53       global $base_url;
       
    54 
       
    55       $this->drupalGet($base_url . '/install.php', array('external' => TRUE));
       
    56       $this->assertResponse(403, 'Cannot access install.php with a "simpletest" user-agent header.');
       
    57 
       
    58       $user = $this->drupalCreateUser();
       
    59       $this->drupalLogin($user);
       
    60       $headers = $this->drupalGetHeaders(TRUE);
       
    61       $this->assertEqual(count($headers), 2, 'There was one intermediate request.');
       
    62       $this->assertTrue(strpos($headers[0][':status'], '302') !== FALSE, 'Intermediate response code was 302.');
       
    63       $this->assertFalse(empty($headers[0]['location']), 'Intermediate request contained a Location header.');
       
    64       $this->assertEqual($this->getUrl(), $headers[0]['location'], 'HTTP redirect was followed');
       
    65       $this->assertFalse($this->drupalGetHeader('Location'), 'Headers from intermediate request were reset.');
       
    66       $this->assertResponse(200, 'Response code from intermediate request was reset.');
       
    67 
       
    68       // Test the maximum redirection option.
       
    69       $this->drupalLogout();
       
    70       $edit = array(
       
    71         'name' => $user->name,
       
    72         'pass' => $user->pass_raw
       
    73       );
       
    74       variable_set('simpletest_maximum_redirects', 1);
       
    75       $this->drupalPost('user?destination=user/logout', $edit, t('Log in'));
       
    76       $headers = $this->drupalGetHeaders(TRUE);
       
    77       $this->assertEqual(count($headers), 2, 'Simpletest stopped following redirects after the first one.');
       
    78     }
       
    79   }
       
    80 
       
    81   /**
       
    82    * Test validation of the User-Agent header we use to perform test requests.
       
    83    */
       
    84   function testUserAgentValidation() {
       
    85     if (!$this->inCURL()) {
       
    86       global $base_url;
       
    87       $simpletest_path = $base_url . '/' . drupal_get_path('module', 'simpletest');
       
    88       $HTTP_path = $simpletest_path .'/tests/http.php?q=node';
       
    89       $https_path = $simpletest_path .'/tests/https.php?q=node';
       
    90       // Generate a valid simpletest User-Agent to pass validation.
       
    91       $this->assertTrue(preg_match('/simpletest\d+/', $this->databasePrefix, $matches), 'Database prefix contains simpletest prefix.');
       
    92       $test_ua = drupal_generate_test_ua($matches[0]);
       
    93       $this->additionalCurlOptions = array(CURLOPT_USERAGENT => $test_ua);
       
    94 
       
    95       // Test pages only available for testing.
       
    96       $this->drupalGet($HTTP_path);
       
    97       $this->assertResponse(200, 'Requesting http.php with a legitimate simpletest User-Agent returns OK.');
       
    98       $this->drupalGet($https_path);
       
    99       $this->assertResponse(200, 'Requesting https.php with a legitimate simpletest User-Agent returns OK.');
       
   100 
       
   101       // Now slightly modify the HMAC on the header, which should not validate.
       
   102       $this->additionalCurlOptions = array(CURLOPT_USERAGENT => $test_ua . 'X');
       
   103       $this->drupalGet($HTTP_path);
       
   104       $this->assertResponse(403, 'Requesting http.php with a bad simpletest User-Agent fails.');
       
   105       $this->drupalGet($https_path);
       
   106       $this->assertResponse(403, 'Requesting https.php with a bad simpletest User-Agent fails.');
       
   107 
       
   108       // Use a real User-Agent and verify that the special files http.php and
       
   109       // https.php can't be accessed.
       
   110       $this->additionalCurlOptions = array(CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12');
       
   111       $this->drupalGet($HTTP_path);
       
   112       $this->assertResponse(403, 'Requesting http.php with a normal User-Agent fails.');
       
   113       $this->drupalGet($https_path);
       
   114       $this->assertResponse(403, 'Requesting https.php with a normal User-Agent fails.');
       
   115     }
       
   116   }
       
   117 
       
   118   /**
       
   119    * Make sure that tests selected through the web interface are run and
       
   120    * that the results are displayed correctly.
       
   121    */
       
   122   function testWebTestRunner() {
       
   123     $this->pass = t('SimpleTest pass.');
       
   124     $this->fail = t('SimpleTest fail.');
       
   125     $this->valid_permission = 'access content';
       
   126     $this->invalid_permission = 'invalid permission';
       
   127 
       
   128     if ($this->inCURL()) {
       
   129       // Only run following code if this test is running itself through a CURL request.
       
   130       $this->stubTest();
       
   131     }
       
   132     else {
       
   133 
       
   134       // Run twice so test_ids can be accumulated.
       
   135       for ($i = 0; $i < 2; $i++) {
       
   136         // Run this test from web interface.
       
   137         $this->drupalGet('admin/config/development/testing');
       
   138 
       
   139         $edit = array();
       
   140         $edit['SimpleTestFunctionalTest'] = TRUE;
       
   141         $this->drupalPost(NULL, $edit, t('Run tests'));
       
   142 
       
   143         // Parse results and confirm that they are correct.
       
   144         $this->getTestResults();
       
   145         $this->confirmStubTestResults();
       
   146       }
       
   147 
       
   148       // Regression test for #290316.
       
   149       // Check that test_id is incrementing.
       
   150       $this->assertTrue($this->test_ids[0] != $this->test_ids[1], 'Test ID is incrementing.');
       
   151     }
       
   152   }
       
   153 
       
   154   /**
       
   155    * Test to be run and the results confirmed.
       
   156    */
       
   157   function stubTest() {
       
   158     $this->pass($this->pass);
       
   159     $this->fail($this->fail);
       
   160 
       
   161     $this->drupalCreateUser(array($this->valid_permission));
       
   162     $this->drupalCreateUser(array($this->invalid_permission));
       
   163 
       
   164     $this->pass(t('Test ID is @id.', array('@id' => $this->testId)));
       
   165 
       
   166     // Generates a warning.
       
   167     $i = 1 / 0;
       
   168 
       
   169     // Call an assert function specific to that class.
       
   170     $this->assertNothing();
       
   171 
       
   172     // Generates a warning inside a PHP function.
       
   173     array_key_exists(NULL, NULL);
       
   174 
       
   175     debug('Foo', 'Debug');
       
   176   }
       
   177 
       
   178   /**
       
   179    * Assert nothing.
       
   180    */
       
   181   function assertNothing() {
       
   182     $this->pass("This is nothing.");
       
   183   }
       
   184 
       
   185   /**
       
   186    * Confirm that the stub test produced the desired results.
       
   187    */
       
   188   function confirmStubTestResults() {
       
   189     $this->assertAssertion(t('Enabled modules: %modules', array('%modules' => 'non_existent_module')), 'Other', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->setUp()');
       
   190 
       
   191     $this->assertAssertion($this->pass, 'Other', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   192     $this->assertAssertion($this->fail, 'Other', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   193 
       
   194     $this->assertAssertion(t('Created permissions: @perms', array('@perms' => $this->valid_permission)), 'Role', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   195     $this->assertAssertion(t('Invalid permission %permission.', array('%permission' => $this->invalid_permission)), 'Role', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   196 
       
   197     // Check that a warning is caught by simpletest.
       
   198     $this->assertAssertion('Division by zero', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   199 
       
   200     // Check that the backtracing code works for specific assert function.
       
   201     $this->assertAssertion('This is nothing.', 'Other', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   202 
       
   203     // Check that errors that occur inside PHP internal functions are correctly reported.
       
   204     // The exact error message differs between PHP versions so we check only
       
   205     // the function name 'array_key_exists'.
       
   206     $this->assertAssertion('array_key_exists', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   207 
       
   208     $this->assertAssertion("Debug: 'Foo'", 'Debug', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
       
   209 
       
   210     $this->assertEqual('6 passes, 5 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct');
       
   211 
       
   212     $this->test_ids[] = $test_id = $this->getTestIdFromResults();
       
   213     $this->assertTrue($test_id, 'Found test ID in results.');
       
   214   }
       
   215 
       
   216   /**
       
   217    * Fetch the test id from the test results.
       
   218    */
       
   219   function getTestIdFromResults() {
       
   220     foreach ($this->childTestResults['assertions'] as $assertion) {
       
   221       if (preg_match('@^Test ID is ([0-9]*)\.$@', $assertion['message'], $matches)) {
       
   222         return $matches[1];
       
   223       }
       
   224     }
       
   225     return NULL;
       
   226   }
       
   227 
       
   228   /**
       
   229    * Assert that an assertion with the specified values is displayed
       
   230    * in the test results.
       
   231    *
       
   232    * @param string $message Assertion message.
       
   233    * @param string $type Assertion type.
       
   234    * @param string $status Assertion status.
       
   235    * @param string $file File where the assertion originated.
       
   236    * @param string $functuion Function where the assertion originated.
       
   237    * @return Assertion result.
       
   238    */
       
   239   function assertAssertion($message, $type, $status, $file, $function) {
       
   240     $message = trim(strip_tags($message));
       
   241     $found = FALSE;
       
   242     foreach ($this->childTestResults['assertions'] as $assertion) {
       
   243       if ((strpos($assertion['message'], $message) !== FALSE) &&
       
   244           $assertion['type'] == $type &&
       
   245           $assertion['status'] == $status &&
       
   246           $assertion['file'] == $file &&
       
   247           $assertion['function'] == $function) {
       
   248         $found = TRUE;
       
   249         break;
       
   250       }
       
   251     }
       
   252     return $this->assertTrue($found, format_string('Found assertion {"@message", "@type", "@status", "@file", "@function"}.', array('@message' => $message, '@type' => $type, '@status' => $status, "@file" => $file, "@function" => $function)));
       
   253   }
       
   254 
       
   255   /**
       
   256    * Get the results from a test and store them in the class array $results.
       
   257    */
       
   258   function getTestResults() {
       
   259     $results = array();
       
   260     if ($this->parse()) {
       
   261       if ($fieldset = $this->getResultFieldSet()) {
       
   262         // Code assumes this is the only test in group.
       
   263         $results['summary'] = $this->asText($fieldset->div->div[1]);
       
   264         $results['name'] = $this->asText($fieldset->legend);
       
   265 
       
   266         $results['assertions'] = array();
       
   267         $tbody = $fieldset->div->table->tbody;
       
   268         foreach ($tbody->tr as $row) {
       
   269           $assertion = array();
       
   270           $assertion['message'] = $this->asText($row->td[0]);
       
   271           $assertion['type'] = $this->asText($row->td[1]);
       
   272           $assertion['file'] = $this->asText($row->td[2]);
       
   273           $assertion['line'] = $this->asText($row->td[3]);
       
   274           $assertion['function'] = $this->asText($row->td[4]);
       
   275           $ok_url = file_create_url('misc/watchdog-ok.png');
       
   276           $assertion['status'] = ($row->td[5]->img['src'] == $ok_url) ? 'Pass' : 'Fail';
       
   277           $results['assertions'][] = $assertion;
       
   278         }
       
   279       }
       
   280     }
       
   281     $this->childTestResults = $results;
       
   282   }
       
   283 
       
   284   /**
       
   285    * Get the fieldset containing the results for group this test is in.
       
   286    */
       
   287   function getResultFieldSet() {
       
   288     $fieldsets = $this->xpath('//fieldset');
       
   289     $info = $this->getInfo();
       
   290     foreach ($fieldsets as $fieldset) {
       
   291       if ($this->asText($fieldset->legend) == $info['name']) {
       
   292         return $fieldset;
       
   293       }
       
   294     }
       
   295     return FALSE;
       
   296   }
       
   297 
       
   298   /**
       
   299    * Extract the text contained by the element.
       
   300    *
       
   301    * @param $element
       
   302    *   Element to extract text from.
       
   303    * @return
       
   304    *   Extracted text.
       
   305    */
       
   306   function asText(SimpleXMLElement $element) {
       
   307     if (!is_object($element)) {
       
   308       return $this->fail('The element is not an element.');
       
   309     }
       
   310     return trim(html_entity_decode(strip_tags($element->asXML())));
       
   311   }
       
   312 
       
   313   /**
       
   314    * Check if the test is being run from inside a CURL request.
       
   315    */
       
   316   function inCURL() {
       
   317     return (bool) drupal_valid_test_ua();
       
   318   }
       
   319 }
       
   320 
       
   321 /**
       
   322  * Test internal testing framework browser.
       
   323  */
       
   324 class SimpleTestBrowserTestCase extends DrupalWebTestCase {
       
   325 
       
   326   /**
       
   327    * A flag indicating whether a cookie has been set in a test.
       
   328    *
       
   329    * @var bool
       
   330    */
       
   331   protected static $cookieSet = FALSE;
       
   332 
       
   333   public static function getInfo() {
       
   334     return array(
       
   335       'name' => 'SimpleTest browser',
       
   336       'description' => 'Test the internal browser of the testing framework.',
       
   337       'group' => 'SimpleTest',
       
   338     );
       
   339   }
       
   340 
       
   341   function setUp() {
       
   342     parent::setUp();
       
   343     variable_set('user_register', USER_REGISTER_VISITORS);
       
   344   }
       
   345 
       
   346   /**
       
   347    * Test DrupalWebTestCase::getAbsoluteUrl().
       
   348    */
       
   349   function testGetAbsoluteUrl() {
       
   350     // Testbed runs with Clean URLs disabled, so disable it here.
       
   351     variable_set('clean_url', 0);
       
   352     $url = 'user/login';
       
   353 
       
   354     $this->drupalGet($url);
       
   355     $absolute = url($url, array('absolute' => TRUE));
       
   356     $this->assertEqual($absolute, $this->url, 'Passed and requested URL are equal.');
       
   357     $this->assertEqual($this->url, $this->getAbsoluteUrl($this->url), 'Requested and returned absolute URL are equal.');
       
   358 
       
   359     $this->drupalPost(NULL, array(), t('Log in'));
       
   360     $this->assertEqual($absolute, $this->url, 'Passed and requested URL are equal.');
       
   361     $this->assertEqual($this->url, $this->getAbsoluteUrl($this->url), 'Requested and returned absolute URL are equal.');
       
   362 
       
   363     $this->clickLink('Create new account');
       
   364     $url = 'user/register';
       
   365     $absolute = url($url, array('absolute' => TRUE));
       
   366     $this->assertEqual($absolute, $this->url, 'Passed and requested URL are equal.');
       
   367     $this->assertEqual($this->url, $this->getAbsoluteUrl($this->url), 'Requested and returned absolute URL are equal.');
       
   368   }
       
   369 
       
   370   /**
       
   371    * Tests XPath escaping.
       
   372    */
       
   373   function testXPathEscaping() {
       
   374     $testpage = <<< EOF
       
   375 <html>
       
   376 <body>
       
   377 <a href="link1">A "weird" link, just to bother the dumb "XPath 1.0"</a>
       
   378 <a href="link2">A second "even more weird" link, in memory of George O'Malley</a>
       
   379 </body>
       
   380 </html>
       
   381 EOF;
       
   382     $this->drupalSetContent($testpage);
       
   383 
       
   384     // Matches the first link.
       
   385     $urls = $this->xpath('//a[text()=:text]', array(':text' => 'A "weird" link, just to bother the dumb "XPath 1.0"'));
       
   386     $this->assertEqual($urls[0]['href'], 'link1', 'Match with quotes.');
       
   387 
       
   388     $urls = $this->xpath('//a[text()=:text]', array(':text' => 'A second "even more weird" link, in memory of George O\'Malley'));
       
   389     $this->assertEqual($urls[0]['href'], 'link2', 'Match with mixed single and double quotes.');
       
   390   }
       
   391 
       
   392   /**
       
   393    * Tests that cookies set during a request are available for testing.
       
   394    */
       
   395   public function testCookies() {
       
   396     // Check that the $this->cookies property is populated when a user logs in.
       
   397     $user = $this->drupalCreateUser();
       
   398     $edit = array('name' => $user->name, 'pass' => $user->pass_raw);
       
   399     $this->drupalPost('<front>', $edit, t('Log in'));
       
   400     $this->assertEqual(count($this->cookies), 1, 'A cookie is set when the user logs in.');
       
   401 
       
   402     // Check that the name and value of the cookie match the request data.
       
   403     $cookie_header = $this->drupalGetHeader('set-cookie', TRUE);
       
   404 
       
   405     // The name and value are located at the start of the string, separated by
       
   406     // an equals sign and ending in a semicolon.
       
   407     preg_match('/^([^=]+)=([^;]+)/', $cookie_header, $matches);
       
   408     $name = $matches[1];
       
   409     $value = $matches[2];
       
   410 
       
   411     $this->assertTrue(array_key_exists($name, $this->cookies), 'The cookie name is correct.');
       
   412     $this->assertEqual($value, $this->cookies[$name]['value'], 'The cookie value is correct.');
       
   413 
       
   414     // Set a flag indicating that a cookie has been set in this test.
       
   415     // @see SimpleTestBrowserTestCase::testCookieDoesNotBleed().
       
   416     self::$cookieSet = TRUE;
       
   417   }
       
   418 
       
   419   /**
       
   420    * Tests that the cookies from a previous test do not bleed into a new test.
       
   421    *
       
   422    * @see SimpleTestBrowserTestCase::testCookies().
       
   423    */
       
   424   public function testCookieDoesNotBleed() {
       
   425     // In order for this test to be effective it should always run after the
       
   426     // testCookies() test.
       
   427     $this->assertTrue(self::$cookieSet, 'Tests have been executed in the expected order.');
       
   428     $this->assertEqual(count($this->cookies), 0, 'No cookies are present at the start of a new test.');
       
   429   }
       
   430 
       
   431 }
       
   432 
       
   433 class SimpleTestMailCaptureTestCase extends DrupalWebTestCase {
       
   434   /**
       
   435    * Implement getInfo().
       
   436    */
       
   437   public static function getInfo() {
       
   438     return array(
       
   439       'name' => 'SimpleTest e-mail capturing',
       
   440       'description' => 'Test the SimpleTest e-mail capturing logic, the assertMail assertion and the drupalGetMails function.',
       
   441       'group' => 'SimpleTest',
       
   442     );
       
   443   }
       
   444 
       
   445   /**
       
   446    * Test to see if the wrapper function is executed correctly.
       
   447    */
       
   448   function testMailSend() {
       
   449     // Create an e-mail.
       
   450     $subject = $this->randomString(64);
       
   451     $body = $this->randomString(128);
       
   452     $message = array(
       
   453       'id' => 'drupal_mail_test',
       
   454       'headers' => array('Content-type'=> 'text/html'),
       
   455       'subject' => $subject,
       
   456       'to' => 'foobar@example.com',
       
   457       'body' => $body,
       
   458     );
       
   459 
       
   460     // Before we send the e-mail, drupalGetMails should return an empty array.
       
   461     $captured_emails = $this->drupalGetMails();
       
   462     $this->assertEqual(count($captured_emails), 0, 'The captured e-mails queue is empty.', 'E-mail');
       
   463 
       
   464     // Send the e-mail.
       
   465     $response = drupal_mail_system('simpletest', 'drupal_mail_test')->mail($message);
       
   466 
       
   467     // Ensure that there is one e-mail in the captured e-mails array.
       
   468     $captured_emails = $this->drupalGetMails();
       
   469     $this->assertEqual(count($captured_emails), 1, 'One e-mail was captured.', 'E-mail');
       
   470 
       
   471     // Assert that the e-mail was sent by iterating over the message properties
       
   472     // and ensuring that they are captured intact.
       
   473     foreach ($message as $field => $value) {
       
   474       $this->assertMail($field, $value, format_string('The e-mail was sent and the value for property @field is intact.', array('@field' => $field)), 'E-mail');
       
   475     }
       
   476 
       
   477     // Send additional e-mails so more than one e-mail is captured.
       
   478     for ($index = 0; $index < 5; $index++) {
       
   479       $message = array(
       
   480         'id' => 'drupal_mail_test_' . $index,
       
   481         'headers' => array('Content-type'=> 'text/html'),
       
   482         'subject' => $this->randomString(64),
       
   483         'to' => $this->randomName(32) . '@example.com',
       
   484         'body' => $this->randomString(512),
       
   485       );
       
   486       drupal_mail_system('drupal_mail_test', $index)->mail($message);
       
   487     }
       
   488 
       
   489     // There should now be 6 e-mails captured.
       
   490     $captured_emails = $this->drupalGetMails();
       
   491     $this->assertEqual(count($captured_emails), 6, 'All e-mails were captured.', 'E-mail');
       
   492 
       
   493     // Test different ways of getting filtered e-mails via drupalGetMails().
       
   494     $captured_emails = $this->drupalGetMails(array('id' => 'drupal_mail_test'));
       
   495     $this->assertEqual(count($captured_emails), 1, 'Only one e-mail is returned when filtering by id.', 'E-mail');
       
   496     $captured_emails = $this->drupalGetMails(array('id' => 'drupal_mail_test', 'subject' => $subject));
       
   497     $this->assertEqual(count($captured_emails), 1, 'Only one e-mail is returned when filtering by id and subject.', 'E-mail');
       
   498     $captured_emails = $this->drupalGetMails(array('id' => 'drupal_mail_test', 'subject' => $subject, 'from' => 'this_was_not_used@example.com'));
       
   499     $this->assertEqual(count($captured_emails), 0, 'No e-mails are returned when querying with an unused from address.', 'E-mail');
       
   500 
       
   501     // Send the last e-mail again, so we can confirm that the drupalGetMails-filter
       
   502     // correctly returns all e-mails with a given property/value.
       
   503     drupal_mail_system('drupal_mail_test', $index)->mail($message);
       
   504     $captured_emails = $this->drupalGetMails(array('id' => 'drupal_mail_test_4'));
       
   505     $this->assertEqual(count($captured_emails), 2, 'All e-mails with the same id are returned when filtering by id.', 'E-mail');
       
   506   }
       
   507 }
       
   508 
       
   509 /**
       
   510  * Test Folder creation
       
   511  */
       
   512 class SimpleTestFolderTestCase extends DrupalWebTestCase {
       
   513   public static function getInfo() {
       
   514     return array(
       
   515       'name' => 'Testing SimpleTest setUp',
       
   516       'description' => "This test will check SimpleTest's treatment of hook_install during setUp.  Image module is used for test.",
       
   517       'group' => 'SimpleTest',
       
   518     );
       
   519   }
       
   520 
       
   521   function setUp() {
       
   522     return parent::setUp('image');
       
   523   }
       
   524 
       
   525   function testFolderSetup() {
       
   526     $directory = file_default_scheme() . '://styles';
       
   527     $this->assertTrue(file_prepare_directory($directory, FALSE), 'Directory created.');
       
   528   }
       
   529 }
       
   530 
       
   531 /**
       
   532  * Test required modules for tests.
       
   533  */
       
   534 class SimpleTestMissingDependentModuleUnitTest extends DrupalUnitTestCase {
       
   535   public static function getInfo() {
       
   536     return array(
       
   537       'name' => 'Testing dependent module test',
       
   538       'description' => 'This test should not load since it requires a module that is not found.',
       
   539       'group' => 'SimpleTest',
       
   540       'dependencies' => array('simpletest_missing_module'),
       
   541     );
       
   542   }
       
   543 
       
   544   /**
       
   545    * Ensure that this test will not be loaded despite its dependency.
       
   546    */
       
   547   function testFail() {
       
   548     $this->fail(t('Running test with missing required module.'));
       
   549   }
       
   550 }
       
   551 
       
   552 /**
       
   553  * Tests a test case that does not run parent::setUp() in its setUp() method.
       
   554  *
       
   555  * If a test case does not call parent::setUp(), running
       
   556  * DrupalTestCase::tearDown() would destroy the main site's database tables.
       
   557  * Therefore, we ensure that tests which are not set up properly are skipped.
       
   558  *
       
   559  * @see DrupalTestCase
       
   560  */
       
   561 class SimpleTestBrokenSetUp extends DrupalWebTestCase {
       
   562   public static function getInfo() {
       
   563     return array(
       
   564       'name' => 'Broken SimpleTest method',
       
   565       'description' => 'Tests a test case that does not call parent::setUp().',
       
   566       'group' => 'SimpleTest'
       
   567     );
       
   568   }
       
   569 
       
   570   function setUp() {
       
   571     // If the test is being run from the main site, set up normally.
       
   572     if (!drupal_valid_test_ua()) {
       
   573       parent::setUp('simpletest');
       
   574       // Create and log in user.
       
   575       $admin_user = $this->drupalCreateUser(array('administer unit tests'));
       
   576       $this->drupalLogin($admin_user);
       
   577     }
       
   578     // If the test is being run from within simpletest, set up the broken test.
       
   579     else {
       
   580       $this->pass(t('The test setUp() method has been run.'));
       
   581       // Don't call parent::setUp(). This should trigger an error message.
       
   582     }
       
   583   }
       
   584 
       
   585   function tearDown() {
       
   586     // If the test is being run from the main site, tear down normally.
       
   587     if (!drupal_valid_test_ua()) {
       
   588       parent::tearDown();
       
   589     }
       
   590     else {
       
   591       // If the test is being run from within simpletest, output a message.
       
   592       $this->pass(t('The tearDown() method has run.'));
       
   593     }
       
   594   }
       
   595 
       
   596   /**
       
   597    * Runs this test case from within the simpletest child site.
       
   598    */
       
   599   function testBreakSetUp() {
       
   600     // If the test is being run from the main site, run it again from the web
       
   601     // interface within the simpletest child site.
       
   602     if (!drupal_valid_test_ua()) {
       
   603       $edit['SimpleTestBrokenSetUp'] = TRUE;
       
   604       $this->drupalPost('admin/config/development/testing', $edit, t('Run tests'));
       
   605 
       
   606       // Verify that the broken test and its tearDown() method are skipped.
       
   607       $this->assertRaw(t('The test setUp() method has been run.'));
       
   608       $this->assertRaw(t('The test cannot be executed because it has not been set up properly.'));
       
   609       $this->assertNoRaw(t('The test method has run.'));
       
   610       $this->assertNoRaw(t('The tearDown() method has run.'));
       
   611     }
       
   612     // If the test is being run from within simpletest, output a message.
       
   613     else {
       
   614       $this->pass(t('The test method has run.'));
       
   615     }
       
   616   }
       
   617 }
       
   618 
       
   619 /**
       
   620  * Verifies that tests bundled with installation profile modules are found.
       
   621  */
       
   622 class SimpleTestInstallationProfileModuleTestsTestCase extends DrupalWebTestCase {
       
   623   /**
       
   624    * Use the Testing profile.
       
   625    *
       
   626    * The Testing profile contains drupal_system_listing_compatible_test.test,
       
   627    * which attempts to:
       
   628    * - run tests using the Minimal profile (which does not contain the
       
   629    *   drupal_system_listing_compatible_test.module)
       
   630    * - but still install the drupal_system_listing_compatible_test.module
       
   631    *   contained in the Testing profile.
       
   632    *
       
   633    * @see DrupalSystemListingCompatibleTestCase
       
   634    */
       
   635   protected $profile = 'testing';
       
   636 
       
   637   public static function getInfo() {
       
   638     return array(
       
   639       'name' => 'Installation profile module tests',
       
   640       'description' => 'Verifies that tests bundled with installation profile modules are found.',
       
   641       'group' => 'SimpleTest',
       
   642     );
       
   643   }
       
   644 
       
   645   function setUp() {
       
   646     parent::setUp(array('simpletest'));
       
   647 
       
   648     $this->admin_user = $this->drupalCreateUser(array('administer unit tests'));
       
   649     $this->drupalLogin($this->admin_user);
       
   650   }
       
   651 
       
   652   /**
       
   653    * Tests existence of test case located in an installation profile module.
       
   654    */
       
   655   function testInstallationProfileTests() {
       
   656     $this->drupalGet('admin/config/development/testing');
       
   657     $this->assertText('Installation profile module tests helper');
       
   658     $edit = array(
       
   659       'DrupalSystemListingCompatibleTestCase' => TRUE,
       
   660     );
       
   661     $this->drupalPost(NULL, $edit, t('Run tests'));
       
   662     $this->assertText('DrupalSystemListingCompatibleTestCase test executed.');
       
   663   }
       
   664 }
       
   665 
       
   666 /**
       
   667  * Verifies that tests in other installation profiles are not found.
       
   668  *
       
   669  * @see SimpleTestInstallationProfileModuleTestsTestCase
       
   670  */
       
   671 class SimpleTestOtherInstallationProfileModuleTestsTestCase extends DrupalWebTestCase {
       
   672   /**
       
   673    * Use the Minimal profile.
       
   674    *
       
   675    * The Testing profile contains drupal_system_listing_compatible_test.test,
       
   676    * which should not be found.
       
   677    *
       
   678    * @see SimpleTestInstallationProfileModuleTestsTestCase
       
   679    * @see DrupalSystemListingCompatibleTestCase
       
   680    */
       
   681   protected $profile = 'minimal';
       
   682 
       
   683   public static function getInfo() {
       
   684     return array(
       
   685       'name' => 'Other Installation profiles',
       
   686       'description' => 'Verifies that tests in other installation profiles are not found.',
       
   687       'group' => 'SimpleTest',
       
   688     );
       
   689   }
       
   690 
       
   691   function setUp() {
       
   692     parent::setUp(array('simpletest'));
       
   693 
       
   694     $this->admin_user = $this->drupalCreateUser(array('administer unit tests'));
       
   695     $this->drupalLogin($this->admin_user);
       
   696   }
       
   697 
       
   698   /**
       
   699    * Tests that tests located in another installation profile do not appear.
       
   700    */
       
   701   function testOtherInstallationProfile() {
       
   702     $this->drupalGet('admin/config/development/testing');
       
   703     $this->assertNoText('Installation profile module tests helper');
       
   704   }
       
   705 }
       
   706 
       
   707 /**
       
   708  * Verifies that tests in other installation profiles are not found.
       
   709  *
       
   710  * @see SimpleTestInstallationProfileModuleTestsTestCase
       
   711  */
       
   712 class SimpleTestDiscoveryTestCase extends DrupalWebTestCase {
       
   713   /**
       
   714    * Use the Testing profile.
       
   715    *
       
   716    * The Testing profile contains drupal_system_listing_compatible_test.test,
       
   717    * which attempts to:
       
   718    * - run tests using the Minimal profile (which does not contain the
       
   719    *   drupal_system_listing_compatible_test.module)
       
   720    * - but still install the drupal_system_listing_compatible_test.module
       
   721    *   contained in the Testing profile.
       
   722    *
       
   723    * @see DrupalSystemListingCompatibleTestCase
       
   724    */
       
   725   protected $profile = 'testing';
       
   726 
       
   727   public static function getInfo() {
       
   728     return array(
       
   729       'name' => 'Discovery of test classes',
       
   730       'description' => 'Verifies that tests classes are discovered and can be autoloaded (class_exists).',
       
   731       'group' => 'SimpleTest',
       
   732     );
       
   733   }
       
   734 
       
   735   function setUp() {
       
   736     parent::setUp(array('simpletest'));
       
   737 
       
   738     $this->admin_user = $this->drupalCreateUser(array('administer unit tests'));
       
   739     $this->drupalLogin($this->admin_user);
       
   740   }
       
   741 
       
   742   /**
       
   743    * Test discovery of PSR-0 test classes.
       
   744    */
       
   745   function testDiscoveryFunctions() {
       
   746     if (version_compare(PHP_VERSION, '5.3') < 0) {
       
   747       // Don't expect PSR-0 tests to be discovered on older PHP versions.
       
   748       return;
       
   749     }
       
   750     // TODO: What if we have cached values? Do we need to force a cache refresh?
       
   751     $classes_all = simpletest_test_get_all();
       
   752     foreach (array(
       
   753       'Drupal\\simpletest\\Tests\\PSR0WebTest',
       
   754       'Drupal\\simpletest\\Tests\\PSR4WebTest',
       
   755       'Drupal\\psr_0_test\\Tests\\ExampleTest',
       
   756       'Drupal\\psr_4_test\\Tests\\ExampleTest',
       
   757     ) as $class) {
       
   758       $this->assert(!empty($classes_all['SimpleTest'][$class]), t('Class @class must be discovered by simpletest_test_get_all().', array('@class' => $class)));
       
   759     }
       
   760   }
       
   761 
       
   762   /**
       
   763    * Tests existence of test cases.
       
   764    */
       
   765   function testDiscovery() {
       
   766     $this->drupalGet('admin/config/development/testing');
       
   767     // Tests within enabled modules.
       
   768     // (without these, this test wouldn't happen in the first place, so this is
       
   769     // a bit pointless. We still run it for proof-of-concept.)
       
   770     // This one is defined in system module.
       
   771     $this->assertText('Drupal error handlers');
       
   772     // This one is defined in simpletest module.
       
   773     $this->assertText('Discovery of test classes');
       
   774     // Tests within disabled modules.
       
   775     if (version_compare(PHP_VERSION, '5.3') < 0) {
       
   776       // Don't expect PSR-0 tests to be discovered on older PHP versions.
       
   777       return;
       
   778     }
       
   779     // These are provided by simpletest itself via PSR-0 and PSR-4.
       
   780     $this->assertText('PSR0 web test');
       
   781     $this->assertText('PSR4 web test');
       
   782     $this->assertText('PSR0 example test: PSR-0 in disabled modules.');
       
   783     $this->assertText('PSR4 example test: PSR-4 in disabled modules.');
       
   784     $this->assertText('PSR0 example test: PSR-0 in nested subfolders.');
       
   785     $this->assertText('PSR4 example test: PSR-4 in nested subfolders.');
       
   786 
       
   787     // Test each test individually.
       
   788     foreach (array(
       
   789       'Drupal\\psr_0_test\\Tests\\ExampleTest',
       
   790       'Drupal\\psr_0_test\\Tests\\Nested\\NestedExampleTest',
       
   791       'Drupal\\psr_4_test\\Tests\\ExampleTest',
       
   792       'Drupal\\psr_4_test\\Tests\\Nested\\NestedExampleTest',
       
   793     ) as $class) {
       
   794       $this->drupalGet('admin/config/development/testing');
       
   795       $edit = array($class => TRUE);
       
   796       $this->drupalPost(NULL, $edit, t('Run tests'));
       
   797       $this->assertText('The test run finished', t('Test @class must finish.', array('@class' => $class)));
       
   798       $this->assertText('1 pass, 0 fails, and 0 exceptions', t('Test @class must pass.', array('@class' => $class)));
       
   799     }
       
   800   }
       
   801 }