/**
  * {@inheritdoc}
  */
 public static function migrateDumpAlter(TestBase $test)
 {
     // Creates a random filename and updates the source database.
     $random = new Random();
     $temp_directory = $test->getTempFilesDirectory();
     file_prepare_directory($temp_directory, FILE_CREATE_DIRECTORY);
     static::$tempFilename = $test->getDatabasePrefix() . $random->name() . '.jpg';
     $file_path = $temp_directory . '/' . static::$tempFilename;
     file_put_contents($file_path, '');
     Database::getConnection('default', 'migrate')->update('files')->condition('fid', 6)->fields(array('filename' => static::$tempFilename, 'filepath' => $file_path))->execute();
     return static::$tempFilename;
 }
 /**
  * Test the complete Drupal migration.
  */
 public function testDrupal()
 {
     $dumps = $this->getDumps();
     $this->loadDumps($dumps);
     $classes = $this->getTestClassesList();
     foreach ($classes as $class) {
         if (is_subclass_of($class, '\\Drupal\\migrate\\Tests\\MigrateDumpAlterInterface')) {
             $class::migrateDumpAlter($this);
         }
     }
     // Run every migration in the order specified by the storage controller.
     foreach (entity_load_multiple('migration', static::$migrations) as $migration) {
         (new MigrateExecutable($migration, $this))->import();
     }
     foreach ($classes as $class) {
         $test_object = new $class($this->testId);
         $test_object->databasePrefix = $this->databasePrefix;
         $test_object->container = $this->container;
         // run() does a lot of setup and tear down work which we don't need:
         // it would setup a new database connection and wouldn't find the
         // Drupal dump. Also by skipping the setUp() methods there are no id
         // mappings or entities prepared. The tests run against solely migrated
         // data.
         foreach (get_class_methods($test_object) as $method) {
             if (strtolower(substr($method, 0, 4)) == 'test') {
                 // Insert a fail record. This will be deleted on completion to ensure
                 // that testing completed.
                 $method_info = new \ReflectionMethod($class, $method);
                 $caller = array('file' => $method_info->getFileName(), 'line' => $method_info->getStartLine(), 'function' => $class . '->' . $method . '()');
                 $completion_check_id = TestBase::insertAssert($this->testId, $class, FALSE, 'The test did not complete due to a fatal error.', 'Completion check', $caller);
                 // Run the test method.
                 try {
                     $test_object->{$method}();
                 } catch (\Exception $e) {
                     $this->exceptionHandler($e);
                 }
                 // Remove the completion check record.
                 TestBase::deleteAssert($completion_check_id);
             }
         }
         // Add the pass/fail/exception/debug results.
         foreach ($this->results as $key => &$value) {
             $value += $test_object->results[$key];
         }
     }
 }
Beispiel #3
0
 /**
  * Cleans up after testing.
  *
  * Deletes created files and temporary files directory, deletes the tables
  * created by setUp(), and resets the database prefix.
  */
 protected function tearDown()
 {
     // Destroy the testing kernel.
     if (isset($this->kernel)) {
         $this->kernel->shutdown();
     }
     parent::tearDown();
     // Ensure that the maximum meta refresh count is reset.
     $this->maximumMetaRefreshCount = NULL;
     // Ensure that internal logged in variable and cURL options are reset.
     $this->loggedInUser = FALSE;
     $this->additionalCurlOptions = array();
     // Close the CURL handler and reset the cookies array used for upgrade
     // testing so test classes containing multiple tests are not polluted.
     $this->curlClose();
     $this->curlCookies = array();
     $this->cookies = array();
 }
 /**
  * Data provider for ::testCommentLinkBuilder.
  */
 public function getLinkCombinations()
 {
     $cases = array();
     // No links should be created if the entity doesn't have the field.
     $cases[] = array($this->getMockNode(FALSE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1), array('view_mode' => 'teaser'), TRUE, TRUE, TRUE, TRUE, array());
     foreach (array('search_result', 'search_index', 'print') as $view_mode) {
         // Nothing should be output in these view modes.
         $cases[] = array($this->getMockNode(TRUE, CommentItemInterface::OPEN, CommentItemInterface::FORM_BELOW, 1), array('view_mode' => $view_mode), TRUE, TRUE, TRUE, TRUE, array());
     }
     // All other combinations.
     $combinations = array('is_anonymous' => array(FALSE, TRUE), 'comment_count' => array(0, 1), 'has_access_comments' => array(0, 1), 'history_exists' => array(FALSE, TRUE), 'has_post_comments' => array(0, 1), 'form_location' => array(CommentItemInterface::FORM_BELOW, CommentItemInterface::FORM_SEPARATE_PAGE), 'comments' => array(CommentItemInterface::OPEN, CommentItemInterface::CLOSED, CommentItemInterface::HIDDEN), 'view_mode' => array('teaser', 'rss', 'full'));
     $permutations = TestBase::generatePermutations($combinations);
     foreach ($permutations as $combination) {
         $case = array($this->getMockNode(TRUE, $combination['comments'], $combination['form_location'], $combination['comment_count']), array('view_mode' => $combination['view_mode']), $combination['has_access_comments'], $combination['history_exists'], $combination['has_post_comments'], $combination['is_anonymous']);
         $expected = array();
         // When comments are enabled in teaser mode, and comments exist, and the
         // user has access - we can output the comment count.
         if ($combination['comments'] && $combination['view_mode'] == 'teaser' && $combination['comment_count'] && $combination['has_access_comments']) {
             $expected['comment-comments'] = '1 comment';
             // And if history module exists, we can show a 'new comments' link.
             if ($combination['history_exists']) {
                 $expected['comment-new-comments'] = '';
             }
         }
         // All view modes other than RSS.
         if ($combination['view_mode'] != 'rss') {
             // Where commenting is open.
             if ($combination['comments'] == CommentItemInterface::OPEN) {
                 // And the user has post-comments permission.
                 if ($combination['has_post_comments']) {
                     // If the view mode is teaser, or the user can access comments and
                     // comments exist or the form is on a separate page.
                     if ($combination['view_mode'] == 'teaser' || $combination['has_access_comments'] && $combination['comment_count'] || $combination['form_location'] == CommentItemInterface::FORM_SEPARATE_PAGE) {
                         // There should be a add comment link.
                         $expected['comment-add'] = array('title' => 'Add new comment');
                         if ($combination['form_location'] == CommentItemInterface::FORM_BELOW) {
                             // On the same page.
                             $expected['comment-add']['url'] = Url::fromRoute('node.view');
                         } else {
                             // On a separate page.
                             $expected['comment-add']['url'] = Url::fromRoute('comment.reply', ['entity_type' => 'node', 'entity' => 1, 'field_name' => 'comment']);
                         }
                     }
                 } elseif ($combination['is_anonymous']) {
                     // Anonymous users get the forbidden message if the can't post
                     // comments.
                     $expected['comment-forbidden'] = "Can't let you do that Dave.";
                 }
             }
         }
         $case[] = $expected;
         $cases[] = $case;
     }
     return $cases;
 }
Beispiel #5
0
 /**
  * {@inheritdoc}
  */
 protected function tearDown()
 {
     if ($this->kernel instanceof DrupalKernel) {
         $this->kernel->shutdown();
     }
     // Before tearing down the test environment, ensure that no stream wrapper
     // of this test leaks into the parent environment. Unlike all other global
     // state variables in Drupal, stream wrappers are a global state construct
     // of PHP core, which has to be maintained manually.
     // @todo Move StreamWrapper management into DrupalKernel.
     // @see https://www.drupal.org/node/2028109
     foreach ($this->streamWrappers as $scheme => $type) {
         $this->unregisterStreamWrapper($scheme, $type);
     }
     parent::tearDown();
 }
 /**
  * Run all tests in this class.
  *
  * Regardless of whether $methods are passed or not, only method names
  * starting with "test" are executed.
  *
  * @param $methods
  *   (optional) A list of method names in the test case class to run; e.g.,
  *   array('testFoo', 'testBar'). By default, all methods of the class are
  *   taken into account, but it can be useful to only run a few selected test
  *   methods during debugging.
  */
 public function run(array $methods = array())
 {
     $class = get_class($this);
     if ($missing_requirements = $this->checkRequirements()) {
         $object_info = new \ReflectionObject($this);
         $caller = array('file' => $object_info->getFileName());
         foreach ($missing_requirements as $missing_requirement) {
             TestBase::insertAssert($this->testId, $class, FALSE, $missing_requirement, 'Requirements check', $caller);
         }
         return;
     }
     TestServiceProvider::$currentTest = $this;
     $simpletest_config = $this->config('simpletest.settings');
     // Unless preset from run-tests.sh, retrieve the current verbose setting.
     if (!isset($this->verbose)) {
         $this->verbose = $simpletest_config->get('verbose');
     }
     if ($this->verbose) {
         // Initialize verbose debugging.
         $this->verbose = TRUE;
         $this->verboseDirectory = PublicStream::basePath() . '/simpletest/verbose';
         $this->verboseDirectoryUrl = file_create_url($this->verboseDirectory);
         if (file_prepare_directory($this->verboseDirectory, FILE_CREATE_DIRECTORY) && !file_exists($this->verboseDirectory . '/.htaccess')) {
             file_put_contents($this->verboseDirectory . '/.htaccess', "<IfModule mod_expires.c>\nExpiresActive Off\n</IfModule>\n");
         }
         $this->verboseClassName = str_replace("\\", "_", $class);
     }
     // HTTP auth settings (<username>:<password>) for the simpletest browser
     // when sending requests to the test site.
     $this->httpAuthMethod = (int) $simpletest_config->get('httpauth.method');
     $username = $simpletest_config->get('httpauth.username');
     $password = $simpletest_config->get('httpauth.password');
     if (!empty($username) && !empty($password)) {
         $this->httpAuthCredentials = $username . ':' . $password;
     }
     set_error_handler(array($this, 'errorHandler'));
     // Iterate through all the methods in this class, unless a specific list of
     // methods to run was passed.
     $test_methods = array_filter(get_class_methods($class), function ($method) {
         return strpos($method, 'test') === 0;
     });
     if (empty($test_methods)) {
         // Call $this->assert() here because we need to pass along custom caller
         // information, lest the wrong originating code file/line be identified.
         $this->assert(FALSE, 'No test methods found.', 'Requirements', array('function' => __METHOD__ . '()', 'file' => __FILE__, 'line' => __LINE__));
     }
     if ($methods) {
         $test_methods = array_intersect($test_methods, $methods);
     }
     foreach ($test_methods as $method) {
         // Insert a fail record. This will be deleted on completion to ensure
         // that testing completed.
         $method_info = new \ReflectionMethod($class, $method);
         $caller = array('file' => $method_info->getFileName(), 'line' => $method_info->getStartLine(), 'function' => $class . '->' . $method . '()');
         $test_completion_check_id = TestBase::insertAssert($this->testId, $class, FALSE, 'The test did not complete due to a fatal error.', 'Completion check', $caller);
         try {
             $this->prepareEnvironment();
         } catch (\Exception $e) {
             $this->exceptionHandler($e);
             // The prepareEnvironment() method isolates the test from the parent
             // Drupal site by creating a random database prefix and test site
             // directory. If this fails, a test would possibly operate in the
             // parent site. Therefore, the entire test run for this test class
             // has to be aborted.
             // restoreEnvironment() cannot be called, because we do not know
             // where exactly the environment setup failed.
             break;
         }
         try {
             $this->setUp();
         } catch (\Exception $e) {
             $this->exceptionHandler($e);
             // Abort if setUp() fails, since all test methods will fail.
             // But ensure to clean up and restore the environment, since
             // prepareEnvironment() succeeded.
             $this->restoreEnvironment();
             break;
         }
         try {
             $this->{$method}();
         } catch (\Exception $e) {
             $this->exceptionHandler($e);
         }
         try {
             $this->tearDown();
         } catch (\Exception $e) {
             $this->exceptionHandler($e);
             // If a test fails to tear down, abort the entire test class, since
             // it is likely that all tests will fail in the same way and a
             // failure here only results in additional test artifacts that have
             // to be manually deleted.
             $this->restoreEnvironment();
             break;
         }
         $this->restoreEnvironment();
         // Remove the test method completion check record.
         TestBase::deleteAssert($test_completion_check_id);
     }
     TestServiceProvider::$currentTest = NULL;
     // Clear out the error messages and restore error handler.
     drupal_get_messages();
     restore_error_handler();
 }
 /**
  * Test permissions on comment fields.
  */
 public function testAccessToAdministrativeFields()
 {
     // Create a comment type.
     $comment_type = CommentType::create(['id' => 'comment', 'label' => 'Default comments', 'description' => 'Default comment field', 'target_entity_type_id' => 'entity_test']);
     $comment_type->save();
     // Create a comment against a test entity.
     $host = EntityTest::create();
     $host->save();
     // An administrator user. No user exists yet, ensure that the first user
     // does not have UID 1.
     $comment_admin_user = $this->createUser(['uid' => 2, 'name' => 'admin'], ['administer comments', 'access comments']);
     // Two comment enabled users, one with edit access.
     $comment_enabled_user = $this->createUser(['name' => 'enabled'], ['post comments', 'skip comment approval', 'edit own comments', 'access comments']);
     $comment_no_edit_user = $this->createUser(['name' => 'no edit'], ['post comments', 'skip comment approval', 'access comments']);
     // An unprivileged user.
     $comment_disabled_user = $this->createUser(['name' => 'disabled'], ['access content']);
     $role = Role::load(RoleInterface::ANONYMOUS_ID);
     $role->grantPermission('post comments')->save();
     $anonymous_user = new AnonymousUserSession();
     // Add two fields.
     $this->addDefaultCommentField('entity_test', 'entity_test', 'comment');
     $this->addDefaultCommentField('entity_test', 'entity_test', 'comment_other');
     // Change the second field's anonymous contact setting.
     $instance = FieldConfig::loadByName('entity_test', 'entity_test', 'comment_other');
     // Default is 'May not contact', for this field - they may contact.
     $instance->setSetting('anonymous', COMMENT_ANONYMOUS_MAY_CONTACT);
     $instance->save();
     // Create three "Comments". One is owned by our edit-enabled user.
     $comment1 = Comment::create(['entity_type' => 'entity_test', 'name' => 'Tony', 'hostname' => 'magic.example.com', 'mail' => '*****@*****.**', 'subject' => 'Bruce the Mesopotamian moose', 'entity_id' => $host->id(), 'comment_type' => 'comment', 'field_name' => 'comment', 'pid' => 0, 'uid' => 0, 'status' => 1]);
     $comment1->save();
     $comment2 = Comment::create(['entity_type' => 'entity_test', 'hostname' => 'magic.example.com', 'subject' => 'Brian the messed up lion', 'entity_id' => $host->id(), 'comment_type' => 'comment', 'field_name' => 'comment', 'status' => 1, 'pid' => 0, 'uid' => $comment_enabled_user->id()]);
     $comment2->save();
     $comment3 = Comment::create(['entity_type' => 'entity_test', 'hostname' => 'magic.example.com', 'status' => 0, 'subject' => 'Gail the minky whale', 'entity_id' => $host->id(), 'comment_type' => 'comment', 'field_name' => 'comment_other', 'pid' => $comment2->id(), 'uid' => $comment_no_edit_user->id()]);
     $comment3->save();
     // Note we intentionally don't save this comment so it remains 'new'.
     $comment4 = Comment::create(['entity_type' => 'entity_test', 'hostname' => 'magic.example.com', 'status' => 0, 'subject' => 'Daniel the Cocker-Spaniel', 'entity_id' => $host->id(), 'comment_type' => 'comment', 'field_name' => 'comment_other', 'pid' => 0, 'uid' => $anonymous_user->id()]);
     // Generate permutations.
     $combinations = ['comment' => [$comment1, $comment2, $comment3, $comment4], 'user' => [$comment_admin_user, $comment_enabled_user, $comment_no_edit_user, $comment_disabled_user, $anonymous_user]];
     $permutations = TestBase::generatePermutations($combinations);
     // Check access to administrative fields.
     foreach ($this->administrativeFields as $field) {
         foreach ($permutations as $set) {
             $may_view = $set['comment']->{$field}->access('view', $set['user']);
             $may_update = $set['comment']->{$field}->access('edit', $set['user']);
             $this->assertTrue($may_view, SafeMarkup::format('User @user can view field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@comment' => $set['comment']->getSubject(), '@field' => $field]));
             $this->assertEqual($may_update, $set['user']->hasPermission('administer comments'), SafeMarkup::format('User @user @state update field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@state' => $may_update ? 'can' : 'cannot', '@comment' => $set['comment']->getSubject(), '@field' => $field]));
         }
     }
     // Check access to normal field.
     foreach ($permutations as $set) {
         $may_update = $set['comment']->access('update', $set['user']) && $set['comment']->subject->access('edit', $set['user']);
         $this->assertEqual($may_update, $set['user']->hasPermission('administer comments') || $set['user']->hasPermission('edit own comments') && $set['user']->id() == $set['comment']->getOwnerId(), SafeMarkup::format('User @user @state update field subject on comment @comment', ['@user' => $set['user']->getUsername(), '@state' => $may_update ? 'can' : 'cannot', '@comment' => $set['comment']->getSubject()]));
     }
     // Check read-only fields.
     foreach ($this->readOnlyFields as $field) {
         // Check view operation.
         foreach ($permutations as $set) {
             $may_view = $set['comment']->{$field}->access('view', $set['user']);
             $may_update = $set['comment']->{$field}->access('edit', $set['user']);
             // Nobody has access to view the hostname field.
             if ($field === 'hostname') {
                 $view_access = FALSE;
                 $state = 'cannot';
             } else {
                 $view_access = TRUE;
                 $state = 'can';
             }
             $this->assertEqual($may_view, $view_access, SafeMarkup::format('User @user @state view field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@comment' => $set['comment']->getSubject(), '@field' => $field, '@state' => $state]));
             $this->assertFalse($may_update, SafeMarkup::format('User @user @state update field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@state' => $may_update ? 'can' : 'cannot', '@comment' => $set['comment']->getSubject(), '@field' => $field]));
         }
     }
     // Check create-only fields.
     foreach ($this->createOnlyFields as $field) {
         // Check view operation.
         foreach ($permutations as $set) {
             $may_view = $set['comment']->{$field}->access('view', $set['user']);
             $may_update = $set['comment']->{$field}->access('edit', $set['user']);
             $this->assertEqual($may_view, TRUE, SafeMarkup::format('User @user can view field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@comment' => $set['comment']->getSubject(), '@field' => $field]));
             $this->assertEqual($may_update, $set['user']->hasPermission('post comments') && $set['comment']->isNew(), SafeMarkup::format('User @user @state update field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@state' => $may_update ? 'can' : 'cannot', '@comment' => $set['comment']->getSubject(), '@field' => $field]));
         }
     }
     // Check contact fields.
     foreach ($this->contactFields as $field) {
         // Check view operation.
         foreach ($permutations as $set) {
             $may_update = $set['comment']->{$field}->access('edit', $set['user']);
             // To edit the 'mail' or 'name' field, either the user has the
             // "administer comments" permissions or the user is anonymous and
             // adding a new comment using a field that allows contact details.
             $this->assertEqual($may_update, $set['user']->hasPermission('administer comments') || $set['user']->isAnonymous() && $set['comment']->isNew() && $set['user']->hasPermission('post comments') && $set['comment']->getFieldName() == 'comment_other', SafeMarkup::format('User @user @state update field @field on comment @comment', ['@user' => $set['user']->getUsername(), '@state' => $may_update ? 'can' : 'cannot', '@comment' => $set['comment']->getSubject(), '@field' => $field]));
         }
     }
     foreach ($permutations as $set) {
         // Check no view-access to mail field for other than admin.
         $may_view = $set['comment']->mail->access('view', $set['user']);
         $this->assertEqual($may_view, $set['user']->hasPermission('administer comments'));
     }
 }
Beispiel #8
0
 /**
  * Constructor for UnitTestBase.
  */
 function __construct($test_id = NULL)
 {
     parent::__construct($test_id);
     $this->skipClasses[__CLASS__] = TRUE;
 }
 /**
  * Test the complete Drupal migration.
  */
 public function testDrupal()
 {
     $dumps = $this->getDumps();
     $this->loadDumps($dumps);
     $classes = $this->getTestClassesList();
     $extension_install_storage = new ExtensionInstallStorage(\Drupal::service('config.storage'), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, TRUE);
     foreach ($classes as $class) {
         if (is_subclass_of($class, '\\Drupal\\migrate\\Tests\\MigrateDumpAlterInterface')) {
             $class::migrateDumpAlter($this);
         }
     }
     // Run every migration in the order specified by the storage controller.
     foreach (entity_load_multiple('migration', static::$migrations) as $migration) {
         (new MigrateExecutable($migration, $this))->import();
         // Ensure that the default migration has the correct dependencies.
         list($base_name, ) = explode(':', $migration->id(), 2);
         $default_configuration = $extension_install_storage->read('migrate.migration.' . $base_name);
         $default_dependencies = isset($default_configuration['dependencies']) ? $default_configuration['dependencies'] : [];
         $this->assertEqual($default_dependencies, $migration->getDependencies(), SafeMarkup::format('Dependencies in @id match after installing. Default configuration @first is equal to active configuration @second.', array('@id' => $migration->id(), '@first' => var_export($default_dependencies, TRUE), '@second' => var_export($migration->getDependencies(), TRUE))));
     }
     foreach ($classes as $class) {
         $test_object = new $class($this->testId);
         $test_object->databasePrefix = $this->databasePrefix;
         $test_object->container = $this->container;
         // run() does a lot of setup and tear down work which we don't need:
         // it would setup a new database connection and wouldn't find the
         // Drupal dump. Also by skipping the setUp() methods there are no id
         // mappings or entities prepared. The tests run against solely migrated
         // data.
         foreach (get_class_methods($test_object) as $method) {
             if (strtolower(substr($method, 0, 4)) == 'test') {
                 // Insert a fail record. This will be deleted on completion to ensure
                 // that testing completed.
                 $method_info = new \ReflectionMethod($class, $method);
                 $caller = array('file' => $method_info->getFileName(), 'line' => $method_info->getStartLine(), 'function' => $class . '->' . $method . '()');
                 $completion_check_id = TestBase::insertAssert($this->testId, $class, FALSE, 'The test did not complete due to a fatal error.', 'Completion check', $caller);
                 // Run the test method.
                 try {
                     $test_object->{$method}();
                 } catch (\Exception $e) {
                     $this->exceptionHandler($e);
                 }
                 // Remove the completion check record.
                 TestBase::deleteAssert($completion_check_id);
             }
         }
         // Add the pass/fail/exception/debug results.
         foreach ($this->results as $key => &$value) {
             $value += $test_object->results[$key];
         }
     }
 }