Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Drupal\FunctionalTests;
|
||||
|
||||
use Behat\Mink\Exception\ElementNotFoundException;
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Behat\Mink\Exception\ExpectationException;
|
||||
use Behat\Mink\Selector\Xpath\Escaper;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
|
@ -220,13 +220,11 @@ trait AssertLegacyTrait {
|
|||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldExists() or
|
||||
* $this->assertSession()->buttonExists() or
|
||||
* $this->assertSession()->fieldValueEquals() instead.
|
||||
*/
|
||||
protected function assertFieldByName($name, $value = NULL) {
|
||||
$this->assertSession()->fieldExists($name);
|
||||
if ($value !== NULL) {
|
||||
$this->assertSession()->fieldValueEquals($name, (string) $value);
|
||||
}
|
||||
$this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,15 +240,11 @@ trait AssertLegacyTrait {
|
|||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldNotExists() or
|
||||
* $this->assertSession()->buttonNotExists() or
|
||||
* $this->assertSession()->fieldValueNotEquals() instead.
|
||||
*/
|
||||
protected function assertNoFieldByName($name, $value = '') {
|
||||
if ($this->getSession()->getPage()->findField($name) && isset($value)) {
|
||||
$this->assertSession()->fieldValueNotEquals($name, (string) $value);
|
||||
}
|
||||
else {
|
||||
$this->assertSession()->fieldNotExists($name);
|
||||
}
|
||||
$this->assertNoFieldByXPath($this->constructFieldXpath('name', $name), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,19 +262,11 @@ trait AssertLegacyTrait {
|
|||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldExists() or
|
||||
* $this->assertSession()->buttonExists() or
|
||||
* $this->assertSession()->fieldValueEquals() instead.
|
||||
*/
|
||||
protected function assertFieldById($id, $value = '') {
|
||||
$xpath = $this->assertSession()->buildXPathQuery('//textarea[@id=:value]|//input[@id=:value]|//select[@id=:value]', [':value' => $id]);
|
||||
$field = $this->getSession()->getPage()->find('xpath', $xpath);
|
||||
|
||||
if (empty($field)) {
|
||||
throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id', $field);
|
||||
}
|
||||
|
||||
if ($value !== NULL) {
|
||||
$this->assertEquals($value, $field->getValue());
|
||||
}
|
||||
$this->assertFieldByXPath($this->constructFieldXpath('id', $id), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -290,23 +276,25 @@ trait AssertLegacyTrait {
|
|||
* Name or ID of field to assert.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldExists() instead.
|
||||
* Use $this->assertSession()->fieldExists() or
|
||||
* $this->assertSession()->buttonExists() instead.
|
||||
*/
|
||||
protected function assertField($field) {
|
||||
$this->assertSession()->fieldExists($field);
|
||||
$this->assertFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a field exists with the given name or ID does NOT exist.
|
||||
* Asserts that a field does NOT exist with the given name or ID.
|
||||
*
|
||||
* @param string $field
|
||||
* Name or ID of field to assert.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldNotExists() instead.
|
||||
* Use $this->assertSession()->fieldNotExists() or
|
||||
* $this->assertSession()->buttonNotExists() instead.
|
||||
*/
|
||||
protected function assertNoField($field) {
|
||||
$this->assertSession()->fieldNotExists($field);
|
||||
$this->assertNoFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -427,23 +415,11 @@ trait AssertLegacyTrait {
|
|||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldNotExists() or
|
||||
* $this->assertSession()->buttonNotExists() or
|
||||
* $this->assertSession()->fieldValueNotEquals() instead.
|
||||
*/
|
||||
protected function assertNoFieldById($id, $value = '') {
|
||||
$xpath = $this->assertSession()->buildXPathQuery('//textarea[@id=:value]|//input[@id=:value]|//select[@id=:value]', [':value' => $id]);
|
||||
$field = $this->getSession()->getPage()->find('xpath', $xpath);
|
||||
|
||||
// Return early if the field could not be found as expected.
|
||||
if ($field === NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($value)) {
|
||||
throw new ExpectationException(sprintf('Id "%s" appears on this page, but it should not.', $id), $this->getSession()->getDriver());
|
||||
}
|
||||
elseif ($value === $field->getValue()) {
|
||||
throw new ExpectationException(sprintf('Failed asserting that %s is not equal to %s', $field->getValue(), $value), $this->getSession()->getDriver());
|
||||
}
|
||||
$this->assertNoFieldByXPath($this->constructFieldXpath('id', $id), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -585,25 +561,32 @@ trait AssertLegacyTrait {
|
|||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages with t().
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ExpectationException
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->xpath() instead and assert that the result is empty.
|
||||
*/
|
||||
protected function assertNoFieldByXPath($xpath, $value = NULL, $message = '') {
|
||||
$fields = $this->xpath($xpath);
|
||||
|
||||
// If value specified then check array for match.
|
||||
$found = TRUE;
|
||||
if (isset($value)) {
|
||||
$found = FALSE;
|
||||
if ($fields) {
|
||||
foreach ($fields as $field) {
|
||||
if ($field->getAttribute('value') == $value) {
|
||||
$found = TRUE;
|
||||
}
|
||||
if (!empty($fields)) {
|
||||
if (isset($value)) {
|
||||
$found = FALSE;
|
||||
try {
|
||||
$this->assertFieldsByValue($fields, $value);
|
||||
$found = TRUE;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
throw new ExpectationException(sprintf('The field resulting from %s was found with the provided value %s.', $xpath, $value), $this->getSession()->getDriver());
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new ExpectationException(sprintf('The field resulting from %s was found.', $xpath), $this->getSession()->getDriver());
|
||||
}
|
||||
}
|
||||
return $this->assertFalse($fields && $found, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -629,7 +612,15 @@ trait AssertLegacyTrait {
|
|||
$found = FALSE;
|
||||
if ($fields) {
|
||||
foreach ($fields as $field) {
|
||||
if ($field->getAttribute('value') == $value) {
|
||||
if ($field->getAttribute('type') == 'checkbox') {
|
||||
if (is_bool($value)) {
|
||||
$found = $field->isChecked() == $value;
|
||||
}
|
||||
else {
|
||||
$found = TRUE;
|
||||
}
|
||||
}
|
||||
elseif ($field->getAttribute('value') == $value) {
|
||||
// Input element with correct value.
|
||||
$found = TRUE;
|
||||
}
|
||||
|
@ -637,8 +628,12 @@ trait AssertLegacyTrait {
|
|||
// Select element with an option.
|
||||
$found = TRUE;
|
||||
}
|
||||
elseif ($field->getText() == $value) {
|
||||
// Text area with correct text.
|
||||
elseif ($field->getTagName() === 'textarea' && $field->getValue() == $value) {
|
||||
// Text area with correct text. Use getValue() here because
|
||||
// getText() would remove any newlines in the value.
|
||||
$found = TRUE;
|
||||
}
|
||||
elseif ($field->getTagName() !== 'input' && $field->getText() == $value) {
|
||||
$found = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -719,6 +714,22 @@ trait AssertLegacyTrait {
|
|||
$this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', $expected_cache_tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether an expected cache tag was absent in the last response.
|
||||
*
|
||||
* @param string $cache_tag
|
||||
* The cache tag to check.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->responseHeaderNotContains() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2864029
|
||||
*/
|
||||
protected function assertNoCacheTag($cache_tag) {
|
||||
@trigger_error('assertNoCacheTag() is deprecated and scheduled for removal in Drupal 9.0.0. Use $this->assertSession()->responseHeaderNotContains() instead. See https://www.drupal.org/node/2864029.', E_USER_DEPRECATED);
|
||||
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', $cache_tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that current response header equals value.
|
||||
*
|
||||
|
@ -772,6 +783,25 @@ trait AssertLegacyTrait {
|
|||
return $this->assertSession()->buildXPathQuery($xpath, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Constructs an XPath for the given set of attributes and value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* Field attributes.
|
||||
* @param string $value
|
||||
* Value of field.
|
||||
*
|
||||
* @return string
|
||||
* XPath for specified values.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->getSession()->getPage()->findField() instead.
|
||||
*/
|
||||
protected function constructFieldXpath($attribute, $value) {
|
||||
$xpath = '//textarea[@' . $attribute . '=:value]|//input[@' . $attribute . '=:value]|//select[@' . $attribute . '=:value]';
|
||||
return $this->buildXPathQuery($xpath, [':value' => $value]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current raw content.
|
||||
*
|
||||
|
@ -783,4 +813,21 @@ trait AssertLegacyTrait {
|
|||
return $this->getSession()->getPage()->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all option elements, including nested options, in a select.
|
||||
*
|
||||
* @param \Behat\Mink\Element\NodeElement $element
|
||||
* The element for which to get the options.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement[]
|
||||
* Option elements in select.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $element->findAll('xpath', 'option') instead.
|
||||
*/
|
||||
protected function getAllOptions(NodeElement $element) {
|
||||
@trigger_error('AssertLegacyTrait::getAllOptions() is scheduled for removal in Drupal 9.0.0. Use $element->findAll(\'xpath\', \'option\') instead.', E_USER_DEPRECATED);
|
||||
return $element->findAll('xpath', '//option');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Bootstrap;
|
||||
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
|
||||
/**
|
||||
* Container base class which triggers an error.
|
||||
*/
|
||||
class ErrorContainer extends Container {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
if ($id === 'http_kernel') {
|
||||
// Enforce a recoverable error.
|
||||
$callable = function (ErrorContainer $container) {
|
||||
};
|
||||
$callable(1);
|
||||
}
|
||||
else {
|
||||
return parent::get($id, $invalidBehavior);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Bootstrap;
|
||||
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
|
||||
/**
|
||||
* Base container which throws an exception.
|
||||
*/
|
||||
class ExceptionContainer extends Container {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
if ($id === 'http_kernel') {
|
||||
throw new \Exception('Thrown exception during Container::get');
|
||||
}
|
||||
else {
|
||||
return parent::get($id, $invalidBehavior);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,375 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Bootstrap;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests kernel panic when things are really messed up.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class UncaughtExceptionTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Last cURL response.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $response = '';
|
||||
|
||||
/**
|
||||
* Last cURL info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info = [];
|
||||
|
||||
/**
|
||||
* Exceptions thrown by site under test that contain this text are ignored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $expectedExceptionMessage;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['error_service_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$settings_filename = $this->siteDirectory . '/settings.php';
|
||||
chmod($settings_filename, 0777);
|
||||
$settings_php = file_get_contents($settings_filename);
|
||||
$settings_php .= "\ninclude_once 'core/tests/Drupal/FunctionalTests/Bootstrap/ErrorContainer.php';\n";
|
||||
$settings_php .= "\ninclude_once 'core/tests/Drupal/FunctionalTests/Bootstrap/ExceptionContainer.php';\n";
|
||||
file_put_contents($settings_filename, $settings_php);
|
||||
|
||||
$settings = [];
|
||||
$settings['config']['system.logging']['error_level'] = (object) [
|
||||
'value' => ERROR_REPORTING_DISPLAY_VERBOSE,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uncaught exception handling when system is in a bad state.
|
||||
*/
|
||||
public function testUncaughtException() {
|
||||
$this->expectedExceptionMessage = 'Oh oh, bananas in the instruments.';
|
||||
\Drupal::state()->set('error_service_test.break_bare_html_renderer', TRUE);
|
||||
|
||||
$this->config('system.logging')
|
||||
->set('error_level', ERROR_REPORTING_HIDE)
|
||||
->save();
|
||||
$settings = [];
|
||||
$settings['config']['system.logging']['error_level'] = (object) [
|
||||
'value' => ERROR_REPORTING_HIDE,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertNoText($this->expectedExceptionMessage);
|
||||
|
||||
$this->config('system.logging')
|
||||
->set('error_level', ERROR_REPORTING_DISPLAY_ALL)
|
||||
->save();
|
||||
$settings = [];
|
||||
$settings['config']['system.logging']['error_level'] = (object) [
|
||||
'value' => ERROR_REPORTING_DISPLAY_ALL,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertText($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uncaught exception handling with custom exception handler.
|
||||
*/
|
||||
public function testUncaughtExceptionCustomExceptionHandler() {
|
||||
$settings_filename = $this->siteDirectory . '/settings.php';
|
||||
chmod($settings_filename, 0777);
|
||||
$settings_php = file_get_contents($settings_filename);
|
||||
$settings_php .= "\n";
|
||||
$settings_php .= "set_exception_handler(function() {\n";
|
||||
$settings_php .= " header('HTTP/1.1 418 I\'m a teapot');\n";
|
||||
$settings_php .= " print('Oh oh, flying teapots');\n";
|
||||
$settings_php .= "});\n";
|
||||
file_put_contents($settings_filename, $settings_php);
|
||||
|
||||
\Drupal::state()->set('error_service_test.break_bare_html_renderer', TRUE);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(418);
|
||||
$this->assertNoText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertNoText('Oh oh, bananas in the instruments');
|
||||
$this->assertText('Oh oh, flying teapots');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a missing dependency on a service.
|
||||
*/
|
||||
public function testMissingDependency() {
|
||||
if (version_compare(PHP_VERSION, '7.1') < 0) {
|
||||
$this->expectedExceptionMessage = 'Argument 1 passed to Drupal\error_service_test\LonelyMonkeyClass::__construct() must be an instance of Drupal\Core\Database\Connection, non';
|
||||
}
|
||||
else {
|
||||
$this->expectedExceptionMessage = 'Too few arguments to function Drupal\error_service_test\LonelyMonkeyClass::__construct(), 0 passed';
|
||||
}
|
||||
$this->drupalGet('broken-service-class');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->assertRaw('The website encountered an unexpected error.');
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a missing dependency on a service with a custom error handler.
|
||||
*/
|
||||
public function testMissingDependencyCustomErrorHandler() {
|
||||
$settings_filename = $this->siteDirectory . '/settings.php';
|
||||
chmod($settings_filename, 0777);
|
||||
$settings_php = file_get_contents($settings_filename);
|
||||
$settings_php .= "\n";
|
||||
$settings_php .= "set_error_handler(function() {\n";
|
||||
$settings_php .= " header('HTTP/1.1 418 I\'m a teapot');\n";
|
||||
$settings_php .= " print('Oh oh, flying teapots');\n";
|
||||
$settings_php .= " exit();\n";
|
||||
$settings_php .= "});\n";
|
||||
$settings_php .= "\$settings['teapots'] = TRUE;\n";
|
||||
file_put_contents($settings_filename, $settings_php);
|
||||
|
||||
$this->drupalGet('broken-service-class');
|
||||
$this->assertResponse(418);
|
||||
$this->assertSame('Oh oh, flying teapots', $this->response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a container which has an error.
|
||||
*/
|
||||
public function testErrorContainer() {
|
||||
$settings = [];
|
||||
$settings['settings']['container_base_class'] = (object) [
|
||||
'value' => '\Drupal\FunctionalTests\Bootstrap\ErrorContainer',
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
\Drupal::service('kernel')->invalidateContainer();
|
||||
|
||||
$this->expectedExceptionMessage = 'Argument 1 passed to Drupal\FunctionalTests\Bootstrap\ErrorContainer::Drupal\FunctionalTests\Bootstrap\{closur';
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a container which has an exception really early.
|
||||
*/
|
||||
public function testExceptionContainer() {
|
||||
$settings = [];
|
||||
$settings['settings']['container_base_class'] = (object) [
|
||||
'value' => '\Drupal\FunctionalTests\Bootstrap\ExceptionContainer',
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
\Drupal::service('kernel')->invalidateContainer();
|
||||
|
||||
$this->expectedExceptionMessage = 'Thrown exception during Container::get';
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->assertRaw('The website encountered an unexpected error');
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the case when the database connection is gone.
|
||||
*/
|
||||
public function testLostDatabaseConnection() {
|
||||
$incorrect_username = $this->randomMachineName(16);
|
||||
switch ($this->container->get('database')->driver()) {
|
||||
case 'pgsql':
|
||||
case 'mysql':
|
||||
$this->expectedExceptionMessage = $incorrect_username;
|
||||
break;
|
||||
default:
|
||||
// We can not carry out this test.
|
||||
$this->pass('Unable to run \Drupal\system\Tests\System\UncaughtExceptionTest::testLostDatabaseConnection for this database type.');
|
||||
return;
|
||||
}
|
||||
|
||||
// We simulate a broken database connection by rewrite settings.php to no
|
||||
// longer have the proper data.
|
||||
$settings['databases']['default']['default']['username'] = (object) [
|
||||
'value' => $incorrect_username,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$settings['databases']['default']['default']['password'] = (object) [
|
||||
'value' => $this->randomMachineName(16),
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertRaw('DatabaseAccessDeniedException');
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests fallback to PHP error log when an exception is thrown while logging.
|
||||
*/
|
||||
public function testLoggerException() {
|
||||
// Ensure the test error log is empty before these tests.
|
||||
$this->assertNoErrorsLogged();
|
||||
|
||||
$this->expectedExceptionMessage = 'Deforestation';
|
||||
\Drupal::state()->set('error_service_test.break_logger', TRUE);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
|
||||
// Find fatal error logged to the error.log
|
||||
$errors = file(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
$this->assertIdentical(count($errors), 8, 'The error + the error that the logging service is broken has been written to the error log.');
|
||||
$this->assertTrue(strpos($errors[0], 'Failed to log error') !== FALSE, 'The error handling logs when an error could not be logged to the logger.');
|
||||
|
||||
$expected_path = \Drupal::root() . '/core/modules/system/tests/modules/error_service_test/src/MonkeysInTheControlRoom.php';
|
||||
$expected_line = 59;
|
||||
$expected_entry = "Failed to log error: Exception: Deforestation in Drupal\\error_service_test\\MonkeysInTheControlRoom->handle() (line ${expected_line} of ${expected_path})";
|
||||
$this->assert(strpos($errors[0], $expected_entry) !== FALSE, 'Original error logged to the PHP error log when an exception is thrown by a logger');
|
||||
|
||||
// The exception is expected. Do not interpret it as a test failure. Not
|
||||
// using File API; a potential error must trigger a PHP warning.
|
||||
unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a specific error has been logged to the PHP error log.
|
||||
*
|
||||
* @param string $error_message
|
||||
* The expected error message.
|
||||
*
|
||||
* @see \Drupal\simpletest\TestBase::prepareEnvironment()
|
||||
* @see \Drupal\Core\DrupalKernel::bootConfiguration()
|
||||
*/
|
||||
protected function assertErrorLogged($error_message) {
|
||||
$error_log_filename = DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log';
|
||||
if (!file_exists($error_log_filename)) {
|
||||
$this->fail('No error logged yet.');
|
||||
}
|
||||
|
||||
$content = file_get_contents($error_log_filename);
|
||||
$rows = explode(PHP_EOL, $content);
|
||||
|
||||
// We iterate over the rows in order to be able to remove the logged error
|
||||
// afterwards.
|
||||
$found = FALSE;
|
||||
foreach ($rows as $row_index => $row) {
|
||||
if (strpos($content, $error_message) !== FALSE) {
|
||||
$found = TRUE;
|
||||
unset($rows[$row_index]);
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($error_log_filename, implode("\n", $rows));
|
||||
|
||||
$this->assertTrue($found, sprintf('The %s error message was logged.', $error_message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that no errors have been logged to the PHP error.log thus far.
|
||||
*
|
||||
* @see \Drupal\simpletest\TestBase::prepareEnvironment()
|
||||
* @see \Drupal\Core\DrupalKernel::bootConfiguration()
|
||||
*/
|
||||
protected function assertNoErrorsLogged() {
|
||||
// Since PHP only creates the error.log file when an actual error is
|
||||
// triggered, it is sufficient to check whether the file exists.
|
||||
$this->assertFalse(file_exists(DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log'), 'PHP error.log is empty.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a Drupal path or an absolute path.
|
||||
*
|
||||
* Executes a cURL request for processing errors and exceptions.
|
||||
*
|
||||
* @param string|\Drupal\Core\Url $path
|
||||
* Request path.
|
||||
* @param array $extra_options
|
||||
* (optional) Curl options to pass to curl_setopt()
|
||||
* @param array $headers
|
||||
* (optional) Not used.
|
||||
*/
|
||||
protected function drupalGet($path, array $extra_options = [], array $headers = []) {
|
||||
$url = $this->buildUrl($path, ['absolute' => TRUE]);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, FALSE);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, drupal_generate_test_ua($this->databasePrefix));
|
||||
$this->response = curl_exec($ch);
|
||||
$this->info = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function assertResponse($code) {
|
||||
$this->assertSame($code, $this->info['http_code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function assertText($text) {
|
||||
$this->assertContains($text, $this->response);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function assertNoText($text) {
|
||||
$this->assertNotContains($text, $this->response);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function assertRaw($text) {
|
||||
$this->assertText($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function assertNoRaw($text) {
|
||||
$this->assertNoText($text);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\FunctionalTests;
|
||||
|
||||
use Behat\Mink\Exception\ExpectationException;
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
@ -22,7 +23,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['test_page_test', 'form_test', 'system_test'];
|
||||
public static $modules = ['test_page_test', 'form_test', 'system_test', 'node'];
|
||||
|
||||
/**
|
||||
* Tests basic page test.
|
||||
|
@ -66,6 +67,21 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertSame('header value', $returned_header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests drupalGet().
|
||||
*/
|
||||
public function testDrupalGet() {
|
||||
$this->drupalGet('test-page');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->addressEquals('test-page');
|
||||
$this->drupalGet('/test-page');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->addressEquals('test-page');
|
||||
$this->drupalGet('/test-page/');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->addressEquals('/test-page/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests basic form functionality.
|
||||
*/
|
||||
|
@ -98,13 +114,27 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
|
||||
// Test drupalPostForm().
|
||||
$edit = ['bananas' => 'red'];
|
||||
$this->drupalPostForm('form-test/object-builder', $edit, 'Save');
|
||||
$result = $this->drupalPostForm('form-test/object-builder', $edit, 'Save');
|
||||
$this->assertSame($this->getSession()->getPage()->getContent(), $result);
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertSame('red', $value);
|
||||
|
||||
$this->drupalPostForm('form-test/object-builder', NULL, 'Save');
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertSame('', $value);
|
||||
|
||||
// Test drupalPostForm() with no-html response.
|
||||
$values = Json::decode($this->drupalPostForm('form_test/form-state-values-clean', [], t('Submit')));
|
||||
$this->assertTrue(1000, $values['beer']);
|
||||
|
||||
// Test drupalPostForm() with form by HTML id.
|
||||
$this->drupalCreateContentType(['type' => 'page']);
|
||||
$this->drupalLogin($this->drupalCreateUser(['create page content']));
|
||||
$this->drupalGet('form-test/two-instances-of-same-form');
|
||||
$this->getSession()->getPage()->fillField('edit-title-0-value', 'form1');
|
||||
$this->getSession()->getPage()->fillField('edit-title-0-value--2', 'form2');
|
||||
$this->drupalPostForm(NULL, [], 'Save', [], 'node-page-form--2');
|
||||
$this->assertSession()->pageTextContains('Page form2 has been created.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,10 +167,52 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertSession()->linkExists('foo|bar|baz');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests linkExistsExact() functionality.
|
||||
*
|
||||
* @see \Drupal\Tests\WebAssert::linkExistsExact()
|
||||
*/
|
||||
public function testLinkExistsExact() {
|
||||
$this->drupalGet('test-pipe-char');
|
||||
$this->assertSession()->linkExistsExact('foo|bar|baz');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests linkExistsExact() functionality fail.
|
||||
*
|
||||
* @see \Drupal\Tests\WebAssert::linkExistsExact()
|
||||
*/
|
||||
public function testInvalidLinkExistsExact() {
|
||||
$this->drupalGet('test-pipe-char');
|
||||
$this->setExpectedException(ExpectationException::class, 'Link with label foo|bar found');
|
||||
$this->assertSession()->linkExistsExact('foo|bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests linkNotExistsExact() functionality.
|
||||
*
|
||||
* @see \Drupal\Tests\WebAssert::linkNotExistsExact()
|
||||
*/
|
||||
public function testLinkNotExistsExact() {
|
||||
$this->drupalGet('test-pipe-char');
|
||||
$this->assertSession()->linkNotExistsExact('foo|bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests linkNotExistsExact() functionality fail.
|
||||
*
|
||||
* @see \Drupal\Tests\WebAssert::linkNotExistsExact()
|
||||
*/
|
||||
public function testInvalidLinkNotExistsExact() {
|
||||
$this->drupalGet('test-pipe-char');
|
||||
$this->setExpectedException(ExpectationException::class, 'Link with label foo|bar|baz not found');
|
||||
$this->assertSession()->linkNotExistsExact('foo|bar|baz');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy text asserts.
|
||||
*/
|
||||
public function testLegacyTextAsserts() {
|
||||
public function testTextAsserts() {
|
||||
$this->drupalGet('test-encoded');
|
||||
$dangerous = 'Bad html <script>alert(123);</script>';
|
||||
$sanitized = Html::escape($dangerous);
|
||||
|
@ -148,13 +220,13 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertText($sanitized);
|
||||
|
||||
// Test getRawContent().
|
||||
$this->assertSame($this->getSession()->getPage()->getContent(), $this->getRawContent());
|
||||
$this->assertSame($this->getSession()->getPage()->getContent(), $this->getSession()->getPage()->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts which use xpath directly.
|
||||
*/
|
||||
public function testLegacyXpathAsserts() {
|
||||
public function testXpathAsserts() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
$this->assertFieldsByValue($this->xpath("//h1[@class = 'page-title']"), NULL);
|
||||
$this->assertFieldsByValue($this->xpath('//table/tbody/tr[2]/td[1]'), 'one');
|
||||
|
@ -181,7 +253,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertNoFieldByXPath("//input[@id = 'edit-name']");
|
||||
$this->fail('The "edit-name" field was not found.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoFieldByXPath correctly failed. The "edit-name" field was found.');
|
||||
}
|
||||
|
||||
|
@ -197,7 +269,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
/**
|
||||
* Tests legacy field asserts using textfields.
|
||||
*/
|
||||
public function testLegacyFieldAssertsWithTextfields() {
|
||||
public function testFieldAssertsForTextfields() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// *** 1. assertNoField().
|
||||
|
@ -230,7 +302,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertField('invalid_name_and_id');
|
||||
$this->fail('The "invalid_name_and_id" field was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('assertField correctly failed. The "invalid_name_and_id" field was not found.');
|
||||
}
|
||||
|
||||
|
@ -319,7 +391,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertFieldByName('non-existing-name');
|
||||
$this->fail('The "non-existing-name" field was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('The "non-existing-name" field was not found');
|
||||
}
|
||||
|
||||
|
@ -328,15 +400,18 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertFieldByName('name', 'not the value');
|
||||
$this->fail('The "name" field with incorrect value was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('assertFieldByName correctly failed. The "name" field with incorrect value was not found.');
|
||||
}
|
||||
|
||||
// Test that text areas can contain new lines.
|
||||
$this->assertFieldsByValue($this->xpath("//textarea[@id = 'edit-test-textarea-with-newline']"), "Test text with\nnewline");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts on other types of field.
|
||||
* Tests legacy field asserts for options field type.
|
||||
*/
|
||||
public function testLegacyFieldAssertsWithNonTextfields() {
|
||||
public function testFieldAssertsForOptions() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// Option field type.
|
||||
|
@ -384,7 +459,17 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
// Button field type.
|
||||
// Test \Drupal\FunctionalTests\AssertLegacyTrait::getAllOptions.
|
||||
$this->drupalGet('/form-test/select');
|
||||
$this->assertCount(6, $this->getAllOptions($this->cssSelect('select[name="opt_groups"]')[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts for button field type.
|
||||
*/
|
||||
public function testFieldAssertsForButton() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
$this->assertFieldById('edit-save', NULL);
|
||||
// Test that the assertion fails correctly if the field value is passed in
|
||||
// rather than the id.
|
||||
|
@ -392,7 +477,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertFieldById('Save', NULL);
|
||||
$this->fail('The field with id of "Save" was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
|
@ -407,7 +492,27 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
// Checkbox field type.
|
||||
// Test that multiple fields with the same name are validated correctly.
|
||||
$this->assertFieldByName('duplicate_button', 'Duplicate button 1');
|
||||
$this->assertFieldByName('duplicate_button', 'Duplicate button 2');
|
||||
$this->assertNoFieldByName('duplicate_button', 'Rabbit');
|
||||
|
||||
try {
|
||||
$this->assertNoFieldByName('duplicate_button', 'Duplicate button 2');
|
||||
$this->fail('The "duplicate_button" field with the value Duplicate button 2 was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoFieldByName correctly failed. The "duplicate_button" field with the value Duplicate button 2 was found.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts for checkbox field type.
|
||||
*/
|
||||
public function testFieldAssertsForCheckbox() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// Part 1 - Test by name.
|
||||
// Test that checkboxes are found/not found correctly by name, when using
|
||||
// TRUE or FALSE to match their 'checked' state.
|
||||
$this->assertFieldByName('checkbox_enabled', TRUE);
|
||||
|
@ -420,17 +525,13 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertFieldByName('checkbox_enabled', NULL);
|
||||
$this->assertFieldByName('checkbox_disabled', NULL);
|
||||
|
||||
// Test that checkboxes are found/not found correctly by ID, when using
|
||||
// TRUE or FALSE to match their 'checked' state.
|
||||
$this->assertFieldById('edit-checkbox-enabled', TRUE);
|
||||
$this->assertFieldById('edit-checkbox-disabled', FALSE);
|
||||
$this->assertNoFieldById('edit-checkbox-enabled', FALSE);
|
||||
$this->assertNoFieldById('edit-checkbox-disabled', TRUE);
|
||||
// Test that checkboxes are found by name when passing no second parameter.
|
||||
$this->assertFieldByName('checkbox_enabled');
|
||||
$this->assertFieldByName('checkbox_disabled');
|
||||
|
||||
// Test that checkboxes are found by by ID, when using NULL to ignore the
|
||||
// 'checked' state.
|
||||
$this->assertFieldById('edit-checkbox-enabled', NULL);
|
||||
$this->assertFieldById('edit-checkbox-disabled', NULL);
|
||||
// Test that we have legacy support.
|
||||
$this->assertFieldByName('checkbox_enabled', '1');
|
||||
$this->assertFieldByName('checkbox_disabled', '');
|
||||
|
||||
// Test that the assertion fails correctly when using NULL to ignore state.
|
||||
try {
|
||||
|
@ -441,6 +542,27 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->pass('assertNoFieldByName failed correctly. The "checkbox_enabled" field was found using NULL value.');
|
||||
}
|
||||
|
||||
// Part 2 - Test by ID.
|
||||
// Test that checkboxes are found/not found correctly by ID, when using
|
||||
// TRUE or FALSE to match their 'checked' state.
|
||||
$this->assertFieldById('edit-checkbox-enabled', TRUE);
|
||||
$this->assertFieldById('edit-checkbox-disabled', FALSE);
|
||||
$this->assertNoFieldById('edit-checkbox-enabled', FALSE);
|
||||
$this->assertNoFieldById('edit-checkbox-disabled', TRUE);
|
||||
|
||||
// Test that checkboxes are found by ID, when using NULL to ignore the
|
||||
// 'checked' state.
|
||||
$this->assertFieldById('edit-checkbox-enabled', NULL);
|
||||
$this->assertFieldById('edit-checkbox-disabled', NULL);
|
||||
|
||||
// Test that checkboxes are found by ID when passing no second parameter.
|
||||
$this->assertFieldById('edit-checkbox-enabled');
|
||||
$this->assertFieldById('edit-checkbox-disabled');
|
||||
|
||||
// Test that we have legacy support.
|
||||
$this->assertFieldById('edit-checkbox-enabled', '1');
|
||||
$this->assertFieldById('edit-checkbox-disabled', '');
|
||||
|
||||
// Test that the assertion fails correctly when using NULL to ignore state.
|
||||
try {
|
||||
$this->assertNoFieldById('edit-checkbox-disabled', NULL);
|
||||
|
@ -450,11 +572,11 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->pass('assertNoFieldById failed correctly. The "edit-checkbox-disabled" field was found by ID using NULL value.');
|
||||
}
|
||||
|
||||
// Test the specific 'checked' assertions.
|
||||
// Part 3 - Test the specific 'checked' assertions.
|
||||
$this->assertFieldChecked('edit-checkbox-enabled');
|
||||
$this->assertNoFieldChecked('edit-checkbox-disabled');
|
||||
|
||||
// Test that the assertion fails correctly with non-existant field id.
|
||||
// Test that the assertion fails correctly with non-existent field id.
|
||||
try {
|
||||
$this->assertNoFieldChecked('incorrect_checkbox_id');
|
||||
$this->fail('The "incorrect_checkbox_id" field was found');
|
||||
|
@ -503,4 +625,51 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
|||
$this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the assumption that local time is in 'Australia/Sydney'.
|
||||
*/
|
||||
public function testLocalTimeZone() {
|
||||
// The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php
|
||||
$this->assertEquals('Australia/Sydney', date_default_timezone_get());
|
||||
|
||||
// The 'Australia/Sydney' time zone is also set in
|
||||
// FunctionalTestSetupTrait::initConfig().
|
||||
$config_factory = $this->container->get('config.factory');
|
||||
$value = $config_factory->get('system.date')->get('timezone.default');
|
||||
$this->assertEquals('Australia/Sydney', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ::checkForMetaRefresh() method.
|
||||
*/
|
||||
public function testCheckForMetaRefresh() {
|
||||
// Disable following redirects in the client.
|
||||
$this->getSession()->getDriver()->getClient()->followRedirects(FALSE);
|
||||
// Set the maximumMetaRefreshCount to zero to make sure the redirect doesn't
|
||||
// happen when doing a drupalGet.
|
||||
$this->maximumMetaRefreshCount = 0;
|
||||
$this->drupalGet('test-meta-refresh');
|
||||
$this->assertNotEmpty($this->cssSelect('meta[http-equiv="refresh"]'));
|
||||
// Allow one redirect to happen.
|
||||
$this->maximumMetaRefreshCount = 1;
|
||||
$this->checkForMetaRefresh();
|
||||
// Check that we are now on the test page.
|
||||
$this->assertSession()->pageTextContains('Test page text.');
|
||||
}
|
||||
|
||||
public function testGetDefaultDriveInstance() {
|
||||
putenv('MINK_DRIVER_ARGS=' . json_encode([NULL, ['key1' => ['key2' => ['key3' => 3, 'key3.1' => 3.1]]]]));
|
||||
$this->getDefaultDriverInstance();
|
||||
$this->assertEquals([NULL, ['key1' => ['key2' => ['key3' => 3, 'key3.1' => 3.1]]]], $this->minkDefaultDriverArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures we can't access modules we shouldn't be able to after install.
|
||||
*/
|
||||
public function testProfileModules() {
|
||||
$this->setExpectedException(\InvalidArgumentException::class, 'The module demo_umami_content does not exist.');
|
||||
$this->assertFileExists('core/profiles/demo_umami/modules/demo_umami_content/demo_umami_content.info.yml');
|
||||
\Drupal::service('extension.list.module')->getPathname('demo_umami_content');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Core\Test;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests Drupal's integration with Symfony PHPUnit Bridge.
|
||||
*
|
||||
* @group Test
|
||||
* @group legacy
|
||||
*/
|
||||
class PhpUnitBridgeTest extends BrowserTestBase {
|
||||
|
||||
protected static $modules = ['deprecation_test'];
|
||||
|
||||
/**
|
||||
* @expectedDeprecation This is the deprecation message for deprecation_test_function().
|
||||
*/
|
||||
public function testSilencedError() {
|
||||
$this->assertEquals('known_return_value', deprecation_test_function());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedDeprecation This is the deprecation message for deprecation_test_function().
|
||||
*/
|
||||
public function testErrorOnSiteUnderTest() {
|
||||
$this->drupalGet(Url::fromRoute('deprecation_test.route'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Datetime;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the functionality of TimestampAgoFormatter core field formatter.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class TimestampAgoFormatterTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* An array of display options to pass to entity_get_display().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $displayOptions;
|
||||
|
||||
/**
|
||||
* A field storage to use in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field used in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldConfig
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser([
|
||||
'access administration pages',
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer entity_test fields',
|
||||
'administer entity_test display',
|
||||
'administer entity_test form display',
|
||||
'view the administration theme',
|
||||
]);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
$field_name = 'field_timestamp';
|
||||
$type = 'timestamp';
|
||||
$widget_type = 'datetime_timestamp';
|
||||
$formatter_type = 'timestamp_ago';
|
||||
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => $type,
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
$this->field = FieldConfig::create([
|
||||
'field_storage' => $this->fieldStorage,
|
||||
'bundle' => 'entity_test',
|
||||
'required' => TRUE,
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
EntityFormDisplay::load('entity_test.entity_test.default')
|
||||
->setComponent($field_name, ['type' => $widget_type])
|
||||
->save();
|
||||
|
||||
$this->displayOptions = [
|
||||
'type' => $formatter_type,
|
||||
'label' => 'hidden',
|
||||
];
|
||||
|
||||
EntityViewDisplay::create([
|
||||
'targetEntityType' => $this->field->getTargetEntityTypeId(),
|
||||
'bundle' => $this->field->getTargetBundle(),
|
||||
'mode' => 'full',
|
||||
'status' => TRUE,
|
||||
])->setComponent($field_name, $this->displayOptions)
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the formatter settings.
|
||||
*/
|
||||
public function testSettings() {
|
||||
$this->drupalGet('entity_test/structure/entity_test/display');
|
||||
|
||||
$edit = [
|
||||
'fields[field_timestamp][region]' => 'content',
|
||||
'fields[field_timestamp][type]' => 'timestamp_ago',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
$this->drupalPostForm(NULL, [], 'field_timestamp_settings_edit');
|
||||
$edit = [
|
||||
'fields[field_timestamp][settings_edit_form][settings][future_format]' => 'ends in @interval',
|
||||
'fields[field_timestamp][settings_edit_form][settings][past_format]' => 'started @interval ago',
|
||||
'fields[field_timestamp][settings_edit_form][settings][granularity]' => 3,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Update');
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
|
||||
$this->assertSession()->pageTextContains('ends in 1 year 1 month 1 week');
|
||||
$this->assertSession()->pageTextContains('started 1 year 1 month 1 week ago');
|
||||
}
|
||||
|
||||
}
|
|
@ -75,10 +75,12 @@ class ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest extends B
|
|||
$storage = $this->container->get('entity_type.manager')->getStorage($this->entityTypeId);
|
||||
|
||||
/** @var ContentEntityInterface $entity */
|
||||
$entity = $storage->create([$this->fieldName => [
|
||||
['shape' => 'rectangle', 'color' => 'green'],
|
||||
['shape' => 'circle', 'color' => 'blue'],
|
||||
]]);
|
||||
$entity = $storage->create([
|
||||
$this->fieldName => [
|
||||
['shape' => 'rectangle', 'color' => 'green'],
|
||||
['shape' => 'circle', 'color' => 'blue'],
|
||||
],
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
$this->drupalGet($this->entityTypeId . '/manage/' . $entity->id() . '/edit');
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Entity;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests field validation filtering on content entity forms.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class ContentEntityFormFieldValidationFilteringTest extends BrowserTestBase {
|
||||
|
||||
use TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* The ID of the type of the entity under test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityTypeId;
|
||||
|
||||
/**
|
||||
* The single-valued field name being tested with the entity type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldNameSingle;
|
||||
|
||||
/**
|
||||
* The multi-valued field name being tested with the entity type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldNameMultiple;
|
||||
|
||||
/**
|
||||
* The name of the file field being tested with the entity type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldNameFile;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test', 'field_test', 'file', 'image'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$web_user = $this->drupalCreateUser(['administer entity_test content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create two fields of field type "test_field", one with single cardinality
|
||||
// and one with unlimited cardinality on the entity type "entity_test". It
|
||||
// is important to use this field type because its default widget has a
|
||||
// custom \Drupal\Core\Field\WidgetInterface::errorElement() implementation.
|
||||
$this->entityTypeId = 'entity_test';
|
||||
$this->fieldNameSingle = 'test_single';
|
||||
$this->fieldNameMultiple = 'test_multiple';
|
||||
$this->fieldNameFile = 'test_file';
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldNameSingle,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'field_name' => $this->fieldNameSingle,
|
||||
'bundle' => $this->entityTypeId,
|
||||
'label' => 'Test single',
|
||||
'required' => TRUE,
|
||||
'translatable' => FALSE,
|
||||
])->save();
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldNameMultiple,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'field_name' => $this->fieldNameMultiple,
|
||||
'bundle' => $this->entityTypeId,
|
||||
'label' => 'Test multiple',
|
||||
'translatable' => FALSE,
|
||||
])->save();
|
||||
|
||||
// Also create a file field to test its '#limit_validation_errors'
|
||||
// implementation.
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldNameFile,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'file',
|
||||
'cardinality' => 1,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'field_name' => $this->fieldNameFile,
|
||||
'bundle' => $this->entityTypeId,
|
||||
'label' => 'Test file',
|
||||
'translatable' => FALSE,
|
||||
])->save();
|
||||
|
||||
entity_get_form_display($this->entityTypeId, $this->entityTypeId, 'default')
|
||||
->setComponent($this->fieldNameSingle, ['type' => 'test_field_widget'])
|
||||
->setComponent($this->fieldNameMultiple, ['type' => 'test_field_widget'])
|
||||
->setComponent($this->fieldNameFile, ['type' => 'file_generic'])
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field widgets with #limit_validation_errors.
|
||||
*/
|
||||
public function testFieldWidgetsWithLimitedValidationErrors() {
|
||||
$assert_session = $this->assertSession();
|
||||
$this->drupalGet($this->entityTypeId . '/add');
|
||||
|
||||
// The 'Test multiple' field is the only multi-valued field in the form, so
|
||||
// try to add a new item for it. This tests the '#limit_validation_errors'
|
||||
// property set by \Drupal\Core\Field\WidgetBase::formMultipleElements().
|
||||
$assert_session->elementsCount('css', 'div#edit-test-multiple-wrapper div.form-type-textfield input', 1);
|
||||
$this->drupalPostForm(NULL, [], 'Add another item');
|
||||
$assert_session->elementsCount('css', 'div#edit-test-multiple-wrapper div.form-type-textfield input', 2);
|
||||
|
||||
// Now try to upload a file. This tests the '#limit_validation_errors'
|
||||
// property set by
|
||||
// \Drupal\file\Plugin\Field\FieldWidget\FileWidget::process().
|
||||
$text_file = current($this->getTestFiles('text'));
|
||||
$edit = [
|
||||
'files[test_file_0]' => \Drupal::service('file_system')->realpath($text_file->uri),
|
||||
];
|
||||
$assert_session->elementNotExists('css', 'input#edit-test-file-0-remove-button');
|
||||
$this->drupalPostForm(NULL, $edit, 'Upload');
|
||||
$assert_session->elementExists('css', 'input#edit-test-file-0-remove-button');
|
||||
|
||||
// Make the 'Test multiple' field required and check that adding another
|
||||
// item throws a validation error.
|
||||
$field_config = FieldConfig::loadByName($this->entityTypeId, $this->entityTypeId, $this->fieldNameMultiple);
|
||||
$field_config->setRequired(TRUE);
|
||||
$field_config->save();
|
||||
|
||||
$this->drupalPostForm($this->entityTypeId . '/add', [], 'Add another item');
|
||||
$assert_session->pageTextContains('Test multiple (value 1) field is required.');
|
||||
|
||||
// Check that saving the form without entering any value for the required
|
||||
// field still throws the proper validation errors.
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
$assert_session->pageTextContains('Test single field is required.');
|
||||
$assert_session->pageTextContains('Test multiple (value 1) field is required.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestBundle;
|
||||
use Drupal\entity_test\Entity\EntityTestMulRevPub;
|
||||
use Drupal\entity_test\Entity\EntityTestRev;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the delete multiple confirmation form.
|
||||
*
|
||||
* @group Entity
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
class DeleteMultipleFormTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test', 'user', 'language'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
EntityTestBundle::create([
|
||||
'id' => 'default',
|
||||
'label' => 'Default',
|
||||
])->save();
|
||||
$this->account = $this->drupalCreateUser(['administer entity_test content']);
|
||||
$this->drupalLogin($this->account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the delete form for translatable entities.
|
||||
*/
|
||||
public function testTranslatableEntities() {
|
||||
ConfigurableLanguage::create(['id' => 'es'])->save();
|
||||
ConfigurableLanguage::create(['id' => 'fr'])->save();
|
||||
|
||||
$selection = [];
|
||||
|
||||
$entity1 = EntityTestMulRevPub::create(['type' => 'default', 'name' => 'entity1']);
|
||||
$entity1->addTranslation('es', ['name' => 'entity1 spanish']);
|
||||
$entity1->addTranslation('fr', ['name' => 'entity1 french']);
|
||||
$entity1->save();
|
||||
$selection[$entity1->id()]['en'] = 'en';
|
||||
|
||||
$entity2 = EntityTestMulRevPub::create(['type' => 'default', 'name' => 'entity2']);
|
||||
$entity2->addTranslation('es', ['name' => 'entity2 spanish']);
|
||||
$entity2->addTranslation('fr', ['name' => 'entity2 french']);
|
||||
$entity2->save();
|
||||
$selection[$entity2->id()]['es'] = 'es';
|
||||
$selection[$entity2->id()]['fr'] = 'fr';
|
||||
|
||||
$entity3 = EntityTestMulRevPub::create(['type' => 'default', 'name' => 'entity3']);
|
||||
$entity3->addTranslation('es', ['name' => 'entity3 spanish']);
|
||||
$entity3->addTranslation('fr', ['name' => 'entity3 french']);
|
||||
$entity3->save();
|
||||
$selection[$entity3->id()]['fr'] = 'fr';
|
||||
|
||||
// This entity will be inaccessible because of
|
||||
// Drupal\entity_test\EntityTestAccessControlHandler.
|
||||
$entity4 = EntityTestMulRevPub::create(['type' => 'default', 'name' => 'forbid_access']);
|
||||
$entity4->save();
|
||||
$selection[$entity4->id()]['en'] = 'en';
|
||||
|
||||
// Add the selection to the tempstore just like DeleteAction would.
|
||||
$tempstore = \Drupal::service('tempstore.private')->get('entity_delete_multiple_confirm');
|
||||
$tempstore->set($this->account->id() . ':entity_test_mulrevpub', $selection);
|
||||
|
||||
$this->drupalGet('/entity_test/delete');
|
||||
$assert = $this->assertSession();
|
||||
$assert->statusCodeEquals(200);
|
||||
$assert->elementTextContains('css', '.page-title', 'Are you sure you want to delete these test entity - revisions, data table, and published interface entities?');
|
||||
$list_selector = '#entity-test-mulrevpub-delete-multiple-confirm-form > div.item-list > ul';
|
||||
$assert->elementTextContains('css', $list_selector, 'entity1 (Original translation) - The following test entity - revisions, data table, and published interface translations will be deleted:');
|
||||
$assert->elementTextContains('css', $list_selector, 'entity2 spanish');
|
||||
$assert->elementTextContains('css', $list_selector, 'entity2 french');
|
||||
$assert->elementTextNotContains('css', $list_selector, 'entity3 spanish');
|
||||
$assert->elementTextContains('css', $list_selector, 'entity3 french');
|
||||
$delete_button = $this->getSession()->getPage()->findButton('Delete');
|
||||
$delete_button->click();
|
||||
$assert = $this->assertSession();
|
||||
$assert->addressEquals('/user/' . $this->account->id());
|
||||
$assert->responseContains('Deleted 6 items.');
|
||||
$assert->responseContains('1 item has not been deleted because you do not have the necessary permissions.');
|
||||
|
||||
\Drupal::entityTypeManager()->getStorage('entity_test_mulrevpub')->resetCache();
|
||||
$remaining_entities = EntityTestMulRevPub::loadMultiple([$entity1->id(), $entity2->id(), $entity3->id(), $entity4->id()]);
|
||||
$this->assertCount(3, $remaining_entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the delete form for untranslatable entities.
|
||||
*/
|
||||
public function testUntranslatableEntities() {
|
||||
$selection = [];
|
||||
|
||||
$entity1 = EntityTestRev::create(['type' => 'default', 'name' => 'entity1']);
|
||||
$entity1->save();
|
||||
$selection[$entity1->id()]['en'] = 'en';
|
||||
|
||||
$entity2 = EntityTestRev::create(['type' => 'default', 'name' => 'entity2']);
|
||||
$entity2->save();
|
||||
$selection[$entity2->id()]['en'] = 'en';
|
||||
|
||||
// This entity will be inaccessible because of
|
||||
// Drupal\entity_test\EntityTestAccessControlHandler.
|
||||
$entity3 = EntityTestRev::create(['type' => 'default', 'name' => 'forbid_access']);
|
||||
$entity3->save();
|
||||
$selection[$entity3->id()]['en'] = 'en';
|
||||
|
||||
// This entity will be inaccessible because of
|
||||
// Drupal\entity_test\EntityTestAccessControlHandler.
|
||||
$entity4 = EntityTestRev::create(['type' => 'default', 'name' => 'forbid_access']);
|
||||
$entity4->save();
|
||||
$selection[$entity4->id()]['en'] = 'en';
|
||||
|
||||
// Add the selection to the tempstore just like DeleteAction would.
|
||||
$tempstore = \Drupal::service('tempstore.private')->get('entity_delete_multiple_confirm');
|
||||
$tempstore->set($this->account->id() . ':entity_test_rev', $selection);
|
||||
|
||||
$this->drupalGet('/entity_test_rev/delete_multiple');
|
||||
$assert = $this->assertSession();
|
||||
$assert->statusCodeEquals(200);
|
||||
$assert->elementTextContains('css', '.page-title', 'Are you sure you want to delete these test entity - revisions entities?');
|
||||
$list_selector = '#entity-test-rev-delete-multiple-confirm-form > div.item-list > ul';
|
||||
$assert->elementTextContains('css', $list_selector, 'entity1');
|
||||
$assert->elementTextContains('css', $list_selector, 'entity2');
|
||||
$delete_button = $this->getSession()->getPage()->findButton('Delete');
|
||||
$delete_button->click();
|
||||
$assert = $this->assertSession();
|
||||
$assert->addressEquals('/user/' . $this->account->id());
|
||||
$assert->responseContains('Deleted 2 items.');
|
||||
$assert->responseContains('2 items have not been deleted because you do not have the necessary permissions.');
|
||||
|
||||
\Drupal::entityTypeManager()->getStorage('entity_test_mulrevpub')->resetCache();
|
||||
$remaining_entities = EntityTestRev::loadMultiple([$entity1->id(), $entity2->id(), $entity3->id(), $entity4->id()]);
|
||||
$this->assertCount(2, $remaining_entities);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\BaseFieldOverrideResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class BaseFieldOverrideHalJsonAnonTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\BaseFieldOverrideResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class BaseFieldOverrideHalJsonBasicAuthTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\BaseFieldOverrideResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class BaseFieldOverrideHalJsonCookieTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\DateFormatResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class DateFormatHalJsonAnonTest extends DateFormatResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\DateFormatResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class DateFormatHalJsonBasicAuthTest extends DateFormatResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\DateFormatResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class DateFormatHalJsonCookieTest extends DateFormatResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityFormDisplayResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityFormDisplayHalJsonAnonTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityFormDisplayResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityFormDisplayHalJsonBasicAuthTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityFormDisplayResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityFormDisplayHalJsonCookieTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityFormModeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityFormModeHalJsonAnonTest extends EntityFormModeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityFormModeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityFormModeHalJsonBasicAuthTest extends EntityFormModeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityFormModeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityFormModeHalJsonCookieTest extends EntityFormModeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityViewDisplayResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityViewDisplayHalJsonAnonTest extends EntityViewDisplayResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityViewDisplayHalJsonBasicAuthTest extends EntityViewDisplayHalJsonAnonTest {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityViewDisplayHalJsonCookieTest extends EntityViewDisplayHalJsonAnonTest {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityViewModeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityViewModeHalJsonAnonTest extends EntityViewModeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityViewModeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityViewModeHalJsonBasicAuthTest extends EntityViewModeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Hal;
|
||||
|
||||
use Drupal\FunctionalTests\Rest\EntityViewModeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityViewModeHalJsonCookieTest extends EntityViewModeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\FunctionalTests\HttpKernel;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
|
@ -72,6 +73,19 @@ class CorsIntegrationTest extends BrowserTestBase {
|
|||
$this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com');
|
||||
|
||||
// Verify POST still functions with 'Origin' header set to site's domain.
|
||||
$origin = \Drupal::request()->getSchemeAndHttpHost();
|
||||
|
||||
/** @var \GuzzleHttp\ClientInterface $httpClient */
|
||||
$httpClient = $this->getSession()->getDriver()->getClient()->getClient();
|
||||
$url = Url::fromUri('base:/test-page');
|
||||
$response = $httpClient->request('POST', $url->setAbsolute()->toString(), [
|
||||
'headers' => [
|
||||
'Origin' => $origin,
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Image;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests image toolkit setup form.
|
||||
*
|
||||
* @group Image
|
||||
*/
|
||||
class ToolkitSetupFormTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Admin user account.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system', 'image_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->adminUser = $this->drupalCreateUser([
|
||||
'administer site configuration',
|
||||
]);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Image toolkit setup form.
|
||||
*/
|
||||
public function testToolkitSetupForm() {
|
||||
// Get form.
|
||||
$this->drupalGet('admin/config/media/image-toolkit');
|
||||
|
||||
// Test that default toolkit is GD.
|
||||
$this->assertFieldByName('image_toolkit', 'gd', 'The default image toolkit is GD.');
|
||||
|
||||
// Test changing the jpeg image quality.
|
||||
$edit = ['gd[image_jpeg_quality]' => '70'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertEqual($this->config('system.image.gd')->get('jpeg_quality'), '70');
|
||||
|
||||
// Test changing the toolkit.
|
||||
$edit = ['image_toolkit' => 'test'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertEqual($this->config('system.image')->get('toolkit'), 'test');
|
||||
$this->assertFieldByName('test[test_parameter]', '10');
|
||||
|
||||
// Test changing the test toolkit parameter.
|
||||
$edit = ['test[test_parameter]' => '0'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertText(t('Test parameter should be different from 0.'), 'Validation error displayed.');
|
||||
$edit = ['test[test_parameter]' => '20'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertEqual($this->config('system.image.test_toolkit')->get('test_parameter'), '20');
|
||||
|
||||
// Test access without the permission 'administer site configuration'.
|
||||
$this->drupalLogin($this->drupalCreateUser(['access administration pages']));
|
||||
$this->drupalGet('admin/config/media/image-toolkit');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
}
|
89
web/core/tests/Drupal/FunctionalTests/Image/ToolkitTest.php
Normal file
89
web/core/tests/Drupal/FunctionalTests/Image/ToolkitTest.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Image;
|
||||
|
||||
/**
|
||||
* Tests image toolkit functions.
|
||||
*
|
||||
* @group Image
|
||||
*/
|
||||
class ToolkitTest extends ToolkitTestBase {
|
||||
|
||||
/**
|
||||
* Check that ImageToolkitManager::getAvailableToolkits() only returns
|
||||
* available toolkits.
|
||||
*/
|
||||
public function testGetAvailableToolkits() {
|
||||
$manager = $this->container->get('image.toolkit.manager');
|
||||
$toolkits = $manager->getAvailableToolkits();
|
||||
$this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.');
|
||||
$this->assertTrue(isset($toolkits['test:derived_toolkit']), 'The derived toolkit was returned.');
|
||||
$this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned');
|
||||
$this->assertToolkitOperationsCalled([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Image's methods.
|
||||
*/
|
||||
public function testLoad() {
|
||||
$image = $this->getImage();
|
||||
$this->assertTrue(is_object($image), 'Returned an object.');
|
||||
$this->assertEqual($image->getToolkitId(), 'test', 'Image had toolkit set.');
|
||||
$this->assertToolkitOperationsCalled(['parseFile']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_save() function.
|
||||
*/
|
||||
public function testSave() {
|
||||
$this->assertFalse($this->image->save(), 'Function returned the expected value.');
|
||||
$this->assertToolkitOperationsCalled(['save']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_apply() function.
|
||||
*/
|
||||
public function testApply() {
|
||||
$data = ['p1' => 1, 'p2' => TRUE, 'p3' => 'text'];
|
||||
$this->assertTrue($this->image->apply('my_operation', $data), 'Function returned the expected value.');
|
||||
|
||||
// Check that apply was called and with the correct parameters.
|
||||
$this->assertToolkitOperationsCalled(['apply']);
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation");
|
||||
$this->assertEqual($calls['apply'][0][1]['p1'], 1, 'integer parameter p1 was passed correctly');
|
||||
$this->assertEqual($calls['apply'][0][1]['p2'], TRUE, 'boolean parameter p2 was passed correctly');
|
||||
$this->assertEqual($calls['apply'][0][1]['p3'], 'text', 'string parameter p3 was passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_apply() function.
|
||||
*/
|
||||
public function testApplyNoParameters() {
|
||||
$this->assertTrue($this->image->apply('my_operation'), 'Function returned the expected value.');
|
||||
|
||||
// Check that apply was called and with the correct parameters.
|
||||
$this->assertToolkitOperationsCalled(['apply']);
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation");
|
||||
$this->assertEqual($calls['apply'][0][1], [], 'passing no parameters was handled correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests image toolkit operations inheritance by derivative toolkits.
|
||||
*/
|
||||
public function testDerivative() {
|
||||
$toolkit_manager = $this->container->get('image.toolkit.manager');
|
||||
$operation_manager = $this->container->get('image.toolkit.operation.manager');
|
||||
|
||||
$toolkit = $toolkit_manager->createInstance('test:derived_toolkit');
|
||||
|
||||
// Load an overwritten and an inherited operation.
|
||||
$blur = $operation_manager->getToolkitOperation($toolkit, 'blur');
|
||||
$invert = $operation_manager->getToolkitOperation($toolkit, 'invert');
|
||||
|
||||
$this->assertIdentical('foo_derived', $blur->getPluginId(), "'Blur' operation overwritten by derivative.");
|
||||
$this->assertIdentical('bar', $invert->getPluginId(), '"Invert" operation inherited from base plugin.');
|
||||
}
|
||||
|
||||
}
|
158
web/core/tests/Drupal/FunctionalTests/Image/ToolkitTestBase.php
Normal file
158
web/core/tests/Drupal/FunctionalTests/Image/ToolkitTestBase.php
Normal file
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Image;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Base class for image manipulation testing.
|
||||
*/
|
||||
abstract class ToolkitTestBase extends BrowserTestBase {
|
||||
|
||||
use TestFileCreationTrait {
|
||||
getTestFiles as drupalGetTestFiles;
|
||||
}
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['image_test'];
|
||||
|
||||
/**
|
||||
* The URI for the file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* The image factory service.
|
||||
*
|
||||
* @var \Drupal\Core\Image\ImageFactory
|
||||
*/
|
||||
protected $imageFactory;
|
||||
|
||||
/**
|
||||
* The image object for the test file.
|
||||
*
|
||||
* @var \Drupal\Core\Image\ImageInterface
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Set the image factory service.
|
||||
$this->imageFactory = $this->container->get('image.factory');
|
||||
|
||||
// Pick a file for testing.
|
||||
$file = current($this->drupalGetTestFiles('image'));
|
||||
$this->file = $file->uri;
|
||||
|
||||
// Setup a dummy image to work with.
|
||||
$this->image = $this->getImage();
|
||||
|
||||
// Clear out any hook calls.
|
||||
$this->imageTestReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an image with the custom toolkit.
|
||||
*
|
||||
* @return \Drupal\Core\Image\ImageInterface
|
||||
* The image object.
|
||||
*/
|
||||
protected function getImage() {
|
||||
$image = $this->imageFactory->get($this->file, 'test');
|
||||
$this->assertTrue($image->isValid(), 'Image file was parsed.');
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that all of the specified image toolkit operations were called
|
||||
* exactly once once, other values result in failure.
|
||||
*
|
||||
* @param $expected
|
||||
* Array with string containing with the operation name, e.g. 'load',
|
||||
* 'save', 'crop', etc.
|
||||
*/
|
||||
public function assertToolkitOperationsCalled(array $expected) {
|
||||
// If one of the image operations is expected, apply should be expected as
|
||||
// well.
|
||||
$operations = [
|
||||
'resize',
|
||||
'rotate',
|
||||
'crop',
|
||||
'desaturate',
|
||||
'create_new',
|
||||
'scale',
|
||||
'scale_and_crop',
|
||||
'my_operation',
|
||||
'convert',
|
||||
];
|
||||
if (count(array_intersect($expected, $operations)) > 0 && !in_array('apply', $expected)) {
|
||||
$expected[] = 'apply';
|
||||
}
|
||||
|
||||
// Determine which operations were called.
|
||||
$actual = array_keys(array_filter($this->imageTestGetAllCalls()));
|
||||
|
||||
// Determine if there were any expected that were not called.
|
||||
$uncalled = array_diff($expected, $actual);
|
||||
if (count($uncalled)) {
|
||||
$this->assertTrue(FALSE, new FormattableMarkup('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(TRUE, new FormattableMarkup('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)]));
|
||||
}
|
||||
|
||||
// Determine if there were any unexpected calls.
|
||||
// If all unexpected calls are operations and apply was expected, we do not
|
||||
// count it as an error.
|
||||
$unexpected = array_diff($actual, $expected);
|
||||
if (count($unexpected) && (!in_array('apply', $expected) || count(array_intersect($unexpected, $operations)) !== count($unexpected))) {
|
||||
$this->assertTrue(FALSE, new FormattableMarkup('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(TRUE, 'No unexpected operations were called.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets/initializes the history of calls to the test toolkit functions.
|
||||
*/
|
||||
protected function imageTestReset() {
|
||||
// Keep track of calls to these operations
|
||||
$results = [
|
||||
'parseFile' => [],
|
||||
'save' => [],
|
||||
'settings' => [],
|
||||
'apply' => [],
|
||||
'resize' => [],
|
||||
'rotate' => [],
|
||||
'crop' => [],
|
||||
'desaturate' => [],
|
||||
'create_new' => [],
|
||||
'scale' => [],
|
||||
'scale_and_crop' => [],
|
||||
'convert' => [],
|
||||
];
|
||||
\Drupal::state()->set('image_test.results', $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of calls to the test toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array keyed by operation name ('parseFile', 'save', 'settings',
|
||||
* 'resize', 'rotate', 'crop', 'desaturate') with values being arrays of
|
||||
* parameters passed to each call.
|
||||
*/
|
||||
protected function imageTestGetAllCalls() {
|
||||
return \Drupal::state()->get('image_test.results') ?: [];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Config\FileStorage;
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\Config\StorageInterface;
|
||||
use Drupal\KernelTests\AssertConfigTrait;
|
||||
|
||||
/**
|
||||
* Provides a class for install profiles to check their installed config.
|
||||
*/
|
||||
abstract class ConfigAfterInstallerTestBase extends InstallerTestBase {
|
||||
|
||||
use AssertConfigTrait;
|
||||
|
||||
/**
|
||||
* Ensures that all the installed config looks like the exported one.
|
||||
*
|
||||
* @param array $skipped_config
|
||||
* An array of skipped config.
|
||||
*/
|
||||
protected function assertInstalledConfig(array $skipped_config) {
|
||||
$this->addToAssertionCount(1);
|
||||
/** @var \Drupal\Core\Config\StorageInterface $active_config_storage */
|
||||
$active_config_storage = $this->container->get('config.storage');
|
||||
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
|
||||
$config_manager = $this->container->get('config.manager');
|
||||
|
||||
$default_install_path = 'core/profiles/' . $this->profile . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
|
||||
$profile_config_storage = new FileStorage($default_install_path, StorageInterface::DEFAULT_COLLECTION);
|
||||
|
||||
foreach ($profile_config_storage->listAll() as $config_name) {
|
||||
$result = $config_manager->diff($profile_config_storage, $active_config_storage, $config_name);
|
||||
try {
|
||||
$this->assertConfigDiff($result, $config_name, $skipped_config);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support with existing settings.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class DistributionProfileExistingSettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Distribution profile',
|
||||
'distribution' => [
|
||||
'name' => 'My Distribution',
|
||||
'install' => [
|
||||
'theme' => 'bartik',
|
||||
],
|
||||
],
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->siteDirectory . '/profiles/mydistro';
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/mydistro.info.yml", Yaml::encode($this->info));
|
||||
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Use the kernel to find the site path because the site.path service should
|
||||
// not be available at this point in the install process.
|
||||
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => $site_path . '/files/config_staging',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Make settings file not writable.
|
||||
$filename = $this->siteDirectory . '/settings.php';
|
||||
// Make the settings file read-only.
|
||||
// Not using File API; a potential error must trigger a PHP warning.
|
||||
chmod($filename, 0444);
|
||||
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw($this->info['distribution']['name']);
|
||||
// Verify that the requested theme is used.
|
||||
$this->assertRaw($this->info['distribution']['install']['theme']);
|
||||
// Verify that the "Choose profile" step does not appear.
|
||||
$this->assertNoText('profile');
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
|
||||
$this->assertArrayNotHasKey('install_profile', Settings::getAll(), 'The install profile has not been written to settings.php.');
|
||||
$this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.');
|
||||
|
||||
$this->rebuildContainer();
|
||||
$this->pass('Container can be rebuilt even though distribution is not written to settings.php.');
|
||||
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class DistributionProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Distribution profile',
|
||||
'distribution' => [
|
||||
'name' => 'My Distribution',
|
||||
'install' => [
|
||||
'theme' => 'bartik',
|
||||
'finish_url' => '/myrootuser',
|
||||
],
|
||||
],
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->siteDirectory . '/profiles/mydistro';
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/mydistro.info.yml", Yaml::encode($this->info));
|
||||
file_put_contents("$path/mydistro.install", "<?php function mydistro_install() {\Drupal::service('path.alias_storage')->save('/user/1', '/myrootuser');}");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw($this->info['distribution']['name']);
|
||||
// Verify that the distribution name is used in the site title.
|
||||
$this->assertTitle('Choose language | ' . $this->info['distribution']['name']);
|
||||
// Verify that the requested theme is used.
|
||||
$this->assertRaw($this->info['distribution']['install']['theme']);
|
||||
// Verify that the "Choose profile" step does not appear.
|
||||
$this->assertNoText('profile');
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('myrootuser');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
|
||||
$this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support with a 'langcode' query string.
|
||||
*
|
||||
* @group Installer
|
||||
*
|
||||
* @see \Drupal\FunctionalTests\Installer\DistributionProfileTranslationTest
|
||||
*/
|
||||
class DistributionProfileTranslationQueryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Distribution profile',
|
||||
'distribution' => [
|
||||
'name' => 'My Distribution',
|
||||
'langcode' => $this->langcode,
|
||||
'install' => [
|
||||
'theme' => 'bartik',
|
||||
],
|
||||
],
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->root . DIRECTORY_SEPARATOR . $this->siteDirectory . '/profiles/mydistro';
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/mydistro.info.yml", Yaml::encode($this->info));
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir($this->root . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
file_put_contents($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.fr.po', $this->getPo('fr'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Pass a different language code than the one set in the distribution
|
||||
// profile. This distribution language should still be used.
|
||||
// The unrouted URL assembler does not exist at this point, so we build the
|
||||
// URL ourselves.
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php' . '?langcode=fr');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because the distribution profile uses a fixed
|
||||
// language.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// The language should have been automatically detected, all following
|
||||
// screens should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual(current($elements)->getText(), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = $this->getSession()->getPage()->find('xpath', '/@dir')->getText();
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw($this->info['distribution']['name']);
|
||||
// Verify that the requested theme is used.
|
||||
$this->assertRaw($this->info['distribution']['install']['theme']);
|
||||
// Verify that the "Choose profile" step does not appear.
|
||||
$this->assertNoText('profile');
|
||||
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getDisplayName());
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*
|
||||
* @see \Drupal\FunctionalTests\Installer\DistributionProfileTest
|
||||
*/
|
||||
class DistributionProfileTranslationTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Distribution profile',
|
||||
'distribution' => [
|
||||
'name' => 'My Distribution',
|
||||
'langcode' => $this->langcode,
|
||||
'install' => [
|
||||
'theme' => 'bartik',
|
||||
],
|
||||
],
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->root . DIRECTORY_SEPARATOR . $this->siteDirectory . '/profiles/mydistro';
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/mydistro.info.yml", Yaml::encode($this->info));
|
||||
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir($this->root . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because the distribution profile uses a fixed
|
||||
// language.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// The language should have been automatically detected, all following
|
||||
// screens should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual(current($elements)->getText(), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = current($this->xpath('/@dir'))->getText();
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw($this->info['distribution']['name']);
|
||||
// Verify that the requested theme is used.
|
||||
$this->assertRaw($this->info['distribution']['install']['theme']);
|
||||
// Verify that the "Choose profile" step does not appear.
|
||||
$this->assertNoText('profile');
|
||||
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getDisplayName());
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that an install profile with only dependencies works as expected.
|
||||
*
|
||||
* @group Installer
|
||||
* @group legacy
|
||||
*/
|
||||
class InstallProfileDependenciesBcTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_install_profile_dependencies_bc';
|
||||
|
||||
/**
|
||||
* Tests that the install profile BC layer for dependencies key works.
|
||||
*
|
||||
* @expectedDeprecation The install profile core/profiles/testing_install_profile_dependencies_bc/testing_install_profile_dependencies_bc.info.yml only implements a 'dependencies' key. As of Drupal 8.6.0 profile's support a new 'install' key for modules that should be installed but not depended on. See https://www.drupal.org/node/2952947.
|
||||
*/
|
||||
public function testUninstallingModules() {
|
||||
$user = $this->drupalCreateUser(['administer modules']);
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->getSession()->getPage()->checkField('uninstall[ban]');
|
||||
$this->getSession()->getPage()->checkField('uninstall[dblog]');
|
||||
$this->click('#edit-submit');
|
||||
// Click the confirm button.
|
||||
$this->click('#edit-submit');
|
||||
$this->assertSession()->responseContains('The selected modules have been uninstalled.');
|
||||
$this->assertSession()->responseContains('No modules are available to uninstall.');
|
||||
// We've uninstalled modules therefore we need to rebuild the container in
|
||||
// the test runner.
|
||||
$this->rebuildContainer();
|
||||
$module_handler = $this->container->get('module_handler');
|
||||
$this->assertFalse($module_handler->moduleExists('ban'));
|
||||
$this->assertFalse($module_handler->moduleExists('dblog'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Extension\ModuleUninstallValidatorException;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that an install profile can require modules.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallProfileDependenciesTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_install_profile_dependencies';
|
||||
|
||||
/**
|
||||
* Tests that an install profile can require modules.
|
||||
*/
|
||||
public function testUninstallingModules() {
|
||||
$user = $this->drupalCreateUser(['administer modules']);
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->assertSession()->fieldDisabled('uninstall[dblog]');
|
||||
$this->getSession()->getPage()->checkField('uninstall[ban]');
|
||||
$this->click('#edit-submit');
|
||||
// Click the confirm button.
|
||||
$this->click('#edit-submit');
|
||||
$this->assertSession()->responseContains('The selected modules have been uninstalled.');
|
||||
// We've uninstalled a module therefore we need to rebuild the container in
|
||||
// the test runner.
|
||||
$this->rebuildContainer();
|
||||
$this->assertFalse($this->container->get('module_handler')->moduleExists('ban'));
|
||||
try {
|
||||
$this->container->get('module_installer')->uninstall(['dblog']);
|
||||
$this->fail('Uninstalled dblog module.');
|
||||
}
|
||||
catch (ModuleUninstallValidatorException $e) {
|
||||
$this->assertContains('The Testing install profile dependencies module is required', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
|
||||
/**
|
||||
* Tests the installer when a config_directory set up but does not exist.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerConfigDirectorySetNoDirectoryErrorTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The directory where the sync directory should be created during install.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $configDirectory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->configDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64();
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $this->configDirectory . '/sync',
|
||||
'required' => TRUE,
|
||||
];
|
||||
// Create the files directory early so we can test the error case.
|
||||
mkdir($this->publicFilesDirectory);
|
||||
// Create a file so the directory can not be created.
|
||||
file_put_contents($this->configDirectory, 'Test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Configure settings.
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear as we had a failure prior to the settings
|
||||
// screen.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// This step should not appear as we had a failure prior to the settings
|
||||
// screen.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation failed.
|
||||
*/
|
||||
public function testError() {
|
||||
$this->assertText("An automated attempt to create the directory {$this->configDirectory}/sync failed, possibly due to a permissions problem.");
|
||||
$this->assertFalse(file_exists($this->configDirectory . '/sync') && is_dir($this->configDirectory . '/sync'), "The directory {$this->configDirectory}/sync does not exist.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
|
||||
/**
|
||||
* Tests the installer when a config_directory set up but does not exist.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerConfigDirectorySetNoDirectoryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The sync directory created during the install.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $syncDirectory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->syncDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64() . '/sync';
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $this->syncDirectory,
|
||||
'required' => TRUE,
|
||||
];
|
||||
// Other directories will be created too.
|
||||
$this->settings['config_directories']['custom'] = (object) [
|
||||
'value' => $this->publicFilesDirectory . '/config_custom',
|
||||
'required' => TRUE,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertTrue(file_exists($this->syncDirectory) && is_dir($this->syncDirectory), "The directory {$this->syncDirectory} exists.");
|
||||
$this->assertTrue(file_exists($this->publicFilesDirectory . '/config_custom') && is_dir($this->publicFilesDirectory . '/config_custom'), "The directory {$this->publicFilesDirectory}/custom_config exists.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
/**
|
||||
* Tests the installer with database errors.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerDatabaseErrorMessagesTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// We are creating a table here to force an error in the installer because
|
||||
// it will try and create the drupal_install_test table as this is part of
|
||||
// the standard database tests performed by the installer in
|
||||
// Drupal\Core\Database\Install\Tasks.
|
||||
Database::getConnection('default')->query('CREATE TABLE {drupal_install_test} (id int NULL)');
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// This step should not appear as we had a failure on the settings screen.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the error message in the settings step is correct.
|
||||
*/
|
||||
public function testSetUpSettingsErrorMessage() {
|
||||
$this->assertRaw('<ul><li>Failed to <strong>CREATE</strong> a test table');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests the installer with empty settings file.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerEmptySettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// Create an empty settings.php file.
|
||||
$path = $this->root . DIRECTORY_SEPARATOR . $this->siteDirectory;
|
||||
file_put_contents($path . '/settings.php', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests the installer when a config_directory has already been set up.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigDirectoryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The expected file perms of the folder.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $expectedFilePerms;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
mkdir($this->root . DIRECTORY_SEPARATOR . $this->siteDirectory . '/config_read_only', 0444);
|
||||
$this->expectedFilePerms = fileperms($this->siteDirectory . '/config_read_only');
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $this->siteDirectory . '/config_read_only',
|
||||
'required' => TRUE,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual($this->expectedFilePerms, fileperms($this->siteDirectory . '/config_read_only'));
|
||||
$this->assertEqual([], glob($this->siteDirectory . '/config_read_only/*'), 'The sync directory is empty after install because it is read-only.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that installing from existing configuration works.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigMultilingualTest extends InstallerExistingConfigTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_config_install_multilingual';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that profiles invalid config can not be installed.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigNoConfigTest extends InstallerExistingConfigTestBase {
|
||||
|
||||
protected $profile = 'no_config_profile';
|
||||
|
||||
/**
|
||||
* Final installer step: Configure site.
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// There are errors therefore there is nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/testing_config_install_no_config.tar.gz';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that profiles with an empty config/sync directory do not work.
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
$this->assertTitle('Configuration validation | Drupal');
|
||||
$this->assertText('The configuration synchronization failed validation.');
|
||||
$this->assertText('This import is empty and if applied would delete all of your configuration, so has been rejected.');
|
||||
|
||||
// Ensure there is no continuation button.
|
||||
$this->assertNoText('Save and continue');
|
||||
$this->assertNoFieldById('edit-submit');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Testing installing from config without system.site.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigNoSystemSiteTest extends InstallerExistingConfigTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// File API functions are not available yet.
|
||||
unlink($this->siteDirectory . '/profiles/' . $this->profile . '/config/sync/system.site.yml');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUpSite() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that profiles with no system.site do not work.
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
$this->htmlOutput(NULL);
|
||||
$this->assertTitle('Configuration validation | Drupal');
|
||||
$this->assertText('The configuration synchronization failed validation.');
|
||||
$this->assertText('This import does not contain system.site configuration, so has been rejected.');
|
||||
|
||||
// Ensure there is no continuation button.
|
||||
$this->assertNoText('Save and continue');
|
||||
$this->assertNoFieldById('edit-submit');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/testing_config_install.tar.gz';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that profiles with hook_install() can't be installed from config.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigProfileHookInstall extends InstallerExistingConfigTestBase {
|
||||
|
||||
protected $profile = 'config_profile_with_hook_install';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Create an .install file with a hook_install() implementation.
|
||||
$path = $this->siteDirectory . '/profiles/' . $this->profile;
|
||||
$contents = <<<EOF
|
||||
<?php
|
||||
|
||||
function config_profile_with_hook_install_install() {
|
||||
}
|
||||
EOF;
|
||||
file_put_contents("$path/{$this->profile}.install", $contents);
|
||||
parent::visitInstaller();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Configure settings.
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// There are errors therefore there is nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final installer step: Configure site.
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// There are errors therefore there is nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
// We're not going to get to the config import stage so this does not
|
||||
// matter.
|
||||
return __DIR__ . '/../../../fixtures/config_install/testing_config_install_no_config.tar.gz';
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms the installation has failed and the expected error is displayed.
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
$this->assertTitle('Requirements problem | Drupal');
|
||||
$this->assertText($this->profile);
|
||||
$this->assertText('The selected profile has a hook_install() implementation and therefore can not be installed from configuration.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that installing from existing configuration works.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigSyncDirectoryMultilingualTest extends InstallerExistingConfigTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_config_install_multilingual';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $existingSyncDirectory = TRUE;
|
||||
|
||||
/**
|
||||
* Installer step: Select installation profile.
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// Ensure the site name 'Multilingual' appears as expected in the 'Use
|
||||
// existing configuration' radio description.
|
||||
$this->assertSession()->pageTextContains('Install Multilingual using existing configuration.');
|
||||
return parent::setUpProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation installed the configuration correctly.
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
parent::testConfigSync();
|
||||
// Ensure that menu blocks have been created correctly.
|
||||
$this->assertSession()->responseNotContains('This block is broken or missing.');
|
||||
$this->assertSession()->linkExists('Add content');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that profiles with hook_install() can't be installed from config.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigSyncDirectoryProfileHookInstall extends InstallerExistingConfigTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_config_install_multilingual';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $existingSyncDirectory = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Create an .install file with a hook_install() implementation.
|
||||
$path = $this->siteDirectory . '/profiles/' . $this->profile;
|
||||
$contents = <<<EOF
|
||||
<?php
|
||||
|
||||
function testing_config_install_multilingual_install() {
|
||||
}
|
||||
EOF;
|
||||
file_put_contents("$path/{$this->profile}.install", $contents);
|
||||
parent::visitInstaller();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Select installation profile.
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This is the form we are testing so wait until the test method to do
|
||||
// assertions.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Requirements problem.
|
||||
*/
|
||||
protected function setUpRequirementsProblem() {
|
||||
// This form will never be reached.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Configure settings.
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This form will never be reached.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final installer step: Configure site.
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// This form will never be reached.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests installing from config is not available due to hook_INSTALL().
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
$this->assertSession()->titleEquals('Select an installation profile | Drupal');
|
||||
$this->assertSession()->responseNotContains('Use existing configuration');
|
||||
|
||||
// Remove the install hook and the option to install from existing
|
||||
// configuration will be available.
|
||||
unlink("{$this->siteDirectory}/profiles/{$this->profile}/{$this->profile}.install");
|
||||
$this->getSession()->reload();
|
||||
$this->assertSession()->titleEquals('Select an installation profile | Drupal');
|
||||
$this->assertSession()->responseContains('Use existing configuration');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that installing from existing configuration works.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigSyncDriectoryProfileMismatchTest extends InstallerExistingConfigTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_config_install_multilingual';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $existingSyncDirectory = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Configure settings.
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// Cause a profile mismatch by hacking the URL.
|
||||
$this->drupalGet(str_replace($this->profile, 'minimal', $this->getUrl()));
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
protected function setUpSite() {
|
||||
// This step will not occur because there is an error.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that profile mismatch fails to install.
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
$this->htmlOutput(NULL);
|
||||
$this->assertTitle('Configuration validation | Drupal');
|
||||
$this->assertText('The configuration synchronization failed validation.');
|
||||
$this->assertText('The selected installation profile minimal does not match the profile stored in configuration testing_config_install_multilingual.');
|
||||
|
||||
// Ensure there is no continuation button.
|
||||
$this->assertNoText('Save and continue');
|
||||
$this->assertNoFieldById('edit-submit');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that installing from existing configuration works.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigTest extends InstallerExistingConfigTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUpSite() {
|
||||
// The configuration is from a site installed in French.
|
||||
// So after selecting the profile the installer detects that the site must
|
||||
// be installed in French, thus we change the button translation.
|
||||
$this->translations['Save and continue'] = 'Enregistrer et continuer';
|
||||
parent::setUpSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getConfigTarball() {
|
||||
return __DIR__ . '/../../../fixtures/config_install/testing_config_install.tar.gz';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Archiver\ArchiveTar;
|
||||
use Drupal\Core\Installer\Form\SelectProfileForm;
|
||||
|
||||
/**
|
||||
* Provides a base class for testing installing from existing configuration.
|
||||
*/
|
||||
abstract class InstallerExistingConfigTestBase extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* This is set by the profile in the core.extension extracted.
|
||||
*/
|
||||
protected $profile = NULL;
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
protected $existingSyncDirectory = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$archiver = new ArchiveTar($this->getConfigTarball(), 'gz');
|
||||
|
||||
if ($this->profile === NULL) {
|
||||
$core_extension = Yaml::decode($archiver->extractInString('core.extension.yml'));
|
||||
$this->profile = $core_extension['profile'];
|
||||
}
|
||||
|
||||
// Create a profile for testing.
|
||||
$info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Configuration installation test profile (' . $this->profile . ')',
|
||||
];
|
||||
|
||||
// File API functions are not available yet.
|
||||
$path = $this->siteDirectory . '/profiles/' . $this->profile;
|
||||
if ($this->existingSyncDirectory) {
|
||||
$config_sync_directory = $this->siteDirectory . '/config/sync';
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $config_sync_directory,
|
||||
'required' => TRUE,
|
||||
];
|
||||
}
|
||||
else {
|
||||
// Put the sync directory inside the profile.
|
||||
$config_sync_directory = $path . '/config/sync';
|
||||
}
|
||||
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/{$this->profile}.info.yml", Yaml::encode($info));
|
||||
|
||||
// Create config/sync directory and extract tarball contents to it.
|
||||
mkdir($config_sync_directory, 0777, TRUE);
|
||||
$files = [];
|
||||
$list = $archiver->listContent();
|
||||
if (is_array($list)) {
|
||||
/** @var array $list */
|
||||
foreach ($list as $file) {
|
||||
$files[] = $file['filename'];
|
||||
}
|
||||
$archiver->extractList($files, $config_sync_directory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filepath to the configuration tarball.
|
||||
*
|
||||
* The tarball will be extracted to the install profile's config/sync
|
||||
* directory for testing.
|
||||
*
|
||||
* @return string
|
||||
* The filepath to the configuration tarball.
|
||||
*/
|
||||
abstract protected function getConfigTarball();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function installParameters() {
|
||||
$parameters = parent::installParameters();
|
||||
|
||||
// The options that change configuration are disabled when installing from
|
||||
// existing configuration.
|
||||
unset($parameters['forms']['install_configure_form']['site_name']);
|
||||
unset($parameters['forms']['install_configure_form']['site_mail']);
|
||||
unset($parameters['forms']['install_configure_form']['update_status_module']);
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation installed the configuration correctly.
|
||||
*/
|
||||
public function testConfigSync() {
|
||||
// After installation there is no snapshot and nothing to import.
|
||||
$change_list = $this->configImporter()->getStorageComparer()->getChangelist();
|
||||
$expected = [
|
||||
'create' => [],
|
||||
// The system.mail is changed configuration because the test system
|
||||
// changes it to ensure that mails are not sent.
|
||||
'update' => ['system.mail'],
|
||||
'delete' => [],
|
||||
'rename' => [],
|
||||
];
|
||||
$this->assertEqual($expected, $change_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Select installation profile.
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
if ($this->existingSyncDirectory) {
|
||||
$edit = [
|
||||
'profile' => SelectProfileForm::CONFIG_INSTALL_PROFILE_KEY,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
}
|
||||
else {
|
||||
parent::setUpProfile();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing settings file with database connection
|
||||
* info.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingDatabaseSettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// Pre-configure database credentials in settings.php.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @todo The database settings form is not supposed to appear if settings.php
|
||||
* contains a valid database connection already (but e.g. no config
|
||||
* directories yet).
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// All database settings should be pre-configured, except password.
|
||||
$values = $this->parameters['forms']['install_settings_form'];
|
||||
$driver = $values['driver'];
|
||||
$edit = [];
|
||||
if (isset($values[$driver]['password']) && $values[$driver]['password'] !== '') {
|
||||
$edit = $this->translatePostValues([
|
||||
$driver => [
|
||||
'password' => $values[$driver]['password'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing Drupal installation.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingInstallationTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Verifies that Drupal can't be reinstalled while an existing installation is
|
||||
* available.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
// Verify that Drupal can't be immediately reinstalled.
|
||||
$this->visitInstaller();
|
||||
$this->assertRaw('Drupal already installed');
|
||||
|
||||
// Delete settings.php and attempt to reinstall again.
|
||||
unlink($this->siteDirectory . '/settings.php');
|
||||
$this->visitInstaller();
|
||||
$this->setUpLanguage();
|
||||
$this->setUpProfile();
|
||||
$this->setUpRequirementsProblem();
|
||||
$this->setUpSettings();
|
||||
$this->assertRaw('Drupal already installed');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests install with existing settings.php and a mismatching install profile.
|
||||
*
|
||||
* @group Installer
|
||||
* @group legacy
|
||||
*/
|
||||
class InstallerExistingSettingsMismatchProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Configures a preexisting settings.php file without an install_profile
|
||||
* setting before invoking the interactive installer.
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// During interactive install we'll change this to a different profile and
|
||||
// this test will ensure that the new value is written to settings.php.
|
||||
$this->settings['settings']['install_profile'] = (object) [
|
||||
'value' => 'minimal',
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Provide profile and language in query string to skip these pages.
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php?langcode=en&profile=testing');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because there is a langcode as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a profile as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*
|
||||
* @expectedDeprecation To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual('testing', \Drupal::installProfile());
|
||||
$this->assertEqual('testing', Settings::get('install_profile'), 'Profile was correctly changed to testing in Settings.php');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing settings file but no install profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingSettingsNoProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Configures a preexisting settings.php file without an install_profile
|
||||
* setting before invoking the interactive installer.
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual('testing', \Drupal::installProfile());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests installer breaks with a profile mismatch and a read-only settings.php.
|
||||
*
|
||||
* @group Installer
|
||||
* @group legacy
|
||||
*/
|
||||
class InstallerExistingSettingsReadOnlyMismatchProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Configures a preexisting settings.php file without an install_profile
|
||||
* setting before invoking the interactive installer.
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// During interactive install we'll change this to a different profile and
|
||||
// this test will ensure that the new value is written to settings.php.
|
||||
$this->settings['settings']['install_profile'] = (object) [
|
||||
'value' => 'minimal',
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure config directories.
|
||||
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => $site_path . '/files/config_staging',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Make settings file not writable. This will break the installer.
|
||||
$filename = $this->siteDirectory . '/settings.php';
|
||||
// Make the settings file read-only.
|
||||
// Not using File API; a potential error must trigger a PHP warning.
|
||||
chmod($filename, 0444);
|
||||
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php?langcode=en&profile=testing');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because there is a lagcode as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a profile as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*
|
||||
* @expectedDeprecation To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->initBrowserOutputFile();
|
||||
$this->htmlOutput(NULL);
|
||||
$this->assertEquals('testing', \Drupal::installProfile());
|
||||
$this->assertEquals('minimal', Settings::get('install_profile'));
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertSession()->pageTextContains("Drupal 8 no longer uses the \$settings['install_profile'] value in settings.php and it can be removed.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing settings file.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingSettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Fully configures a preexisting settings.php file before invoking the
|
||||
* interactive installer.
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Use the kernel to find the site path because the site.path service should
|
||||
// not be available at this point in the install process.
|
||||
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => $site_path . '/files/config_sync',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual('testing', \Drupal::installProfile());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that the early installer uses the correct language direction.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerLanguageDirectionTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Overrides the language code the installer should use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'ar';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir($this->root . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.ar.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue Arabic\"");
|
||||
|
||||
parent::setUpLanguage();
|
||||
// After selecting a different language than English, all following screens
|
||||
// should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual(current($elements)->getText(), 'Save and continue Arabic');
|
||||
$this->translations['Save and continue'] = 'Save and continue Arabic';
|
||||
|
||||
// Verify that language direction is right-to-left.
|
||||
$direction = current($this->xpath('/@dir'))->getText();
|
||||
$this->assertEqual($direction, 'rtl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Language\LanguageManager;
|
||||
|
||||
/**
|
||||
* Verifies that the installer language list combines local and remote languages.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerLanguagePageTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Installer step: Select language.
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir($this->root . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
touch($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.xoxo.po');
|
||||
|
||||
// Check that all predefined languages show up with their native names.
|
||||
$this->visitInstaller();
|
||||
foreach (LanguageManager::getStandardLanguageList() as $langcode => $names) {
|
||||
$this->assertOption('edit-langcode', $langcode);
|
||||
$this->assertRaw('>' . $names[1] . '<');
|
||||
}
|
||||
|
||||
// Check that our custom one shows up with the file name indicated language.
|
||||
$this->assertOption('edit-langcode', 'xoxo');
|
||||
$this->assertRaw('>xoxo<');
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests that an install profile can implement hook_requirements().
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerProfileRequirementsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing_requirements';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This form will never be reached.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// This form will never be reached.
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the profile failed hook_requirements().
|
||||
*/
|
||||
public function testHookRequirementsFailure() {
|
||||
$this->assertSession()->pageTextContains('Testing requirements failed requirements.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Verifies that the installer skipped permission hardening.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerSkipPermissionHardeningTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$this->settings['settings']['skip_permissions_hardening'] = (object) ['value' => TRUE, 'required' => TRUE];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
$site_directory = $this->container->get('app.root') . '/' . $this->siteDirectory;
|
||||
$this->assertTrue(is_writable($site_directory));
|
||||
$this->assertTrue(is_writable($site_directory . '/settings.php'));
|
||||
|
||||
$this->assertSession()->responseContains('All necessary changes to <em class="placeholder">' . $this->siteDirectory . '</em> and <em class="placeholder">' . $this->siteDirectory . '/settings.php</em> have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="https://www.drupal.org/server-permissions">online handbook</a>.');
|
||||
|
||||
parent::setUpSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the expected behaviors of the installation result.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertSession()->addressEquals('user/1');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests the interactive installer.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Ensures that the user page is available after installation.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
|
||||
// Verify that the confirmation message appears.
|
||||
require_once $this->root . '/core/includes/install.inc';
|
||||
$this->assertRaw(t('Congratulations, you installed @drupal!', [
|
||||
'@drupal' => drupal_install_profile_distribution_name(),
|
||||
]));
|
||||
|
||||
// Ensure that the timezone is correct for sites under test after installing
|
||||
// interactively.
|
||||
$this->assertEqual($this->config('system.date')->get('timezone.default'), 'Australia/Sydney');
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Select language.
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Test that \Drupal\Core\Render\BareHtmlPageRenderer adds assets and
|
||||
// metatags as expected to the first page of the installer.
|
||||
$this->assertRaw("core/themes/seven/css/components/buttons.css");
|
||||
$this->assertRaw('<meta charset="utf-8" />');
|
||||
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Choose language', $this->cssSelect('main h2')[0]->getText());
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Select an installation profile', $this->cssSelect('main h2')[0]->getText());
|
||||
$result = $this->xpath('//span[contains(@class, :class) and contains(text(), :text)]', [':class' => 'visually-hidden', ':text' => 'Select an installation profile']);
|
||||
$this->assertEqual(count($result), 1, "Title/Label not displayed when '#title_display' => 'invisible' attribute is set");
|
||||
|
||||
parent::setUpProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Database configuration', $this->cssSelect('main h2')[0]->getText());
|
||||
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Configure site', $this->cssSelect('main h2')[0]->getText());
|
||||
|
||||
// Test that SiteConfigureForm::buildForm() has made the site directory and
|
||||
// the settings file non-writable.
|
||||
$site_directory = $this->container->get('app.root') . '/' . $this->siteDirectory;
|
||||
$this->assertFalse(is_writable($site_directory));
|
||||
$this->assertFalse(is_writable($site_directory . '/settings.php'));
|
||||
|
||||
parent::setUpSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
parent::visitInstaller();
|
||||
|
||||
// Assert the title is correct and has the title suffix.
|
||||
$this->assertTitle('Choose language | Drupal');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Session\UserSession;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
/**
|
||||
* Base class for testing the interactive installer.
|
||||
*/
|
||||
abstract class InstallerTestBase extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Custom settings.php values to write for a test run.
|
||||
*
|
||||
* @var array
|
||||
* An array of settings to write out, in the format expected by
|
||||
* drupal_rewrite_settings().
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* The language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'en';
|
||||
|
||||
/**
|
||||
* The installation profile to install.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'testing';
|
||||
|
||||
/**
|
||||
* Additional parameters to use for installer screens.
|
||||
*
|
||||
* @see FunctionalTestSetupTrait::installParameters()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $parameters = [];
|
||||
|
||||
/**
|
||||
* A string translation map used for translated installer screens.
|
||||
*
|
||||
* Keys are English strings, values are translated strings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $translations = [
|
||||
'Save and continue' => 'Save and continue',
|
||||
];
|
||||
|
||||
/**
|
||||
* Whether the installer has completed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isInstalled = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->isInstalled = FALSE;
|
||||
|
||||
$this->setupBaseUrl();
|
||||
|
||||
$this->prepareDatabasePrefix();
|
||||
|
||||
// Install Drupal test site.
|
||||
$this->prepareEnvironment();
|
||||
|
||||
// Define information about the user 1 account.
|
||||
$this->rootUser = new UserSession([
|
||||
'uid' => 1,
|
||||
'name' => 'admin',
|
||||
'mail' => 'admin@example.com',
|
||||
'pass_raw' => $this->randomMachineName(),
|
||||
]);
|
||||
|
||||
// If any $settings are defined for this test, copy and prepare an actual
|
||||
// settings.php, so as to resemble a regular installation.
|
||||
if (!empty($this->settings)) {
|
||||
// Not using File API; a potential error must trigger a PHP warning.
|
||||
copy(DRUPAL_ROOT . '/sites/default/default.settings.php', DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php');
|
||||
$this->writeSettings($this->settings);
|
||||
}
|
||||
|
||||
// Note that FunctionalTestSetupTrait::installParameters() returns form
|
||||
// input values suitable for a programmed
|
||||
// \Drupal::formBuilder()->submitForm().
|
||||
// @see InstallerTestBase::translatePostValues()
|
||||
$this->parameters = $this->installParameters();
|
||||
|
||||
// Set up a minimal container (required by BrowserTestBase). Set cookie and
|
||||
// server information so that XDebug works.
|
||||
// @see install_begin_request()
|
||||
$request = Request::create($GLOBALS['base_url'] . '/core/install.php', 'GET', [], $_COOKIE, [], $_SERVER);
|
||||
$this->container = new ContainerBuilder();
|
||||
$request_stack = new RequestStack();
|
||||
$request_stack->push($request);
|
||||
$this->container
|
||||
->set('request_stack', $request_stack);
|
||||
$this->container
|
||||
->setParameter('language.default_values', Language::$defaultValues);
|
||||
$this->container
|
||||
->register('language.default', 'Drupal\Core\Language\LanguageDefault')
|
||||
->addArgument('%language.default_values%');
|
||||
$this->container
|
||||
->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
|
||||
->addArgument(new Reference('language.default'));
|
||||
$this->container
|
||||
->register('http_client', 'GuzzleHttp\Client')
|
||||
->setFactory('http_client_factory:fromOptions');
|
||||
$this->container
|
||||
->register('http_client_factory', 'Drupal\Core\Http\ClientFactory')
|
||||
->setArguments([new Reference('http_handler_stack')]);
|
||||
$handler_stack = HandlerStack::create();
|
||||
$test_http_client_middleware = new TestHttpClientMiddleware();
|
||||
$handler_stack->push($test_http_client_middleware(), 'test.http_client.middleware');
|
||||
$this->container
|
||||
->set('http_handler_stack', $handler_stack);
|
||||
|
||||
$this->container
|
||||
->set('app.root', DRUPAL_ROOT);
|
||||
\Drupal::setContainer($this->container);
|
||||
|
||||
// Setup Mink.
|
||||
$this->initMink();
|
||||
|
||||
// Set up the browser test output file.
|
||||
$this->initBrowserOutputFile();
|
||||
|
||||
$this->visitInstaller();
|
||||
|
||||
// Select language.
|
||||
$this->setUpLanguage();
|
||||
|
||||
// Select profile.
|
||||
$this->setUpProfile();
|
||||
|
||||
// Address the requirements problem screen, if any.
|
||||
$this->setUpRequirementsProblem();
|
||||
|
||||
// Configure settings.
|
||||
$this->setUpSettings();
|
||||
|
||||
// @todo Allow test classes based on this class to act on further installer
|
||||
// screens.
|
||||
|
||||
// Configure site.
|
||||
$this->setUpSite();
|
||||
|
||||
if ($this->isInstalled) {
|
||||
// Import new settings.php written by the installer.
|
||||
$request = Request::createFromGlobals();
|
||||
$class_loader = require $this->container->get('app.root') . '/autoload.php';
|
||||
Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
|
||||
foreach ($GLOBALS['config_directories'] as $type => $path) {
|
||||
$this->configDirectories[$type] = $path;
|
||||
}
|
||||
|
||||
// After writing settings.php, the installer removes write permissions
|
||||
// from the site directory. To allow drupal_generate_test_ua() to write
|
||||
// a file containing the private key for drupal_valid_test_ua(), the site
|
||||
// directory has to be writable.
|
||||
// BrowserTestBase::tearDown() will delete the entire test site directory.
|
||||
// Not using File API; a potential error must trigger a PHP warning.
|
||||
chmod($this->container->get('app.root') . '/' . $this->siteDirectory, 0777);
|
||||
$this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
|
||||
$this->kernel->prepareLegacyRequest($request);
|
||||
$this->container = $this->kernel->getContainer();
|
||||
|
||||
// Manually configure the test mail collector implementation to prevent
|
||||
// tests from sending out emails and collect them in state instead.
|
||||
$this->container->get('config.factory')
|
||||
->getEditable('system.mail')
|
||||
->set('interface.default', 'test_mail_collector')
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initFrontPage() {
|
||||
// We don't want to visit the front page with the installer when
|
||||
// initializing Mink, so we do nothing here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the interactive installer.
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Select language.
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
$edit = [
|
||||
'langcode' => $this->langcode,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Select installation profile.
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
$edit = [
|
||||
'profile' => $this->profile,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Configure settings.
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
$edit = $this->translatePostValues($this->parameters['forms']['install_settings_form']);
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Requirements problem.
|
||||
*
|
||||
* Override this method to test specific requirements warnings or errors
|
||||
* during the installer.
|
||||
*
|
||||
* @see system_requirements()
|
||||
*/
|
||||
protected function setUpRequirementsProblem() {
|
||||
// By default, skip the "recommended PHP version" warning on older test
|
||||
// environments. This allows the installer to be tested consistently on
|
||||
// both recommended PHP versions and older (but still supported) versions.
|
||||
if (version_compare(phpversion(), '7.0') < 0) {
|
||||
$this->continueOnExpectedWarnings(['PHP']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Final installer step: Configure site.
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
$edit = $this->translatePostValues($this->parameters['forms']['install_configure_form']);
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
// If we've got to this point the site is installed using the regular
|
||||
// installation workflow.
|
||||
$this->isInstalled = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* FunctionalTestSetupTrait::refreshVariables() tries to operate on persistent
|
||||
* storage, which is only available after the installer completed.
|
||||
*/
|
||||
protected function refreshVariables() {
|
||||
if ($this->isInstalled) {
|
||||
parent::refreshVariables();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues installation when an expected warning is found.
|
||||
*
|
||||
* @param string[] $expected_warnings
|
||||
* A list of warning summaries to expect on the requirements screen (e.g.
|
||||
* 'PHP', 'PHP OPcode caching', etc.). If only the expected warnings
|
||||
* are found, the test will click the "continue anyway" link to go to the
|
||||
* next screen of the installer. If an expected warning is not found, or if
|
||||
* a warning not in the list is present, a fail is raised.
|
||||
*/
|
||||
protected function continueOnExpectedWarnings($expected_warnings = []) {
|
||||
// Don't try to continue if there are errors.
|
||||
if (strpos($this->getTextContent(), 'Errors found') !== FALSE) {
|
||||
return;
|
||||
}
|
||||
// Allow only details elements that are directly after the warning header
|
||||
// or each other. There is no guaranteed wrapper we can rely on across
|
||||
// distributions. When there are multiple warnings, the selectors will be:
|
||||
// - h3#warning+details summary
|
||||
// - h3#warning+details+details summary
|
||||
// - etc.
|
||||
// We add one more selector than expected warnings to confirm that there
|
||||
// isn't any other warning before clicking the link.
|
||||
// @todo Make this more reliable in
|
||||
// https://www.drupal.org/project/drupal/issues/2927345.
|
||||
$selectors = [];
|
||||
for ($i = 0; $i <= count($expected_warnings); $i++) {
|
||||
$selectors[] = 'h3#warning' . implode('', array_fill(0, $i + 1, '+details')) . ' summary';
|
||||
}
|
||||
$warning_elements = $this->cssSelect(implode(', ', $selectors));
|
||||
|
||||
// Confirm that there are only the expected warnings.
|
||||
$warnings = [];
|
||||
foreach ($warning_elements as $warning) {
|
||||
$warnings[] = trim($warning->getText());
|
||||
}
|
||||
$this->assertEquals($expected_warnings, $warnings);
|
||||
$this->clickLink('continue anyway');
|
||||
$this->checkForMetaRefresh();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests translation files for multiple languages get imported during install.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationMultipleLanguageForeignTest extends InstallerTranslationMultipleLanguageTest {
|
||||
|
||||
/**
|
||||
* Overrides the language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
parent::setUpLanguage();
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests that keeping English in a foreign language install works.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationMultipleLanguageKeepEnglishTest extends InstallerTranslationMultipleLanguageForeignTest {
|
||||
|
||||
/**
|
||||
* Switch to the multilingual testing profile with English kept.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'testing_multilingual_with_english';
|
||||
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests translation files for multiple languages get imported during install.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationMultipleLanguageTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Switch to the multilingual testing profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'testing_multilingual';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place custom local translations in the translations directory.
|
||||
mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.es.po', $this->getPo('es'));
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
|
||||
msgid "Anonymous"
|
||||
msgstr "Anonymous $langcode"
|
||||
|
||||
msgid "Language"
|
||||
msgstr "Language $langcode"
|
||||
|
||||
#: Testing site name configuration during the installer.
|
||||
msgid "Drupal"
|
||||
msgstr "Drupal"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function installParameters() {
|
||||
$params = parent::installParameters();
|
||||
$params['forms']['install_configure_form']['site_name'] = 'SITE_NAME_' . $this->langcode;
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that translations ended up at the expected places.
|
||||
*/
|
||||
public function testTranslationsLoaded() {
|
||||
// Ensure the title is correct.
|
||||
$this->assertEqual('SITE_NAME_' . $this->langcode, \Drupal::config('system.site')->get('name'));
|
||||
|
||||
// Verify German and Spanish were configured.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertText('Spanish');
|
||||
// If the installer was English or we used a profile that keeps English, we
|
||||
// expect that configured also. Otherwise English should not be configured
|
||||
// on the site.
|
||||
if ($this->langcode == 'en' || $this->profile == 'testing_multilingual_with_english') {
|
||||
$this->assertText('English');
|
||||
}
|
||||
else {
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
// Verify the strings from the translation files were imported.
|
||||
$this->verifyImportedStringsTranslated();
|
||||
|
||||
/** @var \Drupal\language\ConfigurableLanguageManager $language_manager */
|
||||
$language_manager = \Drupal::languageManager();
|
||||
|
||||
// If the site was installed in a foreign language (only tested with German
|
||||
// in subclasses), then the active configuration should be updated and no
|
||||
// override should exist in German. Otherwise the German translation should
|
||||
// end up in overrides the same way as Spanish (which is not used as a site
|
||||
// installation language). English should be available based on profile
|
||||
// information and should be possible to add if not yet added, making
|
||||
// English overrides available.
|
||||
|
||||
$config = \Drupal::config('user.settings');
|
||||
$override_de = $language_manager->getLanguageConfigOverride('de', 'user.settings');
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$override_es = $language_manager->getLanguageConfigOverride('es', 'user.settings');
|
||||
|
||||
if ($this->langcode == 'de') {
|
||||
// Active configuration should be in German and no German override should
|
||||
// exist.
|
||||
$this->assertEqual($config->get('anonymous'), 'Anonymous de');
|
||||
$this->assertEqual($config->get('langcode'), 'de');
|
||||
$this->assertTrue($override_de->isNew());
|
||||
|
||||
if ($this->profile == 'testing_multilingual_with_english') {
|
||||
// English is already added in this profile. Should make the override
|
||||
// available.
|
||||
$this->assertEqual($override_en->get('anonymous'), 'Anonymous');
|
||||
}
|
||||
else {
|
||||
// English is not yet available.
|
||||
$this->assertTrue($override_en->isNew());
|
||||
|
||||
// Adding English should make the English override available.
|
||||
$edit = ['predefined_langcode' => 'en'];
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$this->assertEqual($override_en->get('anonymous'), 'Anonymous');
|
||||
}
|
||||
|
||||
// Activate a module, to make sure that config is not overridden by module
|
||||
// installation.
|
||||
$edit = [
|
||||
'modules[views][enable]' => TRUE,
|
||||
'modules[filter][enable]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/modules', $edit, t('Install'));
|
||||
|
||||
// Verify the strings from the translation are still as expected.
|
||||
$this->verifyImportedStringsTranslated();
|
||||
}
|
||||
else {
|
||||
// Active configuration should be English.
|
||||
$this->assertEqual($config->get('anonymous'), 'Anonymous');
|
||||
$this->assertEqual($config->get('langcode'), 'en');
|
||||
// There should not be an English override.
|
||||
$this->assertTrue($override_en->isNew());
|
||||
// German should be an override.
|
||||
$this->assertEqual($override_de->get('anonymous'), 'Anonymous de');
|
||||
}
|
||||
|
||||
// Spanish is always an override (never used as installation language).
|
||||
$this->assertEqual($override_es->get('anonymous'), 'Anonymous es');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to verify that the expected strings are translated.
|
||||
*/
|
||||
protected function verifyImportedStringsTranslated() {
|
||||
$test_samples = ['Save and continue', 'Anonymous', 'Language'];
|
||||
$langcodes = ['de', 'es'];
|
||||
|
||||
foreach ($test_samples as $sample) {
|
||||
foreach ($langcodes as $langcode) {
|
||||
$edit = [];
|
||||
$edit['langcode'] = $langcode;
|
||||
$edit['translation'] = 'translated';
|
||||
$edit['string'] = $sample;
|
||||
$this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
|
||||
$this->assertText($sample . ' ' . $langcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Installs Drupal in German and checks resulting site.
|
||||
*
|
||||
* @group Installer
|
||||
*
|
||||
* @see \Drupal\FunctionalTests\Installer\InstallerTranslationTest
|
||||
*/
|
||||
class InstallerTranslationQueryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Overrides the language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir($this->root . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
|
||||
// The unrouted URL assembler does not exist at this point, so we build the
|
||||
// URL ourselves.
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php' . '?langcode=' . $this->langcode);
|
||||
|
||||
// The language should have been automatically detected, all following
|
||||
// screens should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual(current($elements)->getText(), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = current($this->xpath('/@dir'))->getText();
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// The language was was preset by passing a query parameter in the URL, so
|
||||
// no explicit language selection is necessary.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the expected behaviors of the installation result.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Installs Drupal in German and checks resulting site.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Overrides the language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir($this->root . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents($this->root . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
|
||||
parent::setUpLanguage();
|
||||
|
||||
// After selecting a different language than English, all following screens
|
||||
// should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual(current($elements)->getText(), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = current($this->xpath('/@dir'))->getText();
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// We are creating a table here to force an error in the installer because
|
||||
// it will try and create the drupal_install_test table as this is part of
|
||||
// the standard database tests performed by the installer in
|
||||
// Drupal\Core\Database\Install\Tasks.
|
||||
Database::getConnection('default')->query('CREATE TABLE {drupal_install_test} (id int NULL)');
|
||||
parent::setUpSettings();
|
||||
|
||||
// Ensure that the error message translation is working.
|
||||
$this->assertRaw('Beheben Sie alle Probleme unten, um die Installation fortzusetzen. Informationen zur Konfiguration der Datenbankserver finden Sie in der <a href="https://www.drupal.org/getting-started/install">Installationshandbuch</a>, oder kontaktieren Sie Ihren Hosting-Anbieter.');
|
||||
$this->assertRaw('<strong>CREATE</strong> ein Test-Tabelle auf Ihrem Datenbankserver mit dem Befehl <em class="placeholder">CREATE TABLE {drupal_install_test} (id int NULL)</em> fehlgeschlagen.');
|
||||
|
||||
// Now do it successfully.
|
||||
Database::getConnection('default')->query('DROP TABLE {drupal_install_test}');
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the expected behaviors of the installation result.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
|
||||
// The current container still has the english as current language, rebuild.
|
||||
$this->rebuildContainer();
|
||||
/** @var \Drupal\user\Entity\User $account */
|
||||
$account = User::load(0);
|
||||
$this->assertEqual($account->language()->getId(), 'en', 'Anonymous user is English.');
|
||||
$account = User::load(1);
|
||||
$this->assertEqual($account->language()->getId(), 'en', 'Administrator user is English.');
|
||||
$account = $this->drupalCreateUser();
|
||||
$this->assertEqual($account->language()->getId(), 'de', 'New user is German.');
|
||||
|
||||
// Ensure that we can enable basic_auth on a non-english site.
|
||||
$this->drupalPostForm('admin/modules', ['modules[basic_auth][enable]' => TRUE], t('Install'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Assert that the theme CSS was added to the page.
|
||||
$edit = ['preprocess_css' => FALSE];
|
||||
$this->drupalPostForm('admin/config/development/performance', $edit, t('Save configuration'));
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertRaw('classy/css/components/action-links.css');
|
||||
|
||||
// Verify the strings from the translation files were imported.
|
||||
$test_samples = ['Save and continue', 'Anonymous'];
|
||||
foreach ($test_samples as $sample) {
|
||||
$edit = [];
|
||||
$edit['langcode'] = 'de';
|
||||
$edit['translation'] = 'translated';
|
||||
$edit['string'] = $sample;
|
||||
$this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
|
||||
$this->assertText($sample . ' de');
|
||||
}
|
||||
|
||||
/** @var \Drupal\language\ConfigurableLanguageManager $language_manager */
|
||||
$language_manager = \Drupal::languageManager();
|
||||
|
||||
// Installed in German, configuration should be in German. No German or
|
||||
// English overrides should be present.
|
||||
$config = \Drupal::config('user.settings');
|
||||
$override_de = $language_manager->getLanguageConfigOverride('de', 'user.settings');
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$this->assertEqual($config->get('anonymous'), 'Anonymous de');
|
||||
$this->assertEqual($config->get('langcode'), 'de');
|
||||
$this->assertTrue($override_de->isNew());
|
||||
$this->assertTrue($override_en->isNew());
|
||||
|
||||
// Assert that adding English makes the English override available.
|
||||
$edit = ['predefined_langcode' => 'en'];
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$this->assertFalse($override_en->isNew());
|
||||
$this->assertEqual($override_en->get('anonymous'), 'Anonymous');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
|
||||
msgid "Anonymous"
|
||||
msgstr "Anonymous $langcode"
|
||||
|
||||
msgid "Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="https://www.drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider."
|
||||
msgstr "Beheben Sie alle Probleme unten, um die Installation fortzusetzen. Informationen zur Konfiguration der Datenbankserver finden Sie in der <a href="https://www.drupal.org/getting-started/install">Installationshandbuch</a>, oder kontaktieren Sie Ihren Hosting-Anbieter."
|
||||
|
||||
msgid "Failed to <strong>CREATE</strong> a test table on your database server with the command %query. The server reports the following message: %error.<p>Are you sure the configured username has the necessary permissions to create tables in the database?</p>"
|
||||
msgstr "<strong>CREATE</strong> ein Test-Tabelle auf Ihrem Datenbankserver mit dem Befehl %query fehlgeschlagen."
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\KernelTests\AssertConfigTrait;
|
||||
|
||||
/**
|
||||
* Tests the interactive installer installing the minimal profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class MinimalInstallerTest extends ConfigAfterInstallerTestBase {
|
||||
|
||||
use AssertConfigTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'minimal';
|
||||
|
||||
/**
|
||||
* Ensures that the exported minimal configuration is up to date.
|
||||
*/
|
||||
public function testMinimalConfig() {
|
||||
$this->assertInstalledConfig([]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
|
||||
/**
|
||||
* Tests multiple distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class MultipleDistributionsProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
// Create two distributions.
|
||||
foreach (['distribution_one', 'distribution_two'] as $name) {
|
||||
$info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => $name . ' profile',
|
||||
'distribution' => [
|
||||
'name' => $name,
|
||||
'install' => [
|
||||
'theme' => 'bartik',
|
||||
],
|
||||
],
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->root . DIRECTORY_SEPARATOR . $this->siteDirectory . '/profiles/' . $name;
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/$name.info.yml", Yaml::encode($info));
|
||||
}
|
||||
// Install the first distribution.
|
||||
$this->profile = 'distribution_one';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw('distribution_one');
|
||||
// Verify that the requested theme is used.
|
||||
$this->assertRaw('bartik');
|
||||
// Verify that the "Choose profile" step does not appear.
|
||||
$this->assertNoText('profile');
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual(\Drupal::installProfile(), 'distribution_one');
|
||||
$this->assertEqual($this->config('core.extension')->get('profile'), 'distribution_one', 'The install profile has been written to core.extension configuration.');
|
||||
|
||||
$this->rebuildContainer();
|
||||
$this->pass('Container can be rebuilt as distribution is written to configuration.');
|
||||
$this->assertEqual(\Drupal::installProfile(), 'distribution_one');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class SingleVisibleProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The installation profile to install.
|
||||
*
|
||||
* Not needed when only one is visible.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = NULL;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEnvironment() {
|
||||
parent::prepareEnvironment();
|
||||
$profiles = ['standard', 'demo_umami'];
|
||||
foreach ($profiles as $profile) {
|
||||
$info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Override ' . $profile,
|
||||
'hidden' => TRUE,
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->siteDirectory . '/profiles/' . $profile;
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/$profile.info.yml", Yaml::encode($info));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is only one visible profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
// Confirm that the minimal profile was installed.
|
||||
$this->assertEqual(drupal_get_profile(), 'minimal');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the site name can be set during a non-interactive installation.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class SiteNameTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* The site name to be used when testing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $siteName;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function installParameters() {
|
||||
$this->siteName = $this->randomMachineName();
|
||||
$parameters = parent::installParameters();
|
||||
$parameters['forms']['install_configure_form']['site_name'] = $this->siteName;
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the desired site name appears on the page after installation.
|
||||
*/
|
||||
public function testSiteName() {
|
||||
$this->drupalGet('');
|
||||
$this->assertRaw($this->siteName, 'The site name that was set during the installation appears on the front page after installation.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Installer;
|
||||
|
||||
/**
|
||||
* Tests the interactive installer installing the standard profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class StandardInstallerTest extends ConfigAfterInstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'standard';
|
||||
|
||||
/**
|
||||
* Ensures that the user page is available after installation.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
// Verify that the Standard install profile's default frontpage appears.
|
||||
$this->assertRaw('No front page content has been created yet.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// Test that the correct theme is being used.
|
||||
$this->assertNoRaw('bartik');
|
||||
$this->assertRaw('themes/seven/css/theme/install-page.css');
|
||||
parent::setUpSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function curlExec($curl_options, $redirect = FALSE) {
|
||||
// Ensure that we see the classy progress CSS on the batch page.
|
||||
// Batch processing happens as part of HTTP redirects, so we can access the
|
||||
// HTML of the batch page.
|
||||
if (strpos($curl_options[CURLOPT_URL], '&id=1&op=do_nojs') !== FALSE) {
|
||||
$this->assertRaw('themes/classy/css/components/progress.css');
|
||||
}
|
||||
return parent::curlExec($curl_options, $redirect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the exported standard configuration is up to date.
|
||||
*/
|
||||
public function testStandardConfig() {
|
||||
$skipped_config = [];
|
||||
// FunctionalTestSetupTrait::installParameters() uses
|
||||
// simpletest@example.com as mail address.
|
||||
$skipped_config['contact.form.feedback'][] = '- simpletest@example.com';
|
||||
// \Drupal\filter\Entity\FilterFormat::toArray() drops the roles of filter
|
||||
// formats.
|
||||
$skipped_config['filter.format.basic_html'][] = 'roles:';
|
||||
$skipped_config['filter.format.basic_html'][] = '- authenticated';
|
||||
$skipped_config['filter.format.full_html'][] = 'roles:';
|
||||
$skipped_config['filter.format.full_html'][] = '- administrator';
|
||||
$skipped_config['filter.format.restricted_html'][] = 'roles:';
|
||||
$skipped_config['filter.format.restricted_html'][] = '- anonymous';
|
||||
|
||||
$this->assertInstalledConfig($skipped_config);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BaseFieldOverrideJsonAnonTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BaseFieldOverrideJsonBasicAuthTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BaseFieldOverrideJsonCookieTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Core\Field\Entity\BaseFieldOverride;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
abstract class BaseFieldOverrideResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'base_field_override';
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Field\Entity\BaseFieldOverride
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer node fields']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
$camelids = NodeType::create([
|
||||
'name' => 'Camelids',
|
||||
'type' => 'camelids',
|
||||
]);
|
||||
$camelids->save();
|
||||
|
||||
$entity = BaseFieldOverride::create([
|
||||
'field_name' => 'promote',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'camelids',
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'bundle' => 'camelids',
|
||||
'default_value' => [],
|
||||
'default_value_callback' => '',
|
||||
'dependencies' => [
|
||||
'config' => [
|
||||
'node.type.camelids',
|
||||
],
|
||||
],
|
||||
'description' => '',
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'promote',
|
||||
'field_type' => 'boolean',
|
||||
'id' => 'node.camelids.promote',
|
||||
'label' => NULL,
|
||||
'langcode' => 'en',
|
||||
'required' => FALSE,
|
||||
'settings' => [
|
||||
'on_label' => 'On',
|
||||
'off_label' => 'Off',
|
||||
],
|
||||
'status' => TRUE,
|
||||
'translatable' => TRUE,
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return [
|
||||
'user.permissions',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
return "The 'administer node fields' permission is required.";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BaseFieldOverrideXmlAnonTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BaseFieldOverrideXmlBasicAuthTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BaseFieldOverrideXmlCookieTest extends BaseFieldOverrideResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class DateFormatJsonAnonTest extends DateFormatResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class DateFormatJsonBasicAuthTest extends DateFormatResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class DateFormatJsonCookieTest extends DateFormatResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
/**
|
||||
* ResourceTestBase for DateFormat entity.
|
||||
*/
|
||||
abstract class DateFormatResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'date_format';
|
||||
|
||||
/**
|
||||
* The DateFormat entity.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer site configuration']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
// Create a date format.
|
||||
$date_format = DateFormat::create([
|
||||
'id' => 'llama',
|
||||
'label' => 'Llama',
|
||||
'pattern' => 'F d, Y',
|
||||
]);
|
||||
|
||||
$date_format->save();
|
||||
|
||||
return $date_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'dependencies' => [],
|
||||
'id' => 'llama',
|
||||
'label' => 'Llama',
|
||||
'langcode' => 'en',
|
||||
'locked' => FALSE,
|
||||
'pattern' => 'F d, Y',
|
||||
'status' => TRUE,
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class DateFormatXmlAnonTest extends DateFormatResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class DateFormatXmlBasicAuthTest extends DateFormatResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class DateFormatXmlCookieTest extends DateFormatResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormDisplayJsonAnonTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormDisplayJsonBasicAuthTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormDisplayJsonCookieTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
abstract class EntityFormDisplayResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'entity_form_display';
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer node form display']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
// Create a "Camelids" node type.
|
||||
$camelids = NodeType::create([
|
||||
'name' => 'Camelids',
|
||||
'type' => 'camelids',
|
||||
]);
|
||||
|
||||
$camelids->save();
|
||||
|
||||
// Create a form display.
|
||||
$form_display = EntityFormDisplay::create([
|
||||
'targetEntityType' => 'node',
|
||||
'bundle' => 'camelids',
|
||||
'mode' => 'default',
|
||||
]);
|
||||
$form_display->save();
|
||||
|
||||
return $form_display;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'bundle' => 'camelids',
|
||||
'content' => [
|
||||
'created' => [
|
||||
'type' => 'datetime_timestamp',
|
||||
'weight' => 10,
|
||||
'region' => 'content',
|
||||
'settings' => [],
|
||||
'third_party_settings' => [],
|
||||
],
|
||||
'promote' => [
|
||||
'type' => 'boolean_checkbox',
|
||||
'settings' => [
|
||||
'display_label' => TRUE,
|
||||
],
|
||||
'weight' => 15,
|
||||
'region' => 'content',
|
||||
'third_party_settings' => [],
|
||||
],
|
||||
'status' => [
|
||||
'type' => 'boolean_checkbox',
|
||||
'weight' => 120,
|
||||
'region' => 'content',
|
||||
'settings' => [
|
||||
'display_label' => TRUE,
|
||||
],
|
||||
'third_party_settings' => [],
|
||||
],
|
||||
'sticky' => [
|
||||
'type' => 'boolean_checkbox',
|
||||
'settings' => [
|
||||
'display_label' => TRUE,
|
||||
],
|
||||
'weight' => 16,
|
||||
'region' => 'content',
|
||||
'third_party_settings' => [],
|
||||
],
|
||||
'title' => [
|
||||
'type' => 'string_textfield',
|
||||
'weight' => -5,
|
||||
'region' => 'content',
|
||||
'settings' => [
|
||||
'size' => 60,
|
||||
'placeholder' => '',
|
||||
],
|
||||
'third_party_settings' => [],
|
||||
],
|
||||
'uid' => [
|
||||
'type' => 'entity_reference_autocomplete',
|
||||
'weight' => 5,
|
||||
'settings' => [
|
||||
'match_operator' => 'CONTAINS',
|
||||
'size' => 60,
|
||||
'placeholder' => '',
|
||||
],
|
||||
'region' => 'content',
|
||||
'third_party_settings' => [],
|
||||
],
|
||||
],
|
||||
'dependencies' => [
|
||||
'config' => [
|
||||
'node.type.camelids',
|
||||
],
|
||||
],
|
||||
'hidden' => [],
|
||||
'id' => 'node.camelids.default',
|
||||
'langcode' => 'en',
|
||||
'mode' => 'default',
|
||||
'status' => NULL,
|
||||
'targetEntityType' => 'node',
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return [
|
||||
'user.permissions',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
return "The 'administer node form display' permission is required.";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormDisplayXmlAnonTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormDisplayXmlBasicAuthTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormDisplayXmlCookieTest extends EntityFormDisplayResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormModeJsonAnonTest extends EntityFormModeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormModeJsonBasicAuthTest extends EntityFormModeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityFormModeJsonCookieTest extends EntityFormModeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
use Drupal\Core\Entity\Entity\EntityFormMode;
|
||||
|
||||
abstract class EntityFormModeResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @todo: Remove 'field_ui' when https://www.drupal.org/node/2867266.
|
||||
*/
|
||||
public static $modules = ['user', 'field_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'entity_form_mode';
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\EntityFormModeInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer display modes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
$entity_form_mode = EntityFormMode::create([
|
||||
'id' => 'user.test',
|
||||
'label' => 'Test',
|
||||
'targetEntityType' => 'user',
|
||||
]);
|
||||
$entity_form_mode->save();
|
||||
return $entity_form_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'cache' => TRUE,
|
||||
'dependencies' => [
|
||||
'module' => [
|
||||
'user',
|
||||
],
|
||||
],
|
||||
'id' => 'user.test',
|
||||
'label' => 'Test',
|
||||
'langcode' => 'en',
|
||||
'status' => TRUE,
|
||||
'targetEntityType' => 'user',
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue