summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2018-07-21 13:47:25 (GMT)
committerAlex Pott2018-07-21 13:47:46 (GMT)
commitc5782b95a2d0d05fe1223adbac5c2a5323ecf482 (patch)
tree785ffe69464c4cd683fcbfbe84518d84eb7760fb
parente0feb5b1f1be551639c301369dcba6965417316b (diff)
Issue #2973879 by jibran, lauriii, drpal, samuel.mortenson, dawehner, Wim Leers: Add login/logout Nightwatch commands (and a Drupal "login" command to allow for that)
(cherry picked from commit 0083ba97d7eacdcdc8a2a8df6ed07719c6aa1953)
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalCreateRole.js59
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalCreateUser.js58
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalInstall.js12
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalLogin.js30
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalLoginAsAdmin.js37
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalLogout.js37
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalUserIsLoggedIn.js19
-rw-r--r--core/tests/Drupal/Nightwatch/Tests/loginTest.js24
-rw-r--r--core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php2
-rw-r--r--core/tests/Drupal/TestSite/Commands/TestSiteUserLoginCommand.php71
-rw-r--r--core/tests/Drupal/TestSite/TestSiteApplication.php2
-rw-r--r--core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php97
12 files changed, 420 insertions, 28 deletions
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalCreateRole.js b/core/tests/Drupal/Nightwatch/Commands/drupalCreateRole.js
new file mode 100644
index 0000000..e3903ae
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalCreateRole.js
@@ -0,0 +1,59 @@
+/**
+ * Creates role with given permissions.
+ *
+ * @param {object} settings
+ * Settings object
+ * @param {array} settings.permissions
+ * The list of roles granted for the user.
+ * @param {string} [settings.name=null]
+ * The role name.
+ * @param {function} callback
+ * A callback which will be called, when creating the role is finished.
+ * @return {object}
+ * The drupalCreateRole command.
+ */
+exports.command = function drupalCreateRole({ permissions, name = null }, callback) {
+ const self = this;
+ const roleName = name || Math.random().toString(36).substring(2, 15);
+
+ let machineName;
+ this
+ .drupalLoginAsAdmin(() => {
+ this
+ .drupalRelativeURL('/admin/people/roles/add')
+ .setValue('input[name="label"]', roleName)
+ // Wait for the machine name to appear so that it can be used later to
+ // select the permissions from the permission page.
+ .expect.element('.user-role-form .machine-name-value').to.be.visible.before(2000);
+
+ this.perform((done) => {
+ this.getText('.user-role-form .machine-name-value', (element) => {
+ machineName = element.value;
+ done();
+ });
+ })
+ .submitForm('#user-role-form')
+ .drupalRelativeURL('/admin/people/permissions')
+ .perform((client, done) => {
+ Promise.all(
+ permissions.map(permission => (
+ new Promise((resolve) => {
+ client.click(`input[name="${machineName}[${permission}]"]`, () => {
+ resolve();
+ });
+ })
+ )),
+ ).then(() => {
+ done();
+ });
+ })
+ .submitForm('#user-admin-permissions');
+ })
+ .perform(() => {
+ if (typeof callback === 'function') {
+ callback.call(self, machineName);
+ }
+ });
+
+ return this;
+};
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalCreateUser.js b/core/tests/Drupal/Nightwatch/Commands/drupalCreateUser.js
new file mode 100644
index 0000000..7297cdf
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalCreateUser.js
@@ -0,0 +1,58 @@
+/**
+ * Logs into Drupal as the given user.
+ *
+ * @param {object} settings
+ * Settings object
+ * @param {string} settings.name
+ * The user name.
+ * @param {string} settings.password
+ * The user password.
+ * @param {array} [settings.permissions=[]]
+ * The list of permissions granted for the user.
+ * @param {function} callback
+ * A callback which will be called, when the creating the use is finished.
+ * @return {object}
+ * The drupalCreateUser command.
+ */
+exports.command = function drupalCreateUser({ name, password, permissions = [] }, callback) {
+ const self = this;
+
+ let role;
+ this
+ .perform((client, done) => {
+ if (permissions) {
+ client.drupalCreateRole({ permissions, name: null }, (newRole) => {
+ role = newRole;
+ done();
+ });
+ }
+ else {
+ done();
+ }
+ })
+ .drupalLoginAsAdmin(() => {
+ this
+ .drupalRelativeURL('/admin/people/create')
+ .setValue('input[name="name"]', name)
+ .setValue('input[name="pass[pass1]"]', password)
+ .setValue('input[name="pass[pass2]"]', password)
+ .perform((client, done) => {
+ if (role) {
+ client.click(`input[name="roles[${role}]`, () => {
+ done();
+ });
+ }
+ else {
+ done();
+ }
+ })
+ .submitForm('#user-register-form')
+ .assert.containsText('.messages', 'Created a new user account', `User "${name}" was created succesfully.`);
+ });
+
+ if (typeof callback === 'function') {
+ callback.call(self);
+ }
+
+ return this;
+};
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalInstall.js b/core/tests/Drupal/Nightwatch/Commands/drupalInstall.js
index 2f35adf..176eeef 100644
--- a/core/tests/Drupal/Nightwatch/Commands/drupalInstall.js
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalInstall.js
@@ -5,16 +5,16 @@ import { commandAsWebserver } from '../globals';
/**
* Installs a Drupal test site.
*
- * @param {Object}
- * (optional) Settings object
- * @param setupFile
- * (optional) Setup file used by TestSiteApplicationTest
+ * @param {oject} [settings={}]
+ * Settings object
+ * @param {string} [settings.setupFile='']
+ * Setup file used by TestSiteApplicationTest
* @param {function} callback
* A callback which will be called, when the installation is finished.
* @return {object}
* The 'browser' object.
*/
-exports.command = function drupalInstall({ setupFile = '' }, callback) {
+exports.command = function drupalInstall({ setupFile = '' } = {}, callback) {
const self = this;
try {
@@ -23,6 +23,7 @@ exports.command = function drupalInstall({ setupFile = '' }, callback) {
const install = execSync(commandAsWebserver(`php ./scripts/test-site.php install ${setupFile} --base-url ${process.env.DRUPAL_TEST_BASE_URL} ${dbOption} --json`));
const installData = JSON.parse(install.toString());
this.drupalDbPrefix = installData.db_prefix;
+ this.drupalSitePath = installData.site_path;
const url = new URL(process.env.DRUPAL_TEST_BASE_URL);
this
.url(process.env.DRUPAL_TEST_BASE_URL)
@@ -45,5 +46,6 @@ exports.command = function drupalInstall({ setupFile = '' }, callback) {
if (typeof callback === 'function') {
callback.call(self);
}
+
return this;
};
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalLogin.js b/core/tests/Drupal/Nightwatch/Commands/drupalLogin.js
new file mode 100644
index 0000000..c6785ec
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalLogin.js
@@ -0,0 +1,30 @@
+/**
+ * Logs into Drupal as the given user.
+ *
+ * @param {string} name
+ * The user name.
+ * @param {string} password
+ * The user password.
+ * @return {object}
+ * The drupalUserIsLoggedIn command.
+ */
+exports.command = function drupalLogin({ name, password }) {
+ this.drupalUserIsLoggedIn((sessionExists) => {
+ // Log the current user out if necessary.
+ if (sessionExists) {
+ this.drupalLogout();
+ }
+ // Log in with the given credentials.
+ this
+ .drupalRelativeURL('/user/login')
+ .setValue('input[name="name"]', name)
+ .setValue('input[name="pass"]', password)
+ .submitForm('#user-login-form');
+ // Assert that a user is logged in.
+ this.drupalUserIsLoggedIn((sessionExists) => {
+ this.assert.equal(sessionExists, true, `The user "${name}" was logged in.`);
+ });
+ });
+
+ return this;
+};
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalLoginAsAdmin.js b/core/tests/Drupal/Nightwatch/Commands/drupalLoginAsAdmin.js
new file mode 100644
index 0000000..8bc0e4e
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalLoginAsAdmin.js
@@ -0,0 +1,37 @@
+import { execSync } from 'child_process';
+import { URL } from 'url';
+import { commandAsWebserver } from '../globals';
+
+/**
+ * Logs in as the admin user.
+ *
+ * @param {function} callback
+ * A callback which will allow running commands as an administrator.
+ * @return {object}
+ * The drupalLoginAsAdmin command.
+ */
+exports.command = function drupalLoginAsAdmin(callback) {
+ const self = this;
+ this.drupalUserIsLoggedIn((sessionExists) => {
+ if (sessionExists) {
+ this.drupalLogout();
+ }
+ const userLink = execSync(commandAsWebserver(`php ./scripts/test-site.php user-login 1 --site-path ${this.drupalSitePath}`));
+
+ this.drupalRelativeURL(userLink.toString());
+
+ this.drupalUserIsLoggedIn((sessionExists) => {
+ if (!sessionExists) {
+ throw new Error('Logging in as an admin user failed.');
+ }
+ });
+ });
+
+ if (typeof callback === 'function') {
+ callback.call(self);
+ }
+
+ this.drupalLogout({ silent: true });
+
+ return this;
+};
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalLogout.js b/core/tests/Drupal/Nightwatch/Commands/drupalLogout.js
new file mode 100644
index 0000000..f96ce47
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalLogout.js
@@ -0,0 +1,37 @@
+import { execSync } from 'child_process';
+import { URL } from 'url';
+
+/**
+ * Logs out from a Drupal site.
+ *
+ * @param {object} [settings={}]
+ * The settings object.
+ * @param {boolean} [settings.silent=false]
+ * If the command should be run silently.
+ * @param {function} callback
+ * A callback which will be called, when the logout is finished.
+ * @return {object}
+ * The drupalLogout command.
+ */
+exports.command = function drupalLogout({ silent = false } = {}, callback) {
+ const self = this;
+
+ this.drupalRelativeURL('/user/logout');
+
+ this.drupalUserIsLoggedIn((sessionExists) => {
+ if (silent) {
+ if (sessionExists) {
+ throw new Error('Logging out failed.');
+ }
+ }
+ else {
+ this.assert.equal(sessionExists, false, 'The user was logged out.');
+ }
+ });
+
+ if (typeof callback === 'function') {
+ callback.call(self);
+ }
+
+ return this;
+};
diff --git a/core/tests/Drupal/Nightwatch/Commands/drupalUserIsLoggedIn.js b/core/tests/Drupal/Nightwatch/Commands/drupalUserIsLoggedIn.js
new file mode 100644
index 0000000..e5db1c1
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Commands/drupalUserIsLoggedIn.js
@@ -0,0 +1,19 @@
+/**
+ * Checks if a user is logged in.
+ *
+ * @param {function} callback
+ * A callback which will be called, when the login status has been checked.
+ * @return {object}
+ * The drupalUserIsLoggedIn command.
+ */
+exports.command = function drupalUserIsLoggedIn(callback) {
+ if (typeof callback === 'function') {
+ this.getCookies((cookies) => {
+ const sessionExists = cookies.value.some(cookie => cookie.name.match(/^SESS/));
+
+ callback.call(this, sessionExists);
+ });
+ }
+
+ return this;
+};
diff --git a/core/tests/Drupal/Nightwatch/Tests/loginTest.js b/core/tests/Drupal/Nightwatch/Tests/loginTest.js
new file mode 100644
index 0000000..3c62d73
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Tests/loginTest.js
@@ -0,0 +1,24 @@
+module.exports = {
+ '@tags': ['core'],
+
+ before(browser) {
+ browser
+ .drupalInstall();
+ },
+ after(browser) {
+ browser
+ .drupalUninstall();
+ },
+
+ 'Test login': (browser) => {
+ browser
+ .drupalCreateUser({
+ name: 'user',
+ password: '123',
+ permissions: ['access site reports'],
+ })
+ .drupalLogin({ name: 'user', password: '123' })
+ .drupalRelativeURL('/admin/reports')
+ .expect.element('h1.page-title').text.to.contain('Reports');
+ },
+};
diff --git a/core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php b/core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php
index 50167bf..d020304 100644
--- a/core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php
+++ b/core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php
@@ -102,6 +102,7 @@ class TestSiteInstallCommand extends Command {
$output->writeln(json_encode([
'db_prefix' => $this->databasePrefix,
'user_agent' => $user_agent,
+ 'site_path' => $this->siteDirectory,
]));
}
else {
@@ -110,6 +111,7 @@ class TestSiteInstallCommand extends Command {
$io->table([], [
['Database prefix', $this->databasePrefix],
['User agent', $user_agent],
+ ['Site path', $this->siteDirectory],
]);
}
}
diff --git a/core/tests/Drupal/TestSite/Commands/TestSiteUserLoginCommand.php b/core/tests/Drupal/TestSite/Commands/TestSiteUserLoginCommand.php
new file mode 100644
index 0000000..55c9203
--- /dev/null
+++ b/core/tests/Drupal/TestSite/Commands/TestSiteUserLoginCommand.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\TestSite\Commands;
+
+use Drupal\Core\DrupalKernel;
+use Drupal\Core\Site\Settings;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Command to generate a login link for the test site.
+ *
+ * @internal
+ */
+class TestSiteUserLoginCommand extends Command {
+
+ /**
+ * The class loader to use for installation and initialization of setup.
+ *
+ * @var \Symfony\Component\Classloader\Classloader
+ */
+ protected $classLoader;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure() {
+ $this->setName('user-login')
+ ->setDescription('Generate a one time login link for an user.')
+ ->addArgument('uid', InputArgument::REQUIRED, 'The ID of the user for whom the link will be generated')
+ ->addOption('site-path', NULL, InputOption::VALUE_REQUIRED, 'The path for the test site.');
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $root = dirname(dirname(dirname(dirname(dirname(__DIR__)))));
+ chdir($root);
+
+ $this->classLoader = require 'autoload.php';
+ $kernel = new DrupalKernel('prod', $this->classLoader, FALSE);
+ $kernel::bootEnvironment();
+ $kernel->setSitePath($input->getOption('site-path'));
+ Settings::initialize($kernel->getAppRoot(), $kernel->getSitePath(), $this->classLoader);
+
+ $request = Request::createFromGlobals();
+ $kernel->prepareLegacyRequest($request);
+
+ $kernel->boot();
+
+ $container = $kernel->getContainer();
+ $uid = $input->getArgument('uid');
+ if (!is_numeric($uid)) {
+ throw new InvalidArgumentException(sprintf('The "uid" argument needs to be an integer, but it is "%s".', $uid));
+ }
+ $userEntity = $container->get('entity_type.manager')
+ ->getStorage('user')
+ ->load($uid);
+ $url = user_pass_reset_url($userEntity) . '/login';
+ $output->writeln($url);
+ }
+
+}
diff --git a/core/tests/Drupal/TestSite/TestSiteApplication.php b/core/tests/Drupal/TestSite/TestSiteApplication.php
index eba29d8..d67c485 100644
--- a/core/tests/Drupal/TestSite/TestSiteApplication.php
+++ b/core/tests/Drupal/TestSite/TestSiteApplication.php
@@ -5,6 +5,7 @@ namespace Drupal\TestSite;
use Drupal\TestSite\Commands\TestSiteInstallCommand;
use Drupal\TestSite\Commands\TestSiteReleaseLocksCommand;
use Drupal\TestSite\Commands\TestSiteTearDownCommand;
+use Drupal\TestSite\Commands\TestSiteUserLoginCommand;
use Symfony\Component\Console\Application;
/**
@@ -25,6 +26,7 @@ class TestSiteApplication extends Application {
$default_commands[] = new TestSiteInstallCommand();
$default_commands[] = new TestSiteTearDownCommand();
$default_commands[] = new TestSiteReleaseLocksCommand();
+ $default_commands[] = new TestSiteUserLoginCommand();
return $default_commands;
}
diff --git a/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php b/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php
index 50d9f99..d3c6444 100644
--- a/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php
+++ b/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php
@@ -29,10 +29,19 @@ use Symfony\Component\Process\Process;
class TestSiteApplicationTest extends UnitTestCase {
/**
+ * The PHP executable path.
+ *
+ * @var string
+ */
+ protected $php;
+
+ /**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
+ $php_executable_finder = new PhpExecutableFinder();
+ $this->php = $php_executable_finder->find();
$this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
}
@@ -40,14 +49,12 @@ class TestSiteApplicationTest extends UnitTestCase {
* @coversNothing
*/
public function testInstallWithNonExistingFile() {
- $php_binary_finder = new PhpExecutableFinder();
- $php_binary_path = $php_binary_finder->find();
// Create a connection to the DB configured in SIMPLETEST_DB.
$connection = Database::getConnection('default', $this->addTestDatabase(''));
$table_count = count($connection->schema()->findTables('%'));
- $command_line = $php_binary_path . ' core/scripts/test-site.php install --setup-file "this-class-does-not-exist" --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php install --setup-file "this-class-does-not-exist" --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
$process->run();
@@ -60,14 +67,12 @@ class TestSiteApplicationTest extends UnitTestCase {
* @coversNothing
*/
public function testInstallWithFileWithNoClass() {
- $php_binary_finder = new PhpExecutableFinder();
- $php_binary_path = $php_binary_finder->find();
// Create a connection to the DB configured in SIMPLETEST_DB.
$connection = Database::getConnection('default', $this->addTestDatabase(''));
$table_count = count($connection->schema()->findTables('%'));
- $command_line = $php_binary_path . ' core/scripts/test-site.php install --setup-file core/tests/fixtures/empty_file.php.module --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php install --setup-file core/tests/fixtures/empty_file.php.module --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
$process->run();
@@ -80,15 +85,13 @@ class TestSiteApplicationTest extends UnitTestCase {
* @coversNothing
*/
public function testInstallWithNonSetupClass() {
- $php_binary_finder = new PhpExecutableFinder();
- $php_binary_path = $php_binary_finder->find();
// Create a connection to the DB configured in SIMPLETEST_DB.
$connection = Database::getConnection('default', $this->addTestDatabase(''));
$table_count = count($connection->schema()->findTables('%'));
// Use __FILE__ to test absolute paths.
- $command_line = $php_binary_path . ' core/scripts/test-site.php install --setup-file "' . __FILE__ . '" --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php install --setup-file "' . __FILE__ . '" --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root, ['COLUMNS' => PHP_INT_MAX]);
$process->run();
@@ -106,11 +109,9 @@ class TestSiteApplicationTest extends UnitTestCase {
if (!is_writable($simpletest_path)) {
$this->markTestSkipped("Requires the directory $simpletest_path to exist and be writable");
}
- $php_binary_finder = new PhpExecutableFinder();
- $php_binary_path = $php_binary_finder->find();
// Install a site using the JSON output.
- $command_line = $php_binary_path . ' core/scripts/test-site.php install --json --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php install --json --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
// Set the timeout to a value that allows debugging.
$process->setTimeout(500);
@@ -142,7 +143,7 @@ class TestSiteApplicationTest extends UnitTestCase {
// Install another site so we can ensure the tear down command only removes
// one site at a time. Use the regular output.
- $command_line = $php_binary_path . ' core/scripts/test-site.php install --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php install --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
// Set the timeout to a value that allows debugging.
$process->setTimeout(500);
@@ -160,7 +161,7 @@ class TestSiteApplicationTest extends UnitTestCase {
$this->assertFileExists($this->getTestLockFile($other_db_prefix));
// Now test the tear down process as well, but keep the lock.
- $command_line = $php_binary_path . ' core/scripts/test-site.php tear-down ' . $db_prefix . ' --keep-lock --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php tear-down ' . $db_prefix . ' --keep-lock --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
// Set the timeout to a value that allows debugging.
$process->setTimeout(500);
@@ -182,7 +183,7 @@ class TestSiteApplicationTest extends UnitTestCase {
// broken. Prove this by removing its settings.php.
$test_site_settings = $this->root . DIRECTORY_SEPARATOR . $test_database->getTestSitePath() . DIRECTORY_SEPARATOR . 'settings.php';
$this->assertTrue(unlink($test_site_settings));
- $command_line = $php_binary_path . ' core/scripts/test-site.php tear-down ' . $other_db_prefix . ' --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php tear-down ' . $other_db_prefix . ' --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
// Set the timeout to a value that allows debugging.
$process->setTimeout(500);
@@ -208,10 +209,8 @@ class TestSiteApplicationTest extends UnitTestCase {
if (!is_writable($simpletest_path)) {
$this->markTestSkipped("Requires the directory $simpletest_path to exist and be writable");
}
- $php_binary_finder = new PhpExecutableFinder();
- $php_binary_path = $php_binary_finder->find();
- $command_line = $php_binary_path . ' core/scripts/test-site.php install --json --langcode fr --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php install --json --langcode fr --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
$process->setTimeout(500);
$process->run();
@@ -229,7 +228,7 @@ class TestSiteApplicationTest extends UnitTestCase {
$this->assertContains('lang="fr"', (string) $response->getBody());
// Now test the tear down process as well.
- $command_line = $php_binary_path . ' core/scripts/test-site.php tear-down ' . $db_prefix . ' --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $command_line = $this->php . ' core/scripts/test-site.php tear-down ' . $db_prefix . ' --db-url "' . getenv('SIMPLETEST_DB') . '"';
$process = new Process($command_line, $this->root);
$process->setTimeout(500);
$process->run();
@@ -243,10 +242,7 @@ class TestSiteApplicationTest extends UnitTestCase {
* @coversNothing
*/
public function testTearDownDbPrefixValidation() {
- $php_binary_finder = new PhpExecutableFinder();
- $php_binary_path = $php_binary_finder->find();
-
- $command_line = $php_binary_path . ' core/scripts/test-site.php tear-down not-a-valid-prefix';
+ $command_line = $this->php . ' core/scripts/test-site.php tear-down not-a-valid-prefix';
$process = new Process($command_line, $this->root);
$process->setTimeout(500);
$process->run();
@@ -255,6 +251,61 @@ class TestSiteApplicationTest extends UnitTestCase {
}
/**
+ * @coversNothing
+ */
+ public function testUserLogin() {
+ $simpletest_path = $this->root . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . 'simpletest';
+ if (!is_writable($simpletest_path)) {
+ $this->markTestSkipped("Requires the directory $simpletest_path to exist and be writable");
+ }
+
+ // Install a site using the JSON output.
+ $command_line = $this->php . ' core/scripts/test-site.php install --json --setup-file core/tests/Drupal/TestSite/TestSiteInstallTestScript.php --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $process = new Process($command_line, $this->root);
+ // Set the timeout to a value that allows debugging.
+ $process->setTimeout(500);
+ $process->run();
+
+ $this->assertSame(0, $process->getExitCode());
+ $result = json_decode($process->getOutput(), TRUE);
+ $db_prefix = $result['db_prefix'];
+ $site_path = $result['site_path'];
+ $this->assertSame('sites/simpletest/' . str_replace('test', '', $db_prefix), $site_path);
+
+ // Test the user login command with valid uid.
+ $command_line = $this->php . ' core/scripts/test-site.php user-login 1 --site-path ' . $site_path;
+ $process = new Process($command_line, $this->root);
+ $process->run();
+ $this->assertSame(0, $process->getExitCode());
+ $this->assertContains('/user/reset/1/', $process->getOutput());
+
+ $http_client = new Client();
+ $request = (new Request('GET', getenv('SIMPLETEST_BASE_URL') . trim($process->getOutput())))
+ ->withHeader('User-Agent', trim($result['user_agent']));
+
+ $response = $http_client->send($request);
+
+ // Ensure the response sets a new session.
+ $this->assertTrue($response->getHeader('Set-Cookie'));
+
+ // Test the user login command with invalid uid.
+ $command_line = $this->php . ' core/scripts/test-site.php user-login invalid-uid --site-path ' . $site_path;
+ $process = new Process($command_line, $this->root);
+ $process->run();
+ $this->assertSame(1, $process->getExitCode());
+ $this->assertContains('The "uid" argument needs to be an integer, but it is "invalid-uid".', $process->getErrorOutput());
+
+ // Now tear down the test site.
+ $command_line = $this->php . ' core/scripts/test-site.php tear-down ' . $db_prefix . ' --db-url "' . getenv('SIMPLETEST_DB') . '"';
+ $process = new Process($command_line, $this->root);
+ // Set the timeout to a value that allows debugging.
+ $process->setTimeout(500);
+ $process->run();
+ $this->assertSame(0, $process->getExitCode());
+ $this->assertContains("Successfully uninstalled $db_prefix test site", $process->getOutput());
+ }
+
+ /**
* Adds the installed test site to the database connection info.
*
* @param string $db_prefix