upgrades core to 8.4.2
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests Ajax callbacks on FAPI elements.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class AjaxCallbacksTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['ajax_forms_test'];
|
||||
|
||||
/**
|
||||
* Tests if Ajax callback works on date element.
|
||||
*/
|
||||
public function testDateAjaxCallback() {
|
||||
|
||||
// Test Ajax callback when date changes.
|
||||
$this->drupalGet('ajax_forms_test_ajax_element_form');
|
||||
$this->assertSession()->responseContains('No date yet selected');
|
||||
$this->getSession()->getPage()->fillField('edit-date', '2016-01-01');
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
$this->assertSession()->responseNotContains('No date yet selected');
|
||||
$this->assertSession()->responseContains('2016-01-01');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if Ajax callback works on datetime element.
|
||||
*/
|
||||
public function testDateTimeAjaxCallback() {
|
||||
|
||||
// Test Ajax callback when datetime changes.
|
||||
$this->drupalGet('ajax_forms_test_ajax_element_form');
|
||||
$this->assertSession()->responseContains('No datetime selected.');
|
||||
$this->getSession()->getPage()->fillField('edit-datetime-date', '2016-01-01');
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
$this->assertSession()->responseNotContains('No datetime selected.');
|
||||
$this->assertSession()->responseContains('2016-01-01');
|
||||
$this->getSession()->getPage()->fillField('edit-datetime-time', '12:00:00');
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
$this->assertSession()->responseContains('2016-01-01 12:00:00');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests the Ajax image buttons work with key press events.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class AjaxFormImageButtonTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['ajax_forms_test'];
|
||||
|
||||
/**
|
||||
* Tests image buttons can be operated with the keyboard ENTER key.
|
||||
*/
|
||||
public function testAjaxImageButton() {
|
||||
// Get a Field UI manage-display page.
|
||||
$this->drupalGet('ajax_forms_image_button_form');
|
||||
$assertSession = $this->assertSession();
|
||||
$session = $this->getSession();
|
||||
|
||||
$enter_key_event = <<<JS
|
||||
jQuery('#edit-image-button')
|
||||
.trigger(jQuery.Event('keypress', {
|
||||
which: 13
|
||||
}));
|
||||
JS;
|
||||
// PhantomJS driver has buggy behavior with key events, we send a JavaScript
|
||||
// key event instead.
|
||||
// @todo: use WebDriver event when we remove PhantomJS driver.
|
||||
$session->executeScript($enter_key_event);
|
||||
|
||||
$this->assertNotEmpty($assertSession->waitForElementVisible('css', '#ajax-1-more-div'), 'Page updated after image button pressed');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Core\Form;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests for form grouping elements.
|
||||
*
|
||||
* @group form
|
||||
*/
|
||||
class FormGroupingElementsTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* Required modules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['form_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$account = $this->drupalCreateUser();
|
||||
$this->drupalLogin($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that vertical tab children become visible.
|
||||
*
|
||||
* Makes sure that a child element of a vertical tab that is not visible,
|
||||
* becomes visible when the tab is clicked, a fragment link to the child is
|
||||
* clicked or when the URI fragment pointing to that child changes.
|
||||
*/
|
||||
public function testVerticalTabChildVisibility() {
|
||||
$session = $this->getSession();
|
||||
$web_assert = $this->assertSession();
|
||||
|
||||
// Request the group vertical tabs testing page with a fragment identifier
|
||||
// to the second element.
|
||||
$this->drupalGet('form-test/group-vertical-tabs', ['fragment' => 'edit-element-2']);
|
||||
|
||||
$page = $session->getPage();
|
||||
|
||||
$tab_link_1 = $page->find('css', '.vertical-tabs__menu-item > a');
|
||||
|
||||
$child_1_selector = '#edit-element';
|
||||
$child_1 = $page->find('css', $child_1_selector);
|
||||
|
||||
$child_2_selector = '#edit-element-2';
|
||||
$child_2 = $page->find('css', $child_2_selector);
|
||||
|
||||
// Assert that the child in the second vertical tab becomes visible.
|
||||
// It should be visible after initial load due to the fragment in the URI.
|
||||
$this->assertTrue($child_2->isVisible(), 'Child 2 is visible due to a URI fragment');
|
||||
|
||||
// Click on a fragment link pointing to an invisible child inside an
|
||||
// inactive vertical tab.
|
||||
$session->executeScript("jQuery('<a href=\"$child_1_selector\"></a>').insertAfter('h1')[0].click()");
|
||||
|
||||
// Assert that the child in the first vertical tab becomes visible.
|
||||
$web_assert->waitForElementVisible('css', $child_1_selector, 50);
|
||||
|
||||
// Trigger a URI fragment change (hashchange) to show the second vertical
|
||||
// tab again.
|
||||
$session->executeScript("location.replace('$child_2_selector')");
|
||||
|
||||
// Assert that the child in the second vertical tab becomes visible again.
|
||||
$web_assert->waitForElementVisible('css', $child_2_selector, 50);
|
||||
|
||||
$tab_link_1->click();
|
||||
|
||||
// Assert that the child in the first vertical tab is visible again after
|
||||
// a click on the first tab.
|
||||
$this->assertTrue($child_1->isVisible(), 'Child 1 is visible after clicking the parent tab');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that details element children become visible.
|
||||
*
|
||||
* Makes sure that a child element of a details element that is not visible,
|
||||
* becomes visible when a fragment link to the child is clicked or when the
|
||||
* URI fragment pointing to that child changes.
|
||||
*/
|
||||
public function testDetailsChildVisibility() {
|
||||
$session = $this->getSession();
|
||||
$web_assert = $this->assertSession();
|
||||
|
||||
// Store reusable JavaScript code to remove the current URI fragment and
|
||||
// close all details.
|
||||
$reset_js = "location.replace('#'); jQuery('details').removeAttr('open')";
|
||||
|
||||
// Request the group details testing page.
|
||||
$this->drupalGet('form-test/group-details');
|
||||
|
||||
$page = $session->getPage();
|
||||
|
||||
$session->executeScript($reset_js);
|
||||
|
||||
$child_selector = '#edit-element';
|
||||
$child = $page->find('css', $child_selector);
|
||||
|
||||
// Assert that the child is not visible.
|
||||
$this->assertFalse($child->isVisible(), 'Child is not visible');
|
||||
|
||||
// Trigger a URI fragment change (hashchange) to open all parent details
|
||||
// elements of the child.
|
||||
$session->executeScript("location.replace('$child_selector')");
|
||||
|
||||
// Assert that the child becomes visible again after a hash change.
|
||||
$web_assert->waitForElementVisible('css', $child_selector, 50);
|
||||
|
||||
$session->executeScript($reset_js);
|
||||
|
||||
// Click on a fragment link pointing to an invisible child inside a closed
|
||||
// details element.
|
||||
$session->executeScript("jQuery('<a href=\"$child_selector\"></a>').insertAfter('h1')[0].click()");
|
||||
|
||||
// Assert that the child is visible again after a fragment link click.
|
||||
$web_assert->waitForElementVisible('css', $child_selector, 50);
|
||||
|
||||
// Find the summary belonging to the closest details element.
|
||||
$summary = $page->find('css', '#edit-meta > summary');
|
||||
|
||||
// Assert that both aria-expanded and aria-pressed are true.
|
||||
$this->assertTrue($summary->getAttribute('aria-expanded'));
|
||||
$this->assertTrue($summary->getAttribute('aria-pressed'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,13 +48,10 @@ class SessionTest extends JavascriptTestBase {
|
||||
// number of times.
|
||||
$this->drupalGet('<front>');
|
||||
|
||||
$session_assert = $this->assertSession();
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
for ($i = 0; $i < 25; $i++) {
|
||||
$page->clickLink('Link to front page');
|
||||
$session_assert->statusCodeEquals(200);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ JS;
|
||||
public function waitForElement($selector, $locator, $timeout = 10000) {
|
||||
$page = $this->session->getPage();
|
||||
|
||||
$result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) {
|
||||
$result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) {
|
||||
return $page->find($selector, $locator);
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ JS;
|
||||
public function waitForElementVisible($selector, $locator, $timeout = 10000) {
|
||||
$page = $this->session->getPage();
|
||||
|
||||
$result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) {
|
||||
$result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) {
|
||||
$element = $page->find($selector, $locator);
|
||||
if (!empty($element) && $element->isVisible()) {
|
||||
return $element;
|
||||
|
||||
@@ -7,7 +7,7 @@ use Zumba\GastonJS\Exception\DeadClient;
|
||||
use Zumba\Mink\Driver\PhantomJSDriver;
|
||||
|
||||
/**
|
||||
* Runs a browser test using PhantomJS.
|
||||
* Runs a browser test using a driver that supports Javascript.
|
||||
*
|
||||
* Base class for testing browser interaction implemented in JavaScript.
|
||||
*/
|
||||
@@ -142,7 +142,7 @@ abstract class JavascriptTestBase extends BrowserTestBase {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function assertSession($name = NULL) {
|
||||
return new JSWebAssert($this->getSession($name), $this->baseUrl);
|
||||
return new WebDriverWebAssert($this->getSession($name), $this->baseUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests;
|
||||
|
||||
/**
|
||||
* Runs a browser test using PhantomJS.
|
||||
*
|
||||
* Base class for testing browser interaction implemented in JavaScript.
|
||||
*/
|
||||
abstract class LegacyJavascriptTestBase extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function assertSession($name = NULL) {
|
||||
// Return a WebAssert that supports status code and header assertions.
|
||||
return new JSWebAssert($this->getSession($name), $this->baseUrl);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests;
|
||||
|
||||
/**
|
||||
* Defines a JSWebAssert with no support for status code and header assertions.
|
||||
*/
|
||||
class WebDriverWebAssert extends JSWebAssert {
|
||||
|
||||
/**
|
||||
* The use of statusCodeEquals() is not available.
|
||||
*
|
||||
* @param int $code
|
||||
* The status code.
|
||||
*/
|
||||
public function statusCodeEquals($code) {
|
||||
@trigger_error('Support for statusCodeEquals is to be dropped from Javascript tests. See https://www.drupal.org/node/2857562.');
|
||||
parent::statusCodeEquals($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of statusCodeNotEquals() is not available.
|
||||
*
|
||||
* @param int $code
|
||||
* The status code.
|
||||
*/
|
||||
public function statusCodeNotEquals($code) {
|
||||
@trigger_error('Support for statusCodeNotEquals is to be dropped from Javascript tests. See https://www.drupal.org/node/2857562.');
|
||||
parent::statusCodeNotEquals($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of responseHeaderEquals() is not available.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the header.
|
||||
* @param string $value
|
||||
* The value to check the header against.
|
||||
*/
|
||||
public function responseHeaderEquals($name, $value) {
|
||||
@trigger_error('Support for responseHeaderEquals is to be dropped from Javascript tests. See https://www.drupal.org/node/2857562.');
|
||||
parent::responseHeaderEquals($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of responseHeaderNotEquals() is not available.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the header.
|
||||
* @param string $value
|
||||
* The value to check the header against.
|
||||
*/
|
||||
public function responseHeaderNotEquals($name, $value) {
|
||||
@trigger_error('Support for responseHeaderNotEquals is to be dropped from Javascript tests. See https://www.drupal.org/node/2857562.');
|
||||
parent::responseHeaderNotEquals($name, $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -98,13 +99,18 @@ 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']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,6 +143,48 @@ 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.
|
||||
*/
|
||||
@@ -181,7 +229,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 +245,7 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
||||
/**
|
||||
* Tests legacy field asserts using textfields.
|
||||
*/
|
||||
public function testLegacyFieldAssertsWithTextfields() {
|
||||
public function testLegacyFieldAssertsForTextfields() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// *** 1. assertNoField().
|
||||
@@ -230,7 +278,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 +367,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 +376,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 testLegacyFieldAssertsForOptions() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// Option field type.
|
||||
@@ -384,7 +435,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 testLegacyFieldAssertsForButton() {
|
||||
$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 +453,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 +468,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 testLegacyFieldAssertsForCheckbox() {
|
||||
$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 +501,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 +518,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,7 +548,7 @@ 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');
|
||||
|
||||
@@ -517,4 +615,22 @@ class BrowserTestBaseTest extends BrowserTestBase {
|
||||
$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.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-4
@@ -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');
|
||||
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
<?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_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.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for image manipulation testing.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the Bartik theme.
|
||||
*
|
||||
* @group bartik
|
||||
*/
|
||||
class BartikTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->assertTrue($this->container->get('theme_installer')->install(['bartik']));
|
||||
$this->container->get('config.factory')
|
||||
->getEditable('system.theme')
|
||||
->set('default', 'bartik')
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Bartik theme always adds its message CSS and Classy's.
|
||||
*
|
||||
* @see bartik.libraries.yml
|
||||
* @see classy.info.yml
|
||||
*/
|
||||
public function testRegressionMissingMessagesCss() {
|
||||
$this->drupalGet('');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseContains('bartik/css/components/messages.css');
|
||||
$this->assertSession()->responseContains('classy/css/components/messages.css');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the classy theme.
|
||||
*
|
||||
* @group classy
|
||||
*/
|
||||
class ClassyTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->assertTrue($this->container->get('theme_installer')->install(['classy']));
|
||||
$this->container->get('config.factory')
|
||||
->getEditable('system.theme')
|
||||
->set('default', 'classy')
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Classy theme always adds its message CSS.
|
||||
*
|
||||
* @see classy.info.yml
|
||||
*/
|
||||
public function testRegressionMissingMessagesCss() {
|
||||
$this->drupalGet('');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseContains('classy/css/components/messages.css');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Update;
|
||||
|
||||
use Behat\Mink\Driver\GoutteDriver;
|
||||
use Behat\Mink\Mink;
|
||||
use Behat\Mink\Selector\SelectorsHandler;
|
||||
use Behat\Mink\Session;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Test\TestRunnerKernel;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\HiddenFieldSelector;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\user\Entity\User;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Provides a base class for writing an update test.
|
||||
*
|
||||
* To write an update test:
|
||||
* - Write the hook_update_N() implementations that you are testing.
|
||||
* - Create one or more database dump files, which will set the database to the
|
||||
* "before updates" state. Normally, these will add some configuration data to
|
||||
* the database, set up some tables/fields, etc.
|
||||
* - Create a class that extends this class.
|
||||
* - In your setUp() method, point the $this->databaseDumpFiles variable to the
|
||||
* database dump files, and then call parent::setUp() to run the base setUp()
|
||||
* method in this class.
|
||||
* - In your test method, call $this->runUpdates() to run the necessary updates,
|
||||
* and then use test assertions to verify that the result is what you expect.
|
||||
* - In order to test both with a "bare" database dump as well as with a
|
||||
* database dump filled with content, extend your update path test class with
|
||||
* a new test class that overrides the bare database dump. Refer to
|
||||
* UpdatePathTestBaseFilledTest for an example.
|
||||
*
|
||||
* @ingroup update_api
|
||||
*
|
||||
* @see hook_update_N()
|
||||
*/
|
||||
abstract class UpdatePathTestBase extends BrowserTestBase {
|
||||
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable after the database is loaded.
|
||||
*/
|
||||
protected static $modules = [];
|
||||
|
||||
/**
|
||||
* The file path(s) to the dumped database(s) to load into the child site.
|
||||
*
|
||||
* The file system/tests/fixtures/update/drupal-8.bare.standard.php.gz is
|
||||
* normally included first -- this sets up the base database from a bare
|
||||
* standard Drupal installation.
|
||||
*
|
||||
* The file system/tests/fixtures/update/drupal-8.filled.standard.php.gz
|
||||
* can also be used in case we want to test with a database filled with
|
||||
* content, and with all core modules enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $databaseDumpFiles = [];
|
||||
|
||||
/**
|
||||
* The install profile used in the database dump file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $installProfile = 'standard';
|
||||
|
||||
/**
|
||||
* Flag that indicates whether the child site has been updated.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $upgradedSite = FALSE;
|
||||
|
||||
/**
|
||||
* Array of errors triggered during the update process.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $upgradeErrors = [];
|
||||
|
||||
/**
|
||||
* Array of modules loaded when the test starts.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $loadedModules = [];
|
||||
|
||||
/**
|
||||
* Flag to indicate whether zlib is installed or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $zlibInstalled = TRUE;
|
||||
|
||||
/**
|
||||
* Flag to indicate whether there are pending updates or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $pendingUpdates = TRUE;
|
||||
|
||||
/**
|
||||
* The update URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $updateUrl;
|
||||
|
||||
/**
|
||||
* Disable strict config schema checking.
|
||||
*
|
||||
* The schema is verified at the end of running the update.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $strictConfigSchema = FALSE;
|
||||
|
||||
/**
|
||||
* Fail the test if there are failed updates.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $checkFailedUpdates = TRUE;
|
||||
|
||||
/**
|
||||
* Constructs an UpdatePathTestCase object.
|
||||
*
|
||||
* @param $test_id
|
||||
* (optional) The ID of the test. Tests with the same id are reported
|
||||
* together.
|
||||
*/
|
||||
public function __construct($test_id = NULL) {
|
||||
parent::__construct($test_id);
|
||||
$this->zlibInstalled = function_exists('gzopen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides WebTestBase::setUp() for update testing.
|
||||
*
|
||||
* The main difference in this method is that rather than performing the
|
||||
* installation via the installer, a database is loaded. Additional work is
|
||||
* then needed to set various things such as the config directories and the
|
||||
* container that would normally be done via the installer.
|
||||
*/
|
||||
protected function setUp() {
|
||||
$request = Request::createFromGlobals();
|
||||
|
||||
// Boot up Drupal into a state where calling the database API is possible.
|
||||
// This is used to initialize the database system, so we can load the dump
|
||||
// files.
|
||||
$autoloader = require $this->root . '/autoload.php';
|
||||
$kernel = TestRunnerKernel::createFromRequest($request, $autoloader);
|
||||
$kernel->loadLegacyIncludes();
|
||||
|
||||
$this->changeDatabasePrefix();
|
||||
$this->runDbTasks();
|
||||
// Allow classes to set database dump files.
|
||||
$this->setDatabaseDumpFiles();
|
||||
|
||||
// We are going to set a missing zlib requirement property for usage
|
||||
// during the performUpgrade() and tearDown() methods. Also set that the
|
||||
// tests failed.
|
||||
if (!$this->zlibInstalled) {
|
||||
parent::setUp();
|
||||
return;
|
||||
}
|
||||
// Set the update url. This must be set here rather than in
|
||||
// self::__construct() or the old URL generator will leak additional test
|
||||
// sites.
|
||||
$this->updateUrl = Url::fromRoute('system.db_update');
|
||||
|
||||
$this->setupBaseUrl();
|
||||
|
||||
// Install Drupal test site.
|
||||
$this->prepareEnvironment();
|
||||
$this->installDrupal();
|
||||
|
||||
// Add the config directories to settings.php.
|
||||
drupal_install_config_directories();
|
||||
|
||||
// Set the container. parent::rebuildAll() would normally do this, but this
|
||||
// not safe to do here, because the database has not been updated yet.
|
||||
$this->container = \Drupal::getContainer();
|
||||
|
||||
$this->replaceUser1();
|
||||
|
||||
require_once \Drupal::root() . '/core/includes/update.inc';
|
||||
|
||||
// Setup Mink.
|
||||
$session = $this->initMink();
|
||||
|
||||
$cookies = $this->extractCookiesFromRequest(\Drupal::request());
|
||||
foreach ($cookies as $cookie_name => $values) {
|
||||
foreach ($values as $value) {
|
||||
$session->setCookie($cookie_name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the browser test output file.
|
||||
$this->initBrowserOutputFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function installDrupal() {
|
||||
$this->initUserSession();
|
||||
$this->prepareSettings();
|
||||
$this->doInstall();
|
||||
$this->initSettings();
|
||||
|
||||
$request = Request::createFromGlobals();
|
||||
$container = $this->initKernel($request);
|
||||
$this->initConfig($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doInstall() {
|
||||
$this->runDbTasks();
|
||||
// Allow classes to set database dump files.
|
||||
$this->setDatabaseDumpFiles();
|
||||
|
||||
// Load the database(s).
|
||||
foreach ($this->databaseDumpFiles as $file) {
|
||||
if (substr($file, -3) == '.gz') {
|
||||
$file = "compress.zlib://$file";
|
||||
}
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initMink() {
|
||||
$driver = $this->getDefaultDriverInstance();
|
||||
|
||||
if ($driver instanceof GoutteDriver) {
|
||||
// Turn off curl timeout. Having a timeout is not a problem in a normal
|
||||
// test running, but it is a problem when debugging. Also, disable SSL
|
||||
// peer verification so that testing under HTTPS always works.
|
||||
/** @var \GuzzleHttp\Client $client */
|
||||
$client = $this->container->get('http_client_factory')->fromOptions([
|
||||
'timeout' => NULL,
|
||||
'verify' => FALSE,
|
||||
]);
|
||||
|
||||
// Inject a Guzzle middleware to generate debug output for every request
|
||||
// performed in the test.
|
||||
$handler_stack = $client->getConfig('handler');
|
||||
$handler_stack->push($this->getResponseLogHandler());
|
||||
|
||||
$driver->getClient()->setClient($client);
|
||||
}
|
||||
|
||||
$selectors_handler = new SelectorsHandler([
|
||||
'hidden_field_selector' => new HiddenFieldSelector()
|
||||
]);
|
||||
$session = new Session($driver, $selectors_handler);
|
||||
$this->mink = new Mink();
|
||||
$this->mink->registerSession('default', $session);
|
||||
$this->mink->setDefaultSessionName('default');
|
||||
$this->registerSessions();
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set database dump files to be used.
|
||||
*/
|
||||
abstract protected function setDatabaseDumpFiles();
|
||||
|
||||
/**
|
||||
* Add settings that are missed since the installer isn't run.
|
||||
*/
|
||||
protected function prepareSettings() {
|
||||
parent::prepareSettings();
|
||||
|
||||
// Remember the profile which was used.
|
||||
$settings['settings']['install_profile'] = (object) [
|
||||
'value' => $this->installProfile,
|
||||
'required' => TRUE,
|
||||
];
|
||||
// Generate a hash salt.
|
||||
$settings['settings']['hash_salt'] = (object) [
|
||||
'value' => Crypt::randomBytesBase64(55),
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Since the installer isn't run, add the database settings here too.
|
||||
$settings['databases']['default'] = (object) [
|
||||
'value' => Database::getConnectionInfo(),
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
$this->writeSettings($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to run pending database updates.
|
||||
*/
|
||||
protected function runUpdates() {
|
||||
if (!$this->zlibInstalled) {
|
||||
$this->fail('Missing zlib requirement for update tests.');
|
||||
return FALSE;
|
||||
}
|
||||
// The site might be broken at the time so logging in using the UI might
|
||||
// not work, so we use the API itself.
|
||||
drupal_rewrite_settings([
|
||||
'settings' => [
|
||||
'update_free_access' => (object) [
|
||||
'value' => TRUE,
|
||||
'required' => TRUE,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->drupalGet($this->updateUrl);
|
||||
$this->clickLink(t('Continue'));
|
||||
|
||||
$this->doSelectionTest();
|
||||
// Run the update hooks.
|
||||
$this->clickLink(t('Apply pending updates'));
|
||||
$this->checkForMetaRefresh();
|
||||
|
||||
// Ensure there are no failed updates.
|
||||
if ($this->checkFailedUpdates) {
|
||||
$this->assertNoRaw('<strong>' . t('Failed:') . '</strong>');
|
||||
|
||||
// Ensure that there are no pending updates.
|
||||
foreach (['update', 'post_update'] as $update_type) {
|
||||
switch ($update_type) {
|
||||
case 'update':
|
||||
$all_updates = update_get_update_list();
|
||||
break;
|
||||
case 'post_update':
|
||||
$all_updates = \Drupal::service('update.post_update_registry')->getPendingUpdateInformation();
|
||||
break;
|
||||
}
|
||||
foreach ($all_updates as $module => $updates) {
|
||||
if (!empty($updates['pending'])) {
|
||||
foreach (array_keys($updates['pending']) as $update_name) {
|
||||
$this->fail("The $update_name() update function from the $module module did not run.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset the static cache of drupal_get_installed_schema_version() so that
|
||||
// more complex update path testing works.
|
||||
drupal_static_reset('drupal_get_installed_schema_version');
|
||||
|
||||
// The config schema can be incorrect while the update functions are being
|
||||
// executed. But once the update has been completed, it needs to be valid
|
||||
// again. Assert the schema of all configuration objects now.
|
||||
$names = $this->container->get('config.storage')->listAll();
|
||||
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
|
||||
$typed_config = $this->container->get('config.typed');
|
||||
$typed_config->clearCachedDefinitions();
|
||||
foreach ($names as $name) {
|
||||
$config = $this->config($name);
|
||||
$this->assertConfigSchema($typed_config, $name, $config->get());
|
||||
}
|
||||
|
||||
// Ensure that the update hooks updated all entity schema.
|
||||
$needs_updates = \Drupal::entityDefinitionUpdateManager()->needsUpdates();
|
||||
$this->assertFalse($needs_updates, 'After all updates ran, entity schema is up to date.');
|
||||
if ($needs_updates) {
|
||||
foreach (\Drupal::entityDefinitionUpdateManager()
|
||||
->getChangeSummary() as $entity_type_id => $summary) {
|
||||
foreach ($summary as $message) {
|
||||
$this->fail($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the install database tasks for the driver used by the test runner.
|
||||
*/
|
||||
protected function runDbTasks() {
|
||||
// Create a minimal container so that t() works.
|
||||
// @see install_begin_request()
|
||||
$container = new ContainerBuilder();
|
||||
$container->setParameter('language.default_values', Language::$defaultValues);
|
||||
$container
|
||||
->register('language.default', 'Drupal\Core\Language\LanguageDefault')
|
||||
->addArgument('%language.default_values%');
|
||||
$container
|
||||
->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
|
||||
->addArgument(new Reference('language.default'));
|
||||
\Drupal::setContainer($container);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/install.inc';
|
||||
$connection = Database::getConnection();
|
||||
$errors = db_installer_object($connection->driver())->runTasks();
|
||||
if (!empty($errors)) {
|
||||
$this->fail('Failed to run installer database tasks: ' . implode(', ', $errors));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace User 1 with the user created here.
|
||||
*/
|
||||
protected function replaceUser1() {
|
||||
/** @var \Drupal\user\UserInterface $account */
|
||||
// @todo: Saving the account before the update is problematic.
|
||||
// https://www.drupal.org/node/2560237
|
||||
$account = User::load(1);
|
||||
$account->setPassword($this->rootUser->pass_raw);
|
||||
$account->setEmail($this->rootUser->getEmail());
|
||||
$account->setUsername($this->rootUser->getUsername());
|
||||
$account->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the selection page.
|
||||
*/
|
||||
protected function doSelectionTest() {
|
||||
// No-op. Tests wishing to do test the selection page or the general
|
||||
// update.php environment before running update.php can override this method
|
||||
// and implement their required tests.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Update;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
|
||||
/**
|
||||
* Tests the update path base class.
|
||||
*
|
||||
* @group Update
|
||||
*/
|
||||
class UpdatePathTestBaseTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['update_test_schema'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../modules/system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the database was properly loaded.
|
||||
*/
|
||||
public function testDatabaseLoaded() {
|
||||
foreach (['user', 'node', 'system', 'update_test_schema'] as $module) {
|
||||
$this->assertEqual(drupal_get_installed_schema_version($module), 8000, SafeMarkup::format('Module @module schema is 8000', ['@module' => $module]));
|
||||
}
|
||||
|
||||
// Ensure that all {router} entries can be unserialized. If they cannot be
|
||||
// unserialized a notice will be thrown by PHP.
|
||||
|
||||
$result = \Drupal::database()->query("SELECT name, route from {router}")->fetchAllKeyed(0, 1);
|
||||
// For the purpose of fetching the notices and displaying more helpful error
|
||||
// messages, let's override the error handler temporarily.
|
||||
set_error_handler(function ($severity, $message, $filename, $lineno) {
|
||||
throw new \ErrorException($message, 0, $severity, $filename, $lineno);
|
||||
});
|
||||
foreach ($result as $route_name => $route) {
|
||||
try {
|
||||
unserialize($route);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$this->fail(sprintf('Error "%s" while unserializing route %s', $e->getMessage(), Html::escape($route_name)));
|
||||
}
|
||||
}
|
||||
restore_error_handler();
|
||||
|
||||
// Before accessing the site we need to run updates first or the site might
|
||||
// be broken.
|
||||
$this->runUpdates();
|
||||
$this->assertEqual(\Drupal::config('system.site')->get('name'), 'Site-Install');
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertText('Site-Install');
|
||||
|
||||
// Ensure that the database tasks have been run during set up. Neither MySQL
|
||||
// nor SQLite make changes that are testable.
|
||||
$database = $this->container->get('database');
|
||||
if ($database->driver() == 'pgsql') {
|
||||
$this->assertEqual('on', $database->query("SHOW standard_conforming_strings")->fetchField());
|
||||
$this->assertEqual('escape', $database->query("SHOW bytea_output")->fetchField());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that updates are properly run.
|
||||
*/
|
||||
public function testUpdateHookN() {
|
||||
// Increment the schema version.
|
||||
\Drupal::state()->set('update_test_schema_version', 8001);
|
||||
$this->runUpdates();
|
||||
|
||||
$select = \Drupal::database()->select('watchdog');
|
||||
$select->orderBy('wid', 'DESC');
|
||||
$select->range(0, 5);
|
||||
$select->fields('watchdog', ['message']);
|
||||
|
||||
$container_cannot_be_saved_messages = array_filter(iterator_to_array($select->execute()), function ($row) {
|
||||
return strpos($row->message, 'Container cannot be saved to cache.') !== FALSE;
|
||||
});
|
||||
$this->assertEqual([], $container_cannot_be_saved_messages);
|
||||
|
||||
// Ensure schema has changed.
|
||||
$this->assertEqual(drupal_get_installed_schema_version('update_test_schema', TRUE), 8001);
|
||||
// Ensure the index was added for column a.
|
||||
$this->assertTrue(db_index_exists('update_test_schema_table', 'test'), 'Version 8001 of the update_test_schema module is installed.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace Drupal\KernelTests;
|
||||
* Translates Simpletest assertion methods to PHPUnit.
|
||||
*
|
||||
* Protected methods are custom. Public static methods override methods of
|
||||
* \PHPUnit_Framework_Assert.
|
||||
* \PHPUnit\Framework\Assert.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0. Use PHPUnit's native
|
||||
* assert methods instead.
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Config;
|
||||
|
||||
use Drupal\Core\Config\Schema\SequenceDataDefinition;
|
||||
use Drupal\Core\Config\Schema\TypedConfigInterface;
|
||||
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
use Drupal\Core\TypedData\Type\IntegerInterface;
|
||||
use Drupal\Core\TypedData\Type\StringInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
|
||||
|
||||
/**
|
||||
* Tests config validation mechanism.
|
||||
*
|
||||
* @group Config
|
||||
*/
|
||||
class TypedConfigTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig('config_test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the Typed Data API is implemented correctly.
|
||||
*/
|
||||
public function testTypedDataAPI() {
|
||||
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
|
||||
$typed_config_manager = \Drupal::service('config.typed');
|
||||
/** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
|
||||
// Test a primitive.
|
||||
$string_data = $typed_config->get('llama');
|
||||
$this->assertInstanceOf(StringInterface::class, $string_data);
|
||||
$this->assertEquals('llama', $string_data->getValue());
|
||||
|
||||
// Test complex data.
|
||||
$mapping = $typed_config->get('cat');
|
||||
/** @var \Drupal\Core\TypedData\ComplexDataInterface $mapping */
|
||||
$this->assertInstanceOf(ComplexDataInterface::class, $mapping);
|
||||
$this->assertInstanceOf(StringInterface::class, $mapping->get('type'));
|
||||
$this->assertEquals('kitten', $mapping->get('type')->getValue());
|
||||
$this->assertInstanceOf(IntegerInterface::class, $mapping->get('count'));
|
||||
$this->assertEquals(2, $mapping->get('count')->getValue());
|
||||
// Verify the item metadata is available.
|
||||
$this->assertInstanceOf(ComplexDataDefinitionInterface::class, $mapping->getDataDefinition());
|
||||
$this->assertArrayHasKey('type', $mapping->getProperties());
|
||||
$this->assertArrayHasKey('count', $mapping->getProperties());
|
||||
|
||||
// Test accessing sequences.
|
||||
$sequence = $typed_config->get('giraffe');
|
||||
/** @var \Drupal\Core\TypedData\ListInterface $sequence */
|
||||
$this->assertInstanceOf(ComplexDataInterface::class, $sequence);
|
||||
$this->assertInstanceOf(StringInterface::class, $sequence->get('hum1'));
|
||||
$this->assertEquals('hum1', $sequence->get('hum1')->getValue());
|
||||
$this->assertEquals('hum2', $sequence->get('hum2')->getValue());
|
||||
$this->assertEquals(2, count($sequence->getIterator()));
|
||||
// Verify the item metadata is available.
|
||||
$this->assertInstanceOf(SequenceDataDefinition::class, $sequence->getDataDefinition());
|
||||
|
||||
// Test accessing typed config objects for simple config and config
|
||||
// entities.
|
||||
$typed_config_manager = \Drupal::service('config.typed');
|
||||
$typed_config = $typed_config_manager->createFromNameAndData('config_test.validation', \Drupal::configFactory()->get('config_test.validation')->get());
|
||||
$this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
|
||||
$this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', '_core'], array_keys($typed_config->getElements()));
|
||||
|
||||
$config_test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
|
||||
'id' => 'asterix',
|
||||
'label' => 'Asterix',
|
||||
'weight' => 11,
|
||||
'style' => 'test_style',
|
||||
]);
|
||||
|
||||
$typed_config = $typed_config_manager->createFromNameAndData($config_test_entity->getConfigDependencyName(), $config_test_entity->toArray());
|
||||
$this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
|
||||
$this->assertEquals(['uuid', 'langcode', 'status', 'dependencies', 'id', 'label', 'weight', 'style', 'size', 'size_value', 'protected_property'], array_keys($typed_config->getElements()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests config validation via the Typed Data API.
|
||||
*/
|
||||
public function testSimpleConfigValidation() {
|
||||
$config = \Drupal::configFactory()->getEditable('config_test.validation');
|
||||
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
|
||||
$typed_config_manager = \Drupal::service('config.typed');
|
||||
/** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
|
||||
$result = $typed_config->validate();
|
||||
$this->assertInstanceOf(ConstraintViolationListInterface::class, $result);
|
||||
$this->assertEmpty($result);
|
||||
|
||||
// Test constraints on primitive types.
|
||||
$config->set('llama', 'elephant');
|
||||
$config->save();
|
||||
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$result = $typed_config->validate();
|
||||
// Its not a valid llama anymore.
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('no valid llama', $result->get(0)->getMessage());
|
||||
|
||||
// Test constraints on mapping.
|
||||
$config->set('llama', 'llama');
|
||||
$config->set('cat.type', 'nyans');
|
||||
$config->save();
|
||||
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$result = $typed_config->validate();
|
||||
$this->assertEmpty($result);
|
||||
|
||||
// Test constrains on nested mapping.
|
||||
$config->set('cat.type', 'miaus');
|
||||
$config->save();
|
||||
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$result = $typed_config->validate();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('no valid cat', $result->get(0)->getMessage());
|
||||
|
||||
// Test constrains on sequences elements.
|
||||
$config->set('cat.type', 'nyans');
|
||||
$config->set('giraffe', ['muh', 'hum2']);
|
||||
$config->save();
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$result = $typed_config->validate();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('Giraffes just hum', $result->get(0)->getMessage());
|
||||
|
||||
// Test constrains on the sequence itself.
|
||||
$config->set('giraffe', ['hum', 'hum2', 'invalid-key' => 'hum']);
|
||||
$config->save();
|
||||
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$result = $typed_config->validate();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('giraffe', $result->get(0)->getPropertyPath());
|
||||
$this->assertEquals('Invalid giraffe key.', $result->get(0)->getMessage());
|
||||
|
||||
// Validates mapping.
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$value = $typed_config->getValue();
|
||||
unset($value['giraffe']);
|
||||
$value['elephant'] = 'foo';
|
||||
$typed_config->setValue($value);
|
||||
$result = $typed_config->validate();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('', $result->get(0)->getPropertyPath());
|
||||
$this->assertEquals('Missing giraffe.', $result->get(0)->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class AttachedAssetsTest extends KernelTestBase {
|
||||
$build['#attached']['library'][] = 'core/unknown';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$this->assertIdentical([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.');
|
||||
$this->assertSame([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,7 +299,8 @@ class AttachedAssetsTest extends KernelTestBase {
|
||||
"-8_2",
|
||||
"-8_3",
|
||||
"-8_4",
|
||||
"-5_1", // The external script.
|
||||
// The external script.
|
||||
"-5_1",
|
||||
"-3_1",
|
||||
"-3_2",
|
||||
"0_1",
|
||||
@@ -435,12 +436,12 @@ class AttachedAssetsTest extends KernelTestBase {
|
||||
$dynamic_library = $library_discovery->getLibraryByName('common_test', 'dynamic_library');
|
||||
$this->assertTrue(is_array($dynamic_library));
|
||||
if ($this->assertTrue(isset($dynamic_library['version']))) {
|
||||
$this->assertIdentical('1.0', $dynamic_library['version']);
|
||||
$this->assertSame('1.0', $dynamic_library['version']);
|
||||
}
|
||||
// Make sure the dynamic library definition could be altered.
|
||||
// @see common_test_library_info_alter()
|
||||
if ($this->assertTrue(isset($dynamic_library['dependencies']))) {
|
||||
$this->assertIdentical(['core/jquery'], $dynamic_library['dependencies']);
|
||||
$this->assertSame(['core/jquery'], $dynamic_library['dependencies']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Batch;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests batch functionality.
|
||||
*
|
||||
* @group Batch
|
||||
*/
|
||||
class BatchKernelTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
require_once $this->root . '/core/includes/batch.inc';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests _batch_needs_update().
|
||||
*/
|
||||
public function testNeedsUpdate() {
|
||||
// Before ever being called, the return value should be FALSE.
|
||||
$this->assertEquals(FALSE, _batch_needs_update());
|
||||
|
||||
// Set the value to TRUE.
|
||||
$this->assertEquals(TRUE, _batch_needs_update(TRUE));
|
||||
// Check that without a parameter TRUE is returned.
|
||||
$this->assertEquals(TRUE, _batch_needs_update());
|
||||
|
||||
// Set the value to FALSE.
|
||||
$this->assertEquals(FALSE, _batch_needs_update(FALSE));
|
||||
$this->assertEquals(FALSE, _batch_needs_update());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class GetFilenameTest extends KernelTestBase {
|
||||
$non_existing_module = uniqid("", TRUE);
|
||||
|
||||
// Set a custom error handler so we can ignore the file not found error.
|
||||
set_error_handler(function($severity, $message, $file, $line) {
|
||||
set_error_handler(function ($severity, $message, $file, $line) {
|
||||
// Skip error handling if this is a "file not found" error.
|
||||
if (strstr($message, 'is missing from the file system:')) {
|
||||
\Drupal::state()->set('get_filename_test_triggered_error', TRUE);
|
||||
|
||||
@@ -20,7 +20,7 @@ class ChainedFastBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
* A new ChainedFastBackend object.
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
$consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin);
|
||||
$consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin, 100);
|
||||
$fast_backend = new PhpBackend($bin, \Drupal::service('cache_tags.invalidator.checksum'));
|
||||
$backend = new ChainedFastBackend($consistent_backend, $fast_backend, $bin);
|
||||
// Explicitly register the cache bin as it can not work through the
|
||||
|
||||
@@ -11,6 +11,13 @@ use Drupal\Core\Cache\DatabaseBackend;
|
||||
*/
|
||||
class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
/**
|
||||
* The max rows to use for test bins.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $maxRows = 100;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
@@ -25,7 +32,7 @@ class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
* A new DatabaseBackend object.
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin);
|
||||
return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin, static::$maxRows);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,12 +47,60 @@ class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
$cid_long = str_repeat('愛€', 500);
|
||||
$cached_value_long = $this->randomMachineName();
|
||||
$backend->set($cid_long, $cached_value_long);
|
||||
$this->assertIdentical($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id.");
|
||||
$this->assertSame($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id.");
|
||||
|
||||
$cid_short = '愛1€';
|
||||
$cached_value_short = $this->randomMachineName();
|
||||
$backend->set($cid_short, $cached_value_short);
|
||||
$this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id.");
|
||||
$this->assertSame($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the row count limiting of cache bin database tables.
|
||||
*/
|
||||
public function testGarbageCollection() {
|
||||
$backend = $this->getCacheBackend();
|
||||
$max_rows = static::$maxRows;
|
||||
|
||||
$this->assertSame(0, (int) $this->getNumRows());
|
||||
|
||||
// Fill to just the limit.
|
||||
for ($i = 0; $i < $max_rows; $i++) {
|
||||
// Ensure that each cache item created happens in a different millisecond,
|
||||
// by waiting 1 ms (1000 microseconds). The garbage collection might
|
||||
// otherwise keep less than exactly 100 records (which is acceptable for
|
||||
// real-world cases, but not for this test).
|
||||
usleep(1000);
|
||||
$backend->set("test$i", $i);
|
||||
}
|
||||
$this->assertSame($max_rows, $this->getNumRows());
|
||||
|
||||
// Garbage collection has no effect.
|
||||
$backend->garbageCollection();
|
||||
$this->assertSame($max_rows, $this->getNumRows());
|
||||
|
||||
// Go one row beyond the limit.
|
||||
$backend->set('test' . ($max_rows + 1), $max_rows + 1);
|
||||
$this->assertSame($max_rows + 1, $this->getNumRows());
|
||||
|
||||
// Garbage collection removes one row: the oldest.
|
||||
$backend->garbageCollection();
|
||||
$this->assertSame($max_rows, $this->getNumRows());
|
||||
$this->assertFalse($backend->get('test0'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows in the test cache bin database table.
|
||||
*
|
||||
* @return int
|
||||
* The number of rows in the test cache bin database table.
|
||||
*/
|
||||
protected function getNumRows() {
|
||||
$table = 'cache_' . $this->testBin;
|
||||
$connection = $this->container->get('database');
|
||||
$query = $connection->select($table);
|
||||
$query->addExpression('COUNT(cid)', 'cid');
|
||||
return (int) $query->execute()->fetchField();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
* @return \Drupal\Core\Cache\CacheBackendInterface
|
||||
* Cache backend to test.
|
||||
*/
|
||||
protected abstract function createCacheBackend($bin);
|
||||
abstract protected function createCacheBackend($bin);
|
||||
|
||||
/**
|
||||
* Allows specific implementation to change the environment before a test run.
|
||||
@@ -130,22 +130,22 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
public function testSetGet() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
$this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
|
||||
$this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
|
||||
$with_backslash = ['foo' => '\Drupal\foo\Bar'];
|
||||
$backend->set('test1', $with_backslash);
|
||||
$cached = $backend->get('test1');
|
||||
$this->assert(is_object($cached), "Backend returned an object for cache id test1.");
|
||||
$this->assertIdentical($with_backslash, $cached->data);
|
||||
$this->assertSame($with_backslash, $cached->data);
|
||||
$this->assertTrue($cached->valid, 'Item is marked as valid.');
|
||||
// We need to round because microtime may be rounded up in the backend.
|
||||
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
|
||||
|
||||
$this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
|
||||
$this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
|
||||
$backend->set('test2', ['value' => 3], REQUEST_TIME + 3);
|
||||
$cached = $backend->get('test2');
|
||||
$this->assert(is_object($cached), "Backend returned an object for cache id test2.");
|
||||
$this->assertIdentical(['value' => 3], $cached->data);
|
||||
$this->assertSame(['value' => 3], $cached->data);
|
||||
$this->assertTrue($cached->valid, 'Item is marked as valid.');
|
||||
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($cached->expire, REQUEST_TIME + 3, 'Expire time is correct.');
|
||||
@@ -158,22 +158,22 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($cached->expire, REQUEST_TIME - 3, 'Expire time is correct.');
|
||||
|
||||
$this->assertIdentical(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4.");
|
||||
$this->assertSame(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4.");
|
||||
$with_eof = ['foo' => "\nEOF\ndata"];
|
||||
$backend->set('test4', $with_eof);
|
||||
$cached = $backend->get('test4');
|
||||
$this->assert(is_object($cached), "Backend returned an object for cache id test4.");
|
||||
$this->assertIdentical($with_eof, $cached->data);
|
||||
$this->assertSame($with_eof, $cached->data);
|
||||
$this->assertTrue($cached->valid, 'Item is marked as valid.');
|
||||
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
|
||||
|
||||
$this->assertIdentical(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5.");
|
||||
$this->assertSame(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5.");
|
||||
$with_eof_and_semicolon = ['foo' => "\nEOF;\ndata"];
|
||||
$backend->set('test5', $with_eof_and_semicolon);
|
||||
$cached = $backend->get('test5');
|
||||
$this->assert(is_object($cached), "Backend returned an object for cache id test5.");
|
||||
$this->assertIdentical($with_eof_and_semicolon, $cached->data);
|
||||
$this->assertSame($with_eof_and_semicolon, $cached->data);
|
||||
$this->assertTrue($cached->valid, 'Item is marked as valid.');
|
||||
$this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
|
||||
@@ -182,7 +182,7 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
$backend->set('test6', $with_variable);
|
||||
$cached = $backend->get('test6');
|
||||
$this->assert(is_object($cached), "Backend returned an object for cache id test6.");
|
||||
$this->assertIdentical($with_variable, $cached->data);
|
||||
$this->assertSame($with_variable, $cached->data);
|
||||
|
||||
// Make sure that a cached object is not affected by changing the original.
|
||||
$data = new \stdClass();
|
||||
@@ -229,26 +229,26 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
public function testDelete() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
$this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
|
||||
$this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1.");
|
||||
$backend->set('test1', 7);
|
||||
$this->assert(is_object($backend->get('test1')), "Backend returned an object for cache id test1.");
|
||||
|
||||
$this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
|
||||
$this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2.");
|
||||
$backend->set('test2', 3);
|
||||
$this->assert(is_object($backend->get('test2')), "Backend returned an object for cache id %cid.");
|
||||
|
||||
$backend->delete('test1');
|
||||
$this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1 after deletion.");
|
||||
$this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1 after deletion.");
|
||||
|
||||
$this->assert(is_object($backend->get('test2')), "Backend still has an object for cache id test2.");
|
||||
|
||||
$backend->delete('test2');
|
||||
$this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion.");
|
||||
$this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion.");
|
||||
|
||||
$long_cid = str_repeat('a', 300);
|
||||
$backend->set($long_cid, 'test');
|
||||
$backend->delete($long_cid);
|
||||
$this->assertIdentical(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion.");
|
||||
$this->assertSame(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,7 +275,7 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
foreach ($variables as $cid => $value) {
|
||||
$object = $backend->get($cid);
|
||||
$this->assert(is_object($object), sprintf("Backend returned an object for cache id %s.", $cid));
|
||||
$this->assertIdentical($value, $object->data, sprintf("Data of cached id %s kept is identical in type and value", $cid));
|
||||
$this->assertSame($value, $object->data, sprintf("Data of cached id %s kept is identical in type and value", $cid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,9 +300,11 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
$reference = [
|
||||
'test3',
|
||||
'test7',
|
||||
'test21', // Cid does not exist.
|
||||
// Cid does not exist.
|
||||
'test21',
|
||||
'test6',
|
||||
'test19', // Cid does not exist until added before second getMultiple().
|
||||
// Cid does not exist until added before second getMultiple().
|
||||
'test19',
|
||||
'test2',
|
||||
];
|
||||
|
||||
@@ -440,20 +442,23 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
$backend->set('test7', 17);
|
||||
|
||||
$backend->delete('test1');
|
||||
$backend->delete('test23'); // Nonexistent key should not cause an error.
|
||||
// Nonexistent key should not cause an error.
|
||||
$backend->delete('test23');
|
||||
$backend->deleteMultiple([
|
||||
'test3',
|
||||
'test5',
|
||||
'test7',
|
||||
'test19', // Nonexistent key should not cause an error.
|
||||
'test21', // Nonexistent key should not cause an error.
|
||||
// Nonexistent key should not cause an error.
|
||||
'test19',
|
||||
// Nonexistent key should not cause an error.
|
||||
'test21',
|
||||
]);
|
||||
|
||||
// Test if expected keys have been deleted.
|
||||
$this->assertIdentical(FALSE, $backend->get('test1'), "Cache id test1 deleted.");
|
||||
$this->assertIdentical(FALSE, $backend->get('test3'), "Cache id test3 deleted.");
|
||||
$this->assertIdentical(FALSE, $backend->get('test5'), "Cache id test5 deleted.");
|
||||
$this->assertIdentical(FALSE, $backend->get('test7'), "Cache id test7 deleted.");
|
||||
$this->assertSame(FALSE, $backend->get('test1'), "Cache id test1 deleted.");
|
||||
$this->assertSame(FALSE, $backend->get('test3'), "Cache id test3 deleted.");
|
||||
$this->assertSame(FALSE, $backend->get('test5'), "Cache id test5 deleted.");
|
||||
$this->assertSame(FALSE, $backend->get('test7'), "Cache id test7 deleted.");
|
||||
|
||||
// Test if expected keys exist.
|
||||
$this->assertNotIdentical(FALSE, $backend->get('test2'), "Cache id test2 exists.");
|
||||
@@ -461,8 +466,8 @@ abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
$this->assertNotIdentical(FALSE, $backend->get('test6'), "Cache id test6 exists.");
|
||||
|
||||
// Test if that expected keys do not exist.
|
||||
$this->assertIdentical(FALSE, $backend->get('test19'), "Cache id test19 does not exist.");
|
||||
$this->assertIdentical(FALSE, $backend->get('test21'), "Cache id test21 does not exist.");
|
||||
$this->assertSame(FALSE, $backend->get('test19'), "Cache id test19 does not exist.");
|
||||
$this->assertSame(FALSE, $backend->get('test21'), "Cache id test21 does not exist.");
|
||||
|
||||
// Calling deleteMultiple() with an empty array should not cause an error.
|
||||
$this->assertFalse($backend->deleteMultiple([]));
|
||||
|
||||
@@ -70,7 +70,8 @@ class DbDumpTest extends KernelTestBase {
|
||||
parent::register($container);
|
||||
$container->register('cache_factory', 'Drupal\Core\Cache\DatabaseBackendFactory')
|
||||
->addArgument(new Reference('database'))
|
||||
->addArgument(new Reference('cache_tags.invalidator.checksum'));
|
||||
->addArgument(new Reference('cache_tags.invalidator.checksum'))
|
||||
->addArgument(new Reference('settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,8 +206,8 @@ class DbDumpTest extends KernelTestBase {
|
||||
$this->assertTrue(Database::getConnection()
|
||||
->schema()
|
||||
->tableExists($table), SafeMarkup::format('Table @table created by the database script.', ['@table' => $table]));
|
||||
$this->assertIdentical($this->originalTableSchemas[$table], $this->getTableSchema($table), SafeMarkup::format('The schema for @table was properly restored.', ['@table' => $table]));
|
||||
$this->assertIdentical($this->originalTableIndexes[$table], $this->getTableIndexes($table), SafeMarkup::format('The indexes for @table were properly restored.', ['@table' => $table]));
|
||||
$this->assertSame($this->originalTableSchemas[$table], $this->getTableSchema($table), SafeMarkup::format('The schema for @table was properly restored.', ['@table' => $table]));
|
||||
$this->assertSame($this->originalTableIndexes[$table], $this->getTableIndexes($table), SafeMarkup::format('The indexes for @table were properly restored.', ['@table' => $table]));
|
||||
}
|
||||
|
||||
// Ensure the test config has been replaced.
|
||||
|
||||
@@ -31,10 +31,14 @@ class SizeTest extends KernelTestBase {
|
||||
];
|
||||
$this->roundedTestCases = [
|
||||
'2 bytes' => 2,
|
||||
'1 MB' => ($kb * $kb) - 1, // rounded to 1 MB (not 1000 or 1024 kilobyte!)
|
||||
round(3623651 / ($this->exactTestCases['1 MB']), 2) . ' MB' => 3623651, // megabytes
|
||||
round(67234178751368124 / ($this->exactTestCases['1 PB']), 2) . ' PB' => 67234178751368124, // petabytes
|
||||
round(235346823821125814962843827 / ($this->exactTestCases['1 YB']), 2) . ' YB' => 235346823821125814962843827, // yottabytes
|
||||
// Rounded to 1 MB (not 1000 or 1024 kilobyte!).
|
||||
'1 MB' => ($kb * $kb) - 1,
|
||||
// Megabytes.
|
||||
round(3623651 / ($this->exactTestCases['1 MB']), 2) . ' MB' => 3623651,
|
||||
// Petabytes.
|
||||
round(67234178751368124 / ($this->exactTestCases['1 PB']), 2) . ' PB' => 67234178751368124,
|
||||
// Yottabytes.
|
||||
round(235346823821125814962843827 / ($this->exactTestCases['1 YB']), 2) . ' YB' => 235346823821125814962843827,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -278,12 +278,12 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
$this->assertIdentical($storage->read($name), $data);
|
||||
|
||||
// Test that schema type enforcement can be overridden by trusting the data.
|
||||
$this->assertIdentical(99, $config->get('int'));
|
||||
$this->assertSame(99, $config->get('int'));
|
||||
$config->set('int', '99')->save(TRUE);
|
||||
$this->assertIdentical('99', $config->get('int'));
|
||||
$this->assertSame('99', $config->get('int'));
|
||||
// Test that re-saving without testing the data enforces the schema type.
|
||||
$config->save();
|
||||
$this->assertIdentical($data, $config->get());
|
||||
$this->assertSame($data, $config->get());
|
||||
|
||||
// Test that setting an unsupported type for a config object with a schema
|
||||
// fails.
|
||||
|
||||
@@ -161,11 +161,13 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$missing_dependencies = $config_manager->findMissingContentDependencies();
|
||||
$this->assertEqual([], $missing_dependencies);
|
||||
|
||||
$expected = [$entity_test->uuid() => [
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => $entity_test->bundle(),
|
||||
'uuid' => $entity_test->uuid(),
|
||||
]];
|
||||
$expected = [
|
||||
$entity_test->uuid() => [
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => $entity_test->bundle(),
|
||||
'uuid' => $entity_test->uuid(),
|
||||
],
|
||||
];
|
||||
// Delete the content entity so that is it now missing.
|
||||
$entity_test->delete();
|
||||
$missing_dependencies = $config_manager->findMissingContentDependencies();
|
||||
@@ -328,7 +330,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
|
||||
$called = \Drupal::state()->get('config_test.on_dependency_removal_called', []);
|
||||
$this->assertFalse(in_array($entity_3->id(), $called), 'ConfigEntityInterface::onDependencyRemoval() is not called for entity 3.');
|
||||
$this->assertIdentical([$entity_1->id(), $entity_4->id(), $entity_2->id()], $called, 'The most dependent entites have ConfigEntityInterface::onDependencyRemoval() called first.');
|
||||
$this->assertSame([$entity_1->id(), $entity_4->id(), $entity_2->id()], $called, 'The most dependent entites have ConfigEntityInterface::onDependencyRemoval() called first.');
|
||||
|
||||
// Perform a module rebuild so we can know where the node module is located
|
||||
// and uninstall it.
|
||||
|
||||
@@ -57,7 +57,7 @@ class ConfigEntityStaticCacheTest extends KernelTestBase {
|
||||
// config_entity_static_cache_test_config_test_load() sets _loadStamp to a
|
||||
// random string. If they match, it means $entity_2 was retrieved from the
|
||||
// static cache rather than going through a separate load sequence.
|
||||
$this->assertIdentical($entity_1->_loadStamp, $entity_2->_loadStamp);
|
||||
$this->assertSame($entity_1->_loadStamp, $entity_2->_loadStamp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,4 +51,18 @@ class ConfigEntityStorageTest extends KernelTestBase {
|
||||
$this->assertIdentical($entity->toArray(), $original_properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the hasData() method for config entity storage.
|
||||
*
|
||||
* @covers \Drupal\Core\Config\Entity\ConfigEntityStorage::hasData
|
||||
*/
|
||||
public function testHasData() {
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('config_test');
|
||||
$this->assertFalse($storage->hasData());
|
||||
|
||||
// Add a test config entity and check again.
|
||||
$storage->create(['id' => $this->randomMachineName()])->save();
|
||||
$this->assertTrue($storage->hasData());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
// Compare UUIDs as the objects are not identical since
|
||||
// $entity->enforceIsNew is FALSE and $entity_loaded_by_uuid->enforceIsNew
|
||||
// is NULL.
|
||||
$this->assertIdentical($entity->uuid(), $entity_loaded_by_uuid->uuid());
|
||||
$this->assertSame($entity->uuid(), $entity_loaded_by_uuid->uuid());
|
||||
|
||||
$entities = $this->storage->loadByProperties();
|
||||
$this->assertEqual(count($entities), 3, 'Three entities are loaded when no properties are specified.');
|
||||
@@ -100,12 +100,12 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
'style' => 999
|
||||
]);
|
||||
$entity->save();
|
||||
$this->assertIdentical('999', $entity->style);
|
||||
$this->assertSame('999', $entity->style);
|
||||
$entity->style = 999;
|
||||
$entity->trustData()->save();
|
||||
$this->assertIdentical(999, $entity->style);
|
||||
$this->assertSame(999, $entity->style);
|
||||
$entity->save();
|
||||
$this->assertIdentical('999', $entity->style);
|
||||
$this->assertSame('999', $entity->style);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -210,22 +210,22 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
$config_parsed = $filestorage->read($name);
|
||||
|
||||
$key = 'numeric keys';
|
||||
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
|
||||
$this->assertSame($config_data[$key], $config_parsed[$key]);
|
||||
|
||||
$key = 'nested keys';
|
||||
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
|
||||
$this->assertSame($config_data[$key], $config_parsed[$key]);
|
||||
|
||||
$key = 'HTML';
|
||||
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
|
||||
$this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
|
||||
|
||||
$key = 'UTF-8';
|
||||
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
|
||||
$this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
|
||||
|
||||
$key = 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ';
|
||||
$this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
|
||||
$this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]);
|
||||
|
||||
$key = 'invalid xml';
|
||||
$this->assertIdentical($config_data[$key], $config_parsed[$key]);
|
||||
$this->assertSame($config_data[$key], $config_parsed[$key]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class ConfigImportRecreateTest extends KernelTestBase {
|
||||
$this->assertEqual(5, count($creates), 'There are 5 configuration items to create.');
|
||||
$this->assertEqual(5, count($deletes), 'There are 5 configuration items to delete.');
|
||||
$this->assertEqual(0, count($this->configImporter->getUnprocessedConfiguration('update')), 'There are no configuration items to update.');
|
||||
$this->assertIdentical($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.');
|
||||
$this->assertSame($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.');
|
||||
|
||||
$this->configImporter->import();
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
'node.type.' . $content_type->id() . '::config_test.dynamic.' . $test_entity_id,
|
||||
];
|
||||
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
|
||||
$this->assertIdentical($expected, $renames);
|
||||
$this->assertSame($expected, $renames);
|
||||
|
||||
// Try to import the configuration. We expect an exception to be thrown
|
||||
// because the staged entity is of a different type.
|
||||
@@ -138,7 +138,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
'config_test.old::config_test.new'
|
||||
];
|
||||
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
|
||||
$this->assertIdentical($expected, $renames);
|
||||
$this->assertSame($expected, $renames);
|
||||
|
||||
// Try to import the configuration. We expect an exception to be thrown
|
||||
// because the rename is for simple configuration.
|
||||
|
||||
@@ -351,7 +351,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
$name_deletee,
|
||||
$name_other,
|
||||
];
|
||||
$this->assertIdentical($expected, $updates);
|
||||
$this->assertSame($expected, $updates);
|
||||
|
||||
// Import.
|
||||
$this->configImporter->import();
|
||||
|
||||
@@ -146,7 +146,7 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
|
||||
$collection_storage = $active_storage->createCollection('entity');
|
||||
$data = $collection_storage->read('config_test.dynamic.dotted.default');
|
||||
$this->assertIdentical(['label' => 'entity'], $data);
|
||||
$this->assertSame(['label' => 'entity'], $data);
|
||||
|
||||
// Test that the config manager uninstalls configuration from collections
|
||||
// as expected.
|
||||
@@ -185,7 +185,7 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
$data = $active_storage->read($name);
|
||||
$this->assertTrue(isset($data['uuid']));
|
||||
$data = $collection_storage->read($name);
|
||||
$this->assertIdentical(['label' => 'entity'], $data);
|
||||
$this->assertSame(['label' => 'entity'], $data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +227,7 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
$this->assertTrue($entity, 'The config_test.dynamic.other_module_test_with_dependency configuration has been created during install.');
|
||||
// Ensure that dependencies can be added during module installation by
|
||||
// hooks.
|
||||
$this->assertIdentical('config_install_dependency_test', $entity->getDependencies()['module'][0]);
|
||||
$this->assertSame('config_install_dependency_test', $entity->getDependencies()['module'][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,22 +40,23 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
*/
|
||||
public function testSchemaMapping() {
|
||||
// Nonexistent configuration key will have Undefined as metadata.
|
||||
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
|
||||
$this->assertSame(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key');
|
||||
$expected = [];
|
||||
$expected['label'] = 'Undefined';
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
|
||||
|
||||
// Configuration file without schema will return Undefined as well.
|
||||
$this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema'));
|
||||
$this->assertSame(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema'));
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema');
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.');
|
||||
|
||||
// Configuration file with only some schema.
|
||||
$this->assertIdentical(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'));
|
||||
$this->assertSame(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'));
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema');
|
||||
$expected = [];
|
||||
$expected['label'] = 'Schema test data';
|
||||
@@ -67,6 +68,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['mapping']['testlist'] = ['label' => 'Test list'];
|
||||
$expected['type'] = 'config_schema_test.someschema';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.');
|
||||
|
||||
// Check type detection on elements with undefined types.
|
||||
@@ -77,6 +79,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
|
||||
$definition = $config->get('testlist')->getDataDefinition()->toArray();
|
||||
$expected = [];
|
||||
@@ -84,6 +87,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
|
||||
$definition = $config->get('testnoschema')->getDataDefinition()->toArray();
|
||||
$expected = [];
|
||||
@@ -91,6 +95,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected, 'Automatic type detected for an undefined integer is undefined.');
|
||||
|
||||
// Simple case, straight metadata.
|
||||
@@ -109,6 +114,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['mapping']['_core']['type'] = '_core_config_info';
|
||||
$expected['type'] = 'system.maintenance';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
|
||||
|
||||
// Mixed schema with ignore elements.
|
||||
@@ -139,6 +145,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
'type' => 'integer',
|
||||
];
|
||||
$expected['type'] = 'config_schema_test.ignore';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
|
||||
$this->assertEqual($definition, $expected);
|
||||
|
||||
@@ -149,6 +156,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['label'] = 'Irrelevant';
|
||||
$expected['class'] = Ignore::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$this->assertEqual($definition, $expected);
|
||||
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition()->toArray();
|
||||
$expected['label'] = 'Indescribable';
|
||||
@@ -160,8 +168,9 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['label'] = 'Image style';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$expected['mapping']['name']['type'] = 'string';
|
||||
$expected['mapping']['uuid']['type'] = 'string';
|
||||
$expected['mapping']['uuid']['type'] = 'uuid';
|
||||
$expected['mapping']['uuid']['label'] = 'UUID';
|
||||
$expected['mapping']['langcode']['type'] = 'string';
|
||||
$expected['mapping']['langcode']['label'] = 'Language code';
|
||||
@@ -177,7 +186,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['mapping']['effects']['sequence']['mapping']['id']['type'] = 'string';
|
||||
$expected['mapping']['effects']['sequence']['mapping']['data']['type'] = 'image.effect.[%parent.id]';
|
||||
$expected['mapping']['effects']['sequence']['mapping']['weight']['type'] = 'integer';
|
||||
$expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'string';
|
||||
$expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'uuid';
|
||||
$expected['mapping']['third_party_settings']['type'] = 'sequence';
|
||||
$expected['mapping']['third_party_settings']['label'] = 'Third party settings';
|
||||
$expected['mapping']['third_party_settings']['sequence']['type'] = '[%parent.%parent.%type].third_party.[%key]';
|
||||
@@ -193,6 +202,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['label'] = 'Image scale';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$expected['mapping']['width']['type'] = 'integer';
|
||||
$expected['mapping']['width']['label'] = 'Width';
|
||||
$expected['mapping']['height']['type'] = 'integer';
|
||||
@@ -220,6 +230,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['label'] = 'Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$expected['mapping'] = [
|
||||
'integer' => ['type' => 'integer'],
|
||||
'string' => ['type' => 'string'],
|
||||
@@ -241,6 +252,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['mapping']['testdescription']['label'] = 'Description';
|
||||
$expected['type'] = 'config_schema_test.someschema.somemodule.*.*';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_one.subsection');
|
||||
|
||||
@@ -263,6 +275,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
'label' => 'Test item nested one level',
|
||||
'class' => StringData::class,
|
||||
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
|
||||
'unwrap_for_canonical_representation' => TRUE,
|
||||
];
|
||||
$this->assertEqual($definition, $expected);
|
||||
|
||||
@@ -274,6 +287,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
'label' => 'Test item nested two levels',
|
||||
'class' => StringData::class,
|
||||
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
|
||||
'unwrap_for_canonical_representation' => TRUE,
|
||||
];
|
||||
$this->assertEqual($definition, $expected);
|
||||
|
||||
@@ -285,6 +299,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
'label' => 'Test item nested three levels',
|
||||
'class' => StringData::class,
|
||||
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
|
||||
'unwrap_for_canonical_representation' => TRUE,
|
||||
];
|
||||
$this->assertEqual($definition, $expected);
|
||||
}
|
||||
@@ -321,7 +336,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$effect = $effects->get($uuid)->getElements();
|
||||
$this->assertTrue(!$effect['data']->isEmpty() && $effect['id']->getValue() == 'image_scale', 'Got data for the image scale effect from metadata.');
|
||||
$this->assertTrue($effect['data']->get('width') instanceof IntegerInterface, 'Got the right type for the scale effect width.');
|
||||
$this->assertEqual($effect['data']->get('width')->getValue(), 480, 'Got the right value for the scale effect width.' );
|
||||
$this->assertEqual($effect['data']->get('width')->getValue(), 480, 'Got the right value for the scale effect width.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,6 +410,76 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$this->assertIdentical($installed_data, $original_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests configuration sequence sorting using schemas.
|
||||
*/
|
||||
public function testConfigSaveWithSequenceSorting() {
|
||||
$data = [
|
||||
'keyed_sort' => [
|
||||
'b' => '1',
|
||||
'a' => '2',
|
||||
],
|
||||
'no_sort' => [
|
||||
'b' => '2',
|
||||
'a' => '1',
|
||||
],
|
||||
];
|
||||
// Save config which has a schema that enforces sorting.
|
||||
$this->config('config_schema_test.schema_sequence_sort')
|
||||
->setData($data)
|
||||
->save();
|
||||
$this->assertSame(['a' => '2', 'b' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('keyed_sort'));
|
||||
$this->assertSame(['b' => '2', 'a' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
|
||||
|
||||
$data = [
|
||||
'value_sort' => ['b', 'a'],
|
||||
'no_sort' => ['b', 'a'],
|
||||
];
|
||||
// Save config which has a schema that enforces sorting.
|
||||
$this->config('config_schema_test.schema_sequence_sort')
|
||||
->setData($data)
|
||||
->save();
|
||||
|
||||
$this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort'));
|
||||
$this->assertSame(['b', 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
|
||||
|
||||
// Value sort does not preserve keys - this is intentional.
|
||||
$data = [
|
||||
'value_sort' => [1 => 'b', 2 => 'a'],
|
||||
'no_sort' => [1 => 'b', 2 => 'a'],
|
||||
];
|
||||
// Save config which has a schema that enforces sorting.
|
||||
$this->config('config_schema_test.schema_sequence_sort')
|
||||
->setData($data)
|
||||
->save();
|
||||
|
||||
$this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort'));
|
||||
$this->assertSame([1 => 'b', 2 => 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
|
||||
|
||||
// Test sorts do not destroy complex values.
|
||||
$data = [
|
||||
'complex_sort_value' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']],
|
||||
'complex_sort_key' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']],
|
||||
];
|
||||
$this->config('config_schema_test.schema_sequence_sort')
|
||||
->setData($data)
|
||||
->save();
|
||||
$this->assertSame([['foo' => 'a', 'bar' => 'a'], ['foo' => 'b', 'bar' => 'b']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value'));
|
||||
$this->assertSame(['a' => ['foo' => '2', 'bar' => '2'], 'b' => ['foo' => '1', 'bar' => '1']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key'));
|
||||
|
||||
// Swap the previous test scenario around.
|
||||
$data = [
|
||||
'complex_sort_value' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']],
|
||||
'complex_sort_key' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']],
|
||||
];
|
||||
$this->config('config_schema_test.schema_sequence_sort')
|
||||
->setData($data)
|
||||
->save();
|
||||
$this->assertSame([['foo' => '1', 'bar' => '1'], ['foo' => '2', 'bar' => '2']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value'));
|
||||
$this->assertSame([['foo' => 'b', 'bar' => 'b'], ['foo' => 'a', 'bar' => 'a']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests fallback to a greedy wildcard.
|
||||
*/
|
||||
@@ -405,6 +490,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$expected['label'] = 'Schema wildcard fallback test';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['unwrap_for_canonical_representation'] = TRUE;
|
||||
$expected['mapping']['langcode']['type'] = 'string';
|
||||
$expected['mapping']['langcode']['label'] = 'Language code';
|
||||
$expected['mapping']['_core']['type'] = '_core_config_info';
|
||||
@@ -418,8 +504,8 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
|
||||
$definition2 = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something.something');
|
||||
// This should be the schema of config_schema_test.wildcard_fallback.* as
|
||||
//well.
|
||||
$this->assertIdentical($definition, $definition2);
|
||||
// well.
|
||||
$this->assertSame($definition, $definition2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Drupal\KernelTests\Core\Config;
|
||||
use Drupal\Core\Config\Schema\SchemaCheckTrait;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests the functionality of SchemaCheckTrait.
|
||||
*
|
||||
|
||||
@@ -189,7 +189,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$data = ['foo' => 'bar'];
|
||||
$result = $this->storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($data, $this->storage->read($name));
|
||||
$this->assertSame($data, $this->storage->read($name));
|
||||
|
||||
// Create configuration in a new collection.
|
||||
$new_storage = $this->storage->createCollection('collection.sub.new');
|
||||
@@ -197,13 +197,13 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$this->assertEqual([], $new_storage->listAll());
|
||||
$new_storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($data, $new_storage->read($name));
|
||||
$this->assertSame($data, $new_storage->read($name));
|
||||
$this->assertEqual([$name], $new_storage->listAll());
|
||||
$this->assertTrue($new_storage->exists($name));
|
||||
$new_data = ['foo' => 'baz'];
|
||||
$new_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $new_storage->read($name));
|
||||
$this->assertSame($new_data, $new_storage->read($name));
|
||||
|
||||
// Create configuration in another collection.
|
||||
$another_storage = $this->storage->createCollection('collection.sub.another');
|
||||
@@ -211,7 +211,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$this->assertEqual([], $another_storage->listAll());
|
||||
$another_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $another_storage->read($name));
|
||||
$this->assertSame($new_data, $another_storage->read($name));
|
||||
$this->assertEqual([$name], $another_storage->listAll());
|
||||
$this->assertTrue($another_storage->exists($name));
|
||||
|
||||
@@ -219,18 +219,18 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$alt_storage = $this->storage->createCollection('alternate');
|
||||
$alt_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $alt_storage->read($name));
|
||||
$this->assertSame($new_data, $alt_storage->read($name));
|
||||
|
||||
// Switch back to the collection-less mode and check the data still exists
|
||||
// add has not been touched.
|
||||
$this->assertIdentical($data, $this->storage->read($name));
|
||||
$this->assertSame($data, $this->storage->read($name));
|
||||
|
||||
// Check that the getAllCollectionNames() method works.
|
||||
$this->assertIdentical(['alternate', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$this->assertSame(['alternate', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
|
||||
// Check that the collections are removed when they are empty.
|
||||
$alt_storage->delete($name);
|
||||
$this->assertIdentical(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
|
||||
// Create configuration in collection called 'collection'. This ensures that
|
||||
// FileStorage's collection storage works regardless of its use of
|
||||
@@ -240,19 +240,19 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$this->assertEqual([], $parent_storage->listAll());
|
||||
$parent_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $parent_storage->read($name));
|
||||
$this->assertSame($new_data, $parent_storage->read($name));
|
||||
$this->assertEqual([$name], $parent_storage->listAll());
|
||||
$this->assertTrue($parent_storage->exists($name));
|
||||
$this->assertIdentical(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$this->assertSame(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$parent_storage->deleteAll();
|
||||
$this->assertIdentical(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
|
||||
// Check that the having an empty collection-less storage does not break
|
||||
// anything. Before deleting check that the previous delete did not affect
|
||||
// data in another collection.
|
||||
$this->assertIdentical($data, $this->storage->read($name));
|
||||
$this->assertSame($data, $this->storage->read($name));
|
||||
$this->storage->delete($name);
|
||||
$this->assertIdentical(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
}
|
||||
|
||||
abstract protected function read($name);
|
||||
|
||||
@@ -68,8 +68,8 @@ class FileStorageTest extends ConfigStorageTestBase {
|
||||
// @todo https://www.drupal.org/node/2666954 FileStorage::listAll() is
|
||||
// case-sensitive. However, \Drupal\Core\Config\DatabaseStorage::listAll()
|
||||
// is case-insensitive.
|
||||
$this->assertIdentical(['system.performance'], $this->storage->listAll('system'), 'The FileStorage::listAll() with prefix works.');
|
||||
$this->assertIdentical([], $this->storage->listAll('System'), 'The FileStorage::listAll() is case sensitive.');
|
||||
$this->assertSame(['system.performance'], $this->storage->listAll('system'), 'The FileStorage::listAll() with prefix works.');
|
||||
$this->assertSame([], $this->storage->listAll('System'), 'The FileStorage::listAll() is case sensitive.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,14 +16,15 @@ class CaseSensitivityTest extends DatabaseTestBase {
|
||||
|
||||
db_insert('test')
|
||||
->fields([
|
||||
'name' => 'john', // <- A record already exists with name 'John'.
|
||||
// A record already exists with name 'John'.
|
||||
'name' => 'john',
|
||||
'age' => 2,
|
||||
'job' => 'Baby',
|
||||
])
|
||||
->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'john'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '2', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
@@ -32,18 +32,18 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
// Try to open those targets another time, that should return the same objects.
|
||||
$db1b = Database::getConnection('default', 'default');
|
||||
$db2b = Database::getConnection('replica', 'default');
|
||||
$this->assertIdentical($db1, $db1b, 'A second call to getConnection() returns the same object.');
|
||||
$this->assertIdentical($db2, $db2b, 'A second call to getConnection() returns the same object.');
|
||||
$this->assertSame($db1, $db1b, 'A second call to getConnection() returns the same object.');
|
||||
$this->assertSame($db2, $db2b, 'A second call to getConnection() returns the same object.');
|
||||
|
||||
// Try to open an unknown target.
|
||||
$unknown_target = $this->randomMachineName();
|
||||
$db3 = Database::getConnection($unknown_target, 'default');
|
||||
$this->assertNotNull($db3, 'Opening an unknown target returns a real connection object.');
|
||||
$this->assertIdentical($db1, $db3, 'An unknown target opens the default connection.');
|
||||
$this->assertSame($db1, $db3, 'An unknown target opens the default connection.');
|
||||
|
||||
// Try to open that unknown target another time, that should return the same object.
|
||||
$db3b = Database::getConnection($unknown_target, 'default');
|
||||
$this->assertIdentical($db3, $db3b, 'A second call to getConnection() returns the same object.');
|
||||
$this->assertSame($db3, $db3b, 'A second call to getConnection() returns the same object.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
$db1 = Database::getConnection('default', 'default');
|
||||
$db2 = Database::getConnection('replica', 'default');
|
||||
|
||||
$this->assertIdentical($db1, $db2, 'Both targets refer to the same connection.');
|
||||
$this->assertSame($db1, $db2, 'Both targets refer to the same connection.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +131,7 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
try {
|
||||
$db->query('SELECT * FROM {test}; SELECT * FROM {test_people}',
|
||||
[],
|
||||
[ 'allow_delimiter_in_query' => TRUE ]
|
||||
['allow_delimiter_in_query' => TRUE]
|
||||
);
|
||||
$this->fail('No PDO exception thrown for multiple statements.');
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class InsertDefaultsTest extends DatabaseTestBase {
|
||||
}
|
||||
|
||||
$num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical($num_records_before, $num_records_after, 'Do nothing as no fields are specified.');
|
||||
$this->assertSame($num_records_before, $num_records_after, 'Do nothing as no fields are specified.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ class InsertTest extends DatabaseTestBase {
|
||||
$query->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Yoko'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '29', 'Can retrieve after inserting.');
|
||||
}
|
||||
@@ -61,7 +61,7 @@ class InsertTest extends DatabaseTestBase {
|
||||
$query->execute();
|
||||
|
||||
$num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
|
||||
$this->assertSame($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
|
||||
@@ -84,7 +84,8 @@ class InsertTest extends DatabaseTestBase {
|
||||
]);
|
||||
// Check how many records are queued for insertion.
|
||||
$this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
|
||||
$query->execute(); // This should run the insert, but leave the fields intact.
|
||||
// This should run the insert, but leave the fields intact.
|
||||
$query->execute();
|
||||
|
||||
// We should be able to specify values in any order if named.
|
||||
$query->values([
|
||||
@@ -103,7 +104,7 @@ class InsertTest extends DatabaseTestBase {
|
||||
$query->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$this->assertSame((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
|
||||
|
||||
@@ -24,7 +24,8 @@ class InvalidDataTest extends DatabaseTestBase {
|
||||
'age' => 63,
|
||||
'job' => 'Singer',
|
||||
])->values([
|
||||
'name' => 'John', // <-- Duplicate value on unique field.
|
||||
// Duplicate value on unique field.
|
||||
'name' => 'John',
|
||||
'age' => 17,
|
||||
'job' => 'Consultant',
|
||||
])
|
||||
@@ -66,4 +67,81 @@ class InvalidDataTest extends DatabaseTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests inserting with invalid data from a select query.
|
||||
*/
|
||||
public function testInsertDuplicateDataFromSelect() {
|
||||
// Insert multiple records in 'test_people' where one has bad data
|
||||
// (duplicate key). A 'Meredith' record has already been inserted
|
||||
// in ::setUp.
|
||||
db_insert('test_people')
|
||||
->fields(['name', 'age', 'job'])
|
||||
->values([
|
||||
'name' => 'Elvis',
|
||||
'age' => 63,
|
||||
'job' => 'Singer',
|
||||
])->values([
|
||||
// Duplicate value on unique field 'name' for later INSERT in 'test'
|
||||
// table.
|
||||
'name' => 'John',
|
||||
'age' => 17,
|
||||
'job' => 'Consultant',
|
||||
])
|
||||
->values([
|
||||
'name' => 'Frank',
|
||||
'age' => 75,
|
||||
'job' => 'Bass',
|
||||
])
|
||||
->execute();
|
||||
|
||||
try {
|
||||
// Define the subselect query. Add ORDER BY to ensure we have consistent
|
||||
// order in results. Will return:
|
||||
// 0 => [name] => Elvis, [age] => 63, [job] => Singer
|
||||
// 1 => [name] => Frank, [age] => 75, [job] => Bass
|
||||
// 2 => [name] => John, [age] => 17, [job] => Consultant
|
||||
// 3 => [name] => Meredith, [age] => 30, [job] => Speaker
|
||||
// Records 0 and 1 should pass, record 2 should lead to integrity
|
||||
// constraint violation.
|
||||
$query = db_select('test_people', 'tp')
|
||||
->fields('tp', ['name', 'age', 'job'])
|
||||
->orderBy('name');
|
||||
|
||||
// Try inserting from the subselect.
|
||||
db_insert('test')
|
||||
->from($query)
|
||||
->execute();
|
||||
|
||||
$this->fail('Insert succeeded when it should not have.');
|
||||
}
|
||||
catch (IntegrityConstraintViolationException $e) {
|
||||
// Check if the second record was inserted.
|
||||
$name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 75])->fetchField();
|
||||
|
||||
if ($name == 'Frank') {
|
||||
if (!Database::getConnection()->supportsTransactions()) {
|
||||
// This is an expected fail.
|
||||
// Database engines that don't support transactions can leave partial
|
||||
// inserts in place when an error occurs. This is the case for MySQL
|
||||
// when running on a MyISAM table.
|
||||
$this->pass("The whole transaction has not been rolled-back when a duplicate key insert occurs, this is expected because the database doesn't support transactions");
|
||||
}
|
||||
else {
|
||||
$this->fail('The whole transaction is rolled back when a duplicate key insert occurs.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->pass('The whole transaction is rolled back when a duplicate key insert occurs.');
|
||||
}
|
||||
|
||||
// Ensure the values for records 2 and 3 were not inserted.
|
||||
$record = db_select('test')
|
||||
->fields('test', ['name', 'age'])
|
||||
->condition('age', [17, 30], 'IN')
|
||||
->execute()->fetchObject();
|
||||
|
||||
$this->assertFalse($record, 'The rest of the insert aborted as expected.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class LoggingTest extends DatabaseTestBase {
|
||||
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
|
||||
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica']);//->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica'])->fetchCol();
|
||||
|
||||
$queries1 = Database::getLog('testing1');
|
||||
|
||||
|
||||
@@ -30,31 +30,31 @@ class RegressionTest extends DatabaseTestBase {
|
||||
])->execute();
|
||||
|
||||
$from_database = db_query('SELECT job FROM {test} WHERE job = :job', [':job' => $job])->fetchField();
|
||||
$this->assertIdentical($job, $from_database, 'The database handles UTF-8 characters cleanly.');
|
||||
$this->assertSame($job, $from_database, 'The database handles UTF-8 characters cleanly.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the db_table_exists() function.
|
||||
*/
|
||||
public function testDBTableExists() {
|
||||
$this->assertIdentical(TRUE, db_table_exists('test'), 'Returns true for existent table.');
|
||||
$this->assertIdentical(FALSE, db_table_exists('nosuchtable'), 'Returns false for nonexistent table.');
|
||||
$this->assertSame(TRUE, db_table_exists('test'), 'Returns true for existent table.');
|
||||
$this->assertSame(FALSE, db_table_exists('nosuchtable'), 'Returns false for nonexistent table.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the db_field_exists() function.
|
||||
*/
|
||||
public function testDBFieldExists() {
|
||||
$this->assertIdentical(TRUE, db_field_exists('test', 'name'), 'Returns true for existent column.');
|
||||
$this->assertIdentical(FALSE, db_field_exists('test', 'nosuchcolumn'), 'Returns false for nonexistent column.');
|
||||
$this->assertSame(TRUE, db_field_exists('test', 'name'), 'Returns true for existent column.');
|
||||
$this->assertSame(FALSE, db_field_exists('test', 'nosuchcolumn'), 'Returns false for nonexistent column.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the db_index_exists() function.
|
||||
*/
|
||||
public function testDBIndexExists() {
|
||||
$this->assertIdentical(TRUE, db_index_exists('test', 'ages'), 'Returns true for existent index.');
|
||||
$this->assertIdentical(FALSE, db_index_exists('test', 'nosuchindex'), 'Returns false for nonexistent index.');
|
||||
$this->assertSame(TRUE, db_index_exists('test', 'ages'), 'Returns true for existent index.');
|
||||
$this->assertSame(FALSE, db_index_exists('test', 'nosuchindex'), 'Returns false for nonexistent index.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Drupal\KernelTests\Core\Database;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Database\RowCountException;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
@@ -312,7 +313,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'job');
|
||||
$query->condition('name', 'Paul');
|
||||
$query->condition(db_or()->condition('age', 26)->condition('age', 27));
|
||||
$query->condition((new Condition('OR'))->condition('age', 26)->condition('age', 27));
|
||||
|
||||
$job = $query->execute()->fetchField();
|
||||
$this->assertEqual($job, 'Songwriter', 'Correct data retrieved.');
|
||||
@@ -395,7 +396,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
public function testJoinConditionObject() {
|
||||
// Same test as testDefaultJoin, but with a Condition object.
|
||||
$query = db_select('test_task', 't');
|
||||
$join_cond = db_and()->where('t.pid = p.id');
|
||||
$join_cond = (new Condition('AND'))->where('t.pid = p.id');
|
||||
$people_alias = $query->join('test', 'p', $join_cond);
|
||||
$name_field = $query->addField($people_alias, 'name', 'name');
|
||||
$query->addField('t', 'task', 'task');
|
||||
@@ -418,7 +419,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
// Test a condition object that creates placeholders.
|
||||
$t1_name = 'John';
|
||||
$t2_name = 'George';
|
||||
$join_cond = db_and()
|
||||
$join_cond = (new Condition('AND'))
|
||||
->condition('t1.name', $t1_name)
|
||||
->condition('t2.name', $t2_name);
|
||||
$query = db_select('test', 't1');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Database;
|
||||
|
||||
use Drupal\Core\Database\InvalidQueryException;
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
@@ -496,8 +497,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
];
|
||||
$test_groups[] = [
|
||||
'regex' => '#Singer',
|
||||
'expected' => [
|
||||
],
|
||||
'expected' => [],
|
||||
];
|
||||
|
||||
foreach ($test_groups as $test_group) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\KernelTests\Core\Database;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
|
||||
/**
|
||||
* Tests the Update query builder, complex queries.
|
||||
*
|
||||
@@ -15,7 +17,7 @@ class UpdateComplexTest extends DatabaseTestBase {
|
||||
public function testOrConditionUpdate() {
|
||||
$update = db_update('test')
|
||||
->fields(['job' => 'Musician'])
|
||||
->condition(db_or()
|
||||
->condition((new Condition('OR'))
|
||||
->condition('name', 'John')
|
||||
->condition('name', 'Paul')
|
||||
);
|
||||
|
||||
@@ -137,7 +137,7 @@ class DrupalKernelTest extends KernelTestBase {
|
||||
// Check that the container itself is not among the persist IDs because it
|
||||
// does not make sense to persist the container itself.
|
||||
$persist_ids = $container->getParameter('persist_ids');
|
||||
$this->assertIdentical(FALSE, array_search('service_container', $persist_ids));
|
||||
$this->assertSame(FALSE, array_search('service_container', $persist_ids));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,6 +184,11 @@ class DrupalKernelTest extends KernelTestBase {
|
||||
$pass = TRUE;
|
||||
}
|
||||
$this->assertTrue($pass, 'Throws LogicException if DrupalKernel::setSitePath() is called after boot');
|
||||
|
||||
// Ensure no LogicException if DrupalKernel::setSitePath() is called with
|
||||
// identical path after boot.
|
||||
$path = $kernel->getSitePath();
|
||||
$kernel->setSitePath($path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -572,6 +572,33 @@ class ConfigEntityQueryTest extends KernelTestBase {
|
||||
->condition('*.level1.level2', 41)
|
||||
->execute();
|
||||
$this->assertResults([]);
|
||||
// Make sure that "IS NULL" and "IS NOT NULL" work correctly with
|
||||
// array-valued fields/keys.
|
||||
$all = ['1', '2', '3', '4', '5'];
|
||||
$this->queryResults = $this->factory->get('config_query_test')
|
||||
->exists('array.level1.level2')
|
||||
->execute();
|
||||
$this->assertResults($all);
|
||||
$this->queryResults = $this->factory->get('config_query_test')
|
||||
->exists('array.level1')
|
||||
->execute();
|
||||
$this->assertResults($all);
|
||||
$this->queryResults = $this->factory->get('config_query_test')
|
||||
->exists('array')
|
||||
->execute();
|
||||
$this->assertResults($all);
|
||||
$this->queryResults = $this->factory->get('config_query_test')
|
||||
->notExists('array.level1.level2')
|
||||
->execute();
|
||||
$this->assertResults([]);
|
||||
$this->queryResults = $this->factory->get('config_query_test')
|
||||
->notExists('array.level1')
|
||||
->execute();
|
||||
$this->assertResults([]);
|
||||
$this->queryResults = $this->factory->get('config_query_test')
|
||||
->notExists('array')
|
||||
->execute();
|
||||
$this->assertResults([]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,7 +74,7 @@ class ContentEntityChangedTest extends EntityKernelTestBase {
|
||||
|
||||
// We can't assert equality here because the created time is set to the
|
||||
// request time, while instances of ChangedTestItem use the current
|
||||
// timestamp every time. Therefor we check if the changed timestamp is
|
||||
// timestamp every time. Therefore we check if the changed timestamp is
|
||||
// between the created time and now.
|
||||
$this->assertTrue(
|
||||
($entity->getChangedTime() >= $entity->get('created')->value) &&
|
||||
|
||||
@@ -30,10 +30,10 @@ class ContentEntityNullStorageTest extends KernelTestBase {
|
||||
* @see \Drupal\Core\Entity\Query\Null\Query
|
||||
*/
|
||||
public function testEntityQuery() {
|
||||
$this->assertIdentical(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.');
|
||||
$this->assertIdentical([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.');
|
||||
$this->assertIdentical([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.');
|
||||
$this->assertIdentical([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array');
|
||||
$this->assertSame(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.');
|
||||
$this->assertSame([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.');
|
||||
$this->assertSame([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.');
|
||||
$this->assertSame([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array');
|
||||
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -179,12 +179,12 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) { }
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) { }
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Tests valid entries in the EntityAutocomplete Form API element.
|
||||
@@ -353,7 +353,7 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
|
||||
public function testEntityAutocompleteIdInput() {
|
||||
/** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */
|
||||
$form_builder = $this->container->get('form_builder');
|
||||
//$form = $form_builder->getForm($this);
|
||||
// $form = $form_builder->getForm($this);
|
||||
$form_state = (new FormState())
|
||||
->setMethod('GET')
|
||||
->setValues([
|
||||
|
||||
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Entity\EntityTypeEvents;
|
||||
use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldException;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionEvents;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\entity_test_update\Entity\EntityTestUpdate;
|
||||
@@ -114,7 +115,7 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
|
||||
t('The %field_name field needs to be installed.', ['%field_name' => 'Revision ID']),
|
||||
],
|
||||
];
|
||||
$this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.');
|
||||
$this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
|
||||
|
||||
// Run the update and ensure the revision table is created.
|
||||
$this->entityDefinitionUpdateManager->applyUpdates();
|
||||
@@ -776,6 +777,11 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
|
||||
// of a NOT NULL constraint.
|
||||
$this->makeBaseFieldEntityKey();
|
||||
|
||||
// Field storage CRUD operations use the last installed entity type
|
||||
// definition so we need to update it before doing any other field storage
|
||||
// updates.
|
||||
$this->entityDefinitionUpdateManager->updateEntityType($this->state->get('entity_test_update.entity_type'));
|
||||
|
||||
// Try to apply the update and verify they fail since we have a NULL value.
|
||||
$message = 'An error occurs when trying to enabling NOT NULL constraints with NULL data.';
|
||||
try {
|
||||
@@ -817,4 +823,119 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
|
||||
$this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'Entity and field schema data are correctly detected.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a base field with initial values.
|
||||
*/
|
||||
public function testInitialValue() {
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
|
||||
$db_schema = $this->database->schema();
|
||||
|
||||
// Create two entities before adding the base field.
|
||||
/** @var \Drupal\entity_test\Entity\EntityTestUpdate $entity */
|
||||
$storage->create()->save();
|
||||
$storage->create()->save();
|
||||
|
||||
// Add a base field with an initial value.
|
||||
$this->addBaseField();
|
||||
$storage_definition = BaseFieldDefinition::create('string')
|
||||
->setLabel(t('A new base field'))
|
||||
->setInitialValue('test value');
|
||||
|
||||
$this->assertFalse($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' does not exist before applying the update.");
|
||||
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
|
||||
$this->assertTrue($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table.");
|
||||
|
||||
// Check that the initial values have been applied.
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
|
||||
$entities = $storage->loadMultiple();
|
||||
$this->assertEquals('test value', $entities[1]->get('new_base_field')->value);
|
||||
$this->assertEquals('test value', $entities[2]->get('new_base_field')->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a base field with initial values inherited from another field.
|
||||
*/
|
||||
public function testInitialValueFromField() {
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
|
||||
$db_schema = $this->database->schema();
|
||||
|
||||
// Create two entities before adding the base field.
|
||||
/** @var \Drupal\entity_test\Entity\EntityTestUpdate $entity */
|
||||
$storage->create(['name' => 'First entity'])->save();
|
||||
$storage->create(['name' => 'Second entity'])->save();
|
||||
|
||||
// Add a base field with an initial value inherited from another field.
|
||||
$this->addBaseField();
|
||||
$storage_definition = BaseFieldDefinition::create('string')
|
||||
->setLabel(t('A new base field'))
|
||||
->setInitialValueFromField('name');
|
||||
|
||||
$this->assertFalse($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' does not exist before applying the update.");
|
||||
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
|
||||
$this->assertTrue($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table.");
|
||||
|
||||
// Check that the initial values have been applied.
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
|
||||
$entities = $storage->loadMultiple();
|
||||
$this->assertEquals('First entity', $entities[1]->get('new_base_field')->value);
|
||||
$this->assertEquals('Second entity', $entities[2]->get('new_base_field')->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the error handling when using initial values from another field.
|
||||
*/
|
||||
public function testInitialValueFromFieldErrorHandling() {
|
||||
// Check that setting invalid values for 'initial value from field' doesn't
|
||||
// work.
|
||||
try {
|
||||
$this->addBaseField();
|
||||
$storage_definition = BaseFieldDefinition::create('string')
|
||||
->setLabel(t('A new base field'))
|
||||
->setInitialValueFromField('field_that_does_not_exist');
|
||||
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
|
||||
$this->fail('Using a non-existent field as initial value does not work.');
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->assertEquals('Illegal initial value definition on new_base_field: The field field_that_does_not_exist does not exist.', $e->getMessage());
|
||||
$this->pass('Using a non-existent field as initial value does not work.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->addBaseField();
|
||||
$storage_definition = BaseFieldDefinition::create('integer')
|
||||
->setLabel(t('A new base field'))
|
||||
->setInitialValueFromField('name');
|
||||
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition);
|
||||
$this->fail('Using a field of a different type as initial value does not work.');
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->assertEquals('Illegal initial value definition on new_base_field: The field types do not match.', $e->getMessage());
|
||||
$this->pass('Using a field of a different type as initial value does not work.');
|
||||
}
|
||||
|
||||
try {
|
||||
// Add a base field that will not be stored in the shared tables.
|
||||
$initial_field = BaseFieldDefinition::create('string')
|
||||
->setName('initial_field')
|
||||
->setLabel(t('An initial field'))
|
||||
->setCardinality(2);
|
||||
$this->state->set('entity_test_update.additional_base_field_definitions', ['initial_field' => $initial_field]);
|
||||
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('initial_field', 'entity_test_update', 'entity_test', $initial_field);
|
||||
|
||||
// Now add the base field which will try to use the previously added field
|
||||
// as the source of its initial values.
|
||||
$new_base_field = BaseFieldDefinition::create('string')
|
||||
->setName('new_base_field')
|
||||
->setLabel(t('A new base field'))
|
||||
->setInitialValueFromField('initial_field');
|
||||
$this->state->set('entity_test_update.additional_base_field_definitions', ['initial_field' => $initial_field, 'new_base_field' => $new_base_field]);
|
||||
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $new_base_field);
|
||||
$this->fail('Using a field that is not stored in the shared tables as initial value does not work.');
|
||||
}
|
||||
catch (FieldException $e) {
|
||||
$this->assertEquals('Illegal initial value definition on new_base_field: Both fields have to be stored in the shared entity tables.', $e->getMessage());
|
||||
$this->pass('Using a field that is not stored in the shared tables as initial value does not work.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use Drupal\Core\TypedData\DataDefinitionInterface;
|
||||
use Drupal\Core\TypedData\ListInterface;
|
||||
use Drupal\Core\TypedData\Type\StringInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\entity_test\Entity\EntityTestComputedField;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
@@ -471,30 +472,30 @@ class EntityFieldTest extends EntityKernelTestBase {
|
||||
|
||||
// Make sure provided contextual information is right.
|
||||
$entity_adapter = $entity->getTypedData();
|
||||
$this->assertIdentical($entity_adapter->getRoot(), $entity_adapter, 'Entity is root object.');
|
||||
$this->assertSame($entity_adapter->getRoot(), $entity_adapter, 'Entity is root object.');
|
||||
$this->assertEqual($entity_adapter->getPropertyPath(), '');
|
||||
$this->assertEqual($entity_adapter->getName(), '');
|
||||
$this->assertEqual($entity_adapter->getParent(), NULL);
|
||||
|
||||
$field = $entity->user_id;
|
||||
$this->assertIdentical($field->getRoot()->getValue(), $entity, 'Entity is root object.');
|
||||
$this->assertIdentical($field->getEntity(), $entity, 'getEntity() returns the entity.');
|
||||
$this->assertSame($field->getRoot()->getValue(), $entity, 'Entity is root object.');
|
||||
$this->assertSame($field->getEntity(), $entity, 'getEntity() returns the entity.');
|
||||
$this->assertEqual($field->getPropertyPath(), 'user_id');
|
||||
$this->assertEqual($field->getName(), 'user_id');
|
||||
$this->assertIdentical($field->getParent()->getValue(), $entity, 'Parent object matches.');
|
||||
$this->assertSame($field->getParent()->getValue(), $entity, 'Parent object matches.');
|
||||
|
||||
$field_item = $field[0];
|
||||
$this->assertIdentical($field_item->getRoot()->getValue(), $entity, 'Entity is root object.');
|
||||
$this->assertIdentical($field_item->getEntity(), $entity, 'getEntity() returns the entity.');
|
||||
$this->assertSame($field_item->getRoot()->getValue(), $entity, 'Entity is root object.');
|
||||
$this->assertSame($field_item->getEntity(), $entity, 'getEntity() returns the entity.');
|
||||
$this->assertEqual($field_item->getPropertyPath(), 'user_id.0');
|
||||
$this->assertEqual($field_item->getName(), '0');
|
||||
$this->assertIdentical($field_item->getParent(), $field, 'Parent object matches.');
|
||||
$this->assertSame($field_item->getParent(), $field, 'Parent object matches.');
|
||||
|
||||
$item_value = $field_item->get('entity');
|
||||
$this->assertIdentical($item_value->getRoot()->getValue(), $entity, 'Entity is root object.');
|
||||
$this->assertSame($item_value->getRoot()->getValue(), $entity, 'Entity is root object.');
|
||||
$this->assertEqual($item_value->getPropertyPath(), 'user_id.0.entity');
|
||||
$this->assertEqual($item_value->getName(), 'entity');
|
||||
$this->assertIdentical($item_value->getParent(), $field_item, 'Parent object matches.');
|
||||
$this->assertSame($item_value->getParent(), $field_item, 'Parent object matches.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -737,6 +738,16 @@ class EntityFieldTest extends EntityKernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test computed fields.
|
||||
*/
|
||||
public function testComputedFields() {
|
||||
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
|
||||
|
||||
$entity = EntityTestComputedField::create([]);
|
||||
$this->assertEquals($entity->computed_string_field->value, 'foo computed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the computed properties tests for the given entity type.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests loading entities by UUID.
|
||||
*
|
||||
* @group entity
|
||||
*/
|
||||
class EntityLoadByUuidTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['entity_test', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('entity_test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that ::loadEntityByUuid() doesn't apply access checking.
|
||||
*/
|
||||
public function testLoadEntityByUuidAccessChecking() {
|
||||
\Drupal::state()->set('entity_test_query_access', TRUE);
|
||||
// Create two test entities.
|
||||
$entity_0 = EntityTest::create([
|
||||
'type' => 'entity_test',
|
||||
'name' => 'published entity'
|
||||
]);
|
||||
$entity_0->save();
|
||||
$entity_1 = EntityTest::create([
|
||||
'type' => 'entity_test',
|
||||
'name' => 'unpublished entity'
|
||||
]);
|
||||
$entity_1->save();
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityRepositoryInterface $repository */
|
||||
$repository = \Drupal::service('entity.repository');
|
||||
$this->assertEquals($entity_0->id(), $repository->loadEntityByUuid('entity_test', $entity_0->uuid())->id());
|
||||
$this->assertEquals($entity_1->id(), $repository->loadEntityByUuid('entity_test', $entity_1->uuid())->id());
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMulRev;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestMulRev;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
@@ -19,6 +20,8 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*/
|
||||
class EntityQueryTest extends EntityKernelTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
@@ -94,23 +97,27 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
}
|
||||
// Each unit is a list of field name, langcode and a column-value array.
|
||||
$units[] = [$figures, 'en', [
|
||||
'color' => 'red',
|
||||
'shape' => 'triangle',
|
||||
]];
|
||||
'color' => 'red',
|
||||
'shape' => 'triangle',
|
||||
],
|
||||
];
|
||||
$units[] = [$figures, 'en', [
|
||||
'color' => 'blue',
|
||||
'shape' => 'circle',
|
||||
]];
|
||||
'color' => 'blue',
|
||||
'shape' => 'circle',
|
||||
],
|
||||
];
|
||||
// To make it easier to test sorting, the greetings get formats according
|
||||
// to their langcode.
|
||||
$units[] = [$greetings, 'tr', [
|
||||
'value' => 'merhaba',
|
||||
'format' => 'format-tr'
|
||||
]];
|
||||
'value' => 'merhaba',
|
||||
'format' => 'format-tr',
|
||||
],
|
||||
];
|
||||
$units[] = [$greetings, 'pl', [
|
||||
'value' => 'siema',
|
||||
'format' => 'format-pl'
|
||||
]];
|
||||
'value' => 'siema',
|
||||
'format' => 'format-pl',
|
||||
],
|
||||
];
|
||||
// Make these languages available to the greetings field.
|
||||
ConfigurableLanguage::createFromLangcode('tr')->save();
|
||||
ConfigurableLanguage::createFromLangcode('pl')->save();
|
||||
@@ -311,6 +318,16 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
// Now we get everything.
|
||||
$assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15'];
|
||||
$this->assertIdentical($results, $assert);
|
||||
|
||||
// Check that a query on the latest revisions without any condition returns
|
||||
// the correct results.
|
||||
$results = $this->factory->get('entity_test_mulrev')
|
||||
->latestRevision()
|
||||
->sort('id')
|
||||
->sort('revision_id')
|
||||
->execute();
|
||||
$expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'];
|
||||
$this->assertSame($expected, $results);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -866,7 +883,8 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
'description' => [
|
||||
'value' => $this->randomString(),
|
||||
'format' => 'format1',
|
||||
]]);
|
||||
],
|
||||
]);
|
||||
$term1->save();
|
||||
|
||||
$term2 = Term::create([
|
||||
@@ -875,7 +893,8 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
'description' => [
|
||||
'value' => $this->randomString(),
|
||||
'format' => 'format2',
|
||||
]]);
|
||||
],
|
||||
]);
|
||||
$term2->save();
|
||||
|
||||
$ids = \Drupal::entityQuery('taxonomy_term')
|
||||
@@ -887,9 +906,9 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test forward-revisions.
|
||||
* Test pending revisions.
|
||||
*/
|
||||
public function testForwardRevisions() {
|
||||
public function testPendingRevisions() {
|
||||
// Ensure entity 14 is returned.
|
||||
$result = \Drupal::entityQuery('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
@@ -914,7 +933,7 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
->execute();
|
||||
$this->assertEqual(count($result), 1);
|
||||
|
||||
// Verify that field conditions on the default and forward revision are
|
||||
// Verify that field conditions on the default and pending revision are
|
||||
// work as expected.
|
||||
$result = \Drupal::entityQuery('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
@@ -927,6 +946,54 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
->allRevisions()
|
||||
->execute();
|
||||
$this->assertEqual($result, [16 => '14']);
|
||||
|
||||
// Add another pending revision on the same entity and repeat the checks.
|
||||
$entity->setNewRevision(TRUE);
|
||||
$entity->isDefaultRevision(FALSE);
|
||||
$entity->{$this->figures}->setValue([
|
||||
'color' => 'red',
|
||||
'shape' => 'square'
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
// A non-revisioned entity query should still return entity 14.
|
||||
$result = $this->factory->get('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
->execute();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertSame([14 => '14'], $result);
|
||||
|
||||
// Now check an entity query on the latest revision.
|
||||
$result = $this->factory->get('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
->latestRevision()
|
||||
->execute();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertSame([17 => '14'], $result);
|
||||
|
||||
// Verify that field conditions on the default and pending revision still
|
||||
// work as expected.
|
||||
$result = $this->factory->get('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
->condition("$this->figures.color", $current_values[0]['color'])
|
||||
->execute();
|
||||
$this->assertSame([14 => '14'], $result);
|
||||
|
||||
// Now there are two revisions with same value for the figure color.
|
||||
$result = $this->factory->get('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
->condition("$this->figures.color", 'red')
|
||||
->allRevisions()
|
||||
->execute();
|
||||
$this->assertSame([16 => '14', 17 => '14'], $result);
|
||||
|
||||
// Check that querying for the latest revision returns the correct one.
|
||||
$result = $this->factory->get('entity_test_mulrev')
|
||||
->condition('id', [14], 'IN')
|
||||
->condition("$this->figures.color", 'red')
|
||||
->latestRevision()
|
||||
->execute();
|
||||
$this->assertSame([17 => '14'], $result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -946,4 +1013,54 @@ class EntityQueryTest extends EntityKernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that EntityQuery works when querying the same entity from two fields.
|
||||
*/
|
||||
public function testWithTwoEntityReferenceFieldsToSameEntityType() {
|
||||
// Create two entity reference fields referring 'entity_test' entities.
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'ref1', $this->randomMachineName(), 'entity_test');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'ref2', $this->randomMachineName(), 'entity_test');
|
||||
|
||||
// Create two entities to be referred.
|
||||
$ref1 = EntityTest::create(['type' => 'entity_test']);
|
||||
$ref1->save();
|
||||
$ref2 = EntityTest::create(['type' => 'entity_test']);
|
||||
$ref2->save();
|
||||
|
||||
// Create a main entity referring the previous created entities.
|
||||
$entity = EntityTest::create([
|
||||
'type' => 'entity_test',
|
||||
'ref1' => $ref1->id(),
|
||||
'ref2' => $ref2->id(),
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
// Check that works when referring with "{$field_name}".
|
||||
$result = $this->factory->get('entity_test')
|
||||
->condition('type', 'entity_test')
|
||||
->condition('ref1', $ref1->id())
|
||||
->condition('ref2', $ref2->id())
|
||||
->execute();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals($entity->id(), reset($result));
|
||||
|
||||
// Check that works when referring with "{$field_name}.target_id".
|
||||
$result = $this->factory->get('entity_test')
|
||||
->condition('type', 'entity_test')
|
||||
->condition('ref1.target_id', $ref1->id())
|
||||
->condition('ref2.target_id', $ref2->id())
|
||||
->execute();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals($entity->id(), reset($result));
|
||||
|
||||
// Check that works when referring with "{$field_name}.entity.id".
|
||||
$result = $this->factory->get('entity_test')
|
||||
->condition('type', 'entity_test')
|
||||
->condition('ref1.entity.id', $ref1->id())
|
||||
->condition('ref2.entity.id', $ref2->id())
|
||||
->execute();
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals($entity->id(), reset($result));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -247,24 +247,24 @@ class EntityReferenceFieldTest extends EntityKernelTestBase {
|
||||
->create(['name' => $this->randomString()]);
|
||||
|
||||
// Test content entity autocreation.
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->set('user_id', $user);
|
||||
});
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->set('user_id', $user, FALSE);
|
||||
});
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->user_id->setValue($user);
|
||||
});
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->user_id[0]->get('entity')->setValue($user);
|
||||
});
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->user_id->setValue(['entity' => $user, 'target_id' => NULL]);
|
||||
});
|
||||
try {
|
||||
$message = 'Setting both the entity and an invalid target_id property fails.';
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$user->save();
|
||||
$entity->user_id->setValue(['entity' => $user, 'target_id' => $this->generateRandomEntityId()]);
|
||||
});
|
||||
@@ -273,32 +273,32 @@ class EntityReferenceFieldTest extends EntityKernelTestBase {
|
||||
catch (\InvalidArgumentException $e) {
|
||||
$this->pass($message);
|
||||
}
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->user_id = $user;
|
||||
});
|
||||
$this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) {
|
||||
$this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) {
|
||||
$entity->user_id->entity = $user;
|
||||
});
|
||||
|
||||
// Test config entity autocreation.
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->set('user_role', $role);
|
||||
});
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->set('user_role', $role, FALSE);
|
||||
});
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->user_role->setValue($role);
|
||||
});
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->user_role[0]->get('entity')->setValue($role);
|
||||
});
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->user_role->setValue(['entity' => $role, 'target_id' => NULL]);
|
||||
});
|
||||
try {
|
||||
$message = 'Setting both the entity and an invalid target_id property fails.';
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$role->save();
|
||||
$entity->user_role->setValue(['entity' => $role, 'target_id' => $this->generateRandomEntityId(TRUE)]);
|
||||
});
|
||||
@@ -307,10 +307,10 @@ class EntityReferenceFieldTest extends EntityKernelTestBase {
|
||||
catch (\InvalidArgumentException $e) {
|
||||
$this->pass($message);
|
||||
}
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->user_role = $role;
|
||||
});
|
||||
$this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) {
|
||||
$this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) {
|
||||
$entity->user_role->entity = $role;
|
||||
});
|
||||
|
||||
|
||||
+6
-8
@@ -96,13 +96,11 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase {
|
||||
$selection_options = [
|
||||
'target_type' => 'node',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
// Add sorting.
|
||||
'sort' => [
|
||||
'field' => 'field_text.value',
|
||||
'direction' => 'DESC',
|
||||
],
|
||||
'target_bundles' => NULL,
|
||||
// Add sorting.
|
||||
'sort' => [
|
||||
'field' => 'field_text.value',
|
||||
'direction' => 'DESC',
|
||||
],
|
||||
];
|
||||
$handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options);
|
||||
@@ -117,7 +115,7 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase {
|
||||
$this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.');
|
||||
|
||||
// Assert sort by base field.
|
||||
$selection_options['handler_settings']['sort'] = [
|
||||
$selection_options['sort'] = [
|
||||
'field' => 'nid',
|
||||
'direction' => 'ASC',
|
||||
];
|
||||
|
||||
@@ -88,9 +88,9 @@ class EntityRevisionTranslationTest extends EntityKernelTestBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the translation values when saving a forward revision.
|
||||
* Tests the translation values when saving a pending revision.
|
||||
*/
|
||||
public function testTranslationValuesWhenSavingForwardRevisions() {
|
||||
public function testTranslationValuesWhenSavingPendingRevisions() {
|
||||
$user = $this->createUser();
|
||||
$storage = $this->entityManager->getStorage('entity_test_mulrev');
|
||||
|
||||
@@ -103,33 +103,33 @@ class EntityRevisionTranslationTest extends EntityKernelTestBase {
|
||||
$entity->addTranslation('de', ['name' => 'default revision - de']);
|
||||
$entity->save();
|
||||
|
||||
// Create a forward revision for the entity and change a field value for
|
||||
// Create a pending revision for the entity and change a field value for
|
||||
// both languages.
|
||||
$forward_revision = $this->reloadEntity($entity);
|
||||
$pending_revision = $this->reloadEntity($entity);
|
||||
|
||||
$forward_revision->setNewRevision();
|
||||
$forward_revision->isDefaultRevision(FALSE);
|
||||
$pending_revision->setNewRevision();
|
||||
$pending_revision->isDefaultRevision(FALSE);
|
||||
|
||||
$forward_revision->name = 'forward revision - en';
|
||||
$forward_revision->save();
|
||||
$pending_revision->name = 'pending revision - en';
|
||||
$pending_revision->save();
|
||||
|
||||
$forward_revision_translation = $forward_revision->getTranslation('de');
|
||||
$forward_revision_translation->name = 'forward revision - de';
|
||||
$forward_revision_translation->save();
|
||||
$pending_revision_translation = $pending_revision->getTranslation('de');
|
||||
$pending_revision_translation->name = 'pending revision - de';
|
||||
$pending_revision_translation->save();
|
||||
|
||||
$forward_revision_id = $forward_revision->getRevisionId();
|
||||
$forward_revision = $storage->loadRevision($forward_revision_id);
|
||||
$pending_revision_id = $pending_revision->getRevisionId();
|
||||
$pending_revision = $storage->loadRevision($pending_revision_id);
|
||||
|
||||
// Change the value of the field in the default language, save the forward
|
||||
// Change the value of the field in the default language, save the pending
|
||||
// revision and check that the value of the field in the second language is
|
||||
// also taken from the forward revision, *not* from the default revision.
|
||||
$forward_revision->name = 'updated forward revision - en';
|
||||
$forward_revision->save();
|
||||
// also taken from the pending revision, *not* from the default revision.
|
||||
$pending_revision->name = 'updated pending revision - en';
|
||||
$pending_revision->save();
|
||||
|
||||
$forward_revision = $storage->loadRevision($forward_revision_id);
|
||||
$pending_revision = $storage->loadRevision($pending_revision_id);
|
||||
|
||||
$this->assertEquals($forward_revision->name->value, 'updated forward revision - en');
|
||||
$this->assertEquals($forward_revision->getTranslation('de')->name->value, 'forward revision - de');
|
||||
$this->assertEquals($pending_revision->name->value, 'updated pending revision - en');
|
||||
$this->assertEquals($pending_revision->getTranslation('de')->name->value, 'pending revision - de');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -341,12 +341,12 @@ class EntityTranslationTest extends EntityLanguageTestBase {
|
||||
// retrieve a translation referring to it.
|
||||
$translation = $entity->getTranslation(LanguageInterface::LANGCODE_NOT_SPECIFIED);
|
||||
$this->assertFalse($translation->isNewTranslation(), 'Existing translations are not marked as new.');
|
||||
$this->assertIdentical($entity, $translation, 'The translation object corresponding to a non-default language is the entity object itself when the entity is language-neutral.');
|
||||
$this->assertSame($entity, $translation, 'The translation object corresponding to a non-default language is the entity object itself when the entity is language-neutral.');
|
||||
$entity->{$langcode_key}->value = $default_langcode;
|
||||
$translation = $entity->getTranslation($default_langcode);
|
||||
$this->assertIdentical($entity, $translation, 'The translation object corresponding to the default language (explicit) is the entity object itself.');
|
||||
$this->assertSame($entity, $translation, 'The translation object corresponding to the default language (explicit) is the entity object itself.');
|
||||
$translation = $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT);
|
||||
$this->assertIdentical($entity, $translation, 'The translation object corresponding to the default language (implicit) is the entity object itself.');
|
||||
$this->assertSame($entity, $translation, 'The translation object corresponding to the default language (implicit) is the entity object itself.');
|
||||
$this->assertTrue($entity->{$default_langcode_key}->value, 'The translation object is the default one.');
|
||||
|
||||
// Verify that trying to retrieve a translation for a locked language when
|
||||
@@ -657,7 +657,7 @@ class EntityTranslationTest extends EntityLanguageTestBase {
|
||||
$translation = $this->entityManager->getTranslationFromContext($entity2, $default_langcode);
|
||||
$translation_build = $controller->view($translation);
|
||||
$translation_output = (string) $renderer->renderRoot($translation_build);
|
||||
$this->assertIdentical($entity2_output, $translation_output, 'When the entity has no translation no fallback is applied.');
|
||||
$this->assertSame($entity2_output, $translation_output, 'When the entity has no translation no fallback is applied.');
|
||||
|
||||
// Checks that entity translations are rendered properly.
|
||||
$controller = $this->entityManager->getViewBuilder($entity_type);
|
||||
|
||||
@@ -41,7 +41,7 @@ class EntityTypeConstraintsTest extends EntityKernelTestBase {
|
||||
$this->assertEqual($default_constraints + $extra_constraints, $entity_type->getConstraints());
|
||||
|
||||
// Test altering constraints.
|
||||
$altered_constraints = ['Test' => [ 'some_setting' => TRUE]];
|
||||
$altered_constraints = ['Test' => ['some_setting' => TRUE]];
|
||||
$this->state->set('entity_test_constraints.alter', $altered_constraints);
|
||||
// Clear the cache in state instance in the Drupal container, so it can pick
|
||||
// up the modified value.
|
||||
|
||||
@@ -101,8 +101,8 @@ class EntityTypedDataDefinitionTest extends KernelTestBase {
|
||||
|
||||
// Test that the definition factory creates the right definitions for all
|
||||
// entity data types variants.
|
||||
$this->assertEqual($this->typedDataManager->createDataDefinition('entity'), EntityDataDefinition::create());
|
||||
$this->assertEqual($this->typedDataManager->createDataDefinition('entity:node'), EntityDataDefinition::create('node'));
|
||||
$this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity')), serialize(EntityDataDefinition::create()));
|
||||
$this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity:node')), serialize(EntityDataDefinition::create('node')));
|
||||
|
||||
// Config entities don't support typed data.
|
||||
$entity_definition = EntityDataDefinition::create('node_type');
|
||||
@@ -123,7 +123,7 @@ class EntityTypedDataDefinitionTest extends KernelTestBase {
|
||||
// Test that the definition factory creates the right definition object.
|
||||
$reference_definition2 = $this->typedDataManager->createDataDefinition('entity_reference');
|
||||
$this->assertTrue($reference_definition2 instanceof DataReferenceDefinitionInterface);
|
||||
$this->assertEqual($reference_definition2, $reference_definition);
|
||||
$this->assertEqual(serialize($reference_definition2), serialize($reference_definition));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class FieldSqlStorageTest extends EntityKernelTestBase {
|
||||
/**
|
||||
* The table mapping for the tested entity type.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping
|
||||
* @var \Drupal\Core\Entity\Sql\DefaultTableMapping
|
||||
*/
|
||||
protected $tableMapping;
|
||||
|
||||
|
||||
@@ -149,6 +149,10 @@ class FieldWidgetConstraintValidatorTest extends KernelTestBase {
|
||||
|
||||
$errors = $this->getErrorsForEntity($entity);
|
||||
$this->assertEqual($errors[''], 'Entity level validation');
|
||||
|
||||
$entity->name->value = 'entity-level-violation-with-path';
|
||||
$errors = $this->getErrorsForEntity($entity);
|
||||
$this->assertEqual($errors['test][form][element'], 'Entity level validation');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
namespace Drupal\KernelTests\Core\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestWithRevisionLog;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\entity_test_revlog\Entity\EntityTestMulWithRevisionLog;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\user\UserInterface;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Entity\RevisionableContentEntityBase
|
||||
@@ -15,7 +18,7 @@ class RevisionableContentEntityBaseTest extends KernelTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test', 'system', 'user'];
|
||||
public static $modules = ['entity_test_revlog', 'system', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -23,34 +26,102 @@ class RevisionableContentEntityBaseTest extends KernelTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test_revlog');
|
||||
$this->installEntitySchema('entity_test_mul_revlog');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('system', 'sequences');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the correct functionality CRUD operations of entity revisions.
|
||||
*/
|
||||
public function testRevisionableContentEntity() {
|
||||
$entity_type = 'entity_test_mul_revlog';
|
||||
$definition = \Drupal::entityManager()->getDefinition($entity_type);
|
||||
$user = User::create(['name' => 'test name']);
|
||||
$user->save();
|
||||
/** @var \Drupal\entity_test\Entity\EntityTestWithRevisionLog $entity */
|
||||
$entity = EntityTestWithRevisionLog::create([
|
||||
'type' => 'entity_test_revlog',
|
||||
/** @var \Drupal\entity_test_mul_revlog\Entity\EntityTestMulWithRevisionLog $entity */
|
||||
$entity = EntityTestMulWithRevisionLog::create([
|
||||
'type' => $entity_type,
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
// Save the entity, this creates the first revision.
|
||||
$entity->save();
|
||||
$revision_ids[] = $entity->getRevisionId();
|
||||
$this->assertItemsTableCount(1, $definition);
|
||||
|
||||
// Create the second revision.
|
||||
$entity->setNewRevision(TRUE);
|
||||
$random_timestamp = rand(1e8, 2e8);
|
||||
$entity->setRevisionCreationTime($random_timestamp);
|
||||
$entity->setRevisionUserId($user->id());
|
||||
$entity->setRevisionLogMessage('This is my log message');
|
||||
$entity->save();
|
||||
$this->createRevision($entity, $user, $random_timestamp, 'This is my log message');
|
||||
|
||||
$revision_id = $entity->getRevisionId();
|
||||
$revision_ids[] = $revision_id;
|
||||
|
||||
$entity = \Drupal::entityTypeManager()->getStorage('entity_test_revlog')->loadRevision($revision_id);
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_mul_revlog');
|
||||
$entity = $storage->loadRevision($revision_id);
|
||||
$this->assertEquals($random_timestamp, $entity->getRevisionCreationTime());
|
||||
$this->assertEquals($user->id(), $entity->getRevisionUserId());
|
||||
$this->assertEquals($user->id(), $entity->getRevisionUser()->id());
|
||||
$this->assertEquals('This is my log message', $entity->getRevisionLogMessage());
|
||||
|
||||
// Create the third revision.
|
||||
$random_timestamp = rand(1e8, 2e8);
|
||||
$this->createRevision($entity, $user, $random_timestamp, 'This is my log message');
|
||||
$this->assertItemsTableCount(3, $definition);
|
||||
$revision_ids[] = $entity->getRevisionId();
|
||||
|
||||
// Create another 3 revisions.
|
||||
foreach (range(1, 3) as $count) {
|
||||
$timestamp = rand(1e8, 2e8);
|
||||
$this->createRevision($entity, $user, $timestamp, 'This is my log message number: ' . $count);
|
||||
$revision_ids[] = $entity->getRevisionId();
|
||||
}
|
||||
$this->assertItemsTableCount(6, $definition);
|
||||
|
||||
$this->assertEqual(6, count($revision_ids));
|
||||
|
||||
// Delete the first 3 revisions.
|
||||
foreach (range(0, 2) as $key) {
|
||||
$storage->deleteRevision($revision_ids[$key]);
|
||||
}
|
||||
|
||||
// We should have only data for three revisions.
|
||||
$this->assertItemsTableCount(3, $definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the ammount of items on entity related tables.
|
||||
*
|
||||
* @param int $count
|
||||
* The number of items expected to be in revisions related tables.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $definition
|
||||
* The definition and metada of the entity being tested.
|
||||
*/
|
||||
protected function assertItemsTableCount($count, EntityTypeInterface $definition) {
|
||||
$this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getBaseTable() . '}')->fetchField());
|
||||
$this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getDataTable() . '}')->fetchField());
|
||||
$this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionTable() . '}')->fetchField());
|
||||
$this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionDataTable() . '}')->fetchField());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new revision in the entity of this test class.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity where revision will be created.
|
||||
* @param \Drupal\user\UserInterface $user
|
||||
* The author of the new revision.
|
||||
* @param int $timestamp
|
||||
* The timestamp of the new revision.
|
||||
* @param string $log_message
|
||||
* The log message of the new revision.
|
||||
*/
|
||||
protected function createRevision(EntityInterface $entity, UserInterface $user, $timestamp, $log_message) {
|
||||
$entity->setNewRevision(TRUE);
|
||||
$entity->setRevisionCreationTime($timestamp);
|
||||
$entity->setRevisionUserId($user->id());
|
||||
$entity->setRevisionLogMessage($log_message);
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+166
-1
@@ -3,6 +3,15 @@
|
||||
namespace Drupal\KernelTests\Core\Entity;
|
||||
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests validation constraints for ValidReferenceConstraintValidator.
|
||||
@@ -11,6 +20,9 @@ use Drupal\Core\Field\BaseFieldDefinition;
|
||||
*/
|
||||
class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
use ContentTypeCreationTrait;
|
||||
|
||||
/**
|
||||
* The typed data manager to use.
|
||||
*
|
||||
@@ -21,7 +33,7 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'user'];
|
||||
public static $modules = ['field', 'node', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -29,7 +41,12 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('user', ['users_data']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installConfig('node');
|
||||
$this->typedData = $this->container->get('typed_data_manager');
|
||||
|
||||
$this->createContentType(['type' => 'article', 'name' => 'Article']);
|
||||
$this->createContentType(['type' => 'page', 'name' => 'Basic page']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,4 +83,152 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase {
|
||||
$this->assertEqual($violation->getRoot(), $typed_data, 'Violation root is correct.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the validation of pre-existing items in an entity reference field.
|
||||
*/
|
||||
public function testPreExistingItemsValidation() {
|
||||
// Create two types of users, with and without access to bypass content
|
||||
// access.
|
||||
/** @var \Drupal\user\RoleInterface $role_with_access */
|
||||
$role_with_access = Role::create(['id' => 'role_with_access']);
|
||||
$role_with_access->grantPermission('access content');
|
||||
$role_with_access->grantPermission('bypass node access');
|
||||
$role_with_access->save();
|
||||
|
||||
/** @var \Drupal\user\RoleInterface $role_without_access */
|
||||
$role_without_access = Role::create(['id' => 'role_without_access']);
|
||||
$role_without_access->grantPermission('access content');
|
||||
$role_without_access->save();
|
||||
|
||||
$user_with_access = User::create(['roles' => ['role_with_access']]);
|
||||
$user_without_access = User::create(['roles' => ['role_without_access']]);
|
||||
|
||||
// Add an entity reference field.
|
||||
$this->createEntityReferenceField(
|
||||
'entity_test',
|
||||
'entity_test',
|
||||
'field_test',
|
||||
'Field test',
|
||||
'node',
|
||||
'default',
|
||||
['target_bundles' => ['article', 'page']],
|
||||
FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
|
||||
);
|
||||
|
||||
// Create four test nodes.
|
||||
$published_node = Node::create([
|
||||
'title' => 'Test published node',
|
||||
'type' => 'article',
|
||||
'status' => NodeInterface::PUBLISHED,
|
||||
]);
|
||||
$published_node->save();
|
||||
|
||||
$unpublished_node = Node::create([
|
||||
'title' => 'Test unpublished node',
|
||||
'type' => 'article',
|
||||
'status' => NodeInterface::NOT_PUBLISHED,
|
||||
]);
|
||||
$unpublished_node->save();
|
||||
|
||||
$different_bundle_node = Node::create([
|
||||
'title' => 'Test page node',
|
||||
'type' => 'page',
|
||||
'status' => NodeInterface::PUBLISHED,
|
||||
]);
|
||||
$different_bundle_node->save();
|
||||
|
||||
$deleted_node = Node::create([
|
||||
'title' => 'Test deleted node',
|
||||
'type' => 'article',
|
||||
'status' => NodeInterface::PUBLISHED,
|
||||
]);
|
||||
$deleted_node->save();
|
||||
|
||||
$referencing_entity = EntityTest::create([
|
||||
'field_test' => [
|
||||
['entity' => $published_node],
|
||||
['entity' => $unpublished_node],
|
||||
['entity' => $different_bundle_node],
|
||||
['entity' => $deleted_node],
|
||||
]
|
||||
]);
|
||||
|
||||
// Check that users with access are able pass the validation for fields
|
||||
// without pre-existing content.
|
||||
$this->container->get('account_switcher')->switchTo($user_with_access);
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(0, $violations);
|
||||
|
||||
// Check that users without access are not able pass the validation for
|
||||
// fields without pre-existing content.
|
||||
$this->container->get('account_switcher')->switchTo($user_without_access);
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(1, $violations);
|
||||
$this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
|
||||
'%type' => 'node',
|
||||
'%id' => $unpublished_node->id(),
|
||||
]), $violations[0]->getMessage());
|
||||
|
||||
// Now save the referencing entity which will create a pre-existing state
|
||||
// for it and repeat the checks. This time, the user without access should
|
||||
// be able to pass the validation as well because it's not changing the
|
||||
// pre-existing state.
|
||||
$referencing_entity->save();
|
||||
|
||||
$this->container->get('account_switcher')->switchTo($user_with_access);
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(0, $violations);
|
||||
|
||||
// Check that users without access are able pass the validation for fields
|
||||
// with pre-existing content.
|
||||
$this->container->get('account_switcher')->switchTo($user_without_access);
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(0, $violations);
|
||||
|
||||
// Re-save the referencing entity and check that the referenced entity is
|
||||
// not affected.
|
||||
$referencing_entity->name->value = $this->randomString();
|
||||
$referencing_entity->save();
|
||||
$this->assertEquals($published_node->id(), $referencing_entity->field_test[0]->target_id);
|
||||
$this->assertEquals($unpublished_node->id(), $referencing_entity->field_test[1]->target_id);
|
||||
$this->assertEquals($different_bundle_node->id(), $referencing_entity->field_test[2]->target_id);
|
||||
$this->assertEquals($deleted_node->id(), $referencing_entity->field_test[3]->target_id);
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(0, $violations);
|
||||
|
||||
// Remove one of the referencable bundles and check that a pre-existing node
|
||||
// of that bundle can not be referenced anymore.
|
||||
$field = FieldConfig::loadByName('entity_test', 'entity_test', 'field_test');
|
||||
$field->setSetting('handler_settings', ['target_bundles' => ['article']]);
|
||||
$field->save();
|
||||
$referencing_entity = $this->reloadEntity($referencing_entity);
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(1, $violations);
|
||||
$this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
|
||||
'%type' => 'node',
|
||||
'%id' => $different_bundle_node->id(),
|
||||
]), $violations[0]->getMessage());
|
||||
|
||||
// Delete the last node and check that the pre-existing reference is not
|
||||
// valid anymore.
|
||||
$deleted_node->delete();
|
||||
|
||||
$violations = $referencing_entity->field_test->validate();
|
||||
$this->assertCount(2, $violations);
|
||||
$this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [
|
||||
'%type' => 'node',
|
||||
'%id' => $different_bundle_node->id(),
|
||||
]), $violations[0]->getMessage());
|
||||
$this->assertEquals(t('The referenced entity (%type: %id) does not exist.', [
|
||||
'%type' => 'node',
|
||||
'%id' => $deleted_node->id(),
|
||||
]), $violations[1]->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class IgnoreReplicaSubscriberTest extends KernelTestBase {
|
||||
$db1 = Database::getConnection('default', 'default');
|
||||
$db2 = Database::getConnection('replica', 'default');
|
||||
|
||||
$this->assertIdentical($db1, $db2, 'System Init ignores secondaries when requested.');
|
||||
$this->assertSame($db1, $db2, 'System Init ignores secondaries when requested.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,4 +44,20 @@ class ModuleInstallerTest extends KernelTestBase {
|
||||
$this->container->get('router.route_provider')->getRouteByName('router_test.1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests config changes by hook_install() are saved for dependent modules.
|
||||
*
|
||||
* @covers ::install
|
||||
*/
|
||||
public function testConfigChangeOnInstall() {
|
||||
// Install the child module so the parent is installed automatically.
|
||||
$this->container->get('module_installer')->install(['module_handler_test_multiple_child']);
|
||||
$modules = $this->config('core.extension')->get('module');
|
||||
|
||||
$this->assertArrayHasKey('module_handler_test_multiple', $modules, 'Module module_handler_test_multiple is installed');
|
||||
$this->assertArrayHasKey('module_handler_test_multiple_child', $modules, 'Module module_handler_test_multiple_child is installed');
|
||||
$this->assertEquals(1, $modules['module_handler_test_multiple'], 'Weight of module_handler_test_multiple is set.');
|
||||
$this->assertEquals(1, $modules['module_handler_test_multiple_child'], 'Weight of module_handler_test_multiple_child is set.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Field\Entity;
|
||||
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\Entity\BaseFieldOverride;
|
||||
use Drupal\Core\Field\FieldItemList;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Field\Entity\BaseFieldOverride
|
||||
* @group Field
|
||||
*/
|
||||
class BaseFieldOverrideTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('base_field_override');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getClass
|
||||
*
|
||||
* @dataProvider getClassTestCases
|
||||
*/
|
||||
public function testGetClass($field_type, $base_field_class, $expected_override_class) {
|
||||
$base_field = BaseFieldDefinition::create($field_type)
|
||||
->setName('Test Field')
|
||||
->setTargetEntityTypeId('entity_test');
|
||||
if ($base_field_class) {
|
||||
$base_field->setClass($base_field_class);
|
||||
}
|
||||
$override = BaseFieldOverride::createFromBaseFieldDefinition($base_field, 'test_bundle');
|
||||
$this->assertEquals($expected_override_class, ltrim($override->getClass(), '\\'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test cases for ::testGetClass.
|
||||
*/
|
||||
public function getClassTestCases() {
|
||||
return [
|
||||
'String (default class)' => [
|
||||
'string',
|
||||
FALSE,
|
||||
FieldItemList::class,
|
||||
],
|
||||
'String (overriden class)' => [
|
||||
'string',
|
||||
static::class,
|
||||
static::class,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,7 +59,7 @@ class NameMungingTest extends FileTestBase {
|
||||
public function testMungeIgnoreInsecure() {
|
||||
$this->config('system.file')->set('allow_insecure_uploads', 1)->save();
|
||||
$munged_name = file_munge_filename($this->name, '');
|
||||
$this->assertIdentical($munged_name, $this->name, format_string('The original filename (%original) matches the munged filename (%munged) when insecure uploads are enabled.', ['%munged' => $munged_name, '%original' => $this->name]));
|
||||
$this->assertSame($munged_name, $this->name, format_string('The original filename (%original) matches the munged filename (%munged) when insecure uploads are enabled.', ['%munged' => $munged_name, '%original' => $this->name]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,10 +69,10 @@ class NameMungingTest extends FileTestBase {
|
||||
// Declare our extension as whitelisted. The declared extensions should
|
||||
// be case insensitive so test using one with a different case.
|
||||
$munged_name = file_munge_filename($this->nameWithUcExt, $this->badExtension);
|
||||
$this->assertIdentical($munged_name, $this->nameWithUcExt, format_string('The new filename (%munged) matches the original (%original) once the extension has been whitelisted.', ['%munged' => $munged_name, '%original' => $this->nameWithUcExt]));
|
||||
$this->assertSame($munged_name, $this->nameWithUcExt, format_string('The new filename (%munged) matches the original (%original) once the extension has been whitelisted.', ['%munged' => $munged_name, '%original' => $this->nameWithUcExt]));
|
||||
// The allowed extensions should also be normalized.
|
||||
$munged_name = file_munge_filename($this->name, strtoupper($this->badExtension));
|
||||
$this->assertIdentical($munged_name, $this->name, format_string('The new filename (%munged) matches the original (%original) also when the whitelisted extension is in uppercase.', ['%munged' => $munged_name, '%original' => $this->name]));
|
||||
$this->assertSame($munged_name, $this->name, format_string('The new filename (%munged) matches the original (%original) also when the whitelisted extension is in uppercase.', ['%munged' => $munged_name, '%original' => $this->name]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,7 @@ class NameMungingTest extends FileTestBase {
|
||||
public function testUnMunge() {
|
||||
$munged_name = file_munge_filename($this->name, '', FALSE);
|
||||
$unmunged_name = file_unmunge_filename($munged_name);
|
||||
$this->assertIdentical($unmunged_name, $this->name, format_string('The unmunged (%unmunged) filename matches the original (%original)', ['%unmunged' => $unmunged_name, '%original' => $this->name]));
|
||||
$this->assertSame($unmunged_name, $this->name, format_string('The unmunged (%unmunged) filename matches the original (%original)', ['%unmunged' => $unmunged_name, '%original' => $this->name]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -106,13 +106,13 @@ class UrlRewritingTest extends FileTestBase {
|
||||
// Shipped file.
|
||||
$filepath = 'core/assets/vendor/jquery/jquery.min.js';
|
||||
$url = file_create_url($filepath);
|
||||
$this->assertIdentical(base_path() . $filepath, file_url_transform_relative($url));
|
||||
$this->assertSame(base_path() . $filepath, file_url_transform_relative($url));
|
||||
|
||||
// Managed file.
|
||||
$uri = $this->createUri();
|
||||
$url = file_create_url($uri);
|
||||
$public_directory_path = \Drupal::service('stream_wrapper_manager')->getViaScheme('public')->getDirectoryPath();
|
||||
$this->assertIdentical(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url));
|
||||
$this->assertSame(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Drupal\KernelTests\Core\Form;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Session\AnonymousUserSession;
|
||||
use Drupal\Core\Session\UserSession;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
@@ -101,4 +102,16 @@ class FormCacheTest extends KernelTestBase {
|
||||
$account_switcher->switchBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the form cache with an overridden cache expiration.
|
||||
*/
|
||||
public function testCacheCustomExpiration() {
|
||||
// Override form cache expiration so that the cached form expired yesterday.
|
||||
new Settings(['form_cache_expiration' => -1 * (24 * 60 * 60), 'hash_salt' => $this->randomMachineName()]);
|
||||
\Drupal::formBuilder()->setCache($this->formBuildId, $this->form, $this->formState);
|
||||
|
||||
$cached_form_state = new FormState();
|
||||
$this->assertFalse(\Drupal::formBuilder()->getCache($this->formBuildId, $cached_form_state), 'Expired form not returned from cache');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Form;
|
||||
|
||||
use Drupal\Core\Form\FormInterface;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests form validation mesages are displayed in the same order as the fields.
|
||||
*
|
||||
* @group Form
|
||||
*/
|
||||
class FormValidationMessageOrderTest extends KernelTestBase implements FormInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'form_validation_error_message_order_test';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
// Prepare fields with weights specified.
|
||||
$form['one'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => 'One',
|
||||
'#required' => TRUE,
|
||||
'#weight' => 40,
|
||||
];
|
||||
$form['two'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => 'Two',
|
||||
'#required' => TRUE,
|
||||
'#weight' => 30,
|
||||
];
|
||||
$form['three'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => 'Three',
|
||||
'#required' => TRUE,
|
||||
'#weight' => 10,
|
||||
];
|
||||
$form['four'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => 'Four',
|
||||
'#required' => TRUE,
|
||||
'#weight' => 20,
|
||||
];
|
||||
$form['actions'] = [
|
||||
'#type' => 'actions',
|
||||
'submit' => [
|
||||
'#type' => 'submit',
|
||||
'#value' => 'Submit',
|
||||
],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that fields validation messages are sorted in the fields order.
|
||||
*/
|
||||
public function testLimitValidationErrors() {
|
||||
$form_state = new FormState();
|
||||
$form_builder = $this->container->get('form_builder');
|
||||
$form_builder->submitForm($this, $form_state);
|
||||
|
||||
$messages = drupal_get_messages();
|
||||
$this->assertTrue(isset($messages['error']));
|
||||
$error_messages = $messages['error'];
|
||||
$this->assertEqual($error_messages[0], 'Three field is required.');
|
||||
$this->assertEqual($error_messages[1], 'Four field is required.');
|
||||
$this->assertEqual($error_messages[2], 'Two field is required.');
|
||||
$this->assertEqual($error_messages[3], 'One field is required.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -218,14 +218,16 @@ class ToolkitGdTest extends KernelTestBase {
|
||||
$operations += [
|
||||
'rotate_5' => [
|
||||
'function' => 'rotate',
|
||||
'arguments' => ['degrees' => 5, 'background' => '#FF00FF'], // Fuchsia background.
|
||||
// Fuchsia background.
|
||||
'arguments' => ['degrees' => 5, 'background' => '#FF00FF'],
|
||||
'width' => 41,
|
||||
'height' => 23,
|
||||
'corners' => array_fill(0, 4, $this->fuchsia),
|
||||
],
|
||||
'rotate_90' => [
|
||||
'function' => 'rotate',
|
||||
'arguments' => ['degrees' => 90, 'background' => '#FF00FF'], // Fuchsia background.
|
||||
// Fuchsia background.
|
||||
'arguments' => ['degrees' => 90, 'background' => '#FF00FF'],
|
||||
'width' => 20,
|
||||
'height' => 40,
|
||||
'corners' => [$this->transparent, $this->red, $this->green, $this->blue],
|
||||
@@ -365,7 +367,7 @@ class ToolkitGdTest extends KernelTestBase {
|
||||
if ($image->getToolkit()->getType() == $image_original_type || $corner != $this->transparent) {
|
||||
$correct_colors = $this->colorsAreEqual($color, $corner);
|
||||
$this->assertTrue($correct_colors, SafeMarkup::format('Image %file object after %action action has the correct color placement at corner %corner.',
|
||||
['%file' => $file, '%action' => $op, '%corner' => $key]));
|
||||
['%file' => $file, '%action' => $op, '%corner' => $key]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class DatabaseStorageExpirableTest extends StorageTestBase {
|
||||
// Ensure that an item with the same name exists in the other collection.
|
||||
$stores[1]->set('foo', $this->objects[5]);
|
||||
$result = $stores[0]->getAll();
|
||||
// Not using assertIdentical(), since the order is not defined for getAll().
|
||||
// Not using assertSame(), since the order is not defined for getAll().
|
||||
$this->assertEqual(count($result), count($values));
|
||||
foreach ($result as $key => $value) {
|
||||
$this->assertEqual($values[$key], $value);
|
||||
|
||||
@@ -39,7 +39,7 @@ class GarbageCollectionTest extends KernelTestBase {
|
||||
for ($i = 0; $i <= 3; $i++) {
|
||||
$store->setWithExpire('key_' . $i, $this->randomObject(), rand(500, 100000));
|
||||
}
|
||||
$this->assertIdentical(sizeof($store->getAll()), 4, 'Four items were written to the storage.');
|
||||
$this->assertIdentical(count($store->getAll()), 4, 'Four items were written to the storage.');
|
||||
|
||||
// Manually expire the data.
|
||||
for ($i = 0; $i <= 3; $i++) {
|
||||
|
||||
@@ -31,9 +31,15 @@ class KeyValueContentEntityStorageTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests CRUD operations.
|
||||
*
|
||||
* @covers \Drupal\Core\Entity\KeyValueStore\KeyValueEntityStorage::hasData
|
||||
*/
|
||||
public function testCRUD() {
|
||||
$default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
|
||||
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_label');
|
||||
$this->assertFalse($storage->hasData());
|
||||
|
||||
// Verify default properties on a newly created empty entity.
|
||||
$empty = EntityTestLabel::create();
|
||||
$this->assertIdentical($empty->id->value, NULL);
|
||||
@@ -108,6 +114,9 @@ class KeyValueContentEntityStorageTest extends KernelTestBase {
|
||||
$this->fail('EntityMalformedException was not thrown.');
|
||||
}
|
||||
|
||||
// Verify that hasData() returns the expected result.
|
||||
$this->assertTrue($storage->hasData());
|
||||
|
||||
// Verify that the correct status is returned and properties did not change.
|
||||
$this->assertIdentical($status, SAVED_NEW);
|
||||
$this->assertIdentical($entity_test->id(), $expected['id']);
|
||||
@@ -157,4 +166,12 @@ class KeyValueContentEntityStorageTest extends KernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uninstallation of a module that does not use the SQL entity storage.
|
||||
*/
|
||||
public function testUninstall() {
|
||||
$uninstall_validator_reasons = \Drupal::service('content_uninstall_validator')->validate('keyvalue_test');
|
||||
$this->assertEmpty($uninstall_validator_reasons);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ abstract class StorageTestBase extends KernelTestBase {
|
||||
// Ensure that an item with the same name exists in the other collection.
|
||||
$stores[1]->set('foo', $this->objects[5]);
|
||||
$result = $stores[0]->getAll();
|
||||
// Not using assertIdentical(), since the order is not defined for getAll().
|
||||
// Not using assertSame(), since the order is not defined for getAll().
|
||||
$this->assertEqual(count($result), count($values));
|
||||
foreach ($result as $key => $value) {
|
||||
$this->assertEqual($values[$key], $value);
|
||||
|
||||
@@ -47,6 +47,21 @@ class LockTest extends KernelTestBase {
|
||||
$this->assertTrue($success, 'Could acquire second lock a second time within the same request.');
|
||||
|
||||
$this->lock->release('lock_b');
|
||||
|
||||
// Test acquiring an releasing a lock with a long key (over 255 chars).
|
||||
$long_key = 'long_key:BZoMiSf9IIPULsJ98po18TxJ6T4usd3MZrLE0d3qMgG6iAgDlOi1G3oMap7zI5df84l7LtJBg4bOj6XvpO6vDRmP5h5QbA0Bj9rVFiPIPAIQZ9qFvJqTALiK1OR3GpOkWQ4vgEA4LkY0UfznrWBeuK7IWZfv1um6DLosnVXd1z1cJjvbEUqYGJj92rwHfhYihLm8IO9t3P2gAvEkH5Mhc8GBoiTsIDnP01Te1kxGFHO3RuvJIxPnHmZtSdBggmuVN7x9';
|
||||
|
||||
$success = $this->lock->acquire($long_key);
|
||||
$this->assertTrue($success, 'Could acquire long key lock.');
|
||||
|
||||
// This function is not part of the backend, but the default database
|
||||
// backend implement it, we can here use it safely.
|
||||
$is_free = $this->lock->lockMayBeAvailable($long_key);
|
||||
$this->assertFalse($is_free, 'Long key lock is unavailable.');
|
||||
|
||||
$this->lock->release($long_key);
|
||||
$is_free = $this->lock->lockMayBeAvailable($long_key);
|
||||
$this->assertTrue($is_free, 'Long key lock has been released.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ class MenuLinkTreeTest extends KernelTestBase {
|
||||
/**
|
||||
* The menu link plugin manager.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
|
||||
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
|
||||
*/
|
||||
protected $menuLinkManager;
|
||||
|
||||
@@ -111,7 +111,7 @@ class MenuLinkTreeTest extends KernelTestBase {
|
||||
$parameters = new MenuTreeParameters();
|
||||
$tree = $this->linkTree->load('mock', $parameters);
|
||||
|
||||
$count = function(array $tree) {
|
||||
$count = function (array $tree) {
|
||||
$sum = function ($carry, MenuLinkTreeElement $item) {
|
||||
return $carry + $item->count();
|
||||
};
|
||||
|
||||
@@ -16,16 +16,16 @@ use Drupal\Core\Path\AliasWhitelist;
|
||||
class AliasTest extends PathUnitTestBase {
|
||||
|
||||
public function testCRUD() {
|
||||
//Prepare database table.
|
||||
// Prepare database table.
|
||||
$connection = Database::getConnection();
|
||||
$this->fixtures->createTables($connection);
|
||||
|
||||
//Create Path object.
|
||||
// Create Path object.
|
||||
$aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
|
||||
|
||||
$aliases = $this->fixtures->sampleUrlAliases();
|
||||
|
||||
//Create a few aliases
|
||||
// Create a few aliases
|
||||
foreach ($aliases as $idx => $alias) {
|
||||
$aliasStorage->save($alias['source'], $alias['alias'], $alias['langcode']);
|
||||
|
||||
@@ -34,11 +34,11 @@ class AliasTest extends PathUnitTestBase {
|
||||
|
||||
$this->assertEqual(count($rows), 1, format_string('Created an entry for %alias.', ['%alias' => $alias['alias']]));
|
||||
|
||||
//Cache the pid for further tests.
|
||||
// Cache the pid for further tests.
|
||||
$aliases[$idx]['pid'] = $rows[0]->pid;
|
||||
}
|
||||
|
||||
//Load a few aliases
|
||||
// Load a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$pid = $alias['pid'];
|
||||
$loadedAlias = $aliasStorage->load(['pid' => $pid]);
|
||||
@@ -49,7 +49,7 @@ class AliasTest extends PathUnitTestBase {
|
||||
$loadedAlias = $aliasStorage->load(['source' => '/node/1']);
|
||||
$this->assertEqual($loadedAlias['alias'], '/alias_for_node_1_und', 'The last created alias loaded by default.');
|
||||
|
||||
//Update a few aliases
|
||||
// Update a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$fields = $aliasStorage->save($alias['source'], $alias['alias'] . '_updated', $alias['langcode'], $alias['pid']);
|
||||
|
||||
@@ -61,7 +61,7 @@ class AliasTest extends PathUnitTestBase {
|
||||
$this->assertEqual($pid, $alias['pid'], format_string('Updated entry for pid %pid.', ['%pid' => $pid]));
|
||||
}
|
||||
|
||||
//Delete a few aliases
|
||||
// Delete a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$pid = $alias['pid'];
|
||||
$aliasStorage->delete(['pid' => $pid]);
|
||||
@@ -74,11 +74,11 @@ class AliasTest extends PathUnitTestBase {
|
||||
}
|
||||
|
||||
public function testLookupPath() {
|
||||
//Prepare database table.
|
||||
// Prepare database table.
|
||||
$connection = Database::getConnection();
|
||||
$this->fixtures->createTables($connection);
|
||||
|
||||
//Create AliasManager and Path object.
|
||||
// Create AliasManager and Path object.
|
||||
$aliasManager = $this->container->get('path.alias_manager');
|
||||
$aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
|
||||
|
||||
|
||||
@@ -44,8 +44,10 @@ class PathValidatorTest extends KernelTestBase {
|
||||
'PUT',
|
||||
'PATCH',
|
||||
'DELETE',
|
||||
NULL, // Used in CLI context.
|
||||
FALSE, // If no request was even pushed onto the request stack, and hence
|
||||
// Used in CLI context.
|
||||
NULL,
|
||||
// If no request was even pushed onto the request stack, and hence.
|
||||
FALSE,
|
||||
];
|
||||
foreach ($methods as $method) {
|
||||
if ($method === FALSE) {
|
||||
|
||||
@@ -59,7 +59,7 @@ class ContextPluginTest extends KernelTestBase {
|
||||
$plugin->getContextValue('user');
|
||||
}
|
||||
catch (ContextException $e) {
|
||||
$this->assertIdentical("The 'entity:user' context is required and not present.", $e->getMessage(), 'Requesting a non-set value of a required context should throw a context exception.');
|
||||
$this->assertSame("The 'entity:user' context is required and not present.", $e->getMessage(), 'Requesting a non-set value of a required context should throw a context exception.');
|
||||
}
|
||||
|
||||
// Try to pass the wrong class type as a context value.
|
||||
|
||||
@@ -71,7 +71,7 @@ abstract class DiscoveryTestBase extends KernelTestBase {
|
||||
* TRUE if the assertion succeeded, FALSE otherwise.
|
||||
*/
|
||||
protected function assertDefinitionIdentical(array $definition, array $expected_definition) {
|
||||
$func = function (&$item){
|
||||
$func = function (&$item) {
|
||||
if ($item instanceof TranslatableMarkup) {
|
||||
$item = (string) $item;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class QueueTest extends KernelTestBase {
|
||||
$queue2 = new DatabaseQueue($this->randomMachineName(), Database::getConnection());
|
||||
$queue2->createQueue();
|
||||
|
||||
$this->queueTest($queue1, $queue2);
|
||||
$this->runQueueTest($queue1, $queue2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ class QueueTest extends KernelTestBase {
|
||||
$queue2 = new Memory($this->randomMachineName());
|
||||
$queue2->createQueue();
|
||||
|
||||
$this->queueTest($queue1, $queue2);
|
||||
$this->runQueueTest($queue1, $queue2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ class QueueTest extends KernelTestBase {
|
||||
* @param \Drupal\Core\Queue\QueueInterface $queue2
|
||||
* An instantiated queue object.
|
||||
*/
|
||||
protected function queueTest($queue1, $queue2) {
|
||||
protected function runQueueTest($queue1, $queue2) {
|
||||
// Create four items.
|
||||
$data = [];
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
|
||||
@@ -111,8 +111,10 @@ class ContentNegotiationRoutingTest extends KernelTestBase {
|
||||
$tests = [
|
||||
// ['path', 'accept', 'content-type'],
|
||||
|
||||
['conneg/negotiate', '', 'text/html'], // 406?
|
||||
['conneg/negotiate', '', 'text/html'], // 406?
|
||||
// 406?
|
||||
['conneg/negotiate', '', 'text/html'],
|
||||
// 406?
|
||||
['conneg/negotiate', '', 'text/html'],
|
||||
// ['conneg/negotiate', '*/*', '??'],
|
||||
['conneg/negotiate', 'application/json', 'application/json'],
|
||||
['conneg/negotiate', 'application/xml', 'application/xml'],
|
||||
|
||||
@@ -155,7 +155,7 @@ class ExceptionHandlingTest extends KernelTestBase {
|
||||
$kernel = \Drupal::getContainer()->get('http_kernel');
|
||||
$response = $kernel->handle($request)->prepare($request);
|
||||
$this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8');
|
||||
$this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
|
||||
|
||||
// Test both that the backtrace is properly escaped, and that the unescaped
|
||||
// string is not output at all.
|
||||
@@ -178,7 +178,7 @@ class ExceptionHandlingTest extends KernelTestBase {
|
||||
$kernel = \Drupal::getContainer()->get('http_kernel');
|
||||
$response = $kernel->handle($request)->prepare($request);
|
||||
$this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8');
|
||||
$this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
|
||||
|
||||
// Test message is properly escaped, and that the unescaped string is not
|
||||
// output at all.
|
||||
@@ -192,10 +192,11 @@ class ExceptionHandlingTest extends KernelTestBase {
|
||||
$kernel = \Drupal::getContainer()->get('http_kernel');
|
||||
$response = $kernel->handle($request)->prepare($request);
|
||||
// As the Content-type is text/plain the fact that the raw string is
|
||||
// contained in the output does not matter.
|
||||
// contained in the output would not matter, but because it is output by the
|
||||
// final exception subscriber, it is printed as partial HTML, and hence
|
||||
// escaped.
|
||||
$this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
|
||||
$this->setRawContent($response->getContent());
|
||||
$this->assertRaw($string);
|
||||
$this->assertStringStartsWith('The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException</em>: Not acceptable format: json<script>alert(123);</script> in <em class="placeholder">', $response->getContent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Test;
|
||||
|
||||
use Drupal\FunctionalTests\BrowserMissingDependentModuleMethodTest;
|
||||
use Drupal\FunctionalTests\BrowserMissingDependentModuleTest;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* @group Test
|
||||
* @group FunctionalTests
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Tests\BrowserTestBase
|
||||
*/
|
||||
class BrowserTestBaseTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests that a test method is skipped when it requires a module not present.
|
||||
*
|
||||
* In order to catch checkRequirements() regressions, we have to make a new
|
||||
* test object and run checkRequirements() here.
|
||||
*
|
||||
* @covers ::checkRequirements
|
||||
* @covers ::checkModuleRequirements
|
||||
*/
|
||||
public function testMethodRequiresModule() {
|
||||
require __DIR__ . '/../../../../fixtures/BrowserMissingDependentModuleMethodTest.php';
|
||||
|
||||
$stub_test = new BrowserMissingDependentModuleMethodTest();
|
||||
// We have to setName() to the method name we're concerned with.
|
||||
$stub_test->setName('testRequiresModule');
|
||||
|
||||
// We cannot use $this->setExpectedException() because PHPUnit would skip
|
||||
// the test before comparing the exception type.
|
||||
try {
|
||||
$stub_test->publicCheckRequirements();
|
||||
$this->fail('Missing required module throws skipped test exception.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_SkippedTestError $e) {
|
||||
$this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a test case is skipped when it requires a module not present.
|
||||
*
|
||||
* In order to catch checkRequirements() regressions, we have to make a new
|
||||
* test object and run checkRequirements() here.
|
||||
*
|
||||
* @covers ::checkRequirements
|
||||
* @covers ::checkModuleRequirements
|
||||
*/
|
||||
public function testRequiresModule() {
|
||||
require __DIR__ . '/../../../../fixtures/BrowserMissingDependentModuleTest.php';
|
||||
|
||||
$stub_test = new BrowserMissingDependentModuleTest();
|
||||
// We have to setName() to the method name we're concerned with.
|
||||
$stub_test->setName('testRequiresModule');
|
||||
|
||||
// We cannot use $this->setExpectedException() because PHPUnit would skip
|
||||
// the test before comparing the exception type.
|
||||
try {
|
||||
$stub_test->publicCheckRequirements();
|
||||
$this->fail('Missing required module throws skipped test exception.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_SkippedTestError $e) {
|
||||
$this->assertEqual('Required modules: module_does_not_exist', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -77,7 +77,7 @@ class RegistryTest extends KernelTestBase {
|
||||
$registry_base_theme->setThemeManager(\Drupal::theme());
|
||||
|
||||
$preprocess_functions = $registry_subsub_theme->get()['theme_test_template_test']['preprocess functions'];
|
||||
$this->assertIdentical([
|
||||
$this->assertSame([
|
||||
'template_preprocess',
|
||||
'test_basetheme_preprocess_theme_test_template_test',
|
||||
'test_subtheme_preprocess_theme_test_template_test',
|
||||
@@ -85,20 +85,20 @@ class RegistryTest extends KernelTestBase {
|
||||
], $preprocess_functions);
|
||||
|
||||
$preprocess_functions = $registry_sub_theme->get()['theme_test_template_test']['preprocess functions'];
|
||||
$this->assertIdentical([
|
||||
$this->assertSame([
|
||||
'template_preprocess',
|
||||
'test_basetheme_preprocess_theme_test_template_test',
|
||||
'test_subtheme_preprocess_theme_test_template_test',
|
||||
], $preprocess_functions);
|
||||
|
||||
$preprocess_functions = $registry_base_theme->get()['theme_test_template_test']['preprocess functions'];
|
||||
$this->assertIdentical([
|
||||
$this->assertSame([
|
||||
'template_preprocess',
|
||||
'test_basetheme_preprocess_theme_test_template_test',
|
||||
], $preprocess_functions);
|
||||
|
||||
$preprocess_functions = $registry_base_theme->get()['theme_test_function_suggestions']['preprocess functions'];
|
||||
$this->assertIdentical([
|
||||
$this->assertSame([
|
||||
'template_preprocess_theme_test_function_suggestions',
|
||||
'test_basetheme_preprocess_theme_test_function_suggestions',
|
||||
], $preprocess_functions, "Theme functions don't have template_preprocess but do have template_preprocess_HOOK");
|
||||
@@ -125,7 +125,7 @@ class RegistryTest extends KernelTestBase {
|
||||
$hook .= "$suggestion";
|
||||
$expected_preprocess_functions[] = "test_theme_preprocess_$hook";
|
||||
$preprocess_functions = $registry_theme->get()[$hook]['preprocess functions'];
|
||||
$this->assertIdentical($expected_preprocess_functions, $preprocess_functions, "$hook has correct preprocess functions.");
|
||||
$this->assertSame($expected_preprocess_functions, $preprocess_functions, "$hook has correct preprocess functions.");
|
||||
} while ($suggestion = array_shift($suggestions));
|
||||
|
||||
$expected_preprocess_functions = [
|
||||
@@ -136,10 +136,10 @@ class RegistryTest extends KernelTestBase {
|
||||
];
|
||||
|
||||
$preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat']['preprocess functions'];
|
||||
$this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a function correctly inherits preprocess functions.');
|
||||
$this->assertSame($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a function correctly inherits preprocess functions.');
|
||||
|
||||
$preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__bearcat']['preprocess functions'];
|
||||
$this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.');
|
||||
$this->assertSame($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.');
|
||||
|
||||
$this->assertTrue(isset($registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat__tarsier__moose']), 'Preprocess function with an unimplemented lower-level suggestion is added to the registry.');
|
||||
}
|
||||
|
||||
@@ -134,4 +134,4 @@ class ThemeRenderAndAutoescapeTest extends KernelTestBase {
|
||||
|
||||
}
|
||||
|
||||
class NonPrintable { }
|
||||
class NonPrintable {}
|
||||
|
||||
@@ -42,6 +42,7 @@ class TwigWhiteListTest extends KernelTestBase {
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::service('theme_handler')->install(['test_theme']);
|
||||
$this->installSchema('system', ['sequences']);
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('user');
|
||||
|
||||
@@ -77,7 +77,7 @@ class TypedDataDefinitionTest extends KernelTestBase {
|
||||
$map_definition2->setPropertyDefinition('one', DataDefinition::create('string'))
|
||||
->setPropertyDefinition('two', DataDefinition::create('string'))
|
||||
->setPropertyDefinition('three', DataDefinition::create('string'));
|
||||
$this->assertEqual($map_definition, $map_definition2);
|
||||
$this->assertEqual(serialize($map_definition), serialize($map_definition2));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +93,7 @@ class TypedDataDefinitionTest extends KernelTestBase {
|
||||
// Test using the definition factory.
|
||||
$language_reference_definition2 = $this->typedDataManager->createDataDefinition('language_reference');
|
||||
$this->assertTrue($language_reference_definition2 instanceof DataReferenceDefinitionInterface);
|
||||
$this->assertEqual($language_reference_definition, $language_reference_definition2);
|
||||
$this->assertEqual(serialize($language_reference_definition), serialize($language_reference_definition2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ class TypedDataTest extends KernelTestBase {
|
||||
// Check that an all-pass filter leaves the list untouched.
|
||||
$value = ['zero', 'one'];
|
||||
$typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value);
|
||||
$typed_data->filter(function(TypedDataInterface $item) {
|
||||
$typed_data->filter(function (TypedDataInterface $item) {
|
||||
return TRUE;
|
||||
});
|
||||
$this->assertEqual($typed_data->count(), 2);
|
||||
@@ -411,7 +411,7 @@ class TypedDataTest extends KernelTestBase {
|
||||
// Check that a none-pass filter empties the list.
|
||||
$value = ['zero', 'one'];
|
||||
$typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value);
|
||||
$typed_data->filter(function(TypedDataInterface $item) {
|
||||
$typed_data->filter(function (TypedDataInterface $item) {
|
||||
return FALSE;
|
||||
});
|
||||
$this->assertEqual($typed_data->count(), 0);
|
||||
@@ -419,7 +419,7 @@ class TypedDataTest extends KernelTestBase {
|
||||
// Check that filtering correctly renumbers elements.
|
||||
$value = ['zero', 'one', 'two'];
|
||||
$typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value);
|
||||
$typed_data->filter(function(TypedDataInterface $item) {
|
||||
$typed_data->filter(function (TypedDataInterface $item) {
|
||||
return $item->getValue() !== 'one';
|
||||
});
|
||||
$this->assertEqual($typed_data->count(), 2);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Validation;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests various low level constrains provided by core.
|
||||
*
|
||||
* @group Validation
|
||||
*/
|
||||
class ConstraintsTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig('config_test');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Drupal\Core\Validation\Plugin\Validation\Constraint\UuidConstraint
|
||||
*/
|
||||
public function testUuid() {
|
||||
$typed_config_manager = \Drupal::service('config.typed');
|
||||
/** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
|
||||
$typed_config = $typed_config_manager->get('config_test.validation');
|
||||
$typed_config->get('uuid')
|
||||
->setValue(\Drupal::service('uuid')->generate());
|
||||
|
||||
$this->assertCount(0, $typed_config->validate());
|
||||
|
||||
$typed_config->get('uuid')
|
||||
->setValue(\Drupal::service('uuid')->generate() . '-invalid');
|
||||
$this->assertCount(1, $typed_config->validate());
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user