'Basic tests', 'description' => 'Run through basic scenarios and functionality.', 'group' => 'backup_migrate', ); } /** * {@inheritdoc} */ public function setUp(array $modules = array()) { parent::setUp($modules); // Log in as user 1, so that permissions are irrelevant. $this->loginUser1(); } /** * Verify the main page has the expected form, then run a basic backup. */ public function testQuickBackup() { // Ensure that the private file system is working correctly. $this->drupalGet('admin/config/media/file-system'); $this->assertResponse(200); $edit = array(); $this->drupalPost(NULL, $edit, 'Save configuration'); $this->assertResponse(200); $this->assertText('The configuration options have been saved.'); // Load the main B&M page. $this->drupalGet(BACKUP_MIGRATE_MENU_PATH); $this->assertResponse(200); // @todo Confirm each of the tabs are present. // @todo Confirm each of the local tasks are present. // Confirm the form has the expected fields. $this->assertFieldByName('source_id'); $this->assertFieldByName('destination_id'); $this->assertFieldByName('profile_id'); $this->assertFieldByName('copy'); $this->assertFieldByName('copy_destination_id'); $this->assertFieldByName('description_enabled'); // This item should not have a value "selected", it just defaults to the // first item being the active item. $items = array('db', 'files', 'archive'); $this->assertSelectOptions('edit-source-id', $items); $this->assertNoOptionsSelected('edit-source-id'); // This item should have a value "selected", not just the first item. Note: // if the 'manual' backup option isn't available then the private directory // path is not set correctly. $items = array('manual', 'download'); $this->assertSelectOptions('edit-destination-id', $items); $this->assertOptionSelected('edit-destination-id', 'download'); // This item should not have a value "selected", it just defaults to the // first item being the active item. $items = array('default'); $this->assertSelectOptions('edit-profile-id', $items); $this->assertNoOptionsSelected('edit-profile-id'); // This item should not have a value "selected", it just defaults to the // first item being the active item. $items = array('manual', 'download'); $this->assertSelectOptions('edit-copy-destination-id', $items); $this->assertNoOptionsSelected('edit-copy-destination-id'); // Generate a backup and confirm it was created correctly. $edit = array( 'destination_id' => 'manual', ); $this->drupalPost(NULL, $edit, 'Backup now'); $this->assertResponse(200); // Confirm the response is as expected. This is split up into separate // pieces because it'd be more effort than is necessary right now to confirm // what the exact filename is. $this->assertText('Default Database backed up successfully'); $this->assertText('in destination Manual Backups Directory'); $this->assertLink('download'); $this->assertLink('restore'); $this->assertLink('delete'); // Try requesting the backup file. $xpath = $this ->xpath('//a[normalize-space(text())=:label]', array( ':label' => 'download', )); $this->verbose($xpath); $this->assertTrue(isset($xpath[0]['href'])); $this->assertNotNull($xpath[0]['href']); // @todo This doesn't work on drupalci, so work out how to fix it. // $this->drupalGet($xpath[0]['href']); $this->assertResponse(200); } /** * Test the custom validators. */ public function testFieldValidators() { // Need this file loaded for the custom validators. module_load_include('advanced_settings.inc', 'backup_migrate'); $field = 'mock_field'; $element = array( '#value' => 'a', '#title' => '', '#parents' => array($field), ); // Test the memory limit validator. $element['#title'] = 'Mock Field (Memory Limit)'; $test_values = array( // Value to be tested => validity. // Special meaning: no limit. '-1' => TRUE, '50' => TRUE, // 5 megabytes. '5M' => TRUE, // 500 kilobytes. '.5M' => TRUE, // 5 gigabytes. '5G' => TRUE, '.5G' => TRUE, '1.5G' => TRUE, '0' => TRUE, 'a' => FALSE, '-2' => FALSE, // You cannot have half a byte. '1.5' => FALSE, '5T' => FALSE, '5 G' => FALSE, '.5.5G' => FALSE, ); foreach ($test_values as $value => $valid) { $this->assertValidFieldValue('backup_migrate_memory_limit_validate', $element, $value, $valid, 'memory limit value'); } // Test the positive non-zero integer validator. $element['#title'] = 'Mock Field (Unsigned Integer)'; $test_values = array( '0' => TRUE, '1' => TRUE, '10000' => TRUE, // NaN. 'a' => FALSE, // Not an integer. '.5' => FALSE, // Not positive. '-1' => FALSE, // Largest integer. // @code // PHP_INT_MAX => TRUE, // @endcode // Resolves to a decimal. // @code // (PHP_INT_MAX + 1) => FALSE, // @endcode ); foreach ($test_values as $value => $valid) { $this->assertValidFieldValue('backup_migrate_unsigned_integer_validate', $element, $value, $valid, 'zero or a positive integer'); } // Test the validator for decimals ranging from 0 to 1. $element['#title'] = 'Mock Field (Decimal between 0 and 1)'; $test_values = array( '0' => TRUE, '1' => TRUE, '0.1' => TRUE, '.1' => TRUE, '1.1' => FALSE, '-1' => FALSE, '-1.1' => FALSE, '2' => FALSE, 'a' => FALSE, ); foreach ($test_values as $value => $valid) { $this->assertValidFieldValue('backup_migrate_fraction_validate', $element, $value, $valid, 'decimal between 0 and 1'); } } /** * Asserts that the content of a field passes its associated validation. * * @param string $validator * Drupal validator function callback. * @param array $element * Input for error setter. * @param string $value * Field value to be tested. * @param bool $value_is_valid * Expected outcome. * @param string $type * Description of value sub-type. */ protected function assertValidFieldValue($validator, array $element, $value, $value_is_valid, $type) { $form = array(); $form_state = array(); $field = 'mock_field'; $element['#value'] = $value; form_clear_error(); call_user_func_array($validator, array($element, &$form_state, $form)); $errors = form_get_errors(); if ($value_is_valid) { $args = array( '%value' => $value, '%type' => $type, ); $msg = t('%value is a valid %type.', $args); $result = $this->assertTrue(empty($errors[$field]), $msg); } else { $args = array( '%value' => $value, '%type' => $type, '%msg' => strip_tags($errors[$field]), ); $msg = t('%value is not a valid %type. Error message: "%msg".', $args); $result = $this->assertFalse(empty($errors[$field]), $msg); } return $result; } /** * Confirm backup_migrate_to_bytes() works. */ public function testBackupMigrateToBytes() { // PHP manual: // http://php.net/manual/en/ini.core.php#ini.memory-limit // '-1' is a reserved value meaning 'no limit'. $input = '-1'; $expected = -1; $this->assertEqual(backup_migrate_to_bytes($input), $expected); // PHP would halt before this, but let us test anyway. $input = 'nonsense'; $expected = 0; $this->assertEqual(backup_migrate_to_bytes($input), $expected); // This is 123 bytes, but there is a bug in B&M that turns // this into 12.5 megabytes. $input = '123'; $expected = 12582912; $this->assertEqual(backup_migrate_to_bytes($input), $expected); // 45 megabytes. $input = '45M'; $expected = 47185920; $this->assertEqual(backup_migrate_to_bytes($input), $expected); // 8 gigabytes. $input = '8G'; $expected = 8589934592; $this->assertEqual(backup_migrate_to_bytes($input), $expected); } } // @todo Test permissions. // @todo Test admin forms.