updated core and modules
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Performs tests on AJAX forms in cached pages.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class AjaxFormPageCacheTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['ajax_test', 'ajax_forms_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$config = $this->config('system.performance');
|
||||
$config->set('cache.page.max_age', 300);
|
||||
$config->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the build id of the current form.
|
||||
*/
|
||||
protected function getFormBuildId() {
|
||||
$build_id_fields = $this->xpath('//input[@name="form_build_id"]');
|
||||
$this->assertEquals(count($build_id_fields), 1, 'One form build id field on the page');
|
||||
return $build_id_fields[0]->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple form, then submit the form via AJAX to change to it.
|
||||
*/
|
||||
public function testSimpleAJAXFormValue() {
|
||||
$this->drupalGet('ajax_forms_test_get_form');
|
||||
$this->assertEquals($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
|
||||
$build_id_initial = $this->getFormBuildId();
|
||||
|
||||
// Changing the value of a select input element, triggers a AJAX
|
||||
// request/response. The callback on the form responds with three AJAX
|
||||
// commands:
|
||||
// - UpdateBuildIdCommand
|
||||
// - HtmlCommand
|
||||
// - DataCommand
|
||||
$session = $this->getSession();
|
||||
$session->getPage()->selectFieldOption('select', 'green');
|
||||
|
||||
// Wait for the DOM to update. The HtmlCommand will update
|
||||
// #ajax_selected_color to reflect the color change.
|
||||
$green_div = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('green')");
|
||||
$this->assertNotNull($green_div, 'DOM update: The selected color DIV is green.');
|
||||
|
||||
// Confirm the operation of the UpdateBuildIdCommand.
|
||||
$build_id_first_ajax = $this->getFormBuildId();
|
||||
$this->assertNotEquals($build_id_initial, $build_id_first_ajax, 'Build id is changed in the form_build_id element on first AJAX submission');
|
||||
|
||||
// Changing the value of a select input element, triggers a AJAX
|
||||
// request/response.
|
||||
$session->getPage()->selectFieldOption('select', 'red');
|
||||
|
||||
// Wait for the DOM to update.
|
||||
$red_div = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('red')");
|
||||
$this->assertNotNull($red_div, 'DOM update: The selected color DIV is red.');
|
||||
|
||||
// Confirm the operation of the UpdateBuildIdCommand.
|
||||
$build_id_second_ajax = $this->getFormBuildId();
|
||||
$this->assertNotEquals($build_id_first_ajax, $build_id_second_ajax, 'Build id changes on subsequent AJAX submissions');
|
||||
|
||||
// Emulate a push of the reload button and then repeat the test sequence
|
||||
// this time with a page loaded from the cache.
|
||||
$session->reload();
|
||||
$this->assertEquals($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
|
||||
$build_id_from_cache_initial = $this->getFormBuildId();
|
||||
$this->assertEquals($build_id_initial, $build_id_from_cache_initial, 'Build id is the same as on the first request');
|
||||
|
||||
// Changing the value of a select input element, triggers a AJAX
|
||||
// request/response.
|
||||
$session->getPage()->selectFieldOption('select', 'green');
|
||||
|
||||
// Wait for the DOM to update.
|
||||
$green_div2 = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('green')");
|
||||
$this->assertNotNull($green_div2, 'DOM update: After reload - the selected color DIV is green.');
|
||||
|
||||
$build_id_from_cache_first_ajax = $this->getFormBuildId();
|
||||
$this->assertNotEquals($build_id_from_cache_initial, $build_id_from_cache_first_ajax, 'Build id is changed in the simpletest-DOM on first AJAX submission');
|
||||
$this->assertNotEquals($build_id_first_ajax, $build_id_from_cache_first_ajax, 'Build id from first user is not reused');
|
||||
|
||||
// Changing the value of a select input element, triggers a AJAX
|
||||
// request/response.
|
||||
$session->getPage()->selectFieldOption('select', 'red');
|
||||
|
||||
// Wait for the DOM to update.
|
||||
$red_div2 = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('red')");
|
||||
$this->assertNotNull($red_div2, 'DOM update: After reload - the selected color DIV is red.');
|
||||
|
||||
$build_id_from_cache_second_ajax = $this->getFormBuildId();
|
||||
$this->assertNotEquals($build_id_from_cache_first_ajax, $build_id_from_cache_second_ajax, 'Build id changes on subsequent AJAX submissions');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that updating the text field trigger an AJAX request/response.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Ajax\ElementValidationTest::testAjaxElementValidation()
|
||||
*/
|
||||
public function testAjaxElementValidation() {
|
||||
$this->drupalGet('ajax_validation_test');
|
||||
// Changing the value of the textfield will trigger an AJAX
|
||||
// request/response.
|
||||
$this->getSession()->getPage()->fillField('drivertext', 'some dumb text');
|
||||
|
||||
// When the AJAX command updates the DOM a <ul> unsorted list
|
||||
// "message__list" structure will appear on the page echoing back the
|
||||
// "some dumb text" message.
|
||||
$placeholder = $this->assertSession()->waitForElement('css', "ul.messages__list li.messages__item em:contains('some dumb text')");
|
||||
$this->assertNotNull($placeholder, 'Message structure containing input data located.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests AJAX responses.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class AjaxTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['ajax_test'];
|
||||
|
||||
public function testAjaxWithAdminRoute() {
|
||||
\Drupal::service('theme_installer')->install(['stable', 'seven']);
|
||||
$theme_config = \Drupal::configFactory()->getEditable('system.theme');
|
||||
$theme_config->set('admin', 'seven');
|
||||
$theme_config->set('default', 'stable');
|
||||
$theme_config->save();
|
||||
|
||||
$account = $this->drupalCreateUser(['view the administration theme']);
|
||||
$this->drupalLogin($account);
|
||||
|
||||
// First visit the site directly via the URL. This should render it in the
|
||||
// admin theme.
|
||||
$this->drupalGet('admin/ajax-test/theme');
|
||||
$assert = $this->assertSession();
|
||||
$assert->pageTextContains('Current theme: seven');
|
||||
|
||||
// Now click the modal, which should also use the admin theme.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
$assert->pageTextNotContains('Current theme: stable');
|
||||
$this->clickLink('Link 8 (ajax)');
|
||||
$assert->assertWaitOnAjaxRequest();
|
||||
|
||||
$assert->pageTextContains('Current theme: stable');
|
||||
$assert->pageTextNotContains('Current theme: seven');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that AJAX loaded libraries are not retained between requests.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2647916
|
||||
*/
|
||||
public function testDrupalSettingsCachingRegression() {
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
$assert = $this->assertSession();
|
||||
$session = $this->getSession();
|
||||
|
||||
// Insert a fake library into the already loaded library settings.
|
||||
$fake_library = 'fakeLibrary/fakeLibrary';
|
||||
$session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';");
|
||||
|
||||
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
||||
// Test that the fake library is set.
|
||||
$this->assertContains($fake_library, $libraries);
|
||||
|
||||
// Click on the AJAX link.
|
||||
$this->clickLink('Link 8 (ajax)');
|
||||
$assert->assertWaitOnAjaxRequest();
|
||||
|
||||
// Test that the fake library is still set after the AJAX call.
|
||||
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
||||
$this->assertContains($fake_library, $libraries);
|
||||
|
||||
// Reload the page, this should reset the loaded libraries and remove the
|
||||
// fake library.
|
||||
$this->drupalGet('ajax-test/dialog');
|
||||
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
||||
$this->assertNotContains($fake_library, $libraries);
|
||||
|
||||
// Click on the AJAX link again, and the libraries should still not contain
|
||||
// the fake library.
|
||||
$this->clickLink('Link 8 (ajax)');
|
||||
$assert->assertWaitOnAjaxRequest();
|
||||
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
||||
$this->assertNotContains($fake_library, $libraries);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Core;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests for the machine name field.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class MachineNameTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* Required modules.
|
||||
*
|
||||
* Node is required because the machine name callback checks for
|
||||
* access_content.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'form_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$account = $this->drupalCreateUser([
|
||||
'access content',
|
||||
]);
|
||||
$this->drupalLogin($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that machine name field functions.
|
||||
*
|
||||
* Makes sure that the machine name field automatically provides a valid
|
||||
* machine name and that the manual editing mode functions.
|
||||
*/
|
||||
public function testMachineName() {
|
||||
// Visit the machine name test page which contains two machine name fields.
|
||||
$this->drupalGet('form-test/machine-name');
|
||||
|
||||
// Test values for conversion.
|
||||
$test_values = [
|
||||
[
|
||||
'input' => 'Test value !0-9@',
|
||||
'message' => 'A title that should be transliterated must be equal to the php generated machine name',
|
||||
'expected' => 'test_value_0_9_',
|
||||
],
|
||||
[
|
||||
'input' => 'Test value',
|
||||
'message' => 'A title that should not be transliterated must be equal to the php generated machine name',
|
||||
'expected' => 'test_value',
|
||||
],
|
||||
];
|
||||
|
||||
// Get page and session.
|
||||
$page = $this->getSession()->getPage();
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
// Get elements from the page.
|
||||
$title_1 = $page->findField('machine_name_1_label');
|
||||
$machine_name_1_field = $page->findField('machine_name_1');
|
||||
$machine_name_2_field = $page->findField('machine_name_2');
|
||||
$machine_name_1_wrapper = $machine_name_1_field->getParent();
|
||||
$machine_name_2_wrapper = $machine_name_2_field->getParent();
|
||||
$machine_name_1_value = $page->find('css', '#edit-machine-name-1-label-machine-name-suffix .machine-name-value');
|
||||
$machine_name_2_value = $page->find('css', '#edit-machine-name-2-label-machine-name-suffix .machine-name-value');
|
||||
$button_1 = $page->find('css', '#edit-machine-name-1-label-machine-name-suffix button.link');
|
||||
|
||||
// Assert both fields are initialized correctly.
|
||||
$this->assertNotEmpty($machine_name_1_value, 'Machine name field 1 must be initialized');
|
||||
$this->assertNotEmpty($machine_name_2_value, 'Machine name field 2 must be initialized');
|
||||
|
||||
// Field must be present for the rest of the test to work.
|
||||
if (empty($machine_name_1_value)) {
|
||||
$this->fail('Cannot finish test, missing machine name field');
|
||||
}
|
||||
|
||||
// Test each value for conversion to a machine name.
|
||||
foreach ($test_values as $test_info) {
|
||||
// Set the value for the field, triggering the machine name update.
|
||||
$title_1->setValue($test_info['input']);
|
||||
|
||||
// Wait the set timeout for fetching the machine name.
|
||||
$this->assertJsCondition('jQuery("#edit-machine-name-1-label-machine-name-suffix .machine-name-value").html() == "' . $test_info['expected'] . '"');
|
||||
|
||||
// Validate the generated machine name.
|
||||
$this->assertEquals($test_info['expected'], $machine_name_1_value->getHtml(), $test_info['message']);
|
||||
|
||||
// Validate the second machine name field is empty.
|
||||
$this->assertEmpty($machine_name_2_value->getHtml(), 'The second machine name field should still be empty');
|
||||
}
|
||||
|
||||
// Validate the machine name field is hidden. Elements are visually hidden
|
||||
// using positioning, isVisible() will therefore not work.
|
||||
$this->assertEquals(TRUE, $machine_name_1_wrapper->hasClass('visually-hidden'), 'The ID field must not be visible');
|
||||
$this->assertEquals(TRUE, $machine_name_2_wrapper->hasClass('visually-hidden'), 'The ID field must not be visible');
|
||||
|
||||
// Test switching back to the manual editing mode by clicking the edit link.
|
||||
$button_1->click();
|
||||
|
||||
// Validate the visibility of the machine name field.
|
||||
$this->assertEquals(FALSE, $machine_name_1_wrapper->hasClass('visually-hidden'), 'The ID field must now be visible');
|
||||
|
||||
// Validate the visibility of the second machine name field.
|
||||
$this->assertEquals(TRUE, $machine_name_2_wrapper->hasClass('visually-hidden'), 'The ID field must not be visible');
|
||||
|
||||
// Validate if the element contains the correct value.
|
||||
$this->assertEquals($test_values[1]['expected'], $machine_name_1_field->getValue(), 'The ID field value must be equal to the php generated machine name');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Core\Session;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\menu_link_content\Entity\MenuLinkContent;
|
||||
|
||||
/**
|
||||
* Tests that sessions don't expire.
|
||||
*
|
||||
* @group session
|
||||
*/
|
||||
class SessionTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['menu_link_content', 'block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$account = $this->drupalCreateUser();
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$menu_link_content = MenuLinkContent::create([
|
||||
'title' => 'Link to front page',
|
||||
'menu_name' => 'tools',
|
||||
'link' => ['uri' => 'route:<front>'],
|
||||
]);
|
||||
$menu_link_content->save();
|
||||
|
||||
$this->drupalPlaceBlock('system_menu_block:tools');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the session doesn't expire.
|
||||
*
|
||||
* Makes sure that drupal_valid_test_ua() works for multiple requests
|
||||
* performed by the Mink browser. The SIMPLETEST_USER_AGENT cookie must always
|
||||
* be valid.
|
||||
*/
|
||||
public function testSessionExpiration() {
|
||||
// Visit the front page and click the link back to the front page a large
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Dialog;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests the JavaScript functionality of the dialog position.
|
||||
*
|
||||
* @group dialog
|
||||
*/
|
||||
class DialogPositionTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* Tests if the dialog UI works properly with block layout page.
|
||||
*/
|
||||
public function testDialogOpenAndClose() {
|
||||
$admin_user = $this->drupalCreateUser(['administer blocks']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$session = $this->getSession();
|
||||
$assert_session = $this->assertSession();
|
||||
$page = $session->getPage();
|
||||
|
||||
// Open the dialog using the place block link.
|
||||
$placeBlockLink = $page->findLink('Place block');
|
||||
$this->assertTrue($placeBlockLink->isVisible(), 'Place block button exists.');
|
||||
$placeBlockLink->click();
|
||||
$assert_session->assertWaitOnAjaxRequest();
|
||||
$dialog = $page->find('css', '.ui-dialog');
|
||||
$this->assertTrue($dialog->isVisible(), 'Dialog is opened after clicking the Place block button.');
|
||||
|
||||
// Close the dialog again.
|
||||
$closeButton = $page->find('css', '.ui-dialog-titlebar-close');
|
||||
$closeButton->click();
|
||||
$assert_session->assertWaitOnAjaxRequest();
|
||||
$dialog = $page->find('css', '.ui-dialog');
|
||||
$this->assertNull($dialog, 'Dialog is closed after clicking the close button.');
|
||||
|
||||
// Resize the window. The test should pass after waiting for Javascript to
|
||||
// finish as no Javascript errors should have been triggered. If there were
|
||||
// javascript errors the test will fail on that.
|
||||
$session->resizeWindow(625, 625);
|
||||
$assert_session->assertWaitOnAjaxRequest();
|
||||
}
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\EntityReference;
|
||||
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\simpletest\ContentTypeCreationTrait;
|
||||
use Drupal\simpletest\NodeCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests the output of entity reference autocomplete widgets.
|
||||
*
|
||||
* @group entity_reference
|
||||
*/
|
||||
class EntityReferenceAutocompleteWidgetTest extends JavascriptTestBase {
|
||||
|
||||
use ContentTypeCreationTrait;
|
||||
use EntityReferenceTestTrait;
|
||||
use NodeCreationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a Content type and two test nodes.
|
||||
$this->createContentType(['type' => 'page']);
|
||||
$this->createNode(['title' => 'Test page']);
|
||||
$this->createNode(['title' => 'Page test']);
|
||||
|
||||
$user = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'create page content',
|
||||
]);
|
||||
$this->drupalLogin($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the default autocomplete widget return the correct results.
|
||||
*/
|
||||
public function testEntityReferenceAutocompleteWidget() {
|
||||
// Create an entity reference field and use the default 'CONTAINS' match
|
||||
// operator.
|
||||
$field_name = 'field_test';
|
||||
$this->createEntityReferenceField('node', 'page', $field_name, $field_name, 'node', 'default', ['target_bundles' => ['page']]);
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'entity_reference_autocomplete',
|
||||
'settings' => [
|
||||
'match_operator' => 'CONTAINS',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
// Visit the node add page.
|
||||
$this->drupalGet('node/add/page');
|
||||
$page = $this->getSession()->getPage();
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
$autocomplete_field = $page->findField($field_name . '[0][target_id]');
|
||||
$autocomplete_field->setValue('Test');
|
||||
$this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
|
||||
$assert_session->waitOnAutocomplete();
|
||||
|
||||
$results = $page->findAll('css', '.ui-autocomplete li');
|
||||
|
||||
$this->assertCount(2, $results);
|
||||
$assert_session->pageTextContains('Test page');
|
||||
$assert_session->pageTextContains('Page test');
|
||||
|
||||
// Now switch the autocomplete widget to the 'STARTS_WITH' match operator.
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'entity_reference_autocomplete',
|
||||
'settings' => [
|
||||
'match_operator' => 'STARTS_WITH',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('node/add/page');
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$autocomplete_field = $page->findField($field_name . '[0][target_id]');
|
||||
$autocomplete_field->setValue('Test');
|
||||
$this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' ');
|
||||
$assert_session->waitOnAutocomplete();
|
||||
|
||||
$results = $page->findAll('css', '.ui-autocomplete li');
|
||||
|
||||
$this->assertCount(1, $results);
|
||||
$assert_session->pageTextContains('Test page');
|
||||
$assert_session->pageTextNotContains('Page test');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Behat\Mink\Exception\ElementHtmlException;
|
||||
use Behat\Mink\Exception\ElementNotFoundException;
|
||||
use Behat\Mink\Exception\UnsupportedDriverActionException;
|
||||
use Drupal\Tests\WebAssert;
|
||||
|
||||
/**
|
||||
@@ -22,10 +26,344 @@ class JSWebAssert extends WebAssert {
|
||||
* be displayed.
|
||||
*/
|
||||
public function assertWaitOnAjaxRequest($timeout = 10000, $message = 'Unable to complete AJAX request.') {
|
||||
$result = $this->session->wait($timeout, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
|
||||
$condition = <<<JS
|
||||
(function() {
|
||||
function isAjaxing(instance) {
|
||||
return instance && instance.ajaxing === true;
|
||||
}
|
||||
return (
|
||||
// Assert no AJAX request is running (via jQuery or Drupal) and no
|
||||
// animation is running.
|
||||
(typeof jQuery === 'undefined' || (jQuery.active === 0 && jQuery(':animated').length === 0)) &&
|
||||
(typeof Drupal === 'undefined' || typeof Drupal.ajax === 'undefined' || !Drupal.ajax.instances.some(isAjaxing))
|
||||
);
|
||||
}());
|
||||
JS;
|
||||
$result = $this->session->wait($timeout, $condition);
|
||||
if (!$result) {
|
||||
throw new \RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the specified selector and returns it when available.
|
||||
*
|
||||
* @param string $selector
|
||||
* The selector engine name. See ElementInterface::findAll() for the
|
||||
* supported selectors.
|
||||
* @param string|array $locator
|
||||
* The selector locator.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*
|
||||
* @see \Behat\Mink\Element\ElementInterface::findAll()
|
||||
*/
|
||||
public function waitForElement($selector, $locator, $timeout = 10000) {
|
||||
$page = $this->session->getPage();
|
||||
|
||||
$result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) {
|
||||
return $page->find($selector, $locator);
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the specified selector and returns it when available and visible.
|
||||
*
|
||||
* @param string $selector
|
||||
* The selector engine name. See ElementInterface::findAll() for the
|
||||
* supported selectors.
|
||||
* @param string|array $locator
|
||||
* The selector locator.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found and visible, NULL if not.
|
||||
*
|
||||
* @see \Behat\Mink\Element\ElementInterface::findAll()
|
||||
*/
|
||||
public function waitForElementVisible($selector, $locator, $timeout = 10000) {
|
||||
$page = $this->session->getPage();
|
||||
|
||||
$result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) {
|
||||
$element = $page->find($selector, $locator);
|
||||
if (!empty($element) && $element->isVisible()) {
|
||||
return $element;
|
||||
}
|
||||
return NULL;
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* Waits for a button (input[type=submit|image|button|reset], button) with
|
||||
* specified locator and returns it.
|
||||
*
|
||||
* @param string $locator
|
||||
* The button ID, value or alt string.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForButton($locator, $timeout = 10000) {
|
||||
return $this->waitForElement('named', ['button', $locator], $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a link with specified locator and returns it when available.
|
||||
*
|
||||
* @param string $locator
|
||||
* The link ID, title, text or image alt.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForLink($locator, $timeout = 10000) {
|
||||
return $this->waitForElement('named', ['link', $locator], $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a field with specified locator and returns it when available.
|
||||
*
|
||||
* @param string $locator
|
||||
* The input ID, name or label for the field (input, textarea, select).
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForField($locator, $timeout = 10000) {
|
||||
return $this->waitForElement('named', ['field', $locator], $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for an element by its id and returns it when available.
|
||||
*
|
||||
* @param string $id
|
||||
* The element ID.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForId($id, $timeout = 10000) {
|
||||
return $this->waitForElement('named', ['id', $id], $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the jQuery autocomplete delay duration.
|
||||
*
|
||||
* @see https://api.jqueryui.com/autocomplete/#option-delay
|
||||
*/
|
||||
public function waitOnAutocomplete() {
|
||||
// Wait for the autocomplete to be visible.
|
||||
return $this->waitForElementVisible('css', '.ui-autocomplete li');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a node, or it's specific corner, is visible in the viewport.
|
||||
*
|
||||
* Note: Always set the viewport size. This can be done with a PhantomJS
|
||||
* startup parameter or in your test with \Behat\Mink\Session->resizeWindow().
|
||||
* Drupal CI Javascript tests by default use a viewport of 1024x768px.
|
||||
*
|
||||
* @param string $selector_type
|
||||
* The element selector type (CSS, XPath).
|
||||
* @param string|array $selector
|
||||
* The element selector. Note: the first found element is used.
|
||||
* @param bool|string $corner
|
||||
* (Optional) The corner to test:
|
||||
* topLeft, topRight, bottomRight, bottomLeft.
|
||||
* Or FALSE to check the complete element (default).
|
||||
* @param string $message
|
||||
* (optional) A message for the exception.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementHtmlException
|
||||
* When the element doesn't exist.
|
||||
* @throws \Behat\Mink\Exception\ElementNotFoundException
|
||||
* When the element is not visible in the viewport.
|
||||
*/
|
||||
public function assertVisibleInViewport($selector_type, $selector, $corner = FALSE, $message = 'Element is not visible in the viewport.') {
|
||||
$node = $this->session->getPage()->find($selector_type, $selector);
|
||||
if ($node === NULL) {
|
||||
if (is_array($selector)) {
|
||||
$selector = implode(' ', $selector);
|
||||
}
|
||||
throw new ElementNotFoundException($this->session->getDriver(), 'element', $selector_type, $selector);
|
||||
}
|
||||
|
||||
// Check if the node is visible on the page, which is a prerequisite of
|
||||
// being visible in the viewport.
|
||||
if (!$node->isVisible()) {
|
||||
throw new ElementHtmlException($message, $this->session->getDriver(), $node);
|
||||
}
|
||||
|
||||
$result = $this->checkNodeVisibilityInViewport($node, $corner);
|
||||
|
||||
if (!$result) {
|
||||
throw new ElementHtmlException($message, $this->session->getDriver(), $node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a node, or its specific corner, is not visible in the viewport.
|
||||
*
|
||||
* Note: the node should exist in the page, otherwise this assertion fails.
|
||||
*
|
||||
* @param string $selector_type
|
||||
* The element selector type (CSS, XPath).
|
||||
* @param string|array $selector
|
||||
* The element selector. Note: the first found element is used.
|
||||
* @param bool|string $corner
|
||||
* (Optional) Corner to test: topLeft, topRight, bottomRight, bottomLeft.
|
||||
* Or FALSE to check the complete element (default).
|
||||
* @param string $message
|
||||
* (optional) A message for the exception.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementHtmlException
|
||||
* When the element doesn't exist.
|
||||
* @throws \Behat\Mink\Exception\ElementNotFoundException
|
||||
* When the element is not visible in the viewport.
|
||||
*
|
||||
* @see \Drupal\FunctionalJavascriptTests\JSWebAssert::assertVisibleInViewport()
|
||||
*/
|
||||
public function assertNotVisibleInViewport($selector_type, $selector, $corner = FALSE, $message = 'Element is visible in the viewport.') {
|
||||
$node = $this->session->getPage()->find($selector_type, $selector);
|
||||
if ($node === NULL) {
|
||||
if (is_array($selector)) {
|
||||
$selector = implode(' ', $selector);
|
||||
}
|
||||
throw new ElementNotFoundException($this->session->getDriver(), 'element', $selector_type, $selector);
|
||||
}
|
||||
|
||||
$result = $this->checkNodeVisibilityInViewport($node, $corner);
|
||||
|
||||
if ($result) {
|
||||
throw new ElementHtmlException($message, $this->session->getDriver(), $node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the visibility of a node, or it's specific corner.
|
||||
*
|
||||
* @param \Behat\Mink\Element\NodeElement $node
|
||||
* A valid node.
|
||||
* @param bool|string $corner
|
||||
* (Optional) Corner to test: topLeft, topRight, bottomRight, bottomLeft.
|
||||
* Or FALSE to check the complete element (default).
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the node is visible in the viewport, FALSE otherwise.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\UnsupportedDriverActionException
|
||||
* When an invalid corner specification is given.
|
||||
*/
|
||||
private function checkNodeVisibilityInViewport(NodeElement $node, $corner = FALSE) {
|
||||
$xpath = $node->getXpath();
|
||||
|
||||
// Build the Javascript to test if the complete element or a specific corner
|
||||
// is in the viewport.
|
||||
switch ($corner) {
|
||||
case 'topLeft':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.top >= 0 &&
|
||||
r.top <= ly &&
|
||||
r.left >= 0 &&
|
||||
r.left <= lx
|
||||
)
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case 'topRight':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.top >= 0 &&
|
||||
r.top <= ly &&
|
||||
r.right >= 0 &&
|
||||
r.right <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case 'bottomRight':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.bottom >= 0 &&
|
||||
r.bottom <= ly &&
|
||||
r.right >= 0 &&
|
||||
r.right <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case 'bottomLeft':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.bottom >= 0 &&
|
||||
r.bottom <= ly &&
|
||||
r.left >= 0 &&
|
||||
r.left <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case FALSE:
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.top >= 0 &&
|
||||
r.left >= 0 &&
|
||||
r.bottom <= ly &&
|
||||
r.right <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
// Throw an exception if an invalid corner parameter is given.
|
||||
default:
|
||||
throw new UnsupportedDriverActionException($corner, $this->session->getDriver());
|
||||
}
|
||||
|
||||
// Build the full Javascript test. The shared logic gets the corner
|
||||
// specific test logic injected.
|
||||
$full_javascript_visibility_test = <<<JS
|
||||
(function(t){
|
||||
var w = window,
|
||||
d = document,
|
||||
e = d.documentElement,
|
||||
n = d.evaluate("$xpath", d, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue,
|
||||
r = n.getBoundingClientRect(),
|
||||
lx = (w.innerWidth || e.clientWidth),
|
||||
ly = (w.innerHeight || e.clientHeight);
|
||||
|
||||
return t(r, lx, ly);
|
||||
}($test_javascript_function));
|
||||
JS;
|
||||
|
||||
// Check the visibility by injecting and executing the full Javascript test
|
||||
// script in the page.
|
||||
return $this->session->evaluateScript($full_javascript_visibility_test);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ abstract class JavascriptTestBase extends BrowserTestBase {
|
||||
catch (DeadClient $e) {
|
||||
$this->markTestSkipped('PhantomJS is either not installed or not running. Start it via phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768&');
|
||||
}
|
||||
catch (Exception $e) {
|
||||
catch (\Exception $e) {
|
||||
$this->markTestSkipped('An unexpected error occurred while starting Mink: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -47,16 +47,18 @@ abstract class JavascriptTestBase extends BrowserTestBase {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function tearDown() {
|
||||
// Wait for all requests to finish. It is possible that an AJAX request is
|
||||
// still on-going.
|
||||
$result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
|
||||
if (!$result) {
|
||||
// If the wait is unsuccessful, there may still be an AJAX request in
|
||||
// progress. If we tear down now, then this AJAX request may fail with
|
||||
// missing database tables, because tear down will have removed them. Rather
|
||||
// than allow it to fail, throw an explicit exception now explaining what
|
||||
// the problem is.
|
||||
throw new \RuntimeException('Unfinished AJAX requests whilst tearing down a test');
|
||||
if ($this->mink) {
|
||||
// Wait for all requests to finish. It is possible that an AJAX request is
|
||||
// still on-going.
|
||||
$result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
|
||||
if (!$result) {
|
||||
// If the wait is unsuccessful, there may still be an AJAX request in
|
||||
// progress. If we tear down now, then this AJAX request may fail with
|
||||
// missing database tables, because tear down will have removed them.
|
||||
// Rather than allow it to fail, throw an explicit exception now
|
||||
// explaining what the problem is.
|
||||
throw new \RuntimeException('Unfinished AJAX requests while tearing down a test');
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
@@ -97,7 +99,7 @@ abstract class JavascriptTestBase extends BrowserTestBase {
|
||||
* @param string $condition
|
||||
* JS condition to wait until it becomes TRUE.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 1000.
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. If left blank, a
|
||||
* default message will be displayed.
|
||||
@@ -106,7 +108,7 @@ abstract class JavascriptTestBase extends BrowserTestBase {
|
||||
*
|
||||
* @see \Behat\Mink\Driver\DriverInterface::evaluateScript()
|
||||
*/
|
||||
protected function assertJsCondition($condition, $timeout = 1000, $message = '') {
|
||||
protected function assertJsCondition($condition, $timeout = 10000, $message = '') {
|
||||
$message = $message ?: "Javascript condition met:\n" . $condition;
|
||||
$result = $this->getSession()->getDriver()->wait($timeout, $condition);
|
||||
$this->assertTrue($result, $message);
|
||||
@@ -143,4 +145,28 @@ abstract class JavascriptTestBase extends BrowserTestBase {
|
||||
return new JSWebAssert($this->getSession($name), $this->baseUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current Drupal javascript settings and parses into an array.
|
||||
*
|
||||
* Unlike BrowserTestBase::getDrupalSettings(), this implementation reads the
|
||||
* current values of drupalSettings, capturing all changes made via javascript
|
||||
* after the page was loaded.
|
||||
*
|
||||
* @return array
|
||||
* The Drupal javascript settings array.
|
||||
*
|
||||
* @see \Drupal\Tests\BrowserTestBase::getDrupalSettings()
|
||||
*/
|
||||
protected function getDrupalSettings() {
|
||||
$script = <<<EndOfScript
|
||||
(function () {
|
||||
if (typeof drupalSettings !== 'undefined') {
|
||||
return drupalSettings;
|
||||
}
|
||||
})();
|
||||
EndOfScript;
|
||||
|
||||
return $this->getSession()->evaluateScript($script) ?: [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Tests;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests for the JSWebAssert class.
|
||||
*
|
||||
* @group javascript
|
||||
*/
|
||||
class JSWebAssertTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* Required modules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['js_webassert_test'];
|
||||
|
||||
/**
|
||||
* Tests that JSWebAssert assertions work correctly.
|
||||
*/
|
||||
public function testJsWebAssert() {
|
||||
$this->drupalGet('js_webassert_test_form');
|
||||
|
||||
$session = $this->getSession();
|
||||
$assert_session = $this->assertSession();
|
||||
$page = $session->getPage();
|
||||
|
||||
$test_button = $page->findButton('Add button');
|
||||
$test_link = $page->findButton('Add link');
|
||||
$test_field = $page->findButton('Add field');
|
||||
$test_id = $page->findButton('Add ID');
|
||||
$test_wait_on_ajax = $page->findButton('Test assertWaitOnAjaxRequest');
|
||||
$test_wait_on_element_visible = $page->findButton('Test waitForElementVisible');
|
||||
|
||||
// Test the wait...() methods by first checking the fields aren't available
|
||||
// and then are available after the wait method.
|
||||
$result = $page->findButton('Added button');
|
||||
$this->assertEmpty($result);
|
||||
$test_button->click();
|
||||
$result = $assert_session->waitForButton('Added button');
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertTrue($result instanceof NodeElement);
|
||||
|
||||
$result = $page->findLink('Added link');
|
||||
$this->assertEmpty($result);
|
||||
$test_link->click();
|
||||
$result = $assert_session->waitForLink('Added link');
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertTrue($result instanceof NodeElement);
|
||||
|
||||
$result = $page->findField('added_field');
|
||||
$this->assertEmpty($result);
|
||||
$test_field->click();
|
||||
$result = $assert_session->waitForField('added_field');
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertTrue($result instanceof NodeElement);
|
||||
|
||||
$result = $page->findById('js_webassert_test_field_id');
|
||||
$this->assertEmpty($result);
|
||||
$test_id->click();
|
||||
$result = $assert_session->waitForId('js_webassert_test_field_id');
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertTrue($result instanceof NodeElement);
|
||||
|
||||
// Test waitOnAjaxRequest. Verify the element is available after the wait
|
||||
// and the behaviors have run on completing by checking the value.
|
||||
$result = $page->findField('test_assert_wait_on_ajax_input');
|
||||
$this->assertEmpty($result);
|
||||
$test_wait_on_ajax->click();
|
||||
$assert_session->assertWaitOnAjaxRequest();
|
||||
$result = $page->findField('test_assert_wait_on_ajax_input');
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertTrue($result instanceof NodeElement);
|
||||
$this->assertEquals('js_webassert_test', $result->getValue());
|
||||
|
||||
$result = $page->findButton('Added WaitForElementVisible');
|
||||
$this->assertEmpty($result);
|
||||
$test_wait_on_element_visible->click();
|
||||
$result = $assert_session->waitForElementVisible('named', ['button', 'Added WaitForElementVisible']);
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertTrue($result instanceof NodeElement);
|
||||
$this->assertEquals(TRUE, $result->isVisible());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
namespace Drupal\FunctionalTests;
|
||||
|
||||
use Behat\Mink\Exception\ElementNotFoundException;
|
||||
use Behat\Mink\Exception\ExpectationException;
|
||||
use Behat\Mink\Selector\Xpath\Escaper;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\KernelTests\AssertLegacyTrait as BaseAssertLegacyTrait;
|
||||
|
||||
/**
|
||||
@@ -53,10 +58,17 @@ trait AssertLegacyTrait {
|
||||
* Plain text to look for.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->pageTextContains() or
|
||||
* $this->assertSession()->responseContains() instead.
|
||||
* Use instead:
|
||||
* - $this->assertSession()->responseContains() for non-HTML responses,
|
||||
* like XML or Json.
|
||||
* - $this->assertSession()->pageTextContains() for HTML responses. Unlike
|
||||
* the deprecated assertText(), the passed text should be HTML decoded,
|
||||
* exactly as a human sees it in the browser.
|
||||
*/
|
||||
protected function assertText($text) {
|
||||
// Cast MarkupInterface to string.
|
||||
$text = (string) $text;
|
||||
|
||||
$content_type = $this->getSession()->getResponseHeader('Content-type');
|
||||
// In case of a Non-HTML response (example: XML) check the original
|
||||
// response.
|
||||
@@ -64,7 +76,7 @@ trait AssertLegacyTrait {
|
||||
$this->assertSession()->responseContains($text);
|
||||
}
|
||||
else {
|
||||
$this->assertSession()->pageTextContains($text);
|
||||
$this->assertTextHelper($text, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +90,17 @@ trait AssertLegacyTrait {
|
||||
* Plain text to look for.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->pageTextNotContains() or
|
||||
* $this->assertSession()->responseNotContains() instead.
|
||||
* Use instead:
|
||||
* - $this->assertSession()->responseNotContains() for non-HTML responses,
|
||||
* like XML or Json.
|
||||
* - $this->assertSession()->pageTextNotContains() for HTML responses.
|
||||
* Unlike the deprecated assertNoText(), the passed text should be HTML
|
||||
* decoded, exactly as a human sees it in the browser.
|
||||
*/
|
||||
protected function assertNoText($text) {
|
||||
// Cast MarkupInterface to string.
|
||||
$text = (string) $text;
|
||||
|
||||
$content_type = $this->getSession()->getResponseHeader('Content-type');
|
||||
// In case of a Non-HTML response (example: XML) check the original
|
||||
// response.
|
||||
@@ -89,10 +108,40 @@ trait AssertLegacyTrait {
|
||||
$this->assertSession()->responseNotContains($text);
|
||||
}
|
||||
else {
|
||||
$this->assertSession()->pageTextNotContains($text);
|
||||
$this->assertTextHelper($text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for assertText and assertNoText.
|
||||
*
|
||||
* @param string $text
|
||||
* Plain text to look for.
|
||||
* @param bool $not_exists
|
||||
* (optional) TRUE if this text should not exist, FALSE if it should.
|
||||
* Defaults to TRUE.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE on pass, FALSE on fail.
|
||||
*/
|
||||
protected function assertTextHelper($text, $not_exists = TRUE) {
|
||||
$args = ['@text' => $text];
|
||||
$message = $not_exists ? new FormattableMarkup('"@text" not found', $args) : new FormattableMarkup('"@text" found', $args);
|
||||
|
||||
$raw_content = $this->getSession()->getPage()->getContent();
|
||||
// Trying to simulate what the user sees, given that it removes all text
|
||||
// inside the head tags, removes inline Javascript, fix all HTML entities,
|
||||
// removes dangerous protocols and filtering out all HTML tags, as they are
|
||||
// not visible in a normal browser.
|
||||
$raw_content = preg_replace('@<head>(.+?)</head>@si', '', $raw_content);
|
||||
$page_text = Xss::filter($raw_content, []);
|
||||
|
||||
$actual = $not_exists == (strpos($page_text, (string) $text) === FALSE);
|
||||
$this->assertTrue($actual, $message);
|
||||
|
||||
return $actual;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes if the text is found ONLY ONCE on the text version of the page.
|
||||
*
|
||||
@@ -181,24 +230,27 @@ trait AssertLegacyTrait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a field exists with the given name and value.
|
||||
* Asserts that a field does not exist with the given name and value.
|
||||
*
|
||||
* @param string $name
|
||||
* Name of field to assert.
|
||||
* @param string $value
|
||||
* (optional) Value of the field to assert. You may pass in NULL (default)
|
||||
* to skip checking the actual value, while still checking that the field
|
||||
* exists.
|
||||
* (optional) Value for the field, to assert that the field's value on the
|
||||
* page does not match it. You may pass in NULL to skip checking the
|
||||
* value, while still checking that the field does not exist. However, the
|
||||
* default value ('') asserts that the field value is not an empty string.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldNotExists() or
|
||||
* $this->assertSession()->fieldValueNotEquals() instead.
|
||||
*/
|
||||
protected function assertNoFieldByName($name, $value = NULL) {
|
||||
$this->assertSession()->fieldNotExists($name);
|
||||
if ($value !== NULL) {
|
||||
protected function assertNoFieldByName($name, $value = '') {
|
||||
if ($this->getSession()->getPage()->findField($name) && isset($value)) {
|
||||
$this->assertSession()->fieldValueNotEquals($name, (string) $value);
|
||||
}
|
||||
else {
|
||||
$this->assertSession()->fieldNotExists($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,12 +264,23 @@ trait AssertLegacyTrait {
|
||||
* However, the default value ('') asserts that the field value is an empty
|
||||
* string.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementNotFoundException
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldExists() or
|
||||
* $this->assertSession()->fieldValueEquals() instead.
|
||||
*/
|
||||
protected function assertFieldById($id, $value = NULL) {
|
||||
$this->assertFieldByName($id, $value);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,7 +393,7 @@ trait AssertLegacyTrait {
|
||||
* Link position counting from zero.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->linkByHref() instead.
|
||||
* Use $this->assertSession()->linkByHrefExists() instead.
|
||||
*/
|
||||
protected function assertLinkByHref($href, $index = 0) {
|
||||
$this->assertSession()->linkByHrefExists($href, $index);
|
||||
@@ -360,16 +423,26 @@ trait AssertLegacyTrait {
|
||||
* while still checking that the field doesn't exist. However, the default
|
||||
* value ('') asserts that the field value is not an empty string.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ExpectationException
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->fieldNotExists() or
|
||||
* $this->assertSession()->fieldValueNotEquals() instead.
|
||||
*/
|
||||
protected function assertNoFieldById($id, $value = '') {
|
||||
if ($this->getSession()->getPage()->findField($id)) {
|
||||
$this->assertSession()->fieldValueNotEquals($id, (string) $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;
|
||||
}
|
||||
else {
|
||||
$this->assertSession()->fieldNotExists($id);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +474,21 @@ trait AssertLegacyTrait {
|
||||
return $this->assertSession()->optionExists($id, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a select option with the visible text exists.
|
||||
*
|
||||
* @param string $id
|
||||
* The ID of the select field to assert.
|
||||
* @param string $text
|
||||
* The text for the option tag to assert.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->optionExists() instead.
|
||||
*/
|
||||
protected function assertOptionByText($id, $text) {
|
||||
return $this->assertSession()->optionExists($id, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a select option does NOT exist in the current page.
|
||||
*
|
||||
@@ -463,6 +551,102 @@ trait AssertLegacyTrait {
|
||||
$this->assertSession()->checkboxNotChecked($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a field exists in the current page by the given XPath.
|
||||
*
|
||||
* @param string $xpath
|
||||
* XPath used to find the field.
|
||||
* @param string $value
|
||||
* (optional) Value of the field to assert. You may pass in NULL (default)
|
||||
* to skip checking the actual value, while still checking that the field
|
||||
* exists.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages with t().
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->xpath() instead and check the values directly in the test.
|
||||
*/
|
||||
protected function assertFieldByXPath($xpath, $value = NULL, $message = '') {
|
||||
$fields = $this->xpath($xpath);
|
||||
|
||||
$this->assertFieldsByValue($fields, $value, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a field does not exist or its value does not match, by XPath.
|
||||
*
|
||||
* @param string $xpath
|
||||
* XPath used to find the field.
|
||||
* @param string $value
|
||||
* (optional) Value of the field, to assert that the field's value on the
|
||||
* page does not match it.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages with t().
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->assertFalse($fields && $found, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a field exists in the current page with a given Xpath result.
|
||||
*
|
||||
* @param \Behat\Mink\Element\NodeElement[] $fields
|
||||
* Xml elements.
|
||||
* @param string $value
|
||||
* (optional) Value of the field to assert. You may pass in NULL (default) to skip
|
||||
* checking the actual value, while still checking that the field exists.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages with t().
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Iterate over the fields yourself instead and directly check the values in
|
||||
* the test.
|
||||
*/
|
||||
protected function assertFieldsByValue($fields, $value = NULL, $message = '') {
|
||||
// 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) {
|
||||
// Input element with correct value.
|
||||
$found = TRUE;
|
||||
}
|
||||
elseif ($field->find('xpath', '//option[@value = ' . (new Escaper())->escapeLiteral($value) . ' and @selected = "selected"]')) {
|
||||
// Select element with an option.
|
||||
$found = TRUE;
|
||||
}
|
||||
elseif ($field->getText() == $value) {
|
||||
// Text area with correct text.
|
||||
$found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->assertTrue($fields && $found, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes if the raw text IS found escaped on the loaded page, fail otherwise.
|
||||
*
|
||||
@@ -506,6 +690,22 @@ trait AssertLegacyTrait {
|
||||
$this->assertSession()->responseMatches($pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a pass if the Perl regex pattern is not found in the raw content.
|
||||
*
|
||||
* @param string $pattern
|
||||
* Perl regex to look for including the regex delimiters.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->responseNotMatches() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2864262
|
||||
*/
|
||||
protected function assertNoPattern($pattern) {
|
||||
@trigger_error('assertNoPattern() is deprecated and scheduled for removal in Drupal 9.0.0. Use $this->assertSession()->responseNotMatches($pattern) instead. See https://www.drupal.org/node/2864262.', E_USER_DEPRECATED);
|
||||
$this->assertSession()->responseNotMatches($pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts whether an expected cache tag was present in the last response.
|
||||
*
|
||||
@@ -519,6 +719,21 @@ trait AssertLegacyTrait {
|
||||
$this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', $expected_cache_tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that current response header equals value.
|
||||
*
|
||||
* @param string $name
|
||||
* Name of header to assert.
|
||||
* @param string $value
|
||||
* Value of the header to assert
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->responseHeaderEquals() instead.
|
||||
*/
|
||||
protected function assertHeader($name, $value) {
|
||||
$this->assertSession()->responseHeaderEquals($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns WebAssert object.
|
||||
*
|
||||
@@ -553,8 +768,19 @@ trait AssertLegacyTrait {
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->assertSession()->buildXPathQuery() instead.
|
||||
*/
|
||||
protected function buildXPathQuery($xpath, array $args = array()) {
|
||||
protected function buildXPathQuery($xpath, array $args = []) {
|
||||
return $this->assertSession()->buildXPathQuery($xpath, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current raw content.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use $this->getSession()->getPage()->getContent() instead.
|
||||
*/
|
||||
protected function getRawContent() {
|
||||
@trigger_error('AssertLegacyTrait::getRawContent() is scheduled for removal in Drupal 9.0.0. Use $this->getSession()->getPage()->getContent() instead.', E_USER_DEPRECATED);
|
||||
return $this->getSession()->getPage()->getContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,520 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests;
|
||||
|
||||
use Behat\Mink\Exception\ExpectationException;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Tests BrowserTestBase functionality.
|
||||
*
|
||||
* @group browsertestbase
|
||||
*/
|
||||
class BrowserTestBaseTest extends BrowserTestBase {
|
||||
|
||||
use CronRunTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['test_page_test', 'form_test', 'system_test'];
|
||||
|
||||
/**
|
||||
* Tests basic page test.
|
||||
*/
|
||||
public function testGoTo() {
|
||||
$account = $this->drupalCreateUser();
|
||||
$this->drupalLogin($account);
|
||||
|
||||
// Visit a Drupal page that requires login.
|
||||
$this->drupalGet('test-page');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
|
||||
// Test page contains some text.
|
||||
$this->assertSession()->pageTextContains('Test page text.');
|
||||
|
||||
// Check that returned plain text is correct.
|
||||
$text = $this->getTextContent();
|
||||
$this->assertContains('Test page text.', $text);
|
||||
$this->assertNotContains('</html>', $text);
|
||||
|
||||
// Response includes cache tags that we can assert.
|
||||
$this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Tags', 'http_response rendered');
|
||||
|
||||
// Test that we can read the JS settings.
|
||||
$js_settings = $this->getDrupalSettings();
|
||||
$this->assertSame('azAZ09();.,\\\/-_{}', $js_settings['test-setting']);
|
||||
|
||||
// Test drupalGet with a url object.
|
||||
$url = Url::fromRoute('test_page_test.render_title');
|
||||
$this->drupalGet($url);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
|
||||
// Test page contains some text.
|
||||
$this->assertSession()->pageTextContains('Hello Drupal');
|
||||
|
||||
// Test that setting headers with drupalGet() works.
|
||||
$this->drupalGet('system-test/header', [], [
|
||||
'Test-Header' => 'header value',
|
||||
]);
|
||||
$returned_header = $this->getSession()->getResponseHeader('Test-Header');
|
||||
$this->assertSame('header value', $returned_header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests basic form functionality.
|
||||
*/
|
||||
public function testForm() {
|
||||
// Ensure the proper response code for a _form route.
|
||||
$this->drupalGet('form-test/object-builder');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
|
||||
// Ensure the form and text field exist.
|
||||
$this->assertSession()->elementExists('css', 'form#form-test-form-test-object');
|
||||
$this->assertSession()->fieldExists('bananas');
|
||||
|
||||
// Check that the hidden field exists and has a specific value.
|
||||
$this->assertSession()->hiddenFieldExists('strawberry');
|
||||
$this->assertSession()->hiddenFieldExists('red');
|
||||
$this->assertSession()->hiddenFieldExists('redstrawberryhiddenfield');
|
||||
$this->assertSession()->hiddenFieldValueNotEquals('strawberry', 'brown');
|
||||
$this->assertSession()->hiddenFieldValueEquals('strawberry', 'red');
|
||||
|
||||
// Check that a hidden field does not exist.
|
||||
$this->assertSession()->hiddenFieldNotExists('bananas');
|
||||
$this->assertSession()->hiddenFieldNotExists('pineapple');
|
||||
|
||||
$edit = ['bananas' => 'green'];
|
||||
$this->submitForm($edit, 'Save', 'form-test-form-test-object');
|
||||
|
||||
$config_factory = $this->container->get('config.factory');
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertSame('green', $value);
|
||||
|
||||
// Test drupalPostForm().
|
||||
$edit = ['bananas' => 'red'];
|
||||
$this->drupalPostForm('form-test/object-builder', $edit, 'Save');
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests clickLink() functionality.
|
||||
*/
|
||||
public function testClickLink() {
|
||||
$this->drupalGet('test-page');
|
||||
$this->clickLink('Visually identical test links');
|
||||
$this->assertContains('user/login', $this->getSession()->getCurrentUrl());
|
||||
$this->drupalGet('test-page');
|
||||
$this->clickLink('Visually identical test links', 0);
|
||||
$this->assertContains('user/login', $this->getSession()->getCurrentUrl());
|
||||
$this->drupalGet('test-page');
|
||||
$this->clickLink('Visually identical test links', 1);
|
||||
$this->assertContains('user/register', $this->getSession()->getCurrentUrl());
|
||||
}
|
||||
|
||||
public function testError() {
|
||||
$this->setExpectedException('\Exception', 'User notice: foo');
|
||||
$this->drupalGet('test-error');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests linkExists() with pipe character (|) in locator.
|
||||
*
|
||||
* @see \Drupal\Tests\WebAssert::linkExists()
|
||||
*/
|
||||
public function testPipeCharInLocator() {
|
||||
$this->drupalGet('test-pipe-char');
|
||||
$this->assertSession()->linkExists('foo|bar|baz');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy text asserts.
|
||||
*/
|
||||
public function testLegacyTextAsserts() {
|
||||
$this->drupalGet('test-encoded');
|
||||
$dangerous = 'Bad html <script>alert(123);</script>';
|
||||
$sanitized = Html::escape($dangerous);
|
||||
$this->assertNoText($dangerous);
|
||||
$this->assertText($sanitized);
|
||||
|
||||
// Test getRawContent().
|
||||
$this->assertSame($this->getSession()->getPage()->getContent(), $this->getRawContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts which use xpath directly.
|
||||
*/
|
||||
public function testLegacyXpathAsserts() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
$this->assertFieldsByValue($this->xpath("//h1[@class = 'page-title']"), NULL);
|
||||
$this->assertFieldsByValue($this->xpath('//table/tbody/tr[2]/td[1]'), 'one');
|
||||
$this->assertFieldByXPath('//table/tbody/tr[2]/td[1]', 'one');
|
||||
|
||||
$this->assertFieldsByValue($this->xpath("//input[@id = 'edit-name']"), 'Test name');
|
||||
$this->assertFieldByXPath("//input[@id = 'edit-name']", 'Test name');
|
||||
$this->assertFieldsByValue($this->xpath("//select[@id = 'edit-options']"), '2');
|
||||
$this->assertFieldByXPath("//select[@id = 'edit-options']", '2');
|
||||
|
||||
$this->assertNoFieldByXPath('//notexisting');
|
||||
$this->assertNoFieldByXPath("//input[@id = 'edit-name']", 'wrong value');
|
||||
|
||||
// Test that the assertion fails correctly.
|
||||
try {
|
||||
$this->assertFieldByXPath("//input[@id = 'notexisting']");
|
||||
$this->fail('The "notexisting" field was found.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('assertFieldByXPath correctly failed. The "notexisting" field was not found.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->assertNoFieldByXPath("//input[@id = 'edit-name']");
|
||||
$this->fail('The "edit-name" field was not found.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('assertNoFieldByXPath correctly failed. The "edit-name" field was found.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->assertFieldsByValue($this->xpath("//input[@id = 'edit-name']"), 'not the value');
|
||||
$this->fail('The "edit-name" field is found with the value "not the value".');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('The "edit-name" field is not found with the value "not the value".');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts using textfields.
|
||||
*/
|
||||
public function testLegacyFieldAssertsWithTextfields() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// *** 1. assertNoField().
|
||||
$this->assertNoField('invalid_name_and_id');
|
||||
|
||||
// Test that the assertion fails correctly when searching by name.
|
||||
try {
|
||||
$this->assertNoField('name');
|
||||
$this->fail('The "name" field was not found based on name.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoField correctly failed. The "name" field was found by name.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly when searching by id.
|
||||
try {
|
||||
$this->assertNoField('edit-name');
|
||||
$this->fail('The "name" field was not found based on id.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoField correctly failed. The "name" field was found by id.');
|
||||
}
|
||||
|
||||
// *** 2. assertField().
|
||||
$this->assertField('name');
|
||||
$this->assertField('edit-name');
|
||||
|
||||
// Test that the assertion fails correctly if the field does not exist.
|
||||
try {
|
||||
$this->assertField('invalid_name_and_id');
|
||||
$this->fail('The "invalid_name_and_id" field was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertField correctly failed. The "invalid_name_and_id" field was not found.');
|
||||
}
|
||||
|
||||
// *** 3. assertNoFieldById().
|
||||
$this->assertNoFieldById('name');
|
||||
$this->assertNoFieldById('name', 'not the value');
|
||||
$this->assertNoFieldById('notexisting');
|
||||
$this->assertNoFieldById('notexisting', NULL);
|
||||
|
||||
// Test that the assertion fails correctly if no value is passed in.
|
||||
try {
|
||||
$this->assertNoFieldById('edit-description');
|
||||
$this->fail('The "description" field, with no value was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('The "description" field, with no value was found.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly if a NULL value is passed in.
|
||||
try {
|
||||
$this->assertNoFieldById('edit-name', NULL);
|
||||
$this->fail('The "name" field was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('The "name" field was found.');
|
||||
}
|
||||
|
||||
// *** 4. assertFieldById().
|
||||
$this->assertFieldById('edit-name', NULL);
|
||||
$this->assertFieldById('edit-name', 'Test name');
|
||||
$this->assertFieldById('edit-description', NULL);
|
||||
$this->assertFieldById('edit-description');
|
||||
|
||||
// Test that the assertion fails correctly if no value is passed in.
|
||||
try {
|
||||
$this->assertFieldById('edit-name');
|
||||
$this->fail('The "edit-name" field with no value was found.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('The "edit-name" field with no value was not found.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly if the wrong value is passed in.
|
||||
try {
|
||||
$this->assertFieldById('edit-name', 'not the value');
|
||||
$this->fail('The "name" field was found, using the wrong value.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass('The "name" field was not found, using the wrong value.');
|
||||
}
|
||||
|
||||
// *** 5. assertNoFieldByName().
|
||||
$this->assertNoFieldByName('name');
|
||||
$this->assertNoFieldByName('name', 'not the value');
|
||||
$this->assertNoFieldByName('notexisting');
|
||||
$this->assertNoFieldByName('notexisting', NULL);
|
||||
|
||||
// Test that the assertion fails correctly if no value is passed in.
|
||||
try {
|
||||
$this->assertNoFieldByName('description');
|
||||
$this->fail('The "description" field, with no value was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('The "description" field, with no value was found.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly if a NULL value is passed in.
|
||||
try {
|
||||
$this->assertNoFieldByName('name', NULL);
|
||||
$this->fail('The "name" field was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('The "name" field was found.');
|
||||
}
|
||||
|
||||
// *** 6. assertFieldByName().
|
||||
$this->assertFieldByName('name');
|
||||
$this->assertFieldByName('name', NULL);
|
||||
$this->assertFieldByName('name', 'Test name');
|
||||
$this->assertFieldByName('description');
|
||||
$this->assertFieldByName('description', '');
|
||||
$this->assertFieldByName('description', NULL);
|
||||
|
||||
// Test that the assertion fails correctly if given the wrong name.
|
||||
try {
|
||||
$this->assertFieldByName('non-existing-name');
|
||||
$this->fail('The "non-existing-name" field was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('The "non-existing-name" field was not found');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly if given the wrong value.
|
||||
try {
|
||||
$this->assertFieldByName('name', 'not the value');
|
||||
$this->fail('The "name" field with incorrect value was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertFieldByName correctly failed. The "name" field with incorrect value was not found.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests legacy field asserts on other types of field.
|
||||
*/
|
||||
public function testLegacyFieldAssertsWithNonTextfields() {
|
||||
$this->drupalGet('test-field-xpath');
|
||||
|
||||
// Option field type.
|
||||
$this->assertOptionByText('options', 'one');
|
||||
try {
|
||||
$this->assertOptionByText('options', 'four');
|
||||
$this->fail('The select option "four" was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertOption('options', 1);
|
||||
try {
|
||||
$this->assertOption('options', 4);
|
||||
$this->fail('The select option "4" was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertNoOption('options', 'non-existing');
|
||||
try {
|
||||
$this->assertNoOption('options', 'one');
|
||||
$this->fail('The select option "one" was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertOptionSelected('options', 2);
|
||||
try {
|
||||
$this->assertOptionSelected('options', 4);
|
||||
$this->fail('The select option "4" was selected.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$this->assertOptionSelected('options', 1);
|
||||
$this->fail('The select option "1" was selected.');
|
||||
}
|
||||
catch (\PHPUnit_Framework_ExpectationFailedException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
// Button field type.
|
||||
$this->assertFieldById('edit-save', NULL);
|
||||
// Test that the assertion fails correctly if the field value is passed in
|
||||
// rather than the id.
|
||||
try {
|
||||
$this->assertFieldById('Save', NULL);
|
||||
$this->fail('The field with id of "Save" was found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertNoFieldById('Save', NULL);
|
||||
// Test that the assertion fails correctly if the id of an actual field is
|
||||
// passed in.
|
||||
try {
|
||||
$this->assertNoFieldById('edit-save', NULL);
|
||||
$this->fail('The field with id of "edit-save" was not found.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass($e->getMessage());
|
||||
}
|
||||
|
||||
// Checkbox field type.
|
||||
// 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);
|
||||
$this->assertFieldByName('checkbox_disabled', FALSE);
|
||||
$this->assertNoFieldByName('checkbox_enabled', FALSE);
|
||||
$this->assertNoFieldByName('checkbox_disabled', TRUE);
|
||||
|
||||
// Test that checkboxes are found by name when using NULL to ignore the
|
||||
// 'checked' state.
|
||||
$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 by ID, when using NULL to ignore the
|
||||
// 'checked' state.
|
||||
$this->assertFieldById('edit-checkbox-enabled', NULL);
|
||||
$this->assertFieldById('edit-checkbox-disabled', NULL);
|
||||
|
||||
// Test that the assertion fails correctly when using NULL to ignore state.
|
||||
try {
|
||||
$this->assertNoFieldByName('checkbox_enabled', NULL);
|
||||
$this->fail('The "checkbox_enabled" field was not found by name, using NULL value.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoFieldByName failed correctly. The "checkbox_enabled" field was found using NULL value.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly when using NULL to ignore state.
|
||||
try {
|
||||
$this->assertNoFieldById('edit-checkbox-disabled', NULL);
|
||||
$this->fail('The "edit-checkbox-disabled" field was not found by ID, using NULL value.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoFieldById failed correctly. The "edit-checkbox-disabled" field was found by ID using NULL value.');
|
||||
}
|
||||
|
||||
// Test the specific 'checked' assertions.
|
||||
$this->assertFieldChecked('edit-checkbox-enabled');
|
||||
$this->assertNoFieldChecked('edit-checkbox-disabled');
|
||||
|
||||
// Test that the assertion fails correctly with non-existant field id.
|
||||
try {
|
||||
$this->assertNoFieldChecked('incorrect_checkbox_id');
|
||||
$this->fail('The "incorrect_checkbox_id" field was found');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoFieldChecked correctly failed. The "incorrect_checkbox_id" field was not found.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly for a checkbox that is checked.
|
||||
try {
|
||||
$this->assertNoFieldChecked('edit-checkbox-enabled');
|
||||
$this->fail('The "edit-checkbox-enabled" field was not found in a checked state.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertNoFieldChecked correctly failed. The "edit-checkbox-enabled" field was found in a checked state.');
|
||||
}
|
||||
|
||||
// Test that the assertion fails correctly for a checkbox that is not
|
||||
// checked.
|
||||
try {
|
||||
$this->assertFieldChecked('edit-checkbox-disabled');
|
||||
$this->fail('The "edit-checkbox-disabled" field was found and checked.');
|
||||
}
|
||||
catch (ExpectationException $e) {
|
||||
$this->pass('assertFieldChecked correctly failed. The "edit-checkbox-disabled" field was not found in a checked state.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ::cronRun() method.
|
||||
*/
|
||||
public function testCronRun() {
|
||||
$last_cron_time = \Drupal::state()->get('system.cron_last');
|
||||
$this->cronRun();
|
||||
$this->assertSession()->statusCodeEquals(204);
|
||||
$next_cron_time = \Drupal::state()->get('system.cron_last');
|
||||
|
||||
$this->assertGreaterThan($last_cron_time, $next_cron_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal install done in \Drupal\Tests\BrowserTestBase::setUp().
|
||||
*/
|
||||
public function testInstall() {
|
||||
$htaccess_filename = $this->tempFilesDirectory . '/.htaccess';
|
||||
$this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the assumption that local time is in 'Australia/Sydney'.
|
||||
*/
|
||||
public function testLocalTimeZone() {
|
||||
// The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php
|
||||
$this->assertEquals('Australia/Sydney', date_default_timezone_get());
|
||||
|
||||
// The 'Australia/Sydney' time zone is also set in
|
||||
// FunctionalTestSetupTrait::initConfig().
|
||||
$config_factory = $this->container->get('config.factory');
|
||||
$value = $config_factory->get('system.date')->get('timezone.default');
|
||||
$this->assertEquals('Australia/Sydney', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Core\Config;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\Config\SchemaConfigListenerTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the functionality of ConfigSchemaChecker in KernelTestBase tests.
|
||||
*
|
||||
* @group config
|
||||
*/
|
||||
class SchemaConfigListenerTest extends BrowserTestBase {
|
||||
|
||||
use SchemaConfigListenerTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Datetime;
|
||||
|
||||
use Drupal\Core\Datetime\DrupalDateTime;
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the functionality of Timestamp core field UI.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class TimestampTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* An array of display options to pass to entity_get_display().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $displayOptions;
|
||||
|
||||
/**
|
||||
* A field storage to use in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field used in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldConfig
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'entity_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer entity_test form display',
|
||||
'administer content types',
|
||||
'administer node fields',
|
||||
]);
|
||||
|
||||
$this->drupalLogin($web_user);
|
||||
$field_name = 'field_timestamp';
|
||||
$type = 'timestamp';
|
||||
$widget_type = 'datetime_timestamp';
|
||||
$formatter_type = 'timestamp';
|
||||
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => $type,
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
$this->field = FieldConfig::create([
|
||||
'field_storage' => $this->fieldStorage,
|
||||
'bundle' => 'entity_test',
|
||||
'required' => TRUE,
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
EntityFormDisplay::load('entity_test.entity_test.default')
|
||||
->setComponent($field_name, ['type' => $widget_type])
|
||||
->save();
|
||||
|
||||
$this->displayOptions = [
|
||||
'type' => $formatter_type,
|
||||
'label' => 'hidden',
|
||||
];
|
||||
|
||||
EntityViewDisplay::create([
|
||||
'targetEntityType' => $this->field->getTargetEntityTypeId(),
|
||||
'bundle' => $this->field->getTargetBundle(),
|
||||
'mode' => 'full',
|
||||
'status' => TRUE,
|
||||
])->setComponent($field_name, $this->displayOptions)
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the "datetime_timestamp" widget.
|
||||
*/
|
||||
public function testWidget() {
|
||||
// Build up a date in the UTC timezone.
|
||||
$value = '2012-12-31 00:00:00';
|
||||
$date = new DrupalDateTime($value, 'UTC');
|
||||
|
||||
// Update the timezone to the system default.
|
||||
$date->setTimezone(timezone_open(drupal_get_user_timezone()));
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
// Make sure the "datetime_timestamp" widget is on the page.
|
||||
$fields = $this->xpath('//div[contains(@class, "field--widget-datetime-timestamp") and @id="edit-field-timestamp-wrapper"]');
|
||||
$this->assertEquals(1, count($fields));
|
||||
|
||||
// Look for the widget elements and make sure they are empty.
|
||||
$this->assertSession()->fieldExists('field_timestamp[0][value][date]');
|
||||
$this->assertSession()->fieldValueEquals('field_timestamp[0][value][date]', '');
|
||||
$this->assertSession()->fieldExists('field_timestamp[0][value][time]');
|
||||
$this->assertSession()->fieldValueEquals('field_timestamp[0][value][time]', '');
|
||||
|
||||
// Submit the date.
|
||||
$date_format = DateFormat::load('html_date')->getPattern();
|
||||
$time_format = DateFormat::load('html_time')->getPattern();
|
||||
|
||||
$edit = [
|
||||
'field_timestamp[0][value][date]' => $date->format($date_format),
|
||||
'field_timestamp[0][value][time]' => $date->format($time_format),
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save');
|
||||
|
||||
// Make sure the submitted date is set as the default in the widget.
|
||||
$this->assertSession()->fieldExists('field_timestamp[0][value][date]');
|
||||
$this->assertSession()->fieldValueEquals('field_timestamp[0][value][date]', $date->format($date_format));
|
||||
$this->assertSession()->fieldExists('field_timestamp[0][value][time]');
|
||||
$this->assertSession()->fieldValueEquals('field_timestamp[0][value][time]', $date->format($time_format));
|
||||
|
||||
// Make sure the entity was saved.
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getSession()->getCurrentUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertSession()->pageTextContains(sprintf('entity_test %s has been created.', $id));
|
||||
|
||||
// Make sure the timestamp is output properly with the default formatter.
|
||||
$medium = DateFormat::load('medium')->getPattern();
|
||||
$this->drupalGet('entity_test/' . $id);
|
||||
$this->assertSession()->pageTextContains($date->format($medium));
|
||||
}
|
||||
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Entity;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the correct mapping of user input on the correct field delta elements.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* The ID of the type of the entity under test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityTypeId;
|
||||
|
||||
/**
|
||||
* The field name with multiple properties being test with the entity type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$web_user = $this->drupalCreateUser(['administer entity_test content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create a field of field type "shape" with unlimited cardinality on the
|
||||
// entity type "entity_test".
|
||||
$this->entityTypeId = 'entity_test';
|
||||
$this->fieldName = 'shape';
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'shape',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])
|
||||
->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'field_name' => $this->fieldName,
|
||||
'bundle' => $this->entityTypeId,
|
||||
'label' => 'Shape',
|
||||
'translatable' => FALSE,
|
||||
])
|
||||
->save();
|
||||
|
||||
entity_get_form_display($this->entityTypeId, $this->entityTypeId, 'default')
|
||||
->setComponent($this->fieldName, ['type' => 'shape_only_color_editable_widget'])
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the correct user input mapping on complex fields.
|
||||
*/
|
||||
public function testCorrectUserInputMappingOnComplexFields() {
|
||||
/** @var ContentEntityStorageInterface $storage */
|
||||
$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->save();
|
||||
|
||||
$this->drupalGet($this->entityTypeId . '/manage/' . $entity->id() . '/edit');
|
||||
|
||||
// Rearrange the field items.
|
||||
$edit = [
|
||||
"$this->fieldName[0][_weight]" => 0,
|
||||
"$this->fieldName[1][_weight]" => -1,
|
||||
];
|
||||
// Executing an ajax call is important before saving as it will trigger
|
||||
// form state caching and so if for any reasons the form is rebuilt with
|
||||
// the entity built based on the user submitted values with already
|
||||
// reordered field items then the correct mapping will break after the form
|
||||
// builder maps over the new form the user submitted values based on the
|
||||
// previous delta ordering.
|
||||
//
|
||||
// This is how currently the form building process works and this test
|
||||
// ensures the correct behavior no matter what changes would be made to the
|
||||
// form builder or the content entity forms.
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
|
||||
// Reload the entity.
|
||||
$entity = $storage->load($entity->id());
|
||||
|
||||
// Assert that after rearranging the field items the user input will be
|
||||
// mapped on the correct delta field items.
|
||||
$this->assertEquals($entity->get($this->fieldName)->getValue(), [
|
||||
['shape' => 'circle', 'color' => 'blue'],
|
||||
['shape' => 'rectangle', 'color' => 'green'],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Test for BrowserTestBase::getTestMethodCaller() in child classes.
|
||||
*
|
||||
* @group browsertestbase
|
||||
*/
|
||||
class GetTestMethodCallerExtendsTest extends GetTestMethodCallerTest {
|
||||
|
||||
/**
|
||||
* A test method that is not present in the parent class.
|
||||
*/
|
||||
public function testGetTestMethodCallerChildClass() {
|
||||
$method_caller = $this->getTestMethodCaller();
|
||||
$expected = [
|
||||
'file' => __FILE__,
|
||||
'line' => 18,
|
||||
'function' => __CLASS__ . '->' . __FUNCTION__ . '()',
|
||||
'class' => BrowserTestBase::class,
|
||||
'object' => $this,
|
||||
'type' => '->',
|
||||
'args' => [],
|
||||
];
|
||||
$this->assertEquals($expected, $method_caller);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Explicit test for BrowserTestBase::getTestMethodCaller().
|
||||
*
|
||||
* @group browsertestbase
|
||||
*/
|
||||
class GetTestMethodCallerTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Tests BrowserTestBase::getTestMethodCaller().
|
||||
*/
|
||||
public function testGetTestMethodCaller() {
|
||||
$method_caller = $this->getTestMethodCaller();
|
||||
$expected = [
|
||||
'file' => __FILE__,
|
||||
'line' => 18,
|
||||
'function' => __CLASS__ . '->' . __FUNCTION__ . '()',
|
||||
'class' => BrowserTestBase::class,
|
||||
'object' => $this,
|
||||
'type' => '->',
|
||||
'args' => [],
|
||||
];
|
||||
$this->assertEquals($expected, $method_caller);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\HttpKernel;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests CORS provided by Drupal.
|
||||
*
|
||||
* @see sites/default/default.services.yml
|
||||
* @see \Asm89\Stack\Cors
|
||||
* @see \Asm89\Stack\CorsService
|
||||
*
|
||||
* @group Http
|
||||
*/
|
||||
class CorsIntegrationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'test_page_test', 'page_cache'];
|
||||
|
||||
public function testCrossSiteRequest() {
|
||||
// Test default parameters.
|
||||
$cors_config = $this->container->getParameter('cors.config');
|
||||
$this->assertSame(FALSE, $cors_config['enabled']);
|
||||
$this->assertSame([], $cors_config['allowedHeaders']);
|
||||
$this->assertSame([], $cors_config['allowedMethods']);
|
||||
$this->assertSame(['*'], $cors_config['allowedOrigins']);
|
||||
|
||||
$this->assertSame(FALSE, $cors_config['exposedHeaders']);
|
||||
$this->assertSame(FALSE, $cors_config['maxAge']);
|
||||
$this->assertSame(FALSE, $cors_config['supportsCredentials']);
|
||||
|
||||
// Enable CORS with the default options.
|
||||
$cors_config['enabled'] = TRUE;
|
||||
|
||||
$this->setContainerParameter('cors.config', $cors_config);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Fire off a request.
|
||||
$this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'MISS');
|
||||
$this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com');
|
||||
|
||||
// Fire the same exact request. This time it should be cached.
|
||||
$this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'HIT');
|
||||
$this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com');
|
||||
|
||||
// Fire a request for a different origin. Verify the CORS header.
|
||||
$this->drupalGet('/test-page', [], ['Origin' => 'http://example.org']);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'HIT');
|
||||
$this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.org');
|
||||
|
||||
// Configure the CORS stack to allow a specific set of origins.
|
||||
$cors_config['allowedOrigins'] = ['http://example.com'];
|
||||
|
||||
$this->setContainerParameter('cors.config', $cors_config);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Fire a request from an origin that isn't allowed.
|
||||
/** @var \Symfony\Component\HttpFoundation\Response $response */
|
||||
$this->drupalGet('/test-page', [], ['Origin' => 'http://non-valid.com']);
|
||||
$this->assertSession()->statusCodeEquals(403);
|
||||
$this->assertSession()->pageTextContains('Not allowed.');
|
||||
|
||||
// Specify a valid origin.
|
||||
$this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Image;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests image toolkit setup form.
|
||||
*
|
||||
* @group Image
|
||||
*/
|
||||
class ToolkitSetupFormTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Admin user account.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system', 'image_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->adminUser = $this->drupalCreateUser([
|
||||
'administer site configuration',
|
||||
]);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Image toolkit setup form.
|
||||
*/
|
||||
public function testToolkitSetupForm() {
|
||||
// Get form.
|
||||
$this->drupalGet('admin/config/media/image-toolkit');
|
||||
|
||||
// Test that default toolkit is GD.
|
||||
$this->assertFieldByName('image_toolkit', 'gd', 'The default image toolkit is GD.');
|
||||
|
||||
// Test changing the jpeg image quality.
|
||||
$edit = ['gd[image_jpeg_quality]' => '70'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertEqual($this->config('system.image.gd')->get('jpeg_quality'), '70');
|
||||
|
||||
// Test changing the toolkit.
|
||||
$edit = ['image_toolkit' => 'test'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertEqual($this->config('system.image')->get('toolkit'), 'test');
|
||||
$this->assertFieldByName('test[test_parameter]', '10');
|
||||
|
||||
// Test changing the test toolkit parameter.
|
||||
$edit = ['test[test_parameter]' => '0'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertText(t('Test parameter should be different from 0.'), 'Validation error displayed.');
|
||||
$edit = ['test[test_parameter]' => '20'];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save configuration');
|
||||
$this->assertEqual($this->config('system.image.test_toolkit')->get('test_parameter'), '20');
|
||||
|
||||
// Test access without the permission 'administer site configuration'.
|
||||
$this->drupalLogin($this->drupalCreateUser(['access administration pages']));
|
||||
$this->drupalGet('admin/config/media/image-toolkit');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Image;
|
||||
|
||||
/**
|
||||
* Tests image toolkit functions.
|
||||
*
|
||||
* @group Image
|
||||
*/
|
||||
class ToolkitTest extends ToolkitTestBase {
|
||||
/**
|
||||
* Check that ImageToolkitManager::getAvailableToolkits() only returns
|
||||
* available toolkits.
|
||||
*/
|
||||
public function testGetAvailableToolkits() {
|
||||
$manager = $this->container->get('image.toolkit.manager');
|
||||
$toolkits = $manager->getAvailableToolkits();
|
||||
$this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.');
|
||||
$this->assertTrue(isset($toolkits['test:derived_toolkit']), 'The derived toolkit was returned.');
|
||||
$this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned');
|
||||
$this->assertToolkitOperationsCalled([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Image's methods.
|
||||
*/
|
||||
public function testLoad() {
|
||||
$image = $this->getImage();
|
||||
$this->assertTrue(is_object($image), 'Returned an object.');
|
||||
$this->assertEqual($image->getToolkitId(), 'test', 'Image had toolkit set.');
|
||||
$this->assertToolkitOperationsCalled(['parseFile']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_save() function.
|
||||
*/
|
||||
public function testSave() {
|
||||
$this->assertFalse($this->image->save(), 'Function returned the expected value.');
|
||||
$this->assertToolkitOperationsCalled(['save']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_apply() function.
|
||||
*/
|
||||
public function testApply() {
|
||||
$data = ['p1' => 1, 'p2' => TRUE, 'p3' => 'text'];
|
||||
$this->assertTrue($this->image->apply('my_operation', $data), 'Function returned the expected value.');
|
||||
|
||||
// Check that apply was called and with the correct parameters.
|
||||
$this->assertToolkitOperationsCalled(['apply']);
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation");
|
||||
$this->assertEqual($calls['apply'][0][1]['p1'], 1, 'integer parameter p1 was passed correctly');
|
||||
$this->assertEqual($calls['apply'][0][1]['p2'], TRUE, 'boolean parameter p2 was passed correctly');
|
||||
$this->assertEqual($calls['apply'][0][1]['p3'], 'text', 'string parameter p3 was passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_apply() function.
|
||||
*/
|
||||
public function testApplyNoParameters() {
|
||||
$this->assertTrue($this->image->apply('my_operation'), 'Function returned the expected value.');
|
||||
|
||||
// Check that apply was called and with the correct parameters.
|
||||
$this->assertToolkitOperationsCalled(['apply']);
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation");
|
||||
$this->assertEqual($calls['apply'][0][1], [], 'passing no parameters was handled correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests image toolkit operations inheritance by derivative toolkits.
|
||||
*/
|
||||
public function testDerivative() {
|
||||
$toolkit_manager = $this->container->get('image.toolkit.manager');
|
||||
$operation_manager = $this->container->get('image.toolkit.operation.manager');
|
||||
|
||||
$toolkit = $toolkit_manager->createInstance('test:derived_toolkit');
|
||||
|
||||
// Load an overwritten and an inherited operation.
|
||||
$blur = $operation_manager->getToolkitOperation($toolkit, 'blur');
|
||||
$invert = $operation_manager->getToolkitOperation($toolkit, 'invert');
|
||||
|
||||
$this->assertIdentical('foo_derived', $blur->getPluginId(), "'Blur' operation overwritten by derivative.");
|
||||
$this->assertIdentical('bar', $invert->getPluginId(), '"Invert" operation inherited from base plugin.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Image;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for image manipulation testing.
|
||||
*/
|
||||
abstract class ToolkitTestBase extends BrowserTestBase {
|
||||
|
||||
use TestFileCreationTrait {
|
||||
getTestFiles as drupalGetTestFiles;
|
||||
}
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['image_test'];
|
||||
|
||||
/**
|
||||
* The URI for the file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* The image factory service.
|
||||
*
|
||||
* @var \Drupal\Core\Image\ImageFactory
|
||||
*/
|
||||
protected $imageFactory;
|
||||
|
||||
/**
|
||||
* The image object for the test file.
|
||||
*
|
||||
* @var \Drupal\Core\Image\ImageInterface
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Set the image factory service.
|
||||
$this->imageFactory = $this->container->get('image.factory');
|
||||
|
||||
// Pick a file for testing.
|
||||
$file = current($this->drupalGetTestFiles('image'));
|
||||
$this->file = $file->uri;
|
||||
|
||||
// Setup a dummy image to work with.
|
||||
$this->image = $this->getImage();
|
||||
|
||||
// Clear out any hook calls.
|
||||
$this->imageTestReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an image with the custom toolkit.
|
||||
*
|
||||
* @return \Drupal\Core\Image\ImageInterface
|
||||
* The image object.
|
||||
*/
|
||||
protected function getImage() {
|
||||
$image = $this->imageFactory->get($this->file, 'test');
|
||||
$this->assertTrue($image->isValid(), 'Image file was parsed.');
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that all of the specified image toolkit operations were called
|
||||
* exactly once once, other values result in failure.
|
||||
*
|
||||
* @param $expected
|
||||
* Array with string containing with the operation name, e.g. 'load',
|
||||
* 'save', 'crop', etc.
|
||||
*/
|
||||
public function assertToolkitOperationsCalled(array $expected) {
|
||||
// If one of the image operations is expected, apply should be expected as
|
||||
// well.
|
||||
$operations = [
|
||||
'resize',
|
||||
'rotate',
|
||||
'crop',
|
||||
'desaturate',
|
||||
'create_new',
|
||||
'scale',
|
||||
'scale_and_crop',
|
||||
'my_operation',
|
||||
'convert',
|
||||
];
|
||||
if (count(array_intersect($expected, $operations)) > 0 && !in_array('apply', $expected)) {
|
||||
$expected[] = 'apply';
|
||||
}
|
||||
|
||||
// Determine which operations were called.
|
||||
$actual = array_keys(array_filter($this->imageTestGetAllCalls()));
|
||||
|
||||
// Determine if there were any expected that were not called.
|
||||
$uncalled = array_diff($expected, $actual);
|
||||
if (count($uncalled)) {
|
||||
$this->assertTrue(FALSE, SafeMarkup::format('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(TRUE, SafeMarkup::format('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)]));
|
||||
}
|
||||
|
||||
// Determine if there were any unexpected calls.
|
||||
// If all unexpected calls are operations and apply was expected, we do not
|
||||
// count it as an error.
|
||||
$unexpected = array_diff($actual, $expected);
|
||||
if (count($unexpected) && (!in_array('apply', $expected) || count(array_intersect($unexpected, $operations)) !== count($unexpected))) {
|
||||
$this->assertTrue(FALSE, SafeMarkup::format('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(TRUE, 'No unexpected operations were called.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets/initializes the history of calls to the test toolkit functions.
|
||||
*/
|
||||
protected function imageTestReset() {
|
||||
// Keep track of calls to these operations
|
||||
$results = [
|
||||
'parseFile' => [],
|
||||
'save' => [],
|
||||
'settings' => [],
|
||||
'apply' => [],
|
||||
'resize' => [],
|
||||
'rotate' => [],
|
||||
'crop' => [],
|
||||
'desaturate' => [],
|
||||
'create_new' => [],
|
||||
'scale' => [],
|
||||
'scale_and_crop' => [],
|
||||
'convert' => [],
|
||||
];
|
||||
\Drupal::state()->set('image_test.results', $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of calls to the test toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array keyed by operation name ('parseFile', 'save', 'settings',
|
||||
* 'resize', 'rotate', 'crop', 'desaturate') with values being arrays of
|
||||
* parameters passed to each call.
|
||||
*/
|
||||
protected function imageTestGetAllCalls() {
|
||||
return \Drupal::state()->get('image_test.results') ?: [];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Routing;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests incoming path case insensitivity.
|
||||
*
|
||||
* @group routing
|
||||
*/
|
||||
class CaseInsensitivePathTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'views', 'node', 'system_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::state()->set('system_test.module_hidden', FALSE);
|
||||
$this->createContentType(['type' => 'page']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests mixed case paths.
|
||||
*/
|
||||
public function testMixedCasePaths() {
|
||||
// Tests paths defined by routes from standard modules as anonymous.
|
||||
$this->drupalGet('user/login');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/Log in/');
|
||||
$this->drupalGet('User/Login');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/Log in/');
|
||||
|
||||
// Tests paths defined by routes from the Views module.
|
||||
$admin = $this->drupalCreateUser(['access administration pages', 'administer nodes', 'access content overview']);
|
||||
$this->drupalLogin($admin);
|
||||
|
||||
$this->drupalGet('admin/content');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/Content/');
|
||||
$this->drupalGet('Admin/Content');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/Content/');
|
||||
|
||||
// Tests paths with query arguments.
|
||||
|
||||
// Make sure our node title doesn't exist.
|
||||
$this->drupalGet('admin/content');
|
||||
$this->assertSession()->linkNotExists('FooBarBaz');
|
||||
$this->assertSession()->linkNotExists('foobarbaz');
|
||||
|
||||
// Create a node, and make sure it shows up on admin/content.
|
||||
$node = $this->createNode([
|
||||
'title' => 'FooBarBaz',
|
||||
'type' => 'page',
|
||||
]);
|
||||
|
||||
$this->drupalGet('admin/content', [
|
||||
'query' => [
|
||||
'title' => 'FooBarBaz'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertSession()->linkExists('FooBarBaz');
|
||||
$this->assertSession()->linkByHrefExists($node->toUrl()->toString());
|
||||
|
||||
// Make sure the path is case-insensitive, and query case is preserved.
|
||||
|
||||
$this->drupalGet('Admin/Content', [
|
||||
'query' => [
|
||||
'title' => 'FooBarBaz'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertSession()->linkExists('FooBarBaz');
|
||||
$this->assertSession()->linkByHrefExists($node->toUrl()->toString());
|
||||
$this->assertSession()->fieldValueEquals('edit-title', 'FooBarBaz');
|
||||
// Check that we can access the node with a mixed case path.
|
||||
$this->drupalGet('NOdE/' . $node->id());
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/FooBarBaz/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests paths with slugs.
|
||||
*/
|
||||
public function testPathsWithArguments() {
|
||||
$this->drupalGet('system-test/echo/foobarbaz');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/foobarbaz/');
|
||||
$this->assertSession()->pageTextNotMatches('/FooBarBaz/');
|
||||
|
||||
$this->drupalGet('system-test/echo/FooBarBaz');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/FooBarBaz/');
|
||||
$this->assertSession()->pageTextNotMatches('/foobarbaz/');
|
||||
|
||||
// Test utf-8 characters in the route path.
|
||||
$this->drupalGet('/system-test/Ȅchȏ/meΦω/ABc123');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/ABc123/');
|
||||
$this->drupalGet('/system-test/ȅchȎ/MEΦΩ/ABc123');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextMatches('/ABc123/');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\FunctionalTests\Routing;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests url generation and routing for route paths with encoded characters.
|
||||
*
|
||||
* @group routing
|
||||
*/
|
||||
class PathEncodedTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'path_encoded_test'];
|
||||
|
||||
public function testGetEncoded() {
|
||||
$route_paths = [
|
||||
'path_encoded_test.colon' => '/hi/llamma:party',
|
||||
'path_encoded_test.atsign' => '/bloggy/@Dries',
|
||||
'path_encoded_test.parens' => '/cat(box)',
|
||||
];
|
||||
foreach ($route_paths as $route_name => $path) {
|
||||
$this->drupalGet(Url::fromRoute($route_name));
|
||||
$this->assertSession()->pageTextContains('PathEncodedTestController works');
|
||||
}
|
||||
}
|
||||
|
||||
public function testAliasToEncoded() {
|
||||
$route_paths = [
|
||||
'path_encoded_test.colon' => '/hi/llamma:party',
|
||||
'path_encoded_test.atsign' => '/bloggy/@Dries',
|
||||
'path_encoded_test.parens' => '/cat(box)',
|
||||
];
|
||||
/** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
|
||||
$alias_storage = $this->container->get('path.alias_storage');
|
||||
$aliases = [];
|
||||
foreach ($route_paths as $route_name => $path) {
|
||||
$aliases[$route_name] = $this->randomMachineName();
|
||||
$alias_storage->save($path, '/' . $aliases[$route_name]);
|
||||
}
|
||||
foreach ($route_paths as $route_name => $path) {
|
||||
// The alias may be only a suffix of the generated path when the test is
|
||||
// run with Drupal installed in a subdirectory.
|
||||
$this->assertRegExp('@/' . rawurlencode($aliases[$route_name]) . '$@', Url::fromRoute($route_name)->toString());
|
||||
$this->drupalGet(Url::fromRoute($route_name));
|
||||
$this->assertSession()->pageTextContains('PathEncodedTestController works');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,7 +83,6 @@ trait AssertConfigTrait {
|
||||
break;
|
||||
default:
|
||||
throw new \Exception($config_name . ': ' . var_export($op, TRUE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,10 +107,10 @@ class SafeMarkupKernelTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* @dataProvider providerTestSafeMarkupUriWithException
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testSafeMarkupUriWithExceptionUri($string, $uri) {
|
||||
// Should throw an \InvalidArgumentException, due to Uri::toString().
|
||||
$this->setExpectedException(\InvalidArgumentException::class);
|
||||
$args = self::getSafeMarkupUriArgs($uri);
|
||||
|
||||
SafeMarkup::format($string, $args);
|
||||
|
||||
@@ -6,6 +6,7 @@ use Drupal\Core\Config\FileStorage;
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\Config\StorageInterface;
|
||||
use Drupal\KernelTests\AssertConfigTrait;
|
||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
@@ -16,6 +17,7 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
class DefaultConfigTest extends KernelTestBase {
|
||||
|
||||
use AssertConfigTrait;
|
||||
use FileSystemModuleDiscoveryDataProviderTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -27,6 +29,21 @@ class DefaultConfigTest extends KernelTestBase {
|
||||
*/
|
||||
public static $modules = ['system', 'user'];
|
||||
|
||||
/**
|
||||
* The following config entries are changed on module install.
|
||||
*
|
||||
* Comparing them does not make sense.
|
||||
*
|
||||
* @todo Figure out why simpletest.settings is not installed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $skippedConfig = [
|
||||
'locale.settings' => ['path: '],
|
||||
'syslog.settings' => ['facility: '],
|
||||
'simpletest.settings' => TRUE,
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -46,23 +63,9 @@ class DefaultConfigTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests if installed config is equal to the exported config.
|
||||
*
|
||||
* @dataProvider providerTestModuleConfig
|
||||
* @dataProvider coreModuleListDataProvider
|
||||
*/
|
||||
public function testModuleConfig($module) {
|
||||
/** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */
|
||||
$module_installer = $this->container->get('module_installer');
|
||||
/** @var \Drupal\Core\Config\StorageInterface $active_config_storage */
|
||||
$active_config_storage = $this->container->get('config.storage');
|
||||
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
|
||||
$config_manager = $this->container->get('config.manager');
|
||||
|
||||
// @todo https://www.drupal.org/node/2308745 Rest has an implicit dependency
|
||||
// on the Node module remove once solved.
|
||||
if (in_array($module, ['rest', 'hal'])) {
|
||||
$module_installer->install(['node']);
|
||||
}
|
||||
$module_installer->install([$module]);
|
||||
|
||||
// System and user are required in order to be able to install some of the
|
||||
// other modules. Therefore they are put into static::$modules, which though
|
||||
// doesn't install config files, so import those config files explicitly.
|
||||
@@ -73,42 +76,72 @@ class DefaultConfigTest extends KernelTestBase {
|
||||
break;
|
||||
}
|
||||
|
||||
$default_install_path = drupal_get_path('module', $module) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
|
||||
$module_config_storage = new FileStorage($default_install_path, StorageInterface::DEFAULT_COLLECTION);
|
||||
$module_path = drupal_get_path('module', $module) . '/';
|
||||
|
||||
// The following config entries are changed on module install, so compare
|
||||
// them doesn't make sense.
|
||||
$skipped_config = [];
|
||||
$skipped_config['locale.settings'][] = 'path: ';
|
||||
$skipped_config['syslog.settings'][] = 'facility: ';
|
||||
// @todo Figure out why simpletest.settings is not installed.
|
||||
$skipped_config['simpletest.settings'] = TRUE;
|
||||
/** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */
|
||||
$module_installer = $this->container->get('module_installer');
|
||||
|
||||
// Compare the installed config with the one in the module directory.
|
||||
foreach ($module_config_storage->listAll() as $config_name) {
|
||||
$result = $config_manager->diff($module_config_storage, $active_config_storage, $config_name);
|
||||
$this->assertConfigDiff($result, $config_name, $skipped_config);
|
||||
// @todo https://www.drupal.org/node/2308745 Rest has an implicit dependency
|
||||
// on the Node module remove once solved.
|
||||
if (in_array($module, ['rest', 'hal'])) {
|
||||
$module_installer->install(['node']);
|
||||
}
|
||||
|
||||
// Work out any additional modules and themes that need installing to create
|
||||
// an optional config.
|
||||
$optional_config_storage = new FileStorage($module_path . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION);
|
||||
$modules_to_install = [$module];
|
||||
$themes_to_install = [];
|
||||
foreach ($optional_config_storage->listAll() as $config_name) {
|
||||
$data = $optional_config_storage->read($config_name);
|
||||
if (isset($data['dependencies']['module'])) {
|
||||
$modules_to_install = array_merge($modules_to_install, $data['dependencies']['module']);
|
||||
}
|
||||
if (isset($data['dependencies']['theme'])) {
|
||||
$themes_to_install = array_merge($themes_to_install, $data['dependencies']['theme']);
|
||||
}
|
||||
}
|
||||
$module_installer->install(array_unique($modules_to_install));
|
||||
$this->container->get('theme_installer')->install($themes_to_install);
|
||||
|
||||
// Test configuration in the module's config/install directory.
|
||||
$module_config_storage = new FileStorage($module_path . InstallStorage::CONFIG_INSTALL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION);
|
||||
$this->doTestsOnConfigStorage($module_config_storage);
|
||||
|
||||
// Test configuration in the module's config/optional directory.
|
||||
$this->doTestsOnConfigStorage($optional_config_storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test data provider for ::testModuleConfig().
|
||||
* Tests that default config matches the installed config.
|
||||
*
|
||||
* @return array
|
||||
* An array of module names to test.
|
||||
* @param \Drupal\Core\Config\StorageInterface $default_config_storage
|
||||
* The default config storage to test.
|
||||
*/
|
||||
public function providerTestModuleConfig() {
|
||||
$module_dirs = array_keys(iterator_to_array(new \FilesystemIterator(__DIR__ . '/../../../../modules/')));
|
||||
$module_names = array_map(function($path) {
|
||||
return str_replace(__DIR__ . '/../../../../modules/', '', $path);
|
||||
}, $module_dirs);
|
||||
$modules_keyed = array_combine($module_names, $module_names);
|
||||
protected function doTestsOnConfigStorage(StorageInterface $default_config_storage) {
|
||||
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
|
||||
$config_manager = $this->container->get('config.manager');
|
||||
|
||||
$data = array_map(function ($module) {
|
||||
return [$module];
|
||||
}, $modules_keyed);
|
||||
// Just connect directly to the config table so we don't need to worry about
|
||||
// the cache layer.
|
||||
$active_config_storage = $this->container->get('config.storage');
|
||||
|
||||
return $data;
|
||||
foreach ($default_config_storage->listAll() as $config_name) {
|
||||
if ($active_config_storage->exists($config_name)) {
|
||||
// If it is a config entity re-save it. This ensures that any
|
||||
// recalculation of dependencies does not cause config change.
|
||||
if ($entity_type = $config_manager->getEntityTypeIdByName($config_name)) {
|
||||
$entity_storage = $config_manager
|
||||
->getEntityManager()
|
||||
->getStorage($entity_type);
|
||||
$id = $entity_storage->getIDFromConfigName($config_name, $entity_storage->getEntityType()
|
||||
->getConfigPrefix());
|
||||
$entity_storage->load($id)->calculateDependencies()->save();
|
||||
}
|
||||
$result = $config_manager->diff($default_config_storage, $active_config_storage, $config_name);
|
||||
$this->assertConfigDiff($result, $config_name, static::$skippedConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Asset;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Asset\AttachedAssets;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests #attached assets: attached asset libraries and JavaScript settings.
|
||||
*
|
||||
* i.e. tests:
|
||||
*
|
||||
* @code
|
||||
* $build['#attached']['library'] = …
|
||||
* $build['#attached']['drupalSettings'] = …
|
||||
* @endcode
|
||||
*
|
||||
* @group Common
|
||||
* @group Asset
|
||||
*/
|
||||
class AttachedAssetsTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* The asset resolver service.
|
||||
*
|
||||
* @var \Drupal\Core\Asset\AssetResolverInterface
|
||||
*/
|
||||
protected $assetResolver;
|
||||
|
||||
/**
|
||||
* The renderer service.
|
||||
*
|
||||
* @var \Drupal\Core\Render\RendererInterface
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['language', 'simpletest', 'common_test', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
|
||||
$this->assetResolver = $this->container->get('asset.resolver');
|
||||
$this->renderer = $this->container->get('renderer');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that default CSS and JavaScript is empty.
|
||||
*/
|
||||
public function testDefault() {
|
||||
$assets = new AttachedAssets();
|
||||
$this->assertEqual([], $this->assetResolver->getCssAssets($assets, FALSE), 'Default CSS is empty.');
|
||||
list($js_assets_header, $js_assets_footer) = $this->assetResolver->getJsAssets($assets, FALSE);
|
||||
$this->assertEqual([], $js_assets_header, 'Default header JavaScript is empty.');
|
||||
$this->assertEqual([], $js_assets_footer, 'Default footer JavaScript is empty.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests non-existing libraries.
|
||||
*/
|
||||
public function testLibraryUnknown() {
|
||||
$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.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a CSS and a JavaScript file.
|
||||
*/
|
||||
public function testAddFiles() {
|
||||
$build['#attached']['library'][] = 'common_test/files';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$css = $this->assetResolver->getCssAssets($assets, FALSE);
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/bar.css', $css), 'CSS files are correctly added.');
|
||||
$this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/foo.js', $js), 'JavaScript files are correctly added.');
|
||||
|
||||
$css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css);
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_css = $this->renderer->renderPlain($css_render_array);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
|
||||
$this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/bar.css')) . '?' . $query_string . '" media="all" />'), FALSE, 'Rendering an external CSS file.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/foo.js')) . '?' . $query_string . '"></script>'), FALSE, 'Rendering an external JavaScript file.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding JavaScript settings.
|
||||
*/
|
||||
public function testAddJsSettings() {
|
||||
// Add a file in order to test default settings.
|
||||
$build['#attached']['library'][] = 'core/drupalSettings';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$this->assertEqual([], $assets->getSettings(), 'JavaScript settings on $assets are empty.');
|
||||
$javascript = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$this->assertTrue(array_key_exists('currentPath', $javascript['drupalSettings']['data']['path']), 'The current path JavaScript setting is set correctly.');
|
||||
$this->assertTrue(array_key_exists('currentPath', $assets->getSettings()['path']), 'JavaScript settings on $assets are resolved after retrieving JavaScript assets, and are equal to the returned JavaScript settings.');
|
||||
|
||||
$assets->setSettings(['drupal' => 'rocks', 'dries' => 280342800]);
|
||||
$javascript = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$this->assertEqual(280342800, $javascript['drupalSettings']['data']['dries'], 'JavaScript setting is set correctly.');
|
||||
$this->assertEqual('rocks', $javascript['drupalSettings']['data']['drupal'], 'The other JavaScript setting is set correctly.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding external CSS and JavaScript files.
|
||||
*/
|
||||
public function testAddExternalFiles() {
|
||||
$build['#attached']['library'][] = 'common_test/external';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$css = $this->assetResolver->getCssAssets($assets, FALSE);
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$this->assertTrue(array_key_exists('http://example.com/stylesheet.css', $css), 'External CSS files are correctly added.');
|
||||
$this->assertTrue(array_key_exists('http://example.com/script.js', $js), 'External JavaScript files are correctly added.');
|
||||
|
||||
$css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css);
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_css = $this->renderer->renderPlain($css_render_array);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="http://example.com/stylesheet.css" media="all" />'), FALSE, 'Rendering an external CSS file.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, '<script src="http://example.com/script.js"></script>'), FALSE, 'Rendering an external JavaScript file.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding JavaScript files with additional attributes.
|
||||
*/
|
||||
public function testAttributes() {
|
||||
$build['#attached']['library'][] = 'common_test/js-attributes';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$expected_1 = '<script src="http://example.com/deferred-external.js" foo="bar" defer></script>';
|
||||
$expected_2 = '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/deferred-internal.js')) . '?v=1" defer bar="foo"></script>';
|
||||
$this->assertNotIdentical(strpos($rendered_js, $expected_1), FALSE, 'Rendered external JavaScript with correct defer and random attributes.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, $expected_2), FALSE, 'Rendered internal JavaScript with correct defer and random attributes.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that attributes are maintained when JS aggregation is enabled.
|
||||
*/
|
||||
public function testAggregatedAttributes() {
|
||||
$build['#attached']['library'][] = 'common_test/js-attributes';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, TRUE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$expected_1 = '<script src="http://example.com/deferred-external.js" foo="bar" defer></script>';
|
||||
$expected_2 = '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/deferred-internal.js')) . '?v=1" defer bar="foo"></script>';
|
||||
$this->assertNotIdentical(strpos($rendered_js, $expected_1), FALSE, 'Rendered external JavaScript with correct defer and random attributes.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, $expected_2), FALSE, 'Rendered internal JavaScript with correct defer and random attributes.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Integration test for CSS/JS aggregation.
|
||||
*/
|
||||
public function testAggregation() {
|
||||
$build['#attached']['library'][] = 'core/drupal.timezone';
|
||||
$build['#attached']['library'][] = 'core/drupal.vertical-tabs';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$this->assertEqual(1, count($this->assetResolver->getCssAssets($assets, TRUE)), 'There is a sole aggregated CSS asset.');
|
||||
|
||||
list($header_js, $footer_js) = $this->assetResolver->getJsAssets($assets, TRUE);
|
||||
$this->assertEqual([], \Drupal::service('asset.js.collection_renderer')->render($header_js), 'There are 0 JavaScript assets in the header.');
|
||||
$rendered_footer_js = \Drupal::service('asset.js.collection_renderer')->render($footer_js);
|
||||
$this->assertEqual(2, count($rendered_footer_js), 'There are 2 JavaScript assets in the footer.');
|
||||
$this->assertEqual('drupal-settings-json', $rendered_footer_js[0]['#attributes']['data-drupal-selector'], 'The first of the two JavaScript assets in the footer has drupal settings.');
|
||||
$this->assertEqual(0, strpos($rendered_footer_js[1]['#attributes']['src'], base_path()), 'The second of the two JavaScript assets in the footer has the sole aggregated JavaScript asset.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests JavaScript settings.
|
||||
*/
|
||||
public function testSettings() {
|
||||
$build = [];
|
||||
$build['#attached']['library'][] = 'core/drupalSettings';
|
||||
// Nonsensical value to verify if it's possible to override path settings.
|
||||
$build['#attached']['drupalSettings']['path']['pathPrefix'] = 'yarhar';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
// Cast to string since this returns a \Drupal\Core\Render\Markup object.
|
||||
$rendered_js = (string) $this->renderer->renderPlain($js_render_array);
|
||||
|
||||
// Parse the generated drupalSettings <script> back to a PHP representation.
|
||||
$startToken = '{';
|
||||
$endToken = '}';
|
||||
$start = strpos($rendered_js, $startToken);
|
||||
$end = strrpos($rendered_js, $endToken);
|
||||
// Convert to a string, as $renderer_js is a \Drupal\Core\Render\Markup
|
||||
// object.
|
||||
$json = Unicode::substr($rendered_js, $start, $end - $start + 1);
|
||||
$parsed_settings = Json::decode($json);
|
||||
|
||||
// Test whether the settings for core/drupalSettings are available.
|
||||
$this->assertTrue(isset($parsed_settings['path']['baseUrl']), 'drupalSettings.path.baseUrl is present.');
|
||||
$this->assertIdentical($parsed_settings['path']['pathPrefix'], 'yarhar', 'drupalSettings.path.pathPrefix is present and has the correct (overridden) value.');
|
||||
$this->assertIdentical($parsed_settings['path']['currentPath'], '', 'drupalSettings.path.currentPath is present and has the correct value.');
|
||||
$this->assertIdentical($parsed_settings['path']['currentPathIsAdmin'], FALSE, 'drupalSettings.path.currentPathIsAdmin is present and has the correct value.');
|
||||
$this->assertIdentical($parsed_settings['path']['isFront'], FALSE, 'drupalSettings.path.isFront is present and has the correct value.');
|
||||
$this->assertIdentical($parsed_settings['path']['currentLanguage'], 'en', 'drupalSettings.path.currentLanguage is present and has the correct value.');
|
||||
|
||||
// Tests whether altering JavaScript settings via hook_js_settings_alter()
|
||||
// is working as expected.
|
||||
// @see common_test_js_settings_alter()
|
||||
$this->assertIdentical($parsed_settings['pluralDelimiter'], '☃');
|
||||
$this->assertIdentical($parsed_settings['foo'], 'bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests JS assets depending on the 'core/<head>' virtual library.
|
||||
*/
|
||||
public function testHeaderHTML() {
|
||||
$build['#attached']['library'][] = 'common_test/js-header';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[0];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
|
||||
$this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/header.js')) . '?' . $query_string . '"></script>'), FALSE, 'The JS asset in common_test/js-header appears in the header.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/misc/drupal.js'))), FALSE, 'The JS asset of the direct dependency (core/drupal) of common_test/js-header appears in the header.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, '<script src="' . file_url_transform_relative(file_create_url('core/assets/vendor/domready/ready.min.js'))), FALSE, 'The JS asset of the indirect dependency (core/domready) of common_test/js-header appears in the header.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that for assets with cache = FALSE, Drupal sets preprocess = FALSE.
|
||||
*/
|
||||
public function testNoCache() {
|
||||
$build['#attached']['library'][] = 'common_test/no-cache';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$this->assertFalse($js['core/modules/system/tests/modules/common_test/nocache.js']['preprocess'], 'Setting cache to FALSE sets preprocess to FALSE when adding JavaScript.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding JavaScript within conditional comments.
|
||||
*
|
||||
* @see \Drupal\Core\Render\Element\HtmlTag::preRenderConditionalComments()
|
||||
*/
|
||||
public function testBrowserConditionalComments() {
|
||||
$default_query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
|
||||
|
||||
$build['#attached']['library'][] = 'common_test/browsers';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$expected_1 = "<!--[if lte IE 8]>\n" . '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/old-ie.js')) . '?' . $default_query_string . '"></script>' . "\n<![endif]-->";
|
||||
$expected_2 = "<!--[if !IE]><!-->\n" . '<script src="' . file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/no-ie.js')) . '?' . $default_query_string . '"></script>' . "\n<!--<![endif]-->";
|
||||
|
||||
$this->assertNotIdentical(strpos($rendered_js, $expected_1), FALSE, 'Rendered JavaScript within downlevel-hidden conditional comments.');
|
||||
$this->assertNotIdentical(strpos($rendered_js, $expected_2), FALSE, 'Rendered JavaScript within downlevel-revealed conditional comments.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests JavaScript versioning.
|
||||
*/
|
||||
public function testVersionQueryString() {
|
||||
$build['#attached']['library'][] = 'core/backbone';
|
||||
$build['#attached']['library'][] = 'core/domready';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$this->assertTrue(strpos($rendered_js, 'core/assets/vendor/backbone/backbone-min.js?v=1.2.3') > 0 && strpos($rendered_js, 'core/assets/vendor/domready/ready.min.js?v=1.0.8') > 0, 'JavaScript version identifiers correctly appended to URLs');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests JavaScript and CSS asset ordering.
|
||||
*/
|
||||
public function testRenderOrder() {
|
||||
$build['#attached']['library'][] = 'common_test/order';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
// Construct the expected result from the regex.
|
||||
$expected_order_js = [
|
||||
"-8_1",
|
||||
"-8_2",
|
||||
"-8_3",
|
||||
"-8_4",
|
||||
"-5_1", // The external script.
|
||||
"-3_1",
|
||||
"-3_2",
|
||||
"0_1",
|
||||
"0_2",
|
||||
"0_3",
|
||||
];
|
||||
|
||||
// Retrieve the rendered JavaScript and test against the regex.
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$matches = [];
|
||||
if (preg_match_all('/weight_([-0-9]+_[0-9]+)/', $rendered_js, $matches)) {
|
||||
$result = $matches[1];
|
||||
}
|
||||
else {
|
||||
$result = [];
|
||||
}
|
||||
$this->assertIdentical($result, $expected_order_js, 'JavaScript is added in the expected weight order.');
|
||||
|
||||
// Construct the expected result from the regex.
|
||||
$expected_order_css = [
|
||||
// Base.
|
||||
'base_weight_-101_1',
|
||||
'base_weight_-8_1',
|
||||
'layout_weight_-101_1',
|
||||
'base_weight_0_1',
|
||||
'base_weight_0_2',
|
||||
// Layout.
|
||||
'layout_weight_-8_1',
|
||||
'component_weight_-101_1',
|
||||
'layout_weight_0_1',
|
||||
'layout_weight_0_2',
|
||||
// Component.
|
||||
'component_weight_-8_1',
|
||||
'state_weight_-101_1',
|
||||
'component_weight_0_1',
|
||||
'component_weight_0_2',
|
||||
// State.
|
||||
'state_weight_-8_1',
|
||||
'theme_weight_-101_1',
|
||||
'state_weight_0_1',
|
||||
'state_weight_0_2',
|
||||
// Theme.
|
||||
'theme_weight_-8_1',
|
||||
'theme_weight_0_1',
|
||||
'theme_weight_0_2',
|
||||
];
|
||||
|
||||
// Retrieve the rendered CSS and test against the regex.
|
||||
$css = $this->assetResolver->getCssAssets($assets, FALSE);
|
||||
$css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css);
|
||||
$rendered_css = $this->renderer->renderPlain($css_render_array);
|
||||
$matches = [];
|
||||
if (preg_match_all('/([a-z]+)_weight_([-0-9]+_[0-9]+)/', $rendered_css, $matches)) {
|
||||
$result = $matches[0];
|
||||
}
|
||||
else {
|
||||
$result = [];
|
||||
}
|
||||
$this->assertIdentical($result, $expected_order_css, 'CSS is added in the expected weight order.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests rendering the JavaScript with a file's weight above jQuery's.
|
||||
*/
|
||||
public function testRenderDifferentWeight() {
|
||||
// If a library contains assets A and B, and A is listed first, then B can
|
||||
// still make itself appear first by defining a lower weight.
|
||||
$build['#attached']['library'][] = 'core/jquery';
|
||||
$build['#attached']['library'][] = 'common_test/weight';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$this->assertTrue(strpos($rendered_js, 'lighter.css') < strpos($rendered_js, 'first.js'), 'Lighter CSS assets are rendered first.');
|
||||
$this->assertTrue(strpos($rendered_js, 'lighter.js') < strpos($rendered_js, 'first.js'), 'Lighter JavaScript assets are rendered first.');
|
||||
$this->assertTrue(strpos($rendered_js, 'before-jquery.js') < strpos($rendered_js, 'core/assets/vendor/jquery/jquery.min.js'), 'Rendering a JavaScript file above jQuery.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests altering a JavaScript's weight via hook_js_alter().
|
||||
*
|
||||
* @see simpletest_js_alter()
|
||||
*/
|
||||
public function testAlter() {
|
||||
// Add both tableselect.js and simpletest.js.
|
||||
$build['#attached']['library'][] = 'core/drupal.tableselect';
|
||||
$build['#attached']['library'][] = 'simpletest/drupal.simpletest';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
// Render the JavaScript, testing if simpletest.js was altered to be before
|
||||
// tableselect.js. See simpletest_js_alter() to see where this alteration
|
||||
// takes place.
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$this->assertTrue(strpos($rendered_js, 'simpletest.js') < strpos($rendered_js, 'core/misc/tableselect.js'), 'Altering JavaScript weight through the alter hook.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a JavaScript library to the page and alters it.
|
||||
*
|
||||
* @see common_test_library_info_alter()
|
||||
*/
|
||||
public function testLibraryAlter() {
|
||||
// Verify that common_test altered the title of Farbtastic.
|
||||
/** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
|
||||
$library_discovery = \Drupal::service('library.discovery');
|
||||
$library = $library_discovery->getLibraryByName('core', 'jquery.farbtastic');
|
||||
$this->assertEqual($library['version'], '0.0', 'Registered libraries were altered.');
|
||||
|
||||
// common_test_library_info_alter() also added a dependency on jQuery Form.
|
||||
$build['#attached']['library'][] = 'core/jquery.farbtastic';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$this->assertTrue(strpos($rendered_js, 'core/assets/vendor/jquery-form/jquery.form.min.js'), 'Altered library dependencies are added to the page.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically defines an asset library and alters it.
|
||||
*/
|
||||
public function testDynamicLibrary() {
|
||||
/** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
|
||||
$library_discovery = \Drupal::service('library.discovery');
|
||||
// Retrieve a dynamic library definition.
|
||||
// @see common_test_library_info_build()
|
||||
\Drupal::state()->set('common_test.library_info_build_test', TRUE);
|
||||
$library_discovery->clearCachedDefinitions();
|
||||
$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']);
|
||||
}
|
||||
// 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']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that multiple modules can implement libraries with the same name.
|
||||
*
|
||||
* @see common_test.library.yml
|
||||
*/
|
||||
public function testLibraryNameConflicts() {
|
||||
/** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
|
||||
$library_discovery = \Drupal::service('library.discovery');
|
||||
$farbtastic = $library_discovery->getLibraryByName('common_test', 'jquery.farbtastic');
|
||||
$this->assertEqual($farbtastic['version'], '0.1', 'Alternative libraries can be added to the page.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests JavaScript files that have querystrings attached get added right.
|
||||
*/
|
||||
public function testAddJsFileWithQueryString() {
|
||||
$build['#attached']['library'][] = 'common_test/querystring';
|
||||
$assets = AttachedAssets::createFromRenderArray($build);
|
||||
|
||||
$css = $this->assetResolver->getCssAssets($assets, FALSE);
|
||||
$js = $this->assetResolver->getJsAssets($assets, FALSE)[1];
|
||||
$this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2', $css), 'CSS file with query string is correctly added.');
|
||||
$this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2', $js), 'JavaScript file with query string is correctly added.');
|
||||
|
||||
$css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css);
|
||||
$rendered_css = $this->renderer->renderPlain($css_render_array);
|
||||
$js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js);
|
||||
$rendered_js = $this->renderer->renderPlain($js_render_array);
|
||||
$query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
|
||||
$this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . str_replace('&', '&', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2'))) . '&' . $query_string . '" media="all" />'), FALSE, 'CSS file with query string gets version query string correctly appended..');
|
||||
$this->assertNotIdentical(strpos($rendered_js, '<script src="' . str_replace('&', '&', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2'))) . '&' . $query_string . '"></script>'), FALSE, 'JavaScript file with query string gets version query string correctly appended.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Asset;
|
||||
|
||||
use Drupal\Core\Asset\Exception\InvalidLibrariesExtendSpecificationException;
|
||||
use Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the library discovery and library discovery parser.
|
||||
*
|
||||
* @group Render
|
||||
*/
|
||||
class LibraryDiscoveryIntegrationTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* The library discovery service.
|
||||
*
|
||||
* @var \Drupal\Core\Asset\LibraryDiscoveryInterface
|
||||
*/
|
||||
protected $libraryDiscovery;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->container->get('theme_installer')->install(['test_theme', 'classy']);
|
||||
$this->libraryDiscovery = $this->container->get('library.discovery');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that hook_library_info is invoked and the cache is cleared.
|
||||
*/
|
||||
public function testHookLibraryInfoByTheme() {
|
||||
// Activate test_theme and verify that the library 'kitten' is added using
|
||||
// hook_library_info_alter().
|
||||
$this->activateTheme('test_theme');
|
||||
$this->assertTrue($this->libraryDiscovery->getLibraryByName('test_theme', 'kitten'));
|
||||
|
||||
// Now make classy the active theme and assert that library is not added.
|
||||
$this->activateTheme('classy');
|
||||
$this->assertFalse($this->libraryDiscovery->getLibraryByName('test_theme', 'kitten'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that libraries-override are applied to library definitions.
|
||||
*/
|
||||
public function testLibrariesOverride() {
|
||||
// Assert some classy libraries that will be overridden or removed.
|
||||
$this->activateTheme('classy');
|
||||
$this->assertAssetInLibrary('core/themes/classy/css/components/button.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('core/themes/classy/css/components/collapse-processed.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('core/themes/classy/css/components/container-inline.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('core/themes/classy/css/components/details.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('core/themes/classy/css/components/dialog.css', 'classy', 'dialog', 'css');
|
||||
|
||||
// Confirmatory assert on core library to be removed.
|
||||
$this->assertTrue($this->libraryDiscovery->getLibraryByName('core', 'drupal.progress'), 'Confirmatory test on "core/drupal.progress"');
|
||||
|
||||
// Activate test theme that defines libraries overrides.
|
||||
$this->activateTheme('test_theme');
|
||||
|
||||
// Assert that entire library was correctly overridden.
|
||||
$this->assertEqual($this->libraryDiscovery->getLibraryByName('core', 'drupal.collapse'), $this->libraryDiscovery->getLibraryByName('test_theme', 'collapse'), 'Entire library correctly overridden.');
|
||||
|
||||
// Assert that classy library assets were correctly overridden or removed.
|
||||
$this->assertNoAssetInLibrary('core/themes/classy/css/components/button.css', 'classy', 'base', 'css');
|
||||
$this->assertNoAssetInLibrary('core/themes/classy/css/components/collapse-processed.css', 'classy', 'base', 'css');
|
||||
$this->assertNoAssetInLibrary('core/themes/classy/css/components/container-inline.css', 'classy', 'base', 'css');
|
||||
$this->assertNoAssetInLibrary('core/themes/classy/css/components/details.css', 'classy', 'base', 'css');
|
||||
$this->assertNoAssetInLibrary('core/themes/classy/css/components/dialog.css', 'classy', 'dialog', 'css');
|
||||
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_theme/css/my-button.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_theme/css/my-collapse-processed.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('themes/my_theme/css/my-container-inline.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('themes/my_theme/css/my-details.css', 'classy', 'base', 'css');
|
||||
|
||||
// Assert that entire library was correctly removed.
|
||||
$this->assertFalse($this->libraryDiscovery->getLibraryByName('core', 'drupal.progress'), 'Entire library correctly removed.');
|
||||
|
||||
// Assert that overridden library asset still retains attributes.
|
||||
$library = $this->libraryDiscovery->getLibraryByName('core', 'jquery');
|
||||
foreach ($library['js'] as $definition) {
|
||||
if ($definition['data'] == 'core/modules/system/tests/themes/test_theme/js/collapse.js') {
|
||||
$this->assertTrue($definition['minified'] && $definition['weight'] == -20, 'Previous attributes retained');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries-override on drupalSettings.
|
||||
*/
|
||||
public function testLibrariesOverrideDrupalSettings() {
|
||||
// Activate test theme that attempts to override drupalSettings.
|
||||
$this->activateTheme('test_theme_libraries_override_with_drupal_settings');
|
||||
|
||||
// Assert that drupalSettings cannot be overridden and throws an exception.
|
||||
try {
|
||||
$this->libraryDiscovery->getLibraryByName('core', 'drupal.ajax');
|
||||
$this->fail('Throw Exception when trying to override drupalSettings');
|
||||
}
|
||||
catch (InvalidLibrariesOverrideSpecificationException $e) {
|
||||
$expected_message = 'drupalSettings may not be overridden in libraries-override. Trying to override core/drupal.ajax/drupalSettings. Use hook_library_info_alter() instead.';
|
||||
$this->assertEqual($e->getMessage(), $expected_message, 'Throw Exception when trying to override drupalSettings');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries-override on malformed assets.
|
||||
*/
|
||||
public function testLibrariesOverrideMalformedAsset() {
|
||||
// Activate test theme that overrides with a malformed asset.
|
||||
$this->activateTheme('test_theme_libraries_override_with_invalid_asset');
|
||||
|
||||
// Assert that improperly formed asset "specs" throw an exception.
|
||||
try {
|
||||
$this->libraryDiscovery->getLibraryByName('core', 'drupal.dialog');
|
||||
$this->fail('Throw Exception when specifying invalid override');
|
||||
}
|
||||
catch (InvalidLibrariesOverrideSpecificationException $e) {
|
||||
$expected_message = 'Library asset core/drupal.dialog/css is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".';
|
||||
$this->assertEqual($e->getMessage(), $expected_message, 'Throw Exception when specifying invalid override');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests library assets with other ways for specifying paths.
|
||||
*/
|
||||
public function testLibrariesOverrideOtherAssetLibraryNames() {
|
||||
// Activate a test theme that defines libraries overrides on other types of
|
||||
// assets.
|
||||
$this->activateTheme('test_theme');
|
||||
|
||||
// Assert Drupal-relative paths.
|
||||
$this->assertAssetInLibrary('themes/my_theme/css/dropbutton.css', 'core', 'drupal.dropbutton', 'css');
|
||||
|
||||
// Assert stream wrapper paths.
|
||||
$this->assertAssetInLibrary('public://my_css/vertical-tabs.css', 'core', 'drupal.vertical-tabs', 'css');
|
||||
|
||||
// Assert a protocol-relative URI.
|
||||
$this->assertAssetInLibrary('//my-server/my_theme/css/jquery_ui.css', 'core', 'jquery.ui', 'css');
|
||||
|
||||
// Assert an absolute URI.
|
||||
$this->assertAssetInLibrary('http://example.com/my_theme/css/farbtastic.css', 'core', 'jquery.farbtastic', 'css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that base theme libraries-override still apply in sub themes.
|
||||
*/
|
||||
public function testBaseThemeLibrariesOverrideInSubTheme() {
|
||||
// Activate a test theme that has subthemes.
|
||||
$this->activateTheme('test_subtheme');
|
||||
|
||||
// Assert that libraries-override specified in the base theme still applies
|
||||
// in the sub theme.
|
||||
$this->assertNoAssetInLibrary('core/misc/dialog/dialog.js', 'core', 'drupal.dialog', 'js');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_basetheme/css/farbtastic.css', 'core', 'jquery.farbtastic', 'css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries-extend.
|
||||
*/
|
||||
public function testLibrariesExtend() {
|
||||
// Activate classy themes and verify the libraries are not extended.
|
||||
$this->activateTheme('classy');
|
||||
$this->assertNoAssetInLibrary('core/modules/system/tests/themes/test_theme_libraries_extend/css/extend_1.css', 'classy', 'book-navigation', 'css');
|
||||
$this->assertNoAssetInLibrary('core/modules/system/tests/themes/test_theme_libraries_extend/js/extend_1.js', 'classy', 'book-navigation', 'js');
|
||||
$this->assertNoAssetInLibrary('core/modules/system/tests/themes/test_theme_libraries_extend/css/extend_2.css', 'classy', 'book-navigation', 'css');
|
||||
|
||||
// Activate the theme that extends the book-navigation library in classy.
|
||||
$this->activateTheme('test_theme_libraries_extend');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_theme_libraries_extend/css/extend_1.css', 'classy', 'book-navigation', 'css');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_theme_libraries_extend/js/extend_1.js', 'classy', 'book-navigation', 'js');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_theme_libraries_extend/css/extend_2.css', 'classy', 'book-navigation', 'css');
|
||||
|
||||
// Activate a sub theme and confirm that it inherits the library assets
|
||||
// extended in the base theme as well as its own.
|
||||
$this->assertNoAssetInLibrary('core/modules/system/tests/themes/test_basetheme/css/base-libraries-extend.css', 'classy', 'base', 'css');
|
||||
$this->assertNoAssetInLibrary('core/modules/system/tests/themes/test_subtheme/css/sub-libraries-extend.css', 'classy', 'base', 'css');
|
||||
$this->activateTheme('test_subtheme');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_basetheme/css/base-libraries-extend.css', 'classy', 'base', 'css');
|
||||
$this->assertAssetInLibrary('core/modules/system/tests/themes/test_subtheme/css/sub-libraries-extend.css', 'classy', 'base', 'css');
|
||||
|
||||
// Activate test theme that extends with a non-existent library. An
|
||||
// exception should be thrown.
|
||||
$this->activateTheme('test_theme_libraries_extend');
|
||||
try {
|
||||
$this->libraryDiscovery->getLibraryByName('core', 'drupal.dialog');
|
||||
$this->fail('Throw Exception when specifying non-existent libraries-extend.');
|
||||
}
|
||||
catch (InvalidLibrariesExtendSpecificationException $e) {
|
||||
$expected_message = 'The specified library "test_theme_libraries_extend/non_existent_library" does not exist.';
|
||||
$this->assertEqual($e->getMessage(), $expected_message, 'Throw Exception when specifying non-existent libraries-extend.');
|
||||
}
|
||||
|
||||
// Also, test non-string libraries-extend. An exception should be thrown.
|
||||
$this->container->get('theme_installer')->install(['test_theme']);
|
||||
try {
|
||||
$this->libraryDiscovery->getLibraryByName('test_theme', 'collapse');
|
||||
$this->fail('Throw Exception when specifying non-string libraries-extend.');
|
||||
}
|
||||
catch (InvalidLibrariesExtendSpecificationException $e) {
|
||||
$expected_message = 'The libraries-extend specification for each library must be a list of strings.';
|
||||
$this->assertEqual($e->getMessage(), $expected_message, 'Throw Exception when specifying non-string libraries-extend.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates a specified theme.
|
||||
*
|
||||
* Installs the theme if not already installed and makes it the active theme.
|
||||
*
|
||||
* @param string $theme_name
|
||||
* The name of the theme to be activated.
|
||||
*/
|
||||
protected function activateTheme($theme_name) {
|
||||
$this->container->get('theme_installer')->install([$theme_name]);
|
||||
|
||||
/** @var \Drupal\Core\Theme\ThemeInitializationInterface $theme_initializer */
|
||||
$theme_initializer = $this->container->get('theme.initialization');
|
||||
|
||||
/** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */
|
||||
$theme_manager = $this->container->get('theme.manager');
|
||||
|
||||
$theme_manager->setActiveTheme($theme_initializer->getActiveThemeByName($theme_name));
|
||||
|
||||
$this->libraryDiscovery->clearCachedDefinitions();
|
||||
|
||||
// Assert message.
|
||||
$this->pass(sprintf('Activated theme "%s"', $theme_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified asset is in the given library.
|
||||
*
|
||||
* @param string $asset
|
||||
* The asset file with the path for the file.
|
||||
* @param string $extension
|
||||
* The extension in which the $library is defined.
|
||||
* @param string $library_name
|
||||
* Name of the library.
|
||||
* @param mixed $sub_key
|
||||
* The library sub key where the given asset is defined.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the specified asset is found in the library.
|
||||
*/
|
||||
protected function assertAssetInLibrary($asset, $extension, $library_name, $sub_key, $message = NULL) {
|
||||
if (!isset($message)) {
|
||||
$message = sprintf('Asset %s found in library "%s/%s"', $asset, $extension, $library_name);
|
||||
}
|
||||
$library = $this->libraryDiscovery->getLibraryByName($extension, $library_name);
|
||||
foreach ($library[$sub_key] as $definition) {
|
||||
if ($asset == $definition['data']) {
|
||||
return $this->pass($message);
|
||||
}
|
||||
}
|
||||
return $this->fail($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified asset is not in the given library.
|
||||
*
|
||||
* @param string $asset
|
||||
* The asset file with the path for the file.
|
||||
* @param string $extension
|
||||
* The extension in which the $library_name is defined.
|
||||
* @param string $library_name
|
||||
* Name of the library.
|
||||
* @param mixed $sub_key
|
||||
* The library sub key where the given asset is defined.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the specified asset is not found in the library.
|
||||
*/
|
||||
protected function assertNoAssetInLibrary($asset, $extension, $library_name, $sub_key, $message = NULL) {
|
||||
if (!isset($message)) {
|
||||
$message = sprintf('Asset %s not found in library "%s/%s"', $asset, $extension, $library_name);
|
||||
}
|
||||
$library = $this->libraryDiscovery->getLibraryByName($extension, $library_name);
|
||||
foreach ($library[$sub_key] as $definition) {
|
||||
if ($asset == $definition['data']) {
|
||||
return $this->fail($message);
|
||||
}
|
||||
}
|
||||
return $this->pass($message);
|
||||
}
|
||||
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Asset;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the asset files for all core libraries exist.
|
||||
*
|
||||
* This test also changes the active theme to each core theme to verify
|
||||
* the libraries after theme-level libraries-override and libraries-extend are
|
||||
* applied.
|
||||
*
|
||||
* @group Asset
|
||||
*/
|
||||
class ResolvedLibraryDefinitionsFilesMatchTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* The theme handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ThemeHandlerInterface
|
||||
*/
|
||||
protected $themeHandler;
|
||||
|
||||
/**
|
||||
* The theme initialization.
|
||||
*
|
||||
* @var \Drupal\Core\Theme\ThemeInitializationInterface
|
||||
*/
|
||||
protected $themeInitialization;
|
||||
|
||||
/**
|
||||
* The theme manager.
|
||||
*
|
||||
* @var \Drupal\Core\Theme\ThemeManagerInterface
|
||||
*/
|
||||
protected $themeManager;
|
||||
|
||||
/**
|
||||
* The library discovery service.
|
||||
*
|
||||
* @var \Drupal\Core\Asset\LibraryDiscoveryInterface
|
||||
*/
|
||||
protected $libraryDiscovery;
|
||||
|
||||
/**
|
||||
* A list of all core modules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $allModules;
|
||||
|
||||
/**
|
||||
* A list of all core themes.
|
||||
*
|
||||
* We hardcode this because test themes don't use a 'package' or 'hidden' key
|
||||
* so we don't have a good way of filtering to only get "real" themes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $allThemes = [
|
||||
'bartik',
|
||||
'classy',
|
||||
'seven',
|
||||
'stable',
|
||||
'stark',
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of libraries to skip checking, in the format extension/library_name.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $librariesToSkip = [
|
||||
// Locale has a "dummy" library that does not actually exist.
|
||||
'locale/translations',
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of all paths that have been checked.
|
||||
*
|
||||
* @var array[]
|
||||
*/
|
||||
protected $pathsChecked;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Install all core themes.
|
||||
sort($this->allThemes);
|
||||
$this->container->get('theme_installer')->install($this->allThemes);
|
||||
|
||||
// Enable all core modules.
|
||||
$all_modules = system_rebuild_module_data();
|
||||
$all_modules = array_filter($all_modules, function ($module) {
|
||||
// Filter contrib, hidden, already enabled modules and modules in the
|
||||
// Testing package.
|
||||
if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing') {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
});
|
||||
$this->allModules = array_keys($all_modules);
|
||||
$this->allModules[] = 'system';
|
||||
sort($this->allModules);
|
||||
$this->container->get('module_installer')->install($this->allModules);
|
||||
|
||||
$this->themeHandler = $this->container->get('theme_handler');
|
||||
$this->themeInitialization = $this->container->get('theme.initialization');
|
||||
$this->themeManager = $this->container->get('theme.manager');
|
||||
$this->libraryDiscovery = $this->container->get('library.discovery');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all core module and theme library files exist.
|
||||
*/
|
||||
public function testCoreLibraryCompleteness() {
|
||||
// First verify all libraries with no active theme.
|
||||
$this->verifyLibraryFilesExist($this->getAllLibraries());
|
||||
|
||||
// Then verify all libraries for each core theme. This may seem like
|
||||
// overkill but themes can override and extend other extensions' libraries
|
||||
// and these changes are only applied for the active theme.
|
||||
foreach ($this->allThemes as $theme) {
|
||||
$this->themeManager->setActiveTheme($this->themeInitialization->getActiveThemeByName($theme));
|
||||
$this->libraryDiscovery->clearCachedDefinitions();
|
||||
|
||||
$this->verifyLibraryFilesExist($this->getAllLibraries());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all the library files exist.
|
||||
*
|
||||
* @param array[] $library_definitions
|
||||
* An array of library definitions, keyed by extension, then by library, and
|
||||
* so on.
|
||||
*/
|
||||
protected function verifyLibraryFilesExist($library_definitions) {
|
||||
$root = \Drupal::root();
|
||||
foreach ($library_definitions as $extension => $libraries) {
|
||||
foreach ($libraries as $library_name => $library) {
|
||||
if (in_array("$extension/$library_name", $this->librariesToSkip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that all the assets exist.
|
||||
foreach (['css', 'js'] as $asset_type) {
|
||||
foreach ($library[$asset_type] as $asset) {
|
||||
$file = $asset['data'];
|
||||
$path = $root . '/' . $file;
|
||||
// Only check and assert each file path once.
|
||||
if (!isset($this->pathsChecked[$path])) {
|
||||
$this->assertTrue(is_file($path), "$file file referenced from the $extension/$library_name library exists.");
|
||||
$this->pathsChecked[$path] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all libraries for core and all installed modules.
|
||||
*
|
||||
* @return \Drupal\Core\Extension\Extension[]
|
||||
*/
|
||||
protected function getAllLibraries() {
|
||||
$modules = \Drupal::moduleHandler()->getModuleList();
|
||||
$extensions = $modules;
|
||||
$module_list = array_keys($modules);
|
||||
sort($module_list);
|
||||
$this->assertEqual($this->allModules, $module_list, 'All core modules are installed.');
|
||||
|
||||
$themes = $this->themeHandler->listInfo();
|
||||
$extensions += $themes;
|
||||
$theme_list = array_keys($themes);
|
||||
sort($theme_list);
|
||||
$this->assertEqual($this->allThemes, $theme_list, 'All core themes are installed.');
|
||||
|
||||
$libraries['core'] = $this->libraryDiscovery->getLibrariesByExtension('core');
|
||||
|
||||
$root = \Drupal::root();
|
||||
foreach ($extensions as $extension_name => $extension) {
|
||||
$library_file = $extension->getPath() . '/' . $extension_name . '.libraries.yml';
|
||||
if (is_file($root . '/' . $library_file)) {
|
||||
$libraries[$extension_name] = $this->libraryDiscovery->getLibrariesByExtension($extension_name);
|
||||
}
|
||||
}
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Block;
|
||||
|
||||
use Drupal\block_test\PluginForm\EmptyBlockForm;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that blocks can have multiple forms.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class MultipleBlockFormTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'block', 'block_test'];
|
||||
|
||||
/**
|
||||
* Tests that blocks can have multiple forms.
|
||||
*/
|
||||
public function testMultipleForms() {
|
||||
$configuration = ['label' => 'A very cool block'];
|
||||
$block = \Drupal::service('plugin.manager.block')->createInstance('test_multiple_forms_block', $configuration);
|
||||
|
||||
$form_object1 = \Drupal::service('plugin_form.factory')->createInstance($block, 'configure');
|
||||
$form_object2 = \Drupal::service('plugin_form.factory')->createInstance($block, 'secondary');
|
||||
|
||||
// Assert that the block itself is used for the default form.
|
||||
$this->assertSame($block, $form_object1);
|
||||
|
||||
// Ensure that EmptyBlockForm is used and the plugin is set.
|
||||
$this->assertInstanceOf(EmptyBlockForm::class, $form_object2);
|
||||
$this->assertAttributeEquals($block, 'plugin', $form_object2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Bootstrap;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that drupal_get_filename() works correctly.
|
||||
*
|
||||
* @group Bootstrap
|
||||
*/
|
||||
class GetFilenameTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
// Use the testing install profile.
|
||||
$container->setParameter('install_profile', 'testing');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that drupal_get_filename() works when the file is not in database.
|
||||
*/
|
||||
public function testDrupalGetFilename() {
|
||||
// Rebuild system.module.files state data.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
system_rebuild_module_data();
|
||||
|
||||
// Retrieving the location of a module.
|
||||
$this->assertIdentical(drupal_get_filename('module', 'system'), 'core/modules/system/system.info.yml');
|
||||
|
||||
// Retrieving the location of a theme.
|
||||
\Drupal::service('theme_handler')->install(['stark']);
|
||||
$this->assertIdentical(drupal_get_filename('theme', 'stark'), 'core/themes/stark/stark.info.yml');
|
||||
|
||||
// Retrieving the location of a theme engine.
|
||||
$this->assertIdentical(drupal_get_filename('theme_engine', 'twig'), 'core/themes/engines/twig/twig.info.yml');
|
||||
|
||||
// Retrieving the location of a profile. Profiles are a special case with
|
||||
// a fixed location and naming.
|
||||
$this->assertIdentical(drupal_get_filename('profile', 'testing'), 'core/profiles/testing/testing.info.yml');
|
||||
|
||||
|
||||
// Generate a non-existing module name.
|
||||
$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) {
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
throw new \ErrorException($message, 0, $severity, $file, $line);
|
||||
});
|
||||
$this->assertNull(drupal_get_filename('module', $non_existing_module), 'Searching for an item that does not exist returns NULL.');
|
||||
$this->assertTrue(\Drupal::state()->get('get_filename_test_triggered_error'), 'Searching for an item that does not exist triggers an error.');
|
||||
// Restore the original error handler.
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Bootstrap;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that drupal_static() and drupal_static_reset() work.
|
||||
*
|
||||
* @group Bootstrap
|
||||
*/
|
||||
class ResettableStaticTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests drupal_static() function.
|
||||
*
|
||||
* Tests that a variable reference returned by drupal_static() gets reset when
|
||||
* drupal_static_reset() is called.
|
||||
*/
|
||||
public function testDrupalStatic() {
|
||||
$name = __CLASS__ . '_' . __METHOD__;
|
||||
$var = &drupal_static($name, 'foo');
|
||||
$this->assertEqual($var, 'foo', 'Variable returned by drupal_static() was set to its default.');
|
||||
|
||||
// Call the specific reset and the global reset each twice to ensure that
|
||||
// multiple resets can be issued without odd side effects.
|
||||
$var = 'bar';
|
||||
drupal_static_reset($name);
|
||||
$this->assertEqual($var, 'foo', 'Variable was reset after first invocation of name-specific reset.');
|
||||
$var = 'bar';
|
||||
drupal_static_reset($name);
|
||||
$this->assertEqual($var, 'foo', 'Variable was reset after second invocation of name-specific reset.');
|
||||
$var = 'bar';
|
||||
drupal_static_reset();
|
||||
$this->assertEqual($var, 'foo', 'Variable was reset after first invocation of global reset.');
|
||||
$var = 'bar';
|
||||
drupal_static_reset();
|
||||
$this->assertEqual($var, 'foo', 'Variable was reset after second invocation of global reset.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\Apcu4Backend;
|
||||
use Drupal\Core\Cache\ApcuBackend;
|
||||
|
||||
/**
|
||||
* Tests the APCu cache backend.
|
||||
*
|
||||
* @group Cache
|
||||
* @requires extension apcu
|
||||
*/
|
||||
class ApcuBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
/**
|
||||
* Get a list of failed requirements.
|
||||
*
|
||||
* This specifically bypasses checkRequirements because it fails tests. PHP 7
|
||||
* does not have APCu and simpletest does not have a explicit "skip"
|
||||
* functionality so to emulate it we override all test methods and explicitly
|
||||
* pass when requirements are not met.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequirements() {
|
||||
$requirements = [];
|
||||
if (!extension_loaded('apcu')) {
|
||||
$requirements[] = 'APCu extension not found.';
|
||||
}
|
||||
else {
|
||||
if (PHP_SAPI === 'cli' && !ini_get('apc.enable_cli')) {
|
||||
$requirements[] = 'apc.enable_cli must be enabled to run this test.';
|
||||
}
|
||||
}
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if requirements fail.
|
||||
*
|
||||
* If the requirements fail the test method should return immediately instead
|
||||
* of running any tests. Messages will be output to display why the test was
|
||||
* skipped.
|
||||
*/
|
||||
protected function requirementsFail() {
|
||||
$requirements = $this->getRequirements();
|
||||
if (!empty($requirements)) {
|
||||
foreach ($requirements as $message) {
|
||||
$this->pass($message);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
if (version_compare(phpversion('apcu'), '5.0.0', '>=')) {
|
||||
return new ApcuBackend($bin, $this->databasePrefix, \Drupal::service('cache_tags.invalidator.checksum'));
|
||||
}
|
||||
else {
|
||||
return new Apcu4Backend($bin, $this->databasePrefix, \Drupal::service('cache_tags.invalidator.checksum'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function tearDown() {
|
||||
foreach ($this->cachebackends as $bin => $cachebackend) {
|
||||
$this->cachebackends[$bin]->removeBin();
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testSetGet() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testSetGet();
|
||||
|
||||
// Make sure entries are permanent (i.e. no TTL).
|
||||
$backend = $this->getCacheBackend($this->getTestBin());
|
||||
$key = $backend->getApcuKey('TEST8');
|
||||
|
||||
if (class_exists('\APCUIterator')) {
|
||||
$iterator = new \APCUIterator('/^' . $key . '/');
|
||||
}
|
||||
else {
|
||||
$iterator = new \APCIterator('user', '/^' . $key . '/');
|
||||
}
|
||||
|
||||
foreach ($iterator as $item) {
|
||||
$this->assertEqual(0, $item['ttl']);
|
||||
$found = TRUE;
|
||||
}
|
||||
$this->assertTrue($found);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testDelete() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testValueTypeIsKept() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testValueTypeIsKept();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testGetMultiple() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testGetMultiple();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testSetMultiple() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testSetMultiple();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testDeleteMultiple() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testDeleteMultiple();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testDeleteAll() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testDeleteAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testInvalidate() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testInvalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testInvalidateTags() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testInvalidateTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testInvalidateAll() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testInvalidateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testRemoveBin() {
|
||||
if ($this->requirementsFail()) {
|
||||
return;
|
||||
}
|
||||
parent::testRemoveBin();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\BackendChain;
|
||||
use Drupal\Core\Cache\MemoryBackend;
|
||||
|
||||
/**
|
||||
* Unit test of the backend chain using the generic cache unit test base.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
class BackendChainTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
protected function createCacheBackend($bin) {
|
||||
$chain = new BackendChain($bin);
|
||||
|
||||
// We need to create some various backends in the chain.
|
||||
$chain
|
||||
->appendBackend(new MemoryBackend())
|
||||
->prependBackend(new MemoryBackend())
|
||||
->appendBackend(new MemoryBackend());
|
||||
|
||||
\Drupal::service('cache_tags.invalidator')->addInvalidator($chain);
|
||||
|
||||
return $chain;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\simpletest\UserCreationTrait;
|
||||
use Drupal\user\Entity\Role;
|
||||
|
||||
/**
|
||||
* Tests the cache context optimization.
|
||||
*
|
||||
* @group Render
|
||||
*/
|
||||
class CacheContextOptimizationTest extends KernelTestBase {
|
||||
|
||||
use UserCreationTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public static $modules = ['user', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
$this->installConfig(['user']);
|
||||
$this->installSchema('system', ['sequences']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that 'user.permissions' cache context is able to define cache tags.
|
||||
*/
|
||||
public function testUserPermissionCacheContextOptimization() {
|
||||
$user1 = $this->createUser();
|
||||
$this->assertEqual($user1->id(), 1);
|
||||
|
||||
$authenticated_user = $this->createUser(['administer permissions']);
|
||||
$role = $authenticated_user->getRoles()[1];
|
||||
|
||||
$test_element = [
|
||||
'#cache' => [
|
||||
'keys' => ['test'],
|
||||
'contexts' => ['user', 'user.permissions'],
|
||||
],
|
||||
];
|
||||
\Drupal::service('account_switcher')->switchTo($authenticated_user);
|
||||
$element = $test_element;
|
||||
$element['#markup'] = 'content for authenticated users';
|
||||
$output = \Drupal::service('renderer')->renderRoot($element);
|
||||
$this->assertEqual($output, 'content for authenticated users');
|
||||
|
||||
// Verify that the render caching is working so that other tests can be
|
||||
// trusted.
|
||||
$element = $test_element;
|
||||
$element['#markup'] = 'this should not be visible';
|
||||
$output = \Drupal::service('renderer')->renderRoot($element);
|
||||
$this->assertEqual($output, 'content for authenticated users');
|
||||
|
||||
// Even though the cache contexts have been optimized to only include 'user'
|
||||
// cache context, the element should have been changed because
|
||||
// 'user.permissions' cache context defined a cache tags for permission
|
||||
// changes, which should have bubbled up for the element when it was
|
||||
// optimized away.
|
||||
Role::load($role)
|
||||
->revokePermission('administer permissions')
|
||||
->save();
|
||||
$element = $test_element;
|
||||
$element['#markup'] = 'this should be visible';
|
||||
$output = \Drupal::service('renderer')->renderRoot($element);
|
||||
$this->assertEqual($output, 'this should be visible');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that 'user.roles' still works when it is optimized away.
|
||||
*/
|
||||
public function testUserRolesCacheContextOptimization() {
|
||||
$root_user = $this->createUser();
|
||||
$this->assertEqual($root_user->id(), 1);
|
||||
|
||||
$authenticated_user = $this->createUser(['administer permissions']);
|
||||
$role = $authenticated_user->getRoles()[1];
|
||||
|
||||
$test_element = [
|
||||
'#cache' => [
|
||||
'keys' => ['test'],
|
||||
'contexts' => ['user', 'user.roles'],
|
||||
],
|
||||
];
|
||||
\Drupal::service('account_switcher')->switchTo($authenticated_user);
|
||||
$element = $test_element;
|
||||
$element['#markup'] = 'content for authenticated users';
|
||||
$output = \Drupal::service('renderer')->renderRoot($element);
|
||||
$this->assertEqual($output, 'content for authenticated users');
|
||||
|
||||
// Verify that the render caching is working so that other tests can be
|
||||
// trusted.
|
||||
$element = $test_element;
|
||||
$element['#markup'] = 'this should not be visible';
|
||||
$output = \Drupal::service('renderer')->renderRoot($element);
|
||||
$this->assertEqual($output, 'content for authenticated users');
|
||||
|
||||
// Even though the cache contexts have been optimized to only include 'user'
|
||||
// cache context, the element should have been changed because 'user.roles'
|
||||
// cache context defined a cache tag for user entity changes, which should
|
||||
// have bubbled up for the element when it was optimized away.
|
||||
$authenticated_user->removeRole($role);
|
||||
$authenticated_user->save();
|
||||
$element = $test_element;
|
||||
$element['#markup'] = 'this should be visible';
|
||||
$output = \Drupal::service('renderer')->renderRoot($element);
|
||||
$this->assertEqual($output, 'this should be visible');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\ChainedFastBackend;
|
||||
use Drupal\Core\Cache\DatabaseBackend;
|
||||
use Drupal\Core\Cache\PhpBackend;
|
||||
|
||||
/**
|
||||
* Unit test of the fast chained backend using the generic cache unit test base.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
class ChainedFastBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
/**
|
||||
* Creates a new instance of ChainedFastBackend.
|
||||
*
|
||||
* @return \Drupal\Core\Cache\ChainedFastBackend
|
||||
* A new ChainedFastBackend object.
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
$consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin);
|
||||
$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
|
||||
// cache bin list in the container.
|
||||
\Drupal::service('cache_tags.invalidator')->addInvalidator($backend);
|
||||
return $backend;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Tests DatabaseBackend cache tag implementation.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
class DatabaseBackendTagTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
// Change container to database cache backends.
|
||||
$container
|
||||
->register('cache_factory', 'Drupal\Core\Cache\CacheFactory')
|
||||
->addArgument(new Reference('settings'))
|
||||
->addMethodCall('setContainer', [new Reference('service_container')]);
|
||||
}
|
||||
|
||||
public function testTagInvalidations() {
|
||||
// Create cache entry in multiple bins.
|
||||
$tags = ['test_tag:1', 'test_tag:2', 'test_tag:3'];
|
||||
$bins = ['data', 'bootstrap', 'render'];
|
||||
foreach ($bins as $bin) {
|
||||
$bin = \Drupal::cache($bin);
|
||||
$bin->set('test', 'value', Cache::PERMANENT, $tags);
|
||||
$this->assertTrue($bin->get('test'), 'Cache item was set in bin.');
|
||||
}
|
||||
|
||||
$invalidations_before = intval(db_select('cachetags')->fields('cachetags', ['invalidations'])->condition('tag', 'test_tag:2')->execute()->fetchField());
|
||||
Cache::invalidateTags(['test_tag:2']);
|
||||
|
||||
// Test that cache entry has been invalidated in multiple bins.
|
||||
foreach ($bins as $bin) {
|
||||
$bin = \Drupal::cache($bin);
|
||||
$this->assertFalse($bin->get('test'), 'Tag invalidation affected item in bin.');
|
||||
}
|
||||
|
||||
// Test that only one tag invalidation has occurred.
|
||||
$invalidations_after = intval(db_select('cachetags')->fields('cachetags', ['invalidations'])->condition('tag', 'test_tag:2')->execute()->fetchField());
|
||||
$this->assertEqual($invalidations_after, $invalidations_before + 1, 'Only one addition cache tag invalidation has occurred after invalidating a tag used in multiple bins.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\DatabaseBackend;
|
||||
|
||||
/**
|
||||
* Unit test of the database backend using the generic cache unit test base.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
class DatabaseBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* Creates a new instance of DatabaseBackend.
|
||||
*
|
||||
* @return
|
||||
* A new DatabaseBackend object.
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testSetGet() {
|
||||
parent::testSetGet();
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
// Set up a cache ID that is not ASCII and longer than 255 characters so we
|
||||
// can test cache ID normalization.
|
||||
$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.");
|
||||
|
||||
$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.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,620 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests any cache backend.
|
||||
*
|
||||
* Full generic unit test suite for any cache backend. In order to use it for a
|
||||
* cache backend implementation, extend this class and override the
|
||||
* createBackendInstance() method to return an object.
|
||||
*
|
||||
* @see DatabaseBackendUnitTestCase
|
||||
* For a full working implementation.
|
||||
*/
|
||||
abstract class GenericCacheBackendUnitTestBase extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Array of objects implementing Drupal\Core\Cache\CacheBackendInterface.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cachebackends;
|
||||
|
||||
/**
|
||||
* Cache bin to use for testing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $testBin;
|
||||
|
||||
/**
|
||||
* Random value to use in tests.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultValue;
|
||||
|
||||
/**
|
||||
* Gets the testing bin.
|
||||
*
|
||||
* Override this method if you want to work on a different bin than the
|
||||
* default one.
|
||||
*
|
||||
* @return string
|
||||
* Bin name.
|
||||
*/
|
||||
protected function getTestBin() {
|
||||
if (!isset($this->testBin)) {
|
||||
$this->testBin = 'page';
|
||||
}
|
||||
return $this->testBin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cache backend to test.
|
||||
*
|
||||
* Override this method to test a CacheBackend.
|
||||
*
|
||||
* @param string $bin
|
||||
* Bin name to use for this backend instance.
|
||||
*
|
||||
* @return \Drupal\Core\Cache\CacheBackendInterface
|
||||
* Cache backend to test.
|
||||
*/
|
||||
protected abstract function createCacheBackend($bin);
|
||||
|
||||
/**
|
||||
* Allows specific implementation to change the environment before a test run.
|
||||
*/
|
||||
public function setUpCacheBackend() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows alteration of environment after a test run but before tear down.
|
||||
*
|
||||
* Used before the real tear down because the tear down will change things
|
||||
* such as the database prefix.
|
||||
*/
|
||||
public function tearDownCacheBackend() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a backend to test; this will get a shared instance set in the object.
|
||||
*
|
||||
* @return \Drupal\Core\Cache\CacheBackendInterface
|
||||
* Cache backend to test.
|
||||
*/
|
||||
protected function getCacheBackend($bin = NULL) {
|
||||
if (!isset($bin)) {
|
||||
$bin = $this->getTestBin();
|
||||
}
|
||||
if (!isset($this->cachebackends[$bin])) {
|
||||
$this->cachebackends[$bin] = $this->createCacheBackend($bin);
|
||||
// Ensure the backend is empty.
|
||||
$this->cachebackends[$bin]->deleteAll();
|
||||
}
|
||||
return $this->cachebackends[$bin];
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
$this->cachebackends = [];
|
||||
$this->defaultValue = $this->randomMachineName(10);
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$this->setUpCacheBackend();
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
// Destruct the registered backend, each test will get a fresh instance,
|
||||
// properly emptying it here ensure that on persistent data backends they
|
||||
// will come up empty the next test.
|
||||
foreach ($this->cachebackends as $bin => $cachebackend) {
|
||||
$this->cachebackends[$bin]->deleteAll();
|
||||
}
|
||||
unset($this->cachebackends);
|
||||
|
||||
$this->tearDownCacheBackend();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the get and set methods of Drupal\Core\Cache\CacheBackendInterface.
|
||||
*/
|
||||
public function testSetGet() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
$this->assertIdentical(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->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.");
|
||||
$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->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.');
|
||||
|
||||
$backend->set('test3', 'foobar', REQUEST_TIME - 3);
|
||||
$this->assertFalse($backend->get('test3'), 'Invalid item not returned.');
|
||||
$cached = $backend->get('test3', TRUE);
|
||||
$this->assert(is_object($cached), 'Backend returned an object for cache id test3.');
|
||||
$this->assertFalse($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.');
|
||||
|
||||
$this->assertIdentical(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->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.");
|
||||
$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->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.');
|
||||
|
||||
$with_variable = ['foo' => '$bar'];
|
||||
$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);
|
||||
|
||||
// Make sure that a cached object is not affected by changing the original.
|
||||
$data = new \stdClass();
|
||||
$data->value = 1;
|
||||
$data->obj = new \stdClass();
|
||||
$data->obj->value = 2;
|
||||
$backend->set('test7', $data);
|
||||
$expected_data = clone $data;
|
||||
// Add a property to the original. It should not appear in the cached data.
|
||||
$data->this_should_not_be_in_the_cache = TRUE;
|
||||
$cached = $backend->get('test7');
|
||||
$this->assert(is_object($cached), "Backend returned an object for cache id test7.");
|
||||
$this->assertEqual($expected_data, $cached->data);
|
||||
$this->assertFalse(isset($cached->data->this_should_not_be_in_the_cache));
|
||||
// Add a property to the cache data. It should not appear when we fetch
|
||||
// the data from cache again.
|
||||
$cached->data->this_should_not_be_in_the_cache = TRUE;
|
||||
$fresh_cached = $backend->get('test7');
|
||||
$this->assertFalse(isset($fresh_cached->data->this_should_not_be_in_the_cache));
|
||||
|
||||
// Check with a long key.
|
||||
$cid = str_repeat('a', 300);
|
||||
$backend->set($cid, 'test');
|
||||
$this->assertEqual('test', $backend->get($cid)->data);
|
||||
|
||||
// Check that the cache key is case sensitive.
|
||||
$backend->set('TEST8', 'value');
|
||||
$this->assertEqual('value', $backend->get('TEST8')->data);
|
||||
$this->assertFalse($backend->get('test8'));
|
||||
|
||||
// Calling ::set() with invalid cache tags. This should fail an assertion.
|
||||
try {
|
||||
$backend->set('assertion_test', 'value', Cache::PERMANENT, ['node' => [3, 5, 7]]);
|
||||
$this->fail('::set() was called with invalid cache tags, runtime assertion did not fail.');
|
||||
}
|
||||
catch (\AssertionError $e) {
|
||||
$this->pass('::set() was called with invalid cache tags, runtime assertion failed.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Drupal\Core\Cache\CacheBackendInterface::delete().
|
||||
*/
|
||||
public function testDelete() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
$this->assertIdentical(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.");
|
||||
$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->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.");
|
||||
|
||||
$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.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests data type preservation.
|
||||
*/
|
||||
public function testValueTypeIsKept() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
$variables = [
|
||||
'test1' => 1,
|
||||
'test2' => '0',
|
||||
'test3' => '',
|
||||
'test4' => 12.64,
|
||||
'test5' => FALSE,
|
||||
'test6' => [1, 2, 3],
|
||||
];
|
||||
|
||||
// Create cache entries.
|
||||
foreach ($variables as $cid => $data) {
|
||||
$backend->set($cid, $data);
|
||||
}
|
||||
|
||||
// Retrieve and test cache objects.
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Drupal\Core\Cache\CacheBackendInterface::getMultiple().
|
||||
*/
|
||||
public function testGetMultiple() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
// Set numerous testing keys.
|
||||
$long_cid = str_repeat('a', 300);
|
||||
$backend->set('test1', 1);
|
||||
$backend->set('test2', 3);
|
||||
$backend->set('test3', 5);
|
||||
$backend->set('test4', 7);
|
||||
$backend->set('test5', 11);
|
||||
$backend->set('test6', 13);
|
||||
$backend->set('test7', 17);
|
||||
$backend->set($long_cid, 300);
|
||||
|
||||
// Mismatch order for harder testing.
|
||||
$reference = [
|
||||
'test3',
|
||||
'test7',
|
||||
'test21', // Cid does not exist.
|
||||
'test6',
|
||||
'test19', // Cid does not exist until added before second getMultiple().
|
||||
'test2',
|
||||
];
|
||||
|
||||
$cids = $reference;
|
||||
$ret = $backend->getMultiple($cids);
|
||||
// Test return - ensure it contains existing cache ids.
|
||||
$this->assert(isset($ret['test2']), "Existing cache id test2 is set.");
|
||||
$this->assert(isset($ret['test3']), "Existing cache id test3 is set.");
|
||||
$this->assert(isset($ret['test6']), "Existing cache id test6 is set.");
|
||||
$this->assert(isset($ret['test7']), "Existing cache id test7 is set.");
|
||||
// Test return - ensure that objects has expected properties.
|
||||
$this->assertTrue($ret['test2']->valid, 'Item is marked as valid.');
|
||||
$this->assertTrue($ret['test2']->created >= REQUEST_TIME && $ret['test2']->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($ret['test2']->expire, Cache::PERMANENT, 'Expire time is correct.');
|
||||
// Test return - ensure it does not contain nonexistent cache ids.
|
||||
$this->assertFalse(isset($ret['test19']), "Nonexistent cache id test19 is not set.");
|
||||
$this->assertFalse(isset($ret['test21']), "Nonexistent cache id test21 is not set.");
|
||||
// Test values.
|
||||
$this->assertIdentical($ret['test2']->data, 3, "Existing cache id test2 has the correct value.");
|
||||
$this->assertIdentical($ret['test3']->data, 5, "Existing cache id test3 has the correct value.");
|
||||
$this->assertIdentical($ret['test6']->data, 13, "Existing cache id test6 has the correct value.");
|
||||
$this->assertIdentical($ret['test7']->data, 17, "Existing cache id test7 has the correct value.");
|
||||
// Test $cids array - ensure it contains cache id's that do not exist.
|
||||
$this->assert(in_array('test19', $cids), "Nonexistent cache id test19 is in cids array.");
|
||||
$this->assert(in_array('test21', $cids), "Nonexistent cache id test21 is in cids array.");
|
||||
// Test $cids array - ensure it does not contain cache id's that exist.
|
||||
$this->assertFalse(in_array('test2', $cids), "Existing cache id test2 is not in cids array.");
|
||||
$this->assertFalse(in_array('test3', $cids), "Existing cache id test3 is not in cids array.");
|
||||
$this->assertFalse(in_array('test6', $cids), "Existing cache id test6 is not in cids array.");
|
||||
$this->assertFalse(in_array('test7', $cids), "Existing cache id test7 is not in cids array.");
|
||||
|
||||
// Test a second time after deleting and setting new keys which ensures that
|
||||
// if the backend uses statics it does not cause unexpected results.
|
||||
$backend->delete('test3');
|
||||
$backend->delete('test6');
|
||||
$backend->set('test19', 57);
|
||||
|
||||
$cids = $reference;
|
||||
$ret = $backend->getMultiple($cids);
|
||||
// Test return - ensure it contains existing cache ids.
|
||||
$this->assert(isset($ret['test2']), "Existing cache id test2 is set");
|
||||
$this->assert(isset($ret['test7']), "Existing cache id test7 is set");
|
||||
$this->assert(isset($ret['test19']), "Added cache id test19 is set");
|
||||
// Test return - ensure it does not contain nonexistent cache ids.
|
||||
$this->assertFalse(isset($ret['test3']), "Deleted cache id test3 is not set");
|
||||
$this->assertFalse(isset($ret['test6']), "Deleted cache id test6 is not set");
|
||||
$this->assertFalse(isset($ret['test21']), "Nonexistent cache id test21 is not set");
|
||||
// Test values.
|
||||
$this->assertIdentical($ret['test2']->data, 3, "Existing cache id test2 has the correct value.");
|
||||
$this->assertIdentical($ret['test7']->data, 17, "Existing cache id test7 has the correct value.");
|
||||
$this->assertIdentical($ret['test19']->data, 57, "Added cache id test19 has the correct value.");
|
||||
// Test $cids array - ensure it contains cache id's that do not exist.
|
||||
$this->assert(in_array('test3', $cids), "Deleted cache id test3 is in cids array.");
|
||||
$this->assert(in_array('test6', $cids), "Deleted cache id test6 is in cids array.");
|
||||
$this->assert(in_array('test21', $cids), "Nonexistent cache id test21 is in cids array.");
|
||||
// Test $cids array - ensure it does not contain cache id's that exist.
|
||||
$this->assertFalse(in_array('test2', $cids), "Existing cache id test2 is not in cids array.");
|
||||
$this->assertFalse(in_array('test7', $cids), "Existing cache id test7 is not in cids array.");
|
||||
$this->assertFalse(in_array('test19', $cids), "Added cache id test19 is not in cids array.");
|
||||
|
||||
// Test with a long $cid and non-numeric array key.
|
||||
$cids = ['key:key' => $long_cid];
|
||||
$return = $backend->getMultiple($cids);
|
||||
$this->assertEqual(300, $return[$long_cid]->data);
|
||||
$this->assertTrue(empty($cids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Cache\CacheBackendInterface::setMultiple().
|
||||
*/
|
||||
public function testSetMultiple() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
$future_expiration = REQUEST_TIME + 100;
|
||||
|
||||
// Set multiple testing keys.
|
||||
$backend->set('cid_1', 'Some other value');
|
||||
$items = [
|
||||
'cid_1' => ['data' => 1],
|
||||
'cid_2' => ['data' => 2],
|
||||
'cid_3' => ['data' => [1, 2]],
|
||||
'cid_4' => ['data' => 1, 'expire' => $future_expiration],
|
||||
'cid_5' => ['data' => 1, 'tags' => ['test:a', 'test:b']],
|
||||
];
|
||||
$backend->setMultiple($items);
|
||||
$cids = array_keys($items);
|
||||
$cached = $backend->getMultiple($cids);
|
||||
|
||||
$this->assertEqual($cached['cid_1']->data, $items['cid_1']['data'], 'Over-written cache item set correctly.');
|
||||
$this->assertTrue($cached['cid_1']->valid, 'Item is marked as valid.');
|
||||
$this->assertTrue($cached['cid_1']->created >= REQUEST_TIME && $cached['cid_1']->created <= round(microtime(TRUE), 3), 'Created time is correct.');
|
||||
$this->assertEqual($cached['cid_1']->expire, CacheBackendInterface::CACHE_PERMANENT, 'Cache expiration defaults to permanent.');
|
||||
|
||||
$this->assertEqual($cached['cid_2']->data, $items['cid_2']['data'], 'New cache item set correctly.');
|
||||
$this->assertEqual($cached['cid_2']->expire, CacheBackendInterface::CACHE_PERMANENT, 'Cache expiration defaults to permanent.');
|
||||
|
||||
$this->assertEqual($cached['cid_3']->data, $items['cid_3']['data'], 'New cache item with serialized data set correctly.');
|
||||
$this->assertEqual($cached['cid_3']->expire, CacheBackendInterface::CACHE_PERMANENT, 'Cache expiration defaults to permanent.');
|
||||
|
||||
$this->assertEqual($cached['cid_4']->data, $items['cid_4']['data'], 'New cache item set correctly.');
|
||||
$this->assertEqual($cached['cid_4']->expire, $future_expiration, 'Cache expiration has been correctly set.');
|
||||
|
||||
$this->assertEqual($cached['cid_5']->data, $items['cid_5']['data'], 'New cache item set correctly.');
|
||||
|
||||
// Calling ::setMultiple() with invalid cache tags. This should fail an
|
||||
// assertion.
|
||||
try {
|
||||
$items = [
|
||||
'exception_test_1' => ['data' => 1, 'tags' => []],
|
||||
'exception_test_2' => ['data' => 2, 'tags' => ['valid']],
|
||||
'exception_test_3' => ['data' => 3, 'tags' => ['node' => [3, 5, 7]]],
|
||||
];
|
||||
$backend->setMultiple($items);
|
||||
$this->fail('::setMultiple() was called with invalid cache tags, runtime assertion did not fail.');
|
||||
}
|
||||
catch (\AssertionError $e) {
|
||||
$this->pass('::setMultiple() was called with invalid cache tags, runtime assertion failed.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Drupal\Core\Cache\CacheBackendInterface::delete() and
|
||||
* Drupal\Core\Cache\CacheBackendInterface::deleteMultiple().
|
||||
*/
|
||||
public function testDeleteMultiple() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
// Set numerous testing keys.
|
||||
$backend->set('test1', 1);
|
||||
$backend->set('test2', 3);
|
||||
$backend->set('test3', 5);
|
||||
$backend->set('test4', 7);
|
||||
$backend->set('test5', 11);
|
||||
$backend->set('test6', 13);
|
||||
$backend->set('test7', 17);
|
||||
|
||||
$backend->delete('test1');
|
||||
$backend->delete('test23'); // Nonexistent key should not cause an error.
|
||||
$backend->deleteMultiple([
|
||||
'test3',
|
||||
'test5',
|
||||
'test7',
|
||||
'test19', // Nonexistent key should not cause an error.
|
||||
'test21', // Nonexistent key should not cause an error.
|
||||
]);
|
||||
|
||||
// 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.");
|
||||
|
||||
// Test if expected keys exist.
|
||||
$this->assertNotIdentical(FALSE, $backend->get('test2'), "Cache id test2 exists.");
|
||||
$this->assertNotIdentical(FALSE, $backend->get('test4'), "Cache id test4 exists.");
|
||||
$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.");
|
||||
|
||||
// Calling deleteMultiple() with an empty array should not cause an error.
|
||||
$this->assertFalse($backend->deleteMultiple([]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Drupal\Core\Cache\CacheBackendInterface::deleteAll().
|
||||
*/
|
||||
public function testDeleteAll() {
|
||||
$backend_a = $this->getCacheBackend();
|
||||
$backend_b = $this->getCacheBackend('bootstrap');
|
||||
|
||||
// Set both expiring and permanent keys.
|
||||
$backend_a->set('test1', 1, Cache::PERMANENT);
|
||||
$backend_a->set('test2', 3, time() + 1000);
|
||||
$backend_b->set('test3', 4, Cache::PERMANENT);
|
||||
|
||||
$backend_a->deleteAll();
|
||||
|
||||
$this->assertFalse($backend_a->get('test1'), 'First key has been deleted.');
|
||||
$this->assertFalse($backend_a->get('test2'), 'Second key has been deleted.');
|
||||
$this->assertTrue($backend_b->get('test3'), 'Item in other bin is preserved.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Drupal\Core\Cache\CacheBackendInterface::invalidate() and
|
||||
* Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple().
|
||||
*/
|
||||
public function testInvalidate() {
|
||||
$backend = $this->getCacheBackend();
|
||||
$backend->set('test1', 1);
|
||||
$backend->set('test2', 2);
|
||||
$backend->set('test3', 2);
|
||||
$backend->set('test4', 2);
|
||||
|
||||
$reference = ['test1', 'test2', 'test3', 'test4'];
|
||||
|
||||
$cids = $reference;
|
||||
$ret = $backend->getMultiple($cids);
|
||||
$this->assertEqual(count($ret), 4, 'Four items returned.');
|
||||
|
||||
$backend->invalidate('test1');
|
||||
$backend->invalidateMultiple(['test2', 'test3']);
|
||||
|
||||
$cids = $reference;
|
||||
$ret = $backend->getMultiple($cids);
|
||||
$this->assertEqual(count($ret), 1, 'Only one item element returned.');
|
||||
|
||||
$cids = $reference;
|
||||
$ret = $backend->getMultiple($cids, TRUE);
|
||||
$this->assertEqual(count($ret), 4, 'Four items returned.');
|
||||
|
||||
// Calling invalidateMultiple() with an empty array should not cause an
|
||||
// error.
|
||||
$this->assertFalse($backend->invalidateMultiple([]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Drupal\Core\Cache\CacheBackendInterface::invalidateTags().
|
||||
*/
|
||||
public function testInvalidateTags() {
|
||||
$backend = $this->getCacheBackend();
|
||||
|
||||
// Create two cache entries with the same tag and tag value.
|
||||
$backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']);
|
||||
$backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']);
|
||||
$this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Two cache items were created.');
|
||||
|
||||
// Invalidate test_tag of value 1. This should invalidate both entries.
|
||||
Cache::invalidateTags(['test_tag:2']);
|
||||
$this->assertFalse($backend->get('test_cid_invalidate1') || $backend->get('test_cid_invalidate2'), 'Two cache items invalidated after invalidating a cache tag.');
|
||||
$this->assertTrue($backend->get('test_cid_invalidate1', TRUE) && $backend->get('test_cid_invalidate2', TRUE), 'Cache items not deleted after invalidating a cache tag.');
|
||||
|
||||
// Create two cache entries with the same tag and an array tag value.
|
||||
$backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']);
|
||||
$backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']);
|
||||
$this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Two cache items were created.');
|
||||
|
||||
// Invalidate test_tag of value 1. This should invalidate both entries.
|
||||
Cache::invalidateTags(['test_tag:1']);
|
||||
$this->assertFalse($backend->get('test_cid_invalidate1') || $backend->get('test_cid_invalidate2'), 'Two caches removed after invalidating a cache tag.');
|
||||
$this->assertTrue($backend->get('test_cid_invalidate1', TRUE) && $backend->get('test_cid_invalidate2', TRUE), 'Cache items not deleted after invalidating a cache tag.');
|
||||
|
||||
// Create three cache entries with a mix of tags and tag values.
|
||||
$backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']);
|
||||
$backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']);
|
||||
$backend->set('test_cid_invalidate3', $this->defaultValue, Cache::PERMANENT, ['test_tag_foo:3']);
|
||||
$this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2') && $backend->get('test_cid_invalidate3'), 'Three cached items were created.');
|
||||
Cache::invalidateTags(['test_tag_foo:3']);
|
||||
$this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Cache items not matching the tag were not invalidated.');
|
||||
$this->assertFalse($backend->get('test_cid_invalidated3'), 'Cached item matching the tag was removed.');
|
||||
|
||||
// Create cache entry in multiple bins. Two cache entries
|
||||
// (test_cid_invalidate1 and test_cid_invalidate2) still exist from previous
|
||||
// tests.
|
||||
$tags = ['test_tag:1', 'test_tag:2', 'test_tag:3'];
|
||||
$bins = ['path', 'bootstrap', 'page'];
|
||||
foreach ($bins as $bin) {
|
||||
$this->getCacheBackend($bin)->set('test', $this->defaultValue, Cache::PERMANENT, $tags);
|
||||
$this->assertTrue($this->getCacheBackend($bin)->get('test'), 'Cache item was set in bin.');
|
||||
}
|
||||
|
||||
Cache::invalidateTags(['test_tag:2']);
|
||||
|
||||
// Test that the cache entry has been invalidated in multiple bins.
|
||||
foreach ($bins as $bin) {
|
||||
$this->assertFalse($this->getCacheBackend($bin)->get('test'), 'Tag invalidation affected item in bin.');
|
||||
}
|
||||
// Test that the cache entry with a matching tag has been invalidated.
|
||||
$this->assertFalse($this->getCacheBackend($bin)->get('test_cid_invalidate2'), 'Cache items matching tag were invalidated.');
|
||||
// Test that the cache entry with without a matching tag still exists.
|
||||
$this->assertTrue($this->getCacheBackend($bin)->get('test_cid_invalidate1'), 'Cache items not matching tag were not invalidated.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Drupal\Core\Cache\CacheBackendInterface::invalidateAll().
|
||||
*/
|
||||
public function testInvalidateAll() {
|
||||
$backend_a = $this->getCacheBackend();
|
||||
$backend_b = $this->getCacheBackend('bootstrap');
|
||||
|
||||
// Set both expiring and permanent keys.
|
||||
$backend_a->set('test1', 1, Cache::PERMANENT);
|
||||
$backend_a->set('test2', 3, time() + 1000);
|
||||
$backend_b->set('test3', 4, Cache::PERMANENT);
|
||||
|
||||
$backend_a->invalidateAll();
|
||||
|
||||
$this->assertFalse($backend_a->get('test1'), 'First key has been invalidated.');
|
||||
$this->assertFalse($backend_a->get('test2'), 'Second key has been invalidated.');
|
||||
$this->assertTrue($backend_b->get('test3'), 'Item in other bin is preserved.');
|
||||
$this->assertTrue($backend_a->get('test1', TRUE), 'First key has not been deleted.');
|
||||
$this->assertTrue($backend_a->get('test2', TRUE), 'Second key has not been deleted.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Drupal\Core\Cache\CacheBackendInterface::removeBin().
|
||||
*/
|
||||
public function testRemoveBin() {
|
||||
$backend_a = $this->getCacheBackend();
|
||||
$backend_b = $this->getCacheBackend('bootstrap');
|
||||
|
||||
// Set both expiring and permanent keys.
|
||||
$backend_a->set('test1', 1, Cache::PERMANENT);
|
||||
$backend_a->set('test2', 3, time() + 1000);
|
||||
$backend_b->set('test3', 4, Cache::PERMANENT);
|
||||
|
||||
$backend_a->removeBin();
|
||||
|
||||
$this->assertFalse($backend_a->get('test1'), 'First key has been deleted.');
|
||||
$this->assertFalse($backend_a->get('test2', TRUE), 'Second key has been deleted.');
|
||||
$this->assertTrue($backend_b->get('test3'), 'Item in other bin is preserved.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\MemoryBackend;
|
||||
|
||||
/**
|
||||
* Unit test of the memory cache backend using the generic cache unit test base.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
class MemoryBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
/**
|
||||
* Creates a new instance of MemoryBackend.
|
||||
*
|
||||
* @return
|
||||
* A new MemoryBackend object.
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
$backend = new MemoryBackend();
|
||||
\Drupal::service('cache_tags.invalidator')->addInvalidator($backend);
|
||||
return $backend;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Cache;
|
||||
|
||||
use Drupal\Core\Cache\PhpBackend;
|
||||
|
||||
/**
|
||||
* Unit test of the PHP cache backend using the generic cache unit test base.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
class PhpBackendTest extends GenericCacheBackendUnitTestBase {
|
||||
|
||||
/**
|
||||
* Creates a new instance of MemoryBackend.
|
||||
*
|
||||
* @return
|
||||
* A new MemoryBackend object.
|
||||
*/
|
||||
protected function createCacheBackend($bin) {
|
||||
$backend = new PhpBackend($bin, \Drupal::service('cache_tags.invalidator.checksum'));
|
||||
return $backend;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Command;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Command\DbDumpApplication;
|
||||
use Drupal\Core\Config\DatabaseStorage;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Tests for the database dump commands.
|
||||
*
|
||||
* @group Update
|
||||
*/
|
||||
class DbDumpTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'config', 'dblog', 'menu_link_content', 'link', 'block_content', 'file', 'user'];
|
||||
|
||||
/**
|
||||
* Test data to write into config.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Flag to skip these tests, which are database-backend dependent (MySQL).
|
||||
*
|
||||
* @see \Drupal\Core\Command\DbDumpCommand
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skipTests = FALSE;
|
||||
|
||||
/**
|
||||
* An array of original table schemas.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $originalTableSchemas = [];
|
||||
|
||||
/**
|
||||
* An array of original table indexes (including primary and unique keys).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $originalTableIndexes = [];
|
||||
|
||||
/**
|
||||
* Tables that should be part of the exported script.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tables;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Register a database cache backend rather than memory-based.
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
$container->register('cache_factory', 'Drupal\Core\Cache\DatabaseBackendFactory')
|
||||
->addArgument(new Reference('database'))
|
||||
->addArgument(new Reference('cache_tags.invalidator.checksum'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Determine what database backend is running, and set the skip flag.
|
||||
$this->skipTests = Database::getConnection()->databaseType() !== 'mysql';
|
||||
|
||||
// Create some schemas so our export contains tables.
|
||||
$this->installSchema('system', [
|
||||
'key_value_expire',
|
||||
'sessions',
|
||||
]);
|
||||
$this->installSchema('dblog', ['watchdog']);
|
||||
$this->installEntitySchema('block_content');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('file');
|
||||
$this->installEntitySchema('menu_link_content');
|
||||
$this->installSchema('system', 'sequences');
|
||||
|
||||
// Place some sample config to test for in the export.
|
||||
$this->data = [
|
||||
'foo' => $this->randomMachineName(),
|
||||
'bar' => $this->randomMachineName(),
|
||||
];
|
||||
$storage = new DatabaseStorage(Database::getConnection(), 'config');
|
||||
$storage->write('test_config', $this->data);
|
||||
|
||||
// Create user account with some potential syntax issues.
|
||||
$account = User::create(['mail' => 'q\'uote$dollar@example.com', 'name' => '$dollar']);
|
||||
$account->save();
|
||||
|
||||
// Create url_alias (this will create 'url_alias').
|
||||
$this->container->get('path.alias_storage')->save('/user/' . $account->id(), '/user/example');
|
||||
|
||||
// Create a cache table (this will create 'cache_discovery').
|
||||
\Drupal::cache('discovery')->set('test', $this->data);
|
||||
|
||||
// These are all the tables that should now be in place.
|
||||
$this->tables = [
|
||||
'block_content',
|
||||
'block_content_field_data',
|
||||
'block_content_field_revision',
|
||||
'block_content_revision',
|
||||
'cachetags',
|
||||
'config',
|
||||
'cache_bootstrap',
|
||||
'cache_config',
|
||||
'cache_data',
|
||||
'cache_discovery',
|
||||
'cache_entity',
|
||||
'file_managed',
|
||||
'key_value_expire',
|
||||
'menu_link_content',
|
||||
'menu_link_content_data',
|
||||
'sequences',
|
||||
'sessions',
|
||||
'url_alias',
|
||||
'user__roles',
|
||||
'users',
|
||||
'users_field_data',
|
||||
'watchdog',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the command directly.
|
||||
*/
|
||||
public function testDbDumpCommand() {
|
||||
if ($this->skipTests) {
|
||||
$this->pass("Skipping test since the DbDumpCommand is currently only compatible with MySql");
|
||||
return;
|
||||
}
|
||||
|
||||
$application = new DbDumpApplication();
|
||||
$command = $application->find('dump-database-d8-mysql');
|
||||
$command_tester = new CommandTester($command);
|
||||
$command_tester->execute([]);
|
||||
|
||||
// Tables that are schema-only should not have data exported.
|
||||
$pattern = preg_quote("\$connection->insert('sessions')");
|
||||
$this->assertFalse(preg_match('/' . $pattern . '/', $command_tester->getDisplay()), 'Tables defined as schema-only do not have data exported to the script.');
|
||||
|
||||
// Table data is exported.
|
||||
$pattern = preg_quote("\$connection->insert('config')");
|
||||
$this->assertTrue(preg_match('/' . $pattern . '/', $command_tester->getDisplay()), 'Table data is properly exported to the script.');
|
||||
|
||||
// The test data are in the dump (serialized).
|
||||
$pattern = preg_quote(serialize($this->data));
|
||||
$this->assertTrue(preg_match('/' . $pattern . '/', $command_tester->getDisplay()), 'Generated data is found in the exported script.');
|
||||
|
||||
// Check that the user account name and email address was properly escaped.
|
||||
$pattern = preg_quote('"q\'uote\$dollar@example.com"');
|
||||
$this->assertTrue(preg_match('/' . $pattern . '/', $command_tester->getDisplay()), 'The user account email address was properly escaped in the exported script.');
|
||||
$pattern = preg_quote('\'$dollar\'');
|
||||
$this->assertTrue(preg_match('/' . $pattern . '/', $command_tester->getDisplay()), 'The user account name was properly escaped in the exported script.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test loading the script back into the database.
|
||||
*/
|
||||
public function testScriptLoad() {
|
||||
if ($this->skipTests) {
|
||||
$this->pass("Skipping test since the DbDumpCommand is currently only compatible with MySql");
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate the script.
|
||||
$application = new DbDumpApplication();
|
||||
$command = $application->find('dump-database-d8-mysql');
|
||||
$command_tester = new CommandTester($command);
|
||||
$command_tester->execute([]);
|
||||
$script = $command_tester->getDisplay();
|
||||
|
||||
// Store original schemas and drop tables to avoid errors.
|
||||
foreach ($this->tables as $table) {
|
||||
$this->originalTableSchemas[$table] = $this->getTableSchema($table);
|
||||
$this->originalTableIndexes[$table] = $this->getTableIndexes($table);
|
||||
Database::getConnection()->schema()->dropTable($table);
|
||||
}
|
||||
|
||||
// This will load the data.
|
||||
$file = sys_get_temp_dir() . '/' . $this->randomMachineName();
|
||||
file_put_contents($file, $script);
|
||||
require_once $file;
|
||||
|
||||
// The tables should now exist and the schemas should match the originals.
|
||||
foreach ($this->tables as $table) {
|
||||
$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]));
|
||||
}
|
||||
|
||||
// Ensure the test config has been replaced.
|
||||
$config = unserialize(db_query("SELECT data FROM {config} WHERE name = 'test_config'")->fetchField());
|
||||
$this->assertIdentical($config, $this->data, 'Script has properly restored the config table data.');
|
||||
|
||||
// Ensure the cache data was not exported.
|
||||
$this->assertFalse(\Drupal::cache('discovery')
|
||||
->get('test'), 'Cache data was not exported to the script.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get a simplified schema for a given table.
|
||||
*
|
||||
* @param string $table
|
||||
*
|
||||
* @return array
|
||||
* Array keyed by field name, with the values being the field type.
|
||||
*/
|
||||
protected function getTableSchema($table) {
|
||||
// Verify the field type on the data column in the cache table.
|
||||
// @todo this is MySQL specific.
|
||||
$query = db_query("SHOW COLUMNS FROM {" . $table . "}");
|
||||
$definition = [];
|
||||
while ($row = $query->fetchAssoc()) {
|
||||
$definition[$row['Field']] = $row['Type'];
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns indexes for a given table.
|
||||
*
|
||||
* @param string $table
|
||||
* The table to find indexes for.
|
||||
*
|
||||
* @return array
|
||||
* The 'primary key', 'unique keys', and 'indexes' portion of the Drupal
|
||||
* table schema.
|
||||
*/
|
||||
protected function getTableIndexes($table) {
|
||||
$query = db_query("SHOW INDEX FROM {" . $table . "}");
|
||||
$definition = [];
|
||||
while ($row = $query->fetchAssoc()) {
|
||||
$index_name = $row['Key_name'];
|
||||
$column = $row['Column_name'];
|
||||
// Key the arrays by the index sequence for proper ordering (start at 0).
|
||||
$order = $row['Seq_in_index'] - 1;
|
||||
|
||||
// If specified, add length to the index.
|
||||
if ($row['Sub_part']) {
|
||||
$column = [$column, $row['Sub_part']];
|
||||
}
|
||||
|
||||
if ($index_name === 'PRIMARY') {
|
||||
$definition['primary key'][$order] = $column;
|
||||
}
|
||||
elseif ($row['Non_unique'] == 0) {
|
||||
$definition['unique keys'][$index_name][$order] = $column;
|
||||
}
|
||||
else {
|
||||
$definition['indexes'][$index_name][$order] = $column;
|
||||
}
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Common;
|
||||
|
||||
use Drupal\Component\Utility\Bytes;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Parse a predefined amount of bytes and compare the output with the expected
|
||||
* value.
|
||||
*
|
||||
* @group Common
|
||||
*/
|
||||
class SizeTest extends KernelTestBase {
|
||||
protected $exactTestCases;
|
||||
protected $roundedTestCases;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$kb = Bytes::KILOBYTE;
|
||||
$this->exactTestCases = [
|
||||
'1 byte' => 1,
|
||||
'1 KB' => $kb,
|
||||
'1 MB' => $kb * $kb,
|
||||
'1 GB' => $kb * $kb * $kb,
|
||||
'1 TB' => $kb * $kb * $kb * $kb,
|
||||
'1 PB' => $kb * $kb * $kb * $kb * $kb,
|
||||
'1 EB' => $kb * $kb * $kb * $kb * $kb * $kb,
|
||||
'1 ZB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb,
|
||||
'1 YB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb * $kb,
|
||||
];
|
||||
$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
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that format_size() returns the expected string.
|
||||
*/
|
||||
public function testCommonFormatSize() {
|
||||
foreach ([$this->exactTestCases, $this->roundedTestCases] as $test_cases) {
|
||||
foreach ($test_cases as $expected => $input) {
|
||||
$this->assertEqual(
|
||||
($result = format_size($input, NULL)),
|
||||
$expected,
|
||||
$expected . ' == ' . $result . ' (' . $input . ' bytes)'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross-tests Bytes::toInt() and format_size().
|
||||
*/
|
||||
public function testCommonParseSizeFormatSize() {
|
||||
foreach ($this->exactTestCases as $size) {
|
||||
$this->assertEqual(
|
||||
$size,
|
||||
($parsed_size = Bytes::toInt($string = format_size($size, NULL))),
|
||||
$size . ' == ' . $parsed_size . ' (' . $string . ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Common;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Confirm that \Drupal\Component\Utility\Xss::filter() and check_url() work
|
||||
* correctly, including invalid multi-byte sequences.
|
||||
*
|
||||
* @group Common
|
||||
*/
|
||||
class XssUnitTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['filter', 'system'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['system']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests t() functionality.
|
||||
*/
|
||||
public function testT() {
|
||||
$text = t('Simple text');
|
||||
$this->assertEqual($text, 'Simple text', 't leaves simple text alone.');
|
||||
$text = t('Escaped text: @value', ['@value' => '<script>']);
|
||||
$this->assertEqual($text, 'Escaped text: <script>', 't replaces and escapes string.');
|
||||
$text = t('Placeholder text: %value', ['%value' => '<script>']);
|
||||
$this->assertEqual($text, 'Placeholder text: <em class="placeholder"><script></em>', 't replaces, escapes and themes string.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that harmful protocols are stripped.
|
||||
*/
|
||||
public function testBadProtocolStripping() {
|
||||
// Ensure that check_url() strips out harmful protocols, and encodes for
|
||||
// HTML.
|
||||
// Ensure \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() can
|
||||
// be used to return a plain-text string stripped of harmful protocols.
|
||||
$url = 'javascript:http://www.example.com/?x=1&y=2';
|
||||
$expected_plain = 'http://www.example.com/?x=1&y=2';
|
||||
$expected_html = 'http://www.example.com/?x=1&y=2';
|
||||
$this->assertIdentical(check_url($url), $expected_html, 'check_url() filters a URL and encodes it for HTML.');
|
||||
$this->assertIdentical(UrlHelper::filterBadProtocol($url), $expected_html, '\Drupal\Component\Utility\UrlHelper::filterBadProtocol() filters a URL and encodes it for HTML.');
|
||||
$this->assertIdentical(UrlHelper::stripDangerousProtocols($url), $expected_plain, '\Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() filters a URL and returns plain text.');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ class CacheabilityMetadataConfigOverrideTest extends KernelTestBase {
|
||||
'config',
|
||||
'config_override_test',
|
||||
'system',
|
||||
'user'
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
/**
|
||||
* Exempt from strict schema checking.
|
||||
*
|
||||
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
|
||||
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
@@ -32,12 +32,12 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system');
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* Tests CRUD operations.
|
||||
*/
|
||||
function testCRUD() {
|
||||
public function testCRUD() {
|
||||
$storage = $this->container->get('config.storage');
|
||||
$config_factory = $this->container->get('config.factory');
|
||||
$name = 'config_test.crud';
|
||||
@@ -52,7 +52,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
|
||||
// Verify the active configuration contains the saved value.
|
||||
$actual_data = $storage->read($name);
|
||||
$this->assertIdentical($actual_data, array('value' => 'initial'));
|
||||
$this->assertIdentical($actual_data, ['value' => 'initial']);
|
||||
|
||||
// Update the configuration object instance.
|
||||
$config->set('value', 'instance-update');
|
||||
@@ -61,7 +61,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
|
||||
// Verify the active configuration contains the updated value.
|
||||
$actual_data = $storage->read($name);
|
||||
$this->assertIdentical($actual_data, array('value' => 'instance-update'));
|
||||
$this->assertIdentical($actual_data, ['value' => 'instance-update']);
|
||||
|
||||
// Verify a call to $this->config() immediately returns the updated value.
|
||||
$new_config = $this->config($name);
|
||||
@@ -75,7 +75,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
$config->delete();
|
||||
|
||||
// Verify the configuration object is empty.
|
||||
$this->assertIdentical($config->get(), array());
|
||||
$this->assertIdentical($config->get(), []);
|
||||
$this->assertIdentical($config->isNew(), TRUE);
|
||||
|
||||
// Verify that all copies of the configuration has been removed from the
|
||||
@@ -98,7 +98,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
|
||||
// Verify the active configuration contains the updated value.
|
||||
$actual_data = $storage->read($name);
|
||||
$this->assertIdentical($actual_data, array('value' => 're-created'));
|
||||
$this->assertIdentical($actual_data, ['value' => 're-created']);
|
||||
|
||||
// Verify a call to $this->config() immediately returns the updated value.
|
||||
$new_config = $this->config($name);
|
||||
@@ -115,7 +115,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
// Ensure that the old configuration object is removed from both the cache
|
||||
// and the configuration storage.
|
||||
$config = $this->config($name);
|
||||
$this->assertIdentical($config->get(), array());
|
||||
$this->assertIdentical($config->get(), []);
|
||||
$this->assertIdentical($config->isNew(), TRUE);
|
||||
|
||||
// Test renaming when config.factory does not have the object in its static
|
||||
@@ -138,10 +138,10 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
|
||||
// Merge data into the configuration object.
|
||||
$new_config = $this->config($new_name);
|
||||
$expected_values = array(
|
||||
$expected_values = [
|
||||
'value' => 'herp',
|
||||
'404' => 'derp',
|
||||
);
|
||||
];
|
||||
$new_config->merge($expected_values);
|
||||
$new_config->save();
|
||||
$this->assertIdentical($new_config->get('value'), $expected_values['value']);
|
||||
@@ -157,7 +157,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests the validation of configuration object names.
|
||||
*/
|
||||
function testNameValidation() {
|
||||
public function testNameValidation() {
|
||||
// Verify that an object name without namespace causes an exception.
|
||||
$name = 'nonamespace';
|
||||
$message = 'Expected ConfigNameException was thrown for a name without a namespace.';
|
||||
@@ -181,7 +181,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
// Verify that disallowed characters in the name cause an exception.
|
||||
$characters = $test_characters = array(':', '?', '*', '<', '>', '"', '\'', '/', '\\');
|
||||
$characters = $test_characters = [':', '?', '*', '<', '>', '"', '\'', '/', '\\'];
|
||||
foreach ($test_characters as $i => $c) {
|
||||
try {
|
||||
$name = 'namespace.object' . $c;
|
||||
@@ -192,9 +192,9 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
unset($test_characters[$i]);
|
||||
}
|
||||
}
|
||||
$this->assertTrue(empty($test_characters), format_string('Expected ConfigNameException was thrown for all invalid name characters: @characters', array(
|
||||
$this->assertTrue(empty($test_characters), format_string('Expected ConfigNameException was thrown for all invalid name characters: @characters', [
|
||||
'@characters' => implode(' ', $characters),
|
||||
)));
|
||||
]));
|
||||
|
||||
// Verify that a valid config object name can be saved.
|
||||
$name = 'namespace.object';
|
||||
@@ -213,11 +213,11 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests the validation of configuration object values.
|
||||
*/
|
||||
function testValueValidation() {
|
||||
public function testValueValidation() {
|
||||
// Verify that setData() will catch dotted keys.
|
||||
$message = 'Expected ConfigValueException was thrown from setData() for value with dotted keys.';
|
||||
try {
|
||||
$this->config('namespace.object')->setData(array('key.value' => 12))->save();
|
||||
$this->config('namespace.object')->setData(['key.value' => 12])->save();
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ConfigValueException $e) {
|
||||
@@ -227,7 +227,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
// Verify that set() will catch dotted keys.
|
||||
$message = 'Expected ConfigValueException was thrown from set() for value with dotted keys.';
|
||||
try {
|
||||
$this->config('namespace.object')->set('foo', array('key.value' => 12))->save();
|
||||
$this->config('namespace.object')->set('foo', ['key.value' => 12])->save();
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ConfigValueException $e) {
|
||||
@@ -239,7 +239,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
* Tests data type handling.
|
||||
*/
|
||||
public function testDataTypes() {
|
||||
\Drupal::service('module_installer')->install(array('config_test'));
|
||||
\Drupal::service('module_installer')->install(['config_test']);
|
||||
$storage = new DatabaseStorage($this->container->get('database'), 'config');
|
||||
$name = 'config_test.types';
|
||||
$config = $this->config($name);
|
||||
@@ -247,8 +247,8 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
$this->verbose('<pre>' . $original_content . "\n" . var_export($storage->read($name), TRUE));
|
||||
|
||||
// Verify variable data types are intact.
|
||||
$data = array(
|
||||
'array' => array(),
|
||||
$data = [
|
||||
'array' => [],
|
||||
'boolean' => TRUE,
|
||||
'exp' => 1.2e+34,
|
||||
'float' => 3.14159,
|
||||
@@ -258,7 +258,7 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
'octal' => 0775,
|
||||
'string' => 'string',
|
||||
'string_int' => '1',
|
||||
);
|
||||
];
|
||||
$data['_core']['default_config_hash'] = Crypt::hashBase64(serialize($data));
|
||||
$this->assertIdentical($config->get(), $data);
|
||||
|
||||
@@ -292,9 +292,9 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
$this->fail('No Exception thrown upon saving invalid data type.');
|
||||
}
|
||||
catch (UnsupportedDataTypeConfigException $e) {
|
||||
$this->pass(SafeMarkup::format('%class thrown upon saving invalid data type.', array(
|
||||
$this->pass(SafeMarkup::format('%class thrown upon saving invalid data type.', [
|
||||
'%class' => get_class($e),
|
||||
)));
|
||||
]));
|
||||
}
|
||||
|
||||
// Test that setting an unsupported type for a config object with no schema
|
||||
@@ -309,9 +309,9 @@ class ConfigCRUDTest extends KernelTestBase {
|
||||
$this->fail('No Exception thrown upon saving invalid data type.');
|
||||
}
|
||||
catch (UnsupportedDataTypeConfigException $e) {
|
||||
$this->pass(SafeMarkup::format('%class thrown upon saving invalid data type.', array(
|
||||
$this->pass(SafeMarkup::format('%class thrown upon saving invalid data type.', [
|
||||
'%class' => get_class($e),
|
||||
)));
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
/**
|
||||
* Tests for configuration dependencies.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Config\ConfigManager
|
||||
*
|
||||
* @group config
|
||||
*/
|
||||
class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
@@ -19,20 +21,20 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test', 'entity_test', 'user');
|
||||
public static $modules = ['config_test', 'entity_test', 'user'];
|
||||
|
||||
/**
|
||||
* Tests that calculating dependencies for system module.
|
||||
*/
|
||||
public function testNonEntity() {
|
||||
$this->installConfig(array('system'));
|
||||
$this->installConfig(['system']);
|
||||
$config_manager = \Drupal::service('config.manager');
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', array('system'));
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', ['system']);
|
||||
$this->assertTrue(isset($dependents['system.site']), 'Simple configuration system.site has a UUID key even though it is not a configuration entity and therefore is found when looking for dependencies of the System module.');
|
||||
// Ensure that calling
|
||||
// \Drupal\Core\Config\ConfigManager::findConfigEntityDependentsAsEntities()
|
||||
// does not try to load system.site as an entity.
|
||||
$config_manager->findConfigEntityDependentsAsEntities('module', array('system'));
|
||||
$config_manager->findConfigEntityDependentsAsEntities('module', ['system']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,22 +46,22 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$storage = $this->container->get('entity.manager')->getStorage('config_test');
|
||||
// Test dependencies between modules.
|
||||
$entity1 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity1',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'module' => array('node')
|
||||
)
|
||||
)
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'module' => ['node']
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
$entity1->save();
|
||||
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', array('node'));
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', ['node']);
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 has a dependency on the Node module.');
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', array('config_test'));
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', ['config_test']);
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 has a dependency on the config_test module.');
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', array('views'));
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', ['views']);
|
||||
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on the Views module.');
|
||||
// Ensure that the provider of the config entity is not actually written to
|
||||
// the dependencies array.
|
||||
@@ -68,22 +70,22 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$this->assertTrue(empty($root_module_dependencies), 'Node module is not written to the root dependencies array as it is enforced.');
|
||||
|
||||
// Create additional entities to test dependencies on config entities.
|
||||
$entity2 = $storage->create(array('id' => 'entity2', 'dependencies' => array('enforced' => array('config' => array($entity1->getConfigDependencyName())))));
|
||||
$entity2 = $storage->create(['id' => 'entity2', 'dependencies' => ['enforced' => ['config' => [$entity1->getConfigDependencyName()]]]]);
|
||||
$entity2->save();
|
||||
$entity3 = $storage->create(array('id' => 'entity3', 'dependencies' => array('enforced' => array('config' => array($entity2->getConfigDependencyName())))));
|
||||
$entity3 = $storage->create(['id' => 'entity3', 'dependencies' => ['enforced' => ['config' => [$entity2->getConfigDependencyName()]]]]);
|
||||
$entity3->save();
|
||||
$entity4 = $storage->create(array('id' => 'entity4', 'dependencies' => array('enforced' => array('config' => array($entity3->getConfigDependencyName())))));
|
||||
$entity4 = $storage->create(['id' => 'entity4', 'dependencies' => ['enforced' => ['config' => [$entity3->getConfigDependencyName()]]]]);
|
||||
$entity4->save();
|
||||
|
||||
// Test getting $entity1's dependencies as configuration dependency objects.
|
||||
$dependents = $config_manager->findConfigEntityDependents('config', array($entity1->getConfigDependencyName()));
|
||||
$dependents = $config_manager->findConfigEntityDependents('config', [$entity1->getConfigDependencyName()]);
|
||||
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on itself.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 has a dependency on config_test.dynamic.entity1.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on config_test.dynamic.entity1.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity4']), 'config_test.dynamic.entity4 has a dependency on config_test.dynamic.entity1.');
|
||||
|
||||
// Test getting $entity2's dependencies as entities.
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('config', array($entity2->getConfigDependencyName()));
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('config', [$entity2->getConfigDependencyName()]);
|
||||
$dependent_ids = $this->getDependentIds($dependents);
|
||||
$this->assertFalse(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 does not have a dependency on config_test.dynamic.entity1.');
|
||||
$this->assertFalse(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 does not have a dependency on itself.');
|
||||
@@ -92,7 +94,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
|
||||
// Test getting node module's dependencies as configuration dependency
|
||||
// objects.
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', array('node'));
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', ['node']);
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 has a dependency on the Node module.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 has a dependency on the Node module.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on the Node module.');
|
||||
@@ -103,20 +105,20 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
// no longer depend on node module.
|
||||
$entity1->setEnforcedDependencies([])->save();
|
||||
$entity3->setEnforcedDependencies(['module' => ['node'], 'config' => [$entity2->getConfigDependencyName()]])->save();
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', array('node'));
|
||||
$dependents = $config_manager->findConfigEntityDependents('module', ['node']);
|
||||
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on the Node module.');
|
||||
$this->assertFalse(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 does not have a dependency on the Node module.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on the Node module.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity4']), 'config_test.dynamic.entity4 has a dependency on the Node module.');
|
||||
|
||||
// Test dependency on a content entity.
|
||||
$entity_test = EntityTest::create(array(
|
||||
$entity_test = EntityTest::create([
|
||||
'name' => $this->randomString(),
|
||||
'type' => 'entity_test',
|
||||
));
|
||||
]);
|
||||
$entity_test->save();
|
||||
$entity2->setEnforcedDependencies(['config' => [$entity1->getConfigDependencyName()], 'content' => [$entity_test->getConfigDependencyName()]])->save();;
|
||||
$dependents = $config_manager->findConfigEntityDependents('content', array($entity_test->getConfigDependencyName()));
|
||||
$dependents = $config_manager->findConfigEntityDependents('content', [$entity_test->getConfigDependencyName()]);
|
||||
$this->assertFalse(isset($dependents['config_test.dynamic.entity1']), 'config_test.dynamic.entity1 does not have a dependency on the content entity.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity2']), 'config_test.dynamic.entity2 has a dependency on the content entity.');
|
||||
$this->assertTrue(isset($dependents['config_test.dynamic.entity3']), 'config_test.dynamic.entity3 has a dependency on the content entity (via entity2).');
|
||||
@@ -125,10 +127,10 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
// Create a configuration entity of a different type with the same ID as one
|
||||
// of the entities already created.
|
||||
$alt_storage = $this->container->get('entity.manager')->getStorage('config_query_test');
|
||||
$alt_storage->create(array('id' => 'entity1', 'dependencies' => array('enforced' => array('config' => array($entity1->getConfigDependencyName())))))->save();
|
||||
$alt_storage->create(array('id' => 'entity2', 'dependencies' => array('enforced' => array('module' => array('views')))))->save();
|
||||
$alt_storage->create(['id' => 'entity1', 'dependencies' => ['enforced' => ['config' => [$entity1->getConfigDependencyName()]]]])->save();
|
||||
$alt_storage->create(['id' => 'entity2', 'dependencies' => ['enforced' => ['module' => ['views']]]])->save();
|
||||
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('config', array($entity1->getConfigDependencyName()));
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('config', [$entity1->getConfigDependencyName()]);
|
||||
$dependent_ids = $this->getDependentIds($dependents);
|
||||
$this->assertFalse(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 does not have a dependency on itself.');
|
||||
$this->assertTrue(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 has a dependency on config_test.dynamic.entity1.');
|
||||
@@ -137,7 +139,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$this->assertTrue(in_array('config_query_test:entity1', $dependent_ids), 'config_query_test.dynamic.entity1 has a dependency on config_test.dynamic.entity1.');
|
||||
$this->assertFalse(in_array('config_query_test:entity2', $dependent_ids), 'config_query_test.dynamic.entity2 does not have a dependency on config_test.dynamic.entity1.');
|
||||
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('module', array('node', 'views'));
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('module', ['node', 'views']);
|
||||
$dependent_ids = $this->getDependentIds($dependents);
|
||||
$this->assertFalse(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 does not have a dependency on Views or Node.');
|
||||
$this->assertFalse(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 does not have a dependency on Views or Node.');
|
||||
@@ -146,7 +148,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$this->assertFalse(in_array('config_query_test:entity1', $dependent_ids), 'config_test.query.entity1 does not have a dependency on Views or Node.');
|
||||
$this->assertTrue(in_array('config_query_test:entity2', $dependent_ids), 'config_test.query.entity2 has a dependency on Views or Node.');
|
||||
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('module', array('config_test'));
|
||||
$dependents = $config_manager->findConfigEntityDependentsAsEntities('module', ['config_test']);
|
||||
$dependent_ids = $this->getDependentIds($dependents);
|
||||
$this->assertTrue(in_array('config_test:entity1', $dependent_ids), 'config_test.dynamic.entity1 has a dependency on config_test module.');
|
||||
$this->assertTrue(in_array('config_test:entity2', $dependent_ids), 'config_test.dynamic.entity2 has a dependency on config_test module.');
|
||||
@@ -192,25 +194,25 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
->getStorage('config_test');
|
||||
// Test dependencies between modules.
|
||||
$entity1 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity1',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'module' => array('node', 'config_test')
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'module' => ['node', 'config_test']
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity1->save();
|
||||
$entity2 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity2',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity1->getConfigDependencyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity1->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity2->save();
|
||||
// Perform a module rebuild so we can know where the node module is located
|
||||
@@ -256,14 +258,14 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
->getStorage('config_test');
|
||||
// Entity 1 will be deleted because it depends on node.
|
||||
$entity_1 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity_' . $entity_id_suffixes[0],
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'module' => array('node', 'config_test')
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'module' => ['node', 'config_test']
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity_1->save();
|
||||
|
||||
@@ -271,14 +273,14 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
// \Drupal\config_test\Entity::onDependencyRemoval() will remove the
|
||||
// dependency before config entities are deleted.
|
||||
$entity_2 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity_' . $entity_id_suffixes[1],
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity_1->getConfigDependencyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity_1->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity_2->save();
|
||||
|
||||
@@ -286,34 +288,34 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
// be fixed. The ConfigEntityInterface::onDependencyRemoval() method will
|
||||
// not be called for this entity.
|
||||
$entity_3 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity_' . $entity_id_suffixes[2],
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity_2->getConfigDependencyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity_2->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity_3->save();
|
||||
|
||||
// Entity 4's config dependency will be fixed but it will still be deleted
|
||||
// because it also depends on the node module.
|
||||
$entity_4 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity_' . $entity_id_suffixes[3],
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity_1->getConfigDependencyName()),
|
||||
'module' => array('node', 'config_test')
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity_1->getConfigDependencyName()],
|
||||
'module' => ['node', 'config_test']
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity_4->save();
|
||||
|
||||
// Set a more complicated test where dependencies will be fixed.
|
||||
\Drupal::state()->set('config_test.fix_dependencies', array($entity_1->getConfigDependencyName()));
|
||||
\Drupal::state()->set('config_test.fix_dependencies', [$entity_1->getConfigDependencyName()]);
|
||||
\Drupal::state()->set('config_test.on_dependency_removal_called', []);
|
||||
|
||||
// Do a dry run using
|
||||
@@ -339,13 +341,130 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$this->assertFalse($storage->load($entity_1->id()), 'Entity 1 deleted');
|
||||
$entity_2 = $storage->load($entity_2->id());
|
||||
$this->assertTrue($entity_2, 'Entity 2 not deleted');
|
||||
$this->assertEqual($entity_2->calculateDependencies()->getDependencies()['config'], array(), 'Entity 2 dependencies updated to remove dependency on entity 1.');
|
||||
$this->assertEqual($entity_2->calculateDependencies()->getDependencies()['config'], [], 'Entity 2 dependencies updated to remove dependency on entity 1.');
|
||||
$entity_3 = $storage->load($entity_3->id());
|
||||
$this->assertTrue($entity_3, 'Entity 3 not deleted');
|
||||
$this->assertEqual($entity_3->calculateDependencies()->getDependencies()['config'], [$entity_2->getConfigDependencyName()], 'Entity 3 still depends on entity 2.');
|
||||
$this->assertFalse($storage->load($entity_4->id()), 'Entity 4 deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::uninstall
|
||||
* @covers ::getConfigEntitiesToChangeOnDependencyRemoval
|
||||
*/
|
||||
public function testConfigEntityUninstallThirdParty() {
|
||||
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
|
||||
$config_manager = \Drupal::service('config.manager');
|
||||
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage('config_test');
|
||||
// Entity 1 will be fixed because it only has a dependency via third-party
|
||||
// settings, which are fixable.
|
||||
$entity_1 = $storage->create([
|
||||
'id' => 'entity_1',
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'module' => ['config_test'],
|
||||
],
|
||||
],
|
||||
'third_party_settings' => [
|
||||
'node' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
],
|
||||
]);
|
||||
$entity_1->save();
|
||||
|
||||
// Entity 2 has a dependency on entity 1.
|
||||
$entity_2 = $storage->create([
|
||||
'id' => 'entity_2',
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity_1->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
'third_party_settings' => [
|
||||
'node' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
],
|
||||
]);
|
||||
$entity_2->save();
|
||||
|
||||
// Entity 3 will be unchanged because it is dependent on entity 2 which can
|
||||
// be fixed. The ConfigEntityInterface::onDependencyRemoval() method will
|
||||
// not be called for this entity.
|
||||
$entity_3 = $storage->create([
|
||||
'id' => 'entity_3',
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity_2->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$entity_3->save();
|
||||
|
||||
// Entity 4's config dependency will be fixed but it will still be deleted
|
||||
// because it also depends on the node module.
|
||||
$entity_4 = $storage->create([
|
||||
'id' => 'entity_4',
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity_1->getConfigDependencyName()],
|
||||
'module' => ['node', 'config_test'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$entity_4->save();
|
||||
|
||||
\Drupal::state()->set('config_test.fix_dependencies', []);
|
||||
\Drupal::state()->set('config_test.on_dependency_removal_called', []);
|
||||
|
||||
// Do a dry run using
|
||||
// \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval().
|
||||
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('module', ['node']);
|
||||
$config_entity_ids = [
|
||||
'update' => [],
|
||||
'delete' => [],
|
||||
'unchanged' => [],
|
||||
];
|
||||
foreach ($config_entities as $type => $config_entities_by_type) {
|
||||
foreach ($config_entities_by_type as $config_entity) {
|
||||
$config_entity_ids[$type][] = $config_entity->id();
|
||||
}
|
||||
}
|
||||
$expected = [
|
||||
'update' => [$entity_1->id(), $entity_2->id()],
|
||||
'delete' => [$entity_4->id()],
|
||||
'unchanged' => [$entity_3->id()],
|
||||
];
|
||||
$this->assertSame($expected, $config_entity_ids);
|
||||
|
||||
$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->assertSame([$entity_1->id(), $entity_4->id(), $entity_2->id()], $called, 'The most dependent entities have ConfigEntityInterface::onDependencyRemoval() called first.');
|
||||
|
||||
// Perform a module rebuild so we can know where the node module is located
|
||||
// and uninstall it.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
system_rebuild_module_data();
|
||||
// Perform the uninstall.
|
||||
$config_manager->uninstall('module', 'node');
|
||||
|
||||
// Test that expected actions have been performed.
|
||||
$entity_1 = $storage->load($entity_1->id());
|
||||
$this->assertTrue($entity_1, 'Entity 1 not deleted');
|
||||
$this->assertSame($entity_1->getThirdPartySettings('node'), [], 'Entity 1 third party settings updated.');
|
||||
$entity_2 = $storage->load($entity_2->id());
|
||||
$this->assertTrue($entity_2, 'Entity 2 not deleted');
|
||||
$this->assertSame($entity_2->getThirdPartySettings('node'), [], 'Entity 2 third party settings updated.');
|
||||
$this->assertSame($entity_2->calculateDependencies()->getDependencies()['config'], [$entity_1->getConfigDependencyName()], 'Entity 2 still depends on entity 1.');
|
||||
$entity_3 = $storage->load($entity_3->id());
|
||||
$this->assertTrue($entity_3, 'Entity 3 not deleted');
|
||||
$this->assertSame($entity_3->calculateDependencies()->getDependencies()['config'], [$entity_2->getConfigDependencyName()], 'Entity 3 still depends on entity 2.');
|
||||
$this->assertFalse($storage->load($entity_4->id()), 'Entity 4 deleted');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deleting a configuration entity and dependency management.
|
||||
*/
|
||||
@@ -356,20 +475,20 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$storage = $this->container->get('entity.manager')->getStorage('config_test');
|
||||
// Test dependencies between configuration entities.
|
||||
$entity1 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity1'
|
||||
)
|
||||
]
|
||||
);
|
||||
$entity1->save();
|
||||
$entity2 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity2',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity1->getConfigDependencyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity1->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity2->save();
|
||||
|
||||
@@ -387,13 +506,13 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$this->assertFalse($storage->load('entity2'), 'Entity 2 deleted');
|
||||
|
||||
// Set a more complicated test where dependencies will be fixed.
|
||||
\Drupal::state()->set('config_test.fix_dependencies', array($entity1->getConfigDependencyName()));
|
||||
\Drupal::state()->set('config_test.fix_dependencies', [$entity1->getConfigDependencyName()]);
|
||||
|
||||
// Entity1 will be deleted by the test.
|
||||
$entity1 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity1',
|
||||
)
|
||||
]
|
||||
);
|
||||
$entity1->save();
|
||||
|
||||
@@ -401,28 +520,28 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
// \Drupal\config_test\Entity::onDependencyRemoval() will remove the
|
||||
// dependency before config entities are deleted.
|
||||
$entity2 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity2',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity1->getConfigDependencyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity1->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity2->save();
|
||||
|
||||
// Entity3 will be unchanged because it is dependent on Entity2 which can
|
||||
// be fixed.
|
||||
$entity3 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity3',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity2->getConfigDependencyName()),
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity2->getConfigDependencyName()],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity3->save();
|
||||
|
||||
@@ -440,7 +559,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
$this->assertFalse($storage->load('entity1'), 'Entity 1 deleted');
|
||||
$entity2 = $storage->load('entity2');
|
||||
$this->assertTrue($entity2, 'Entity 2 not deleted');
|
||||
$this->assertEqual($entity2->calculateDependencies()->getDependencies()['config'], array(), 'Entity 2 dependencies updated to remove dependency on Entity1.');
|
||||
$this->assertEqual($entity2->calculateDependencies()->getDependencies()['config'], [], 'Entity 2 dependencies updated to remove dependency on Entity1.');
|
||||
$entity3 = $storage->load('entity3');
|
||||
$this->assertTrue($entity3, 'Entity 3 not deleted');
|
||||
$this->assertEqual($entity3->calculateDependencies()->getDependencies()['config'], [$entity2->getConfigDependencyName()], 'Entity 3 still depends on Entity 2.');
|
||||
@@ -466,30 +585,30 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $storage */
|
||||
$storage = $this->container->get('entity.manager')->getStorage('config_test');
|
||||
$entity1 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity1',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'content' => array($content_entity->getConfigDependencyName())
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'content' => [$content_entity->getConfigDependencyName()]
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity1->save();
|
||||
$entity2 = $storage->create(
|
||||
array(
|
||||
[
|
||||
'id' => 'entity2',
|
||||
'dependencies' => array(
|
||||
'enforced' => array(
|
||||
'config' => array($entity1->getConfigDependencyName())
|
||||
),
|
||||
),
|
||||
)
|
||||
'dependencies' => [
|
||||
'enforced' => [
|
||||
'config' => [$entity1->getConfigDependencyName()]
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$entity2->save();
|
||||
|
||||
// Create a configuration entity that is not in the dependency chain.
|
||||
$entity3 = $storage->create(array('id' => 'entity3'));
|
||||
$entity3 = $storage->create(['id' => 'entity3']);
|
||||
$entity3->save();
|
||||
|
||||
$config_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval('content', [$content_entity->getConfigDependencyName()]);
|
||||
@@ -509,7 +628,7 @@ class ConfigDependencyTest extends EntityKernelTestBase {
|
||||
* An array with values of entity_type_id:ID
|
||||
*/
|
||||
protected function getDependentIds(array $dependents) {
|
||||
$dependent_ids = array();
|
||||
$dependent_ids = [];
|
||||
foreach ($dependents as $dependent) {
|
||||
$dependent_ids[] = $dependent->getEntityTypeId() . ':' . $dependent->id();
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test', 'system');
|
||||
public static $modules = ['config_test', 'system'];
|
||||
|
||||
/**
|
||||
* Tests calculating the difference between two sets of configuration.
|
||||
*/
|
||||
function testDiff() {
|
||||
public function testDiff() {
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$config_name = 'config_test.system';
|
||||
@@ -32,7 +32,7 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
$change_data = 'foobar';
|
||||
|
||||
// Install the default config.
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
$original_data = \Drupal::config($config_name)->get();
|
||||
|
||||
// Change a configuration value in sync.
|
||||
@@ -44,9 +44,9 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
// Verify that the diff reflects a change.
|
||||
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
|
||||
$edits = $diff->getEdits();
|
||||
$this->assertEqual($edits[0]->type, 'change', 'The first item in the diff is a change.');
|
||||
$this->assertEqual($edits[0]->orig[0], $change_key . ': ' . $original_data[$change_key], format_string("The active value for key '%change_key' is '%original_data'.", array('%change_key' => $change_key, '%original_data' => $original_data[$change_key])));
|
||||
$this->assertEqual($edits[0]->closing[0], $change_key . ': ' . $change_data, format_string("The sync value for key '%change_key' is '%change_data'.", array('%change_key' => $change_key, '%change_data' => $change_data)));
|
||||
$this->assertYamlEdit($edits, $change_key, 'change',
|
||||
[$change_key . ': ' . $original_data[$change_key]],
|
||||
[$change_key . ': ' . $change_data]);
|
||||
|
||||
// Reset data back to original, and remove a key
|
||||
$sync_data = $original_data;
|
||||
@@ -56,10 +56,11 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
// Verify that the diff reflects a removed key.
|
||||
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
|
||||
$edits = $diff->getEdits();
|
||||
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
|
||||
$this->assertEqual($edits[1]->type, 'delete', 'The second item in the diff is a delete.');
|
||||
$this->assertEqual($edits[1]->orig[0], $remove_key . ': ' . $original_data[$remove_key], format_string("The active value for key '%remove_key' is '%original_data'.", array('%remove_key' => $remove_key, '%original_data' => $original_data[$remove_key])));
|
||||
$this->assertFalse($edits[1]->closing, format_string("The key '%remove_key' does not exist in sync.", array('%remove_key' => $remove_key)));
|
||||
$this->assertYamlEdit($edits, $change_key, 'copy');
|
||||
$this->assertYamlEdit($edits, $remove_key, 'delete',
|
||||
[$remove_key . ': ' . $original_data[$remove_key]],
|
||||
FALSE
|
||||
);
|
||||
|
||||
// Reset data back to original and add a key
|
||||
$sync_data = $original_data;
|
||||
@@ -69,17 +70,15 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
// Verify that the diff reflects an added key.
|
||||
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
|
||||
$edits = $diff->getEdits();
|
||||
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
|
||||
$this->assertEqual($edits[1]->type, 'add', 'The second item in the diff is an add.');
|
||||
$this->assertFalse($edits[1]->orig, format_string("The key '%add_key' does not exist in active.", array('%add_key' => $add_key)));
|
||||
$this->assertEqual($edits[1]->closing[0], $add_key . ': ' . $add_data, format_string("The sync value for key '%add_key' is '%add_data'.", array('%add_key' => $add_key, '%add_data' => $add_data)));
|
||||
$this->assertYamlEdit($edits, $change_key, 'copy');
|
||||
$this->assertYamlEdit($edits, $add_key, 'add', FALSE, [$add_key . ': ' . $add_data]);
|
||||
|
||||
// Test diffing a renamed config entity.
|
||||
$test_entity_id = $this->randomMachineName();
|
||||
$test_entity = entity_create('config_test', array(
|
||||
$test_entity = entity_create('config_test', [
|
||||
'id' => $test_entity_id,
|
||||
'label' => $this->randomMachineName(),
|
||||
));
|
||||
]);
|
||||
$test_entity->save();
|
||||
$data = $active->read('config_test.dynamic.' . $test_entity_id);
|
||||
$sync->write('config_test.dynamic.' . $test_entity_id, $data);
|
||||
@@ -97,10 +96,11 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
|
||||
$diff = \Drupal::service('config.manager')->diff($active, $sync, 'config_test.dynamic.' . $new_test_entity_id, $config_name);
|
||||
$edits = $diff->getEdits();
|
||||
$this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
|
||||
$this->assertEqual($edits[1]->type, 'change', 'The second item in the diff is a change.');
|
||||
$this->assertEqual($edits[1]->orig, array('id: ' . $new_test_entity_id));
|
||||
$this->assertEqual($edits[1]->closing, array('id: ' . $test_entity_id));
|
||||
$this->assertYamlEdit($edits, 'uuid', 'copy');
|
||||
$this->assertYamlEdit($edits, 'id', 'change',
|
||||
['id: ' . $new_test_entity_id],
|
||||
['id: ' . $test_entity_id]);
|
||||
$this->assertYamlEdit($edits, 'label', 'copy');
|
||||
$this->assertEqual($edits[2]->type, 'copy', 'The third item in the diff is a copy.');
|
||||
$this->assertEqual(count($edits), 3, 'There are three items in the diff.');
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests calculating the difference between two sets of config collections.
|
||||
*/
|
||||
function testCollectionDiff() {
|
||||
public function testCollectionDiff() {
|
||||
/** @var \Drupal\Core\Config\StorageInterface $active */
|
||||
$active = $this->container->get('config.storage');
|
||||
/** @var \Drupal\Core\Config\StorageInterface $sync */
|
||||
@@ -117,12 +117,12 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
$sync_test_collection = $sync->createCollection('test');
|
||||
|
||||
$config_name = 'config_test.test';
|
||||
$data = array('foo' => 'bar');
|
||||
$data = ['foo' => 'bar'];
|
||||
|
||||
$active->write($config_name, $data);
|
||||
$sync->write($config_name, $data);
|
||||
$active_test_collection->write($config_name, $data);
|
||||
$sync_test_collection->write($config_name, array('foo' => 'baz'));
|
||||
$sync_test_collection->write($config_name, ['foo' => 'baz']);
|
||||
|
||||
// Test the fields match in the default collection diff.
|
||||
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
|
||||
@@ -133,10 +133,56 @@ class ConfigDiffTest extends KernelTestBase {
|
||||
// Test that the differences are detected when diffing the collection.
|
||||
$diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name, NULL, 'test');
|
||||
$edits = $diff->getEdits();
|
||||
$this->assertEqual($edits[0]->type, 'change', 'The second item in the diff is a copy.');
|
||||
$this->assertEqual($edits[0]->orig, array('foo: bar'));
|
||||
$this->assertEqual($edits[0]->closing, array('foo: baz'));
|
||||
$this->assertEqual($edits[1]->type, 'copy', 'The second item in the diff is a copy.');
|
||||
$this->assertYamlEdit($edits, 'foo', 'change', ['foo: bar'], ['foo: baz']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to test that an edit is found in a diff'd YAML file.
|
||||
*
|
||||
* @param array $edits
|
||||
* A list of edits.
|
||||
* @param string $field
|
||||
* The field key that is being asserted.
|
||||
* @param string $type
|
||||
* The type of edit that is being asserted.
|
||||
* @param mixed $orig
|
||||
* (optional) The original value of of the edit. If not supplied, assertion
|
||||
* is skipped.
|
||||
* @param mixed $closing
|
||||
* (optional) The closing value of of the edit. If not supplied, assertion
|
||||
* is skipped.
|
||||
*/
|
||||
protected function assertYamlEdit(array $edits, $field, $type, $orig = NULL, $closing = NULL) {
|
||||
$match = FALSE;
|
||||
foreach ($edits as $edit) {
|
||||
// Choose which section to search for the field.
|
||||
$haystack = $type == 'add' ? $edit->closing : $edit->orig;
|
||||
// Look through each line and try and find the key.
|
||||
if (is_array($haystack)) {
|
||||
foreach ($haystack as $item) {
|
||||
if (strpos($item, $field . ':') === 0) {
|
||||
$match = TRUE;
|
||||
// Assert that the edit is of the type specified.
|
||||
$this->assertEqual($edit->type, $type, "The $field item in the diff is a $type");
|
||||
// If an original value was given, assert that it matches.
|
||||
if (isset($orig)) {
|
||||
$this->assertIdentical($edit->orig, $orig, "The original value for key '$field' is correct.");
|
||||
}
|
||||
// If a closing value was given, assert that it matches.
|
||||
if (isset($closing)) {
|
||||
$this->assertIdentical($edit->closing, $closing, "The closing value for key '$field' is correct.");
|
||||
}
|
||||
// Break out of the search entirely.
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't match anything, fail.
|
||||
if (!$match) {
|
||||
$this->fail("$field edit was not matched");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class ConfigEntityNormalizeTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test');
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
@@ -24,15 +24,15 @@ class ConfigEntityNormalizeTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
public function testNormalize() {
|
||||
$config_entity = entity_create('config_test', array('id' => 'system', 'label' => 'foobar', 'weight' => 1));
|
||||
$config_entity = entity_create('config_test', ['id' => 'system', 'label' => 'foobar', 'weight' => 1]);
|
||||
$config_entity->save();
|
||||
|
||||
// Modify stored config entity, this is comparable with a schema change.
|
||||
$config = $this->config('config_test.dynamic.system');
|
||||
$data = array(
|
||||
$data = [
|
||||
'label' => 'foobar',
|
||||
'additional_key' => TRUE
|
||||
) + $config->getRawData();
|
||||
] + $config->getRawData();
|
||||
$config->setData($data)->save();
|
||||
$this->assertNotIdentical($config_entity->toArray(), $config->getRawData(), 'Stored config entity is not is equivalent to config schema.');
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class ConfigEntityStaticCacheTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test', 'config_entity_static_cache_test');
|
||||
public static $modules = ['config_test', 'config_entity_static_cache_test'];
|
||||
|
||||
/**
|
||||
* The type ID of the entity under test.
|
||||
@@ -42,7 +42,7 @@ class ConfigEntityStaticCacheTest extends KernelTestBase {
|
||||
$this->entityId = 'test_1';
|
||||
$this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId)
|
||||
->create(array('id' => $this->entityId, 'label' => 'Original label'))
|
||||
->create(['id' => $this->entityId, 'label' => 'Original label'])
|
||||
->save();
|
||||
}
|
||||
|
||||
@@ -50,8 +50,10 @@ class ConfigEntityStaticCacheTest extends KernelTestBase {
|
||||
* Tests that the static cache is working.
|
||||
*/
|
||||
public function testCacheHit() {
|
||||
$entity_1 = entity_load($this->entityTypeId, $this->entityId);
|
||||
$entity_2 = entity_load($this->entityTypeId, $this->entityId);
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId);
|
||||
$entity_1 = $storage->load($this->entityId);
|
||||
$entity_2 = $storage->load($this->entityId);
|
||||
// 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.
|
||||
@@ -62,19 +64,21 @@ class ConfigEntityStaticCacheTest extends KernelTestBase {
|
||||
* Tests that the static cache is reset on entity save and delete.
|
||||
*/
|
||||
public function testReset() {
|
||||
$entity = entity_load($this->entityTypeId, $this->entityId);
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId);
|
||||
$entity = $storage->load($this->entityId);
|
||||
|
||||
// Ensure loading after a save retrieves the updated entity rather than an
|
||||
// obsolete cached one.
|
||||
$entity->label = 'New label';
|
||||
$entity->save();
|
||||
$entity = entity_load($this->entityTypeId, $this->entityId);
|
||||
$entity = $storage->load($this->entityId);
|
||||
$this->assertIdentical($entity->label, 'New label');
|
||||
|
||||
// Ensure loading after a delete retrieves NULL rather than an obsolete
|
||||
// cached one.
|
||||
$entity->delete();
|
||||
$this->assertNull(entity_load($this->entityTypeId, $this->entityId));
|
||||
$this->assertNull($storage->load($this->entityId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,15 +16,15 @@ class ConfigEntityStatusTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test');
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
/**
|
||||
* Tests the enabling/disabling of entities.
|
||||
*/
|
||||
function testCRUD() {
|
||||
$entity = entity_create('config_test', array(
|
||||
public function testCRUD() {
|
||||
$entity = entity_create('config_test', [
|
||||
'id' => strtolower($this->randomMachineName()),
|
||||
));
|
||||
]);
|
||||
$this->assertTrue($entity->status(), 'Default status is enabled.');
|
||||
$entity->save();
|
||||
$this->assertTrue($entity->status(), 'Status is enabled after saving.');
|
||||
|
||||
@@ -18,7 +18,7 @@ class ConfigEntityStorageTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test');
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
/**
|
||||
* Tests creating configuration entities with changed UUIDs.
|
||||
@@ -27,11 +27,10 @@ class ConfigEntityStorageTest extends KernelTestBase {
|
||||
$entity_type = 'config_test';
|
||||
$id = 'test_1';
|
||||
// Load the original configuration entity.
|
||||
$this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(array('id' => $id))
|
||||
->save();
|
||||
$entity = entity_load($entity_type, $id);
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type);
|
||||
$storage->create(['id' => $id])->save();
|
||||
$entity = $storage->load($id);
|
||||
|
||||
$original_properties = $entity->toArray();
|
||||
|
||||
@@ -44,7 +43,7 @@ class ConfigEntityStorageTest extends KernelTestBase {
|
||||
$this->fail('Exception thrown when attempting to save a configuration entity with a UUID that does not match the existing UUID.');
|
||||
}
|
||||
catch (ConfigDuplicateUUIDException $e) {
|
||||
$this->pass(format_string('Exception thrown when attempting to save a configuration entity with a UUID that does not match existing data: %e.', array('%e' => $e)));
|
||||
$this->pass(format_string('Exception thrown when attempting to save a configuration entity with a UUID that does not match existing data: %e.', ['%e' => $e]));
|
||||
}
|
||||
|
||||
// Ensure that the config entity was not corrupted.
|
||||
|
||||
@@ -14,7 +14,7 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
/**
|
||||
* Exempt from strict schema checking.
|
||||
*
|
||||
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
|
||||
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
@@ -25,7 +25,7 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test');
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
/**
|
||||
* The config_test entity storage.
|
||||
@@ -57,19 +57,19 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
// Create three entities, two with the same style.
|
||||
$style = $this->randomMachineName(8);
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$entity = $this->storage->create(array(
|
||||
$entity = $this->storage->create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => $this->randomString(),
|
||||
'style' => $style,
|
||||
));
|
||||
]);
|
||||
$entity->save();
|
||||
}
|
||||
$entity = $this->storage->create(array(
|
||||
$entity = $this->storage->create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => $this->randomString(),
|
||||
// Use a different length for the entity to ensure uniqueness.
|
||||
'style' => $this->randomMachineName(9),
|
||||
));
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
// Ensure that the configuration entity can be loaded by UUID.
|
||||
@@ -85,7 +85,7 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
$entities = $this->storage->loadByProperties();
|
||||
$this->assertEqual(count($entities), 3, 'Three entities are loaded when no properties are specified.');
|
||||
|
||||
$entities = $this->storage->loadByProperties(array('style' => $style));
|
||||
$entities = $this->storage->loadByProperties(['style' => $style]);
|
||||
$this->assertEqual(count($entities), 2, 'Two entities are loaded when the style property is specified.');
|
||||
|
||||
// Assert that both returned entities have a matching style property.
|
||||
@@ -94,11 +94,11 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
// Test that schema type enforcement can be overridden by trusting the data.
|
||||
$entity = $this->storage->create(array(
|
||||
$entity = $this->storage->create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => $this->randomString(),
|
||||
'style' => 999
|
||||
));
|
||||
]);
|
||||
$entity->save();
|
||||
$this->assertIdentical('999', $entity->style);
|
||||
$entity->style = 999;
|
||||
|
||||
@@ -18,64 +18,64 @@ class ConfigEventsTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_events_test');
|
||||
public static $modules = ['config_events_test'];
|
||||
|
||||
/**
|
||||
* Tests configuration events.
|
||||
*/
|
||||
function testConfigEvents() {
|
||||
public function testConfigEvents() {
|
||||
$name = 'config_events_test.test';
|
||||
|
||||
$config = new Config($name, \Drupal::service('config.storage'), \Drupal::service('event_dispatcher'), \Drupal::service('config.typed'));
|
||||
$config->set('key', 'initial');
|
||||
$this->assertIdentical(\Drupal::state()->get('config_events_test.event', array()), array(), 'No events fired by creating a new configuration object');
|
||||
$this->assertIdentical(\Drupal::state()->get('config_events_test.event', []), [], 'No events fired by creating a new configuration object');
|
||||
$config->save();
|
||||
|
||||
$event = \Drupal::state()->get('config_events_test.event', array());
|
||||
$event = \Drupal::state()->get('config_events_test.event', []);
|
||||
$this->assertIdentical($event['event_name'], ConfigEvents::SAVE);
|
||||
$this->assertIdentical($event['current_config_data'], array('key' => 'initial'));
|
||||
$this->assertIdentical($event['raw_config_data'], array('key' => 'initial'));
|
||||
$this->assertIdentical($event['original_config_data'], array());
|
||||
$this->assertIdentical($event['current_config_data'], ['key' => 'initial']);
|
||||
$this->assertIdentical($event['raw_config_data'], ['key' => 'initial']);
|
||||
$this->assertIdentical($event['original_config_data'], []);
|
||||
|
||||
$config->set('key', 'updated')->save();
|
||||
$event = \Drupal::state()->get('config_events_test.event', array());
|
||||
$event = \Drupal::state()->get('config_events_test.event', []);
|
||||
$this->assertIdentical($event['event_name'], ConfigEvents::SAVE);
|
||||
$this->assertIdentical($event['current_config_data'], array('key' => 'updated'));
|
||||
$this->assertIdentical($event['raw_config_data'], array('key' => 'updated'));
|
||||
$this->assertIdentical($event['original_config_data'], array('key' => 'initial'));
|
||||
$this->assertIdentical($event['current_config_data'], ['key' => 'updated']);
|
||||
$this->assertIdentical($event['raw_config_data'], ['key' => 'updated']);
|
||||
$this->assertIdentical($event['original_config_data'], ['key' => 'initial']);
|
||||
|
||||
$config->delete();
|
||||
$event = \Drupal::state()->get('config_events_test.event', array());
|
||||
$event = \Drupal::state()->get('config_events_test.event', []);
|
||||
$this->assertIdentical($event['event_name'], ConfigEvents::DELETE);
|
||||
$this->assertIdentical($event['current_config_data'], array());
|
||||
$this->assertIdentical($event['raw_config_data'], array());
|
||||
$this->assertIdentical($event['original_config_data'], array('key' => 'updated'));
|
||||
$this->assertIdentical($event['current_config_data'], []);
|
||||
$this->assertIdentical($event['raw_config_data'], []);
|
||||
$this->assertIdentical($event['original_config_data'], ['key' => 'updated']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests configuration rename event that is fired from the ConfigFactory.
|
||||
*/
|
||||
function testConfigRenameEvent() {
|
||||
public function testConfigRenameEvent() {
|
||||
$name = 'config_events_test.test';
|
||||
$new_name = 'config_events_test.test_rename';
|
||||
$GLOBALS['config'][$name] = array('key' => 'overridden');
|
||||
$GLOBALS['config'][$new_name] = array('key' => 'new overridden');
|
||||
$GLOBALS['config'][$name] = ['key' => 'overridden'];
|
||||
$GLOBALS['config'][$new_name] = ['key' => 'new overridden'];
|
||||
|
||||
$config = $this->config($name);
|
||||
$config->set('key', 'initial')->save();
|
||||
$event = \Drupal::state()->get('config_events_test.event', array());
|
||||
$event = \Drupal::state()->get('config_events_test.event', []);
|
||||
$this->assertIdentical($event['event_name'], ConfigEvents::SAVE);
|
||||
$this->assertIdentical($event['current_config_data'], array('key' => 'initial'));
|
||||
$this->assertIdentical($event['current_config_data'], ['key' => 'initial']);
|
||||
|
||||
// Override applies when getting runtime config.
|
||||
$this->assertEqual($GLOBALS['config'][$name], \Drupal::config($name)->get());
|
||||
|
||||
\Drupal::configFactory()->rename($name, $new_name);
|
||||
$event = \Drupal::state()->get('config_events_test.event', array());
|
||||
$event = \Drupal::state()->get('config_events_test.event', []);
|
||||
$this->assertIdentical($event['event_name'], ConfigEvents::RENAME);
|
||||
$this->assertIdentical($event['current_config_data'], array('key' => 'new overridden'));
|
||||
$this->assertIdentical($event['raw_config_data'], array('key' => 'initial'));
|
||||
$this->assertIdentical($event['original_config_data'], array('key' => 'new overridden'));
|
||||
$this->assertIdentical($event['current_config_data'], ['key' => 'new overridden']);
|
||||
$this->assertIdentical($event['raw_config_data'], ['key' => 'initial']);
|
||||
$this->assertIdentical($event['original_config_data'], ['key' => 'new overridden']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
/**
|
||||
* Exempt from strict schema checking.
|
||||
*
|
||||
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
|
||||
* @see \Drupal\Core\Config\Development\ConfigSchemaChecker
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
@@ -24,7 +24,7 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests setting, writing, and reading of a configuration setting.
|
||||
*/
|
||||
function testReadWriteConfig() {
|
||||
public function testReadWriteConfig() {
|
||||
$storage = $this->container->get('config.storage');
|
||||
|
||||
$name = 'foo.bar';
|
||||
@@ -33,19 +33,19 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
$nested_key = 'biff.bang';
|
||||
$nested_value = 'pow';
|
||||
$array_key = 'array';
|
||||
$array_value = array(
|
||||
$array_value = [
|
||||
'foo' => 'bar',
|
||||
'biff' => array(
|
||||
'biff' => [
|
||||
'bang' => 'pow',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
$casting_array_key = 'casting_array';
|
||||
$casting_array_false_value_key = 'casting_array.cast.false';
|
||||
$casting_array_value = array(
|
||||
'cast' => array(
|
||||
$casting_array_value = [
|
||||
'cast' => [
|
||||
'false' => FALSE,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
$nested_array_key = 'nested.array';
|
||||
$true_key = 'true';
|
||||
$false_key = 'false';
|
||||
@@ -58,7 +58,7 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
$this->assertTrue($config, 'Config object created.');
|
||||
|
||||
// Verify the configuration object is empty.
|
||||
$this->assertEqual($config->get(), array(), 'New config object is empty.');
|
||||
$this->assertEqual($config->get(), [], 'New config object is empty.');
|
||||
|
||||
// Verify nothing was saved.
|
||||
$data = $storage->read($name);
|
||||
@@ -173,7 +173,7 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
// Get file listing for all files starting with 'bar'. Should return
|
||||
// an empty array.
|
||||
$files = $storage->listAll('bar');
|
||||
$this->assertEqual($files, array(), 'No files listed with the prefix \'bar\'.');
|
||||
$this->assertEqual($files, [], 'No files listed with the prefix \'bar\'.');
|
||||
|
||||
// Delete the configuration.
|
||||
$config = $this->config($name);
|
||||
@@ -187,22 +187,22 @@ class ConfigFileContentTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests serialization of configuration to file.
|
||||
*/
|
||||
function testSerialization() {
|
||||
public function testSerialization() {
|
||||
$name = $this->randomMachineName(10) . '.' . $this->randomMachineName(10);
|
||||
$config_data = array(
|
||||
$config_data = [
|
||||
// Indexed arrays; the order of elements is essential.
|
||||
'numeric keys' => array('i', 'n', 'd', 'e', 'x', 'e', 'd'),
|
||||
'numeric keys' => ['i', 'n', 'd', 'e', 'x', 'e', 'd'],
|
||||
// Infinitely nested keys using arbitrary element names.
|
||||
'nested keys' => array(
|
||||
'nested keys' => [
|
||||
// HTML/XML in values.
|
||||
'HTML' => '<strong> <bold> <em> <blockquote>',
|
||||
// UTF-8 in values.
|
||||
'UTF-8' => 'FrançAIS is ÜBER-åwesome',
|
||||
// Unicode in keys and values.
|
||||
'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ' => 'αβγδεζηθικλμνξοσὠ',
|
||||
),
|
||||
],
|
||||
'invalid xml' => '</title><script type="text/javascript">alert("Title XSS!");</script> & < > " \' ',
|
||||
);
|
||||
];
|
||||
|
||||
// Encode and write, and reload and decode the configuration data.
|
||||
$filestorage = new FileStorage(config_get_config_directory(CONFIG_SYNC_DIRECTORY));
|
||||
|
||||
@@ -33,7 +33,7 @@ class ConfigImportRecreateTest extends KernelTestBase {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(array('field', 'node'));
|
||||
$this->installConfig(['field', 'node']);
|
||||
|
||||
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(array('field'));
|
||||
$this->installConfig(['field']);
|
||||
|
||||
// Set up the ConfigImporter object for testing.
|
||||
$storage_comparer = new StorageComparer(
|
||||
@@ -67,10 +67,10 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
public function testRenameValidation() {
|
||||
// Create a test entity.
|
||||
$test_entity_id = $this->randomMachineName();
|
||||
$test_entity = entity_create('config_test', array(
|
||||
$test_entity = entity_create('config_test', [
|
||||
'id' => $test_entity_id,
|
||||
'label' => $this->randomMachineName(),
|
||||
));
|
||||
]);
|
||||
$test_entity->save();
|
||||
$uuid = $test_entity->uuid();
|
||||
|
||||
@@ -91,9 +91,9 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
// Confirm that the staged configuration is detected as a rename since the
|
||||
// UUIDs match.
|
||||
$this->configImporter->reset();
|
||||
$expected = array(
|
||||
$expected = [
|
||||
'node.type.' . $content_type->id() . '::config_test.dynamic.' . $test_entity_id,
|
||||
);
|
||||
];
|
||||
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
|
||||
$this->assertIdentical($expected, $renames);
|
||||
|
||||
@@ -105,9 +105,9 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
}
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->pass('Expected ConfigImporterException thrown when a renamed configuration entity does not match the existing entity type.');
|
||||
$expected = array(
|
||||
SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', array('@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id))
|
||||
);
|
||||
$expected = [
|
||||
SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', ['@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id])
|
||||
];
|
||||
$this->assertEqual($expected, $this->configImporter->getErrors());
|
||||
}
|
||||
}
|
||||
@@ -134,9 +134,9 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
// Confirm that the staged configuration is detected as a rename since the
|
||||
// UUIDs match.
|
||||
$this->configImporter->reset();
|
||||
$expected = array(
|
||||
$expected = [
|
||||
'config_test.old::config_test.new'
|
||||
);
|
||||
];
|
||||
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
|
||||
$this->assertIdentical($expected, $renames);
|
||||
|
||||
@@ -148,9 +148,9 @@ class ConfigImportRenameValidationTest extends KernelTestBase {
|
||||
}
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->pass('Expected ConfigImporterException thrown when simple configuration is renamed.');
|
||||
$expected = array(
|
||||
SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', array('@old_name' => 'config_test.old', '@new_name' => 'config_test.new'))
|
||||
);
|
||||
$expected = [
|
||||
SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', ['@old_name' => 'config_test.old', '@new_name' => 'config_test.new'])
|
||||
];
|
||||
$this->assertEqual($expected, $this->configImporter->getErrors());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@ class ConfigImporterMissingContentTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'user', 'entity_test', 'config_test', 'config_import_test');
|
||||
public static $modules = ['system', 'user', 'entity_test', 'config_test', 'config_import_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('system', 'sequences');
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
// Installing config_test's default configuration pollutes the global
|
||||
// variable being used for recording hook invocations by this test already,
|
||||
// so it has to be cleared out manually.
|
||||
@@ -66,16 +66,16 @@ class ConfigImporterMissingContentTest extends KernelTestBase {
|
||||
* @see \Drupal\Core\Config\ConfigImporter::processMissingContent()
|
||||
* @see \Drupal\config_import_test\EventSubscriber
|
||||
*/
|
||||
function testMissingContent() {
|
||||
public function testMissingContent() {
|
||||
\Drupal::state()->set('config_import_test.config_import_missing_content', TRUE);
|
||||
|
||||
// Update a configuration entity in the sync directory to have a dependency
|
||||
// on two content entities that do not exist.
|
||||
$storage = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$entity_one = EntityTest::create(array('name' => 'one'));
|
||||
$entity_two = EntityTest::create(array('name' => 'two'));
|
||||
$entity_three = EntityTest::create(array('name' => 'three'));
|
||||
$entity_one = EntityTest::create(['name' => 'one']);
|
||||
$entity_two = EntityTest::create(['name' => 'two']);
|
||||
$entity_three = EntityTest::create(['name' => 'three']);
|
||||
$dynamic_name = 'config_test.dynamic.dotted.default';
|
||||
$original_dynamic_data = $storage->read($dynamic_name);
|
||||
// Entity one will be resolved by
|
||||
|
||||
@@ -28,12 +28,12 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test', 'system', 'config_import_test');
|
||||
public static $modules = ['config_test', 'system', 'config_import_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
// Installing config_test's default configuration pollutes the global
|
||||
// variable being used for recording hook invocations by this test already,
|
||||
// so it has to be cleared out manually.
|
||||
@@ -63,7 +63,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests omission of module APIs for bare configuration operations.
|
||||
*/
|
||||
function testNoImport() {
|
||||
public function testNoImport() {
|
||||
$dynamic_name = 'config_test.dynamic.dotted.default';
|
||||
|
||||
// Verify the default configuration values exist.
|
||||
@@ -78,7 +78,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
* Tests that trying to import from an empty sync configuration directory
|
||||
* fails.
|
||||
*/
|
||||
function testEmptyImportFails() {
|
||||
public function testEmptyImportFails() {
|
||||
try {
|
||||
$this->container->get('config.storage.sync')->deleteAll();
|
||||
$this->configImporter->reset()->import();
|
||||
@@ -92,7 +92,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests verification of site UUID before importing configuration.
|
||||
*/
|
||||
function testSiteUuidValidate() {
|
||||
public function testSiteUuidValidate() {
|
||||
$sync = \Drupal::service('config.storage.sync');
|
||||
// Create updated configuration object.
|
||||
$config_data = $this->config('system.site')->get();
|
||||
@@ -106,7 +106,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
|
||||
$error_log = $this->configImporter->getErrors();
|
||||
$expected = array('Site UUID in source storage does not match the target storage.');
|
||||
$expected = ['Site UUID in source storage does not match the target storage.'];
|
||||
$this->assertEqual($expected, $error_log);
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests deletion of configuration during import.
|
||||
*/
|
||||
function testDeleted() {
|
||||
public function testDeleted() {
|
||||
$dynamic_name = 'config_test.dynamic.dotted.default';
|
||||
$storage = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
@@ -151,7 +151,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests creation of configuration during import.
|
||||
*/
|
||||
function testNew() {
|
||||
public function testNew() {
|
||||
$dynamic_name = 'config_test.dynamic.new';
|
||||
$storage = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
@@ -160,11 +160,11 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
$this->assertIdentical($storage->exists($dynamic_name), FALSE, $dynamic_name . ' not found.');
|
||||
|
||||
// Create new config entity.
|
||||
$original_dynamic_data = array(
|
||||
$original_dynamic_data = [
|
||||
'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651',
|
||||
'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(),
|
||||
'status' => TRUE,
|
||||
'dependencies' => array(),
|
||||
'dependencies' => [],
|
||||
'id' => 'new',
|
||||
'label' => 'New',
|
||||
'weight' => 0,
|
||||
@@ -172,7 +172,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
'size' => '',
|
||||
'size_value' => '',
|
||||
'protected_property' => '',
|
||||
);
|
||||
];
|
||||
$sync->write($dynamic_name, $original_dynamic_data);
|
||||
|
||||
$this->assertIdentical($sync->exists($dynamic_name), TRUE, $dynamic_name . ' found.');
|
||||
@@ -205,29 +205,29 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests that secondary writes are overwritten.
|
||||
*/
|
||||
function testSecondaryWritePrimaryFirst() {
|
||||
public function testSecondaryWritePrimaryFirst() {
|
||||
$name_primary = 'config_test.dynamic.primary';
|
||||
$name_secondary = 'config_test.dynamic.secondary';
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$uuid = $this->container->get('uuid');
|
||||
|
||||
$values_primary = array(
|
||||
$values_primary = [
|
||||
'id' => 'primary',
|
||||
'label' => 'Primary',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
);
|
||||
];
|
||||
$sync->write($name_primary, $values_primary);
|
||||
$values_secondary = array(
|
||||
$values_secondary = [
|
||||
'id' => 'secondary',
|
||||
'label' => 'Secondary Sync',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
// Add a dependency on primary, to ensure that is synced first.
|
||||
'dependencies' => array(
|
||||
'config' => array($name_primary),
|
||||
)
|
||||
);
|
||||
'dependencies' => [
|
||||
'config' => [$name_primary],
|
||||
]
|
||||
];
|
||||
$sync->write($name_secondary, $values_secondary);
|
||||
|
||||
// Import.
|
||||
@@ -245,35 +245,35 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
|
||||
$logs = $this->configImporter->getErrors();
|
||||
$this->assertEqual(count($logs), 1);
|
||||
$this->assertEqual($logs[0], SafeMarkup::format('Deleted and replaced configuration entity "@name"', array('@name' => $name_secondary)));
|
||||
$this->assertEqual($logs[0], SafeMarkup::format('Deleted and replaced configuration entity "@name"', ['@name' => $name_secondary]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that secondary writes are overwritten.
|
||||
*/
|
||||
function testSecondaryWriteSecondaryFirst() {
|
||||
public function testSecondaryWriteSecondaryFirst() {
|
||||
$name_primary = 'config_test.dynamic.primary';
|
||||
$name_secondary = 'config_test.dynamic.secondary';
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$uuid = $this->container->get('uuid');
|
||||
|
||||
$values_primary = array(
|
||||
$values_primary = [
|
||||
'id' => 'primary',
|
||||
'label' => 'Primary',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
// Add a dependency on secondary, so that is synced first.
|
||||
'dependencies' => array(
|
||||
'config' => array($name_secondary),
|
||||
)
|
||||
);
|
||||
'dependencies' => [
|
||||
'config' => [$name_secondary],
|
||||
]
|
||||
];
|
||||
$sync->write($name_primary, $values_primary);
|
||||
$values_secondary = array(
|
||||
$values_secondary = [
|
||||
'id' => 'secondary',
|
||||
'label' => 'Secondary Sync',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
);
|
||||
];
|
||||
$sync->write($name_secondary, $values_secondary);
|
||||
|
||||
// Import.
|
||||
@@ -297,7 +297,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests that secondary updates for deleted files work as expected.
|
||||
*/
|
||||
function testSecondaryUpdateDeletedDeleterFirst() {
|
||||
public function testSecondaryUpdateDeletedDeleterFirst() {
|
||||
$name_deleter = 'config_test.dynamic.deleter';
|
||||
$name_deletee = 'config_test.dynamic.deletee';
|
||||
$name_other = 'config_test.dynamic.other';
|
||||
@@ -305,52 +305,52 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$uuid = $this->container->get('uuid');
|
||||
|
||||
$values_deleter = array(
|
||||
$values_deleter = [
|
||||
'id' => 'deleter',
|
||||
'label' => 'Deleter',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
);
|
||||
];
|
||||
$storage->write($name_deleter, $values_deleter);
|
||||
$values_deleter['label'] = 'Updated Deleter';
|
||||
$sync->write($name_deleter, $values_deleter);
|
||||
$values_deletee = array(
|
||||
$values_deletee = [
|
||||
'id' => 'deletee',
|
||||
'label' => 'Deletee',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
// Add a dependency on deleter, to make sure that is synced first.
|
||||
'dependencies' => array(
|
||||
'config' => array($name_deleter),
|
||||
)
|
||||
);
|
||||
'dependencies' => [
|
||||
'config' => [$name_deleter],
|
||||
]
|
||||
];
|
||||
$storage->write($name_deletee, $values_deletee);
|
||||
$values_deletee['label'] = 'Updated Deletee';
|
||||
$sync->write($name_deletee, $values_deletee);
|
||||
|
||||
// Ensure that import will continue after the error.
|
||||
$values_other = array(
|
||||
$values_other = [
|
||||
'id' => 'other',
|
||||
'label' => 'Other',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
// Add a dependency on deleter, to make sure that is synced first. This
|
||||
// will also be synced after the deletee due to alphabetical ordering.
|
||||
'dependencies' => array(
|
||||
'config' => array($name_deleter),
|
||||
)
|
||||
);
|
||||
'dependencies' => [
|
||||
'config' => [$name_deleter],
|
||||
]
|
||||
];
|
||||
$storage->write($name_other, $values_other);
|
||||
$values_other['label'] = 'Updated other';
|
||||
$sync->write($name_other, $values_other);
|
||||
|
||||
// Check update changelist order.
|
||||
$updates = $this->configImporter->reset()->getStorageComparer()->getChangelist('update');
|
||||
$expected = array(
|
||||
$expected = [
|
||||
$name_deleter,
|
||||
$name_deletee,
|
||||
$name_other,
|
||||
);
|
||||
];
|
||||
$this->assertIdentical($expected, $updates);
|
||||
|
||||
// Import.
|
||||
@@ -373,7 +373,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
|
||||
$logs = $this->configImporter->getErrors();
|
||||
$this->assertEqual(count($logs), 1);
|
||||
$this->assertEqual($logs[0], SafeMarkup::format('Update target "@name" is missing.', array('@name' => $name_deletee)));
|
||||
$this->assertEqual($logs[0], SafeMarkup::format('Update target "@name" is missing.', ['@name' => $name_deletee]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,32 +383,32 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
* configuration tree imports. Therefore, any configuration updates that cause
|
||||
* secondary deletes should be reflected already in the staged configuration.
|
||||
*/
|
||||
function testSecondaryUpdateDeletedDeleteeFirst() {
|
||||
public function testSecondaryUpdateDeletedDeleteeFirst() {
|
||||
$name_deleter = 'config_test.dynamic.deleter';
|
||||
$name_deletee = 'config_test.dynamic.deletee';
|
||||
$storage = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$uuid = $this->container->get('uuid');
|
||||
|
||||
$values_deleter = array(
|
||||
$values_deleter = [
|
||||
'id' => 'deleter',
|
||||
'label' => 'Deleter',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
// Add a dependency on deletee, to make sure that is synced first.
|
||||
'dependencies' => array(
|
||||
'config' => array($name_deletee),
|
||||
),
|
||||
);
|
||||
'dependencies' => [
|
||||
'config' => [$name_deletee],
|
||||
],
|
||||
];
|
||||
$storage->write($name_deleter, $values_deleter);
|
||||
$values_deleter['label'] = 'Updated Deleter';
|
||||
$sync->write($name_deleter, $values_deleter);
|
||||
$values_deletee = array(
|
||||
$values_deletee = [
|
||||
'id' => 'deletee',
|
||||
'label' => 'Deletee',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
);
|
||||
];
|
||||
$storage->write($name_deletee, $values_deletee);
|
||||
$values_deletee['label'] = 'Updated Deletee';
|
||||
$sync->write($name_deletee, $values_deletee);
|
||||
@@ -429,30 +429,30 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests that secondary deletes for deleted files work as expected.
|
||||
*/
|
||||
function testSecondaryDeletedDeleteeSecond() {
|
||||
public function testSecondaryDeletedDeleteeSecond() {
|
||||
$name_deleter = 'config_test.dynamic.deleter';
|
||||
$name_deletee = 'config_test.dynamic.deletee';
|
||||
$storage = $this->container->get('config.storage');
|
||||
|
||||
$uuid = $this->container->get('uuid');
|
||||
|
||||
$values_deleter = array(
|
||||
$values_deleter = [
|
||||
'id' => 'deleter',
|
||||
'label' => 'Deleter',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
// Add a dependency on deletee, to make sure this delete is synced first.
|
||||
'dependencies' => array(
|
||||
'config' => array($name_deletee),
|
||||
),
|
||||
);
|
||||
'dependencies' => [
|
||||
'config' => [$name_deletee],
|
||||
],
|
||||
];
|
||||
$storage->write($name_deleter, $values_deleter);
|
||||
$values_deletee = array(
|
||||
$values_deletee = [
|
||||
'id' => 'deletee',
|
||||
'label' => 'Deletee',
|
||||
'weight' => 0,
|
||||
'uuid' => $uuid->generate(),
|
||||
);
|
||||
];
|
||||
$storage->write($name_deletee, $values_deletee);
|
||||
|
||||
// Import.
|
||||
@@ -471,7 +471,7 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests updating of configuration during import.
|
||||
*/
|
||||
function testUpdated() {
|
||||
public function testUpdated() {
|
||||
$name = 'config_test.system';
|
||||
$dynamic_name = 'config_test.dynamic.dotted.default';
|
||||
$storage = $this->container->get('config.storage');
|
||||
@@ -483,9 +483,9 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
|
||||
// Replace the file content of the existing configuration objects in the
|
||||
// sync directory.
|
||||
$original_name_data = array(
|
||||
$original_name_data = [
|
||||
'foo' => 'beer',
|
||||
);
|
||||
];
|
||||
$sync->write($name, $original_name_data);
|
||||
$original_dynamic_data = $storage->read($dynamic_name);
|
||||
$original_dynamic_data['label'] = 'Updated';
|
||||
@@ -528,11 +528,11 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests the isInstallable method()
|
||||
*/
|
||||
function testIsInstallable() {
|
||||
public function testIsInstallable() {
|
||||
$config_name = 'config_test.dynamic.isinstallable';
|
||||
$this->assertFalse($this->container->get('config.storage')->exists($config_name));
|
||||
\Drupal::state()->set('config_test.isinstallable', TRUE);
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
$this->assertTrue($this->container->get('config.storage')->exists($config_name));
|
||||
}
|
||||
|
||||
@@ -668,6 +668,34 @@ class ConfigImporterTest extends KernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests install profile validation during configuration import.
|
||||
*
|
||||
* @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
|
||||
*/
|
||||
public function testInstallProfileMisMatch() {
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
|
||||
$extensions = $sync->read('core.extension');
|
||||
// Change the install profile.
|
||||
$extensions['profile'] = 'this_will_not_work';
|
||||
$sync->write('core.extension', $extensions);
|
||||
|
||||
try {
|
||||
$this->configImporter->reset()->import();
|
||||
$this->fail('ConfigImporterException not thrown; an invalid import was not stopped due to missing dependencies.');
|
||||
}
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
|
||||
$error_log = $this->configImporter->getErrors();
|
||||
// Install profiles can not be changed. Note that KernelTestBase currently
|
||||
// does not use an install profile. This situation should be impossible
|
||||
// to get in but site's can removed the install profile setting from
|
||||
// settings.php so the test is valid.
|
||||
$this->assertEqual(['Cannot change the install profile from <em class="placeholder">this_will_not_work</em> to <em class="placeholder"></em> once Drupal is installed.'], $error_log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests config_get_config_directory().
|
||||
*/
|
||||
|
||||
@@ -34,7 +34,7 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests module installation.
|
||||
*/
|
||||
function testModuleInstallation() {
|
||||
public function testModuleInstallation() {
|
||||
$default_config = 'config_test.system';
|
||||
$default_configuration_entity = 'config_test.dynamic.dotted.default';
|
||||
|
||||
@@ -49,7 +49,7 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
|
||||
|
||||
// Install the test module.
|
||||
$this->installModules(array('config_test'));
|
||||
$this->installModules(['config_test']);
|
||||
|
||||
// Verify that default module config exists.
|
||||
\Drupal::configFactory()->reset($default_config);
|
||||
@@ -69,14 +69,14 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
$this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
|
||||
|
||||
// Install the schema test module.
|
||||
$this->enableModules(array('config_schema_test'));
|
||||
$this->installConfig(array('config_schema_test'));
|
||||
$this->enableModules(['config_schema_test']);
|
||||
$this->installConfig(['config_schema_test']);
|
||||
|
||||
// After module installation the new schema should exist.
|
||||
$this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.');
|
||||
|
||||
// Test that uninstalling configuration removes configuration schema.
|
||||
$this->config('core.extension')->set('module', array())->save();
|
||||
$this->config('core.extension')->set('module', [])->save();
|
||||
\Drupal::service('config.manager')->uninstall('module', 'config_test');
|
||||
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
|
||||
}
|
||||
@@ -86,28 +86,28 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
*/
|
||||
public function testCollectionInstallationNoCollections() {
|
||||
// Install the test module.
|
||||
$this->enableModules(array('config_collection_install_test'));
|
||||
$this->installConfig(array('config_collection_install_test'));
|
||||
$this->enableModules(['config_collection_install_test']);
|
||||
$this->installConfig(['config_collection_install_test']);
|
||||
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
|
||||
$active_storage = \Drupal::service('config.storage');
|
||||
$this->assertEqual(array(), $active_storage->getAllCollectionNames());
|
||||
$this->assertEqual([], $active_storage->getAllCollectionNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests config objects in collections are installed as expected.
|
||||
*/
|
||||
public function testCollectionInstallationCollections() {
|
||||
$collections = array(
|
||||
$collections = [
|
||||
'another_collection',
|
||||
'collection.test1',
|
||||
'collection.test2',
|
||||
);
|
||||
];
|
||||
// Set the event listener to return three possible collections.
|
||||
// @see \Drupal\config_collection_install_test\EventSubscriber
|
||||
\Drupal::state()->set('config_collection_install_test.collection_names', $collections);
|
||||
// Install the test module.
|
||||
$this->enableModules(array('config_collection_install_test'));
|
||||
$this->installConfig(array('config_collection_install_test'));
|
||||
$this->enableModules(['config_collection_install_test']);
|
||||
$this->installConfig(['config_collection_install_test']);
|
||||
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
|
||||
$active_storage = \Drupal::service('config.storage');
|
||||
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
|
||||
@@ -140,20 +140,20 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
// is not enabled.
|
||||
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
|
||||
// Enable the 'config_test' module and try again.
|
||||
$this->enableModules(array('config_test'));
|
||||
$this->enableModules(['config_test']);
|
||||
\Drupal::service('config.installer')->installCollectionDefaultConfig('entity');
|
||||
$collections[] = 'entity';
|
||||
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
|
||||
$collection_storage = $active_storage->createCollection('entity');
|
||||
$data = $collection_storage->read('config_test.dynamic.dotted.default');
|
||||
$this->assertIdentical(array('label' => 'entity'), $data);
|
||||
$this->assertIdentical(['label' => 'entity'], $data);
|
||||
|
||||
// Test that the config manager uninstalls configuration from collections
|
||||
// as expected.
|
||||
\Drupal::service('config.manager')->uninstall('module', 'config_collection_install_test');
|
||||
$this->assertEqual(array('entity'), $active_storage->getAllCollectionNames());
|
||||
$this->assertEqual(['entity'], $active_storage->getAllCollectionNames());
|
||||
\Drupal::service('config.manager')->uninstall('module', 'config_test');
|
||||
$this->assertEqual(array(), $active_storage->getAllCollectionNames());
|
||||
$this->assertEqual([], $active_storage->getAllCollectionNames());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,12 +165,12 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
* using simple configuration.
|
||||
*/
|
||||
public function testCollectionInstallationCollectionConfigEntity() {
|
||||
$collections = array(
|
||||
$collections = [
|
||||
'entity',
|
||||
);
|
||||
];
|
||||
\Drupal::state()->set('config_collection_install_test.collection_names', $collections);
|
||||
// Install the test module.
|
||||
$this->installModules(array('config_test', 'config_collection_install_test'));
|
||||
$this->installModules(['config_test', 'config_collection_install_test']);
|
||||
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
|
||||
$active_storage = \Drupal::service('config.storage');
|
||||
$this->assertEqual($collections, $active_storage->getAllCollectionNames());
|
||||
@@ -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(array('label' => 'entity'), $data);
|
||||
$this->assertIdentical(['label' => 'entity'], $data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,8 +199,27 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
}
|
||||
catch (UnmetDependenciesException $e) {
|
||||
$this->assertEqual($e->getExtension(), 'config_install_dependency_test');
|
||||
$this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency']);
|
||||
$this->assertEqual($e->getMessage(), 'Configuration objects (config_test.dynamic.other_module_test_with_dependency) provided by config_install_dependency_test have unmet dependencies');
|
||||
$this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test', 'config_test.dynamic.dotted.english']]);
|
||||
$this->assertEqual($e->getMessage(), 'Configuration objects provided by <em class="placeholder">config_install_dependency_test</em> have unmet dependencies: <em class="placeholder">config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test, config_test.dynamic.dotted.english)</em>');
|
||||
}
|
||||
try {
|
||||
$this->installModules(['config_install_double_dependency_test']);
|
||||
$this->fail('Expected UnmetDependenciesException not thrown.');
|
||||
}
|
||||
catch (UnmetDependenciesException $e) {
|
||||
$this->assertEquals('config_install_double_dependency_test', $e->getExtension());
|
||||
$this->assertEquals(['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test', 'config_test.dynamic.dotted.english']], $e->getConfigObjects());
|
||||
$this->assertEquals('Configuration objects provided by <em class="placeholder">config_install_double_dependency_test</em> have unmet dependencies: <em class="placeholder">config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test, config_test.dynamic.dotted.english)</em>', $e->getMessage());
|
||||
}
|
||||
$this->installModules(['config_test_language']);
|
||||
try {
|
||||
$this->installModules(['config_install_dependency_test']);
|
||||
$this->fail('Expected UnmetDependenciesException not thrown.');
|
||||
}
|
||||
catch (UnmetDependenciesException $e) {
|
||||
$this->assertEqual($e->getExtension(), 'config_install_dependency_test');
|
||||
$this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test']]);
|
||||
$this->assertEqual($e->getMessage(), 'Configuration objects provided by <em class="placeholder">config_install_dependency_test</em> have unmet dependencies: <em class="placeholder">config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test)</em>');
|
||||
}
|
||||
$this->installModules(['config_other_module_config_test']);
|
||||
$this->installModules(['config_install_dependency_test']);
|
||||
@@ -214,7 +233,7 @@ class ConfigInstallTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests imported configuration entities with and without language information.
|
||||
*/
|
||||
function testLanguage() {
|
||||
public function testLanguage() {
|
||||
$this->installModules(['config_test_language']);
|
||||
// Test imported configuration with implicit language code.
|
||||
$storage = new InstallStorage();
|
||||
|
||||
@@ -17,20 +17,20 @@ class ConfigLanguageOverrideTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('user', 'language', 'config_test', 'system', 'field');
|
||||
public static $modules = ['user', 'language', 'config_test', 'system', 'field'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests locale override based on language.
|
||||
*/
|
||||
function testConfigLanguageOverride() {
|
||||
public function testConfigLanguageOverride() {
|
||||
// The language module implements a config factory override object that
|
||||
// overrides configuration when the Language module is enabled. This test ensures that
|
||||
// English overrides work.
|
||||
@@ -68,40 +68,40 @@ class ConfigLanguageOverrideTest extends KernelTestBase {
|
||||
// Test how overrides react to base configuration changes. Set up some base
|
||||
// values.
|
||||
\Drupal::configFactory()->getEditable('config_test.foo')
|
||||
->set('value', array('key' => 'original'))
|
||||
->set('value', ['key' => 'original'])
|
||||
->set('label', 'Original')
|
||||
->save();
|
||||
\Drupal::languageManager()
|
||||
->getLanguageConfigOverride('de', 'config_test.foo')
|
||||
->set('value', array('key' => 'override'))
|
||||
->set('value', ['key' => 'override'])
|
||||
->set('label', 'Override')
|
||||
->save();
|
||||
\Drupal::languageManager()
|
||||
->getLanguageConfigOverride('fr', 'config_test.foo')
|
||||
->set('value', array('key' => 'override'))
|
||||
->set('value', ['key' => 'override'])
|
||||
->save();
|
||||
\Drupal::configFactory()->clearStaticCache();
|
||||
$config = \Drupal::config('config_test.foo');
|
||||
$this->assertIdentical($config->get('value'), array('key' => 'override'));
|
||||
$this->assertIdentical($config->get('value'), ['key' => 'override']);
|
||||
|
||||
// Ensure renaming the config will rename the override.
|
||||
\Drupal::languageManager()->setConfigOverrideLanguage(\Drupal::languageManager()->getLanguage('en'));
|
||||
\Drupal::configFactory()->rename('config_test.foo', 'config_test.bar');
|
||||
$config = \Drupal::config('config_test.bar');
|
||||
$this->assertEqual($config->get('value'), array('key' => 'original'));
|
||||
$this->assertEqual($config->get('value'), ['key' => 'original']);
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.foo');
|
||||
$this->assertTrue($override->isNew());
|
||||
$this->assertEqual($override->get('value'), NULL);
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
|
||||
$this->assertFalse($override->isNew());
|
||||
$this->assertEqual($override->get('value'), array('key' => 'override'));
|
||||
$this->assertEqual($override->get('value'), ['key' => 'override']);
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'config_test.bar');
|
||||
$this->assertFalse($override->isNew());
|
||||
$this->assertEqual($override->get('value'), array('key' => 'override'));
|
||||
$this->assertEqual($override->get('value'), ['key' => 'override']);
|
||||
|
||||
// Ensure changing data in the config will update the overrides.
|
||||
$config = \Drupal::configFactory()->getEditable('config_test.bar')->clear('value.key')->save();
|
||||
$this->assertEqual($config->get('value'), array());
|
||||
$this->assertEqual($config->get('value'), []);
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
|
||||
$this->assertFalse($override->isNew());
|
||||
$this->assertEqual($override->get('value'), NULL);
|
||||
|
||||
@@ -16,7 +16,7 @@ class ConfigModuleOverridesTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'config', 'config_override_test');
|
||||
public static $modules = ['system', 'config', 'config_override_test'];
|
||||
|
||||
public function testSimpleModuleOverrides() {
|
||||
$GLOBALS['config_test_run_module_overrides'] = TRUE;
|
||||
|
||||
@@ -16,7 +16,7 @@ class ConfigOverrideTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'config_test');
|
||||
public static $modules = ['system', 'config_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
@@ -26,12 +26,12 @@ class ConfigOverrideTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests configuration override.
|
||||
*/
|
||||
function testConfOverride() {
|
||||
$expected_original_data = array(
|
||||
public function testConfOverride() {
|
||||
$expected_original_data = [
|
||||
'foo' => 'bar',
|
||||
'baz' => NULL,
|
||||
'404' => 'herp',
|
||||
);
|
||||
];
|
||||
|
||||
// Set globals before installing to prove that the installed file does not
|
||||
// contain these values.
|
||||
@@ -40,7 +40,7 @@ class ConfigOverrideTest extends KernelTestBase {
|
||||
$overrides['config_test.system']['404'] = 'derp';
|
||||
$GLOBALS['config'] = $overrides;
|
||||
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
|
||||
// Verify that the original configuration data exists. Have to read storage
|
||||
// directly otherwise overrides will apply.
|
||||
@@ -90,10 +90,10 @@ class ConfigOverrideTest extends KernelTestBase {
|
||||
|
||||
// Write file to sync.
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$expected_new_data = array(
|
||||
$expected_new_data = [
|
||||
'foo' => 'barbar',
|
||||
'404' => 'herpderp',
|
||||
);
|
||||
];
|
||||
$sync->write('config_test.system', $expected_new_data);
|
||||
|
||||
// Import changed data from sync to active.
|
||||
|
||||
@@ -18,7 +18,7 @@ class ConfigOverridesPriorityTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'config', 'config_override_test', 'language');
|
||||
public static $modules = ['system', 'config', 'config_override_test', 'language'];
|
||||
|
||||
public function testOverridePriorities() {
|
||||
$GLOBALS['config_test_run_module_overrides'] = FALSE;
|
||||
@@ -50,10 +50,10 @@ class ConfigOverridesPriorityTest extends KernelTestBase {
|
||||
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
|
||||
|
||||
// Override using language.
|
||||
$language = new Language(array(
|
||||
$language = new Language([
|
||||
'name' => 'French',
|
||||
'id' => 'fr',
|
||||
));
|
||||
]);
|
||||
\Drupal::languageManager()->setConfigOverrideLanguage($language);
|
||||
\Drupal::languageManager()
|
||||
->getLanguageConfigOverride($language->getId(), 'system.site')
|
||||
|
||||
@@ -5,6 +5,10 @@ namespace Drupal\KernelTests\Core\Config;
|
||||
use Drupal\Core\Config\FileStorage;
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\Config\Schema\ConfigSchemaAlterException;
|
||||
use Drupal\Core\Config\Schema\Ignore;
|
||||
use Drupal\Core\Config\Schema\Mapping;
|
||||
use Drupal\Core\Config\Schema\Undefined;
|
||||
use Drupal\Core\TypedData\Plugin\DataType\StringData;
|
||||
use Drupal\Core\TypedData\Type\IntegerInterface;
|
||||
use Drupal\Core\TypedData\Type\StringInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
@@ -21,26 +25,26 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'language', 'field', 'image', 'config_test', 'config_schema_test');
|
||||
public static $modules = ['system', 'language', 'field', 'image', 'config_test', 'config_schema_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('system', 'image', 'config_schema_test'));
|
||||
$this->installConfig(['system', 'image', 'config_schema_test']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the basic metadata retrieval layer.
|
||||
*/
|
||||
function testSchemaMapping() {
|
||||
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'));
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key');
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Undefined';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
|
||||
@@ -53,14 +57,14 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
// Configuration file with only some schema.
|
||||
$this->assertIdentical(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'));
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema');
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Schema test data';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['mapping']['langcode']['type'] = 'string';
|
||||
$expected['mapping']['langcode']['label'] = 'Language code';
|
||||
$expected['mapping']['_core']['type'] = '_core_config_info';
|
||||
$expected['mapping']['testitem'] = array('label' => 'Test item');
|
||||
$expected['mapping']['testlist'] = array('label' => 'Test list');
|
||||
$expected['mapping']['testitem'] = ['label' => 'Test item'];
|
||||
$expected['mapping']['testlist'] = ['label' => 'Test list'];
|
||||
$expected['type'] = 'config_schema_test.someschema';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.');
|
||||
@@ -68,40 +72,40 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
// Check type detection on elements with undefined types.
|
||||
$config = \Drupal::service('config.typed')->get('config_schema_test.someschema');
|
||||
$definition = $config->get('testitem')->getDataDefinition()->toArray();
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Test item';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
|
||||
$definition = $config->get('testlist')->getDataDefinition()->toArray();
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Test list';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
|
||||
$definition = $config->get('testnoschema')->getDataDefinition()->toArray();
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Undefined';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
|
||||
$expected['class'] = Undefined::class;
|
||||
$expected['type'] = 'undefined';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$this->assertEqual($definition, $expected, 'Automatic type detected for an undefined integer is undefined.');
|
||||
|
||||
// Simple case, straight metadata.
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('system.maintenance');
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Maintenance mode';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['mapping']['message'] = array(
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['mapping']['message'] = [
|
||||
'label' => 'Message to display when in maintenance mode',
|
||||
'type' => 'text',
|
||||
);
|
||||
$expected['mapping']['langcode'] = array(
|
||||
];
|
||||
$expected['mapping']['langcode'] = [
|
||||
'label' => 'Language code',
|
||||
'type' => 'string',
|
||||
);
|
||||
];
|
||||
$expected['mapping']['_core']['type'] = '_core_config_info';
|
||||
$expected['type'] = 'system.maintenance';
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
@@ -109,41 +113,41 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
|
||||
// Mixed schema with ignore elements.
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.ignore');
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Ignore test';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['mapping']['langcode'] = array(
|
||||
$expected['mapping']['langcode'] = [
|
||||
'type' => 'string',
|
||||
'label' => 'Language code',
|
||||
);
|
||||
];
|
||||
$expected['mapping']['_core']['type'] = '_core_config_info';
|
||||
$expected['mapping']['label'] = array(
|
||||
$expected['mapping']['label'] = [
|
||||
'label' => 'Label',
|
||||
'type' => 'label',
|
||||
);
|
||||
$expected['mapping']['irrelevant'] = array(
|
||||
];
|
||||
$expected['mapping']['irrelevant'] = [
|
||||
'label' => 'Irrelevant',
|
||||
'type' => 'ignore',
|
||||
);
|
||||
$expected['mapping']['indescribable'] = array(
|
||||
];
|
||||
$expected['mapping']['indescribable'] = [
|
||||
'label' => 'Indescribable',
|
||||
'type' => 'ignore',
|
||||
);
|
||||
$expected['mapping']['weight'] = array(
|
||||
];
|
||||
$expected['mapping']['weight'] = [
|
||||
'label' => 'Weight',
|
||||
'type' => 'integer',
|
||||
);
|
||||
];
|
||||
$expected['type'] = 'config_schema_test.ignore';
|
||||
|
||||
$this->assertEqual($definition, $expected);
|
||||
|
||||
// The ignore elements themselves.
|
||||
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('irrelevant')->getDataDefinition()->toArray();
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['type'] = 'ignore';
|
||||
$expected['label'] = 'Irrelevant';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Ignore';
|
||||
$expected['class'] = Ignore::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
|
||||
$this->assertEqual($definition, $expected);
|
||||
$definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition()->toArray();
|
||||
@@ -152,9 +156,9 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
|
||||
// More complex case, generic type. Metadata for image style.
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('image.style.large');
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Image style';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['mapping']['name']['type'] = 'string';
|
||||
$expected['mapping']['uuid']['type'] = 'string';
|
||||
@@ -185,9 +189,9 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
// More complex, type based on a complex one.
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('image.effect.image_scale');
|
||||
// This should be the schema for image.effect.image_scale.
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Image scale';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['mapping']['width']['type'] = 'integer';
|
||||
$expected['mapping']['width']['label'] = 'Width';
|
||||
@@ -211,10 +215,10 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$a = \Drupal::config('config_test.dynamic.third_party');
|
||||
$test = \Drupal::service('config.typed')->get('config_test.dynamic.third_party')->get('third_party_settings.config_schema_test');
|
||||
$definition = $test->getDataDefinition()->toArray();
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['type'] = 'config_test.dynamic.*.third_party.config_schema_test';
|
||||
$expected['label'] = 'Mapping';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['mapping'] = [
|
||||
'integer' => ['type' => 'integer'],
|
||||
@@ -225,9 +229,9 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
// More complex, several level deep test.
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection');
|
||||
// This should be the schema of config_schema_test.someschema.somemodule.*.*.
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Schema multiple filesystem marker test';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['mapping']['langcode']['type'] = 'string';
|
||||
$expected['mapping']['langcode']['label'] = 'Language code';
|
||||
$expected['mapping']['_core']['type'] = '_core_config_info';
|
||||
@@ -248,47 +252,47 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests metadata retrieval with several levels of %parent indirection.
|
||||
*/
|
||||
function testSchemaMappingWithParents() {
|
||||
public function testSchemaMappingWithParents() {
|
||||
$config_data = \Drupal::service('config.typed')->get('config_schema_test.someschema.with_parents');
|
||||
|
||||
// Test fetching parent one level up.
|
||||
$entry = $config_data->get('one_level');
|
||||
$definition = $entry->get('testitem')->getDataDefinition()->toArray();
|
||||
$expected = array(
|
||||
$expected = [
|
||||
'type' => 'config_schema_test.someschema.with_parents.key_1',
|
||||
'label' => 'Test item nested one level',
|
||||
'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData',
|
||||
'class' => StringData::class,
|
||||
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
|
||||
);
|
||||
];
|
||||
$this->assertEqual($definition, $expected);
|
||||
|
||||
// Test fetching parent two levels up.
|
||||
$entry = $config_data->get('two_levels');
|
||||
$definition = $entry->get('wrapper')->get('testitem')->getDataDefinition()->toArray();
|
||||
$expected = array(
|
||||
$expected = [
|
||||
'type' => 'config_schema_test.someschema.with_parents.key_2',
|
||||
'label' => 'Test item nested two levels',
|
||||
'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData',
|
||||
'class' => StringData::class,
|
||||
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
|
||||
);
|
||||
];
|
||||
$this->assertEqual($definition, $expected);
|
||||
|
||||
// Test fetching parent three levels up.
|
||||
$entry = $config_data->get('three_levels');
|
||||
$definition = $entry->get('wrapper_1')->get('wrapper_2')->get('testitem')->getDataDefinition()->toArray();
|
||||
$expected = array(
|
||||
$expected = [
|
||||
'type' => 'config_schema_test.someschema.with_parents.key_3',
|
||||
'label' => 'Test item nested three levels',
|
||||
'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData',
|
||||
'class' => StringData::class,
|
||||
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
|
||||
);
|
||||
];
|
||||
$this->assertEqual($definition, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests metadata applied to configuration objects.
|
||||
*/
|
||||
function testSchemaData() {
|
||||
public function testSchemaData() {
|
||||
// Try a simple property.
|
||||
$meta = \Drupal::service('config.typed')->get('system.site');
|
||||
$property = $meta->get('page')->get('front');
|
||||
@@ -324,7 +328,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
* Test configuration value data type enforcement using schemas.
|
||||
*/
|
||||
public function testConfigSaveWithSchema() {
|
||||
$untyped_values = array(
|
||||
$untyped_values = [
|
||||
'string' => 1,
|
||||
'empty_string' => '',
|
||||
'null_string' => NULL,
|
||||
@@ -333,22 +337,22 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
'boolean' => 1,
|
||||
// If the config schema doesn't have a type it shouldn't be casted.
|
||||
'no_type' => 1,
|
||||
'mapping' => array(
|
||||
'mapping' => [
|
||||
'string' => 1
|
||||
),
|
||||
],
|
||||
'float' => '3.14',
|
||||
'null_float' => '',
|
||||
'sequence' => array (1, 0, 1),
|
||||
'sequence_bc' => array(1, 0, 1),
|
||||
'sequence' => [1, 0, 1],
|
||||
'sequence_bc' => [1, 0, 1],
|
||||
// Not in schema and therefore should be left untouched.
|
||||
'not_present_in_schema' => TRUE,
|
||||
// Test a custom type.
|
||||
'config_schema_test_integer' => '1',
|
||||
'config_schema_test_integer_empty_string' => '',
|
||||
);
|
||||
];
|
||||
$untyped_to_typed = $untyped_values;
|
||||
|
||||
$typed_values = array(
|
||||
$typed_values = [
|
||||
'string' => '1',
|
||||
'empty_string' => '',
|
||||
'null_string' => NULL,
|
||||
@@ -356,17 +360,17 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
'null_integer' => NULL,
|
||||
'boolean' => TRUE,
|
||||
'no_type' => 1,
|
||||
'mapping' => array(
|
||||
'mapping' => [
|
||||
'string' => '1'
|
||||
),
|
||||
],
|
||||
'float' => 3.14,
|
||||
'null_float' => NULL,
|
||||
'sequence' => array (TRUE, FALSE, TRUE),
|
||||
'sequence_bc' => array(TRUE, FALSE, TRUE),
|
||||
'sequence' => [TRUE, FALSE, TRUE],
|
||||
'sequence_bc' => [TRUE, FALSE, TRUE],
|
||||
'not_present_in_schema' => TRUE,
|
||||
'config_schema_test_integer' => 1,
|
||||
'config_schema_test_integer_empty_string' => NULL,
|
||||
);
|
||||
];
|
||||
|
||||
// Save config which has a schema that enforces types.
|
||||
$this->config('config_schema_test.schema_data_types')
|
||||
@@ -394,12 +398,12 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests fallback to a greedy wildcard.
|
||||
*/
|
||||
function testSchemaFallback() {
|
||||
public function testSchemaFallback() {
|
||||
$definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something');
|
||||
// This should be the schema of config_schema_test.wildcard_fallback.*.
|
||||
$expected = array();
|
||||
$expected = [];
|
||||
$expected['label'] = 'Schema wildcard fallback test';
|
||||
$expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
|
||||
$expected['class'] = Mapping::class;
|
||||
$expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
|
||||
$expected['mapping']['langcode']['type'] = 'string';
|
||||
$expected['mapping']['langcode']['label'] = 'Language code';
|
||||
@@ -423,7 +427,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
*
|
||||
* @see \Drupal\Core\Config\TypedConfigManager::getFallbackName()
|
||||
*/
|
||||
function testColonsInSchemaTypeDetermination() {
|
||||
public function testColonsInSchemaTypeDetermination() {
|
||||
$tests = \Drupal::service('config.typed')->get('config_schema_test.plugin_types')->get('tests')->getElements();
|
||||
$definition = $tests[0]->getDataDefinition()->toArray();
|
||||
$this->assertEqual($definition['type'], 'test.plugin_types.boolean');
|
||||
@@ -631,6 +635,27 @@ class ConfigSchemaTest extends KernelTestBase {
|
||||
$this->assertEqual($definition['type'], 'wrapping.test.double_brackets.*||test.double_brackets.cat.dog');
|
||||
$definition = $tests[1]->getDataDefinition()->toArray();
|
||||
$this->assertEqual($definition['type'], 'wrapping.test.double_brackets.*||test.double_brackets.turtle.horse');
|
||||
|
||||
$typed_values = [
|
||||
'tests' => [
|
||||
[
|
||||
'id' => 'cat:persion.dog',
|
||||
'foo' => 'cat',
|
||||
'bar' => 'dog',
|
||||
'breed' => 'persion',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
\Drupal::configFactory()->getEditable('wrapping.config_schema_test.other_double_brackets')
|
||||
->setData($typed_values)
|
||||
->save();
|
||||
$tests = \Drupal::service('config.typed')->get('wrapping.config_schema_test.other_double_brackets')->get('tests')->getElements();
|
||||
$definition = $tests[0]->getDataDefinition()->toArray();
|
||||
// Check that definition type is a merge of the expected types.
|
||||
$this->assertEqual($definition['type'], 'wrapping.test.other_double_brackets.*||test.double_brackets.cat:*.*');
|
||||
// Check that breed was inherited from parent definition.
|
||||
$this->assertEqual($definition['mapping']['breed'], ['type' => 'string']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class ConfigSnapshotTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test', 'system');
|
||||
public static $modules = ['config_test', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -33,7 +33,7 @@ class ConfigSnapshotTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests config snapshot creation and updating.
|
||||
*/
|
||||
function testSnapshot() {
|
||||
public function testSnapshot() {
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$snapshot = $this->container->get('config.storage.snapshot');
|
||||
@@ -50,7 +50,7 @@ class ConfigSnapshotTest extends KernelTestBase {
|
||||
$this->assertFalse($active_snapshot_comparer->createChangelist()->hasChanges());
|
||||
|
||||
// Install the default config.
|
||||
$this->installConfig(array('config_test'));
|
||||
$this->installConfig(['config_test']);
|
||||
// Although we have imported config this has not affected the snapshot.
|
||||
$this->assertTrue($active_snapshot_comparer->reset()->hasChanges());
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\KernelTests\Core\Config;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\config_test\TestInstallStorage;
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
@@ -23,7 +23,7 @@ class DefaultConfigTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'config_test');
|
||||
public static $modules = ['system', 'config_test'];
|
||||
|
||||
/**
|
||||
* Themes which provide default configuration and need enabling.
|
||||
|
||||
@@ -27,14 +27,14 @@ class SchemaCheckTraitTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('config_test', 'config_schema_test');
|
||||
public static $modules = ['config_test', 'config_schema_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('config_test', 'config_schema_test'));
|
||||
$this->installConfig(['config_test', 'config_schema_test']);
|
||||
$this->typedConfig = \Drupal::service('config.typed');
|
||||
}
|
||||
|
||||
@@ -53,14 +53,14 @@ class SchemaCheckTraitTest extends KernelTestBase {
|
||||
|
||||
// Add a new key, a new array and overwrite boolean with array to test the
|
||||
// error messages.
|
||||
$config_data = array('new_key' => 'new_value', 'new_array' => array()) + $config_data;
|
||||
$config_data['boolean'] = array();
|
||||
$config_data = ['new_key' => 'new_value', 'new_array' => []] + $config_data;
|
||||
$config_data['boolean'] = [];
|
||||
$ret = $this->checkConfigSchema($this->typedConfig, 'config_test.types', $config_data);
|
||||
$expected = array(
|
||||
$expected = [
|
||||
'config_test.types:new_key' => 'missing schema',
|
||||
'config_test.types:new_array' => 'missing schema',
|
||||
'config_test.types:boolean' => 'non-scalar value but not defined as an array (such as mapping or sequence)',
|
||||
);
|
||||
];
|
||||
$this->assertEqual($ret, $expected);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\KernelTests\Core\Config;
|
||||
|
||||
use Drupal\Core\Config\Schema\SchemaIncompleteException;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\Traits\Core\Config\SchemaConfigListenerTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the functionality of ConfigSchemaChecker in KernelTestBase tests.
|
||||
@@ -12,50 +12,22 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
*/
|
||||
class SchemaConfigListenerTest extends KernelTestBase {
|
||||
|
||||
use SchemaConfigListenerTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = array('config_test');
|
||||
public static $modules = ['config_test'];
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Config\Testing\ConfigSchemaChecker.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testConfigSchemaChecker() {
|
||||
// Test a non-existing schema.
|
||||
$message = 'Expected SchemaIncompleteException thrown';
|
||||
try {
|
||||
$this->config('config_schema_test.schemaless')->set('foo', 'bar')->save();
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (SchemaIncompleteException $e) {
|
||||
$this->pass($message);
|
||||
$this->assertEqual('No schema for config_schema_test.schemaless', $e->getMessage());
|
||||
}
|
||||
|
||||
// Test a valid schema.
|
||||
$message = 'Unexpected SchemaIncompleteException thrown';
|
||||
$config = $this->config('config_test.types')->set('int', 10);
|
||||
try {
|
||||
$config->save();
|
||||
$this->pass($message);
|
||||
}
|
||||
catch (SchemaIncompleteException $e) {
|
||||
$this->fail($message);
|
||||
}
|
||||
|
||||
// Test an invalid schema.
|
||||
$message = 'Expected SchemaIncompleteException thrown';
|
||||
$config = $this->config('config_test.types')
|
||||
->set('foo', 'bar')
|
||||
->set('array', 1);
|
||||
try {
|
||||
$config->save();
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (SchemaIncompleteException $e) {
|
||||
$this->pass($message);
|
||||
$this->assertEqual('Schema errors for config_test.types with the following errors: config_test.types:foo missing schema, config_test.types:array variable type is integer but applied schema class is Drupal\Core\Config\Schema\Sequence', $e->getMessage());
|
||||
}
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Install configuration provided by the module so that the order of the
|
||||
// config keys is the same as
|
||||
// \Drupal\FunctionalTests\Core\Config\SchemaConfigListenerTest.
|
||||
$this->installConfig(['config_test']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class CachedStorageTest extends ConfigStorageTestBase {
|
||||
$this->storage = new CachedStorage($this->fileStorage, \Drupal::service('cache.config'));
|
||||
$this->cache = \Drupal::service('cache_factory')->get('config');
|
||||
// ::listAll() verifications require other configuration data to exist.
|
||||
$this->storage->write('system.performance', array());
|
||||
$this->storage->write('system.performance', []);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
*
|
||||
* @todo Coverage: Trigger PDOExceptions / Database exceptions.
|
||||
*/
|
||||
function testCRUD() {
|
||||
public function testCRUD() {
|
||||
$name = 'config_test.storage';
|
||||
|
||||
// Checking whether a non-existing name exists returns FALSE.
|
||||
@@ -44,7 +44,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$this->assertIdentical($data, FALSE);
|
||||
|
||||
// Writing data returns TRUE and the data has been written.
|
||||
$data = array('foo' => 'bar');
|
||||
$data = ['foo' => 'bar'];
|
||||
$result = $this->storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
|
||||
@@ -86,11 +86,11 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
|
||||
// Deleting all names with prefix deletes the appropriate data and returns
|
||||
// TRUE.
|
||||
$files = array(
|
||||
$files = [
|
||||
'config_test.test.biff',
|
||||
'config_test.test.bang',
|
||||
'config_test.test.pow',
|
||||
);
|
||||
];
|
||||
foreach ($files as $name) {
|
||||
$this->storage->write($name, $data);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$result = $this->storage->deleteAll('config_test.');
|
||||
$names = $this->storage->listAll('config_test.');
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($names, array());
|
||||
$this->assertIdentical($names, []);
|
||||
|
||||
// Test renaming an object that does not exist throws an exception.
|
||||
try {
|
||||
@@ -127,7 +127,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
|
||||
// Write something to the valid storage to prove that the storages do not
|
||||
// pollute one another.
|
||||
$data = array('foo' => 'bar');
|
||||
$data = ['foo' => 'bar'];
|
||||
$result = $this->storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
|
||||
@@ -150,20 +150,20 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
|
||||
// Listing on a non-existing storage bin returns an empty array.
|
||||
$result = $this->invalidStorage->listAll();
|
||||
$this->assertIdentical($result, array());
|
||||
$this->assertIdentical($result, []);
|
||||
// Writing to a non-existing storage bin creates the bin.
|
||||
$this->invalidStorage->write($name, array('foo' => 'bar'));
|
||||
$this->invalidStorage->write($name, ['foo' => 'bar']);
|
||||
$result = $this->invalidStorage->read($name);
|
||||
$this->assertIdentical($result, array('foo' => 'bar'));
|
||||
$this->assertIdentical($result, ['foo' => 'bar']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests storage writing and reading data preserving data type.
|
||||
*/
|
||||
function testDataTypes() {
|
||||
public function testDataTypes() {
|
||||
$name = 'config_test.types';
|
||||
$data = array(
|
||||
'array' => array(),
|
||||
$data = [
|
||||
'array' => [],
|
||||
'boolean' => TRUE,
|
||||
'exp' => 1.2e+34,
|
||||
'float' => 3.14159,
|
||||
@@ -172,7 +172,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
'octal' => 0775,
|
||||
'string' => 'string',
|
||||
'string_int' => '1',
|
||||
);
|
||||
];
|
||||
|
||||
$result = $this->storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
@@ -186,7 +186,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
*/
|
||||
public function testCollection() {
|
||||
$name = 'config_test.storage';
|
||||
$data = array('foo' => 'bar');
|
||||
$data = ['foo' => 'bar'];
|
||||
$result = $this->storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($data, $this->storage->read($name));
|
||||
@@ -194,13 +194,13 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
// Create configuration in a new collection.
|
||||
$new_storage = $this->storage->createCollection('collection.sub.new');
|
||||
$this->assertFalse($new_storage->exists($name));
|
||||
$this->assertEqual(array(), $new_storage->listAll());
|
||||
$this->assertEqual([], $new_storage->listAll());
|
||||
$new_storage->write($name, $data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($data, $new_storage->read($name));
|
||||
$this->assertEqual(array($name), $new_storage->listAll());
|
||||
$this->assertEqual([$name], $new_storage->listAll());
|
||||
$this->assertTrue($new_storage->exists($name));
|
||||
$new_data = array('foo' => 'baz');
|
||||
$new_data = ['foo' => 'baz'];
|
||||
$new_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $new_storage->read($name));
|
||||
@@ -208,11 +208,11 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
// Create configuration in another collection.
|
||||
$another_storage = $this->storage->createCollection('collection.sub.another');
|
||||
$this->assertFalse($another_storage->exists($name));
|
||||
$this->assertEqual(array(), $another_storage->listAll());
|
||||
$this->assertEqual([], $another_storage->listAll());
|
||||
$another_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $another_storage->read($name));
|
||||
$this->assertEqual(array($name), $another_storage->listAll());
|
||||
$this->assertEqual([$name], $another_storage->listAll());
|
||||
$this->assertTrue($another_storage->exists($name));
|
||||
|
||||
// Create configuration in yet another collection.
|
||||
@@ -226,33 +226,33 @@ abstract class ConfigStorageTestBase extends KernelTestBase {
|
||||
$this->assertIdentical($data, $this->storage->read($name));
|
||||
|
||||
// Check that the getAllCollectionNames() method works.
|
||||
$this->assertIdentical(array('alternate', 'collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
|
||||
$this->assertIdentical(['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(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
|
||||
$this->assertIdentical(['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
|
||||
// subdirectories.
|
||||
$parent_storage = $this->storage->createCollection('collection');
|
||||
$this->assertFalse($parent_storage->exists($name));
|
||||
$this->assertEqual(array(), $parent_storage->listAll());
|
||||
$this->assertEqual([], $parent_storage->listAll());
|
||||
$parent_storage->write($name, $new_data);
|
||||
$this->assertIdentical($result, TRUE);
|
||||
$this->assertIdentical($new_data, $parent_storage->read($name));
|
||||
$this->assertEqual(array($name), $parent_storage->listAll());
|
||||
$this->assertEqual([$name], $parent_storage->listAll());
|
||||
$this->assertTrue($parent_storage->exists($name));
|
||||
$this->assertIdentical(array('collection', 'collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
|
||||
$this->assertIdentical(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
$parent_storage->deleteAll();
|
||||
$this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
|
||||
$this->assertIdentical(['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->storage->delete($name);
|
||||
$this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames());
|
||||
$this->assertIdentical(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
|
||||
}
|
||||
|
||||
abstract protected function read($name);
|
||||
|
||||
@@ -21,20 +21,20 @@ class DatabaseStorageTest extends ConfigStorageTestBase {
|
||||
$this->invalidStorage = new DatabaseStorage($this->container->get('database'), 'invalid');
|
||||
|
||||
// ::listAll() verifications require other configuration data to exist.
|
||||
$this->storage->write('system.performance', array());
|
||||
$this->storage->write('system.performance', []);
|
||||
}
|
||||
|
||||
protected function read($name) {
|
||||
$data = db_query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name))->fetchField();
|
||||
$data = db_query('SELECT data FROM {config} WHERE name = :name', [':name' => $name])->fetchField();
|
||||
return unserialize($data);
|
||||
}
|
||||
|
||||
protected function insert($name, $data) {
|
||||
db_insert('config')->fields(array('name' => $name, 'data' => $data))->execute();
|
||||
db_insert('config')->fields(['name' => $name, 'data' => $data])->execute();
|
||||
}
|
||||
|
||||
protected function update($name, $data) {
|
||||
db_update('config')->fields(array('data' => $data))->condition('name', $name)->execute();
|
||||
db_update('config')->fields(['data' => $data])->condition('name', $name)->execute();
|
||||
}
|
||||
|
||||
protected function delete($name) {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Drupal\KernelTests\Core\Config\Storage;
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Config\FileStorage;
|
||||
use Drupal\Core\Config\UnsupportedDataTypeConfigException;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\Core\StreamWrapper\PublicStream;
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ class FileStorageTest extends ConfigStorageTestBase {
|
||||
|
||||
// FileStorage::listAll() requires other configuration data to exist.
|
||||
$this->storage->write('system.performance', $this->config('system.performance')->get());
|
||||
$this->storage->write('core.extension', array('module' => array()));
|
||||
$this->storage->write('core.extension', ['module' => []]);
|
||||
}
|
||||
|
||||
protected function read($name) {
|
||||
@@ -57,10 +57,10 @@ class FileStorageTest extends ConfigStorageTestBase {
|
||||
* Tests the FileStorage::listAll method with a relative and absolute path.
|
||||
*/
|
||||
public function testlistAll() {
|
||||
$expected_files = array(
|
||||
$expected_files = [
|
||||
'core.extension',
|
||||
'system.performance',
|
||||
);
|
||||
];
|
||||
|
||||
$config_files = $this->storage->listAll();
|
||||
$this->assertIdentical($config_files, $expected_files, 'Relative path, two config files found.');
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Config\Storage;
|
||||
|
||||
use Drupal\config\StorageReplaceDataWrapper;
|
||||
use Drupal\Core\Config\StorageInterface;
|
||||
|
||||
/**
|
||||
* Tests StorageReplaceDataWrapper operations.
|
||||
*
|
||||
* @group config
|
||||
*/
|
||||
class StorageReplaceDataWrapperTest extends ConfigStorageTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->storage = new StorageReplaceDataWrapper($this->container->get('config.storage'));
|
||||
// ::listAll() verifications require other configuration data to exist.
|
||||
$this->storage->write('system.performance', []);
|
||||
$this->storage->replaceData('system.performance', ['foo' => 'bar']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function read($name) {
|
||||
return $this->storage->read($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function insert($name, $data) {
|
||||
$this->storage->write($name, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function update($name, $data) {
|
||||
$this->storage->write($name, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function delete($name) {
|
||||
$this->storage->delete($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testInvalidStorage() {
|
||||
// No-op as this test does not make sense.
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if new collections created correctly.
|
||||
*
|
||||
* @param string $collection
|
||||
* The collection name.
|
||||
*
|
||||
* @dataProvider providerCollections
|
||||
*/
|
||||
public function testCreateCollection($collection) {
|
||||
$initial_collection_name = $this->storage->getCollectionName();
|
||||
|
||||
// Create new storage with given collection and check it is set correctly.
|
||||
$new_storage = $this->storage->createCollection($collection);
|
||||
$this->assertSame($collection, $new_storage->getCollectionName());
|
||||
|
||||
// Check collection not changed in the current storage instance.
|
||||
$this->assertSame($initial_collection_name, $this->storage->getCollectionName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing different collections.
|
||||
*
|
||||
* @return array
|
||||
* Returns an array of collection names.
|
||||
*/
|
||||
public function providerCollections() {
|
||||
return [
|
||||
[StorageInterface::DEFAULT_COLLECTION],
|
||||
['foo.bar'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can do basic alters.
|
||||
*/
|
||||
function testSimpleAlter() {
|
||||
public function testSimpleAlter() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$query->addField('test', 'age', 'age');
|
||||
@@ -27,7 +27,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can alter the joins on a query.
|
||||
*/
|
||||
function testAlterWithJoin() {
|
||||
public function testAlterWithJoin() {
|
||||
$query = db_select('test_task');
|
||||
$tid_field = $query->addField('test_task', 'tid');
|
||||
$task_field = $query->addField('test_task', 'task');
|
||||
@@ -51,7 +51,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can alter a query's conditionals.
|
||||
*/
|
||||
function testAlterChangeConditional() {
|
||||
public function testAlterChangeConditional() {
|
||||
$query = db_select('test_task');
|
||||
$tid_field = $query->addField('test_task', 'tid');
|
||||
$pid_field = $query->addField('test_task', 'pid');
|
||||
@@ -76,7 +76,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can alter the fields of a query.
|
||||
*/
|
||||
function testAlterChangeFields() {
|
||||
public function testAlterChangeFields() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
@@ -91,7 +91,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can alter expressions in the query.
|
||||
*/
|
||||
function testAlterExpression() {
|
||||
public function testAlterExpression() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_field = $query->addExpression("age*2", 'double_age');
|
||||
@@ -111,7 +111,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
*
|
||||
* This also tests hook_query_TAG_alter().
|
||||
*/
|
||||
function testAlterRemoveRange() {
|
||||
public function testAlterRemoveRange() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$query->addField('test', 'age', 'age');
|
||||
@@ -126,7 +126,7 @@ class AlterTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can do basic alters on subqueries.
|
||||
*/
|
||||
function testSimpleAlterSubquery() {
|
||||
public function testSimpleAlterSubquery() {
|
||||
// Create a sub-query with an alter tag.
|
||||
$subquery = db_select('test', 'p');
|
||||
$subquery->addField('p', 'name');
|
||||
|
||||
@@ -15,63 +15,63 @@ class BasicSyntaxTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests string concatenation.
|
||||
*/
|
||||
function testConcatLiterals() {
|
||||
$result = db_query('SELECT CONCAT(:a1, CONCAT(:a2, CONCAT(:a3, CONCAT(:a4, :a5))))', array(
|
||||
public function testConcatLiterals() {
|
||||
$result = db_query('SELECT CONCAT(:a1, CONCAT(:a2, CONCAT(:a3, CONCAT(:a4, :a5))))', [
|
||||
':a1' => 'This',
|
||||
':a2' => ' ',
|
||||
':a3' => 'is',
|
||||
':a4' => ' a ',
|
||||
':a5' => 'test.',
|
||||
));
|
||||
]);
|
||||
$this->assertIdentical($result->fetchField(), 'This is a test.', 'Basic CONCAT works.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests string concatenation with field values.
|
||||
*/
|
||||
function testConcatFields() {
|
||||
$result = db_query('SELECT CONCAT(:a1, CONCAT(name, CONCAT(:a2, CONCAT(age, :a3)))) FROM {test} WHERE age = :age', array(
|
||||
public function testConcatFields() {
|
||||
$result = db_query('SELECT CONCAT(:a1, CONCAT(name, CONCAT(:a2, CONCAT(age, :a3)))) FROM {test} WHERE age = :age', [
|
||||
':a1' => 'The age of ',
|
||||
':a2' => ' is ',
|
||||
':a3' => '.',
|
||||
':age' => 25,
|
||||
));
|
||||
]);
|
||||
$this->assertIdentical($result->fetchField(), 'The age of John is 25.', 'Field CONCAT works.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests string concatenation with separator.
|
||||
*/
|
||||
function testConcatWsLiterals() {
|
||||
$result = db_query("SELECT CONCAT_WS(', ', :a1, NULL, :a2, :a3, :a4)", array(
|
||||
public function testConcatWsLiterals() {
|
||||
$result = db_query("SELECT CONCAT_WS(', ', :a1, NULL, :a2, :a3, :a4)", [
|
||||
':a1' => 'Hello',
|
||||
':a2' => NULL,
|
||||
':a3' => '',
|
||||
':a4' => 'world.',
|
||||
));
|
||||
]);
|
||||
$this->assertIdentical($result->fetchField(), 'Hello, , world.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests string concatenation with separator, with field values.
|
||||
*/
|
||||
function testConcatWsFields() {
|
||||
$result = db_query("SELECT CONCAT_WS('-', :a1, name, :a2, age) FROM {test} WHERE age = :age", array(
|
||||
public function testConcatWsFields() {
|
||||
$result = db_query("SELECT CONCAT_WS('-', :a1, name, :a2, age) FROM {test} WHERE age = :age", [
|
||||
':a1' => 'name',
|
||||
':a2' => 'age',
|
||||
':age' => 25,
|
||||
));
|
||||
]);
|
||||
$this->assertIdentical($result->fetchField(), 'name-John-age-25');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests escaping of LIKE wildcards.
|
||||
*/
|
||||
function testLikeEscape() {
|
||||
public function testLikeEscape() {
|
||||
db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'Ring_',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Match both "Ringo" and "Ring_".
|
||||
@@ -93,15 +93,15 @@ class BasicSyntaxTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests a LIKE query containing a backslash.
|
||||
*/
|
||||
function testLikeBackslash() {
|
||||
public function testLikeBackslash() {
|
||||
db_insert('test')
|
||||
->fields(array('name'))
|
||||
->values(array(
|
||||
->fields(['name'])
|
||||
->values([
|
||||
'name' => 'abcde\f',
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'name' => 'abc%\_',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Match both rows using a LIKE expression with two wildcards and a verbatim
|
||||
|
||||
@@ -11,20 +11,20 @@ class CaseSensitivityTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests BINARY collation in MySQL.
|
||||
*/
|
||||
function testCaseSensitiveInsert() {
|
||||
public function testCaseSensitiveInsert() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
|
||||
db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'john', // <- A record already exists with 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.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'john'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'john'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '2', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that connections return appropriate connection objects.
|
||||
*/
|
||||
function testConnectionRouting() {
|
||||
public function testConnectionRouting() {
|
||||
// Clone the primary credentials to a replica connection.
|
||||
// Note this will result in two independent connection objects that happen
|
||||
// to point to the same place.
|
||||
@@ -49,7 +49,7 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that connections return appropriate connection objects.
|
||||
*/
|
||||
function testConnectionRoutingOverride() {
|
||||
public function testConnectionRoutingOverride() {
|
||||
// Clone the primary credentials to a replica connection.
|
||||
// Note this will result in two independent connection objects that happen
|
||||
// to point to the same place.
|
||||
@@ -67,7 +67,7 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests the closing of a database connection.
|
||||
*/
|
||||
function testConnectionClosing() {
|
||||
public function testConnectionClosing() {
|
||||
// Open the default target so we have an object to compare.
|
||||
$db1 = Database::getConnection('default', 'default');
|
||||
|
||||
@@ -82,7 +82,7 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests the connection options of the active database.
|
||||
*/
|
||||
function testConnectionOptions() {
|
||||
public function testConnectionOptions() {
|
||||
$connection_info = Database::getConnectionInfo('default');
|
||||
|
||||
// Be sure we're connected to the default database.
|
||||
@@ -168,9 +168,9 @@ class ConnectionTest extends DatabaseTestBase {
|
||||
$stmt->execute();
|
||||
foreach ($stmt->fetchAllAssoc('word') as $word => $row) {
|
||||
$expected = '"' . $word . '"';
|
||||
$this->assertIdentical($db->escapeTable($word), $expected, format_string('The reserved word %word was correctly escaped when used as a table name.', array('%word' => $word)));
|
||||
$this->assertIdentical($db->escapeField($word), $expected, format_string('The reserved word %word was correctly escaped when used as a column name.', array('%word' => $word)));
|
||||
$this->assertIdentical($db->escapeAlias($word), $expected, format_string('The reserved word %word was correctly escaped when used as an alias.', array('%word' => $word)));
|
||||
$this->assertIdentical($db->escapeTable($word), $expected, format_string('The reserved word %word was correctly escaped when used as a table name.', ['%word' => $word]));
|
||||
$this->assertIdentical($db->escapeField($word), $expected, format_string('The reserved word %word was correctly escaped when used as a column name.', ['%word' => $word]));
|
||||
$this->assertIdentical($db->escapeAlias($word), $expected, format_string('The reserved word %word was correctly escaped when used as an alias.', ['%word' => $word]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
*/
|
||||
protected function assertConnection($id) {
|
||||
$list = $this->monitor->query('SHOW PROCESSLIST')->fetchAllKeyed(0, 0);
|
||||
return $this->assertTrue(isset($list[$id]), format_string('Connection ID @id found.', array('@id' => $id)));
|
||||
return $this->assertTrue(isset($list[$id]), format_string('Connection ID @id found.', ['@id' => $id]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
*/
|
||||
protected function assertNoConnection($id) {
|
||||
$list = $this->monitor->query('SHOW PROCESSLIST')->fetchAllKeyed(0, 0);
|
||||
return $this->assertFalse(isset($list[$id]), format_string('Connection ID @id not found.', array('@id' => $id)));
|
||||
return $this->assertFalse(isset($list[$id]), format_string('Connection ID @id not found.', ['@id' => $id]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +94,7 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
*
|
||||
* @todo getConnectionID() executes a query.
|
||||
*/
|
||||
function testOpenClose() {
|
||||
public function testOpenClose() {
|
||||
if ($this->skipTest) {
|
||||
return;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests Database::closeConnection() with a query.
|
||||
*/
|
||||
function testOpenQueryClose() {
|
||||
public function testOpenQueryClose() {
|
||||
if ($this->skipTest) {
|
||||
return;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests Database::closeConnection() with a query and custom prefetch method.
|
||||
*/
|
||||
function testOpenQueryPrefetchClose() {
|
||||
public function testOpenQueryPrefetchClose() {
|
||||
if ($this->skipTest) {
|
||||
return;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests Database::closeConnection() with a select query.
|
||||
*/
|
||||
function testOpenSelectQueryClose() {
|
||||
public function testOpenSelectQueryClose() {
|
||||
if ($this->skipTest) {
|
||||
return;
|
||||
}
|
||||
@@ -186,18 +186,18 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
|
||||
// Create a table.
|
||||
$name = 'foo';
|
||||
Database::getConnection($this->target, $this->key)->schema()->createTable($name, array(
|
||||
'fields' => array(
|
||||
'name' => array(
|
||||
Database::getConnection($this->target, $this->key)->schema()->createTable($name, [
|
||||
'fields' => [
|
||||
'name' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
),
|
||||
));
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// Execute a query.
|
||||
Database::getConnection($this->target, $this->key)->select('foo', 'f')
|
||||
->fields('f', array('name'))
|
||||
->fields('f', ['name'])
|
||||
->execute()
|
||||
->fetchAll();
|
||||
|
||||
@@ -221,6 +221,12 @@ class ConnectionUnitTest extends KernelTestBase {
|
||||
$reflection = new \ReflectionObject($connection);
|
||||
$connection_property = $reflection->getProperty('connection');
|
||||
$connection_property->setAccessible(TRUE);
|
||||
// Skip this test when a database driver does not implement PDO.
|
||||
// An alternative database driver that does not implement PDO
|
||||
// should implement its own connection test.
|
||||
if (get_class($connection_property->getValue($connection)) !== 'PDO') {
|
||||
$this->markTestSkipped('Ignored PDO connection unit test for this driver because it does not implement PDO.');
|
||||
}
|
||||
$error_mode = $connection_property->getValue($connection)
|
||||
->getAttribute(\PDO::ATTR_ERRMODE);
|
||||
$this->assertEqual($error_mode, \PDO::ERRMODE_EXCEPTION, 'Ensure the default error mode is set to exception.');
|
||||
|
||||
@@ -12,11 +12,11 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
*/
|
||||
abstract class DatabaseTestBase extends KernelTestBase {
|
||||
|
||||
public static $modules = array('database_test');
|
||||
public static $modules = ['database_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('database_test', array(
|
||||
$this->installSchema('database_test', [
|
||||
'test',
|
||||
'test_people',
|
||||
'test_people_copy',
|
||||
@@ -27,120 +27,120 @@ abstract class DatabaseTestBase extends KernelTestBase {
|
||||
'test_serialized',
|
||||
'test_special_columns',
|
||||
'TEST_UPPERCASE',
|
||||
));
|
||||
]);
|
||||
self::addSampleData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up tables for NULL handling.
|
||||
*/
|
||||
function ensureSampleDataNull() {
|
||||
public function ensureSampleDataNull() {
|
||||
db_insert('test_null')
|
||||
->fields(array('name', 'age'))
|
||||
->values(array(
|
||||
->fields(['name', 'age'])
|
||||
->values([
|
||||
'name' => 'Kermit',
|
||||
'age' => 25,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'name' => 'Fozzie',
|
||||
'age' => NULL,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'name' => 'Gonzo',
|
||||
'age' => 27,
|
||||
))
|
||||
->execute();
|
||||
])
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up our sample data.
|
||||
*/
|
||||
static function addSampleData() {
|
||||
public static function addSampleData() {
|
||||
// We need the IDs, so we can't use a multi-insert here.
|
||||
$john = db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'John',
|
||||
'age' => 25,
|
||||
'job' => 'Singer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$george = db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'George',
|
||||
'age' => 27,
|
||||
'job' => 'Singer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'Ringo',
|
||||
'age' => 28,
|
||||
'job' => 'Drummer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$paul = db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'Paul',
|
||||
'age' => 26,
|
||||
'job' => 'Songwriter',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
db_insert('test_people')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'Meredith',
|
||||
'age' => 30,
|
||||
'job' => 'Speaker',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
db_insert('test_task')
|
||||
->fields(array('pid', 'task', 'priority'))
|
||||
->values(array(
|
||||
->fields(['pid', 'task', 'priority'])
|
||||
->values([
|
||||
'pid' => $john,
|
||||
'task' => 'eat',
|
||||
'priority' => 3,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'pid' => $john,
|
||||
'task' => 'sleep',
|
||||
'priority' => 4,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'pid' => $john,
|
||||
'task' => 'code',
|
||||
'priority' => 1,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'pid' => $george,
|
||||
'task' => 'sing',
|
||||
'priority' => 2,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'pid' => $george,
|
||||
'task' => 'sleep',
|
||||
'priority' => 2,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'pid' => $paul,
|
||||
'task' => 'found new band',
|
||||
'priority' => 1,
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'pid' => $paul,
|
||||
'task' => 'perform at superbowl',
|
||||
'priority' => 3,
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
db_insert('test_special_columns')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'id' => 1,
|
||||
'offset' => 'Offset value 1',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ class DeleteTruncateTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can use a subselect in a delete successfully.
|
||||
*/
|
||||
function testSubselectDelete() {
|
||||
public function testSubselectDelete() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_task}')->fetchField();
|
||||
$pid_to_delete = db_query("SELECT * FROM {test_task} WHERE task = 'sleep'")->fetchField();
|
||||
|
||||
$subquery = db_select('test', 't')
|
||||
->fields('t', array('id'))
|
||||
->condition('t.id', array($pid_to_delete), 'IN');
|
||||
->fields('t', ['id'])
|
||||
->condition('t.id', [$pid_to_delete], 'IN');
|
||||
$delete = db_delete('test_task')
|
||||
->condition('task', 'sleep')
|
||||
->condition('pid', $subquery, 'IN');
|
||||
@@ -41,7 +41,7 @@ class DeleteTruncateTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can delete a single record successfully.
|
||||
*/
|
||||
function testSimpleDelete() {
|
||||
public function testSimpleDelete() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
|
||||
$num_deleted = db_delete('test')
|
||||
@@ -56,7 +56,7 @@ class DeleteTruncateTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can truncate a whole table successfully.
|
||||
*/
|
||||
function testTruncate() {
|
||||
public function testTruncate() {
|
||||
$num_records_before = db_query("SELECT COUNT(*) FROM {test}")->fetchField();
|
||||
$this->assertTrue($num_records_before > 0, 'The table is not empty.');
|
||||
|
||||
@@ -69,7 +69,7 @@ class DeleteTruncateTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can delete a single special column name record successfully.
|
||||
*/
|
||||
function testSpecialColumnDelete() {
|
||||
public function testSpecialColumnDelete() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_special_columns}')->fetchField();
|
||||
|
||||
$num_deleted = db_delete('test_special_columns')
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Drupal\KernelTests\Core\Database;
|
||||
|
||||
use Drupal\Core\Database\RowCountException;
|
||||
use Drupal\Core\Database\StatementInterface;
|
||||
use Drupal\system\Tests\Database\FakeRecord;
|
||||
use Drupal\Tests\system\Functional\Database\FakeRecord;
|
||||
|
||||
/**
|
||||
* Tests the Database system's various fetch capabilities.
|
||||
@@ -18,9 +18,9 @@ class FetchTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can fetch a record properly in default object mode.
|
||||
*/
|
||||
function testQueryFetchDefault() {
|
||||
$records = array();
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25));
|
||||
public function testQueryFetchDefault() {
|
||||
$records = [];
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25]);
|
||||
$this->assertTrue($result instanceof StatementInterface, 'Result set is a Drupal statement object.');
|
||||
foreach ($result as $record) {
|
||||
$records[] = $record;
|
||||
@@ -34,9 +34,9 @@ class FetchTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can fetch a record to an object explicitly.
|
||||
*/
|
||||
function testQueryFetchObject() {
|
||||
$records = array();
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_OBJ));
|
||||
public function testQueryFetchObject() {
|
||||
$records = [];
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_OBJ]);
|
||||
foreach ($result as $record) {
|
||||
$records[] = $record;
|
||||
$this->assertTrue(is_object($record), 'Record is an object.');
|
||||
@@ -49,9 +49,9 @@ class FetchTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can fetch a record to an associative array explicitly.
|
||||
*/
|
||||
function testQueryFetchArray() {
|
||||
$records = array();
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_ASSOC));
|
||||
public function testQueryFetchArray() {
|
||||
$records = [];
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_ASSOC]);
|
||||
foreach ($result as $record) {
|
||||
$records[] = $record;
|
||||
if ($this->assertTrue(is_array($record), 'Record is an array.')) {
|
||||
@@ -67,9 +67,9 @@ class FetchTest extends DatabaseTestBase {
|
||||
*
|
||||
* @see \Drupal\system\Tests\Database\FakeRecord
|
||||
*/
|
||||
function testQueryFetchClass() {
|
||||
$records = array();
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => 'Drupal\system\Tests\Database\FakeRecord'));
|
||||
public function testQueryFetchClass() {
|
||||
$records = [];
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => FakeRecord::class]);
|
||||
foreach ($result as $record) {
|
||||
$records[] = $record;
|
||||
if ($this->assertTrue($record instanceof FakeRecord, 'Record is an object of class FakeRecord.')) {
|
||||
@@ -83,9 +83,9 @@ class FetchTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can fetch a record into an indexed array explicitly.
|
||||
*/
|
||||
function testQueryFetchNum() {
|
||||
$records = array();
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_NUM));
|
||||
public function testQueryFetchNum() {
|
||||
$records = [];
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_NUM]);
|
||||
foreach ($result as $record) {
|
||||
$records[] = $record;
|
||||
if ($this->assertTrue(is_array($record), 'Record is an array.')) {
|
||||
@@ -99,9 +99,9 @@ class FetchTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can fetch a record into a doubly-keyed array explicitly.
|
||||
*/
|
||||
function testQueryFetchBoth() {
|
||||
$records = array();
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_BOTH));
|
||||
public function testQueryFetchBoth() {
|
||||
$records = [];
|
||||
$result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_BOTH]);
|
||||
foreach ($result as $record) {
|
||||
$records[] = $record;
|
||||
if ($this->assertTrue(is_array($record), 'Record is an array.')) {
|
||||
@@ -113,15 +113,28 @@ class FetchTest extends DatabaseTestBase {
|
||||
$this->assertIdentical(count($records), 1, 'There is only one record.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that we can fetch all records into an array explicitly.
|
||||
*/
|
||||
public function testQueryFetchAllColumn() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$query->orderBy('name');
|
||||
$query_result = $query->execute()->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
$expected_result = ['George', 'John', 'Paul', 'Ringo'];
|
||||
$this->assertEqual($query_result, $expected_result, 'Returned the correct result.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that we can fetch an entire column of a result set at once.
|
||||
*/
|
||||
function testQueryFetchCol() {
|
||||
$result = db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25));
|
||||
public function testQueryFetchCol() {
|
||||
$result = db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25]);
|
||||
$column = $result->fetchCol();
|
||||
$this->assertIdentical(count($column), 3, 'fetchCol() returns the right number of records.');
|
||||
|
||||
$result = db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25));
|
||||
$result = db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25]);
|
||||
$i = 0;
|
||||
foreach ($result as $record) {
|
||||
$this->assertIdentical($record->name, $column[$i++], 'Column matches direct access.');
|
||||
|
||||
@@ -14,20 +14,20 @@ class InsertDefaultsTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can run a query that uses default values for everything.
|
||||
*/
|
||||
function testDefaultInsert() {
|
||||
$query = db_insert('test')->useDefaults(array('job'));
|
||||
public function testDefaultInsert() {
|
||||
$query = db_insert('test')->useDefaults(['job']);
|
||||
$id = $query->execute();
|
||||
|
||||
$schema = drupal_get_module_schema('database_test', 'test');
|
||||
|
||||
$job = db_query('SELECT job FROM {test} WHERE id = :id', array(':id' => $id))->fetchField();
|
||||
$job = db_query('SELECT job FROM {test} WHERE id = :id', [':id' => $id])->fetchField();
|
||||
$this->assertEqual($job, $schema['fields']['job']['default'], 'Default field value is set.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that no action will be preformed if no fields are specified.
|
||||
*/
|
||||
function testDefaultEmptyInsert() {
|
||||
public function testDefaultEmptyInsert() {
|
||||
$num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
|
||||
try {
|
||||
@@ -46,15 +46,15 @@ class InsertDefaultsTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can insert fields with values and defaults in the same query.
|
||||
*/
|
||||
function testDefaultInsertWithFields() {
|
||||
public function testDefaultInsertWithFields() {
|
||||
$query = db_insert('test')
|
||||
->fields(array('name' => 'Bob'))
|
||||
->useDefaults(array('job'));
|
||||
->fields(['name' => 'Bob'])
|
||||
->useDefaults(['job']);
|
||||
$id = $query->execute();
|
||||
|
||||
$schema = drupal_get_module_schema('database_test', 'test');
|
||||
|
||||
$job = db_query('SELECT job FROM {test} WHERE id = :id', array(':id' => $id))->fetchField();
|
||||
$job = db_query('SELECT job FROM {test} WHERE id = :id', [':id' => $id])->fetchField();
|
||||
$this->assertEqual($job, $schema['fields']['job']['default'], 'Default field value is set.');
|
||||
}
|
||||
|
||||
|
||||
@@ -12,27 +12,27 @@ class InsertLobTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can insert a single blob field successfully.
|
||||
*/
|
||||
function testInsertOneBlob() {
|
||||
public function testInsertOneBlob() {
|
||||
$data = "This is\000a test.";
|
||||
$this->assertTrue(strlen($data) === 15, 'Test data contains a NULL.');
|
||||
$id = db_insert('test_one_blob')
|
||||
->fields(array('blob1' => $data))
|
||||
->fields(['blob1' => $data])
|
||||
->execute();
|
||||
$r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', array(':id' => $id))->fetchAssoc();
|
||||
$this->assertTrue($r['blob1'] === $data, format_string('Can insert a blob: id @id, @data.', array('@id' => $id, '@data' => serialize($r))));
|
||||
$r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', [':id' => $id])->fetchAssoc();
|
||||
$this->assertTrue($r['blob1'] === $data, format_string('Can insert a blob: id @id, @data.', ['@id' => $id, '@data' => serialize($r)]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can insert multiple blob fields in the same query.
|
||||
*/
|
||||
function testInsertMultipleBlob() {
|
||||
public function testInsertMultipleBlob() {
|
||||
$id = db_insert('test_two_blobs')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'blob1' => 'This is',
|
||||
'blob2' => 'a test',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
$r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', array(':id' => $id))->fetchAssoc();
|
||||
$r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', [':id' => $id])->fetchAssoc();
|
||||
$this->assertTrue($r['blob1'] === 'This is' && $r['blob2'] === 'a test', 'Can insert multiple blobs per row.');
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ class InsertTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests very basic insert functionality.
|
||||
*/
|
||||
function testSimpleInsert() {
|
||||
public function testSimpleInsert() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
|
||||
$query = db_insert('test');
|
||||
$query->fields(array(
|
||||
$query->fields([
|
||||
'name' => 'Yoko',
|
||||
'age' => '29',
|
||||
));
|
||||
]);
|
||||
|
||||
// Check how many records are queued for insertion.
|
||||
$this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
|
||||
@@ -27,34 +27,34 @@ class InsertTest extends DatabaseTestBase {
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Yoko'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Yoko'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '29', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can insert multiple records in one query object.
|
||||
*/
|
||||
function testMultiInsert() {
|
||||
public function testMultiInsert() {
|
||||
$num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
|
||||
$query = db_insert('test');
|
||||
$query->fields(array(
|
||||
$query->fields([
|
||||
'name' => 'Larry',
|
||||
'age' => '30',
|
||||
));
|
||||
]);
|
||||
|
||||
// We should be able to specify values in any order if named.
|
||||
$query->values(array(
|
||||
$query->values([
|
||||
'age' => '31',
|
||||
'name' => 'Curly',
|
||||
));
|
||||
]);
|
||||
|
||||
// Check how many records are queued for insertion.
|
||||
$this->assertIdentical($query->count(), 2, 'Two records are queued for insertion.');
|
||||
|
||||
// We should be able to say "use the field order".
|
||||
// This is not the recommended mechanism for most cases, but it should work.
|
||||
$query->values(array('Moe', '32'));
|
||||
$query->values(['Moe', '32']);
|
||||
|
||||
// Check how many records are queued for insertion.
|
||||
$this->assertIdentical($query->count(), 3, 'Three records are queued for insertion.');
|
||||
@@ -62,41 +62,41 @@ class InsertTest extends DatabaseTestBase {
|
||||
|
||||
$num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Larry'))->fetchField();
|
||||
$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', array(':name' => 'Curly'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Moe'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an insert object can be reused with new data after it executes.
|
||||
*/
|
||||
function testRepeatedInsert() {
|
||||
public function testRepeatedInsert() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
|
||||
$query = db_insert('test');
|
||||
|
||||
$query->fields(array(
|
||||
$query->fields([
|
||||
'name' => 'Larry',
|
||||
'age' => '30',
|
||||
));
|
||||
]);
|
||||
// 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.
|
||||
|
||||
// We should be able to specify values in any order if named.
|
||||
$query->values(array(
|
||||
$query->values([
|
||||
'age' => '31',
|
||||
'name' => 'Curly',
|
||||
));
|
||||
]);
|
||||
// Check how many records are queued for insertion.
|
||||
$this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
|
||||
$query->execute();
|
||||
|
||||
// We should be able to say "use the field order".
|
||||
$query->values(array('Moe', '32'));
|
||||
$query->values(['Moe', '32']);
|
||||
|
||||
// Check how many records are queued for insertion.
|
||||
$this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
|
||||
@@ -104,43 +104,43 @@ class InsertTest extends DatabaseTestBase {
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
|
||||
$this->assertIdentical((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Larry'))->fetchField();
|
||||
$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', array(':name' => 'Curly'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Moe'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can specify fields without values and specify values later.
|
||||
*/
|
||||
function testInsertFieldOnlyDefinition() {
|
||||
public function testInsertFieldOnlyDefinition() {
|
||||
// This is useful for importers, when we want to create a query and define
|
||||
// its fields once, then loop over a multi-insert execution.
|
||||
db_insert('test')
|
||||
->fields(array('name', 'age'))
|
||||
->values(array('Larry', '30'))
|
||||
->values(array('Curly', '31'))
|
||||
->values(array('Moe', '32'))
|
||||
->fields(['name', 'age'])
|
||||
->values(['Larry', '30'])
|
||||
->values(['Curly', '31'])
|
||||
->values(['Moe', '32'])
|
||||
->execute();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Larry'))->fetchField();
|
||||
$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', array(':name' => 'Curly'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Moe'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that inserts return the proper auto-increment ID.
|
||||
*/
|
||||
function testInsertLastInsertID() {
|
||||
public function testInsertLastInsertID() {
|
||||
$id = db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'Larry',
|
||||
'age' => '30',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$this->assertIdentical($id, '5', 'Auto-increment ID returned successfully.');
|
||||
@@ -149,14 +149,14 @@ class InsertTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that the INSERT INTO ... SELECT (fields) ... syntax works.
|
||||
*/
|
||||
function testInsertSelectFields() {
|
||||
public function testInsertSelectFields() {
|
||||
$query = db_select('test_people', 'tp');
|
||||
// The query builder will always append expressions after fields.
|
||||
// Add the expression first to test that the insert fields are correctly
|
||||
// re-ordered.
|
||||
$query->addExpression('tp.age', 'age');
|
||||
$query
|
||||
->fields('tp', array('name', 'job'))
|
||||
->fields('tp', ['name', 'job'])
|
||||
->condition('tp.name', 'Meredith');
|
||||
|
||||
// The resulting query should be equivalent to:
|
||||
@@ -168,14 +168,14 @@ class InsertTest extends DatabaseTestBase {
|
||||
->from($query)
|
||||
->execute();
|
||||
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Meredith'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Meredith'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the INSERT INTO ... SELECT * ... syntax works.
|
||||
*/
|
||||
function testInsertSelectAll() {
|
||||
public function testInsertSelectAll() {
|
||||
$query = db_select('test_people', 'tp')
|
||||
->fields('tp')
|
||||
->condition('tp.name', 'Meredith');
|
||||
@@ -189,21 +189,21 @@ class InsertTest extends DatabaseTestBase {
|
||||
->from($query)
|
||||
->execute();
|
||||
|
||||
$saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', array(':name' => 'Meredith'))->fetchField();
|
||||
$saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', [':name' => 'Meredith'])->fetchField();
|
||||
$this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can INSERT INTO a special named column.
|
||||
*/
|
||||
function testSpecialColumnInsert() {
|
||||
public function testSpecialColumnInsert() {
|
||||
$id = db_insert('test_special_columns')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'id' => 2,
|
||||
'offset' => 'Offset value 2',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
$saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', array(':id' => 2))->fetchField();
|
||||
$saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', [':id' => 2])->fetchField();
|
||||
$this->assertIdentical($saved_value, 'Offset value 2', 'Can retrieve special column name value after inserting.');
|
||||
}
|
||||
|
||||
|
||||
@@ -14,31 +14,31 @@ class InvalidDataTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests aborting of traditional SQL database systems with invalid data.
|
||||
*/
|
||||
function testInsertDuplicateData() {
|
||||
public function testInsertDuplicateData() {
|
||||
// Try to insert multiple records where at least one has bad data.
|
||||
try {
|
||||
db_insert('test')
|
||||
->fields(array('name', 'age', 'job'))
|
||||
->values(array(
|
||||
->fields(['name', 'age', 'job'])
|
||||
->values([
|
||||
'name' => 'Elvis',
|
||||
'age' => 63,
|
||||
'job' => 'Singer',
|
||||
))->values(array(
|
||||
])->values([
|
||||
'name' => 'John', // <-- Duplicate value on unique field.
|
||||
'age' => 17,
|
||||
'job' => 'Consultant',
|
||||
))
|
||||
->values(array(
|
||||
])
|
||||
->values([
|
||||
'name' => 'Frank',
|
||||
'age' => 75,
|
||||
'job' => 'Singer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
$this->fail('Insert succeeded when it should not have.');
|
||||
}
|
||||
catch (IntegrityConstraintViolationException $e) {
|
||||
// Check if the first record was inserted.
|
||||
$name = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 63))->fetchField();
|
||||
$name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 63])->fetchField();
|
||||
|
||||
if ($name == 'Elvis') {
|
||||
if (!Database::getConnection()->supportsTransactions()) {
|
||||
@@ -58,8 +58,8 @@ class InvalidDataTest extends DatabaseTestBase {
|
||||
|
||||
// Ensure the other values were not inserted.
|
||||
$record = db_select('test')
|
||||
->fields('test', array('name', 'age'))
|
||||
->condition('age', array(17, 75), 'IN')
|
||||
->fields('test', ['name', 'age'])
|
||||
->condition('age', [17, 75], 'IN')
|
||||
->execute()->fetchObject();
|
||||
|
||||
$this->assertFalse($record, 'The rest of the insert aborted as expected.');
|
||||
|
||||
@@ -16,7 +16,7 @@ class LargeQueryTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests truncation of messages when max_allowed_packet exception occurs.
|
||||
*/
|
||||
function testMaxAllowedPacketQueryTruncating() {
|
||||
public function testMaxAllowedPacketQueryTruncating() {
|
||||
// This test only makes sense if we are running on a MySQL database.
|
||||
// Test if we are.
|
||||
$database = Database::getConnectionInfo('default');
|
||||
@@ -29,7 +29,7 @@ class LargeQueryTest extends DatabaseTestBase {
|
||||
if (Environment::checkMemoryLimit($max_allowed_packet + (16 * 1024 * 1024))) {
|
||||
$long_name = str_repeat('a', $max_allowed_packet + 1);
|
||||
try {
|
||||
db_query('SELECT name FROM {test} WHERE name = :name', array(':name' => $long_name));
|
||||
db_query('SELECT name FROM {test} WHERE name = :name', [':name' => $long_name]);
|
||||
$this->fail("An exception should be thrown for queries larger than 'max_allowed_packet'");
|
||||
}
|
||||
catch (DatabaseException $e) {
|
||||
|
||||
@@ -14,14 +14,14 @@ class LoggingTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can log the existence of a query.
|
||||
*/
|
||||
function testEnableLogging() {
|
||||
public function testEnableLogging() {
|
||||
Database::startLog('testing');
|
||||
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchCol();
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchCol();
|
||||
|
||||
// Trigger a call that does not have file in the backtrace.
|
||||
call_user_func_array('db_query', array('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo')))->fetchCol();
|
||||
call_user_func_array('db_query', ['SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo']])->fetchCol();
|
||||
|
||||
$queries = Database::getLog('testing', 'default');
|
||||
|
||||
@@ -35,14 +35,14 @@ class LoggingTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can run two logs in parallel.
|
||||
*/
|
||||
function testEnableMultiLogging() {
|
||||
public function testEnableMultiLogging() {
|
||||
Database::startLog('testing1');
|
||||
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol();
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
|
||||
|
||||
Database::startLog('testing2');
|
||||
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchCol();
|
||||
|
||||
$queries1 = Database::getLog('testing1');
|
||||
$queries2 = Database::getLog('testing2');
|
||||
@@ -54,7 +54,7 @@ class LoggingTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests logging queries against multiple targets on the same connection.
|
||||
*/
|
||||
function testEnableTargetLogging() {
|
||||
public function testEnableTargetLogging() {
|
||||
// Clone the primary credentials to a replica connection and to another fake
|
||||
// connection.
|
||||
$connection_info = Database::getConnectionInfo('default');
|
||||
@@ -62,9 +62,9 @@ class LoggingTest extends DatabaseTestBase {
|
||||
|
||||
Database::startLog('testing1');
|
||||
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol();
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
|
||||
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'), array('target' => 'replica'));//->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica']);//->fetchCol();
|
||||
|
||||
$queries1 = Database::getLog('testing1');
|
||||
|
||||
@@ -80,17 +80,17 @@ class LoggingTest extends DatabaseTestBase {
|
||||
* a fake target so the query should fall back to running on the default
|
||||
* target.
|
||||
*/
|
||||
function testEnableTargetLoggingNoTarget() {
|
||||
public function testEnableTargetLoggingNoTarget() {
|
||||
Database::startLog('testing1');
|
||||
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol();
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
|
||||
|
||||
// We use "fake" here as a target because any non-existent target will do.
|
||||
// However, because all of the tests in this class share a single page
|
||||
// request there is likely to be a target of "replica" from one of the other
|
||||
// unit tests, so we use a target here that we know with absolute certainty
|
||||
// does not exist.
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'), array('target' => 'fake'))->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'fake'])->fetchCol();
|
||||
|
||||
$queries1 = Database::getLog('testing1');
|
||||
|
||||
@@ -102,7 +102,7 @@ class LoggingTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can log queries separately on different connections.
|
||||
*/
|
||||
function testEnableMultiConnectionLogging() {
|
||||
public function testEnableMultiConnectionLogging() {
|
||||
// Clone the primary credentials to a fake connection.
|
||||
// That both connections point to the same physical database is irrelevant.
|
||||
$connection_info = Database::getConnectionInfo('default');
|
||||
@@ -111,11 +111,11 @@ class LoggingTest extends DatabaseTestBase {
|
||||
Database::startLog('testing1');
|
||||
Database::startLog('testing1', 'test2');
|
||||
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol();
|
||||
db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol();
|
||||
|
||||
$old_key = db_set_active('test2');
|
||||
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'), array('target' => 'replica'))->fetchCol();
|
||||
db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica'])->fetchCol();
|
||||
|
||||
db_set_active($old_key);
|
||||
|
||||
@@ -126,4 +126,13 @@ class LoggingTest extends DatabaseTestBase {
|
||||
$this->assertEqual(count($queries2), 1, 'Correct number of queries recorded for second connection.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that getLog with a wrong key return an empty array.
|
||||
*/
|
||||
public function testGetLoggingWrongKey() {
|
||||
$result = Database::getLog('wrong');
|
||||
|
||||
$this->assertEqual($result, [], 'The function getLog with a wrong key returns an empty array.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,15 +15,15 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can merge-insert a record successfully.
|
||||
*/
|
||||
function testMergeInsert() {
|
||||
public function testMergeInsert() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
$result = db_merge('test_people')
|
||||
->key('job', 'Presenter')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'age' => 31,
|
||||
'name' => 'Tiffany',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$this->assertEqual($result, Merge::STATUS_INSERT, 'Insert status returned.');
|
||||
@@ -31,7 +31,7 @@ class MergeTest extends DatabaseTestBase {
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before + 1, $num_records_after, 'Merge inserted properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Presenter'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Presenter'])->fetch();
|
||||
$this->assertEqual($person->name, 'Tiffany', 'Name set correctly.');
|
||||
$this->assertEqual($person->age, 31, 'Age set correctly.');
|
||||
$this->assertEqual($person->job, 'Presenter', 'Job set correctly.');
|
||||
@@ -40,15 +40,15 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can merge-update a record successfully.
|
||||
*/
|
||||
function testMergeUpdate() {
|
||||
public function testMergeUpdate() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
$result = db_merge('test_people')
|
||||
->key('job', 'Speaker')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'age' => 31,
|
||||
'name' => 'Tiffany',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$this->assertEqual($result, Merge::STATUS_UPDATE, 'Update status returned.');
|
||||
@@ -56,7 +56,7 @@ class MergeTest extends DatabaseTestBase {
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch();
|
||||
$this->assertEqual($person->name, 'Tiffany', 'Name set correctly.');
|
||||
$this->assertEqual($person->age, 31, 'Age set correctly.');
|
||||
$this->assertEqual($person->job, 'Speaker', 'Job set correctly.');
|
||||
@@ -68,19 +68,19 @@ class MergeTest extends DatabaseTestBase {
|
||||
* This test varies from the previous test because it manually defines which
|
||||
* fields are inserted, and which fields are updated.
|
||||
*/
|
||||
function testMergeUpdateExcept() {
|
||||
public function testMergeUpdateExcept() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
db_merge('test_people')
|
||||
->key('job', 'Speaker')
|
||||
->insertFields(array('age' => 31))
|
||||
->updateFields(array('name' => 'Tiffany'))
|
||||
->insertFields(['age' => 31])
|
||||
->updateFields(['name' => 'Tiffany'])
|
||||
->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch();
|
||||
$this->assertEqual($person->name, 'Tiffany', 'Name set correctly.');
|
||||
$this->assertEqual($person->age, 30, 'Age skipped correctly.');
|
||||
$this->assertEqual($person->job, 'Speaker', 'Job set correctly.');
|
||||
@@ -89,24 +89,24 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can merge-update a record, with alternate replacement.
|
||||
*/
|
||||
function testMergeUpdateExplicit() {
|
||||
public function testMergeUpdateExplicit() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
db_merge('test_people')
|
||||
->key('job', 'Speaker')
|
||||
->insertFields(array(
|
||||
->insertFields([
|
||||
'age' => 31,
|
||||
'name' => 'Tiffany',
|
||||
))
|
||||
->updateFields(array(
|
||||
])
|
||||
->updateFields([
|
||||
'name' => 'Joe',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch();
|
||||
$this->assertEqual($person->name, 'Joe', 'Name set correctly.');
|
||||
$this->assertEqual($person->age, 30, 'Age skipped correctly.');
|
||||
$this->assertEqual($person->job, 'Speaker', 'Job set correctly.');
|
||||
@@ -115,10 +115,10 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can merge-update a record successfully, with expressions.
|
||||
*/
|
||||
function testMergeUpdateExpression() {
|
||||
public function testMergeUpdateExpression() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
$age_before = db_query('SELECT age FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetchField();
|
||||
$age_before = db_query('SELECT age FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetchField();
|
||||
|
||||
// This is a very contrived example, as I have no idea why you'd want to
|
||||
// change age this way, but that's beside the point.
|
||||
@@ -127,15 +127,15 @@ class MergeTest extends DatabaseTestBase {
|
||||
// which is what is supposed to happen.
|
||||
db_merge('test_people')
|
||||
->key('job', 'Speaker')
|
||||
->fields(array('name' => 'Tiffany'))
|
||||
->insertFields(array('age' => 31))
|
||||
->expression('age', 'age + :age', array(':age' => 4))
|
||||
->fields(['name' => 'Tiffany'])
|
||||
->insertFields(['age' => 31])
|
||||
->expression('age', 'age + :age', [':age' => 4])
|
||||
->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch();
|
||||
$this->assertEqual($person->name, 'Tiffany', 'Name set correctly.');
|
||||
$this->assertEqual($person->age, $age_before + 4, 'Age updated correctly.');
|
||||
$this->assertEqual($person->job, 'Speaker', 'Job set correctly.');
|
||||
@@ -144,7 +144,7 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can merge-insert without any update fields.
|
||||
*/
|
||||
function testMergeInsertWithoutUpdate() {
|
||||
public function testMergeInsertWithoutUpdate() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
db_merge('test_people')
|
||||
@@ -154,7 +154,7 @@ class MergeTest extends DatabaseTestBase {
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before + 1, $num_records_after, 'Merge inserted properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Presenter'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Presenter'])->fetch();
|
||||
$this->assertEqual($person->name, '', 'Name set correctly.');
|
||||
$this->assertEqual($person->age, 0, 'Age set correctly.');
|
||||
$this->assertEqual($person->job, 'Presenter', 'Job set correctly.');
|
||||
@@ -163,7 +163,7 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can merge-update without any update fields.
|
||||
*/
|
||||
function testMergeUpdateWithoutUpdate() {
|
||||
public function testMergeUpdateWithoutUpdate() {
|
||||
$num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
|
||||
db_merge('test_people')
|
||||
@@ -173,20 +173,20 @@ class MergeTest extends DatabaseTestBase {
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before, $num_records_after, 'Merge skipped properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch();
|
||||
$this->assertEqual($person->name, 'Meredith', 'Name skipped correctly.');
|
||||
$this->assertEqual($person->age, 30, 'Age skipped correctly.');
|
||||
$this->assertEqual($person->job, 'Speaker', 'Job skipped correctly.');
|
||||
|
||||
db_merge('test_people')
|
||||
->key('job', 'Speaker')
|
||||
->insertFields(array('age' => 31))
|
||||
->insertFields(['age' => 31])
|
||||
->execute();
|
||||
|
||||
$num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
|
||||
$this->assertEqual($num_records_before, $num_records_after, 'Merge skipped properly.');
|
||||
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch();
|
||||
$person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch();
|
||||
$this->assertEqual($person->name, 'Meredith', 'Name skipped correctly.');
|
||||
$this->assertEqual($person->age, 30, 'Age skipped correctly.');
|
||||
$this->assertEqual($person->job, 'Speaker', 'Job skipped correctly.');
|
||||
@@ -195,17 +195,17 @@ class MergeTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that an invalid merge query throws an exception.
|
||||
*/
|
||||
function testInvalidMerge() {
|
||||
public function testInvalidMerge() {
|
||||
try {
|
||||
// This query will fail because there is no key field specified.
|
||||
// Normally it would throw an exception but we are suppressing it with
|
||||
// the throw_exception option.
|
||||
$options['throw_exception'] = FALSE;
|
||||
db_merge('test_people', $options)
|
||||
->fields(array(
|
||||
->fields([
|
||||
'age' => 31,
|
||||
'name' => 'Tiffany',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
$this->pass('$options[\'throw_exception\'] is FALSE, no InvalidMergeQueryException thrown.');
|
||||
}
|
||||
@@ -217,10 +217,10 @@ class MergeTest extends DatabaseTestBase {
|
||||
try {
|
||||
// This query will fail because there is no key field specified.
|
||||
db_merge('test_people')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'age' => 31,
|
||||
'name' => 'Tiffany',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
}
|
||||
catch (InvalidMergeQueryException $e) {
|
||||
|
||||
@@ -15,7 +15,7 @@ class NextIdTest extends KernelTestBase {
|
||||
* The modules to enable.
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system');
|
||||
public static $modules = ['system'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
@@ -25,7 +25,7 @@ class NextIdTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests that the sequences API works.
|
||||
*/
|
||||
function testDbNextId() {
|
||||
public function testDbNextId() {
|
||||
$first = db_next_id();
|
||||
$second = db_next_id();
|
||||
// We can test for exact increase in here because we know there is no
|
||||
|
||||
@@ -20,7 +20,7 @@ class PrefixInfoTest extends DatabaseTestBase {
|
||||
* The other two by Drupal core supported databases do not have this variable
|
||||
* set in the return array.
|
||||
*/
|
||||
function testGetPrefixInfo() {
|
||||
public function testGetPrefixInfo() {
|
||||
$connection_info = Database::getConnectionInfo('default');
|
||||
if ($connection_info['default']['driver'] == 'mysql') {
|
||||
// Copy the default connection info to the 'extra' key.
|
||||
|
||||
@@ -12,20 +12,20 @@ class QueryTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can pass an array of values directly in the query.
|
||||
*/
|
||||
function testArraySubstitution() {
|
||||
$names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', array(':ages[]' => array(25, 26, 27)))->fetchAll();
|
||||
public function testArraySubstitution() {
|
||||
$names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', [':ages[]' => [25, 26, 27]])->fetchAll();
|
||||
$this->assertEqual(count($names), 3, 'Correct number of names returned');
|
||||
|
||||
$names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', array(':ages[]' => array(25)))->fetchAll();
|
||||
$names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', [':ages[]' => [25]])->fetchAll();
|
||||
$this->assertEqual(count($names), 1, 'Correct number of names returned');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can not pass a scalar value when an array is expected.
|
||||
*/
|
||||
function testScalarSubstitution() {
|
||||
public function testScalarSubstitution() {
|
||||
try {
|
||||
$names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', array(':ages[]' => 25))->fetchAll();
|
||||
$names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', [':ages[]' => 25])->fetchAll();
|
||||
$this->fail('Array placeholder with scalar argument should result in an exception.');
|
||||
}
|
||||
catch (\InvalidArgumentException $e) {
|
||||
@@ -39,12 +39,12 @@ class QueryTest extends DatabaseTestBase {
|
||||
*/
|
||||
public function testArrayArgumentsSQLInjection() {
|
||||
// Attempt SQL injection and verify that it does not work.
|
||||
$condition = array(
|
||||
$condition = [
|
||||
"1 ;INSERT INTO {test} (name) VALUES ('test12345678'); -- " => '',
|
||||
'1' => '',
|
||||
);
|
||||
];
|
||||
try {
|
||||
db_query("SELECT * FROM {test} WHERE name = :name", array(':name' => $condition))->fetchObject();
|
||||
db_query("SELECT * FROM {test} WHERE name = :name", [':name' => $condition])->fetchObject();
|
||||
$this->fail('SQL injection attempt via array arguments should result in a database exception.');
|
||||
}
|
||||
catch (\InvalidArgumentException $e) {
|
||||
@@ -101,7 +101,7 @@ class QueryTest extends DatabaseTestBase {
|
||||
|
||||
try {
|
||||
$result = db_select('test', 't')
|
||||
->fields('t', array('name', 'name'))
|
||||
->fields('t', ['name', 'name'])
|
||||
->condition('name', 1, $injection)
|
||||
->execute();
|
||||
$this->fail('Should not be able to attempt SQL injection via operator.');
|
||||
@@ -118,7 +118,7 @@ class QueryTest extends DatabaseTestBase {
|
||||
|
||||
try {
|
||||
$result = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->fields('t', ['name'])
|
||||
->condition('name', 1, $injection)
|
||||
->execute();
|
||||
$this->fail('Should not be able to attempt SQL injection via operator.');
|
||||
@@ -139,9 +139,9 @@ class QueryTest extends DatabaseTestBase {
|
||||
$count = db_query('SELECT COUNT(*) >= 3 FROM {test}')->fetchField();
|
||||
$this->assertEqual((bool) $count, TRUE);
|
||||
|
||||
$count = db_query('SELECT COUNT(*) >= :count FROM {test}', array(
|
||||
$count = db_query('SELECT COUNT(*) >= :count FROM {test}', [
|
||||
':count' => 3,
|
||||
))->fetchField();
|
||||
])->fetchField();
|
||||
$this->assertEqual((bool) $count, TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,17 +9,10 @@ namespace Drupal\KernelTests\Core\Database;
|
||||
*/
|
||||
class RangeQueryTest extends DatabaseTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('database_test');
|
||||
|
||||
/**
|
||||
* Confirms that range queries work and return the correct result.
|
||||
*/
|
||||
function testRangeQuery() {
|
||||
public function testRangeQuery() {
|
||||
// Test if return correct number of rows.
|
||||
$range_rows = db_query_range("SELECT name FROM {test} ORDER BY name", 1, 3)->fetchAll();
|
||||
$this->assertEqual(count($range_rows), 3, 'Range query work and return correct number of rows.');
|
||||
|
||||
@@ -14,29 +14,29 @@ class RegressionTest extends DatabaseTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'user');
|
||||
public static $modules = ['node', 'user'];
|
||||
|
||||
/**
|
||||
* Ensures that non-ASCII UTF-8 data is stored in the database properly.
|
||||
*/
|
||||
function testRegression_310447() {
|
||||
public function testRegression_310447() {
|
||||
// That's a 255 character UTF-8 string.
|
||||
$job = str_repeat("é", 255);
|
||||
db_insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => $this->randomMachineName(),
|
||||
'age' => 20,
|
||||
'job' => $job,
|
||||
))->execute();
|
||||
])->execute();
|
||||
|
||||
$from_database = db_query('SELECT job FROM {test} WHERE job = :job', array(':job' => $job))->fetchField();
|
||||
$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.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the db_table_exists() function.
|
||||
*/
|
||||
function testDBTableExists() {
|
||||
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.');
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class RegressionTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests the db_field_exists() function.
|
||||
*/
|
||||
function testDBFieldExists() {
|
||||
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.');
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class RegressionTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests the db_index_exists() function.
|
||||
*/
|
||||
function testDBIndexExists() {
|
||||
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.');
|
||||
}
|
||||
|
||||
@@ -24,34 +24,34 @@ class SchemaTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests database interactions.
|
||||
*/
|
||||
function testSchema() {
|
||||
public function testSchema() {
|
||||
// Try creating a table.
|
||||
$table_specification = array(
|
||||
$table_specification = [
|
||||
'description' => 'Schema table description may contain "quotes" and could be long—very long indeed.',
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => 'int',
|
||||
'default' => NULL,
|
||||
),
|
||||
'test_field' => array(
|
||||
],
|
||||
'test_field' => [
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Schema table description may contain "quotes" and could be long—very long indeed. There could be "multiple quoted regions".',
|
||||
),
|
||||
'test_field_string' => array(
|
||||
],
|
||||
'test_field_string' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 20,
|
||||
'not null' => TRUE,
|
||||
'default' => "'\"funky default'\"",
|
||||
'description' => 'Schema column description for string.',
|
||||
),
|
||||
'test_field_string_ascii' => array(
|
||||
],
|
||||
'test_field_string_ascii' => [
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 255,
|
||||
'description' => 'Schema column description for ASCII string.',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
db_create_table('test_table', $table_specification);
|
||||
|
||||
// Assert that the table exists.
|
||||
@@ -95,7 +95,7 @@ class SchemaTest extends KernelTestBase {
|
||||
$index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field');
|
||||
$this->assertIdentical($index_exists, FALSE, 'Fake index does not exists');
|
||||
// Add index.
|
||||
db_add_index('test_table', 'test_field', array('test_field'), $table_specification);
|
||||
db_add_index('test_table', 'test_field', ['test_field'], $table_specification);
|
||||
// Test for created index and test for the boolean result of indexExists().
|
||||
$index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field');
|
||||
$this->assertIdentical($index_exists, TRUE, 'Index created.');
|
||||
@@ -123,13 +123,13 @@ class SchemaTest extends KernelTestBase {
|
||||
// Recreate the table.
|
||||
db_create_table('test_table', $table_specification);
|
||||
db_field_set_default('test_table', 'test_field', 0);
|
||||
db_add_field('test_table', 'test_serial', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Added column description.'));
|
||||
db_add_field('test_table', 'test_serial', ['type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Added column description.']);
|
||||
|
||||
// Assert that the column comment has been set.
|
||||
$this->checkSchemaComment('Added column description.', 'test_table', 'test_serial');
|
||||
|
||||
// Change the new field to a serial column.
|
||||
db_change_field('test_table', 'test_serial', 'test_serial', array('type' => 'serial', 'not null' => TRUE, 'description' => 'Changed column description.'), array('primary key' => array('test_serial')));
|
||||
db_change_field('test_table', 'test_serial', 'test_serial', ['type' => 'serial', 'not null' => TRUE, 'description' => 'Changed column description.'], ['primary key' => ['test_serial']]);
|
||||
|
||||
// Assert that the column comment has been set.
|
||||
$this->checkSchemaComment('Changed column description.', 'test_table', 'test_serial');
|
||||
@@ -143,24 +143,46 @@ class SchemaTest extends KernelTestBase {
|
||||
$count = db_query('SELECT COUNT(*) FROM {test_table}')->fetchField();
|
||||
$this->assertEqual($count, 2, 'There were two rows.');
|
||||
|
||||
// Test adding a serial field to an existing table.
|
||||
db_drop_table('test_table');
|
||||
db_create_table('test_table', $table_specification);
|
||||
db_field_set_default('test_table', 'test_field', 0);
|
||||
db_add_field('test_table', 'test_serial', ['type' => 'serial', 'not null' => TRUE], ['primary key' => ['test_serial']]);
|
||||
|
||||
$this->assertPrimaryKeyColumns('test_table', ['test_serial']);
|
||||
|
||||
$this->assertTrue($this->tryInsert(), 'Insert with a serial succeeded.');
|
||||
$max1 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField();
|
||||
$this->assertTrue($this->tryInsert(), 'Insert with a serial succeeded.');
|
||||
$max2 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField();
|
||||
$this->assertTrue($max2 > $max1, 'The serial is monotone.');
|
||||
|
||||
$count = db_query('SELECT COUNT(*) FROM {test_table}')->fetchField();
|
||||
$this->assertEqual($count, 2, 'There were two rows.');
|
||||
|
||||
// Test adding a new column and form a composite primary key with it.
|
||||
db_add_field('test_table', 'test_composite_primary_key', ['type' => 'int', 'not null' => TRUE, 'default' => 0], ['primary key' => ['test_serial', 'test_composite_primary_key']]);
|
||||
|
||||
$this->assertPrimaryKeyColumns('test_table', ['test_serial', 'test_composite_primary_key']);
|
||||
|
||||
// Test renaming of keys and constraints.
|
||||
db_drop_table('test_table');
|
||||
$table_specification = array(
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
$table_specification = [
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'test_field' => array(
|
||||
],
|
||||
'test_field' => [
|
||||
'type' => 'int',
|
||||
'default' => 0,
|
||||
),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'test_field' => array('test_field'),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
'primary key' => ['id'],
|
||||
'unique keys' => [
|
||||
'test_field' => ['test_field'],
|
||||
],
|
||||
];
|
||||
db_create_table('test_table', $table_specification);
|
||||
|
||||
// Tests for indexes are Database specific.
|
||||
@@ -215,18 +237,18 @@ class SchemaTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
// Use database specific data type and ensure that table is created.
|
||||
$table_specification = array(
|
||||
$table_specification = [
|
||||
'description' => 'Schema table description.',
|
||||
'fields' => array(
|
||||
'timestamp' => array(
|
||||
'fields' => [
|
||||
'timestamp' => [
|
||||
'mysql_type' => 'timestamp',
|
||||
'pgsql_type' => 'timestamp',
|
||||
'sqlite_type' => 'datetime',
|
||||
'not null' => FALSE,
|
||||
'default' => NULL,
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
try {
|
||||
db_create_table('test_timestamp', $table_specification);
|
||||
}
|
||||
@@ -240,56 +262,56 @@ class SchemaTest extends KernelTestBase {
|
||||
*
|
||||
* @see \Drupal\Core\Database\Driver\mysql\Schema::getNormalizedIndexes()
|
||||
*/
|
||||
function testIndexLength() {
|
||||
public function testIndexLength() {
|
||||
if (Database::getConnection()->databaseType() != 'mysql') {
|
||||
return;
|
||||
}
|
||||
$table_specification = array(
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
$table_specification = [
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => 'int',
|
||||
'default' => NULL,
|
||||
),
|
||||
'test_field_text' => array(
|
||||
],
|
||||
'test_field_text' => [
|
||||
'type' => 'text',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'test_field_string_long' => array(
|
||||
],
|
||||
'test_field_string_long' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'test_field_string_ascii_long' => array(
|
||||
],
|
||||
'test_field_string_ascii_long' => [
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 255,
|
||||
),
|
||||
'test_field_string_short' => array(
|
||||
],
|
||||
'test_field_string_short' => [
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'test_regular' => array(
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
'test_regular' => [
|
||||
'test_field_text',
|
||||
'test_field_string_long',
|
||||
'test_field_string_ascii_long',
|
||||
'test_field_string_short',
|
||||
),
|
||||
'test_length' => array(
|
||||
array('test_field_text', 128),
|
||||
array('test_field_string_long', 128),
|
||||
array('test_field_string_ascii_long', 128),
|
||||
array('test_field_string_short', 128),
|
||||
),
|
||||
'test_mixed' => array(
|
||||
array('test_field_text', 200),
|
||||
],
|
||||
'test_length' => [
|
||||
['test_field_text', 128],
|
||||
['test_field_string_long', 128],
|
||||
['test_field_string_ascii_long', 128],
|
||||
['test_field_string_short', 128],
|
||||
],
|
||||
'test_mixed' => [
|
||||
['test_field_text', 200],
|
||||
'test_field_string_long',
|
||||
array('test_field_string_ascii_long', 200),
|
||||
['test_field_string_ascii_long', 200],
|
||||
'test_field_string_short',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
db_create_table('test_table_index_length', $table_specification);
|
||||
|
||||
$schema_object = Database::getConnection()->schema();
|
||||
@@ -331,29 +353,29 @@ class SchemaTest extends KernelTestBase {
|
||||
|
||||
// Get index information.
|
||||
$results = db_query('SHOW INDEX FROM {test_table_index_length}');
|
||||
$expected_lengths = array(
|
||||
'test_regular' => array(
|
||||
$expected_lengths = [
|
||||
'test_regular' => [
|
||||
'test_field_text' => 191,
|
||||
'test_field_string_long' => 191,
|
||||
'test_field_string_ascii_long' => NULL,
|
||||
'test_field_string_short' => NULL,
|
||||
),
|
||||
'test_length' => array(
|
||||
],
|
||||
'test_length' => [
|
||||
'test_field_text' => 128,
|
||||
'test_field_string_long' => 128,
|
||||
'test_field_string_ascii_long' => 128,
|
||||
'test_field_string_short' => NULL,
|
||||
),
|
||||
'test_mixed' => array(
|
||||
],
|
||||
'test_mixed' => [
|
||||
'test_field_text' => 191,
|
||||
'test_field_string_long' => 191,
|
||||
'test_field_string_ascii_long' => 200,
|
||||
'test_field_string_short' => NULL,
|
||||
),
|
||||
'test_separate' => array(
|
||||
],
|
||||
'test_separate' => [
|
||||
'test_field_text' => 191,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// Count the number of columns defined in the indexes.
|
||||
$column_count = 0;
|
||||
@@ -379,10 +401,10 @@ class SchemaTest extends KernelTestBase {
|
||||
* @return
|
||||
* TRUE if the insert succeeded, FALSE otherwise.
|
||||
*/
|
||||
function tryInsert($table = 'test_table') {
|
||||
public function tryInsert($table = 'test_table') {
|
||||
try {
|
||||
db_insert($table)
|
||||
->fields(array('id' => mt_rand(10, 20)))
|
||||
->fields(['id' => mt_rand(10, 20)])
|
||||
->execute();
|
||||
return TRUE;
|
||||
}
|
||||
@@ -401,7 +423,7 @@ class SchemaTest extends KernelTestBase {
|
||||
* @param $column
|
||||
* Optional column to test.
|
||||
*/
|
||||
function checkSchemaComment($description, $table, $column = NULL) {
|
||||
public function checkSchemaComment($description, $table, $column = NULL) {
|
||||
if (method_exists(Database::getConnection()->schema(), 'getComment')) {
|
||||
$comment = Database::getConnection()->schema()->getComment($table, $column);
|
||||
// The schema comment truncation for mysql is different.
|
||||
@@ -416,21 +438,21 @@ class SchemaTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests creating unsigned columns and data integrity thereof.
|
||||
*/
|
||||
function testUnsignedColumns() {
|
||||
public function testUnsignedColumns() {
|
||||
// First create the table with just a serial column.
|
||||
$table_name = 'unsigned_table';
|
||||
$table_spec = array(
|
||||
'fields' => array('serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE)),
|
||||
'primary key' => array('serial_column'),
|
||||
);
|
||||
$table_spec = [
|
||||
'fields' => ['serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE]],
|
||||
'primary key' => ['serial_column'],
|
||||
];
|
||||
db_create_table($table_name, $table_spec);
|
||||
|
||||
// Now set up columns for the other types.
|
||||
$types = array('int', 'float', 'numeric');
|
||||
$types = ['int', 'float', 'numeric'];
|
||||
foreach ($types as $type) {
|
||||
$column_spec = array('type' => $type, 'unsigned' => TRUE);
|
||||
$column_spec = ['type' => $type, 'unsigned' => TRUE];
|
||||
if ($type == 'numeric') {
|
||||
$column_spec += array('precision' => 10, 'scale' => 0);
|
||||
$column_spec += ['precision' => 10, 'scale' => 0];
|
||||
}
|
||||
$column_name = $type . '_column';
|
||||
$table_spec['fields'][$column_name] = $column_spec;
|
||||
@@ -439,8 +461,8 @@ class SchemaTest extends KernelTestBase {
|
||||
|
||||
// Finally, check each column and try to insert invalid values into them.
|
||||
foreach ($table_spec['fields'] as $column_name => $column_spec) {
|
||||
$this->assertTrue(db_field_exists($table_name, $column_name), format_string('Unsigned @type column was created.', array('@type' => $column_spec['type'])));
|
||||
$this->assertFalse($this->tryUnsignedInsert($table_name, $column_name), format_string('Unsigned @type column rejected a negative value.', array('@type' => $column_spec['type'])));
|
||||
$this->assertTrue(db_field_exists($table_name, $column_name), format_string('Unsigned @type column was created.', ['@type' => $column_spec['type']]));
|
||||
$this->assertFalse($this->tryUnsignedInsert($table_name, $column_name), format_string('Unsigned @type column rejected a negative value.', ['@type' => $column_spec['type']]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,10 +477,10 @@ class SchemaTest extends KernelTestBase {
|
||||
* @return
|
||||
* TRUE if the insert succeeded, FALSE otherwise.
|
||||
*/
|
||||
function tryUnsignedInsert($table_name, $column_name) {
|
||||
public function tryUnsignedInsert($table_name, $column_name) {
|
||||
try {
|
||||
db_insert($table_name)
|
||||
->fields(array($column_name => -1))
|
||||
->fields([$column_name => -1])
|
||||
->execute();
|
||||
return TRUE;
|
||||
}
|
||||
@@ -470,22 +492,22 @@ class SchemaTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests adding columns to an existing table.
|
||||
*/
|
||||
function testSchemaAddField() {
|
||||
public function testSchemaAddField() {
|
||||
// Test varchar types.
|
||||
foreach (array(1, 32, 128, 256, 512) as $length) {
|
||||
$base_field_spec = array(
|
||||
foreach ([1, 32, 128, 256, 512] as $length) {
|
||||
$base_field_spec = [
|
||||
'type' => 'varchar',
|
||||
'length' => $length,
|
||||
);
|
||||
$variations = array(
|
||||
array('not null' => FALSE),
|
||||
array('not null' => FALSE, 'default' => '7'),
|
||||
array('not null' => FALSE, 'default' => substr('"thing"', 0, $length)),
|
||||
array('not null' => FALSE, 'default' => substr("\"'hing", 0, $length)),
|
||||
array('not null' => TRUE, 'initial' => 'd'),
|
||||
array('not null' => FALSE, 'default' => NULL),
|
||||
array('not null' => TRUE, 'initial' => 'd', 'default' => '7'),
|
||||
);
|
||||
];
|
||||
$variations = [
|
||||
['not null' => FALSE],
|
||||
['not null' => FALSE, 'default' => '7'],
|
||||
['not null' => FALSE, 'default' => substr('"thing"', 0, $length)],
|
||||
['not null' => FALSE, 'default' => substr("\"'hing", 0, $length)],
|
||||
['not null' => TRUE, 'initial' => 'd'],
|
||||
['not null' => FALSE, 'default' => NULL],
|
||||
['not null' => TRUE, 'initial' => 'd', 'default' => '7'],
|
||||
];
|
||||
|
||||
foreach ($variations as $variation) {
|
||||
$field_spec = $variation + $base_field_spec;
|
||||
@@ -494,18 +516,19 @@ class SchemaTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
// Test int and float types.
|
||||
foreach (array('int', 'float') as $type) {
|
||||
foreach (array('tiny', 'small', 'medium', 'normal', 'big') as $size) {
|
||||
$base_field_spec = array(
|
||||
foreach (['int', 'float'] as $type) {
|
||||
foreach (['tiny', 'small', 'medium', 'normal', 'big'] as $size) {
|
||||
$base_field_spec = [
|
||||
'type' => $type,
|
||||
'size' => $size,
|
||||
);
|
||||
$variations = array(
|
||||
array('not null' => FALSE),
|
||||
array('not null' => FALSE, 'default' => 7),
|
||||
array('not null' => TRUE, 'initial' => 1),
|
||||
array('not null' => TRUE, 'initial' => 1, 'default' => 7),
|
||||
);
|
||||
];
|
||||
$variations = [
|
||||
['not null' => FALSE],
|
||||
['not null' => FALSE, 'default' => 7],
|
||||
['not null' => TRUE, 'initial' => 1],
|
||||
['not null' => TRUE, 'initial' => 1, 'default' => 7],
|
||||
['not null' => TRUE, 'initial_from_field' => 'serial_column'],
|
||||
];
|
||||
|
||||
foreach ($variations as $variation) {
|
||||
$field_spec = $variation + $base_field_spec;
|
||||
@@ -515,24 +538,25 @@ class SchemaTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
// Test numeric types.
|
||||
foreach (array(1, 5, 10, 40, 65) as $precision) {
|
||||
foreach (array(0, 2, 10, 30) as $scale) {
|
||||
foreach ([1, 5, 10, 40, 65] as $precision) {
|
||||
foreach ([0, 2, 10, 30] as $scale) {
|
||||
// Skip combinations where precision is smaller than scale.
|
||||
if ($precision <= $scale) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$base_field_spec = array(
|
||||
$base_field_spec = [
|
||||
'type' => 'numeric',
|
||||
'scale' => $scale,
|
||||
'precision' => $precision,
|
||||
);
|
||||
$variations = array(
|
||||
array('not null' => FALSE),
|
||||
array('not null' => FALSE, 'default' => 7),
|
||||
array('not null' => TRUE, 'initial' => 1),
|
||||
array('not null' => TRUE, 'initial' => 1, 'default' => 7),
|
||||
);
|
||||
];
|
||||
$variations = [
|
||||
['not null' => FALSE],
|
||||
['not null' => FALSE, 'default' => 7],
|
||||
['not null' => TRUE, 'initial' => 1],
|
||||
['not null' => TRUE, 'initial' => 1, 'default' => 7],
|
||||
['not null' => TRUE, 'initial_from_field' => 'serial_column'],
|
||||
];
|
||||
|
||||
foreach ($variations as $variation) {
|
||||
$field_spec = $variation + $base_field_spec;
|
||||
@@ -554,15 +578,15 @@ class SchemaTest extends KernelTestBase {
|
||||
protected function assertFieldAdditionRemoval($field_spec) {
|
||||
// Try creating the field on a new table.
|
||||
$table_name = 'test_table_' . ($this->counter++);
|
||||
$table_spec = array(
|
||||
'fields' => array(
|
||||
'serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
|
||||
$table_spec = [
|
||||
'fields' => [
|
||||
'serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE],
|
||||
'test_field' => $field_spec,
|
||||
),
|
||||
'primary key' => array('serial_column'),
|
||||
);
|
||||
],
|
||||
'primary key' => ['serial_column'],
|
||||
];
|
||||
db_create_table($table_name, $table_spec);
|
||||
$this->pass(format_string('Table %table created.', array('%table' => $table_name)));
|
||||
$this->pass(format_string('Table %table created.', ['%table' => $table_name]));
|
||||
|
||||
// Check the characteristics of the field.
|
||||
$this->assertFieldCharacteristics($table_name, 'test_field', $field_spec);
|
||||
@@ -572,24 +596,24 @@ class SchemaTest extends KernelTestBase {
|
||||
|
||||
// Try adding a field to an existing table.
|
||||
$table_name = 'test_table_' . ($this->counter++);
|
||||
$table_spec = array(
|
||||
'fields' => array(
|
||||
'serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
|
||||
),
|
||||
'primary key' => array('serial_column'),
|
||||
);
|
||||
$table_spec = [
|
||||
'fields' => [
|
||||
'serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE],
|
||||
],
|
||||
'primary key' => ['serial_column'],
|
||||
];
|
||||
db_create_table($table_name, $table_spec);
|
||||
$this->pass(format_string('Table %table created.', array('%table' => $table_name)));
|
||||
$this->pass(format_string('Table %table created.', ['%table' => $table_name]));
|
||||
|
||||
// Insert some rows to the table to test the handling of initial values.
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
db_insert($table_name)
|
||||
->useDefaults(array('serial_column'))
|
||||
->useDefaults(['serial_column'])
|
||||
->execute();
|
||||
}
|
||||
|
||||
db_add_field($table_name, 'test_field', $field_spec);
|
||||
$this->pass(format_string('Column %column created.', array('%column' => 'test_field')));
|
||||
$this->pass(format_string('Column %column created.', ['%column' => 'test_field']));
|
||||
|
||||
// Check the characteristics of the field.
|
||||
$this->assertFieldCharacteristics($table_name, 'test_field', $field_spec);
|
||||
@@ -612,7 +636,7 @@ class SchemaTest extends KernelTestBase {
|
||||
if (isset($field_spec['initial'])) {
|
||||
// There should be no row with a value different then $field_spec['initial'].
|
||||
$count = db_select($table_name)
|
||||
->fields($table_name, array('serial_column'))
|
||||
->fields($table_name, ['serial_column'])
|
||||
->condition($field_name, $field_spec['initial'], '<>')
|
||||
->countQuery()
|
||||
->execute()
|
||||
@@ -620,14 +644,27 @@ class SchemaTest extends KernelTestBase {
|
||||
$this->assertEqual($count, 0, 'Initial values filled out.');
|
||||
}
|
||||
|
||||
// Check that the initial value from another field has been registered.
|
||||
if (isset($field_spec['initial_from_field'])) {
|
||||
// There should be no row with a value different than
|
||||
// $field_spec['initial_from_field'].
|
||||
$count = db_select($table_name)
|
||||
->fields($table_name, ['serial_column'])
|
||||
->where($table_name . '.' . $field_spec['initial_from_field'] . ' <> ' . $table_name . '.' . $field_name)
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertEqual($count, 0, 'Initial values from another field filled out.');
|
||||
}
|
||||
|
||||
// Check that the default value has been registered.
|
||||
if (isset($field_spec['default'])) {
|
||||
// Try inserting a row, and check the resulting value of the new column.
|
||||
$id = db_insert($table_name)
|
||||
->useDefaults(array('serial_column'))
|
||||
->useDefaults(['serial_column'])
|
||||
->execute();
|
||||
$field_value = db_select($table_name)
|
||||
->fields($table_name, array($field_name))
|
||||
->fields($table_name, [$field_name])
|
||||
->condition('serial_column', $id)
|
||||
->execute()
|
||||
->fetchField();
|
||||
@@ -638,15 +675,15 @@ class SchemaTest extends KernelTestBase {
|
||||
/**
|
||||
* Tests changing columns between types.
|
||||
*/
|
||||
function testSchemaChangeField() {
|
||||
$field_specs = array(
|
||||
array('type' => 'int', 'size' => 'normal', 'not null' => FALSE),
|
||||
array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 17),
|
||||
array('type' => 'float', 'size' => 'normal', 'not null' => FALSE),
|
||||
array('type' => 'float', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 7.3),
|
||||
array('type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => FALSE),
|
||||
array('type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => TRUE, 'initial' => 1, 'default' => 7),
|
||||
);
|
||||
public function testSchemaChangeField() {
|
||||
$field_specs = [
|
||||
['type' => 'int', 'size' => 'normal', 'not null' => FALSE],
|
||||
['type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 17],
|
||||
['type' => 'float', 'size' => 'normal', 'not null' => FALSE],
|
||||
['type' => 'float', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 7.3],
|
||||
['type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => FALSE],
|
||||
['type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => TRUE, 'initial' => 1, 'default' => 7],
|
||||
];
|
||||
|
||||
foreach ($field_specs as $i => $old_spec) {
|
||||
foreach ($field_specs as $j => $new_spec) {
|
||||
@@ -658,12 +695,12 @@ class SchemaTest extends KernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
$field_specs = array(
|
||||
array('type' => 'varchar_ascii', 'length' => '255'),
|
||||
array('type' => 'varchar', 'length' => '255'),
|
||||
array('type' => 'text'),
|
||||
array('type' => 'blob', 'size' => 'big'),
|
||||
);
|
||||
$field_specs = [
|
||||
['type' => 'varchar_ascii', 'length' => '255'],
|
||||
['type' => 'varchar', 'length' => '255'],
|
||||
['type' => 'text'],
|
||||
['type' => 'blob', 'size' => 'big'],
|
||||
];
|
||||
|
||||
foreach ($field_specs as $i => $old_spec) {
|
||||
foreach ($field_specs as $j => $new_spec) {
|
||||
@@ -690,15 +727,15 @@ class SchemaTest extends KernelTestBase {
|
||||
*/
|
||||
protected function assertFieldChange($old_spec, $new_spec, $test_data = NULL) {
|
||||
$table_name = 'test_table_' . ($this->counter++);
|
||||
$table_spec = array(
|
||||
'fields' => array(
|
||||
'serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
|
||||
$table_spec = [
|
||||
'fields' => [
|
||||
'serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE],
|
||||
'test_field' => $old_spec,
|
||||
),
|
||||
'primary key' => array('serial_column'),
|
||||
);
|
||||
],
|
||||
'primary key' => ['serial_column'],
|
||||
];
|
||||
db_create_table($table_name, $table_spec);
|
||||
$this->pass(format_string('Table %table created.', array('%table' => $table_name)));
|
||||
$this->pass(format_string('Table %table created.', ['%table' => $table_name]));
|
||||
|
||||
// Check the characteristics of the field.
|
||||
$this->assertFieldCharacteristics($table_name, 'test_field', $old_spec);
|
||||
@@ -789,4 +826,46 @@ class SchemaTest extends KernelTestBase {
|
||||
Database::setActiveConnection('default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the primary keys of a table.
|
||||
*
|
||||
* @param string $table_name
|
||||
* The name of the table to check.
|
||||
* @param array $primary_key
|
||||
* The expected key column specifier for a table's primary key.
|
||||
*/
|
||||
protected function assertPrimaryKeyColumns($table_name, array $primary_key = []) {
|
||||
$db_type = Database::getConnection()->databaseType();
|
||||
|
||||
switch ($db_type) {
|
||||
case 'mysql':
|
||||
$result = Database::getConnection()->query("SHOW KEYS FROM {" . $table_name . "} WHERE Key_name = 'PRIMARY'")->fetchAllAssoc('Column_name');
|
||||
$this->assertSame($primary_key, array_keys($result));
|
||||
|
||||
break;
|
||||
case 'pgsql':
|
||||
$result = Database::getConnection()->query("SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = '{" . $table_name . "}'::regclass AND i.indisprimary")
|
||||
->fetchAllAssoc('attname');
|
||||
$this->assertSame($primary_key, array_keys($result));
|
||||
|
||||
break;
|
||||
case 'sqlite':
|
||||
// For SQLite we need access to the protected
|
||||
// \Drupal\Core\Database\Driver\sqlite\Schema::introspectSchema() method
|
||||
// because we have no other way of getting the table prefixes needed for
|
||||
// running a straight PRAGMA query.
|
||||
$schema_object = Database::getConnection()->schema();
|
||||
$reflection = new \ReflectionMethod($schema_object, 'introspectSchema');
|
||||
$reflection->setAccessible(TRUE);
|
||||
|
||||
$table_info = $reflection->invoke($schema_object, $table_name);
|
||||
$this->assertSame($primary_key, $table_info['primary key']);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class SelectCloneTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Test that subqueries as value within conditions are cloned properly.
|
||||
*/
|
||||
function testSelectConditionSubQueryCloning() {
|
||||
public function testSelectConditionSubQueryCloning() {
|
||||
$subquery = db_select('test', 't');
|
||||
$subquery->addField('t', 'id', 'id');
|
||||
$subquery->condition('age', 28, '<');
|
||||
|
||||
@@ -18,12 +18,12 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'user', 'node_access_test', 'field');
|
||||
public static $modules = ['system', 'user', 'node_access_test', 'field'];
|
||||
|
||||
/**
|
||||
* Tests simple JOIN statements.
|
||||
*/
|
||||
function testDefaultJoin() {
|
||||
public function testDefaultJoin() {
|
||||
$query = db_select('test_task', 't');
|
||||
$people_alias = $query->join('test', 'p', 't.pid = p.id');
|
||||
$name_field = $query->addField($people_alias, 'name', 'name');
|
||||
@@ -48,7 +48,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests LEFT OUTER joins.
|
||||
*/
|
||||
function testLeftOuterJoin() {
|
||||
public function testLeftOuterJoin() {
|
||||
$query = db_select('test', 'p');
|
||||
$people_alias = $query->leftJoin('test_task', 't', 't.pid = p.id');
|
||||
$name_field = $query->addField('p', 'name', 'name');
|
||||
@@ -72,7 +72,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests GROUP BY clauses.
|
||||
*/
|
||||
function testGroupBy() {
|
||||
public function testGroupBy() {
|
||||
$query = db_select('test_task', 't');
|
||||
$count_field = $query->addExpression('COUNT(task)', 'num');
|
||||
$task_field = $query->addField('t', 'task');
|
||||
@@ -82,7 +82,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
|
||||
$num_records = 0;
|
||||
$last_count = 0;
|
||||
$records = array();
|
||||
$records = [];
|
||||
foreach ($result as $record) {
|
||||
$num_records++;
|
||||
$this->assertTrue($record->$count_field >= $last_count, 'Results returned in correct order.');
|
||||
@@ -90,16 +90,16 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
$records[$record->$task_field] = $record->$count_field;
|
||||
}
|
||||
|
||||
$correct_results = array(
|
||||
$correct_results = [
|
||||
'eat' => 1,
|
||||
'sleep' => 2,
|
||||
'code' => 1,
|
||||
'found new band' => 1,
|
||||
'perform at superbowl' => 1,
|
||||
);
|
||||
];
|
||||
|
||||
foreach ($correct_results as $task => $count) {
|
||||
$this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", array('@task' => $task)));
|
||||
$this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", ['@task' => $task]));
|
||||
}
|
||||
|
||||
$this->assertEqual($num_records, 6, 'Returned the correct number of total rows.');
|
||||
@@ -108,7 +108,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests GROUP BY and HAVING clauses together.
|
||||
*/
|
||||
function testGroupByAndHaving() {
|
||||
public function testGroupByAndHaving() {
|
||||
$query = db_select('test_task', 't');
|
||||
$count_field = $query->addExpression('COUNT(task)', 'num');
|
||||
$task_field = $query->addField('t', 'task');
|
||||
@@ -119,7 +119,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
|
||||
$num_records = 0;
|
||||
$last_count = 0;
|
||||
$records = array();
|
||||
$records = [];
|
||||
foreach ($result as $record) {
|
||||
$num_records++;
|
||||
$this->assertTrue($record->$count_field >= 2, 'Record has the minimum count.');
|
||||
@@ -128,12 +128,12 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
$records[$record->$task_field] = $record->$count_field;
|
||||
}
|
||||
|
||||
$correct_results = array(
|
||||
$correct_results = [
|
||||
'sleep' => 2,
|
||||
);
|
||||
];
|
||||
|
||||
foreach ($correct_results as $task => $count) {
|
||||
$this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", array('@task' => $task)));
|
||||
$this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", ['@task' => $task]));
|
||||
}
|
||||
|
||||
$this->assertEqual($num_records, 1, 'Returned the correct number of total rows.');
|
||||
@@ -144,7 +144,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
*
|
||||
* The SQL clause varies with the database.
|
||||
*/
|
||||
function testRange() {
|
||||
public function testRange() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$query->addField('test', 'age', 'age');
|
||||
@@ -157,7 +157,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Test whether the range property of a select clause can be undone.
|
||||
*/
|
||||
function testRangeUndo() {
|
||||
public function testRangeUndo() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
@@ -171,7 +171,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests distinct queries.
|
||||
*/
|
||||
function testDistinct() {
|
||||
public function testDistinct() {
|
||||
$query = db_select('test_task');
|
||||
$query->addField('test_task', 'task');
|
||||
$query->distinct();
|
||||
@@ -183,7 +183,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can generate a count query from a built query.
|
||||
*/
|
||||
function testCountQuery() {
|
||||
public function testCountQuery() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
@@ -203,7 +203,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests having queries.
|
||||
*/
|
||||
function testHavingCountQuery() {
|
||||
public function testHavingCountQuery() {
|
||||
$query = db_select('test')
|
||||
->extend('Drupal\Core\Database\Query\PagerSelectExtender')
|
||||
->groupBy('age')
|
||||
@@ -217,7 +217,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that countQuery removes 'all_fields' statements and ordering clauses.
|
||||
*/
|
||||
function testCountQueryRemovals() {
|
||||
public function testCountQueryRemovals() {
|
||||
$query = db_select('test');
|
||||
$query->fields('test');
|
||||
$query->orderBy('name');
|
||||
@@ -248,14 +248,14 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that countQuery properly removes fields and expressions.
|
||||
*/
|
||||
function testCountQueryFieldRemovals() {
|
||||
public function testCountQueryFieldRemovals() {
|
||||
// countQuery should remove all fields and expressions, so this can be
|
||||
// tested by adding a non-existent field and expression: if it ends
|
||||
// up in the query, an error will be thrown. If not, it will return the
|
||||
// number of records, which in this case happens to be 4 (there are four
|
||||
// records in the {test} table).
|
||||
$query = db_select('test');
|
||||
$query->fields('test', array('fail'));
|
||||
$query->fields('test', ['fail']);
|
||||
$this->assertEqual(4, $query->countQuery()->execute()->fetchField(), 'Count Query removed fields');
|
||||
|
||||
$query = db_select('test');
|
||||
@@ -266,7 +266,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can generate a count query from a query with distinct.
|
||||
*/
|
||||
function testCountQueryDistinct() {
|
||||
public function testCountQueryDistinct() {
|
||||
$query = db_select('test_task');
|
||||
$query->addField('test_task', 'task');
|
||||
$query->distinct();
|
||||
@@ -279,7 +279,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can generate a count query from a query with GROUP BY.
|
||||
*/
|
||||
function testCountQueryGroupBy() {
|
||||
public function testCountQueryGroupBy() {
|
||||
$query = db_select('test_task');
|
||||
$query->addField('test_task', 'pid');
|
||||
$query->groupBy('pid');
|
||||
@@ -304,7 +304,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that we can properly nest conditional clauses.
|
||||
*/
|
||||
function testNestedConditions() {
|
||||
public function testNestedConditions() {
|
||||
// This query should translate to:
|
||||
// "SELECT job FROM {test} WHERE name = 'Paul' AND (age = 26 OR age = 27)"
|
||||
// That should find only one record. Yes it's a non-optimal way of writing
|
||||
@@ -321,7 +321,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms we can join on a single table twice with a dynamic alias.
|
||||
*/
|
||||
function testJoinTwice() {
|
||||
public function testJoinTwice() {
|
||||
$query = db_select('test')->fields('test');
|
||||
$alias = $query->join('test', 'test', 'test.job = %alias.job');
|
||||
$query->addField($alias, 'name', 'othername');
|
||||
@@ -335,7 +335,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can join on a query.
|
||||
*/
|
||||
function testJoinSubquery() {
|
||||
public function testJoinSubquery() {
|
||||
$this->installSchema('system', 'sequences');
|
||||
|
||||
$account = User::create([
|
||||
@@ -343,7 +343,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
'mail' => $this->randomMachineName() . '@example.com',
|
||||
]);
|
||||
|
||||
$query = db_select('test_task', 'tt', array('target' => 'replica'));
|
||||
$query = db_select('test_task', 'tt', ['target' => 'replica']);
|
||||
$query->addExpression('tt.pid + 1', 'abc');
|
||||
$query->condition('priority', 1, '>');
|
||||
$query->condition('priority', 100, '<');
|
||||
@@ -375,7 +375,7 @@ class SelectComplexTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that rowCount() throws exception on SELECT query.
|
||||
*/
|
||||
function testSelectWithRowCount() {
|
||||
public function testSelectWithRowCount() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$result = $query->execute();
|
||||
|
||||
@@ -12,7 +12,7 @@ class SelectOrderedTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests basic ORDER BY.
|
||||
*/
|
||||
function testSimpleSelectOrdered() {
|
||||
public function testSimpleSelectOrdered() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
@@ -33,7 +33,7 @@ class SelectOrderedTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests multiple ORDER BY.
|
||||
*/
|
||||
function testSimpleSelectMultiOrdered() {
|
||||
public function testSimpleSelectMultiOrdered() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
@@ -43,12 +43,12 @@ class SelectOrderedTest extends DatabaseTestBase {
|
||||
$result = $query->execute();
|
||||
|
||||
$num_records = 0;
|
||||
$expected = array(
|
||||
array('Ringo', 28, 'Drummer'),
|
||||
array('John', 25, 'Singer'),
|
||||
array('George', 27, 'Singer'),
|
||||
array('Paul', 26, 'Songwriter'),
|
||||
);
|
||||
$expected = [
|
||||
['Ringo', 28, 'Drummer'],
|
||||
['John', 25, 'Singer'],
|
||||
['George', 27, 'Singer'],
|
||||
['Paul', 26, 'Songwriter'],
|
||||
];
|
||||
$results = $result->fetchAll(\PDO::FETCH_NUM);
|
||||
foreach ($expected as $k => $record) {
|
||||
$num_records++;
|
||||
@@ -64,7 +64,7 @@ class SelectOrderedTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests ORDER BY descending.
|
||||
*/
|
||||
function testSimpleSelectOrderedDesc() {
|
||||
public function testSimpleSelectOrderedDesc() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
|
||||
@@ -12,7 +12,7 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can use a subquery in a FROM clause.
|
||||
*/
|
||||
function testFromSubquerySelect() {
|
||||
public function testFromSubquerySelect() {
|
||||
// Create a subquery, which is just a normal query object.
|
||||
$subquery = db_select('test_task', 'tt');
|
||||
$subquery->addField('tt', 'pid', 'pid');
|
||||
@@ -39,14 +39,14 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
// WHERE tt.task = 'code'
|
||||
$people = $select->execute()->fetchCol();
|
||||
|
||||
$this->assertEqual(count($people), 1, 'Returned the correct number of rows.');
|
||||
$this->assertCount(1, $people, 'Returned the correct number of rows.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can use a subquery in a FROM clause with a LIMIT.
|
||||
*/
|
||||
function testFromSubquerySelectWithLimit() {
|
||||
public function testFromSubquerySelectWithLimit() {
|
||||
// Create a subquery, which is just a normal query object.
|
||||
$subquery = db_select('test_task', 'tt');
|
||||
$subquery->addField('tt', 'pid', 'pid');
|
||||
@@ -66,13 +66,13 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
// INNER JOIN test t ON t.id=tt.pid
|
||||
$people = $select->execute()->fetchCol();
|
||||
|
||||
$this->assertEqual(count($people), 1, 'Returned the correct number of rows.');
|
||||
$this->assertCount(1, $people, 'Returned the correct number of rows.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can use a subquery in a WHERE clause.
|
||||
* Tests that we can use a subquery with an IN operator in a WHERE clause.
|
||||
*/
|
||||
function testConditionSubquerySelect() {
|
||||
public function testConditionSubquerySelect() {
|
||||
// Create a subquery, which is just a normal query object.
|
||||
$subquery = db_select('test_task', 'tt');
|
||||
$subquery->addField('tt', 'pid', 'pid');
|
||||
@@ -89,13 +89,98 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
// FROM test tt2
|
||||
// WHERE tt2.pid IN (SELECT tt.pid AS pid FROM test_task tt WHERE tt.priority=1)
|
||||
$people = $select->execute()->fetchCol();
|
||||
$this->assertEqual(count($people), 5, 'Returned the correct number of rows.');
|
||||
$this->assertCount(5, $people, 'Returned the correct number of rows.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can use a subquery with a relational operator in a WHERE clause.
|
||||
*/
|
||||
public function testConditionSubquerySelect2() {
|
||||
// Create a subquery, which is just a normal query object.
|
||||
$subquery = db_select('test', 't2');
|
||||
$subquery->addExpression('AVG(t2.age)');
|
||||
|
||||
// Create another query that adds a clause using the subquery.
|
||||
$select = db_select('test', 't');
|
||||
$select->addField('t', 'name');
|
||||
$select->condition('t.age', $subquery, '<');
|
||||
|
||||
// The resulting query should be equivalent to:
|
||||
// SELECT t.name
|
||||
// FROM test t
|
||||
// WHERE t.age < (SELECT AVG(t2.age) FROM test t2)
|
||||
$people = $select->execute()->fetchCol();
|
||||
$this->assertEquals(['John', 'Paul'], $people, 'Returned Paul and John.', 0.0, 10, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can use 2 subqueries with a relational operator in a WHERE clause.
|
||||
*/
|
||||
public function testConditionSubquerySelect3() {
|
||||
// Create subquery 1, which is just a normal query object.
|
||||
$subquery1 = db_select('test_task', 'tt');
|
||||
$subquery1->addExpression('AVG(tt.priority)');
|
||||
$subquery1->where('tt.pid = t.id');
|
||||
|
||||
// Create subquery 2, which is just a normal query object.
|
||||
$subquery2 = db_select('test_task', 'tt2');
|
||||
$subquery2->addExpression('AVG(tt2.priority)');
|
||||
|
||||
// Create another query that adds a clause using the subqueries.
|
||||
$select = db_select('test', 't');
|
||||
$select->addField('t', 'name');
|
||||
$select->condition($subquery1, $subquery2, '>');
|
||||
|
||||
// The resulting query should be equivalent to:
|
||||
// SELECT t.name
|
||||
// FROM test t
|
||||
// WHERE (SELECT AVG(tt.priority) FROM test_task tt WHERE tt.pid = t.id) > (SELECT AVG(tt2.priority) FROM test_task tt2)
|
||||
$people = $select->execute()->fetchCol();
|
||||
$this->assertEquals(['John'], $people, 'Returned John.', 0.0, 10, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can use multiple subqueries.
|
||||
*
|
||||
* This test uses a subquery at the left hand side and multiple subqueries at
|
||||
* the right hand side. The test query may not be that logical but that's due
|
||||
* to the limited amount of data and tables. 'Valid' use cases do exist :)
|
||||
*/
|
||||
public function testConditionSubquerySelect4() {
|
||||
// Create subquery 1, which is just a normal query object.
|
||||
$subquery1 = db_select('test_task', 'tt');
|
||||
$subquery1->addExpression('AVG(tt.priority)');
|
||||
$subquery1->where('tt.pid = t.id');
|
||||
|
||||
// Create subquery 2, which is just a normal query object.
|
||||
$subquery2 = db_select('test_task', 'tt2');
|
||||
$subquery2->addExpression('MIN(tt2.priority)');
|
||||
$subquery2->where('tt2.pid <> t.id');
|
||||
|
||||
// Create subquery 3, which is just a normal query object.
|
||||
$subquery3 = db_select('test_task', 'tt3');
|
||||
$subquery3->addExpression('AVG(tt3.priority)');
|
||||
$subquery3->where('tt3.pid <> t.id');
|
||||
|
||||
// Create another query that adds a clause using the subqueries.
|
||||
$select = db_select('test', 't');
|
||||
$select->addField('t', 'name');
|
||||
$select->condition($subquery1, [$subquery2, $subquery3], 'BETWEEN');
|
||||
|
||||
// The resulting query should be equivalent to:
|
||||
// SELECT t.name AS name
|
||||
// FROM {test} t
|
||||
// WHERE (SELECT AVG(tt.priority) AS expression FROM {test_task} tt WHERE (tt.pid = t.id))
|
||||
// BETWEEN (SELECT MIN(tt2.priority) AS expression FROM {test_task} tt2 WHERE (tt2.pid <> t.id))
|
||||
// AND (SELECT AVG(tt3.priority) AS expression FROM {test_task} tt3 WHERE (tt3.pid <> t.id));
|
||||
$people = $select->execute()->fetchCol();
|
||||
$this->assertEquals(['George', 'Paul'], $people, 'Returned George and Paul.', 0.0, 10, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can use a subquery in a JOIN clause.
|
||||
*/
|
||||
function testJoinSubquerySelect() {
|
||||
public function testJoinSubquerySelect() {
|
||||
// Create a subquery, which is just a normal query object.
|
||||
$subquery = db_select('test_task', 'tt');
|
||||
$subquery->addField('tt', 'pid', 'pid');
|
||||
@@ -113,7 +198,7 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
// INNER JOIN (SELECT tt.pid AS pid FROM test_task tt WHERE priority=1) tt ON t.id=tt.pid
|
||||
$people = $select->execute()->fetchCol();
|
||||
|
||||
$this->assertEqual(count($people), 2, 'Returned the correct number of rows.');
|
||||
$this->assertCount(2, $people, 'Returned the correct number of rows.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,28 +207,28 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
* We essentially select all rows from the {test} table that have matching
|
||||
* rows in the {test_people} table based on the shared name column.
|
||||
*/
|
||||
function testExistsSubquerySelect() {
|
||||
public function testExistsSubquerySelect() {
|
||||
// Put George into {test_people}.
|
||||
db_insert('test_people')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'George',
|
||||
'age' => 27,
|
||||
'job' => 'Singer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
// Base query to {test}.
|
||||
$query = db_select('test', 't')
|
||||
->fields('t', array('name'));
|
||||
->fields('t', ['name']);
|
||||
// Subquery to {test_people}.
|
||||
$subquery = db_select('test_people', 'tp')
|
||||
->fields('tp', array('name'))
|
||||
->fields('tp', ['name'])
|
||||
->where('tp.name = t.name');
|
||||
$query->exists($subquery);
|
||||
$result = $query->execute();
|
||||
|
||||
// Ensure that we got the right record.
|
||||
$record = $result->fetch();
|
||||
$this->assertEqual($record->name, 'George', 'Fetched name is correct using EXISTS query.');
|
||||
$this->assertEquals('George', $record->name, 'Fetched name is correct using EXISTS query.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,28 +237,28 @@ class SelectSubqueryTest extends DatabaseTestBase {
|
||||
* We essentially select all rows from the {test} table that don't have
|
||||
* matching rows in the {test_people} table based on the shared name column.
|
||||
*/
|
||||
function testNotExistsSubquerySelect() {
|
||||
public function testNotExistsSubquerySelect() {
|
||||
// Put George into {test_people}.
|
||||
db_insert('test_people')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'George',
|
||||
'age' => 27,
|
||||
'job' => 'Singer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Base query to {test}.
|
||||
$query = db_select('test', 't')
|
||||
->fields('t', array('name'));
|
||||
->fields('t', ['name']);
|
||||
// Subquery to {test_people}.
|
||||
$subquery = db_select('test_people', 'tp')
|
||||
->fields('tp', array('name'))
|
||||
->fields('tp', ['name'])
|
||||
->where('tp.name = t.name');
|
||||
$query->notExists($subquery);
|
||||
|
||||
// Ensure that we got the right number of records.
|
||||
$people = $query->execute()->fetchCol();
|
||||
$this->assertEqual(count($people), 3, 'NOT EXISTS query returned the correct results.');
|
||||
$this->assertCount(3, $people, 'NOT EXISTS query returned the correct results.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests rudimentary SELECT statements.
|
||||
*/
|
||||
function testSimpleSelect() {
|
||||
public function testSimpleSelect() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'name');
|
||||
$query->addField('test', 'age', 'age');
|
||||
@@ -26,7 +26,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests rudimentary SELECT statement with a COMMENT.
|
||||
*/
|
||||
function testSimpleComment() {
|
||||
public function testSimpleComment() {
|
||||
$query = db_select('test')->comment('Testing query comments');
|
||||
$query->addField('test', 'name');
|
||||
$query->addField('test', 'age', 'age');
|
||||
@@ -44,7 +44,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests query COMMENT system against vulnerabilities.
|
||||
*/
|
||||
function testVulnerableComment() {
|
||||
public function testVulnerableComment() {
|
||||
$query = db_select('test')->comment('Testing query comments */ SELECT nid FROM {node}; --');
|
||||
$query->addField('test', 'name');
|
||||
$query->addField('test', 'age', 'age');
|
||||
@@ -68,7 +68,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Provides expected and input values for testVulnerableComment().
|
||||
*/
|
||||
function makeCommentsProvider() {
|
||||
public function makeCommentsProvider() {
|
||||
return [
|
||||
[
|
||||
'/* */ ',
|
||||
@@ -99,7 +99,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests basic conditionals on SELECT statements.
|
||||
*/
|
||||
function testSimpleSelectConditional() {
|
||||
public function testSimpleSelectConditional() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_field = $query->addField('test', 'age', 'age');
|
||||
@@ -119,7 +119,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests SELECT statements with expressions.
|
||||
*/
|
||||
function testSimpleSelectExpression() {
|
||||
public function testSimpleSelectExpression() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_field = $query->addExpression("age*2", 'double_age');
|
||||
@@ -139,7 +139,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests SELECT statements with multiple expressions.
|
||||
*/
|
||||
function testSimpleSelectExpressionMultiple() {
|
||||
public function testSimpleSelectExpressionMultiple() {
|
||||
$query = db_select('test');
|
||||
$name_field = $query->addField('test', 'name');
|
||||
$age_double_field = $query->addExpression("age*2");
|
||||
@@ -161,9 +161,9 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests adding multiple fields to a SELECT statement at the same time.
|
||||
*/
|
||||
function testSimpleSelectMultipleFields() {
|
||||
public function testSimpleSelectMultipleFields() {
|
||||
$record = db_select('test')
|
||||
->fields('test', array('id', 'name', 'age', 'job'))
|
||||
->fields('test', ['id', 'name', 'age', 'job'])
|
||||
->condition('age', 27)
|
||||
->execute()->fetchObject();
|
||||
|
||||
@@ -184,7 +184,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests adding all fields from a given table to a SELECT statement.
|
||||
*/
|
||||
function testSimpleSelectAllFields() {
|
||||
public function testSimpleSelectAllFields() {
|
||||
$record = db_select('test')
|
||||
->fields('test')
|
||||
->condition('age', 27)
|
||||
@@ -207,11 +207,11 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that a comparison with NULL is always FALSE.
|
||||
*/
|
||||
function testNullCondition() {
|
||||
public function testNullCondition() {
|
||||
$this->ensureSampleDataNull();
|
||||
|
||||
$names = db_select('test_null', 'tn')
|
||||
->fields('tn', array('name'))
|
||||
->fields('tn', ['name'])
|
||||
->condition('age', NULL)
|
||||
->execute()->fetchCol();
|
||||
|
||||
@@ -221,11 +221,11 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can find a record with a NULL value.
|
||||
*/
|
||||
function testIsNullCondition() {
|
||||
public function testIsNullCondition() {
|
||||
$this->ensureSampleDataNull();
|
||||
|
||||
$names = db_select('test_null', 'tn')
|
||||
->fields('tn', array('name'))
|
||||
->fields('tn', ['name'])
|
||||
->isNull('age')
|
||||
->execute()->fetchCol();
|
||||
|
||||
@@ -236,11 +236,11 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can find a record without a NULL value.
|
||||
*/
|
||||
function testIsNotNullCondition() {
|
||||
public function testIsNotNullCondition() {
|
||||
$this->ensureSampleDataNull();
|
||||
|
||||
$names = db_select('test_null', 'tn')
|
||||
->fields('tn', array('name'))
|
||||
->fields('tn', ['name'])
|
||||
->isNotNull('tn.age')
|
||||
->orderBy('name')
|
||||
->execute()->fetchCol();
|
||||
@@ -256,13 +256,13 @@ class SelectTest extends DatabaseTestBase {
|
||||
* This is semantically equal to UNION DISTINCT, so we don't explicitly test
|
||||
* that.
|
||||
*/
|
||||
function testUnion() {
|
||||
public function testUnion() {
|
||||
$query_1 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->condition('age', array(27, 28), 'IN');
|
||||
->fields('t', ['name'])
|
||||
->condition('age', [27, 28], 'IN');
|
||||
|
||||
$query_2 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->fields('t', ['name'])
|
||||
->condition('age', 28);
|
||||
|
||||
$query_1->union($query_2);
|
||||
@@ -279,13 +279,13 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can UNION ALL multiple SELECT queries together.
|
||||
*/
|
||||
function testUnionAll() {
|
||||
public function testUnionAll() {
|
||||
$query_1 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->condition('age', array(27, 28), 'IN');
|
||||
->fields('t', ['name'])
|
||||
->condition('age', [27, 28], 'IN');
|
||||
|
||||
$query_2 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->fields('t', ['name'])
|
||||
->condition('age', 28);
|
||||
|
||||
$query_1->union($query_2, 'ALL');
|
||||
@@ -303,13 +303,13 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can get a count query for a UNION Select query.
|
||||
*/
|
||||
function testUnionCount() {
|
||||
public function testUnionCount() {
|
||||
$query_1 = db_select('test', 't')
|
||||
->fields('t', array('name', 'age'))
|
||||
->condition('age', array(27, 28), 'IN');
|
||||
->fields('t', ['name', 'age'])
|
||||
->condition('age', [27, 28], 'IN');
|
||||
|
||||
$query_2 = db_select('test', 't')
|
||||
->fields('t', array('name', 'age'))
|
||||
->fields('t', ['name', 'age'])
|
||||
->condition('age', 28);
|
||||
|
||||
$query_1->union($query_2, 'ALL');
|
||||
@@ -325,15 +325,15 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can UNION multiple Select queries together and set the ORDER.
|
||||
*/
|
||||
function testUnionOrder() {
|
||||
public function testUnionOrder() {
|
||||
// This gives George and Ringo.
|
||||
$query_1 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->condition('age', array(27, 28), 'IN');
|
||||
->fields('t', ['name'])
|
||||
->condition('age', [27, 28], 'IN');
|
||||
|
||||
// This gives Paul.
|
||||
$query_2 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->fields('t', ['name'])
|
||||
->condition('age', 26);
|
||||
|
||||
$query_1->union($query_2);
|
||||
@@ -354,15 +354,15 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that we can UNION multiple Select queries together with and a LIMIT.
|
||||
*/
|
||||
function testUnionOrderLimit() {
|
||||
public function testUnionOrderLimit() {
|
||||
// This gives George and Ringo.
|
||||
$query_1 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->condition('age', array(27, 28), 'IN');
|
||||
->fields('t', ['name'])
|
||||
->condition('age', [27, 28], 'IN');
|
||||
|
||||
// This gives Paul.
|
||||
$query_2 = db_select('test', 't')
|
||||
->fields('t', array('name'))
|
||||
->fields('t', ['name'])
|
||||
->condition('age', 26);
|
||||
|
||||
$query_1->union($query_2);
|
||||
@@ -395,19 +395,19 @@ class SelectTest extends DatabaseTestBase {
|
||||
* order each time, the only way this could happen is if we have successfully
|
||||
* triggered the database's random ordering functionality.
|
||||
*/
|
||||
function testRandomOrder() {
|
||||
public function testRandomOrder() {
|
||||
// Use 52 items, so the chance that this test fails by accident will be the
|
||||
// same as the chance that a deck of cards will come out in the same order
|
||||
// after shuffling it (in other words, nearly impossible).
|
||||
$number_of_items = 52;
|
||||
while (db_query("SELECT MAX(id) FROM {test}")->fetchField() < $number_of_items) {
|
||||
db_insert('test')->fields(array('name' => $this->randomMachineName()))->execute();
|
||||
db_insert('test')->fields(['name' => $this->randomMachineName()])->execute();
|
||||
}
|
||||
|
||||
// First select the items in order and make sure we get an ordered list.
|
||||
$expected_ids = range(1, $number_of_items);
|
||||
$ordered_ids = db_select('test', 't')
|
||||
->fields('t', array('id'))
|
||||
->fields('t', ['id'])
|
||||
->range(0, $number_of_items)
|
||||
->orderBy('id')
|
||||
->execute()
|
||||
@@ -418,7 +418,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
// expect this to contain a differently ordered version of the original
|
||||
// result.
|
||||
$randomized_ids = db_select('test', 't')
|
||||
->fields('t', array('id'))
|
||||
->fields('t', ['id'])
|
||||
->range(0, $number_of_items)
|
||||
->orderRandom()
|
||||
->execute()
|
||||
@@ -431,7 +431,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
// Now perform the exact same query again, and make sure the order is
|
||||
// different.
|
||||
$randomized_ids_second_set = db_select('test', 't')
|
||||
->fields('t', array('id'))
|
||||
->fields('t', ['id'])
|
||||
->range(0, $number_of_items)
|
||||
->orderRandom()
|
||||
->execute()
|
||||
@@ -447,24 +447,24 @@ class SelectTest extends DatabaseTestBase {
|
||||
*/
|
||||
public function testRegexCondition() {
|
||||
|
||||
$test_groups[] = array(
|
||||
$test_groups[] = [
|
||||
'regex' => 'hn$',
|
||||
'expected' => array(
|
||||
'expected' => [
|
||||
'John',
|
||||
),
|
||||
);
|
||||
$test_groups[] = array(
|
||||
],
|
||||
];
|
||||
$test_groups[] = [
|
||||
'regex' => '^Pau',
|
||||
'expected' => array(
|
||||
'expected' => [
|
||||
'Paul',
|
||||
),
|
||||
);
|
||||
$test_groups[] = array(
|
||||
],
|
||||
];
|
||||
$test_groups[] = [
|
||||
'regex' => 'Ringo|George',
|
||||
'expected' => array(
|
||||
'expected' => [
|
||||
'Ringo', 'George',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
$database = $this->container->get('database');
|
||||
@@ -480,25 +480,25 @@ class SelectTest extends DatabaseTestBase {
|
||||
|
||||
// Ensure that filter by "#" still works due to the quoting.
|
||||
$database->insert('test')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'name' => 'Pete',
|
||||
'age' => 26,
|
||||
'job' => '#Drummer',
|
||||
))
|
||||
])
|
||||
->execute();
|
||||
|
||||
$test_groups = array();
|
||||
$test_groups[] = array(
|
||||
$test_groups = [];
|
||||
$test_groups[] = [
|
||||
'regex' => '#Drummer',
|
||||
'expected' => array(
|
||||
'expected' => [
|
||||
'Pete',
|
||||
),
|
||||
);
|
||||
$test_groups[] = array(
|
||||
],
|
||||
];
|
||||
$test_groups[] = [
|
||||
'regex' => '#Singer',
|
||||
'expected' => array(
|
||||
),
|
||||
);
|
||||
'expected' => [
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($test_groups as $test_group) {
|
||||
$query = $database->select('test', 't');
|
||||
@@ -509,12 +509,19 @@ class SelectTest extends DatabaseTestBase {
|
||||
$this->assertEqual(count($result), count($test_group['expected']), 'Returns the expected number of rows.');
|
||||
$this->assertEqual(sort($result), sort($test_group['expected']), 'Returns the expected rows.');
|
||||
}
|
||||
|
||||
// Ensure that REGEXP filter still works with no-string type field.
|
||||
$query = $database->select('test', 't');
|
||||
$query->addField('t', 'age');
|
||||
$query->condition('t.age', '2[6]', 'REGEXP');
|
||||
$result = $query->execute()->fetchField();
|
||||
$this->assertEquals($result, '26', 'Regexp with number type.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that aliases are renamed when they are duplicates.
|
||||
*/
|
||||
function testSelectDuplicateAlias() {
|
||||
public function testSelectDuplicateAlias() {
|
||||
$query = db_select('test', 't');
|
||||
$alias1 = $query->addField('t', 'name', 'the_alias');
|
||||
$alias2 = $query->addField('t', 'age', 'the_alias');
|
||||
@@ -524,7 +531,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests that an invalid merge query throws an exception.
|
||||
*/
|
||||
function testInvalidSelectCount() {
|
||||
public function testInvalidSelectCount() {
|
||||
try {
|
||||
// This query will fail because the table does not exist.
|
||||
// Normally it would throw an exception but we are suppressing
|
||||
@@ -559,11 +566,11 @@ class SelectTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Tests thrown exception for IN query conditions with an empty array.
|
||||
*/
|
||||
function testEmptyInCondition() {
|
||||
public function testEmptyInCondition() {
|
||||
try {
|
||||
db_select('test', 't')
|
||||
->fields('t')
|
||||
->condition('age', array(), 'IN')
|
||||
->condition('age', [], 'IN')
|
||||
->execute();
|
||||
|
||||
$this->fail('Expected exception not thrown');
|
||||
@@ -575,7 +582,7 @@ class SelectTest extends DatabaseTestBase {
|
||||
try {
|
||||
db_select('test', 't')
|
||||
->fields('t')
|
||||
->condition('age', array(), 'NOT IN')
|
||||
->condition('age', [], 'NOT IN')
|
||||
->execute();
|
||||
|
||||
$this->fail('Expected exception not thrown');
|
||||
|
||||
@@ -11,7 +11,7 @@ class SerializeQueryTest extends DatabaseTestBase {
|
||||
/**
|
||||
* Confirms that a query can be serialized and unserialized.
|
||||
*/
|
||||
function testSerializeQuery() {
|
||||
public function testSerializeQuery() {
|
||||
$query = db_select('test');
|
||||
$query->addField('test', 'age');
|
||||
$query->condition('name', 'Ringo');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user