Update core 8.3.0
This commit is contained in:
parent
da7a7918f8
commit
cd7a898e66
6144 changed files with 132297 additions and 87747 deletions
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Bootstrap;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests drupal_set_message() and related functions.
|
||||
*
|
||||
* @group Bootstrap
|
||||
*/
|
||||
class DrupalSetMessageTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system_test'];
|
||||
|
||||
/**
|
||||
* Tests drupal_set_message().
|
||||
*/
|
||||
public function testDrupalSetMessage() {
|
||||
// The page at system-test/drupal-set-message sets two messages and then
|
||||
// removes the first before it is displayed.
|
||||
$this->drupalGet('system-test/drupal-set-message');
|
||||
$this->assertNoText('First message (removed).');
|
||||
$this->assertRaw(t('Second message with <em>markup!</em> (not removed).'));
|
||||
|
||||
// Ensure duplicate messages are handled as expected.
|
||||
$this->assertUniqueText('Non Duplicated message');
|
||||
$this->assertNoUniqueText('Duplicated message');
|
||||
|
||||
// Ensure Markup objects are rendered as expected.
|
||||
$this->assertRaw('Markup with <em>markup!</em>');
|
||||
$this->assertUniqueText('Markup with markup!');
|
||||
$this->assertRaw('Markup2 with <em>markup!</em>');
|
||||
|
||||
// Ensure when the same message is of different types it is not duplicated.
|
||||
$this->assertUniqueText('Non duplicate Markup / string.');
|
||||
$this->assertNoUniqueText('Duplicate Markup / string.');
|
||||
|
||||
// Ensure that strings that are not marked as safe are escaped.
|
||||
$this->assertEscaped('<em>This<span>markup will be</span> escaped</em>.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Cache;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Provides helper methods for cache tests.
|
||||
*/
|
||||
abstract class CacheTestBase extends BrowserTestBase {
|
||||
|
||||
protected $defaultBin = 'render';
|
||||
protected $defaultCid = 'test_temporary';
|
||||
protected $defaultValue = 'CacheTest';
|
||||
|
||||
/**
|
||||
* Checks whether or not a cache entry exists.
|
||||
*
|
||||
* @param $cid
|
||||
* The cache id.
|
||||
* @param $var
|
||||
* The variable the cache should contain.
|
||||
* @param $bin
|
||||
* The bin the cache item was stored in.
|
||||
* @return
|
||||
* TRUE on pass, FALSE on fail.
|
||||
*/
|
||||
protected function checkCacheExists($cid, $var, $bin = NULL) {
|
||||
if ($bin == NULL) {
|
||||
$bin = $this->defaultBin;
|
||||
}
|
||||
|
||||
$cached = \Drupal::cache($bin)->get($cid);
|
||||
|
||||
return isset($cached->data) && $cached->data == $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a cache entry exists.
|
||||
*
|
||||
* @param $message
|
||||
* Message to display.
|
||||
* @param $var
|
||||
* The variable the cache should contain.
|
||||
* @param $cid
|
||||
* The cache id.
|
||||
* @param $bin
|
||||
* The bin the cache item was stored in.
|
||||
*/
|
||||
protected function assertCacheExists($message, $var = NULL, $cid = NULL, $bin = NULL) {
|
||||
if ($bin == NULL) {
|
||||
$bin = $this->defaultBin;
|
||||
}
|
||||
if ($cid == NULL) {
|
||||
$cid = $this->defaultCid;
|
||||
}
|
||||
if ($var == NULL) {
|
||||
$var = $this->defaultValue;
|
||||
}
|
||||
|
||||
$this->assertTrue($this->checkCacheExists($cid, $var, $bin), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a cache entry has been removed.
|
||||
*
|
||||
* @param $message
|
||||
* Message to display.
|
||||
* @param $cid
|
||||
* The cache id.
|
||||
* @param $bin
|
||||
* The bin the cache item was stored in.
|
||||
*/
|
||||
public function assertCacheRemoved($message, $cid = NULL, $bin = NULL) {
|
||||
if ($bin == NULL) {
|
||||
$bin = $this->defaultBin;
|
||||
}
|
||||
if ($cid == NULL) {
|
||||
$cid = $this->defaultCid;
|
||||
}
|
||||
|
||||
$cached = \Drupal::cache($bin)->get($cid);
|
||||
$this->assertFalse($cached, $message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Cache;
|
||||
|
||||
/**
|
||||
* Tests our clearing is done the proper way.
|
||||
*
|
||||
* @group Cache
|
||||
*/
|
||||
use Drupal\Core\Cache\Cache;
|
||||
|
||||
class ClearTest extends CacheTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
$this->defaultBin = 'render';
|
||||
$this->defaultValue = $this->randomMachineName(10);
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests drupal_flush_all_caches().
|
||||
*/
|
||||
public function testFlushAllCaches() {
|
||||
// Create cache entries for each flushed cache bin.
|
||||
$bins = Cache::getBins();
|
||||
$this->assertTrue($bins, 'Cache::getBins() returned bins to flush.');
|
||||
foreach ($bins as $bin => $cache_backend) {
|
||||
$cid = 'test_cid_clear' . $bin;
|
||||
$cache_backend->set($cid, $this->defaultValue);
|
||||
}
|
||||
|
||||
// Remove all caches then make sure that they are cleared.
|
||||
drupal_flush_all_caches();
|
||||
|
||||
foreach ($bins as $bin => $cache_backend) {
|
||||
$cid = 'test_cid_clear' . $bin;
|
||||
$this->assertFalse($this->checkCacheExists($cid, $this->defaultValue, $bin), format_string('All cache entries removed from @bin.', ['@bin' => $bin]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Cache;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
|
||||
/**
|
||||
* Provides helper methods for page cache tags tests.
|
||||
*/
|
||||
abstract class PageCacheTagsTestBase extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Always enable header dumping in page cache tags tests, this aids debugging.
|
||||
*/
|
||||
protected $dumpHeaders = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Enable page caching.
|
||||
$config = $this->config('system.performance');
|
||||
$config->set('cache.page.max_age', 3600);
|
||||
$config->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that when loading a given page, it's a page cache hit or miss.
|
||||
*
|
||||
* @param \Drupal\Core\Url $url
|
||||
* The page for this URL will be loaded.
|
||||
* @param string $hit_or_miss
|
||||
* 'HIT' if a page cache hit is expected, 'MISS' otherwise.
|
||||
*
|
||||
* @param array|false $tags
|
||||
* When expecting a page cache hit, you may optionally specify an array of
|
||||
* expected cache tags. While FALSE, the cache tags will not be verified.
|
||||
*/
|
||||
protected function verifyPageCache(Url $url, $hit_or_miss, $tags = FALSE) {
|
||||
$this->drupalGet($url);
|
||||
$message = SafeMarkup::format('Page cache @hit_or_miss for %path.', ['@hit_or_miss' => $hit_or_miss, '%path' => $url->toString()]);
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), $hit_or_miss, $message);
|
||||
|
||||
if ($hit_or_miss === 'HIT' && is_array($tags)) {
|
||||
$absolute_url = $url->setAbsolute()->toString();
|
||||
$cid_parts = [$absolute_url, 'html'];
|
||||
$cid = implode(':', $cid_parts);
|
||||
$cache_entry = \Drupal::cache('render')->get($cid);
|
||||
sort($cache_entry->tags);
|
||||
$tags = array_unique($tags);
|
||||
sort($tags);
|
||||
$this->assertIdentical($cache_entry->tags, $tags);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Datetime;
|
||||
|
||||
use Drupal\Core\Datetime\DrupalDateTime;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests DrupalDateTime functionality.
|
||||
*
|
||||
* @group Datetime
|
||||
*/
|
||||
class DrupalDateTimeTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Set up required modules.
|
||||
*/
|
||||
public static $modules = [];
|
||||
|
||||
/**
|
||||
* Test setup.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the AJAX Timezone Callback can deal with various formats.
|
||||
*/
|
||||
public function testSystemTimezone() {
|
||||
$options = [
|
||||
'query' => [
|
||||
'date' => 'Tue+Sep+17+2013+21%3A35%3A31+GMT%2B0100+(BST)#',
|
||||
]
|
||||
];
|
||||
// Query the AJAX Timezone Callback with a long-format date.
|
||||
$response = $this->drupalGet('system/timezone/BST/3600/1', $options);
|
||||
$this->assertEqual($response, '"Europe\/London"', 'Timezone AJAX callback successfully identifies and responds to a long-format date.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that DrupalDateTime can detect the right timezone to use.
|
||||
* Test with a variety of less commonly used timezone names to
|
||||
* help ensure that the system timezone will be different than the
|
||||
* stated timezones.
|
||||
*/
|
||||
public function testDateTimezone() {
|
||||
$date_string = '2007-01-31 21:00:00';
|
||||
|
||||
// Make sure no site timezone has been set.
|
||||
$this->config('system.date')
|
||||
->set('timezone.user.configurable', 0)
|
||||
->set('timezone.default', NULL)
|
||||
->save();
|
||||
|
||||
// Detect the system timezone.
|
||||
$system_timezone = date_default_timezone_get();
|
||||
|
||||
// Create a date object with an unspecified timezone, which should
|
||||
// end up using the system timezone.
|
||||
$date = new DrupalDateTime($date_string);
|
||||
$timezone = $date->getTimezone()->getName();
|
||||
$this->assertTrue($timezone == $system_timezone, 'DrupalDateTime uses the system timezone when there is no site timezone.');
|
||||
|
||||
// Create a date object with a specified timezone.
|
||||
$date = new DrupalDateTime($date_string, 'America/Yellowknife');
|
||||
$timezone = $date->getTimezone()->getName();
|
||||
$this->assertTrue($timezone == 'America/Yellowknife', 'DrupalDateTime uses the specified timezone if provided.');
|
||||
|
||||
// Set a site timezone.
|
||||
$this->config('system.date')->set('timezone.default', 'Europe/Warsaw')->save();
|
||||
|
||||
// Create a date object with an unspecified timezone, which should
|
||||
// end up using the site timezone.
|
||||
$date = new DrupalDateTime($date_string);
|
||||
$timezone = $date->getTimezone()->getName();
|
||||
$this->assertTrue($timezone == 'Europe/Warsaw', 'DrupalDateTime uses the site timezone if provided.');
|
||||
|
||||
// Create user.
|
||||
$this->config('system.date')->set('timezone.user.configurable', 1)->save();
|
||||
$test_user = $this->drupalCreateUser([]);
|
||||
$this->drupalLogin($test_user);
|
||||
|
||||
// Set up the user with a different timezone than the site.
|
||||
$edit = ['mail' => $test_user->getEmail(), 'timezone' => 'Asia/Manila'];
|
||||
$this->drupalPostForm('user/' . $test_user->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Reload the user and reset the timezone in AccountProxy::setAccount().
|
||||
\Drupal::entityManager()->getStorage('user')->resetCache();
|
||||
$this->container->get('current_user')->setAccount(User::load($test_user->id()));
|
||||
|
||||
// Create a date object with an unspecified timezone, which should
|
||||
// end up using the user timezone.
|
||||
$date = new DrupalDateTime($date_string);
|
||||
$timezone = $date->getTimezone()->getName();
|
||||
$this->assertTrue($timezone == 'Asia/Manila', 'DrupalDateTime uses the user timezone, if configurable timezones are used and it is set.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ability to override the time zone in the format method.
|
||||
*/
|
||||
public function testTimezoneFormat() {
|
||||
// Create a date in UTC
|
||||
$date = DrupalDateTime::createFromTimestamp(87654321, 'UTC');
|
||||
|
||||
// Verify that the date format method displays the default time zone.
|
||||
$this->assertEqual($date->format('Y/m/d H:i:s e'), '1972/10/11 12:25:21 UTC', 'Date has default UTC time zone and correct date/time.');
|
||||
|
||||
// Verify that the format method can override the time zone.
|
||||
$this->assertEqual($date->format('Y/m/d H:i:s e', ['timezone' => 'America/New_York']), '1972/10/11 08:25:21 America/New_York', 'Date displayed overidden time zone and correct date/time');
|
||||
|
||||
// Verify that the date format method still displays the default time zone
|
||||
// for the date object.
|
||||
$this->assertEqual($date->format('Y/m/d H:i:s e'), '1972/10/11 12:25:21 UTC', 'Date still has default UTC time zone and correct date/time');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\DrupalKernel;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests content negotiation.
|
||||
*
|
||||
* @group DrupalKernel
|
||||
*/
|
||||
class ContentNegotiationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Verifies HTML responses for bogus Accept headers.
|
||||
*
|
||||
* Drupal does not fully support older browsers, but a page output is still
|
||||
* expected.
|
||||
*
|
||||
* @see https://www.drupal.org/node/1716790
|
||||
*/
|
||||
public function testBogusAcceptHeader() {
|
||||
$tests = [
|
||||
// See https://bugs.webkit.org/show_bug.cgi?id=27267.
|
||||
'Firefox 3.5 (2009)' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'IE8 (2009)' => 'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*',
|
||||
'Opera (2009)' => 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1',
|
||||
'Chrome (2009)' => 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
|
||||
// See https://github.com/symfony/symfony/pull/564.
|
||||
'Firefox 3.6 (2010)' => 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Safari (2010)' => '*/*',
|
||||
'Opera (2010)' => 'image/jpeg,image/gif,image/x-xbitmap,text/html,image/webp,image/png,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.1',
|
||||
// See https://www.drupal.org/node/1716790.
|
||||
'Safari (2010), iOS 4.2.1 (2012)' => 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
|
||||
'Android #1 (2012)' => 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
|
||||
'Android #2 (2012)' => 'text/xml,text/html,application/xhtml+xml,image/png,text/plain,*/*;q=0.8',
|
||||
];
|
||||
foreach ($tests as $case => $header) {
|
||||
$this->drupalGet('', [], ['Accept: ' . $header]);
|
||||
$this->assertNoText('Unsupported Media Type', '"Unsupported Media Type" not found for ' . $case);
|
||||
$this->assertText(t('Log in'), '"Log in" found for ' . $case);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\search\Entity\SearchPage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\system\Entity\Action;
|
||||
|
||||
/**
|
||||
* Tests ConfigEntity importing.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class ConfigEntityImportTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['action', 'block', 'filter', 'image', 'search', 'search_extra_type'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test methods for each module within a single test run.
|
||||
*/
|
||||
public function testConfigUpdateImport() {
|
||||
$this->doActionUpdate();
|
||||
$this->doBlockUpdate();
|
||||
$this->doFilterFormatUpdate();
|
||||
$this->doImageStyleUpdate();
|
||||
$this->doSearchPageUpdate();
|
||||
}
|
||||
/**
|
||||
* Tests updating a action during import.
|
||||
*/
|
||||
protected function doActionUpdate() {
|
||||
// Create a test action with a known label.
|
||||
$name = 'system.action.apple';
|
||||
$entity = Action::create([
|
||||
'id' => 'apple',
|
||||
'plugin' => 'action_message_action',
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
$this->checkSinglePluginConfigSync($entity, 'configuration', 'message', '');
|
||||
|
||||
// Read the existing data, and prepare an altered version in sync.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['configuration']['message'] = 'Granny Smith';
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating a block during import.
|
||||
*/
|
||||
protected function doBlockUpdate() {
|
||||
// Create a test block with a known label.
|
||||
$name = 'block.block.apple';
|
||||
$block = $this->drupalPlaceBlock('system_powered_by_block', [
|
||||
'id' => 'apple',
|
||||
'label' => 'Red Delicious',
|
||||
]);
|
||||
|
||||
$this->checkSinglePluginConfigSync($block, 'settings', 'label', 'Red Delicious');
|
||||
|
||||
// Read the existing data, and prepare an altered version in sync.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['settings']['label'] = 'Granny Smith';
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating a filter format during import.
|
||||
*/
|
||||
protected function doFilterFormatUpdate() {
|
||||
// Create a test filter format with a known label.
|
||||
$name = 'filter.format.plain_text';
|
||||
|
||||
/** @var $entity \Drupal\filter\Entity\FilterFormat */
|
||||
$entity = FilterFormat::load('plain_text');
|
||||
$plugin_collection = $entity->getPluginCollections()['filters'];
|
||||
|
||||
$filters = $entity->get('filters');
|
||||
$this->assertIdentical(72, $filters['filter_url']['settings']['filter_url_length']);
|
||||
|
||||
$filters['filter_url']['settings']['filter_url_length'] = 100;
|
||||
$entity->set('filters', $filters);
|
||||
$entity->save();
|
||||
$this->assertIdentical($filters, $entity->get('filters'));
|
||||
$this->assertIdentical($filters, $plugin_collection->getConfiguration());
|
||||
|
||||
$filters['filter_url']['settings']['filter_url_length'] = -100;
|
||||
$entity->getPluginCollections()['filters']->setConfiguration($filters);
|
||||
$entity->save();
|
||||
$this->assertIdentical($filters, $entity->get('filters'));
|
||||
$this->assertIdentical($filters, $plugin_collection->getConfiguration());
|
||||
|
||||
// Read the existing data, and prepare an altered version in sync.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['filters']['filter_url']['settings']['filter_url_length'] = 100;
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating an image style during import.
|
||||
*/
|
||||
protected function doImageStyleUpdate() {
|
||||
// Create a test image style with a known label.
|
||||
$name = 'image.style.thumbnail';
|
||||
|
||||
/** @var $entity \Drupal\image\Entity\ImageStyle */
|
||||
$entity = ImageStyle::load('thumbnail');
|
||||
$plugin_collection = $entity->getPluginCollections()['effects'];
|
||||
|
||||
$effects = $entity->get('effects');
|
||||
$effect_id = key($effects);
|
||||
$this->assertIdentical(100, $effects[$effect_id]['data']['height']);
|
||||
|
||||
$effects[$effect_id]['data']['height'] = 50;
|
||||
$entity->set('effects', $effects);
|
||||
$entity->save();
|
||||
// Ensure the entity and plugin have the correct configuration.
|
||||
$this->assertIdentical($effects, $entity->get('effects'));
|
||||
$this->assertIdentical($effects, $plugin_collection->getConfiguration());
|
||||
|
||||
$effects[$effect_id]['data']['height'] = -50;
|
||||
$entity->getPluginCollections()['effects']->setConfiguration($effects);
|
||||
$entity->save();
|
||||
// Ensure the entity and plugin have the correct configuration.
|
||||
$this->assertIdentical($effects, $entity->get('effects'));
|
||||
$this->assertIdentical($effects, $plugin_collection->getConfiguration());
|
||||
|
||||
// Read the existing data, and prepare an altered version in sync.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$effect_name = key($original_data['effects']);
|
||||
|
||||
$custom_data['effects'][$effect_name]['data']['upscale'] = FALSE;
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating a search page during import.
|
||||
*/
|
||||
protected function doSearchPageUpdate() {
|
||||
// Create a test search page with a known label.
|
||||
$name = 'search.page.apple';
|
||||
$entity = SearchPage::create([
|
||||
'id' => 'apple',
|
||||
'plugin' => 'search_extra_type_search',
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
$this->checkSinglePluginConfigSync($entity, 'configuration', 'boost', 'bi');
|
||||
|
||||
// Read the existing data, and prepare an altered version in sync.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['configuration']['boost'] = 'asdf';
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a single set of plugin config stays in sync.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityWithPluginCollectionInterface $entity
|
||||
* The entity.
|
||||
* @param string $config_key
|
||||
* Where the plugin config is stored.
|
||||
* @param string $setting_key
|
||||
* The setting within the plugin config to change.
|
||||
* @param mixed $expected
|
||||
* The expected default value of the plugin config setting.
|
||||
*/
|
||||
protected function checkSinglePluginConfigSync(EntityWithPluginCollectionInterface $entity, $config_key, $setting_key, $expected) {
|
||||
$plugin_collection = $entity->getPluginCollections()[$config_key];
|
||||
$settings = $entity->get($config_key);
|
||||
|
||||
// Ensure the default config exists.
|
||||
$this->assertIdentical($expected, $settings[$setting_key]);
|
||||
|
||||
// Change the plugin config by setting it on the entity.
|
||||
$settings[$setting_key] = $this->randomString();
|
||||
$entity->set($config_key, $settings);
|
||||
$entity->save();
|
||||
$this->assertIdentical($settings, $entity->get($config_key));
|
||||
$this->assertIdentical($settings, $plugin_collection->getConfiguration());
|
||||
|
||||
// Change the plugin config by setting it on the plugin.
|
||||
$settings[$setting_key] = $this->randomString();
|
||||
$plugin_collection->setConfiguration($settings);
|
||||
$entity->save();
|
||||
$this->assertIdentical($settings, $entity->get($config_key));
|
||||
$this->assertIdentical($settings, $plugin_collection->getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that config entities are updated during import.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the config object.
|
||||
* @param array $original_data
|
||||
* The original data stored in the config object.
|
||||
* @param array $custom_data
|
||||
* The new data to store in the config object.
|
||||
*/
|
||||
public function assertConfigUpdateImport($name, $original_data, $custom_data) {
|
||||
$this->container->get('config.storage.sync')->write($name, $custom_data);
|
||||
|
||||
// Verify the active configuration still returns the default values.
|
||||
$config = $this->config($name);
|
||||
$this->assertIdentical($config->get(), $original_data);
|
||||
|
||||
// Import.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Verify the values were updated.
|
||||
$this->container->get('config.factory')->reset($name);
|
||||
$config = $this->config($name);
|
||||
$this->assertIdentical($config->get(), $custom_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestBundle;
|
||||
use Drupal\entity_test\Entity\EntityTestMul;
|
||||
use Drupal\entity_test\Entity\EntityTestWithBundle;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the /add and /add/{type} controllers.
|
||||
*
|
||||
* @group entity
|
||||
*/
|
||||
class EntityAddUITest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
/**
|
||||
* Tests the add page for an entity type using bundle entities.
|
||||
*/
|
||||
public function testAddPageWithBundleEntities() {
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer entity_test_with_bundle content',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Users without create access for bundles do not have access to the add
|
||||
// page if there are no bundles.
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
$this->assertResponse(403);
|
||||
|
||||
$bundle_admin_user = $this->drupalCreateUser([
|
||||
'administer entity_test_with_bundle content',
|
||||
'administer entity_test_bundle content',
|
||||
]);
|
||||
$this->drupalLogin($bundle_admin_user);
|
||||
|
||||
// No bundles exist, the add bundle message should be present as the user
|
||||
// has the necessary permissions.
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
$this->assertText('There is no test entity bundle yet.');
|
||||
$this->assertLink('Add a new test entity bundle.');
|
||||
|
||||
// One bundle exists, confirm redirection to the add-form.
|
||||
EntityTestBundle::create([
|
||||
'id' => 'test',
|
||||
'label' => 'Test label',
|
||||
'description' => 'My test description',
|
||||
])->save();
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
$this->assertUrl('/entity_test_with_bundle/add/test');
|
||||
|
||||
// Two bundles exist, confirm both are shown.
|
||||
EntityTestBundle::create([
|
||||
'id' => 'test2',
|
||||
'label' => 'Test2 label',
|
||||
'description' => 'My test2 description',
|
||||
])->save();
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
|
||||
$this->assertLink('Test label');
|
||||
$this->assertLink('Test2 label');
|
||||
$this->assertText('My test description');
|
||||
$this->assertText('My test2 description');
|
||||
|
||||
$this->clickLink('Test2 label');
|
||||
$this->drupalGet('/entity_test_with_bundle/add/test2');
|
||||
|
||||
$this->drupalPostForm(NULL, ['name[0][value]' => 'test name'], t('Save'));
|
||||
$entity = EntityTestWithBundle::load(1);
|
||||
$this->assertEqual('test name', $entity->label());
|
||||
|
||||
// Create a new user that only has bundle specific permissions.
|
||||
$user = $this->drupalCreateUser([
|
||||
'create test entity_test_with_bundle entities',
|
||||
'create test2 entity_test_with_bundle entities',
|
||||
]);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
// Create a bundle that the user does not have create permissions for.
|
||||
EntityTestBundle::create([
|
||||
'id' => 'test3',
|
||||
'label' => 'Test3 label',
|
||||
'description' => 'My test3 description',
|
||||
])->save();
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
$this->assertLink('Test label');
|
||||
$this->assertLink('Test2 label');
|
||||
$this->assertNoLink('Test3 label');
|
||||
$this->clickLink(t('Test label'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Without any permissions, access must be denied.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Create a new user that has bundle create permissions.
|
||||
$user = $this->drupalCreateUser([
|
||||
'administer entity_test_bundle content',
|
||||
]);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
// User has access to the add page but no bundles are shown because the user
|
||||
// does not have bundle specific permissions. The add bundle message is
|
||||
// present as the user has bundle create permissions.
|
||||
$this->drupalGet('/entity_test_with_bundle/add');
|
||||
$this->assertNoLink('Test label');
|
||||
$this->assertNoLink('Test2 label');
|
||||
$this->assertNoLink('Test3 label');
|
||||
$this->assertLink('Add a new test entity bundle.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the add page for an entity type not using bundle entities.
|
||||
*/
|
||||
public function testAddPageWithoutBundleEntities() {
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer entity_test content',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
entity_test_create_bundle('test', 'Test label', 'entity_test_mul');
|
||||
// Delete the default bundle, so that we can rely on our own.
|
||||
entity_test_delete_bundle('entity_test_mul', 'entity_test_mul');
|
||||
|
||||
// One bundle exists, confirm redirection to the add-form.
|
||||
$this->drupalGet('/entity_test_mul/add');
|
||||
$this->assertUrl('/entity_test_mul/add/test');
|
||||
|
||||
// Two bundles exist, confirm both are shown.
|
||||
entity_test_create_bundle('test2', 'Test2 label', 'entity_test_mul');
|
||||
$this->drupalGet('/entity_test_mul/add');
|
||||
|
||||
$this->assertLink('Test label');
|
||||
$this->assertLink('Test2 label');
|
||||
|
||||
$this->clickLink('Test2 label');
|
||||
$this->drupalGet('/entity_test_mul/add/test2');
|
||||
|
||||
$this->drupalPostForm(NULL, ['name[0][value]' => 'test name'], t('Save'));
|
||||
$entity = EntityTestMul::load(1);
|
||||
$this->assertEqual('test name', $entity->label());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,720 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\system\Tests\Cache\PageCacheTagsTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Provides helper methods for Entity cache tags tests.
|
||||
*/
|
||||
abstract class EntityCacheTagsTestBase extends PageCacheTagsTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test', 'field_test'];
|
||||
|
||||
/**
|
||||
* The main entity used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* The entity instance referencing the main entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $referencingEntity;
|
||||
|
||||
/**
|
||||
* The entity instance not referencing the main entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $nonReferencingEntity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Give anonymous users permission to view test entities, so that we can
|
||||
// verify the cache tags of cached versions of test entity pages.
|
||||
$user_role = Role::load(RoleInterface::ANONYMOUS_ID);
|
||||
$user_role->grantPermission('view test entity');
|
||||
$user_role->save();
|
||||
|
||||
// Create an entity.
|
||||
$this->entity = $this->createEntity();
|
||||
|
||||
// If this is an entity with field UI enabled, then add a configurable
|
||||
// field. We will use this configurable field in later tests to ensure that
|
||||
// field configuration invalidate render cache entries.
|
||||
if ($this->entity->getEntityType()->get('field_ui_base_route')) {
|
||||
// Add field, so we can modify the field storage and field entities to
|
||||
// verify that changes to those indeed clear cache tags.
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'configurable_field',
|
||||
'entity_type' => $this->entity->getEntityTypeId(),
|
||||
'type' => 'test_field',
|
||||
'settings' => [],
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entity->getEntityTypeId(),
|
||||
'bundle' => $this->entity->bundle(),
|
||||
'field_name' => 'configurable_field',
|
||||
'label' => 'Configurable field',
|
||||
'settings' => [],
|
||||
])->save();
|
||||
|
||||
// Reload the entity now that a new field has been added to it.
|
||||
$storage = $this->container
|
||||
->get('entity.manager')
|
||||
->getStorage($this->entity->getEntityTypeId());
|
||||
$storage->resetCache();
|
||||
$this->entity = $storage->load($this->entity->id());
|
||||
}
|
||||
|
||||
// Create a referencing and a non-referencing entity.
|
||||
list(
|
||||
$this->referencingEntity,
|
||||
$this->nonReferencingEntity,
|
||||
) = $this->createReferenceTestEntities($this->entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates standardized entity cache tags test info.
|
||||
*
|
||||
* @param string $entity_type_label
|
||||
* The label of the entity type whose cache tags to test.
|
||||
* @param string $group
|
||||
* The test group.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @see \Drupal\simpletest\TestBase::getInfo()
|
||||
*/
|
||||
protected static function generateStandardizedInfo($entity_type_label, $group) {
|
||||
return [
|
||||
'name' => "$entity_type_label entity cache tags",
|
||||
'description' => "Test the $entity_type_label entity's cache tags.",
|
||||
'group' => $group,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity to be tested.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* The entity to be tested.
|
||||
*/
|
||||
abstract protected function createEntity();
|
||||
|
||||
/**
|
||||
* Returns the access cache contexts for the tested entity.
|
||||
*
|
||||
* Only list cache contexts that aren't part of the required cache contexts.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be tested, as created by createEntity().
|
||||
*
|
||||
* @return string[]
|
||||
* An array of the additional cache contexts.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityAccessControlHandlerInterface
|
||||
*/
|
||||
protected function getAccessCacheContextsForEntity(EntityInterface $entity) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional (non-standard) cache contexts for the tested entity.
|
||||
*
|
||||
* Only list cache contexts that aren't part of the required cache contexts.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be tested, as created by createEntity().
|
||||
*
|
||||
* @return string[]
|
||||
* An array of the additional cache contexts.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Entity\EntityCacheTagsTestBase::createEntity()
|
||||
*/
|
||||
protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional (non-standard) cache tags for the tested entity.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to be tested, as created by createEntity().
|
||||
* @return array
|
||||
* An array of the additional cache tags.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Entity\EntityCacheTagsTestBase::createEntity()
|
||||
*/
|
||||
protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional cache tags for the tested entity's listing by type.
|
||||
*
|
||||
* @return string[]
|
||||
* An array of the additional cache contexts.
|
||||
*/
|
||||
protected function getAdditionalCacheContextsForEntityListing() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional cache tags for the tested entity's listing by type.
|
||||
*
|
||||
* Necessary when there are unavoidable default entities of this type, e.g.
|
||||
* the anonymous and administrator User entities always exist.
|
||||
*
|
||||
* @return array
|
||||
* An array of the additional cache tags.
|
||||
*/
|
||||
protected function getAdditionalCacheTagsForEntityListing() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the preferred view mode for the given entity type.
|
||||
*
|
||||
* Prefers 'full', picks the first one otherwise, and if none are available,
|
||||
* chooses 'default'.
|
||||
*/
|
||||
protected function selectViewMode($entity_type) {
|
||||
$view_modes = \Drupal::entityManager()
|
||||
->getStorage('entity_view_mode')
|
||||
->loadByProperties(['targetEntityType' => $entity_type]);
|
||||
|
||||
if (empty($view_modes)) {
|
||||
return 'default';
|
||||
}
|
||||
else {
|
||||
// Prefer the "full" display mode.
|
||||
if (isset($view_modes[$entity_type . '.full'])) {
|
||||
return 'full';
|
||||
}
|
||||
else {
|
||||
$view_modes = array_keys($view_modes);
|
||||
return substr($view_modes[0], strlen($entity_type) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a referencing and a non-referencing entity for testing purposes.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $referenced_entity
|
||||
* The entity that the referencing entity should reference.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface[]
|
||||
* An array containing a referencing entity and a non-referencing entity.
|
||||
*/
|
||||
protected function createReferenceTestEntities($referenced_entity) {
|
||||
// All referencing entities should be of the type 'entity_test'.
|
||||
$entity_type = 'entity_test';
|
||||
|
||||
// Create a "foo" bundle for the given entity type.
|
||||
$bundle = 'foo';
|
||||
entity_test_create_bundle($bundle, NULL, $entity_type);
|
||||
|
||||
// Add a field of the given type to the given entity type's "foo" bundle.
|
||||
$field_name = $referenced_entity->getEntityTypeId() . '_reference';
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'type' => 'entity_reference',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
'settings' => [
|
||||
'target_type' => $referenced_entity->getEntityTypeId(),
|
||||
],
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $bundle,
|
||||
'settings' => [
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => [
|
||||
$referenced_entity->bundle() => $referenced_entity->bundle(),
|
||||
],
|
||||
'sort' => ['field' => '_none'],
|
||||
'auto_create' => FALSE,
|
||||
],
|
||||
],
|
||||
])->save();
|
||||
if (!$this->entity->getEntityType()->hasHandlerClass('view_builder')) {
|
||||
entity_get_display($entity_type, $bundle, 'full')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'entity_reference_label',
|
||||
])
|
||||
->save();
|
||||
}
|
||||
else {
|
||||
$referenced_entity_view_mode = $this->selectViewMode($this->entity->getEntityTypeId());
|
||||
entity_get_display($entity_type, $bundle, 'full')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'entity_reference_entity_view',
|
||||
'settings' => [
|
||||
'view_mode' => $referenced_entity_view_mode,
|
||||
],
|
||||
])
|
||||
->save();
|
||||
}
|
||||
|
||||
// Create an entity that does reference the entity being tested.
|
||||
$label_key = \Drupal::entityManager()->getDefinition($entity_type)->getKey('label');
|
||||
$referencing_entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create([
|
||||
$label_key => 'Referencing ' . $entity_type,
|
||||
'status' => 1,
|
||||
'type' => $bundle,
|
||||
$field_name => ['target_id' => $referenced_entity->id()],
|
||||
]);
|
||||
$referencing_entity->save();
|
||||
|
||||
// Create an entity that does not reference the entity being tested.
|
||||
$non_referencing_entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create([
|
||||
$label_key => 'Non-referencing ' . $entity_type,
|
||||
'status' => 1,
|
||||
'type' => $bundle,
|
||||
]);
|
||||
$non_referencing_entity->save();
|
||||
|
||||
return [
|
||||
$referencing_entity,
|
||||
$non_referencing_entity,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests cache tags presence and invalidation of the entity when referenced.
|
||||
*
|
||||
* Tests the following cache tags:
|
||||
* - entity type view cache tag: "<entity type>_view"
|
||||
* - entity cache tag: "<entity type>:<entity ID>"
|
||||
* - entity type list cache tag: "<entity type>_list"
|
||||
* - referencing entity type view cache tag: "<referencing entity type>_view"
|
||||
* - referencing entity type cache tag: "<referencing entity type>:<referencing entity ID>"
|
||||
*/
|
||||
public function testReferencedEntity() {
|
||||
$entity_type = $this->entity->getEntityTypeId();
|
||||
$referencing_entity_url = $this->referencingEntity->urlInfo('canonical');
|
||||
$non_referencing_entity_url = $this->nonReferencingEntity->urlInfo('canonical');
|
||||
$listing_url = Url::fromRoute('entity.entity_test.collection_referencing_entities', [
|
||||
'entity_reference_field_name' => $entity_type . '_reference',
|
||||
'referenced_entity_type' => $entity_type,
|
||||
'referenced_entity_id' => $this->entity->id(),
|
||||
]);
|
||||
$empty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_empty', ['entity_type_id' => $entity_type]);
|
||||
$nonempty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_labels_alphabetically', ['entity_type_id' => $entity_type]);
|
||||
|
||||
// The default cache contexts for rendered entities.
|
||||
$default_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
|
||||
$entity_cache_contexts = $default_cache_contexts;
|
||||
$page_cache_contexts = Cache::mergeContexts($default_cache_contexts, ['url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT]);
|
||||
|
||||
// Cache tags present on every rendered page.
|
||||
// 'user.permissions' is a required cache context, and responses that vary
|
||||
// by this cache context when requested by anonymous users automatically
|
||||
// also get this cache tag, to ensure correct invalidation.
|
||||
$page_cache_tags = Cache::mergeTags(['http_response', 'rendered'], ['config:user.role.anonymous']);
|
||||
// If the block module is used, the Block page display variant is used,
|
||||
// which adds the block config entity type's list cache tags.
|
||||
$page_cache_tags = Cache::mergeTags($page_cache_tags, \Drupal::moduleHandler()->moduleExists('block') ? ['config:block_list'] : []);
|
||||
|
||||
$page_cache_tags_referencing_entity = in_array('user.permissions', $this->getAccessCacheContextsForEntity($this->referencingEntity)) ? ['config:user.role.anonymous'] : [];
|
||||
|
||||
$view_cache_tag = [];
|
||||
if ($this->entity->getEntityType()->hasHandlerClass('view_builder')) {
|
||||
$view_cache_tag = \Drupal::entityManager()->getViewBuilder($entity_type)
|
||||
->getCacheTags();
|
||||
}
|
||||
|
||||
$context_metadata = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($entity_cache_contexts);
|
||||
$cache_context_tags = $context_metadata->getCacheTags();
|
||||
|
||||
// Generate the cache tags for the (non) referencing entities.
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($this->referencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags());
|
||||
// Includes the main entity's cache tags, since this entity references it.
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $this->entity->getCacheTags());
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $this->getAdditionalCacheTagsForEntity($this->entity));
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $view_cache_tag);
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $cache_context_tags);
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['rendered']);
|
||||
|
||||
$non_referencing_entity_cache_tags = Cache::mergeTags($this->nonReferencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags());
|
||||
$non_referencing_entity_cache_tags = Cache::mergeTags($non_referencing_entity_cache_tags, ['rendered']);
|
||||
|
||||
// Generate the cache tags for all two possible entity listing paths.
|
||||
// 1. list cache tag only (listing query has no match)
|
||||
// 2. list cache tag plus entity cache tag (listing query has a match)
|
||||
$empty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $page_cache_tags);
|
||||
|
||||
$nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->entity->getCacheTags());
|
||||
$nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $this->getAdditionalCacheTagsForEntityListing($this->entity));
|
||||
$nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags);
|
||||
|
||||
$this->pass("Test referencing entity.", 'Debug');
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
|
||||
// Verify a cache hit, but also the presence of the correct cache tags.
|
||||
$expected_tags = Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags);
|
||||
$expected_tags = Cache::mergeTags($expected_tags, $page_cache_tags_referencing_entity);
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT', $expected_tags);
|
||||
|
||||
// Also verify the existence of an entity render cache entry.
|
||||
$cache_keys = ['entity_view', 'entity_test', $this->referencingEntity->id(), 'full'];
|
||||
$cid = $this->createCacheId($cache_keys, $entity_cache_contexts);
|
||||
$access_cache_contexts = $this->getAccessCacheContextsForEntity($this->entity);
|
||||
$additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->referencingEntity);
|
||||
$redirected_cid = NULL;
|
||||
if (count($access_cache_contexts) || count($additional_cache_contexts)) {
|
||||
$cache_contexts = Cache::mergeContexts($entity_cache_contexts, $additional_cache_contexts);
|
||||
$cache_contexts = Cache::mergeContexts($cache_contexts, $access_cache_contexts);
|
||||
$redirected_cid = $this->createCacheId($cache_keys, $cache_contexts);
|
||||
$context_metadata = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($cache_contexts);
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $context_metadata->getCacheTags());
|
||||
}
|
||||
$this->verifyRenderCache($cid, $referencing_entity_cache_tags, $redirected_cid);
|
||||
|
||||
$this->pass("Test non-referencing entity.", 'Debug');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'MISS');
|
||||
// Verify a cache hit, but also the presence of the correct cache tags.
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT', Cache::mergeTags($non_referencing_entity_cache_tags, $page_cache_tags));
|
||||
// Also verify the existence of an entity render cache entry.
|
||||
$cache_keys = ['entity_view', 'entity_test', $this->nonReferencingEntity->id(), 'full'];
|
||||
$cid = $this->createCacheId($cache_keys, $entity_cache_contexts);
|
||||
$this->verifyRenderCache($cid, $non_referencing_entity_cache_tags);
|
||||
|
||||
|
||||
$this->pass("Test listing of referencing entities.", 'Debug');
|
||||
// Prime the page cache for the listing of referencing entities.
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
|
||||
// Verify a cache hit, but also the presence of the correct cache tags.
|
||||
$expected_tags = Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags);
|
||||
$expected_tags = Cache::mergeTags($expected_tags, $page_cache_tags_referencing_entity);
|
||||
$this->verifyPageCache($listing_url, 'HIT', $expected_tags);
|
||||
|
||||
$this->pass("Test empty listing.", 'Debug');
|
||||
// Prime the page cache for the empty listing.
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'MISS');
|
||||
// Verify a cache hit, but also the presence of the correct cache tags.
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT', $empty_entity_listing_cache_tags);
|
||||
// Verify the entity type's list cache contexts are present.
|
||||
$contexts_in_header = $this->drupalGetHeader('X-Drupal-Cache-Contexts');
|
||||
$this->assertEqual(Cache::mergeContexts($page_cache_contexts, $this->getAdditionalCacheContextsForEntityListing()), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header));
|
||||
|
||||
|
||||
$this->pass("Test listing containing referenced entity.", 'Debug');
|
||||
// Prime the page cache for the listing containing the referenced entity.
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS', $nonempty_entity_listing_cache_tags);
|
||||
// Verify a cache hit, but also the presence of the correct cache tags.
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT', $nonempty_entity_listing_cache_tags);
|
||||
// Verify the entity type's list cache contexts are present.
|
||||
$contexts_in_header = $this->drupalGetHeader('X-Drupal-Cache-Contexts');
|
||||
$this->assertEqual(Cache::mergeContexts($page_cache_contexts, $this->getAdditionalCacheContextsForEntityListing()), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header));
|
||||
|
||||
|
||||
// Verify that after modifying the referenced entity, there is a cache miss
|
||||
// for every route except the one for the non-referencing entity.
|
||||
$this->pass("Test modification of referenced entity.", 'Debug');
|
||||
$this->entity->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
|
||||
|
||||
// Verify that after modifying the referencing entity, there is a cache miss
|
||||
// for every route except the ones for the non-referencing entity and the
|
||||
// empty entity listing.
|
||||
$this->pass("Test modification of referencing entity.", 'Debug');
|
||||
$this->referencingEntity->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
|
||||
|
||||
// Verify that after modifying the non-referencing entity, there is a cache
|
||||
// miss only for the non-referencing entity route.
|
||||
$this->pass("Test modification of non-referencing entity.", 'Debug');
|
||||
$this->nonReferencingEntity->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'MISS');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
|
||||
|
||||
if ($this->entity->getEntityType()->hasHandlerClass('view_builder')) {
|
||||
// Verify that after modifying the entity's display, there is a cache miss
|
||||
// for both the referencing entity, and the listing of referencing
|
||||
// entities, but not for any other routes.
|
||||
$referenced_entity_view_mode = $this->selectViewMode($this->entity->getEntityTypeId());
|
||||
$this->pass("Test modification of referenced entity's '$referenced_entity_view_mode' display.", 'Debug');
|
||||
$entity_display = entity_get_display($entity_type, $this->entity->bundle(), $referenced_entity_view_mode);
|
||||
$entity_display->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
}
|
||||
|
||||
|
||||
if ($bundle_entity_type_id = $this->entity->getEntityType()->getBundleEntityType()) {
|
||||
// Verify that after modifying the corresponding bundle entity, there is a
|
||||
// cache miss for both the referencing entity, and the listing of
|
||||
// referencing entities, but not for any other routes.
|
||||
$this->pass("Test modification of referenced entity's bundle entity.", 'Debug');
|
||||
$bundle_entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($bundle_entity_type_id)
|
||||
->load($this->entity->bundle());
|
||||
$bundle_entity->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
// Special case: entity types may choose to use their bundle entity type
|
||||
// cache tags, to avoid having excessively granular invalidation.
|
||||
$is_special_case = $bundle_entity->getCacheTags() == $this->entity->getCacheTags() && $bundle_entity->getEntityType()->getListCacheTags() == $this->entity->getEntityType()->getListCacheTags();
|
||||
if ($is_special_case) {
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
|
||||
}
|
||||
else {
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
}
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
if ($is_special_case) {
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($this->entity->getEntityType()->get('field_ui_base_route')) {
|
||||
// Verify that after modifying a configurable field on the entity, there
|
||||
// is a cache miss.
|
||||
$this->pass("Test modification of referenced entity's configurable field.", 'Debug');
|
||||
$field_storage_name = $this->entity->getEntityTypeId() . '.configurable_field';
|
||||
$field_storage = FieldStorageConfig::load($field_storage_name);
|
||||
$field_storage->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
|
||||
|
||||
// Verify that after modifying a configurable field on the entity, there
|
||||
// is a cache miss.
|
||||
$this->pass("Test modification of referenced entity's configurable field.", 'Debug');
|
||||
$field_name = $this->entity->getEntityTypeId() . '.' . $this->entity->bundle() . '.configurable_field';
|
||||
$field = FieldConfig::load($field_name);
|
||||
$field->save();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
}
|
||||
|
||||
|
||||
// Verify that after invalidating the entity's cache tag directly, there is
|
||||
// a cache miss for every route except the ones for the non-referencing
|
||||
// entity and the empty entity listing.
|
||||
$this->pass("Test invalidation of referenced entity's cache tag.", 'Debug');
|
||||
Cache::invalidateTags($this->entity->getCacheTagsToInvalidate());
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
|
||||
// Verify that after invalidating the entity's list cache tag directly,
|
||||
// there is a cache miss for both the empty entity listing and the non-empty
|
||||
// entity listing routes, but not for other routes.
|
||||
$this->pass("Test invalidation of referenced entity's list cache tag.", 'Debug');
|
||||
Cache::invalidateTags($this->entity->getEntityType()->getListCacheTags());
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
|
||||
|
||||
if (!empty($view_cache_tag)) {
|
||||
// Verify that after invalidating the generic entity type's view cache tag
|
||||
// directly, there is a cache miss for both the referencing entity, and the
|
||||
// listing of referencing entities, but not for other routes.
|
||||
$this->pass("Test invalidation of referenced entity's 'view' cache tag.", 'Debug');
|
||||
Cache::invalidateTags($view_cache_tag);
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT');
|
||||
$this->verifyPageCache($listing_url, 'HIT');
|
||||
}
|
||||
|
||||
// Verify that after deleting the entity, there is a cache miss for every
|
||||
// route except for the non-referencing entity one.
|
||||
$this->pass('Test deletion of referenced entity.', 'Debug');
|
||||
$this->entity->delete();
|
||||
$this->verifyPageCache($referencing_entity_url, 'MISS');
|
||||
$this->verifyPageCache($listing_url, 'MISS');
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'MISS');
|
||||
$this->verifyPageCache($non_referencing_entity_url, 'HIT');
|
||||
|
||||
// Verify cache hits.
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($this->referencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags());
|
||||
$referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['http_response', 'rendered']);
|
||||
|
||||
$nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->getAdditionalCacheTagsForEntityListing());
|
||||
$nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags);
|
||||
|
||||
$this->verifyPageCache($referencing_entity_url, 'HIT', Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags));
|
||||
$this->verifyPageCache($listing_url, 'HIT', $page_cache_tags);
|
||||
$this->verifyPageCache($empty_entity_listing_url, 'HIT', $empty_entity_listing_cache_tags);
|
||||
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT', $nonempty_entity_listing_cache_tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cache ID from a list of cache keys and a set of cache contexts.
|
||||
*
|
||||
* @param string[] $keys
|
||||
* A list of cache keys.
|
||||
* @param string[] $contexts
|
||||
* A set of cache contexts.
|
||||
*
|
||||
* @return string
|
||||
* The cache ID string.
|
||||
*/
|
||||
protected function createCacheId(array $keys, array $contexts) {
|
||||
$cid_parts = $keys;
|
||||
|
||||
$contexts = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($contexts);
|
||||
$cid_parts = array_merge($cid_parts, $contexts->getKeys());
|
||||
|
||||
return implode(':', $cid_parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a given render cache entry exists, with the correct cache tags.
|
||||
*
|
||||
* @param string $cid
|
||||
* The render cache item ID.
|
||||
* @param array $tags
|
||||
* An array of expected cache tags.
|
||||
* @param string|null $redirected_cid
|
||||
* (optional) The redirected render cache item ID.
|
||||
*/
|
||||
protected function verifyRenderCache($cid, array $tags, $redirected_cid = NULL) {
|
||||
// Also verify the existence of an entity render cache entry.
|
||||
$cache_entry = \Drupal::cache('render')->get($cid);
|
||||
$this->assertTrue($cache_entry, 'A render cache entry exists.');
|
||||
sort($cache_entry->tags);
|
||||
sort($tags);
|
||||
$this->assertIdentical($cache_entry->tags, $tags);
|
||||
$is_redirecting_cache_item = isset($cache_entry->data['#cache_redirect']);
|
||||
if ($redirected_cid === NULL) {
|
||||
$this->assertFalse($is_redirecting_cache_item, 'Render cache entry is not a redirect.');
|
||||
// If this is a redirecting cache item unlike we expected, log it.
|
||||
if ($is_redirecting_cache_item) {
|
||||
debug($cache_entry->data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Verify that $cid contains a cache redirect.
|
||||
$this->assertTrue($is_redirecting_cache_item, 'Render cache entry is a redirect.');
|
||||
// If this is not a redirecting cache item unlike we expected, log it.
|
||||
if (!$is_redirecting_cache_item) {
|
||||
debug($cache_entry->data);
|
||||
}
|
||||
// Verify that the cache redirect points to the expected CID.
|
||||
$redirect_cache_metadata = $cache_entry->data['#cache'];
|
||||
$actual_redirection_cid = $this->createCacheId(
|
||||
$redirect_cache_metadata['keys'],
|
||||
$redirect_cache_metadata['contexts']
|
||||
);
|
||||
$this->assertIdentical($redirected_cid, $actual_redirection_cid);
|
||||
// Finally, verify that the redirected CID exists and has the same cache
|
||||
// tags.
|
||||
$this->verifyRenderCache($redirected_cid, $tags);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests entity list builder functionality.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityListBuilderTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create and log in user.
|
||||
$this->webUser = $this->drupalCreateUser([
|
||||
'administer entity_test content',
|
||||
]);
|
||||
$this->drupalLogin($this->webUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test paging.
|
||||
*/
|
||||
public function testPager() {
|
||||
// Create 51 test entities.
|
||||
for ($i = 1; $i < 52; $i++) {
|
||||
EntityTest::create(['name' => 'Test entity ' . $i])->save();
|
||||
}
|
||||
|
||||
// Load the listing page.
|
||||
$this->drupalGet('entity_test/list');
|
||||
|
||||
// Item 51 should not be present.
|
||||
$this->assertRaw('Test entity 50', 'Item 50 is shown.');
|
||||
$this->assertNoRaw('Test entity 51', 'Item 51 is on the next page.');
|
||||
|
||||
// Browse to the next page.
|
||||
$this->clickLink(t('Page 2'));
|
||||
$this->assertNoRaw('Test entity 50', 'Test entity 50 is on the previous page.');
|
||||
$this->assertRaw('Test entity 51', 'Test entity 51 is shown.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct cache contexts are set.
|
||||
*/
|
||||
public function testCacheContexts() {
|
||||
/** @var \Drupal\Core\Entity\EntityListBuilderInterface $list_builder */
|
||||
$list_builder = $this->container->get('entity.manager')->getListBuilder('entity_test');
|
||||
|
||||
$build = $list_builder->render();
|
||||
$this->container->get('renderer')->renderRoot($build);
|
||||
|
||||
$this->assertEqual(['entity_test_view_grants', 'languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'url.query_args.pagers:0', 'user.permissions'], $build['#cache']['contexts']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the list cache tags are set.
|
||||
*/
|
||||
public function testCacheTags() {
|
||||
$this->drupalGet('entity_test/list');
|
||||
$this->assertCacheTag('entity_test_list');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that operations can be injected from the hook.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityOperationsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create and log in user.
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer permissions']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that hook_entity_operation_alter() can add an operation.
|
||||
*
|
||||
* @see entity_test_entity_operation_alter()
|
||||
*/
|
||||
public function testEntityOperationAlter() {
|
||||
// Check that role listing contain our test_operation operation.
|
||||
$this->drupalGet('admin/people/roles');
|
||||
$roles = user_roles();
|
||||
foreach ($roles as $role) {
|
||||
$this->assertLinkByHref($role->url() . '/test_operation');
|
||||
$this->assertLink(format_string('Test Operation: @label', ['@label' => $role->label()]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createRole(array $permissions, $rid = NULL, $name = NULL, $weight = NULL) {
|
||||
// WebTestBase::drupalCreateRole() by default uses random strings which may
|
||||
// include HTML entities for the entity label. Since in this test the entity
|
||||
// label is used to generate a link, and AssertContentTrait::assertLink() is
|
||||
// not designed to deal with links potentially containing HTML entities this
|
||||
// causes random failures. Use a random HTML safe string instead.
|
||||
$name = $name ?: $this->randomMachineName();
|
||||
return parent::createRole($permissions, $rid, $name, $weight);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,516 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity\EntityReferenceSelection;
|
||||
|
||||
use Drupal\comment\Tests\CommentTestTrait;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\comment\Entity\Comment;
|
||||
|
||||
/**
|
||||
* Tests for the base handlers provided by Entity Reference.
|
||||
*
|
||||
* @group entity_reference
|
||||
*/
|
||||
class EntityReferenceSelectionAccessTest extends BrowserTestBase {
|
||||
|
||||
use CommentTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'comment'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create an Article node type.
|
||||
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a selection plugin returns the expected results.
|
||||
*
|
||||
* @param array $selection_options
|
||||
* An array of options as required by entity reference selection plugins.
|
||||
* @param array $tests
|
||||
* An array of tests to run.
|
||||
* @param string $handler_name
|
||||
* The name of the entity type selection handler being tested.
|
||||
*/
|
||||
protected function assertReferenceable(array $selection_options, $tests, $handler_name) {
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options);
|
||||
|
||||
foreach ($tests as $test) {
|
||||
foreach ($test['arguments'] as $arguments) {
|
||||
$result = call_user_func_array([$handler, 'getReferenceableEntities'], $arguments);
|
||||
$this->assertEqual($result, $test['result'], format_string('Valid result set returned by @handler.', ['@handler' => $handler_name]));
|
||||
|
||||
$result = call_user_func_array([$handler, 'countReferenceableEntities'], $arguments);
|
||||
if (!empty($test['result'])) {
|
||||
$bundle = key($test['result']);
|
||||
$count = count($test['result'][$bundle]);
|
||||
}
|
||||
else {
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
$this->assertEqual($result, $count, format_string('Valid count returned by @handler.', ['@handler' => $handler_name]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the node-specific overrides of the entity handler.
|
||||
*/
|
||||
public function testNodeHandler() {
|
||||
$selection_options = [
|
||||
'target_type' => 'node',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
],
|
||||
];
|
||||
|
||||
// Build a set of test data.
|
||||
// Titles contain HTML-special characters to test escaping.
|
||||
$node_values = [
|
||||
'published1' => [
|
||||
'type' => 'article',
|
||||
'status' => NodeInterface::PUBLISHED,
|
||||
'title' => 'Node published1 (<&>)',
|
||||
'uid' => 1,
|
||||
],
|
||||
'published2' => [
|
||||
'type' => 'article',
|
||||
'status' => NodeInterface::PUBLISHED,
|
||||
'title' => 'Node published2 (<&>)',
|
||||
'uid' => 1,
|
||||
],
|
||||
'unpublished' => [
|
||||
'type' => 'article',
|
||||
'status' => NodeInterface::NOT_PUBLISHED,
|
||||
'title' => 'Node unpublished (<&>)',
|
||||
'uid' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
$nodes = [];
|
||||
$node_labels = [];
|
||||
foreach ($node_values as $key => $values) {
|
||||
$node = Node::create($values);
|
||||
$node->save();
|
||||
$nodes[$key] = $node;
|
||||
$node_labels[$key] = Html::escape($node->label());
|
||||
}
|
||||
|
||||
// Test as a non-admin.
|
||||
$normal_user = $this->drupalCreateUser(['access content']);
|
||||
\Drupal::currentUser()->setAccount($normal_user);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'article' => [
|
||||
$nodes['published1']->id() => $node_labels['published1'],
|
||||
$nodes['published2']->id() => $node_labels['published2'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['published1', 'CONTAINS'],
|
||||
['Published1', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'article' => [
|
||||
$nodes['published1']->id() => $node_labels['published1'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['published2', 'CONTAINS'],
|
||||
['Published2', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'article' => [
|
||||
$nodes['published2']->id() => $node_labels['published2'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['invalid node', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['Node unpublished', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler');
|
||||
|
||||
// Test as an admin.
|
||||
$admin_user = $this->drupalCreateUser(['access content', 'bypass node access']);
|
||||
\Drupal::currentUser()->setAccount($admin_user);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'article' => [
|
||||
$nodes['published1']->id() => $node_labels['published1'],
|
||||
$nodes['published2']->id() => $node_labels['published2'],
|
||||
$nodes['unpublished']->id() => $node_labels['unpublished'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['Node unpublished', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'article' => [
|
||||
$nodes['unpublished']->id() => $node_labels['unpublished'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user-specific overrides of the entity handler.
|
||||
*/
|
||||
public function testUserHandler() {
|
||||
$selection_options = [
|
||||
'target_type' => 'user',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
'include_anonymous' => TRUE,
|
||||
],
|
||||
];
|
||||
|
||||
// Build a set of test data.
|
||||
$user_values = [
|
||||
'anonymous' => User::load(0),
|
||||
'admin' => User::load(1),
|
||||
'non_admin' => [
|
||||
'name' => 'non_admin <&>',
|
||||
'mail' => 'non_admin@example.com',
|
||||
'roles' => [],
|
||||
'pass' => user_password(),
|
||||
'status' => 1,
|
||||
],
|
||||
'blocked' => [
|
||||
'name' => 'blocked <&>',
|
||||
'mail' => 'blocked@example.com',
|
||||
'roles' => [],
|
||||
'pass' => user_password(),
|
||||
'status' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$user_values['anonymous']->name = $this->config('user.settings')->get('anonymous');
|
||||
$users = [];
|
||||
|
||||
$user_labels = [];
|
||||
foreach ($user_values as $key => $values) {
|
||||
if (is_array($values)) {
|
||||
$account = User::create($values);
|
||||
$account->save();
|
||||
}
|
||||
else {
|
||||
$account = $values;
|
||||
}
|
||||
$users[$key] = $account;
|
||||
$user_labels[$key] = Html::escape($account->getUsername());
|
||||
}
|
||||
|
||||
// Test as a non-admin.
|
||||
\Drupal::currentUser()->setAccount($users['non_admin']);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'user' => [
|
||||
$users['admin']->id() => $user_labels['admin'],
|
||||
$users['non_admin']->id() => $user_labels['non_admin'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['non_admin', 'CONTAINS'],
|
||||
['NON_ADMIN', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'user' => [
|
||||
$users['non_admin']->id() => $user_labels['non_admin'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['invalid user', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['blocked', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler');
|
||||
|
||||
\Drupal::currentUser()->setAccount($users['admin']);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'user' => [
|
||||
$users['anonymous']->id() => $user_labels['anonymous'],
|
||||
$users['admin']->id() => $user_labels['admin'],
|
||||
$users['non_admin']->id() => $user_labels['non_admin'],
|
||||
$users['blocked']->id() => $user_labels['blocked'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['blocked', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'user' => [
|
||||
$users['blocked']->id() => $user_labels['blocked'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['Anonymous', 'CONTAINS'],
|
||||
['anonymous', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'user' => [
|
||||
$users['anonymous']->id() => $user_labels['anonymous'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)');
|
||||
|
||||
// Test the 'include_anonymous' option.
|
||||
$selection_options['handler_settings']['include_anonymous'] = FALSE;
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
['Anonymous', 'CONTAINS'],
|
||||
['anonymous', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)');
|
||||
|
||||
// Check that the Anonymous user is not included in the results when no
|
||||
// label matching is done, for example when using the 'options_select'
|
||||
// widget.
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL],
|
||||
],
|
||||
'result' => [
|
||||
'user' => [
|
||||
$users['admin']->id() => $user_labels['admin'],
|
||||
$users['non_admin']->id() => $user_labels['non_admin'],
|
||||
$users['blocked']->id() => $user_labels['blocked'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the comment-specific overrides of the entity handler.
|
||||
*/
|
||||
public function testCommentHandler() {
|
||||
$selection_options = [
|
||||
'target_type' => 'comment',
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
'target_bundles' => NULL,
|
||||
],
|
||||
];
|
||||
|
||||
// Build a set of test data.
|
||||
$node_values = [
|
||||
'published' => [
|
||||
'type' => 'article',
|
||||
'status' => 1,
|
||||
'title' => 'Node published',
|
||||
'uid' => 1,
|
||||
],
|
||||
'unpublished' => [
|
||||
'type' => 'article',
|
||||
'status' => 0,
|
||||
'title' => 'Node unpublished',
|
||||
'uid' => 1,
|
||||
],
|
||||
];
|
||||
$nodes = [];
|
||||
foreach ($node_values as $key => $values) {
|
||||
$node = Node::create($values);
|
||||
$node->save();
|
||||
$nodes[$key] = $node;
|
||||
}
|
||||
|
||||
// Create comment field on article.
|
||||
$this->addDefaultCommentField('node', 'article');
|
||||
|
||||
$comment_values = [
|
||||
'published_published' => [
|
||||
'entity_id' => $nodes['published']->id(),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'comment',
|
||||
'uid' => 1,
|
||||
'cid' => NULL,
|
||||
'pid' => 0,
|
||||
'status' => CommentInterface::PUBLISHED,
|
||||
'subject' => 'Comment Published <&>',
|
||||
'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
],
|
||||
'published_unpublished' => [
|
||||
'entity_id' => $nodes['published']->id(),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'comment',
|
||||
'uid' => 1,
|
||||
'cid' => NULL,
|
||||
'pid' => 0,
|
||||
'status' => CommentInterface::NOT_PUBLISHED,
|
||||
'subject' => 'Comment Unpublished <&>',
|
||||
'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
],
|
||||
'unpublished_published' => [
|
||||
'entity_id' => $nodes['unpublished']->id(),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'comment',
|
||||
'uid' => 1,
|
||||
'cid' => NULL,
|
||||
'pid' => 0,
|
||||
'status' => CommentInterface::NOT_PUBLISHED,
|
||||
'subject' => 'Comment Published on Unpublished node <&>',
|
||||
'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
],
|
||||
];
|
||||
|
||||
$comments = [];
|
||||
$comment_labels = [];
|
||||
foreach ($comment_values as $key => $values) {
|
||||
$comment = Comment::create($values);
|
||||
$comment->save();
|
||||
$comments[$key] = $comment;
|
||||
$comment_labels[$key] = Html::escape($comment->label());
|
||||
}
|
||||
|
||||
// Test as a non-admin.
|
||||
$normal_user = $this->drupalCreateUser(['access content', 'access comments']);
|
||||
\Drupal::currentUser()->setAccount($normal_user);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'comment' => [
|
||||
$comments['published_published']->cid->value => $comment_labels['published_published'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['Published', 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'comment' => [
|
||||
$comments['published_published']->cid->value => $comment_labels['published_published'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['invalid comment', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
[
|
||||
'arguments' => [
|
||||
['Comment Unpublished', 'CONTAINS'],
|
||||
],
|
||||
'result' => [],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler');
|
||||
|
||||
// Test as a comment admin.
|
||||
$admin_user = $this->drupalCreateUser(['access content', 'access comments', 'administer comments']);
|
||||
\Drupal::currentUser()->setAccount($admin_user);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'comment' => [
|
||||
$comments['published_published']->cid->value => $comment_labels['published_published'],
|
||||
$comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)');
|
||||
|
||||
// Test as a node and comment admin.
|
||||
$admin_user = $this->drupalCreateUser(['access content', 'access comments', 'administer comments', 'bypass node access']);
|
||||
\Drupal::currentUser()->setAccount($admin_user);
|
||||
$referenceable_tests = [
|
||||
[
|
||||
'arguments' => [
|
||||
[NULL, 'CONTAINS'],
|
||||
],
|
||||
'result' => [
|
||||
'comment' => [
|
||||
$comments['published_published']->cid->value => $comment_labels['published_published'],
|
||||
$comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'],
|
||||
$comments['unpublished_published']->cid->value => $comment_labels['unpublished_published'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMulRev;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Create a entity with revisions and test viewing, saving, reverting, and
|
||||
* deleting revisions.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityRevisionsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test', 'language'];
|
||||
|
||||
/**
|
||||
* A user with permission to administer entity_test content.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create and log in user.
|
||||
$this->webUser = $this->drupalCreateUser([
|
||||
'administer entity_test content',
|
||||
'view test entity',
|
||||
]);
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Enable an additional language.
|
||||
ConfigurableLanguage::createFromLangcode('de')->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check node revision related operations.
|
||||
*/
|
||||
public function testRevisions() {
|
||||
|
||||
// All revisable entity variations have to have the same results.
|
||||
foreach (entity_test_entity_types(ENTITY_TEST_TYPES_REVISABLE) as $entity_type) {
|
||||
$this->runRevisionsTests($entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the revision tests for the given entity type.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type to run the tests with.
|
||||
*/
|
||||
protected function runRevisionsTests($entity_type) {
|
||||
|
||||
// Create initial entity.
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create([
|
||||
'name' => 'foo',
|
||||
'user_id' => $this->webUser->id(),
|
||||
]);
|
||||
$entity->field_test_text->value = 'bar';
|
||||
$entity->save();
|
||||
|
||||
$names = [];
|
||||
$texts = [];
|
||||
$created = [];
|
||||
$revision_ids = [];
|
||||
|
||||
// Create three revisions.
|
||||
$revision_count = 3;
|
||||
for ($i = 0; $i < $revision_count; $i++) {
|
||||
$legacy_revision_id = $entity->revision_id->value;
|
||||
$legacy_name = $entity->name->value;
|
||||
$legacy_text = $entity->field_test_text->value;
|
||||
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)->load($entity->id->value);
|
||||
$entity->setNewRevision(TRUE);
|
||||
$names[] = $entity->name->value = $this->randomMachineName(32);
|
||||
$texts[] = $entity->field_test_text->value = $this->randomMachineName(32);
|
||||
$created[] = $entity->created->value = time() + $i + 1;
|
||||
$entity->save();
|
||||
$revision_ids[] = $entity->revision_id->value;
|
||||
|
||||
// Check that the fields and properties contain new content.
|
||||
$this->assertTrue($entity->revision_id->value > $legacy_revision_id, format_string('%entity_type: Revision ID changed.', ['%entity_type' => $entity_type]));
|
||||
$this->assertNotEqual($entity->name->value, $legacy_name, format_string('%entity_type: Name changed.', ['%entity_type' => $entity_type]));
|
||||
$this->assertNotEqual($entity->field_test_text->value, $legacy_text, format_string('%entity_type: Text changed.', ['%entity_type' => $entity_type]));
|
||||
}
|
||||
|
||||
$storage = $this->container->get('entity_type.manager')->getStorage($entity_type);
|
||||
for ($i = 0; $i < $revision_count; $i++) {
|
||||
// Load specific revision.
|
||||
$entity_revision = $storage->loadRevision($revision_ids[$i]);
|
||||
|
||||
// Check if properties and fields contain the revision specific content.
|
||||
$this->assertEqual($entity_revision->revision_id->value, $revision_ids[$i], format_string('%entity_type: Revision ID matches.', ['%entity_type' => $entity_type]));
|
||||
$this->assertEqual($entity_revision->name->value, $names[$i], format_string('%entity_type: Name matches.', ['%entity_type' => $entity_type]));
|
||||
$this->assertEqual($entity_revision->field_test_text->value, $texts[$i], format_string('%entity_type: Text matches.', ['%entity_type' => $entity_type]));
|
||||
|
||||
// Check non-revisioned values are loaded.
|
||||
$this->assertTrue(isset($entity_revision->created->value), format_string('%entity_type: Non-revisioned field is loaded.', ['%entity_type' => $entity_type]));
|
||||
$this->assertEqual($entity_revision->created->value, $created[2], format_string('%entity_type: Non-revisioned field value is the same between revisions.', ['%entity_type' => $entity_type]));
|
||||
}
|
||||
|
||||
// Confirm the correct revision text appears in the edit form.
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->load($entity->id->value);
|
||||
$this->drupalGet($entity_type . '/manage/' . $entity->id->value . '/edit');
|
||||
$this->assertFieldById('edit-name-0-value', $entity->name->value, format_string('%entity_type: Name matches in UI.', ['%entity_type' => $entity_type]));
|
||||
$this->assertFieldById('edit-field-test-text-0-value', $entity->field_test_text->value, format_string('%entity_type: Text matches in UI.', ['%entity_type' => $entity_type]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an entity revision is upcasted in the correct language.
|
||||
*/
|
||||
public function testEntityRevisionParamConverter() {
|
||||
// Create a test entity with multiple revisions and translations for them.
|
||||
$entity = EntityTestMulRev::create([
|
||||
'name' => 'default revision - en',
|
||||
'user_id' => $this->webUser,
|
||||
'language' => 'en',
|
||||
]);
|
||||
$entity->addTranslation('de', ['name' => 'default revision - de']);
|
||||
$entity->save();
|
||||
|
||||
$forward_revision = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev')->loadUnchanged($entity->id());
|
||||
|
||||
$forward_revision->setNewRevision();
|
||||
$forward_revision->isDefaultRevision(FALSE);
|
||||
|
||||
$forward_revision->name = 'forward revision - en';
|
||||
$forward_revision->save();
|
||||
|
||||
$forward_revision_translation = $forward_revision->getTranslation('de');
|
||||
$forward_revision_translation->name = 'forward revision - de';
|
||||
$forward_revision_translation->save();
|
||||
|
||||
// Check that the entity revision is upcasted in the correct language.
|
||||
$revision_url = 'entity_test_mulrev/' . $entity->id() . '/revision/' . $forward_revision->getRevisionId() . '/view';
|
||||
|
||||
$this->drupalGet($revision_url);
|
||||
$this->assertText('forward revision - en');
|
||||
$this->assertNoText('forward revision - de');
|
||||
|
||||
$this->drupalGet('de/' . $revision_url);
|
||||
$this->assertText('forward revision - de');
|
||||
$this->assertNoText('forward revision - en');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests EntityViewController functionality.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityViewControllerTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
/**
|
||||
* Array of test entities.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $entities = [];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create some dummy entity_test entities.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$entity_test = $this->createTestEntity('entity_test');
|
||||
$entity_test->save();
|
||||
$this->entities[] = $entity_test;
|
||||
}
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser(['view test entity']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests EntityViewController.
|
||||
*/
|
||||
public function testEntityViewController() {
|
||||
$get_label_markup = function($label) {
|
||||
return '<h1 class="page-title">
|
||||
<div class="field field--name-name field--type-string field--label-hidden field__item">' . $label . '</div>
|
||||
</h1>';
|
||||
};
|
||||
|
||||
foreach ($this->entities as $entity) {
|
||||
$this->drupalGet('entity_test/' . $entity->id());
|
||||
$this->assertRaw($entity->label());
|
||||
$this->assertRaw($get_label_markup($entity->label()));
|
||||
$this->assertRaw('full');
|
||||
|
||||
$this->drupalGet('entity_test_converter/' . $entity->id());
|
||||
$this->assertRaw($entity->label());
|
||||
$this->assertRaw('full');
|
||||
|
||||
$this->drupalGet('entity_test_no_view_mode/' . $entity->id());
|
||||
$this->assertRaw($entity->label());
|
||||
$this->assertRaw('full');
|
||||
}
|
||||
|
||||
// Test viewing a revisionable entity.
|
||||
$entity_test_rev = $this->createTestEntity('entity_test_rev');
|
||||
$entity_test_rev->save();
|
||||
$entity_test_rev->name->value = 'rev 2';
|
||||
$entity_test_rev->setNewRevision(TRUE);
|
||||
$entity_test_rev->isDefaultRevision(TRUE);
|
||||
$entity_test_rev->save();
|
||||
$this->drupalGet('entity_test_rev/' . $entity_test_rev->id() . '/revision/' . $entity_test_rev->revision_id->value . '/view');
|
||||
$this->assertRaw($entity_test_rev->label());
|
||||
$this->assertRaw($get_label_markup($entity_test_rev->label()));
|
||||
|
||||
// As entity_test IDs must be integers, make sure requests for non-integer
|
||||
// IDs return a page not found error.
|
||||
$this->drupalGet('entity_test/invalid');
|
||||
$this->assertResponse(404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field item attributes.
|
||||
*/
|
||||
public function testFieldItemAttributes() {
|
||||
// Make sure the test field will be rendered.
|
||||
entity_get_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent('field_test_text', ['type' => 'text_default'])
|
||||
->save();
|
||||
|
||||
// Create an entity and save test value in field_test_text.
|
||||
$test_value = $this->randomMachineName();
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_test_text = $test_value;
|
||||
$entity->save();
|
||||
|
||||
// Browse to the entity and verify that the attribute is rendered in the
|
||||
// field item HTML markup.
|
||||
$this->drupalGet('entity_test/' . $entity->id());
|
||||
$xpath = $this->xpath('//div[@data-field-item-attr="foobar"]/p[text()=:value]', [':value' => $test_value]);
|
||||
$this->assertTrue($xpath, 'The field item attribute has been found in the rendered output of the field.');
|
||||
|
||||
// Enable the RDF module to ensure that two modules can add attributes to
|
||||
// the same field item.
|
||||
\Drupal::service('module_installer')->install(['rdf']);
|
||||
$this->resetAll();
|
||||
|
||||
// Set an RDF mapping for the field_test_text field. This RDF mapping will
|
||||
// be turned into RDFa attributes in the field item output.
|
||||
$mapping = rdf_get_mapping('entity_test', 'entity_test');
|
||||
$mapping->setFieldMapping('field_test_text', [
|
||||
'properties' => ['schema:text'],
|
||||
])->save();
|
||||
// Browse to the entity and verify that the attributes from both modules
|
||||
// are rendered in the field item HTML markup.
|
||||
$this->drupalGet('entity_test/' . $entity->id());
|
||||
$xpath = $this->xpath('//div[@data-field-item-attr="foobar" and @property="schema:text"]/p[text()=:value]', [':value' => $test_value]);
|
||||
$this->assertTrue($xpath, 'The field item attributes from both modules have been found in the rendered output of the field.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a view builder can successfully override the view builder.
|
||||
*/
|
||||
public function testEntityViewControllerViewBuilder() {
|
||||
$entity_test = $this->createTestEntity('entity_test_view_builder');
|
||||
$entity_test->save();
|
||||
$this->drupalGet('entity_test_view_builder/' . $entity_test->id());
|
||||
$this->assertText($entity_test->label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entity for testing.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* The created entity.
|
||||
*/
|
||||
protected function createTestEntity($entity_type) {
|
||||
$data = [
|
||||
'bundle' => $entity_type,
|
||||
'name' => $this->randomMachineName(),
|
||||
];
|
||||
return $this->container->get('entity.manager')->getStorage($entity_type)->create($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\File;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests file system configuration operations.
|
||||
*
|
||||
* @group File
|
||||
*/
|
||||
class ConfigTest extends BrowserTestBase {
|
||||
|
||||
protected function setUp(){
|
||||
parent::setUp();
|
||||
$this->drupalLogin ($this->drupalCreateUser(['administer site configuration']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests file configuration page.
|
||||
*/
|
||||
public function testFileConfigurationPage() {
|
||||
$this->drupalGet('admin/config/media/file-system');
|
||||
|
||||
// Set the file paths to non-default values.
|
||||
// The respective directories are created automatically
|
||||
// upon form submission.
|
||||
$file_path = $this->publicFilesDirectory;
|
||||
$fields = [
|
||||
'file_temporary_path' => $file_path . '/file_config_page_test/temporary',
|
||||
'file_default_scheme' => 'private',
|
||||
];
|
||||
|
||||
// Check that public and private can be selected as default scheme.
|
||||
$this->assertText('Public local files served by the webserver.');
|
||||
$this->assertText('Private local files served by Drupal.');
|
||||
|
||||
$this->drupalPostForm(NULL, $fields, t('Save configuration'));
|
||||
$this->assertText(t('The configuration options have been saved.'));
|
||||
foreach ($fields as $field => $value) {
|
||||
$this->assertFieldByName($field, $value);
|
||||
}
|
||||
|
||||
// Remove the private path, rebuild the container and verify that private
|
||||
// can no longer be selected in the UI.
|
||||
$settings['settings']['file_private_path'] = (object) [
|
||||
'value' => '',
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
$this->rebuildContainer();
|
||||
|
||||
$this->drupalGet('admin/config/media/file-system');
|
||||
$this->assertText('Public local files served by the webserver.');
|
||||
$this->assertNoText('Private local files served by Drupal.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\File;
|
||||
|
||||
use Drupal\Component\PhpStorage\FileStorage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the log message added by file_save_htacess().
|
||||
*
|
||||
* @group File
|
||||
*/
|
||||
class FileSaveHtaccessLoggingTest extends BrowserTestBase {
|
||||
|
||||
protected static $modules = ['dblog'];
|
||||
|
||||
/**
|
||||
* Tests file_save_htaccess().
|
||||
*/
|
||||
public function testHtaccessSave() {
|
||||
// Prepare test directories.
|
||||
$private = $this->publicFilesDirectory . '/test/private';
|
||||
|
||||
// Verify that file_save_htaccess() returns FALSE if .htaccess cannot be
|
||||
// written and writes a correctly formatted message to the error log. Set
|
||||
// $private to TRUE so all possible .htaccess lines are written.
|
||||
$this->assertFalse(file_save_htaccess($private, TRUE));
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet('admin/reports/dblog');
|
||||
$this->clickLink("Security warning: Couldn't write .htaccess file. Please…");
|
||||
|
||||
$lines = FileStorage::htaccessLines(TRUE);
|
||||
foreach (array_filter(explode("\n", $lines)) as $line) {
|
||||
$this->assertEscaped($line);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\FileTransfer;
|
||||
|
||||
use Drupal\Core\FileTransfer\FileTransferException;
|
||||
use Drupal\Core\StreamWrapper\PublicStream;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the jail is respected and that protocols using recursive file move
|
||||
* operations work.
|
||||
*
|
||||
* @group FileTransfer
|
||||
*/
|
||||
class FileTransferTest extends BrowserTestBase {
|
||||
protected $hostname = 'localhost';
|
||||
protected $username = 'drupal';
|
||||
protected $password = 'password';
|
||||
protected $port = '42';
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->testConnection = TestFileTransfer::factory(\Drupal::root(), ['hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port]);
|
||||
}
|
||||
|
||||
public function _getFakeModuleFiles() {
|
||||
$files = [
|
||||
'fake.module',
|
||||
'fake.info.yml',
|
||||
'theme' => [
|
||||
'fake.html.twig'
|
||||
],
|
||||
'inc' => [
|
||||
'fake.inc'
|
||||
]
|
||||
];
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function _buildFakeModule() {
|
||||
$location = 'temporary://fake';
|
||||
if (is_dir($location)) {
|
||||
$ret = 0;
|
||||
$output = [];
|
||||
exec('rm -Rf ' . escapeshellarg($location), $output, $ret);
|
||||
if ($ret != 0) {
|
||||
throw new Exception('Error removing fake module directory.');
|
||||
}
|
||||
}
|
||||
|
||||
$files = $this->_getFakeModuleFiles();
|
||||
$this->_writeDirectory($location, $files);
|
||||
return $location;
|
||||
}
|
||||
|
||||
public function _writeDirectory($base, $files = []) {
|
||||
mkdir($base);
|
||||
foreach ($files as $key => $file) {
|
||||
if (is_array($file)) {
|
||||
$this->_writeDirectory($base . DIRECTORY_SEPARATOR . $key, $file);
|
||||
}
|
||||
else {
|
||||
//just write the filename into the file
|
||||
file_put_contents($base . DIRECTORY_SEPARATOR . $file, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testJail() {
|
||||
$source = $this->_buildFakeModule();
|
||||
|
||||
// This convoluted piece of code is here because our testing framework does
|
||||
// not support expecting exceptions.
|
||||
$gotit = FALSE;
|
||||
try {
|
||||
$this->testConnection->copyDirectory($source, sys_get_temp_dir());
|
||||
}
|
||||
catch (FileTransferException $e) {
|
||||
$gotit = TRUE;
|
||||
}
|
||||
$this->assertTrue($gotit, 'Was not able to copy a directory outside of the jailed area.');
|
||||
|
||||
$gotit = TRUE;
|
||||
try {
|
||||
$this->testConnection->copyDirectory($source, \Drupal::root() . '/' . PublicStream::basePath());
|
||||
}
|
||||
catch (FileTransferException $e) {
|
||||
$gotit = FALSE;
|
||||
}
|
||||
$this->assertTrue($gotit, 'Was able to copy a directory inside of the jailed area');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\FileTransfer;
|
||||
|
||||
/**
|
||||
* Mock connection object for test case.
|
||||
*/
|
||||
class MockTestConnection {
|
||||
|
||||
protected $commandsRun = [];
|
||||
public $connectionString;
|
||||
|
||||
public function run($cmd) {
|
||||
$this->commandsRun[] = $cmd;
|
||||
}
|
||||
|
||||
public function flushCommands() {
|
||||
$out = $this->commandsRun;
|
||||
$this->commandsRun = [];
|
||||
return $out;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\FileTransfer;
|
||||
|
||||
use Drupal\Core\FileTransfer\FileTransfer;
|
||||
use Drupal\Core\FileTransfer\FileTransferException;
|
||||
|
||||
/**
|
||||
* Mock FileTransfer object for test case.
|
||||
*/
|
||||
class TestFileTransfer extends FileTransfer {
|
||||
protected $host = NULL;
|
||||
protected $username = NULL;
|
||||
protected $password = NULL;
|
||||
protected $port = NULL;
|
||||
|
||||
/**
|
||||
* This is for testing the CopyRecursive logic.
|
||||
*/
|
||||
public $shouldIsDirectoryReturnTrue = FALSE;
|
||||
|
||||
public function __construct($jail, $username, $password, $hostname = 'localhost', $port = 9999) {
|
||||
parent::__construct($jail, $username, $password, $hostname, $port);
|
||||
}
|
||||
|
||||
public static function factory($jail, $settings) {
|
||||
return new TestFileTransfer($jail, $settings['username'], $settings['password'], $settings['hostname'], $settings['port']);
|
||||
}
|
||||
|
||||
public function connect() {
|
||||
$this->connection = new MockTestConnection();
|
||||
$this->connection->connectionString = 'test://' . urlencode($this->username) . ':' . urlencode($this->password) . "@$this->host:$this->port/";
|
||||
}
|
||||
|
||||
public function copyFileJailed($source, $destination) {
|
||||
$this->connection->run("copyFile $source $destination");
|
||||
}
|
||||
|
||||
protected function removeDirectoryJailed($directory) {
|
||||
$this->connection->run("rmdir $directory");
|
||||
}
|
||||
|
||||
public function createDirectoryJailed($directory) {
|
||||
$this->connection->run("mkdir $directory");
|
||||
}
|
||||
|
||||
public function removeFileJailed($destination) {
|
||||
if (!ftp_delete($this->connection, $item)) {
|
||||
throw new FileTransferException('Unable to remove to file @file.', NULL, ['@file' => $item]);
|
||||
}
|
||||
}
|
||||
|
||||
public function isDirectory($path) {
|
||||
return $this->shouldIsDirectoryReturnTrue;
|
||||
}
|
||||
|
||||
public function isFile($path) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function chmodJailed($path, $mode, $recursive) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Form;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests access control for form elements.
|
||||
*
|
||||
* @group Form
|
||||
*/
|
||||
class ElementsAccessTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['form_test'];
|
||||
|
||||
/**
|
||||
* Ensures that child values are still processed when #access = FALSE.
|
||||
*/
|
||||
public function testAccessFalse() {
|
||||
$this->drupalPostForm('form_test/vertical-tabs-access', NULL, t('Submit'));
|
||||
$this->assertNoText(t('This checkbox inside a vertical tab does not have its default value.'));
|
||||
$this->assertNoText(t('This textfield inside a vertical tab does not have its default value.'));
|
||||
$this->assertNoText(t('This checkbox inside a fieldset does not have its default value.'));
|
||||
$this->assertNoText(t('This checkbox inside a container does not have its default value.'));
|
||||
$this->assertNoText(t('This checkbox inside a nested container does not have its default value.'));
|
||||
$this->assertNoText(t('This checkbox inside a vertical tab whose fieldset access is allowed does not have its default value.'));
|
||||
$this->assertText(t('The form submitted correctly.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Form;
|
||||
|
||||
use Drupal\system\Tests\System\SystemConfigFormTestBase;
|
||||
use Drupal\form_test\FormTestObject;
|
||||
|
||||
/**
|
||||
* Tests building a form from an object.
|
||||
*
|
||||
* @group Form
|
||||
*/
|
||||
class FormObjectTest extends SystemConfigFormTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['form_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->form = new FormTestObject($this->container->get('config.factory'));
|
||||
$this->values = [
|
||||
'bananas' => [
|
||||
'#value' => $this->randomString(10),
|
||||
'#config_name' => 'form_test.object',
|
||||
'#config_key' => 'bananas',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using an object as the form callback.
|
||||
*
|
||||
* @see \Drupal\form_test\EventSubscriber\FormTestEventSubscriber::onKernelRequest()
|
||||
*/
|
||||
public function testObjectFormCallback() {
|
||||
$config_factory = $this->container->get('config.factory');
|
||||
|
||||
$this->drupalGet('form-test/object-builder');
|
||||
$this->assertText('The FormTestObject::buildForm() method was used for this form.');
|
||||
$elements = $this->xpath('//form[@id="form-test-form-test-object"]');
|
||||
$this->assertTrue(!empty($elements), 'The correct form ID was used.');
|
||||
$this->drupalPostForm(NULL, ['bananas' => 'green'], t('Save'));
|
||||
$this->assertText('The FormTestObject::validateForm() method was used for this form.');
|
||||
$this->assertText('The FormTestObject::submitForm() method was used for this form.');
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertIdentical('green', $value);
|
||||
|
||||
$this->drupalGet('form-test/object-arguments-builder/yellow');
|
||||
$this->assertText('The FormTestArgumentsObject::buildForm() method was used for this form.');
|
||||
$elements = $this->xpath('//form[@id="form-test-form-test-arguments-object"]');
|
||||
$this->assertTrue(!empty($elements), 'The correct form ID was used.');
|
||||
$this->drupalPostForm(NULL, NULL, t('Save'));
|
||||
$this->assertText('The FormTestArgumentsObject::validateForm() method was used for this form.');
|
||||
$this->assertText('The FormTestArgumentsObject::submitForm() method was used for this form.');
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertIdentical('yellow', $value);
|
||||
|
||||
$this->drupalGet('form-test/object-service-builder');
|
||||
$this->assertText('The FormTestServiceObject::buildForm() method was used for this form.');
|
||||
$elements = $this->xpath('//form[@id="form-test-form-test-service-object"]');
|
||||
$this->assertTrue(!empty($elements), 'The correct form ID was used.');
|
||||
$this->drupalPostForm(NULL, ['bananas' => 'brown'], t('Save'));
|
||||
$this->assertText('The FormTestServiceObject::validateForm() method was used for this form.');
|
||||
$this->assertText('The FormTestServiceObject::submitForm() method was used for this form.');
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertIdentical('brown', $value);
|
||||
|
||||
$this->drupalGet('form-test/object-controller-builder');
|
||||
$this->assertText('The FormTestControllerObject::create() method was used for this form.');
|
||||
$this->assertText('The FormTestControllerObject::buildForm() method was used for this form.');
|
||||
$elements = $this->xpath('//form[@id="form-test-form-test-controller-object"]');
|
||||
$this->assertTrue(!empty($elements), 'The correct form ID was used.');
|
||||
$this->assertText('custom_value', 'Ensure parameters are injected from request attributes.');
|
||||
$this->assertText('request_value', 'Ensure the request object is injected.');
|
||||
$this->drupalPostForm(NULL, ['bananas' => 'black'], t('Save'));
|
||||
$this->assertText('The FormTestControllerObject::validateForm() method was used for this form.');
|
||||
$this->assertText('The FormTestControllerObject::submitForm() method was used for this form.');
|
||||
$value = $config_factory->get('form_test.object')->get('bananas');
|
||||
$this->assertIdentical('black', $value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Form;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests \Drupal\system\Form\ModulesListForm.
|
||||
*
|
||||
* @group Form
|
||||
*/
|
||||
class ModulesListFormWebTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system_test', 'help'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::state()->set('system_test.module_hidden', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the module list form.
|
||||
*/
|
||||
public function testModuleListForm() {
|
||||
$this->drupalLogin(
|
||||
$this->drupalCreateUser(
|
||||
['administer modules', 'administer permissions']
|
||||
)
|
||||
);
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertResponse('200');
|
||||
|
||||
// Check that system_test's configure link was rendered correctly.
|
||||
$this->assertFieldByXPath("//a[contains(@href, '/system-test/configure/bar') and text()='Configure ']/span[contains(@class, 'visually-hidden') and text()='the System test module']");
|
||||
|
||||
// Check that system_test's permissions link was rendered correctly.
|
||||
$this->assertFieldByXPath("//a[contains(@href, '/admin/people/permissions#module-system_test') and @title='Configure permissions']");
|
||||
|
||||
// Check that system_test's help link was rendered correctly.
|
||||
$this->assertFieldByXPath("//a[contains(@href, '/admin/help/system_test') and @title='Help']");
|
||||
|
||||
// Ensure that the Testing module's machine name is printed. Testing module
|
||||
// is used because its machine name is different than its human readable
|
||||
// name.
|
||||
$this->assertText('simpletest');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Form;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests form redirection functionality.
|
||||
*
|
||||
* @group Form
|
||||
*/
|
||||
class RedirectTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['form_test', 'block'];
|
||||
|
||||
/**
|
||||
* Tests form redirection.
|
||||
*/
|
||||
public function testRedirect() {
|
||||
$path = 'form-test/redirect';
|
||||
$options = ['query' => ['foo' => 'bar']];
|
||||
$options['absolute'] = TRUE;
|
||||
|
||||
// Test basic redirection.
|
||||
$edit = [
|
||||
'redirection' => TRUE,
|
||||
'destination' => $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Submit'));
|
||||
$this->assertUrl($edit['destination'], [], 'Basic redirection works.');
|
||||
|
||||
|
||||
// Test without redirection.
|
||||
$edit = [
|
||||
'redirection' => FALSE,
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Submit'));
|
||||
$this->assertUrl($path, [], 'When redirect is set to FALSE, there should be no redirection.');
|
||||
|
||||
// Test redirection with query parameters.
|
||||
$edit = [
|
||||
'redirection' => TRUE,
|
||||
'destination' => $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Submit'), $options);
|
||||
$this->assertUrl($edit['destination'], [], 'Redirection with query parameters works.');
|
||||
|
||||
// Test without redirection but with query parameters.
|
||||
$edit = [
|
||||
'redirection' => FALSE,
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Submit'), $options);
|
||||
$this->assertUrl($path, $options, 'When redirect is set to FALSE, there should be no redirection, and the query parameters should be passed along.');
|
||||
|
||||
// Test redirection back to the original path.
|
||||
$edit = [
|
||||
'redirection' => TRUE,
|
||||
'destination' => '',
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Submit'));
|
||||
$this->assertUrl($path, [], 'When using an empty redirection string, there should be no redirection.');
|
||||
|
||||
// Test redirection back to the original path with query parameters.
|
||||
$edit = [
|
||||
'redirection' => TRUE,
|
||||
'destination' => '',
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Submit'), $options);
|
||||
$this->assertUrl($path, $options, 'When using an empty redirection string, there should be no redirection, and the query parameters should be passed along.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests form redirection from 404/403 pages with the Block form.
|
||||
*/
|
||||
public function testRedirectFromErrorPages() {
|
||||
// Make sure the block containing the redirect form is placed.
|
||||
$this->drupalPlaceBlock('redirect_form_block');
|
||||
|
||||
// Create a user that does not have permission to administer blocks.
|
||||
$user = $this->drupalCreateUser(['administer themes']);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
// Visit page 'foo' (404 page) and submit the form. Verify it ends up
|
||||
// at the right URL.
|
||||
$expected = \Drupal::url('form_test.route1', [], ['query' => ['test1' => 'test2'], 'absolute' => TRUE]);
|
||||
$this->drupalGet('foo');
|
||||
$this->assertResponse(404);
|
||||
$this->drupalPostForm(NULL, [], t('Submit'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertUrl($expected, [], 'Redirected to correct URL/query.');
|
||||
|
||||
// Visit the block admin page (403 page) and submit the form. Verify it
|
||||
// ends up at the right URL.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->assertResponse(403);
|
||||
$this->drupalPostForm(NULL, [], t('Submit'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertUrl($expected, [], 'Redirected to correct URL/query.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Lock;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Confirm locking works between two separate requests.
|
||||
*
|
||||
* @group Lock
|
||||
*/
|
||||
class LockFunctionalTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system_test'];
|
||||
|
||||
/**
|
||||
* Confirms that we can acquire and release locks in two parallel requests.
|
||||
*/
|
||||
public function testLockAcquire() {
|
||||
$lock = $this->container->get('lock');
|
||||
$lock_acquired = 'TRUE: Lock successfully acquired in \Drupal\system_test\Controller\SystemTestController::lockAcquire()';
|
||||
$lock_not_acquired = 'FALSE: Lock not acquired in \Drupal\system_test\Controller\SystemTestController::lockAcquire()';
|
||||
$this->assertTrue($lock->acquire('system_test_lock_acquire'), 'Lock acquired by this request.', 'Lock');
|
||||
$this->assertTrue($lock->acquire('system_test_lock_acquire'), 'Lock extended by this request.', 'Lock');
|
||||
$lock->release('system_test_lock_acquire');
|
||||
|
||||
// Cause another request to acquire the lock.
|
||||
$this->drupalGet('system-test/lock-acquire');
|
||||
$this->assertText($lock_acquired, 'Lock acquired by the other request.', 'Lock');
|
||||
// The other request has finished, thus it should have released its lock.
|
||||
$this->assertTrue($lock->acquire('system_test_lock_acquire'), 'Lock acquired by this request.', 'Lock');
|
||||
// This request holds the lock, so the other request cannot acquire it.
|
||||
$this->drupalGet('system-test/lock-acquire');
|
||||
$this->assertText($lock_not_acquired, 'Lock not acquired by the other request.', 'Lock');
|
||||
$lock->release('system_test_lock_acquire');
|
||||
|
||||
// Try a very short timeout and lock breaking.
|
||||
$this->assertTrue($lock->acquire('system_test_lock_acquire', 0.5), 'Lock acquired by this request.', 'Lock');
|
||||
sleep(1);
|
||||
// The other request should break our lock.
|
||||
$this->drupalGet('system-test/lock-acquire');
|
||||
$this->assertText($lock_acquired, 'Lock acquired by the other request, breaking our lock.', 'Lock');
|
||||
// We cannot renew it, since the other thread took it.
|
||||
$this->assertFalse($lock->acquire('system_test_lock_acquire'), 'Lock cannot be extended by this request.', 'Lock');
|
||||
|
||||
// Check the shut-down function.
|
||||
$lock_acquired_exit = 'TRUE: Lock successfully acquired in \Drupal\system_test\Controller\SystemTestController::lockExit()';
|
||||
$this->drupalGet('system-test/lock-exit');
|
||||
$this->assertText($lock_acquired_exit, 'Lock acquired by the other request before exit.', 'Lock');
|
||||
$this->assertTrue($lock->acquire('system_test_lock_exit'), 'Lock acquired by this request after the other request exits.', 'Lock');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the persistent lock is persisted between requests.
|
||||
*/
|
||||
public function testPersistentLock() {
|
||||
$persistent_lock = $this->container->get('lock.persistent');
|
||||
// Get a persistent lock.
|
||||
$this->drupalGet('system-test/lock-persist/lock1');
|
||||
$this->assertText('TRUE: Lock successfully acquired in SystemTestController::lockPersist()');
|
||||
// Ensure that a shutdown function has not released the lock.
|
||||
$this->assertFalse($persistent_lock->lockMayBeAvailable('lock1'));
|
||||
$this->drupalGet('system-test/lock-persist/lock1');
|
||||
$this->assertText('FALSE: Lock not acquired in SystemTestController::lockPersist()');
|
||||
|
||||
// Get another persistent lock.
|
||||
$this->drupalGet('system-test/lock-persist/lock2');
|
||||
$this->assertText('TRUE: Lock successfully acquired in SystemTestController::lockPersist()');
|
||||
$this->assertFalse($persistent_lock->lockMayBeAvailable('lock2'));
|
||||
|
||||
// Release the first lock and try getting it again.
|
||||
$persistent_lock->release('lock1');
|
||||
$this->drupalGet('system-test/lock-persist/lock1');
|
||||
$this->assertText('TRUE: Lock successfully acquired in SystemTestController::lockPersist()');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Mail;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Mail\MailFormatHelper;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests for \Drupal\Core\Mail\MailFormatHelper::htmlToText().
|
||||
*
|
||||
* @group Mail
|
||||
*/
|
||||
class HtmlToTextTest extends BrowserTestBase {
|
||||
/**
|
||||
* Converts a string to its PHP source equivalent for display in test messages.
|
||||
*
|
||||
* @param $text
|
||||
* The text string to convert.
|
||||
*
|
||||
* @return
|
||||
* An HTML representation of the text string that, when displayed in a
|
||||
* browser, represents the PHP source code equivalent of $text.
|
||||
*/
|
||||
protected function stringToHtml($text) {
|
||||
return '"' .
|
||||
str_replace(
|
||||
["\n", ' '],
|
||||
['\n', ' '],
|
||||
Html::escape($text)
|
||||
) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to test \Drupal\Core\Mail\MailFormatHelper::htmlToText().
|
||||
*
|
||||
* @param $html
|
||||
* The source HTML string to be converted.
|
||||
* @param $text
|
||||
* The expected result of converting $html to text.
|
||||
* @param $message
|
||||
* A text message to display in the assertion message.
|
||||
* @param $allowed_tags
|
||||
* (optional) An array of allowed tags, or NULL to default to the full
|
||||
* set of tags supported by
|
||||
* \Drupal\Core\Mail\MailFormatHelper::htmlToText().
|
||||
*/
|
||||
protected function assertHtmlToText($html, $text, $message, $allowed_tags = NULL) {
|
||||
preg_match_all('/<([a-z0-6]+)/', Unicode::strtolower($html), $matches);
|
||||
$tested_tags = implode(', ', array_unique($matches[1]));
|
||||
$message .= ' (' . $tested_tags . ')';
|
||||
$result = MailFormatHelper::htmlToText($html, $allowed_tags);
|
||||
$pass = $this->assertEqual($result, $text, Html::escape($message));
|
||||
$verbose = 'html = <pre>' . $this->stringToHtml($html)
|
||||
. '</pre><br />' . 'result = <pre>' . $this->stringToHtml($result)
|
||||
. '</pre><br />' . 'expected = <pre>' . $this->stringToHtml($text)
|
||||
. '</pre>';
|
||||
$this->verbose($verbose);
|
||||
if (!$pass) {
|
||||
$this->pass("Previous test verbose info:<br />$verbose");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test supported tags of \Drupal\Core\Mail\MailFormatHelper::htmlToText().
|
||||
*/
|
||||
public function testTags() {
|
||||
global $base_path, $base_url;
|
||||
$tests = [
|
||||
// @todo Trailing linefeeds should be trimmed.
|
||||
'<a href = "https://www.drupal.org">Drupal.org</a>' => "Drupal.org [1]\n\n[1] https://www.drupal.org\n",
|
||||
// @todo Footer URLs should be absolute.
|
||||
"<a href = \"$base_path\">Homepage</a>" => "Homepage [1]\n\n[1] $base_url/\n",
|
||||
'<address>Drupal</address>' => "Drupal\n",
|
||||
// @todo The <address> tag is currently not supported.
|
||||
'<address>Drupal</address><address>Drupal</address>' => "DrupalDrupal\n",
|
||||
'<b>Drupal</b>' => "*Drupal*\n",
|
||||
// @todo There should be a space between the '>' and the text.
|
||||
'<blockquote>Drupal</blockquote>' => ">Drupal\n",
|
||||
'<blockquote>Drupal</blockquote><blockquote>Drupal</blockquote>' => ">Drupal\n>Drupal\n",
|
||||
'<br />Drupal<br />Drupal<br /><br />Drupal' => "Drupal\nDrupal\nDrupal\n",
|
||||
'<br/>Drupal<br/>Drupal<br/><br/>Drupal' => "Drupal\nDrupal\nDrupal\n",
|
||||
// @todo There should be two line breaks before the paragraph.
|
||||
'<br/>Drupal<br/>Drupal<br/><br/>Drupal<p>Drupal</p>' => "Drupal\nDrupal\nDrupal\nDrupal\n\n",
|
||||
'<div>Drupal</div>' => "Drupal\n",
|
||||
// @todo The <div> tag is currently not supported.
|
||||
'<div>Drupal</div><div>Drupal</div>' => "DrupalDrupal\n",
|
||||
'<em>Drupal</em>' => "/Drupal/\n",
|
||||
'<h1>Drupal</h1>' => "======== DRUPAL ==============================================================\n\n",
|
||||
'<h1>Drupal</h1><p>Drupal</p>' => "======== DRUPAL ==============================================================\n\nDrupal\n\n",
|
||||
'<h2>Drupal</h2>' => "-------- DRUPAL --------------------------------------------------------------\n\n",
|
||||
'<h2>Drupal</h2><p>Drupal</p>' => "-------- DRUPAL --------------------------------------------------------------\n\nDrupal\n\n",
|
||||
'<h3>Drupal</h3>' => ".... Drupal\n\n",
|
||||
'<h3>Drupal</h3><p>Drupal</p>' => ".... Drupal\n\nDrupal\n\n",
|
||||
'<h4>Drupal</h4>' => ".. Drupal\n\n",
|
||||
'<h4>Drupal</h4><p>Drupal</p>' => ".. Drupal\n\nDrupal\n\n",
|
||||
'<h5>Drupal</h5>' => "Drupal\n\n",
|
||||
'<h5>Drupal</h5><p>Drupal</p>' => "Drupal\n\nDrupal\n\n",
|
||||
'<h6>Drupal</h6>' => "Drupal\n\n",
|
||||
'<h6>Drupal</h6><p>Drupal</p>' => "Drupal\n\nDrupal\n\n",
|
||||
'<hr />Drupal<hr />' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\n",
|
||||
'<hr/>Drupal<hr/>' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\n",
|
||||
'<hr/>Drupal<hr/><p>Drupal</p>' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\nDrupal\n\n",
|
||||
'<i>Drupal</i>' => "/Drupal/\n",
|
||||
'<p>Drupal</p>' => "Drupal\n\n",
|
||||
'<p>Drupal</p><p>Drupal</p>' => "Drupal\n\nDrupal\n\n",
|
||||
'<strong>Drupal</strong>' => "*Drupal*\n",
|
||||
// @todo Tables are currently not supported.
|
||||
'<table><tr><td>Drupal</td><td>Drupal</td></tr><tr><td>Drupal</td><td>Drupal</td></tr></table>' => "DrupalDrupalDrupalDrupal\n",
|
||||
'<table><tr><td>Drupal</td></tr></table><p>Drupal</p>' => "Drupal\nDrupal\n\n",
|
||||
// @todo The <u> tag is currently not supported.
|
||||
'<u>Drupal</u>' => "Drupal\n",
|
||||
'<ul><li>Drupal</li></ul>' => " * Drupal\n\n",
|
||||
'<ul><li>Drupal <em>Drupal</em> Drupal</li></ul>' => " * Drupal /Drupal/ Drupal\n\n",
|
||||
// @todo Lines containing nothing but spaces should be trimmed.
|
||||
'<ul><li>Drupal</li><li><ol><li>Drupal</li><li>Drupal</li></ol></li></ul>' => " * Drupal\n * 1) Drupal\n 2) Drupal\n \n\n",
|
||||
'<ul><li>Drupal</li><li><ol><li>Drupal</li></ol></li><li>Drupal</li></ul>' => " * Drupal\n * 1) Drupal\n \n * Drupal\n\n",
|
||||
'<ul><li>Drupal</li><li>Drupal</li></ul>' => " * Drupal\n * Drupal\n\n",
|
||||
'<ul><li>Drupal</li></ul><p>Drupal</p>' => " * Drupal\n\nDrupal\n\n",
|
||||
'<ol><li>Drupal</li></ol>' => " 1) Drupal\n\n",
|
||||
'<ol><li>Drupal</li><li><ul><li>Drupal</li><li>Drupal</li></ul></li></ol>' => " 1) Drupal\n 2) * Drupal\n * Drupal\n \n\n",
|
||||
'<ol><li>Drupal</li><li>Drupal</li></ol>' => " 1) Drupal\n 2) Drupal\n\n",
|
||||
'<ol>Drupal</ol>' => "Drupal\n\n",
|
||||
'<ol><li>Drupal</li></ol><p>Drupal</p>' => " 1) Drupal\n\nDrupal\n\n",
|
||||
'<dl><dt>Drupal</dt></dl>' => "Drupal\n\n",
|
||||
'<dl><dt>Drupal</dt><dd>Drupal</dd></dl>' => "Drupal\n Drupal\n\n",
|
||||
'<dl><dt>Drupal</dt><dd>Drupal</dd><dt>Drupal</dt><dd>Drupal</dd></dl>' => "Drupal\n Drupal\nDrupal\n Drupal\n\n",
|
||||
'<dl><dt>Drupal</dt><dd>Drupal</dd></dl><p>Drupal</p>' => "Drupal\n Drupal\n\nDrupal\n\n",
|
||||
'<dl><dt>Drupal<dd>Drupal</dl>' => "Drupal\n Drupal\n\n",
|
||||
'<dl><dt>Drupal</dt></dl><p>Drupal</p>' => "Drupal\n\nDrupal\n\n",
|
||||
// @todo Again, lines containing only spaces should be trimmed.
|
||||
'<ul><li>Drupal</li><li><dl><dt>Drupal</dt><dd>Drupal</dd><dt>Drupal</dt><dd>Drupal</dd></dl></li><li>Drupal</li></ul>' => " * Drupal\n * Drupal\n Drupal\n Drupal\n Drupal\n \n * Drupal\n\n",
|
||||
// Tests malformed HTML tags.
|
||||
'<br>Drupal<br>Drupal' => "Drupal\nDrupal\n",
|
||||
'<hr>Drupal<hr>Drupal' => "------------------------------------------------------------------------------\nDrupal\n------------------------------------------------------------------------------\nDrupal\n",
|
||||
'<ol><li>Drupal<li>Drupal</ol>' => " 1) Drupal\n 2) Drupal\n\n",
|
||||
'<ul><li>Drupal <em>Drupal</em> Drupal</ul></ul>' => " * Drupal /Drupal/ Drupal\n\n",
|
||||
'<ul><li>Drupal<li>Drupal</ol>' => " * Drupal\n * Drupal\n\n",
|
||||
'<ul><li>Drupal<li>Drupal</ul>' => " * Drupal\n * Drupal\n\n",
|
||||
'<ul>Drupal</ul>' => "Drupal\n\n",
|
||||
'Drupal</ul></ol></dl><li>Drupal' => "Drupal\n * Drupal\n",
|
||||
'<dl>Drupal</dl>' => "Drupal\n\n",
|
||||
'<dl>Drupal</dl><p>Drupal</p>' => "Drupal\n\nDrupal\n\n",
|
||||
'<dt>Drupal</dt>' => "Drupal\n",
|
||||
// Tests some unsupported HTML tags.
|
||||
'<html>Drupal</html>' => "Drupal\n",
|
||||
// @todo Perhaps the contents of <script> tags should be dropped.
|
||||
'<script type="text/javascript">Drupal</script>' => "Drupal\n",
|
||||
// A couple of tests for Unicode characters.
|
||||
'<q>I <em>will</em> be back…</q>' => "I /will/ be back…\n",
|
||||
'FrançAIS is ÜBER-åwesome' => "FrançAIS is ÜBER-åwesome\n",
|
||||
];
|
||||
|
||||
foreach ($tests as $html => $text) {
|
||||
$this->assertHtmlToText($html, $text, 'Supported tags');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests allowing tags in \Drupal\Core\Mail\MailFormatHelper::htmlToText().
|
||||
*/
|
||||
public function testDrupalHtmlToTextArgs() {
|
||||
// The second parameter of \Drupal\Core\Mail\MailFormatHelper::htmlToText()
|
||||
// overrules the allowed tags.
|
||||
$this->assertHtmlToText(
|
||||
'Drupal <b>Drupal</b> Drupal',
|
||||
"Drupal *Drupal* Drupal\n",
|
||||
'Allowed <b> tag found',
|
||||
['b']
|
||||
);
|
||||
$this->assertHtmlToText(
|
||||
'Drupal <h1>Drupal</h1> Drupal',
|
||||
"Drupal Drupal Drupal\n",
|
||||
'Disallowed <h1> tag not found',
|
||||
['b']
|
||||
);
|
||||
|
||||
$this->assertHtmlToText(
|
||||
'Drupal <p><em><b>Drupal</b></em><p> Drupal',
|
||||
"Drupal Drupal Drupal\n",
|
||||
'Disallowed <p>, <em>, and <b> tags not found',
|
||||
['a', 'br', 'h1']
|
||||
);
|
||||
|
||||
$this->assertHtmlToText(
|
||||
'<html><body>Drupal</body></html>',
|
||||
"Drupal\n",
|
||||
'Unsupported <html> and <body> tags not found',
|
||||
['html', 'body']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that whitespace is collapsed.
|
||||
*/
|
||||
public function testDrupalHtmltoTextCollapsesWhitespace() {
|
||||
$input = "<p>Drupal Drupal\n\nDrupal<pre>Drupal Drupal\n\nDrupal</pre>Drupal Drupal\n\nDrupal</p>";
|
||||
// @todo The whitespace should be collapsed.
|
||||
$collapsed = "Drupal Drupal\n\nDrupalDrupal Drupal\n\nDrupalDrupal Drupal\n\nDrupal\n\n";
|
||||
$this->assertHtmlToText(
|
||||
$input,
|
||||
$collapsed,
|
||||
'Whitespace is collapsed',
|
||||
['p']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that text separated by block-level tags in HTML get separated by
|
||||
* (at least) a newline in the plaintext version.
|
||||
*/
|
||||
public function testDrupalHtmlToTextBlockTagToNewline() {
|
||||
$input = '[text]'
|
||||
. '<blockquote>[blockquote]</blockquote>'
|
||||
. '<br />[br]'
|
||||
. '<dl><dt>[dl-dt]</dt>'
|
||||
. '<dt>[dt]</dt>'
|
||||
. '<dd>[dd]</dd>'
|
||||
. '<dd>[dd-dl]</dd></dl>'
|
||||
. '<h1>[h1]</h1>'
|
||||
. '<h2>[h2]</h2>'
|
||||
. '<h3>[h3]</h3>'
|
||||
. '<h4>[h4]</h4>'
|
||||
. '<h5>[h5]</h5>'
|
||||
. '<h6>[h6]</h6>'
|
||||
. '<hr />[hr]'
|
||||
. '<ol><li>[ol-li]</li>'
|
||||
. '<li>[li]</li>'
|
||||
. '<li>[li-ol]</li></ol>'
|
||||
. '<p>[p]</p>'
|
||||
. '<ul><li>[ul-li]</li>'
|
||||
. '<li>[li-ul]</li></ul>'
|
||||
. '[text]';
|
||||
$output = MailFormatHelper::htmlToText($input);
|
||||
$pass = $this->assertFalse(
|
||||
preg_match('/\][^\n]*\[/s', $output),
|
||||
'Block-level HTML tags should force newlines'
|
||||
);
|
||||
if (!$pass) {
|
||||
$this->verbose($this->stringToHtml($output));
|
||||
}
|
||||
$output_upper = Unicode::strtoupper($output);
|
||||
$upper_input = Unicode::strtoupper($input);
|
||||
$upper_output = MailFormatHelper::htmlToText($upper_input);
|
||||
$pass = $this->assertEqual(
|
||||
$upper_output,
|
||||
$output_upper,
|
||||
'Tag recognition should be case-insensitive'
|
||||
);
|
||||
if (!$pass) {
|
||||
$this->verbose(
|
||||
$upper_output
|
||||
. '<br />should be equal to <br />'
|
||||
. $output_upper
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that headers are properly separated from surrounding text.
|
||||
*/
|
||||
public function testHeaderSeparation() {
|
||||
$html = 'Drupal<h1>Drupal</h1>Drupal';
|
||||
// @todo There should be more space above the header than below it.
|
||||
$text = "Drupal\n======== DRUPAL ==============================================================\n\nDrupal\n";
|
||||
$this->assertHtmlToText($html, $text,
|
||||
'Text before and after <h1> tag');
|
||||
$html = '<p>Drupal</p><h1>Drupal</h1>Drupal';
|
||||
// @todo There should be more space above the header than below it.
|
||||
$text = "Drupal\n\n======== DRUPAL ==============================================================\n\nDrupal\n";
|
||||
$this->assertHtmlToText($html, $text,
|
||||
'Paragraph before and text after <h1> tag');
|
||||
$html = 'Drupal<h1>Drupal</h1><p>Drupal</p>';
|
||||
// @todo There should be more space above the header than below it.
|
||||
$text = "Drupal\n======== DRUPAL ==============================================================\n\nDrupal\n\n";
|
||||
$this->assertHtmlToText($html, $text,
|
||||
'Text before and paragraph after <h1> tag');
|
||||
$html = '<p>Drupal</p><h1>Drupal</h1><p>Drupal</p>';
|
||||
$text = "Drupal\n\n======== DRUPAL ==============================================================\n\nDrupal\n\n";
|
||||
$this->assertHtmlToText($html, $text,
|
||||
'Paragraph before and after <h1> tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that footnote references are properly generated.
|
||||
*/
|
||||
public function testFootnoteReferences() {
|
||||
global $base_path, $base_url;
|
||||
$source = '<a href="http://www.example.com/node/1">Host and path</a>'
|
||||
. '<br /><a href="http://www.example.com">Host, no path</a>'
|
||||
. '<br /><a href="' . $base_path . 'node/1">Path, no host</a>'
|
||||
. '<br /><a href="node/1">Relative path</a>';
|
||||
// @todo Footnote URLs should be absolute.
|
||||
$tt = "Host and path [1]"
|
||||
. "\nHost, no path [2]"
|
||||
// @todo The following two references should be combined.
|
||||
. "\nPath, no host [3]"
|
||||
. "\nRelative path [4]"
|
||||
. "\n"
|
||||
. "\n[1] http://www.example.com/node/1"
|
||||
. "\n[2] http://www.example.com"
|
||||
// @todo The following two references should be combined.
|
||||
. "\n[3] $base_url/node/1"
|
||||
. "\n[4] node/1\n";
|
||||
$this->assertHtmlToText($source, $tt, 'Footnotes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that combinations of paragraph breaks, line breaks, linefeeds,
|
||||
* and spaces are properly handled.
|
||||
*/
|
||||
public function testDrupalHtmlToTextParagraphs() {
|
||||
$tests = [];
|
||||
$tests[] = [
|
||||
'html' => "<p>line 1<br />\nline 2<br />line 3\n<br />line 4</p><p>paragraph</p>",
|
||||
// @todo Trailing line breaks should be trimmed.
|
||||
'text' => "line 1\nline 2\nline 3\nline 4\n\nparagraph\n\n",
|
||||
];
|
||||
$tests[] = [
|
||||
'html' => "<p>line 1<br /> line 2</p> <p>line 4<br /> line 5</p> <p>0</p>",
|
||||
// @todo Trailing line breaks should be trimmed.
|
||||
'text' => "line 1\nline 2\n\nline 4\nline 5\n\n0\n\n",
|
||||
];
|
||||
foreach ($tests as $test) {
|
||||
$this->assertHtmlToText($test['html'], $test['text'], 'Paragraph breaks');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Mail\MailFormatHelper::htmlToText() wrapping.
|
||||
*
|
||||
* RFC 3676 says, "The Text/Plain media type is the lowest common
|
||||
* denominator of Internet email, with lines of no more than 998 characters."
|
||||
*
|
||||
* RFC 2046 says, "SMTP [RFC-821] allows a maximum of 998 octets before the
|
||||
* next CRLF sequence."
|
||||
*
|
||||
* RFC 821 says, "The maximum total length of a text line including the
|
||||
* <CRLF> is 1000 characters."
|
||||
*/
|
||||
public function testVeryLongLineWrap() {
|
||||
$input = 'Drupal<br /><p>' . str_repeat('x', 2100) . '</p><br />Drupal';
|
||||
$output = MailFormatHelper::htmlToText($input);
|
||||
$eol = Settings::get('mail_line_endings', PHP_EOL);
|
||||
|
||||
$maximum_line_length = 0;
|
||||
foreach (explode($eol, $output) as $line) {
|
||||
// We must use strlen() rather than Unicode::strlen() in order to count
|
||||
// octets rather than characters.
|
||||
$maximum_line_length = max($maximum_line_length, strlen($line . $eol));
|
||||
}
|
||||
$verbose = 'Maximum line length found was ' . $maximum_line_length . ' octets.';
|
||||
$this->assertTrue($maximum_line_length <= 1000, $verbose);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that trailing whitespace is removed before newlines.
|
||||
*
|
||||
* @see \Drupal\Core\Mail\MailFormatHelper::wrapMail()
|
||||
*/
|
||||
public function testRemoveTrailingWhitespace() {
|
||||
$text = "Hi there! \nHerp Derp";
|
||||
$mail_lines = explode("\n", MailFormatHelper::wrapMail($text));
|
||||
$this->assertNotEqual(" ", substr($mail_lines[0], -1), 'Trailing whitespace removed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that trailing whitespace from Usenet style signatures is not removed.
|
||||
*
|
||||
* RFC 3676 says, "This is a special case; an (optionally quoted or quoted and
|
||||
* stuffed) line consisting of DASH DASH SP is neither fixed nor flowed."
|
||||
*
|
||||
* @see \Drupal\Core\Mail\MailFormatHelper::wrapMail()
|
||||
*/
|
||||
public function testUsenetSignature() {
|
||||
$text = "Hi there!\n-- \nHerp Derp";
|
||||
$mail_lines = explode("\n", MailFormatHelper::wrapMail($text));
|
||||
$this->assertEqual("-- ", $mail_lines[1], 'Trailing whitespace not removed for dash-dash-space signatures.');
|
||||
|
||||
$text = "Hi there!\n-- \nHerp Derp";
|
||||
$mail_lines = explode("\n", MailFormatHelper::wrapMail($text));
|
||||
$this->assertEqual("--", $mail_lines[1], 'Trailing whitespace removed for incorrect dash-dash-space signatures.');
|
||||
}
|
||||
|
||||
}
|
||||
102
web/core/modules/system/tests/src/Functional/Mail/MailTest.php
Normal file
102
web/core/modules/system/tests/src/Functional/Mail/MailTest.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Mail;
|
||||
|
||||
use Drupal\Core\Mail\Plugin\Mail\TestMailCollector;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\system_mail_failure_test\Plugin\Mail\TestPhpMailFailure;
|
||||
|
||||
/**
|
||||
* Performs tests on the pluggable mailing framework.
|
||||
*
|
||||
* @group Mail
|
||||
*/
|
||||
class MailTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['simpletest', 'system_mail_failure_test'];
|
||||
|
||||
/**
|
||||
* Assert that the pluggable mail system is functional.
|
||||
*/
|
||||
public function testPluggableFramework() {
|
||||
// Switch mail backends.
|
||||
$this->config('system.mail')->set('interface.default', 'test_php_mail_failure')->save();
|
||||
|
||||
// Get the default MailInterface class instance.
|
||||
$mail_backend = \Drupal::service('plugin.manager.mail')->getInstance(['module' => 'default', 'key' => 'default']);
|
||||
|
||||
// Assert whether the default mail backend is an instance of the expected
|
||||
// class.
|
||||
$this->assertTrue($mail_backend instanceof TestPhpMailFailure, 'Default mail interface can be swapped.');
|
||||
|
||||
// Add a module-specific mail backend.
|
||||
$this->config('system.mail')->set('interface.mymodule_testkey', 'test_mail_collector')->save();
|
||||
|
||||
// Get the added MailInterface class instance.
|
||||
$mail_backend = \Drupal::service('plugin.manager.mail')->getInstance(['module' => 'mymodule', 'key' => 'testkey']);
|
||||
|
||||
// Assert whether the added mail backend is an instance of the expected
|
||||
// class.
|
||||
$this->assertTrue($mail_backend instanceof TestMailCollector, 'Additional mail interfaces can be added.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that message sending may be canceled.
|
||||
*
|
||||
* @see simpletest_mail_alter()
|
||||
*/
|
||||
public function testCancelMessage() {
|
||||
$language_interface = \Drupal::languageManager()->getCurrentLanguage();
|
||||
|
||||
// Use the state system collector mail backend.
|
||||
$this->config('system.mail')->set('interface.default', 'test_mail_collector')->save();
|
||||
// Reset the state variable that holds sent messages.
|
||||
\Drupal::state()->set('system.test_mail_collector', []);
|
||||
|
||||
// Send a test message that simpletest_mail_alter should cancel.
|
||||
\Drupal::service('plugin.manager.mail')->mail('simpletest', 'cancel_test', 'cancel@example.com', $language_interface->getId());
|
||||
// Retrieve sent message.
|
||||
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
|
||||
$sent_message = end($captured_emails);
|
||||
|
||||
// Assert that the message was not actually sent.
|
||||
$this->assertFalse($sent_message, 'Message was canceled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the From: and Reply-to: headers.
|
||||
*/
|
||||
public function testFromAndReplyToHeader() {
|
||||
$language = \Drupal::languageManager()->getCurrentLanguage();
|
||||
|
||||
// Use the state system collector mail backend.
|
||||
$this->config('system.mail')->set('interface.default', 'test_mail_collector')->save();
|
||||
// Reset the state variable that holds sent messages.
|
||||
\Drupal::state()->set('system.test_mail_collector', []);
|
||||
// Send an email with a reply-to address specified.
|
||||
$from_email = 'Drupal <simpletest@example.com>';
|
||||
$reply_email = 'someone_else@example.com';
|
||||
\Drupal::service('plugin.manager.mail')->mail('simpletest', 'from_test', 'from_test@example.com', $language, [], $reply_email);
|
||||
// Test that the reply-to email is just the email and not the site name
|
||||
// and default sender email.
|
||||
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
|
||||
$sent_message = end($captured_emails);
|
||||
$this->assertEqual($from_email, $sent_message['headers']['From'], 'Message is sent from the site email account.');
|
||||
$this->assertEqual($reply_email, $sent_message['headers']['Reply-to'], 'Message reply-to headers are set.');
|
||||
$this->assertFalse(isset($sent_message['headers']['Errors-To']), 'Errors-to header must not be set, it is deprecated.');
|
||||
|
||||
// Send an email and check that the From-header contains the site name.
|
||||
\Drupal::service('plugin.manager.mail')->mail('simpletest', 'from_test', 'from_test@example.com', $language);
|
||||
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
|
||||
$sent_message = end($captured_emails);
|
||||
$this->assertEqual($from_email, $sent_message['headers']['From'], 'Message is sent from the site email account.');
|
||||
$this->assertFalse(isset($sent_message['headers']['Reply-to']), 'Message reply-to is not set if not specified.');
|
||||
$this->assertFalse(isset($sent_message['headers']['Errors-To']), 'Errors-to header must not be set, it is deprecated.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Menu;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the route access checks on menu links.
|
||||
*
|
||||
* @group Menu
|
||||
*/
|
||||
class MenuAccessTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'menu_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests menu link for route with access check.
|
||||
*
|
||||
* @see \Drupal\menu_test\Access\AccessCheck::access()
|
||||
*/
|
||||
public function testMenuBlockLinksAccessCheck() {
|
||||
$this->drupalPlaceBlock('system_menu_block:account');
|
||||
// Test that there's link rendered on the route.
|
||||
$this->drupalGet('menu_test_access_check_session');
|
||||
$this->assertLink('Test custom route access check');
|
||||
// Page still accessible but thre should not be menu link.
|
||||
$this->drupalGet('menu_test_access_check_session');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoLink('Test custom route access check');
|
||||
// Test that page is no more accessible.
|
||||
$this->drupalGet('menu_test_access_check_session');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Check for access to a restricted local task from a default local task.
|
||||
$this->drupalGet('foo/asdf');
|
||||
$this->assertResponse(200);
|
||||
$this->assertLinkByHref('foo/asdf');
|
||||
$this->assertLinkByHref('foo/asdf/b');
|
||||
$this->assertNoLinkByHref('foo/asdf/c');
|
||||
|
||||
// Attempt to access a restricted local task.
|
||||
$this->drupalGet('foo/asdf/c');
|
||||
$this->assertResponse(403);
|
||||
$elements = $this->xpath('//ul[@class=:class]/li/a[@href=:href]', [
|
||||
':class' => 'tabs primary',
|
||||
':href' => Url::fromRoute('menu_test.router_test1', ['bar' => 'asdf'])->toString(),
|
||||
]);
|
||||
$this->assertTrue(empty($elements), 'No tab linking to foo/asdf found');
|
||||
$this->assertNoLinkByHref('foo/asdf/b');
|
||||
$this->assertNoLinkByHref('foo/asdf/c');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Menu;
|
||||
|
||||
use Drupal\menu_link_content\Entity\MenuLinkContent;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Ensures that menu links don't cause XSS issues.
|
||||
*
|
||||
* @group Menu
|
||||
*/
|
||||
class MenuLinkSecurityTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['menu_link_content', 'block', 'menu_test'];
|
||||
|
||||
/**
|
||||
* Ensures that a menu link does not cause an XSS issue.
|
||||
*/
|
||||
public function testMenuLink() {
|
||||
$menu_link_content = MenuLinkContent::create([
|
||||
'title' => '<script>alert("Wild animals")</script>',
|
||||
'menu_name' => 'tools',
|
||||
'link' => ['uri' => 'route:<front>'],
|
||||
]);
|
||||
$menu_link_content->save();
|
||||
|
||||
$this->drupalPlaceBlock('system_menu_block:tools');
|
||||
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertNoRaw('<script>alert("Wild animals")</script>');
|
||||
$this->assertNoRaw('<script>alert("Even more wild animals")</script>');
|
||||
$this->assertEscaped('<script>alert("Wild animals")</script>');
|
||||
$this->assertEscaped('<script>alert("Even more wild animals")</script>');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Module;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests class loading for modules.
|
||||
*
|
||||
* @group Module
|
||||
*/
|
||||
class ClassLoaderTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* The expected result from calling the module-provided class' method.
|
||||
*/
|
||||
protected $expected = 'Drupal\\module_autoload_test\\SomeClass::testMethod() was invoked.';
|
||||
|
||||
/**
|
||||
* Tests that module-provided classes can be loaded when a module is enabled.
|
||||
*
|
||||
* @see \Drupal\module_autoload_test\SomeClass
|
||||
*/
|
||||
public function testClassLoading() {
|
||||
// Enable the module_test and module_autoload_test modules.
|
||||
\Drupal::service('module_installer')->install(['module_test', 'module_autoload_test'], FALSE);
|
||||
$this->resetAll();
|
||||
// Check twice to test an unprimed and primed system_list() cache.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$this->drupalGet('module-test/class-loading');
|
||||
$this->assertResponse(200);
|
||||
$this->assertText($this->expected, 'Autoloader loads classes from an enabled module.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that module-provided classes can't be loaded if module not installed.
|
||||
*
|
||||
* @see \Drupal\module_autoload_test\SomeClass
|
||||
*/
|
||||
public function testClassLoadingNotInstalledModules() {
|
||||
// Enable the module_test module.
|
||||
\Drupal::service('module_installer')->install(['module_test'], FALSE);
|
||||
$this->resetAll();
|
||||
// Check twice to test an unprimed and primed system_list() cache.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$this->drupalGet('module-test/class-loading');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoText($this->expected, 'Autoloader does not load classes from a disabled module.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that module-provided classes can't be loaded from disabled modules.
|
||||
*
|
||||
* @see \Drupal\module_autoload_test\SomeClass
|
||||
*/
|
||||
public function testClassLoadingDisabledModules() {
|
||||
// Enable the module_test and module_autoload_test modules.
|
||||
\Drupal::service('module_installer')->install(['module_test', 'module_autoload_test'], FALSE);
|
||||
$this->resetAll();
|
||||
// Ensure that module_autoload_test is disabled.
|
||||
$this->container->get('module_installer')->uninstall(['module_autoload_test'], FALSE);
|
||||
$this->resetAll();
|
||||
// Check twice to test an unprimed and primed system_list() cache.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$this->drupalGet('module-test/class-loading');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoText($this->expected, 'Autoloader does not load classes from a disabled module.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the negative caches in the class loader don't result in crashes.
|
||||
*/
|
||||
public function testMultipleModules() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$edit = [
|
||||
"modules[module_install_class_loader_test1][enable]" => TRUE,
|
||||
"modules[module_install_class_loader_test2][enable]" => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/modules', $edit, t('Install'));
|
||||
$this->rebuildContainer();
|
||||
$this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_install_class_loader_test2'), 'The module_install_class_loader_test2 module has been installed.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Module;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installation of modules.
|
||||
*
|
||||
* @group Module
|
||||
*/
|
||||
class ExperimentalModuleTest extends BrowserTestBase {
|
||||
|
||||
|
||||
/**
|
||||
* The admin user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->adminUser = $this->drupalCreateUser(['access administration pages', 'administer modules']);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests installing experimental modules and dependencies in the UI.
|
||||
*/
|
||||
public function testExperimentalConfirmForm() {
|
||||
|
||||
// First, test installing a non-experimental module with no dependencies.
|
||||
// There should be no confirmation form and no experimental module warning.
|
||||
$edit = [];
|
||||
$edit["modules[test_page_test][enable]"] = TRUE;
|
||||
$this->drupalPostForm('admin/modules', $edit, t('Install'));
|
||||
$this->assertText('Module Test page has been enabled.');
|
||||
$this->assertNoText('Experimental modules are provided for testing purposes only.');
|
||||
|
||||
// Uninstall the module.
|
||||
\Drupal::service('module_installer')->uninstall(['test_page_test']);
|
||||
|
||||
// Next, test installing an experimental module with no dependencies.
|
||||
// There should be a confirmation form with an experimental warning, but no
|
||||
// list of dependencies.
|
||||
$edit = [];
|
||||
$edit["modules[experimental_module_test][enable]"] = TRUE;
|
||||
$this->drupalPostForm('admin/modules', $edit, 'Install');
|
||||
|
||||
// The module should not be enabled and there should be a warning and a
|
||||
// list of the experimental modules with only this one.
|
||||
$this->assertNoText('Experimental Test has been enabled.');
|
||||
$this->assertText('Experimental modules are provided for testing purposes only.');
|
||||
$this->assertText('The following modules are experimental: Experimental Test');
|
||||
|
||||
// There should be no message about enabling dependencies.
|
||||
$this->assertNoText('You must enable');
|
||||
|
||||
// Enable the module and confirm that it worked.
|
||||
$this->drupalPostForm(NULL, [], 'Continue');
|
||||
$this->assertText('Experimental Test has been enabled.');
|
||||
|
||||
// Uninstall the module.
|
||||
\Drupal::service('module_installer')->uninstall(['experimental_module_test']);
|
||||
|
||||
// Test enabling a module that is not itself experimental, but that depends
|
||||
// on an experimental module.
|
||||
$edit = [];
|
||||
$edit["modules[experimental_module_dependency_test][enable]"] = TRUE;
|
||||
$this->drupalPostForm('admin/modules', $edit, 'Install');
|
||||
|
||||
// The module should not be enabled and there should be a warning and a
|
||||
// list of the experimental modules with only this one.
|
||||
$this->assertNoText('2 modules have been enabled: Experimental Dependency Test, Experimental Test');
|
||||
$this->assertText('Experimental modules are provided for testing purposes only.');
|
||||
|
||||
$this->assertText('The following modules are experimental: Experimental Test');
|
||||
|
||||
// Ensure the non-experimental module is not listed as experimental.
|
||||
$this->assertNoText('The following modules are experimental: Experimental Test, Experimental Dependency Test');
|
||||
$this->assertNoText('The following modules are experimental: Experimental Dependency Test');
|
||||
|
||||
// There should be a message about enabling dependencies.
|
||||
$this->assertText('You must enable the Experimental Test module to install Experimental Dependency Test');
|
||||
|
||||
// Enable the module and confirm that it worked.
|
||||
$this->drupalPostForm(NULL, [], 'Continue');
|
||||
$this->assertText('2 modules have been enabled: Experimental Dependency Test, Experimental Test');
|
||||
|
||||
// Uninstall the modules.
|
||||
\Drupal::service('module_installer')->uninstall(['experimental_module_test', 'experimental_module_dependency_test']);
|
||||
|
||||
// Finally, check both the module and its experimental dependency. There is
|
||||
// still a warning about experimental modules, but no message about
|
||||
// dependencies, since the user specifically enabled the dependency.
|
||||
$edit = [];
|
||||
$edit["modules[experimental_module_test][enable]"] = TRUE;
|
||||
$edit["modules[experimental_module_dependency_test][enable]"] = TRUE;
|
||||
$this->drupalPostForm('admin/modules', $edit, 'Install');
|
||||
|
||||
// The module should not be enabled and there should be a warning and a
|
||||
// list of the experimental modules with only this one.
|
||||
$this->assertNoText('2 modules have been enabled: Experimental Dependency Test, Experimental Test');
|
||||
$this->assertText('Experimental modules are provided for testing purposes only.');
|
||||
|
||||
$this->assertText('The following modules are experimental: Experimental Test');
|
||||
|
||||
// Ensure the non-experimental module is not listed as experimental.
|
||||
$this->assertNoText('The following modules are experimental: Experimental Dependency Test, Experimental Test');
|
||||
$this->assertNoText('The following modules are experimental: Experimental Dependency Test');
|
||||
|
||||
// There should be no message about enabling dependencies.
|
||||
$this->assertNoText('You must enable');
|
||||
|
||||
// Enable the module and confirm that it worked.
|
||||
$this->drupalPostForm(NULL, [], 'Continue');
|
||||
$this->assertText('2 modules have been enabled: Experimental Dependency Test, Experimental Test');
|
||||
|
||||
// Try to enable an experimental module that can not be due to
|
||||
// hook_requirements().
|
||||
\Drupal::state()->set('experimental_module_requirements_test_requirements', TRUE);
|
||||
$edit = [];
|
||||
$edit["modules[experimental_module_requirements_test][enable]"] = TRUE;
|
||||
$this->drupalPostForm('admin/modules', $edit, 'Install');
|
||||
$this->assertUrl('admin/modules', [], 'If the module can not be installed we are not taken to the confirm form.');
|
||||
$this->assertText('The Experimental Test Requirements module can not be installed.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Module;
|
||||
|
||||
use Drupal\Core\Extension\ExtensionNameLengthException;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installation of modules.
|
||||
*
|
||||
* @group Module
|
||||
*/
|
||||
class InstallTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['module_test'];
|
||||
|
||||
/**
|
||||
* Verify that drupal_get_schema() can be used during module installation.
|
||||
*/
|
||||
public function testGetSchemaAtInstallTime() {
|
||||
// @see module_test_install()
|
||||
$value = db_query("SELECT data FROM {module_test}")->fetchField();
|
||||
$this->assertIdentical($value, 'varchar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests enabling User module once more.
|
||||
*
|
||||
* Regression: The installer might enable a module twice due to automatic
|
||||
* dependency resolution. A bug caused the stored weight for User module to
|
||||
* be an array.
|
||||
*/
|
||||
public function testEnableUserTwice() {
|
||||
\Drupal::service('module_installer')->install(['user'], FALSE);
|
||||
$this->assertIdentical($this->config('core.extension')->get('module.user'), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests recorded schema versions of early installed modules in the installer.
|
||||
*/
|
||||
public function testRequiredModuleSchemaVersions() {
|
||||
$version = drupal_get_installed_schema_version('system', TRUE);
|
||||
$this->assertTrue($version > 0, 'System module version is > 0.');
|
||||
$version = drupal_get_installed_schema_version('user', TRUE);
|
||||
$this->assertTrue($version > 0, 'User module version is > 0.');
|
||||
|
||||
$post_update_key_value = \Drupal::keyValue('post_update');
|
||||
$existing_updates = $post_update_key_value->get('existing_updates', []);
|
||||
$this->assertTrue(in_array('module_test_post_update_test', $existing_updates));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that post update functions are removed on uninstall.
|
||||
*/
|
||||
public function testUninstallPostUpdateFunctions() {
|
||||
\Drupal::service('module_installer')->uninstall(['module_test']);
|
||||
|
||||
$post_update_key_value = \Drupal::keyValue('post_update');
|
||||
$existing_updates = $post_update_key_value->get('existing_updates', []);
|
||||
$this->assertFalse(in_array('module_test_post_update_test', $existing_updates));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an exception is thrown when a module name is too long.
|
||||
*/
|
||||
public function testModuleNameLength() {
|
||||
$module_name = 'invalid_module_name_over_the_maximum_allowed_character_length';
|
||||
$message = format_string('Exception thrown when enabling module %name with a name length over the allowed maximum', ['%name' => $module_name]);
|
||||
try {
|
||||
$this->container->get('module_installer')->install([$module_name]);
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ExtensionNameLengthException $e) {
|
||||
$this->pass($message);
|
||||
}
|
||||
|
||||
// Since for the UI, the submit callback uses FALSE, test that too.
|
||||
$message = format_string('Exception thrown when enabling as if via the UI the module %name with a name length over the allowed maximum', ['%name' => $module_name]);
|
||||
try {
|
||||
$this->container->get('module_installer')->install([$module_name], FALSE);
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ExtensionNameLengthException $e) {
|
||||
$this->pass($message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Module;
|
||||
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Config\FileStorage;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Helper class for module test cases.
|
||||
*/
|
||||
abstract class ModuleTestBase extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system_test'];
|
||||
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->adminUser = $this->drupalCreateUser(['access administration pages', 'administer modules']);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert there are tables that begin with the specified base table name.
|
||||
*
|
||||
* @param $base_table
|
||||
* Beginning of table name to look for.
|
||||
* @param $count
|
||||
* (optional) Whether or not to assert that there are tables that match the
|
||||
* specified base table. Defaults to TRUE.
|
||||
*/
|
||||
public function assertTableCount($base_table, $count = TRUE) {
|
||||
$tables = db_find_tables(Database::getConnection()->prefixTables('{' . $base_table . '}') . '%');
|
||||
|
||||
if ($count) {
|
||||
return $this->assertTrue($tables, format_string('Tables matching "@base_table" found.', ['@base_table' => $base_table]));
|
||||
}
|
||||
return $this->assertFalse($tables, format_string('Tables matching "@base_table" not found.', ['@base_table' => $base_table]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that all tables defined in a module's hook_schema() exist.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module.
|
||||
*/
|
||||
public function assertModuleTablesExist($module) {
|
||||
$tables = array_keys(drupal_get_module_schema($module));
|
||||
$tables_exist = TRUE;
|
||||
foreach ($tables as $table) {
|
||||
if (!db_table_exists($table)) {
|
||||
$tables_exist = FALSE;
|
||||
}
|
||||
}
|
||||
return $this->assertTrue($tables_exist, format_string('All database tables defined by the @module module exist.', ['@module' => $module]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that none of the tables defined in a module's hook_schema() exist.
|
||||
*
|
||||
* @param $module
|
||||
* The name of the module.
|
||||
*/
|
||||
public function assertModuleTablesDoNotExist($module) {
|
||||
$tables = array_keys(drupal_get_module_schema($module));
|
||||
$tables_exist = FALSE;
|
||||
foreach ($tables as $table) {
|
||||
if (db_table_exists($table)) {
|
||||
$tables_exist = TRUE;
|
||||
}
|
||||
}
|
||||
return $this->assertFalse($tables_exist, format_string('None of the database tables defined by the @module module exist.', ['@module' => $module]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the default configuration of a module has been installed.
|
||||
*
|
||||
* @param string $module
|
||||
* The name of the module.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if configuration has been installed, FALSE otherwise.
|
||||
*/
|
||||
public function assertModuleConfig($module) {
|
||||
$module_config_dir = drupal_get_path('module', $module) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
|
||||
if (!is_dir($module_config_dir)) {
|
||||
return;
|
||||
}
|
||||
$module_file_storage = new FileStorage($module_config_dir);
|
||||
|
||||
// Verify that the module's default config directory is not empty and
|
||||
// contains default configuration files (instead of something else).
|
||||
$all_names = $module_file_storage->listAll();
|
||||
if (empty($all_names)) {
|
||||
// Module has an empty config directory. For example it might contain a
|
||||
// schema directory.
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($all_names);
|
||||
|
||||
// Look up each default configuration object name in the active
|
||||
// configuration, and if it exists, remove it from the stack.
|
||||
// Only default config that belongs to $module is guaranteed to exist; any
|
||||
// other default config depends on whether other modules are enabled. Thus,
|
||||
// list all default config once more, but filtered by $module.
|
||||
$names = $module_file_storage->listAll($module . '.');
|
||||
foreach ($names as $key => $name) {
|
||||
if ($this->config($name)->get()) {
|
||||
unset($names[$key]);
|
||||
}
|
||||
}
|
||||
// Verify that all configuration has been installed (which means that $names
|
||||
// is empty).
|
||||
return $this->assertFalse($names, format_string('All default configuration of @module module found.', ['@module' => $module]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that no configuration exists for a given module.
|
||||
*
|
||||
* @param string $module
|
||||
* The name of the module.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if no configuration was found, FALSE otherwise.
|
||||
*/
|
||||
public function assertNoModuleConfig($module) {
|
||||
$names = \Drupal::configFactory()->listAll($module . '.');
|
||||
return $this->assertFalse($names, format_string('No configuration found for @module module.', ['@module' => $module]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the list of modules are enabled or disabled.
|
||||
*
|
||||
* @param $modules
|
||||
* Module list to check.
|
||||
* @param $enabled
|
||||
* Expected module state.
|
||||
*/
|
||||
public function assertModules(array $modules, $enabled) {
|
||||
$this->rebuildContainer();
|
||||
foreach ($modules as $module) {
|
||||
if ($enabled) {
|
||||
$message = 'Module "@module" is enabled.';
|
||||
}
|
||||
else {
|
||||
$message = 'Module "@module" is not enabled.';
|
||||
}
|
||||
$this->assertEqual($this->container->get('module_handler')->moduleExists($module), $enabled, format_string($message, ['@module' => $module]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a log entry was entered for a module's status change.
|
||||
*
|
||||
* @param $type
|
||||
* The category to which this message belongs.
|
||||
* @param $message
|
||||
* The message to store in the log. Keep $message translatable
|
||||
* by not concatenating dynamic values into it! Variables in the
|
||||
* message should be added by using placeholder strings alongside
|
||||
* the variables argument to declare the value of the placeholders.
|
||||
* See t() for documentation on how $message and $variables interact.
|
||||
* @param $variables
|
||||
* Array of variables to replace in the message on display or
|
||||
* NULL if message is already translated or not possible to
|
||||
* translate.
|
||||
* @param $severity
|
||||
* The severity of the message, as per RFC 3164.
|
||||
* @param $link
|
||||
* A link to associate with the message.
|
||||
*/
|
||||
public function assertLogMessage($type, $message, $variables = [], $severity = RfcLogLevel::NOTICE, $link = '') {
|
||||
$count = db_select('watchdog', 'w')
|
||||
->condition('type', $type)
|
||||
->condition('message', $message)
|
||||
->condition('variables', serialize($variables))
|
||||
->condition('severity', $severity)
|
||||
->condition('link', $link)
|
||||
->countQuery()
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertTrue($count > 0, format_string('watchdog table contains @count rows for @message', ['@count' => $count, '@message' => format_string($message, $variables)]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Module;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityMalformedException;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the uninstallation of modules.
|
||||
*
|
||||
* @group Module
|
||||
*/
|
||||
class UninstallTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['module_test', 'user', 'views', 'node'];
|
||||
|
||||
/**
|
||||
* Tests the hook_modules_uninstalled() of the user module.
|
||||
*/
|
||||
public function testUserPermsUninstalled() {
|
||||
// Uninstalls the module_test module, so hook_modules_uninstalled()
|
||||
// is executed.
|
||||
$this->container->get('module_installer')->uninstall(['module_test']);
|
||||
|
||||
// Are the perms defined by module_test removed?
|
||||
$this->assertFalse(user_roles(FALSE, 'module_test perm'), 'Permissions were all removed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Uninstall page and Uninstall confirmation page.
|
||||
*/
|
||||
public function testUninstallPage() {
|
||||
$account = $this->drupalCreateUser(['administer modules']);
|
||||
$this->drupalLogin($account);
|
||||
|
||||
// Create a node type.
|
||||
$node_type = NodeType::create(['type' => 'uninstall_blocker', 'name' => 'Uninstall blocker']);
|
||||
// Create a dependency that can be fixed.
|
||||
$node_type->setThirdPartySetting('module_test', 'key', 'value');
|
||||
$node_type->save();
|
||||
// Add a node to prevent node from being uninstalled.
|
||||
$node = Node::create([
|
||||
'type' => 'uninstall_blocker',
|
||||
'title' => $this->randomString(),
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->assertTitle(t('Uninstall') . ' | Drupal');
|
||||
|
||||
// Be sure labels are rendered properly.
|
||||
// @see regression https://www.drupal.org/node/2512106
|
||||
$this->assertRaw('<label for="edit-uninstall-node" class="module-name table-filter-text-source">Node</label>');
|
||||
|
||||
$this->assertText(\Drupal::translation()->translate('The following reason prevents Node from being uninstalled:'));
|
||||
$this->assertText(\Drupal::translation()->translate('There is content for the entity type: Content'));
|
||||
// Delete the node to allow node to be uninstalled.
|
||||
$node->delete();
|
||||
|
||||
// Uninstall module_test.
|
||||
$edit = [];
|
||||
$edit['uninstall[module_test]'] = TRUE;
|
||||
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
|
||||
$this->assertNoText(\Drupal::translation()->translate('Configuration deletions'), 'No configuration deletions listed on the module install confirmation page.');
|
||||
$this->assertText(\Drupal::translation()->translate('Configuration updates'), 'Configuration updates listed on the module install confirmation page.');
|
||||
$this->assertText($node_type->label());
|
||||
$this->drupalPostForm(NULL, NULL, t('Uninstall'));
|
||||
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
|
||||
|
||||
// Uninstall node testing that the configuration that will be deleted is
|
||||
// listed.
|
||||
$node_dependencies = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('module', ['node']);
|
||||
$edit = [];
|
||||
$edit['uninstall[node]'] = TRUE;
|
||||
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
|
||||
$this->assertText(\Drupal::translation()->translate('Configuration deletions'), 'Configuration deletions listed on the module install confirmation page.');
|
||||
$this->assertNoText(\Drupal::translation()->translate('Configuration updates'), 'No configuration updates listed on the module install confirmation page.');
|
||||
|
||||
$entity_types = [];
|
||||
foreach ($node_dependencies as $entity) {
|
||||
$label = $entity->label() ?: $entity->id();
|
||||
$this->assertText($label);
|
||||
$entity_types[] = $entity->getEntityTypeId();
|
||||
}
|
||||
$entity_types = array_unique($entity_types);
|
||||
foreach ($entity_types as $entity_type_id) {
|
||||
$entity_type = \Drupal::entityManager()->getDefinition($entity_type_id);
|
||||
// Add h3's since the entity type label is often repeated in the entity
|
||||
// labels.
|
||||
$this->assertRaw('<h3>' . $entity_type->getLabel() . '</h3>');
|
||||
}
|
||||
|
||||
// Set a unique cache entry to be able to test whether all caches are
|
||||
// cleared during the uninstall.
|
||||
\Drupal::cache()->set('uninstall_test', 'test_uninstall_page', Cache::PERMANENT);
|
||||
$cached = \Drupal::cache()->get('uninstall_test');
|
||||
$this->assertEqual($cached->data, 'test_uninstall_page', SafeMarkup::format('Cache entry found: @bin', ['@bin' => $cached->data]));
|
||||
|
||||
$this->drupalPostForm(NULL, NULL, t('Uninstall'));
|
||||
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
|
||||
$this->assertNoRaw('<label', 'The page does not have double escaped HTML tags.');
|
||||
|
||||
// Make sure our unique cache entry is gone.
|
||||
$cached = \Drupal::cache()->get('uninstall_test');
|
||||
$this->assertFalse($cached, 'Cache entry not found');
|
||||
// Make sure we get an error message when we try to confirm uninstallation
|
||||
// of an empty list of modules.
|
||||
$this->drupalGet('admin/modules/uninstall/confirm');
|
||||
$this->assertText(t('The selected modules could not be uninstalled, either due to a website problem or due to the uninstall confirmation form timing out. Please try again.'), 'Module uninstall confirmation form displays error message');
|
||||
|
||||
// Make sure confirmation page is accessible only during uninstall process.
|
||||
$this->drupalGet('admin/modules/uninstall/confirm');
|
||||
$this->assertUrl('admin/modules/uninstall');
|
||||
$this->assertTitle(t('Uninstall') . ' | Drupal');
|
||||
|
||||
// Make sure the correct error is shown when no modules are selected.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
|
||||
$this->assertText(t('No modules selected.'), 'No module is selected to uninstall');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a module which fails to install can still be uninstalled.
|
||||
*/
|
||||
public function testFailedInstallStatus() {
|
||||
$account = $this->drupalCreateUser(['administer modules']);
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$message = 'Exception thrown when installing module_installer_config_test with an invalid configuration file.';
|
||||
try {
|
||||
$this->container->get('module_installer')->install(['module_installer_config_test']);
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (EntityMalformedException $e) {
|
||||
$this->pass($message);
|
||||
}
|
||||
|
||||
// Even though the module failed to install properly, its configuration
|
||||
// status is "enabled" and should still be available to uninstall.
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->assertText('Module installer config test');
|
||||
$edit['uninstall[module_installer_config_test]'] = TRUE;
|
||||
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
|
||||
$this->drupalPostForm(NULL, NULL, t('Uninstall'));
|
||||
$this->assertText(t('The selected modules have been uninstalled.'));
|
||||
$this->assertNoText('Module installer config test');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\ParamConverter;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
|
||||
/**
|
||||
* Tests upcasting of url arguments to entities.
|
||||
*
|
||||
* @group ParamConverter
|
||||
*/
|
||||
class UpcastingTest extends BrowserTestBase {
|
||||
|
||||
public static $modules = ['paramconverter_test', 'node', 'language'];
|
||||
|
||||
/**
|
||||
* Confirms that all parameters are converted as expected.
|
||||
*
|
||||
* All of these requests end up being processed by a controller with the
|
||||
* signature: f($user, $node, $foo) returning either values or labels
|
||||
* like "user: Dries, node: First post, foo: bar"
|
||||
*
|
||||
* The tests shuffle the parameters around an checks if the right thing is
|
||||
* happening.
|
||||
*/
|
||||
public function testUpcasting() {
|
||||
$node = $this->drupalCreateNode(['title' => $this->randomMachineName(8)]);
|
||||
$user = $this->drupalCreateUser(['access content']);
|
||||
$foo = 'bar';
|
||||
|
||||
// paramconverter_test/test_user_node_foo/{user}/{node}/{foo}
|
||||
$this->drupalGet("paramconverter_test/test_user_node_foo/" . $user->id() . '/' . $node->id() . "/$foo");
|
||||
$this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: $foo", 'user and node upcast by entity name');
|
||||
|
||||
// paramconverter_test/test_node_user_user/{node}/{foo}/{user}
|
||||
// options.parameters.foo.type = entity:user
|
||||
$this->drupalGet("paramconverter_test/test_node_user_user/" . $node->id() . "/" . $user->id() . "/" . $user->id());
|
||||
$this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: {$user->label()}", 'foo converted to user as well');
|
||||
|
||||
// paramconverter_test/test_node_node_foo/{user}/{node}/{foo}
|
||||
// options.parameters.user.type = entity:node
|
||||
$this->drupalGet("paramconverter_test/test_node_node_foo/" . $node->id() . "/" . $node->id() . "/$foo");
|
||||
$this->assertRaw("user: {$node->label()}, node: {$node->label()}, foo: $foo", 'user is upcast to node (rather than to user)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms we can upcast to controller arguments of the same type.
|
||||
*/
|
||||
public function testSameTypes() {
|
||||
$node = $this->drupalCreateNode(['title' => $this->randomMachineName(8)]);
|
||||
$parent = $this->drupalCreateNode(['title' => $this->randomMachineName(8)]);
|
||||
// paramconverter_test/node/{node}/set/parent/{parent}
|
||||
// options.parameters.parent.type = entity:node
|
||||
$this->drupalGet("paramconverter_test/node/" . $node->id() . "/set/parent/" . $parent->id());
|
||||
$this->assertRaw("Setting '" . $parent->getTitle() . "' as parent of '" . $node->getTitle() . "'.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms entity is shown in user's language by default.
|
||||
*/
|
||||
public function testEntityLanguage() {
|
||||
$language = ConfigurableLanguage::createFromLangcode('de');
|
||||
$language->save();
|
||||
\Drupal::configFactory()->getEditable('language.negotiation')
|
||||
->set('url.prefixes', ['de' => 'de'])
|
||||
->save();
|
||||
|
||||
// The container must be recreated after adding a new language.
|
||||
$this->rebuildContainer();
|
||||
|
||||
$node = $this->drupalCreateNode(['title' => 'English label']);
|
||||
$translation = $node->addTranslation('de');
|
||||
$translation->setTitle('Deutscher Titel')->save();
|
||||
|
||||
$this->drupalGet("/paramconverter_test/node/" . $node->id() . "/test_language");
|
||||
$this->assertRaw("English label");
|
||||
$this->drupalGet("paramconverter_test/node/" . $node->id() . "/test_language", ['language' => $language]);
|
||||
$this->assertRaw("Deutscher Titel");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Path;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
|
||||
/**
|
||||
* Tests altering the inbound path and the outbound path.
|
||||
*
|
||||
* @group Path
|
||||
*/
|
||||
class UrlAlterFunctionalTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['path', 'forum', 'url_alter_test'];
|
||||
|
||||
/**
|
||||
* Test that URL altering works and that it occurs in the correct order.
|
||||
*/
|
||||
public function testUrlAlter() {
|
||||
// Ensure that the url_alias table exists after Drupal installation.
|
||||
$this->assertTrue(Database::getConnection()->schema()->tableExists('url_alias'), 'The url_alias table exists after Drupal installation.');
|
||||
|
||||
// User names can have quotes and plus signs so we should ensure that URL
|
||||
// altering works with this.
|
||||
$account = $this->drupalCreateUser(['administer url aliases'], "a'foo+bar");
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$uid = $account->id();
|
||||
$name = $account->getUsername();
|
||||
|
||||
// Test a single altered path.
|
||||
$this->drupalGet("user/$name");
|
||||
$this->assertResponse('200', 'The user/username path gets resolved correctly');
|
||||
$this->assertUrlOutboundAlter("/user/$uid", "/user/$name");
|
||||
|
||||
// Test that a path always uses its alias.
|
||||
$path = ['source' => "/user/$uid/test1", 'alias' => '/alias/test1'];
|
||||
$this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
|
||||
$this->rebuildContainer();
|
||||
$this->assertUrlInboundAlter('/alias/test1', "/user/$uid/test1");
|
||||
$this->assertUrlOutboundAlter("/user/$uid/test1", '/alias/test1');
|
||||
|
||||
// Test adding an alias via the UI.
|
||||
$edit = ['source' => "/user/$uid/edit", 'alias' => '/alias/test2'];
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
$this->assertText(t('The alias has been saved.'));
|
||||
$this->drupalGet('alias/test2');
|
||||
$this->assertResponse('200', 'The path alias gets resolved correctly');
|
||||
$this->assertUrlOutboundAlter("/user/$uid/edit", '/alias/test2');
|
||||
|
||||
// Test a non-existent user is not altered.
|
||||
$uid++;
|
||||
$this->assertUrlOutboundAlter("/user/$uid", "/user/$uid");
|
||||
|
||||
// Test that 'forum' is altered to 'community' correctly, both at the root
|
||||
// level and for a specific existing forum.
|
||||
$this->drupalGet('community');
|
||||
$this->assertText('General discussion', 'The community path gets resolved correctly');
|
||||
$this->assertUrlOutboundAlter('/forum', '/community');
|
||||
$forum_vid = $this->config('forum.settings')->get('vocabulary');
|
||||
$term_name = $this->randomMachineName();
|
||||
$term = Term::create([
|
||||
'name' => $term_name,
|
||||
'vid' => $forum_vid,
|
||||
]);
|
||||
$term->save();
|
||||
$this->drupalGet("community/" . $term->id());
|
||||
$this->assertText($term_name, 'The community/{tid} path gets resolved correctly');
|
||||
$this->assertUrlOutboundAlter("/forum/" . $term->id(), "/community/" . $term->id());
|
||||
|
||||
// Test outbound query string altering.
|
||||
$url = Url::fromRoute('user.login');
|
||||
$this->assertIdentical(\Drupal::request()->getBaseUrl() . '/user/login?foo=bar', $url->toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an outbound path is altered to an expected value.
|
||||
*
|
||||
* @param $original
|
||||
* A string with the original path that is run through generateFrommPath().
|
||||
* @param $final
|
||||
* A string with the expected result after generateFrommPath().
|
||||
*
|
||||
* @return
|
||||
* TRUE if $original was correctly altered to $final, FALSE otherwise.
|
||||
*/
|
||||
protected function assertUrlOutboundAlter($original, $final) {
|
||||
// Test outbound altering.
|
||||
$result = $this->container->get('path_processor_manager')->processOutbound($original);
|
||||
return $this->assertIdentical($result, $final, format_string('Altered outbound URL %original, expected %final, and got %result.', ['%original' => $original, '%final' => $final, '%result' => $result]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a inbound path is altered to an expected value.
|
||||
*
|
||||
* @param $original
|
||||
* The original path before it has been altered by inbound URL processing.
|
||||
* @param $final
|
||||
* A string with the expected result.
|
||||
*
|
||||
* @return
|
||||
* TRUE if $original was correctly altered to $final, FALSE otherwise.
|
||||
*/
|
||||
protected function assertUrlInboundAlter($original, $final) {
|
||||
// Test inbound altering.
|
||||
$result = $this->container->get('path.alias_manager')->getPathByAlias($original);
|
||||
return $this->assertIdentical($result, $final, format_string('Altered inbound URL %original, expected %final, and got %result.', ['%original' => $original, '%final' => $final, '%result' => $result]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Render;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Performs tests for the effects of the ajax_page_state query parameter.
|
||||
*
|
||||
* @group Render
|
||||
*/
|
||||
class AjaxPageStateTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'views'];
|
||||
|
||||
/**
|
||||
* User account with all available permissions
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create an administrator with all permissions.
|
||||
$this->adminUser = $this->drupalCreateUser(array_keys(\Drupal::service('user.permissions')
|
||||
->getPermissions()));
|
||||
|
||||
// Log in so there are more libraries to test with otherwise only html5shiv
|
||||
// is the only one in the source we can easily test for.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default functionality without the param ajax_page_state[libraries].
|
||||
*
|
||||
* The libraries html5shiv and drupalSettings are loaded default from core
|
||||
* and available in code as scripts. Do this as the base test.
|
||||
*/
|
||||
public function testLibrariesAvailable() {
|
||||
$this->drupalGet('node', []);
|
||||
$this->assertRaw(
|
||||
'/core/assets/vendor/html5shiv/html5shiv.min.js',
|
||||
'The html5shiv library from core should be loaded.'
|
||||
);
|
||||
$this->assertRaw(
|
||||
'/core/misc/drupalSettingsLoader.js',
|
||||
'The drupalSettings library from core should be loaded.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give ajax_page_state[libraries]=core/html5shiv to exclude the library.
|
||||
*
|
||||
* When called with ajax_page_state[libraries]=core/html5shiv the library
|
||||
* should be excluded as it is already loaded. This should not affect other
|
||||
* libraries so test if drupalSettings is still available.
|
||||
*/
|
||||
public function testHtml5ShivIsNotLoaded() {
|
||||
$this->drupalGet('node',
|
||||
[
|
||||
"query" =>
|
||||
[
|
||||
'ajax_page_state' => [
|
||||
'libraries' => 'core/html5shiv'
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
$this->assertNoRaw(
|
||||
'/core/assets/vendor/html5shiv/html5shiv.min.js',
|
||||
'The html5shiv library from core should be excluded from loading'
|
||||
);
|
||||
|
||||
$this->assertRaw(
|
||||
'/core/misc/drupalSettingsLoader.js',
|
||||
'The drupalSettings library from core should be loaded.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if multiple libraries can be excluded.
|
||||
*
|
||||
* The ajax_page_state[libraries] should be able to support multiple libraries
|
||||
* comma separated.
|
||||
*/
|
||||
public function testMultipleLibrariesAreNotLoaded() {
|
||||
$this->drupalGet('node',
|
||||
['query' => ['ajax_page_state' => ['libraries' => 'core/html5shiv,core/drupalSettings']]]
|
||||
);
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoRaw(
|
||||
'/core/assets/vendor/html5shiv/html5shiv.min.js',
|
||||
'The html5shiv library from core should be excluded from loading.'
|
||||
);
|
||||
|
||||
$this->assertNoRaw(
|
||||
'/core/misc/drupalSettingsLoader.js',
|
||||
'The drupalSettings library from core should be excluded from loading.'
|
||||
);
|
||||
|
||||
$this->drupalGet('node');
|
||||
$this->assertRaw(
|
||||
'/core/assets/vendor/html5shiv/html5shiv.min.js',
|
||||
'The html5shiv library from core should be included in loading.'
|
||||
);
|
||||
|
||||
$this->assertRaw(
|
||||
'/core/misc/drupalSettingsLoader.js',
|
||||
'The drupalSettings library from core should be included in loading.'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Render;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests selecting a display variant.
|
||||
*
|
||||
* @group Render
|
||||
*/
|
||||
class DisplayVariantTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['display_variant_test'];
|
||||
|
||||
/**
|
||||
* Tests selecting the variant and passing configuration.
|
||||
*/
|
||||
public function testPageDisplayVariantSelectionEvent() {
|
||||
// Tests that our display variant was selected, and that its configuration
|
||||
// was passed correctly. If the configuration wasn't passed, we'd get an
|
||||
// error page here.
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertRaw('A very important, required value.');
|
||||
$this->assertRaw('Explicitly passed in context.');
|
||||
$this->assertCacheTag('custom_cache_tag');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Routing;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
|
||||
|
||||
/**
|
||||
* A mock matcher that can be configured with any matching logic for testing.
|
||||
*/
|
||||
class MockMatcher implements RequestMatcherInterface {
|
||||
|
||||
/**
|
||||
* The matcher being tested.
|
||||
*/
|
||||
protected $matcher;
|
||||
|
||||
/**
|
||||
* Constructs a MockMatcher object.
|
||||
*
|
||||
* @param \Closure $matcher
|
||||
* An anonymous function that will be used for the matchRequest() method.
|
||||
*/
|
||||
public function __construct(\Closure $matcher) {
|
||||
$this->matcher = $matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matchRequest(Request $request) {
|
||||
$matcher = $this->matcher;
|
||||
return $matcher($request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Routing;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Function Tests for the routing permission system.
|
||||
*
|
||||
* @group Routing
|
||||
*/
|
||||
class RouterPermissionTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['router_test'];
|
||||
|
||||
/**
|
||||
* Tests permission requirements on routes.
|
||||
*/
|
||||
public function testPermissionAccess() {
|
||||
$path = 'router_test/test7';
|
||||
$this->drupalGet($path);
|
||||
$this->assertResponse(403, "Access denied for a route where we don't have a permission");
|
||||
|
||||
$this->drupalGet('router_test/test8');
|
||||
$this->assertResponse(403, 'Access denied by default if no access specified');
|
||||
|
||||
$user = $this->drupalCreateUser(['access test7']);
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet('router_test/test7');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoRaw('Access denied');
|
||||
$this->assertRaw('test7text', 'The correct string was returned because the route was successful.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\ServiceProvider;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests service provider registration to the DIC.
|
||||
*
|
||||
* @group ServiceProvider
|
||||
*/
|
||||
class ServiceProviderWebTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['file', 'service_provider_test'];
|
||||
|
||||
/**
|
||||
* Tests that module service providers get registered to the DIC.
|
||||
*
|
||||
* Also tests that services provided by module service providers get
|
||||
* registered to the DIC.
|
||||
*/
|
||||
public function testServiceProviderRegistrationIntegration() {
|
||||
$this->assertTrue(\Drupal::hasService('service_provider_test_class'), 'The service_provider_test_class service has been registered to the DIC');
|
||||
// The event subscriber method in the test class calls drupal_set_message()
|
||||
// with a message saying it has fired. This will fire on every page request
|
||||
// so it should show up on the front page.
|
||||
$this->drupalGet('');
|
||||
$this->assertText(t('The service_provider_test event subscriber fired!'), 'The service_provider_test event subscriber fired');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Confirm that the fingerprinting meta tag appears as expected.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class AdminMetaTagTest extends BrowserTestBase {
|
||||
/**
|
||||
* Verify that the meta tag HTML is generated correctly.
|
||||
*/
|
||||
public function testMetaTag() {
|
||||
list($version, ) = explode('.', \Drupal::VERSION);
|
||||
$string = '<meta name="Generator" content="Drupal ' . $version . ' (https://www.drupal.org)" />';
|
||||
$this->drupalGet('node');
|
||||
$this->assertRaw($string, 'Fingerprinting meta tag generated correctly.', 'System');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the locked functionality of date formats.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class DateFormatsLockedTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Tests attempts at listing, editing, and deleting locked date formats.
|
||||
*/
|
||||
public function testDateLocking() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// Locked date formats are not linked on the listing page, locked date
|
||||
// formats are clearly marked as such; unlocked formats are not marked as
|
||||
// "locked".
|
||||
$this->drupalGet('admin/config/regional/date-time');
|
||||
$this->assertLinkByHref('admin/config/regional/date-time/formats/manage/short');
|
||||
$this->assertNoLinkByHref('admin/config/regional/date-time/formats/manage/html_date');
|
||||
$this->assertText('Fallback date format');
|
||||
$this->assertNoText('short (locked)');
|
||||
|
||||
// Locked date formats are not editable.
|
||||
$this->drupalGet('admin/config/regional/date-time/formats/manage/short');
|
||||
$this->assertResponse(200);
|
||||
$this->drupalGet('admin/config/regional/date-time/formats/manage/html_date');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Locked date formats are not deletable.
|
||||
$this->drupalGet('admin/config/regional/date-time/formats/manage/short/delete');
|
||||
$this->assertResponse(200);
|
||||
$this->drupalGet('admin/config/regional/date-time/formats/manage/html_date/delete');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests validity of date format machine names.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class DateFormatsMachineNameTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create a new administrator user for the test.
|
||||
$admin = $this->drupalCreateUser(['administer site configuration']);
|
||||
$this->drupalLogin($admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that date formats cannot be created with invalid machine names.
|
||||
*/
|
||||
public function testDateFormatsMachineNameAllowedValues() {
|
||||
// Try to create a date format with a not allowed character to test the date
|
||||
// format specific machine name replace pattern.
|
||||
$edit = [
|
||||
'label' => 'Something Not Allowed',
|
||||
'id' => 'something.bad',
|
||||
'date_format_pattern' => 'Y-m-d',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertText(t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'), 'It is not possible to create a date format with the machine name that has any character other than lowercase letters, digits or underscore.');
|
||||
|
||||
// Try to create a date format with the reserved machine name "custom".
|
||||
$edit = [
|
||||
'label' => 'Custom',
|
||||
'id' => 'custom',
|
||||
'date_format_pattern' => 'Y-m-d',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertText(t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'), 'It is not possible to create a date format with the machine name "custom".');
|
||||
|
||||
// Try to create a date format with a machine name, "fallback", that
|
||||
// already exists.
|
||||
$edit = [
|
||||
'label' => 'Fallback',
|
||||
'id' => 'fallback',
|
||||
'date_format_pattern' => 'j/m/Y',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertText(t('The machine-readable name is already in use. It must be unique.'), 'It is not possible to create a date format with the machine name "fallback". It is a built-in format that already exists.');
|
||||
|
||||
// Create a date format with a machine name distinct from the previous two.
|
||||
$id = Unicode::strtolower($this->randomMachineName(16));
|
||||
$edit = [
|
||||
'label' => $this->randomMachineName(16),
|
||||
'id' => $id,
|
||||
'date_format_pattern' => 'd/m/Y',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertText(t('Custom date format added.'), 'It is possible to create a date format with a new machine name.');
|
||||
|
||||
// Try to create a date format with same machine name as the previous one.
|
||||
$edit = [
|
||||
'label' => $this->randomMachineName(16),
|
||||
'id' => $id,
|
||||
'date_format_pattern' => 'd-m-Y',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertText(t('The machine-readable name is already in use. It must be unique.'), 'It is not possible to create a new date format with an existing machine name.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Configure date and time settings. Test date formatting and time zone
|
||||
* handling, including daylight saving time.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class DateTimeTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'node', 'language', 'field', 'field_ui', 'datetime', 'options'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create admin user and log in admin user.
|
||||
$this->drupalLogin ($this->drupalCreateUser([
|
||||
'administer site configuration',
|
||||
'administer content types',
|
||||
'administer nodes',
|
||||
'administer node fields',
|
||||
'administer node form display',
|
||||
'administer node display',
|
||||
]));
|
||||
$this->drupalPlaceBlock('local_actions_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test time zones and DST handling.
|
||||
*/
|
||||
public function testTimeZoneHandling() {
|
||||
// Setup date/time settings for Honolulu time.
|
||||
$config = $this->config('system.date')
|
||||
->set('timezone.default', 'Pacific/Honolulu')
|
||||
->set('timezone.user.configurable', 0)
|
||||
->save();
|
||||
DateFormat::load('medium')
|
||||
->setPattern('Y-m-d H:i:s O')
|
||||
->save();
|
||||
|
||||
// Create some nodes with different authored-on dates.
|
||||
$date1 = '2007-01-31 21:00:00 -1000';
|
||||
$date2 = '2007-07-31 21:00:00 -1000';
|
||||
$this->drupalCreateContentType(['type' => 'article']);
|
||||
$node1 = $this->drupalCreateNode(['created' => strtotime($date1), 'type' => 'article']);
|
||||
$node2 = $this->drupalCreateNode(['created' => strtotime($date2), 'type' => 'article']);
|
||||
|
||||
// Confirm date format and time zone.
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertText('2007-01-31 21:00:00 -1000', 'Date should be identical, with GMT offset of -10 hours.');
|
||||
$this->drupalGet('node/' . $node2->id());
|
||||
$this->assertText('2007-07-31 21:00:00 -1000', 'Date should be identical, with GMT offset of -10 hours.');
|
||||
|
||||
// Set time zone to Los Angeles time.
|
||||
$config->set('timezone.default', 'America/Los_Angeles')->save();
|
||||
\Drupal::entityManager()->getViewBuilder('node')->resetCache([$node1, $node2]);
|
||||
|
||||
// Confirm date format and time zone.
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertText('2007-01-31 23:00:00 -0800', 'Date should be two hours ahead, with GMT offset of -8 hours.');
|
||||
$this->drupalGet('node/' . $node2->id());
|
||||
$this->assertText('2007-08-01 00:00:00 -0700', 'Date should be three hours ahead, with GMT offset of -7 hours.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test date format configuration.
|
||||
*/
|
||||
public function testDateFormatConfiguration() {
|
||||
// Confirm 'no custom date formats available' message appears.
|
||||
$this->drupalGet('admin/config/regional/date-time');
|
||||
|
||||
// Add custom date format.
|
||||
$this->clickLink(t('Add format'));
|
||||
$date_format_id = strtolower($this->randomMachineName(8));
|
||||
$name = ucwords($date_format_id);
|
||||
$date_format = 'd.m.Y - H:i';
|
||||
$edit = [
|
||||
'id' => $date_format_id,
|
||||
'label' => $name,
|
||||
'date_format_pattern' => $date_format,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
|
||||
$this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
|
||||
$this->assertText($name, 'Custom date format appears in the date format list.');
|
||||
$this->assertText(t('Delete'), 'Delete link for custom date format appears.');
|
||||
|
||||
// Edit the custom date format and re-save without editing the format.
|
||||
$this->drupalGet('admin/config/regional/date-time');
|
||||
$this->clickLink(t('Edit'));
|
||||
$this->drupalPostForm(NULL, NULL, t('Save format'));
|
||||
$this->assertUrl('admin/config/regional/date-time', ['absolute' => TRUE], 'Correct page redirection.');
|
||||
$this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
|
||||
|
||||
// Edit custom date format.
|
||||
$this->drupalGet('admin/config/regional/date-time');
|
||||
$this->clickLink(t('Edit'));
|
||||
$edit = [
|
||||
'date_format_pattern' => 'Y m',
|
||||
];
|
||||
$this->drupalPostForm($this->getUrl(), $edit, t('Save format'));
|
||||
$this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
|
||||
$this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
|
||||
|
||||
// Delete custom date format.
|
||||
$this->clickLink(t('Delete'));
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/manage/' . $date_format_id . '/delete', [], t('Delete'));
|
||||
$this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
|
||||
$this->assertRaw(t('The date format %format has been deleted.', ['%format' => $name]), 'Custom date format removed.');
|
||||
|
||||
// Make sure the date does not exist in config.
|
||||
$date_format = DateFormat::load($date_format_id);
|
||||
$this->assertFalse($date_format);
|
||||
|
||||
// Add a new date format with an existing format.
|
||||
$date_format_id = strtolower($this->randomMachineName(8));
|
||||
$name = ucwords($date_format_id);
|
||||
$date_format = 'Y';
|
||||
$edit = [
|
||||
'id' => $date_format_id,
|
||||
'label' => $name,
|
||||
'date_format_pattern' => $date_format,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
|
||||
$this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
|
||||
$this->assertText($name, 'Custom date format appears in the date format list.');
|
||||
$this->assertText(t('Delete'), 'Delete link for custom date format appears.');
|
||||
|
||||
$date_format = DateFormat::create([
|
||||
'id' => 'xss_short',
|
||||
'label' => 'XSS format',
|
||||
'pattern' => '\<\s\c\r\i\p\t\>\a\l\e\r\t\(\'\X\S\S\'\)\;\<\/\s\c\r\i\p\t\>',
|
||||
]);
|
||||
$date_format->save();
|
||||
|
||||
$this->drupalGet(Url::fromRoute('entity.date_format.collection'));
|
||||
$this->assertEscaped("<script>alert('XSS');</script>", 'The date format was properly escaped');
|
||||
|
||||
// Add a new date format with HTML in it.
|
||||
$date_format_id = strtolower($this->randomMachineName(8));
|
||||
$name = ucwords($date_format_id);
|
||||
$date_format = '& \<\e\m\>Y\<\/\e\m\>';
|
||||
$edit = [
|
||||
'id' => $date_format_id,
|
||||
'label' => $name,
|
||||
'date_format_pattern' => $date_format,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
|
||||
$this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
|
||||
$this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
|
||||
$this->assertText($name, 'Custom date format appears in the date format list.');
|
||||
$this->assertEscaped('<em>' . date("Y") . '</em>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test handling case with invalid data in selectors (like February, 31st).
|
||||
*/
|
||||
public function testEnteringDateTimeViaSelectors() {
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'page_with_date', 'name' => 'Page with date']);
|
||||
|
||||
$this->drupalGet('admin/structure/types/manage/page_with_date');
|
||||
$this->assertResponse(200, 'Content type created.');
|
||||
|
||||
$this->drupalGet('admin/structure/types/manage/page_with_date/fields/add-field');
|
||||
$edit = [
|
||||
'new_storage_type' => 'datetime',
|
||||
'label' => 'dt',
|
||||
'field_name' => 'dt',
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/page_with_date/fields/add-field', $edit, t('Save and continue'));
|
||||
$this->assertText(t('These settings apply to the'), 'New datetime field created, now configuring');
|
||||
|
||||
$this->drupalGet('admin/structure/types/manage/page_with_date/fields/node.page_with_date.field_dt/storage');
|
||||
$edit = [
|
||||
'settings[datetime_type]' => 'datetime',
|
||||
'cardinality' => 'number',
|
||||
'cardinality_number' => '1',
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/page_with_date/fields/node.page_with_date.field_dt/storage', $edit, t('Save field settings'));
|
||||
|
||||
$this->drupalGet('admin/structure/types/manage/page_with_date/fields');
|
||||
$this->assertText('field_dt', 'New field is in place');
|
||||
|
||||
$this->drupalGet('admin/structure/types/manage/page_with_date/form-display');
|
||||
$edit = [
|
||||
'fields[field_dt][type]' => 'datetime_datelist',
|
||||
'fields[field_dt][region]' => 'content',
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/page_with_date/form-display', $edit, t('Save'));
|
||||
$this->drupalLogout();
|
||||
|
||||
// Now log in as a regular editor.
|
||||
$this->drupalLogin($this->drupalCreateUser(['create page_with_date content']));
|
||||
|
||||
$this->drupalGet('node/add/page_with_date');
|
||||
$edit = [
|
||||
'title[0][value]' => 'sample doc',
|
||||
'field_dt[0][value][year]' => '2016',
|
||||
'field_dt[0][value][month]' => '2',
|
||||
'field_dt[0][value][day]' => '31',
|
||||
'field_dt[0][value][hour]' => '1',
|
||||
'field_dt[0][value][minute]' => '30',
|
||||
];
|
||||
$this->drupalPostForm('node/add/page_with_date', $edit, t('Save'));
|
||||
$this->assertText(t('Selected combination of day and month is not valid.'), 'Inorrect date failed validation');
|
||||
|
||||
$edit['field_dt[0][value][day]'] = '29';
|
||||
$this->drupalPostForm('node/add/page_with_date', $edit, t('Save'));
|
||||
$this->assertNoText(t('Selected combination of day and month is not valid.'), 'Correct date passed validation.');
|
||||
|
||||
$this->drupalGet('node/1');
|
||||
$this->assertText(t('Mon, 02/29/2016 - 01:30'), 'Node successfully created with valid date.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the handling of requests containing 'index.php'.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class IndexPhpTest extends BrowserTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test index.php handling.
|
||||
*/
|
||||
public function testIndexPhpHandling() {
|
||||
$index_php = $GLOBALS['base_url'] . '/index.php';
|
||||
|
||||
$this->drupalGet($index_php, ['external' => TRUE]);
|
||||
$this->assertResponse(200, 'Make sure index.php returns a valid page.');
|
||||
|
||||
$this->drupalGet($index_php . '/user', ['external' => TRUE]);
|
||||
$this->assertResponse(200, 'Make sure index.php/user returns a valid page.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Test SimplePageVariant main content rendering fallback page display variant.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class MainContentFallbackTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'system_test'];
|
||||
|
||||
protected $adminUser;
|
||||
protected $webUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create and log in admin user.
|
||||
$this->adminUser = $this->drupalCreateUser([
|
||||
'access administration pages',
|
||||
'administer site configuration',
|
||||
'administer modules',
|
||||
]);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Create a web user.
|
||||
$this->webUser = $this->drupalCreateUser(['access user profiles']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test availability of main content: Drupal falls back to SimplePageVariant.
|
||||
*/
|
||||
public function testMainContentFallback() {
|
||||
$edit = [];
|
||||
// Uninstall the block module.
|
||||
$edit['uninstall[block]'] = 'block';
|
||||
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
|
||||
$this->drupalPostForm(NULL, NULL, t('Uninstall'));
|
||||
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
|
||||
$this->rebuildContainer();
|
||||
$this->assertFalse(\Drupal::moduleHandler()->moduleExists('block'), 'Block module uninstall.');
|
||||
|
||||
// When Block module is not installed and BlockPageVariant is not available,
|
||||
// Drupal should fall back to SimplePageVariant. Both for the admin and the
|
||||
// front-end theme.
|
||||
$this->drupalGet('admin/config/system/site-information');
|
||||
$this->assertField('site_name', 'Fallback to SimplePageVariant works for admin theme.');
|
||||
$this->drupalGet('system-test/main-content-fallback');
|
||||
$this->assertText(t('Content to test main content fallback'), 'Fallback to SimplePageVariant works for front-end theme.');
|
||||
// Request a user* page and see if it is displayed.
|
||||
$this->drupalLogin($this->webUser);
|
||||
$this->drupalGet('user/' . $this->webUser->id() . '/edit');
|
||||
$this->assertField('mail', 'User interface still available.');
|
||||
|
||||
// Enable the block module again.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$edit = [];
|
||||
$edit['modules[block][enable]'] = 'block';
|
||||
$this->drupalPostForm('admin/modules', $edit, t('Install'));
|
||||
$this->assertText(t('Module Block has been enabled.'), 'Modules status has been updated.');
|
||||
$this->rebuildContainer();
|
||||
$this->assertTrue(\Drupal::moduleHandler()->moduleExists('block'), 'Block module re-enabled.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests HTTP file fetching and error handling.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class RetrieveFileTest extends BrowserTestBase {
|
||||
/**
|
||||
* Invokes system_retrieve_file() in several scenarios.
|
||||
*/
|
||||
public function testFileRetrieving() {
|
||||
// Test 404 handling by trying to fetch a randomly named file.
|
||||
drupal_mkdir($sourcedir = 'public://' . $this->randomMachineName());
|
||||
$filename = 'Файл для тестирования ' . $this->randomMachineName();
|
||||
$url = file_create_url($sourcedir . '/' . $filename);
|
||||
$retrieved_file = system_retrieve_file($url);
|
||||
$this->assertFalse($retrieved_file, 'Non-existent file not fetched.');
|
||||
|
||||
// Actually create that file, download it via HTTP and test the returned path.
|
||||
file_put_contents($sourcedir . '/' . $filename, 'testing');
|
||||
$retrieved_file = system_retrieve_file($url);
|
||||
|
||||
// URLs could not contains characters outside the ASCII set so $filename
|
||||
// has to be encoded.
|
||||
$encoded_filename = rawurlencode($filename);
|
||||
|
||||
$this->assertEqual($retrieved_file, 'public://' . $encoded_filename, 'Sane path for downloaded file returned (public:// scheme).');
|
||||
$this->assertTrue(is_file($retrieved_file), 'Downloaded file does exist (public:// scheme).');
|
||||
$this->assertEqual(filesize($retrieved_file), 7, 'File size of downloaded file is correct (public:// scheme).');
|
||||
file_unmanaged_delete($retrieved_file);
|
||||
|
||||
// Test downloading file to a different location.
|
||||
drupal_mkdir($targetdir = 'temporary://' . $this->randomMachineName());
|
||||
$retrieved_file = system_retrieve_file($url, $targetdir);
|
||||
$this->assertEqual($retrieved_file, "$targetdir/$encoded_filename", 'Sane path for downloaded file returned (temporary:// scheme).');
|
||||
$this->assertTrue(is_file($retrieved_file), 'Downloaded file does exist (temporary:// scheme).');
|
||||
$this->assertEqual(filesize($retrieved_file), 7, 'File size of downloaded file is correct (temporary:// scheme).');
|
||||
file_unmanaged_delete($retrieved_file);
|
||||
|
||||
file_unmanaged_delete_recursive($sourcedir);
|
||||
file_unmanaged_delete_recursive($targetdir);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests Drupal permissions hardening of /sites subdirectories.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class SitesDirectoryHardeningTest extends BrowserTestBase {
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Tests the default behavior to restrict directory permissions is enforced.
|
||||
*
|
||||
* Checks both the the current sites directory and settings.php.
|
||||
*/
|
||||
public function testSitesDirectoryHardening() {
|
||||
$site_path = $this->kernel->getSitePath();
|
||||
$settings_file = $this->settingsFile($site_path);
|
||||
|
||||
// First, we check based on what the initial install has set.
|
||||
$this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file.', ['@file' => $site_path]));
|
||||
|
||||
// We intentionally don't check for settings.local.php as that file is
|
||||
// not created by Drupal.
|
||||
$this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file.', ['@file' => $settings_file]));
|
||||
|
||||
$this->makeWritable($site_path);
|
||||
$this->checkSystemRequirements();
|
||||
|
||||
$this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file after manual permissions change.', ['@file' => $site_path]));
|
||||
$this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file after manual permissions change.', ['@file' => $settings_file]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests writable files remain writable when directory hardening is disabled.
|
||||
*/
|
||||
public function testSitesDirectoryHardeningConfig() {
|
||||
$site_path = $this->kernel->getSitePath();
|
||||
$settings_file = $this->settingsFile($site_path);
|
||||
|
||||
// Disable permissions enforcement.
|
||||
$settings = Settings::getAll();
|
||||
$settings['skip_permissions_hardening'] = TRUE;
|
||||
new Settings($settings);
|
||||
$this->assertTrue(Settings::get('skip_permissions_hardening'), 'Able to set hardening to true');
|
||||
$this->makeWritable($site_path);
|
||||
|
||||
// Manually trigger the requirements check.
|
||||
$requirements = $this->checkSystemRequirements();
|
||||
$this->assertEqual(REQUIREMENT_WARNING, $requirements['configuration_files']['severity'], 'Warning severity is properly set.');
|
||||
$this->assertEqual($this->t('Protection disabled'), (string) $requirements['configuration_files']['description']['#context']['configuration_error_list']['#items'][0], 'Description is properly set.');
|
||||
|
||||
$this->assertTrue(is_writable($site_path), 'Site directory remains writable when automatically fixing permissions is disabled.');
|
||||
$this->assertTrue(is_writable($settings_file), 'settings.php remains writable when automatically fixing permissions is disabled.');
|
||||
|
||||
// Re-enable permissions enforcement.
|
||||
$settings = Settings::getAll();
|
||||
$settings['skip_permissions_hardening'] = FALSE;
|
||||
new Settings($settings);
|
||||
|
||||
// Manually trigger the requirements check.
|
||||
$this->checkSystemRequirements();
|
||||
|
||||
$this->assertFalse(is_writable($site_path), 'Site directory is protected when automatically fixing permissions is enabled.');
|
||||
$this->assertFalse(is_writable($settings_file), 'settings.php is protected when automatically fixing permissions is enabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks system runtime requirements.
|
||||
*
|
||||
* @return array
|
||||
* An array of system requirements.
|
||||
*/
|
||||
protected function checkSystemRequirements() {
|
||||
module_load_install('system');
|
||||
return system_requirements('runtime');
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given path and settings file writable.
|
||||
*
|
||||
* @param string $site_path
|
||||
* The sites directory path, such as 'sites/default'.
|
||||
*/
|
||||
protected function makeWritable($site_path) {
|
||||
chmod($site_path, 0755);
|
||||
chmod($this->settingsFile($site_path), 0644);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to settings.php
|
||||
*
|
||||
* @param string $site_path
|
||||
* The sites subdirectory path.
|
||||
*
|
||||
* @return string
|
||||
* The path to settings.php.
|
||||
*/
|
||||
protected function settingsFile($site_path) {
|
||||
$settings_file = $site_path . '/settings.php';
|
||||
return $settings_file;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\system\SystemRequirements;
|
||||
|
||||
/**
|
||||
* Tests output on the status overview page.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class StatusTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['update_test_postupdate'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Unset the sync directory in settings.php to trigger $config_directories
|
||||
// error.
|
||||
$settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => '',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer site configuration',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the status page returns.
|
||||
*/
|
||||
public function testStatusPage() {
|
||||
// Go to Administration.
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertResponse(200, 'The status page is reachable.');
|
||||
|
||||
$phpversion = phpversion();
|
||||
$this->assertText($phpversion, 'Php version is shown on the page.');
|
||||
|
||||
// Checks if the suggestion to update to php 5.5.21 or 5.6.5 for disabling
|
||||
// multiple statements is present when necessary.
|
||||
if (\Drupal::database()->driver() === 'mysql' && !SystemRequirements::phpVersionWithPdoDisallowMultipleStatements($phpversion)) {
|
||||
$this->assertText(t('PHP (multiple statement disabling)'));
|
||||
}
|
||||
else {
|
||||
$this->assertNoText(t('PHP (multiple statement disabling)'));
|
||||
}
|
||||
|
||||
if (function_exists('phpinfo')) {
|
||||
$this->assertLinkByHref(Url::fromRoute('system.php')->toString());
|
||||
}
|
||||
else {
|
||||
$this->assertNoLinkByHref(Url::fromRoute('system.php')->toString());
|
||||
}
|
||||
|
||||
// If a module is fully installed no pending updates exists.
|
||||
$this->assertNoText(t('Out of date'));
|
||||
|
||||
// The global $config_directories is not properly formed.
|
||||
$this->assertRaw(t('Your %file file must define the $config_directories variable as an array containing the names of directories in which configuration files can be found. It must contain a %sync_key key.', ['%file' => $this->siteDirectory . '/settings.php', '%sync_key' => CONFIG_SYNC_DIRECTORY]));
|
||||
|
||||
// Set the schema version of update_test_postupdate to a lower version, so
|
||||
// update_test_postupdate_update_8001() needs to be executed.
|
||||
drupal_set_installed_schema_version('update_test_postupdate', 8000);
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertText(t('Out of date'));
|
||||
|
||||
// Now cleanup the executed post update functions.
|
||||
drupal_set_installed_schema_version('update_test_postupdate', 8001);
|
||||
/** @var \Drupal\Core\Update\UpdateRegistry $post_update_registry */
|
||||
$post_update_registry = \Drupal::service('update.post_update_registry');
|
||||
$post_update_registry->filterOutInvokedUpdatesByModule('update_test_postupdate');
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertText(t('Out of date'));
|
||||
|
||||
$this->drupalGet('admin/reports/status/php');
|
||||
$this->assertResponse(200, 'The phpinfo page is reachable.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the authorize.php script and related API.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class SystemAuthorizeTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create an administrator user.
|
||||
$this->drupalLogin ($this->drupalCreateUser(['administer software updates']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to initialize authorize.php and load it via drupalGet().
|
||||
*
|
||||
* Initializing authorize.php needs to happen in the child Drupal
|
||||
* installation, not the parent. So, we visit a menu callback provided by
|
||||
* system_test.module which calls system_authorized_init() to initialize the
|
||||
* $_SESSION inside the test site, not the framework site. This callback
|
||||
* redirects to authorize.php when it's done initializing.
|
||||
*
|
||||
* @see system_authorized_init()
|
||||
*/
|
||||
public function drupalGetAuthorizePHP($page_title = 'system-test-auth') {
|
||||
$this->drupalGet('system-test/authorize-init/' . $page_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the FileTransfer hooks
|
||||
*/
|
||||
public function testFileTransferHooks() {
|
||||
$page_title = $this->randomMachineName(16);
|
||||
$this->drupalGetAuthorizePHP($page_title);
|
||||
$this->assertTitle(strtr('@title | Drupal', ['@title' => $page_title]), 'authorize.php page title is correct.');
|
||||
$this->assertNoText('It appears you have reached this page in error.');
|
||||
$this->assertText('To continue, provide your server connection details');
|
||||
// Make sure we see the new connection method added by system_test.
|
||||
$this->assertRaw('System Test FileTransfer');
|
||||
// Make sure the settings form callback works.
|
||||
$this->assertText('System Test Username');
|
||||
// Test that \Drupal\Core\Render\BareHtmlPageRenderer adds assets as
|
||||
// expected to the first page of the authorize.php script.
|
||||
$this->assertRaw('core/misc/states.js');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Scan token-like patterns in a dummy text to check token scanning.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class TokenScanTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Scans dummy text, then tests the output.
|
||||
*/
|
||||
public function testTokenScan() {
|
||||
// Define text with valid and not valid, fake and existing token-like
|
||||
// strings.
|
||||
$text = 'First a [valid:simple], but dummy token, and a dummy [valid:token with: spaces].';
|
||||
$text .= 'Then a [not valid:token].';
|
||||
$text .= 'Then an [:empty token type].';
|
||||
$text .= 'Then an [empty token:].';
|
||||
$text .= 'Then a totally empty token: [:].';
|
||||
$text .= 'Last an existing token: [node:author:name].';
|
||||
$token_wannabes = \Drupal::token()->scan($text);
|
||||
|
||||
$this->assertTrue(isset($token_wannabes['valid']['simple']), 'A simple valid token has been matched.');
|
||||
$this->assertTrue(isset($token_wannabes['valid']['token with: spaces']), 'A valid token with space characters in the token name has been matched.');
|
||||
$this->assertFalse(isset($token_wannabes['not valid']), 'An invalid token with spaces in the token type has not been matched.');
|
||||
$this->assertFalse(isset($token_wannabes['empty token']), 'An empty token has not been matched.');
|
||||
$this->assertFalse(isset($token_wannabes['']['empty token type']), 'An empty token type has not been matched.');
|
||||
$this->assertFalse(isset($token_wannabes['']['']), 'An empty token and type has not been matched.');
|
||||
$this->assertTrue(isset($token_wannabes['node']), 'An existing valid token has been matched.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\System;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests output on the status overview page.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class TrustedHostsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer site configuration',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the status page shows an error when the trusted host setting
|
||||
* is missing from settings.php
|
||||
*/
|
||||
public function testStatusPageWithoutConfiguration() {
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertResponse(200, 'The status page is reachable.');
|
||||
|
||||
$this->assertRaw(t('Trusted Host Settings'));
|
||||
$this->assertRaw(t('The trusted_host_patterns setting is not configured in settings.php.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the status page shows the trusted patterns from settings.php.
|
||||
*/
|
||||
public function testStatusPageWithConfiguration() {
|
||||
$settings['settings']['trusted_host_patterns'] = (object) [
|
||||
'value' => ['^' . preg_quote(\Drupal::request()->getHost()) . '$'],
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('admin/reports/status');
|
||||
$this->assertResponse(200, 'The status page is reachable.');
|
||||
|
||||
$this->assertRaw(t('Trusted Host Settings'));
|
||||
$this->assertRaw(t('The trusted_host_patterns setting is set to allow'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that fake requests have the proper host configured.
|
||||
*
|
||||
* @see \Drupal\Core\Http\TrustedHostsRequestFactory
|
||||
*/
|
||||
public function testFakeRequests() {
|
||||
$this->container->get('module_installer')->install(['trusted_hosts_test']);
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
|
||||
$host = $this->container->get('request_stack')->getCurrentRequest()->getHost();
|
||||
$settings['settings']['trusted_host_patterns'] = (object) [
|
||||
'value' => ['^' . preg_quote($host) . '$'],
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('trusted-hosts-test/fake-request');
|
||||
$this->assertText('Host: ' . $host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that shortcut module works together with host verification.
|
||||
*/
|
||||
public function testShortcut() {
|
||||
$this->container->get('module_installer')->install(['block', 'shortcut']);
|
||||
$this->rebuildContainer();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityManagerInterface $entity_manager */
|
||||
$entity_manager = $this->container->get('entity.manager');
|
||||
$shortcut_storage = $entity_manager->getStorage('shortcut');
|
||||
|
||||
$shortcut = $shortcut_storage->create([
|
||||
'title' => $this->randomString(),
|
||||
'link' => 'internal:/admin/reports/status',
|
||||
'shortcut_set' => 'default',
|
||||
]);
|
||||
$shortcut_storage->save($shortcut);
|
||||
|
||||
// Grant the current user access to see the shortcuts.
|
||||
$role_storage = $entity_manager->getStorage('user_role');
|
||||
$roles = $this->loggedInUser->getRoles(TRUE);
|
||||
/** @var \Drupal\user\RoleInterface $role */
|
||||
$role = $role_storage->load(reset($roles));
|
||||
$role->grantPermission('access shortcuts')->save();
|
||||
|
||||
$this->drupalPlaceBlock('shortcuts');
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertLink($shortcut->label());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the multi theme engine support.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class EngineNyanCatTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['theme_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::service('theme_handler')->install(['test_theme_nyan_cat_engine']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a theme's template is overridable based on the 'template' filename.
|
||||
*/
|
||||
public function testTemplateOverride() {
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_theme_nyan_cat_engine')
|
||||
->save();
|
||||
$this->drupalGet('theme-test/template-test');
|
||||
$this->assertText('Success: Template overridden with Nyan Cat theme. All of them', 'Template overridden by Nyan Cat file.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests autocompletion not loading registry.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class FastTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['theme_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->account = $this->drupalCreateUser(['access user profiles']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests access to user autocompletion and verify the correct results.
|
||||
*/
|
||||
public function testUserAutocomplete() {
|
||||
$this->drupalLogin($this->account);
|
||||
$this->drupalGet('user/autocomplete', ['query' => ['q' => $this->account->getUsername()]]);
|
||||
$this->assertRaw($this->account->getUsername());
|
||||
$this->assertNoText('registry initialized', 'The registry was not initialized');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the theme system can be correctly initialized early in the page
|
||||
* request.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class ThemeEarlyInitializationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['theme_test'];
|
||||
|
||||
/**
|
||||
* Test that the theme system can generate output in a request listener.
|
||||
*/
|
||||
public function testRequestListener() {
|
||||
$this->drupalGet('theme-test/request-listener');
|
||||
// Verify that themed output generated in the request listener appears.
|
||||
$this->assertRaw('Themed output generated in a KernelEvents::REQUEST listener');
|
||||
// Verify that the default theme's CSS still appears even though the theme
|
||||
// system was initialized early.
|
||||
$this->assertRaw('classy/css/components/action-links.css');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests processing of theme .info.yml properties.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class ThemeInfoTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['theme_test'];
|
||||
|
||||
/**
|
||||
* The theme handler used in this test for enabling themes.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ThemeHandler
|
||||
*/
|
||||
protected $themeHandler;
|
||||
|
||||
/**
|
||||
* The theme manager used in this test.
|
||||
*
|
||||
* @var \Drupal\Core\Theme\ThemeManagerInterface
|
||||
*/
|
||||
protected $themeManager;
|
||||
|
||||
/**
|
||||
* The state service used in this test.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->themeHandler = $this->container->get('theme_handler');
|
||||
$this->themeManager = $this->container->get('theme.manager');
|
||||
$this->state = $this->container->get('state');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests stylesheets-remove.
|
||||
*/
|
||||
public function testStylesheets() {
|
||||
$this->themeHandler->install(['test_basetheme', 'test_subtheme']);
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_subtheme')
|
||||
->save();
|
||||
|
||||
$base = drupal_get_path('theme', 'test_basetheme');
|
||||
$sub = drupal_get_path('theme', 'test_subtheme') . '/css';
|
||||
|
||||
// All removals are expected to be based on a file's path and name and
|
||||
// should work nevertheless.
|
||||
$this->drupalGet('theme-test/info/stylesheets');
|
||||
|
||||
$this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$base/base-add.css"])), "$base/base-add.css found");
|
||||
$this->assertIdentical(0, count($this->xpath('//link[contains(@href, :href)]', [':href' => "base-remove.css"])), "base-remove.css not found");
|
||||
|
||||
$this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$sub/sub-add.css"])), "$sub/sub-add.css found");
|
||||
$this->assertIdentical(0, count($this->xpath('//link[contains(@href, :href)]', [':href' => "sub-remove.css"])), "sub-remove.css not found");
|
||||
$this->assertIdentical(0, count($this->xpath('//link[contains(@href, :href)]', [':href' => "base-add.sub-remove.css"])), "base-add.sub-remove.css not found");
|
||||
|
||||
// Verify that CSS files with the same name are loaded from both the base theme and subtheme.
|
||||
$this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$base/samename.css"])), "$base/samename.css found");
|
||||
$this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$sub/samename.css"])), "$sub/samename.css found");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that changes to the info file are picked up.
|
||||
*/
|
||||
public function testChanges() {
|
||||
$this->themeHandler->install(['test_theme']);
|
||||
$this->config('system.theme')->set('default', 'test_theme')->save();
|
||||
$this->themeManager->resetActiveTheme();
|
||||
|
||||
$active_theme = $this->themeManager->getActiveTheme();
|
||||
// Make sure we are not testing the wrong theme.
|
||||
$this->assertEqual('test_theme', $active_theme->getName());
|
||||
$this->assertEqual(['classy/base', 'core/normalize', 'test_theme/global-styling'], $active_theme->getLibraries());
|
||||
|
||||
// @see theme_test_system_info_alter()
|
||||
$this->state->set('theme_test.modify_info_files', TRUE);
|
||||
drupal_flush_all_caches();
|
||||
$active_theme = $this->themeManager->getActiveTheme();
|
||||
$this->assertEqual(['classy/base', 'core/normalize', 'test_theme/global-styling', 'core/backbone'], $active_theme->getLibraries());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the generation of 'theme_token' key in Drupal settings.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class ThemeTokenTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* We want to visit the 'admin/structure/block' page.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static public $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$account = $this->drupalCreateUser(['administer blocks', 'view the administration theme']);
|
||||
$this->drupalLogin($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the 'theme_token' key of 'ajaxPageState' is computed.
|
||||
*/
|
||||
public function testThemeToken() {
|
||||
// Visit the block administrative page with default theme. We use that page
|
||||
// because 'misc/ajax.js' is loaded there and we can test the token
|
||||
// generation.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$settings = $this->getDrupalSettings();
|
||||
$this->assertNull($settings['ajaxPageState']['theme_token']);
|
||||
|
||||
// Install 'seven' and configure it as administrative theme.
|
||||
$this->container->get('theme_installer')->install(['seven']);
|
||||
$this->config('system.theme')->set('admin', 'seven')->save();
|
||||
|
||||
// Revisit the page. This time the page is displayed using the 'seven' theme
|
||||
// and that is different from the default theme ('classy').
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$settings = $this->getDrupalSettings();
|
||||
$this->assertNotNull($settings['ajaxPageState']['theme_token']);
|
||||
// The CSRF token is a 43 length string.
|
||||
$this->assertTrue(is_string($settings['ajaxPageState']['theme_token']));
|
||||
$this->assertEqual(strlen($settings['ajaxPageState']['theme_token']), 43);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests Twig extensions.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class TwigExtensionTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['theme_test', 'twig_extension_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::service('theme_handler')->install(['test_theme']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the provided Twig extension loads the service appropriately.
|
||||
*/
|
||||
public function testTwigExtensionLoaded() {
|
||||
$twigService = \Drupal::service('twig');
|
||||
$ext = $twigService->getExtension('twig_extension_test.test_extension');
|
||||
$this->assertEqual(get_class($ext), 'Drupal\twig_extension_test\TwigExtension\TestExtension', 'TestExtension loaded successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Twig extension's filter produces expected output.
|
||||
*/
|
||||
public function testTwigExtensionFilter() {
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_theme')
|
||||
->save();
|
||||
|
||||
$this->drupalGet('twig-extension-test/filter');
|
||||
$this->assertText('Every plant is not a mineral.', 'Success: String filtered.');
|
||||
// Test safe_join filter.
|
||||
$this->assertRaw('<em>will be escaped</em><br/><em>will be markup</em><br/><strong>will be rendered</strong>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the Twig extension's function produces expected output.
|
||||
*/
|
||||
public function testTwigExtensionFunction() {
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_theme')
|
||||
->save();
|
||||
|
||||
$this->drupalGet('twig-extension-test/function');
|
||||
$this->assertText('THE QUICK BROWN BOX JUMPS OVER THE LAZY DOG 123.', 'Success: Text converted to uppercase.');
|
||||
$this->assertText('the quick brown box jumps over the lazy dog 123.', 'Success: Text converted to lowercase.');
|
||||
$this->assertNoText('The Quick Brown Fox Jumps Over The Lazy Dog 123.', 'Success: No text left behind.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests output of integer and double 0 values of TwigExtension::escapeFilter().
|
||||
*
|
||||
* @see https://www.drupal.org/node/2417733
|
||||
*/
|
||||
public function testsRenderEscapedZeroValue() {
|
||||
/** @var \Drupal\Core\Template\TwigExtension $extension */
|
||||
$extension = \Drupal::service('twig.extension');
|
||||
/** @var \Drupal\Core\Template\TwigEnvironment $twig */
|
||||
$twig = \Drupal::service('twig');
|
||||
$this->assertIdentical($extension->escapeFilter($twig, 0), 0, 'TwigExtension::escapeFilter() returns zero correctly when provided as an integer.');
|
||||
$this->assertIdentical($extension->escapeFilter($twig, 0.0), 0, 'TwigExtension::escapeFilter() returns zero correctly when provided as a double.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests output of integer and double 0 values of TwigExtension->renderVar().
|
||||
*
|
||||
* @see https://www.drupal.org/node/2417733
|
||||
*/
|
||||
public function testsRenderZeroValue() {
|
||||
/** @var \Drupal\Core\Template\TwigExtension $extension */
|
||||
$extension = \Drupal::service('twig.extension');
|
||||
$this->assertIdentical($extension->renderVar(0), 0, 'TwigExtension::renderVar() renders zero correctly when provided as an integer.');
|
||||
$this->assertIdentical($extension->renderVar(0.0), 0, 'TwigExtension::renderVar() renders zero correctly when provided as a double.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests adding Twig loaders.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class TwigLoaderTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['twig_loader_test'];
|
||||
|
||||
/**
|
||||
* Tests adding an additional twig loader to the loader chain.
|
||||
*/
|
||||
public function testTwigLoaderAddition() {
|
||||
$environment = \Drupal::service('twig');
|
||||
|
||||
$template = $environment->loadTemplate('kittens');
|
||||
$this->assertEqual($template->render([]), 'kittens', 'Passing "kittens" to the custom Twig loader returns "kittens".');
|
||||
|
||||
$template = $environment->loadTemplate('meow');
|
||||
$this->assertEqual($template->render([]), 'cats', 'Passing something other than "kittens" to the custom Twig loader returns "cats".');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests Twig registry loader.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class TwigRegistryLoaderTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['twig_theme_test', 'block'];
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Template\TwigEnvironment
|
||||
*/
|
||||
protected $twig;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
\Drupal::service('theme_handler')->install(['test_theme_twig_registry_loader', 'test_theme_twig_registry_loader_theme', 'test_theme_twig_registry_loader_subtheme']);
|
||||
$this->twig = \Drupal::service('twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a value is a Twig template.
|
||||
*/
|
||||
public function assertTwigTemplate($value, $message = '', $group = 'Other') {
|
||||
$this->assertTrue($value instanceof \Twig_Template, $message, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests template discovery using the Drupal theme registry.
|
||||
*/
|
||||
public function testTemplateDiscovery() {
|
||||
$this->assertTwigTemplate($this->twig->resolveTemplate('block.html.twig'), 'Found block.html.twig in block module.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests template extension and includes using the Drupal theme registry.
|
||||
*/
|
||||
public function testTwigNamespaces() {
|
||||
// Test the module-provided extend and insert templates.
|
||||
$this->drupalGet('twig-theme-test/registry-loader');
|
||||
$this->assertText('This line is from twig_theme_test/templates/twig-registry-loader-test-extend.html.twig');
|
||||
$this->assertText('This line is from twig_theme_test/templates/twig-registry-loader-test-include.html.twig');
|
||||
|
||||
// Enable a theme that overrides the extend and insert templates to ensure
|
||||
// they are picked up by the registry loader.
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_theme_twig_registry_loader')
|
||||
->save();
|
||||
$this->drupalGet('twig-theme-test/registry-loader');
|
||||
$this->assertText('This line is from test_theme_twig_registry_loader/templates/twig-registry-loader-test-extend.html.twig');
|
||||
$this->assertText('This line is from test_theme_twig_registry_loader/templates/twig-registry-loader-test-include.html.twig');
|
||||
|
||||
// Enable overriding theme that overrides the extend and insert templates
|
||||
// from the base theme.
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_theme_twig_registry_loader_theme')
|
||||
->save();
|
||||
$this->drupalGet('twig-theme-test/registry-loader');
|
||||
$this->assertText('This line is from test_theme_twig_registry_loader_theme/templates/twig-registry-loader-test-extend.html.twig');
|
||||
$this->assertText('This line is from test_theme_twig_registry_loader_theme/templates/twig-registry-loader-test-include.html.twig');
|
||||
|
||||
// Enable a subtheme for the theme that doesn't have any overrides to make
|
||||
// sure that templates are being loaded from the first parent which has the
|
||||
// templates.
|
||||
$this->config('system.theme')
|
||||
->set('default', 'test_theme_twig_registry_loader_subtheme')
|
||||
->save();
|
||||
$this->drupalGet('twig-theme-test/registry-loader');
|
||||
$this->assertText('This line is from test_theme_twig_registry_loader_theme/templates/twig-registry-loader-test-extend.html.twig');
|
||||
$this->assertText('This line is from test_theme_twig_registry_loader_theme/templates/twig-registry-loader-test-include.html.twig');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Core\PhpStorage\PhpStorageFactory;
|
||||
|
||||
/**
|
||||
* Tests overriding Twig engine settings via settings.php.
|
||||
*
|
||||
* @group Theme
|
||||
*/
|
||||
class TwigSettingsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['theme_test'];
|
||||
|
||||
/**
|
||||
* Ensures Twig template auto reload setting can be overridden.
|
||||
*/
|
||||
public function testTwigAutoReloadOverride() {
|
||||
// Enable auto reload and rebuild the service container.
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['auto_reload'] = TRUE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Check isAutoReload() via the Twig service container.
|
||||
$this->assertTrue($this->container->get('twig')->isAutoReload(), 'Automatic reloading of Twig templates enabled.');
|
||||
|
||||
// Disable auto reload and check the service container again.
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['auto_reload'] = FALSE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
|
||||
$this->assertFalse($this->container->get('twig')->isAutoReload(), 'Automatic reloading of Twig templates disabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures Twig engine debug setting can be overridden.
|
||||
*/
|
||||
public function testTwigDebugOverride() {
|
||||
// Enable debug and rebuild the service container.
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['debug'] = TRUE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Check isDebug() via the Twig service container.
|
||||
$this->assertTrue($this->container->get('twig')->isDebug(), 'Twig debug enabled.');
|
||||
$this->assertTrue($this->container->get('twig')->isAutoReload(), 'Twig automatic reloading is enabled when debug is enabled.');
|
||||
|
||||
// Override auto reload when debug is enabled.
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['auto_reload'] = FALSE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
$this->assertFalse($this->container->get('twig')->isAutoReload(), 'Twig automatic reloading can be disabled when debug is enabled.');
|
||||
|
||||
// Disable debug and check the service container again.
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['debug'] = FALSE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
|
||||
$this->assertFalse($this->container->get('twig')->isDebug(), 'Twig debug disabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures Twig template cache setting can be overridden.
|
||||
*/
|
||||
public function testTwigCacheOverride() {
|
||||
$extension = twig_extension();
|
||||
$theme_handler = $this->container->get('theme_handler');
|
||||
$theme_handler->install(['test_theme']);
|
||||
$this->config('system.theme')->set('default', 'test_theme')->save();
|
||||
|
||||
// The registry still works on theme globals, so set them here.
|
||||
\Drupal::theme()->setActiveTheme(\Drupal::service('theme.initialization')->getActiveThemeByName('test_theme'));
|
||||
|
||||
// Reset the theme registry, so that the new theme is used.
|
||||
$this->container->set('theme.registry', NULL);
|
||||
|
||||
// Load array of Twig templates.
|
||||
// reset() is necessary to invalidate caches tagged with 'theme_registry'.
|
||||
$registry = $this->container->get('theme.registry');
|
||||
$registry->reset();
|
||||
$templates = $registry->getRuntime();
|
||||
|
||||
// Get the template filename and the cache filename for
|
||||
// theme_test.template_test.html.twig.
|
||||
$info = $templates->get('theme_test_template_test');
|
||||
$template_filename = $info['path'] . '/' . $info['template'] . $extension;
|
||||
$cache_filename = $this->container->get('twig')->getCacheFilename($template_filename);
|
||||
|
||||
// Navigate to the page and make sure the template gets cached.
|
||||
$this->drupalGet('theme-test/template-test');
|
||||
$this->assertTrue(PhpStorageFactory::get('twig')->exists($cache_filename), 'Cached Twig template found.');
|
||||
|
||||
// Disable the Twig cache and rebuild the service container.
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['cache'] = FALSE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// This should return false after rebuilding the service container.
|
||||
$this->assertFalse($this->container->get('twig')->getCache(), 'Twig environment has caching disabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests twig inline templates with auto_reload.
|
||||
*/
|
||||
public function testTwigInlineWithAutoReload() {
|
||||
$parameters = $this->container->getParameter('twig.config');
|
||||
$parameters['auto_reload'] = TRUE;
|
||||
$parameters['debug'] = TRUE;
|
||||
$this->setContainerParameter('twig.config', $parameters);
|
||||
$this->rebuildContainer();
|
||||
|
||||
$this->drupalGet('theme-test/inline-template-test');
|
||||
$this->assertResponse(200);
|
||||
$this->drupalGet('theme-test/inline-template-test');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ class ActionTest extends KernelTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = array('system', 'field', 'user', 'action_test');
|
||||
public static $modules = ['system', 'field', 'user', 'action_test'];
|
||||
|
||||
/**
|
||||
* The action manager.
|
||||
|
|
@ -34,7 +34,7 @@ class ActionTest extends KernelTestBase {
|
|||
|
||||
$this->actionManager = $this->container->get('plugin.manager.action');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('system', array('sequences'));
|
||||
$this->installSchema('system', ['sequences']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,7 +59,7 @@ class ActionTest extends KernelTestBase {
|
|||
// Create a new unsaved user.
|
||||
$name = $this->randomMachineName();
|
||||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
$account = $user_storage->create(array('name' => $name, 'bundle' => 'user'));
|
||||
$account = $user_storage->create(['name' => $name, 'bundle' => 'user']);
|
||||
$loaded_accounts = $user_storage->loadMultiple();
|
||||
$this->assertEqual(count($loaded_accounts), 0);
|
||||
|
||||
|
|
@ -76,25 +76,25 @@ class ActionTest extends KernelTestBase {
|
|||
*/
|
||||
public function testDependencies() {
|
||||
// Create a new action that depends on a user role.
|
||||
$action = Action::create(array(
|
||||
$action = Action::create([
|
||||
'id' => 'user_add_role_action.' . RoleInterface::ANONYMOUS_ID,
|
||||
'type' => 'user',
|
||||
'label' => t('Add the anonymous role to the selected users'),
|
||||
'configuration' => array(
|
||||
'configuration' => [
|
||||
'rid' => RoleInterface::ANONYMOUS_ID,
|
||||
),
|
||||
],
|
||||
'plugin' => 'user_add_role_action',
|
||||
));
|
||||
]);
|
||||
$action->save();
|
||||
|
||||
$expected = array(
|
||||
'config' => array(
|
||||
$expected = [
|
||||
'config' => [
|
||||
'user.role.' . RoleInterface::ANONYMOUS_ID,
|
||||
),
|
||||
'module' => array(
|
||||
],
|
||||
'module' => [
|
||||
'user',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
$this->assertIdentical($expected, $action->calculateDependencies()->getDependencies());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
public static $modules = [
|
||||
'system',
|
||||
'block',
|
||||
'menu_test',
|
||||
|
|
@ -39,7 +39,7 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
'field',
|
||||
'user',
|
||||
'link',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* The block under test.
|
||||
|
|
@ -97,16 +97,16 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
$this->blockManager = $this->container->get('plugin.manager.block');
|
||||
|
||||
$routes = new RouteCollection();
|
||||
$requirements = array('_access' => 'TRUE');
|
||||
$options = array('_access_checks' => array('access_check.default'));
|
||||
$routes->add('example1', new Route('/example1', array(), $requirements, $options));
|
||||
$routes->add('example2', new Route('/example2', array(), $requirements, $options));
|
||||
$routes->add('example3', new Route('/example3', array(), $requirements, $options));
|
||||
$routes->add('example4', new Route('/example4', array(), $requirements, $options));
|
||||
$routes->add('example5', new Route('/example5', array(), $requirements, $options));
|
||||
$routes->add('example6', new Route('/example6', array(), $requirements, $options));
|
||||
$routes->add('example7', new Route('/example7', array(), $requirements, $options));
|
||||
$routes->add('example8', new Route('/example8', array(), $requirements, $options));
|
||||
$requirements = ['_access' => 'TRUE'];
|
||||
$options = ['_access_checks' => ['access_check.default']];
|
||||
$routes->add('example1', new Route('/example1', [], $requirements, $options));
|
||||
$routes->add('example2', new Route('/example2', [], $requirements, $options));
|
||||
$routes->add('example3', new Route('/example3', [], $requirements, $options));
|
||||
$routes->add('example4', new Route('/example4', [], $requirements, $options));
|
||||
$routes->add('example5', new Route('/example5', [], $requirements, $options));
|
||||
$routes->add('example6', new Route('/example6', [], $requirements, $options));
|
||||
$routes->add('example7', new Route('/example7', [], $requirements, $options));
|
||||
$routes->add('example8', new Route('/example8', [], $requirements, $options));
|
||||
|
||||
$mock_route_provider = new MockRouteProvider($routes);
|
||||
$this->container->set('router.route_provider', $mock_route_provider);
|
||||
|
|
@ -115,11 +115,11 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
$menu_name = 'mock';
|
||||
$label = $this->randomMachineName(16);
|
||||
|
||||
$this->menu = Menu::create(array(
|
||||
$this->menu = Menu::create([
|
||||
'id' => $menu_name,
|
||||
'label' => $label,
|
||||
'description' => 'Description text',
|
||||
));
|
||||
]);
|
||||
$this->menu->save();
|
||||
|
||||
// This creates a tree with the following structure:
|
||||
|
|
@ -132,16 +132,16 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
// - 6
|
||||
// - 8
|
||||
// With link 6 being the only external link.
|
||||
$links = array(
|
||||
1 => MenuLinkMock::create(array('id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '', 'weight' => 0)),
|
||||
2 => MenuLinkMock::create(array('id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => '', 'route_parameters' => array('foo' => 'bar'), 'weight' => 1)),
|
||||
3 => MenuLinkMock::create(array('id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'weight' => 2)),
|
||||
4 => MenuLinkMock::create(array('id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3', 'weight' => 3)),
|
||||
5 => MenuLinkMock::create(array('id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '', 'expanded' => TRUE, 'weight' => 4)),
|
||||
6 => MenuLinkMock::create(array('id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '', 'weight' => 5)),
|
||||
7 => MenuLinkMock::create(array('id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => 'test.example5', 'weight' => 6)),
|
||||
8 => MenuLinkMock::create(array('id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '', 'weight' => 7)),
|
||||
);
|
||||
$links = [
|
||||
1 => MenuLinkMock::create(['id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '', 'weight' => 0]),
|
||||
2 => MenuLinkMock::create(['id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => '', 'route_parameters' => ['foo' => 'bar'], 'weight' => 1]),
|
||||
3 => MenuLinkMock::create(['id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'weight' => 2]),
|
||||
4 => MenuLinkMock::create(['id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3', 'weight' => 3]),
|
||||
5 => MenuLinkMock::create(['id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '', 'expanded' => TRUE, 'weight' => 4]),
|
||||
6 => MenuLinkMock::create(['id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '', 'weight' => 5]),
|
||||
7 => MenuLinkMock::create(['id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => 'test.example5', 'weight' => 6]),
|
||||
8 => MenuLinkMock::create(['id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '', 'weight' => 7]),
|
||||
];
|
||||
foreach ($links as $instance) {
|
||||
$this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition());
|
||||
}
|
||||
|
|
@ -152,25 +152,25 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
*/
|
||||
public function testSystemMenuBlockConfigDependencies() {
|
||||
|
||||
$block = Block::create(array(
|
||||
$block = Block::create([
|
||||
'plugin' => 'system_menu_block:' . $this->menu->id(),
|
||||
'region' => 'footer',
|
||||
'id' => 'machinename',
|
||||
'theme' => 'stark',
|
||||
));
|
||||
]);
|
||||
|
||||
$dependencies = $block->calculateDependencies()->getDependencies();
|
||||
$expected = array(
|
||||
'config' => array(
|
||||
$expected = [
|
||||
'config' => [
|
||||
'system.menu.' . $this->menu->id()
|
||||
),
|
||||
'module' => array(
|
||||
],
|
||||
'module' => [
|
||||
'system'
|
||||
),
|
||||
'theme' => array(
|
||||
],
|
||||
'theme' => [
|
||||
'stark'
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
$this->assertIdentical($expected, $dependencies);
|
||||
}
|
||||
|
||||
|
|
@ -180,13 +180,13 @@ class SystemMenuBlockTest extends KernelTestBase {
|
|||
public function testConfigLevelDepth() {
|
||||
// Helper function to generate a configured block instance.
|
||||
$place_block = function ($level, $depth) {
|
||||
return $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), array(
|
||||
return $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), [
|
||||
'region' => 'footer',
|
||||
'id' => 'machinename',
|
||||
'theme' => 'stark',
|
||||
'level' => $level,
|
||||
'depth' => $depth,
|
||||
));
|
||||
]);
|
||||
};
|
||||
|
||||
// All the different block instances we're going to test.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class PageRenderTest extends KernelTestBase {
|
|||
/**
|
||||
* Tests hook_page_attachments() exceptions.
|
||||
*/
|
||||
function testHookPageAttachmentsExceptions() {
|
||||
public function testHookPageAttachmentsExceptions() {
|
||||
$this->enableModules(['common_test', 'system']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ class PageRenderTest extends KernelTestBase {
|
|||
/**
|
||||
* Tests hook_page_attachments_alter() exceptions.
|
||||
*/
|
||||
function testHookPageAlter() {
|
||||
public function testHookPageAlter() {
|
||||
$this->enableModules(['common_test', 'system']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ class PageRenderTest extends KernelTestBase {
|
|||
* @param string $hook
|
||||
* The page render hook to assert expected exceptions for.
|
||||
*/
|
||||
function assertPageRenderHookExceptions($module, $hook) {
|
||||
public function assertPageRenderHookExceptions($module, $hook) {
|
||||
$html_renderer = \Drupal::getContainer()->get('main_content_renderer.html');
|
||||
|
||||
// Assert a valid hook implementation doesn't trigger an exception.
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ class SystemListingTest extends KernelTestBase {
|
|||
/**
|
||||
* Tests that files in different directories take precedence as expected.
|
||||
*/
|
||||
function testDirectoryPrecedence() {
|
||||
public function testDirectoryPrecedence() {
|
||||
// Define the module files we will search for, and the directory precedence
|
||||
// we expect.
|
||||
$expected_directories = array(
|
||||
$expected_directories = [
|
||||
// When both copies of the module are compatible with Drupal core, the
|
||||
// copy in the profile directory takes precedence.
|
||||
'drupal_system_listing_compatible_test' => array(
|
||||
'drupal_system_listing_compatible_test' => [
|
||||
'core/profiles/testing/modules',
|
||||
'core/modules/system/tests/modules',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// This test relies on two versions of the same module existing in
|
||||
// different places in the filesystem. Without that, the test has no
|
||||
|
|
@ -32,22 +32,22 @@ class SystemListingTest extends KernelTestBase {
|
|||
foreach ($expected_directories as $module => $directories) {
|
||||
foreach ($directories as $directory) {
|
||||
$filename = "$directory/$module/$module.info.yml";
|
||||
$this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename)));
|
||||
$this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', ['@filename' => $filename]));
|
||||
}
|
||||
}
|
||||
|
||||
// Now scan the directories and check that the files take precedence as
|
||||
// expected.
|
||||
$listing = new ExtensionDiscovery(\Drupal::root());
|
||||
$listing->setProfileDirectories(array('core/profiles/testing'));
|
||||
$listing->setProfileDirectories(['core/profiles/testing']);
|
||||
$files = $listing->scan('module');
|
||||
foreach ($expected_directories as $module => $directories) {
|
||||
$expected_directory = array_shift($directories);
|
||||
$expected_uri = "$expected_directory/$module/$module.info.yml";
|
||||
$this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', array(
|
||||
$this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', [
|
||||
'@actual' => $files[$module]->getPathname(),
|
||||
'@expected' => $expected_uri,
|
||||
)));
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ class SystemListingTest extends KernelTestBase {
|
|||
*/
|
||||
public function testFileScanIgnoreDirectory() {
|
||||
$listing = new ExtensionDiscovery(\Drupal::root(), FALSE);
|
||||
$listing->setProfileDirectories(array('core/profiles/testing'));
|
||||
$listing->setProfileDirectories(['core/profiles/testing']);
|
||||
$files = $listing->scan('module');
|
||||
$this->assertArrayHasKey('drupal_system_listing_compatible_test', $files);
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ class SystemListingTest extends KernelTestBase {
|
|||
|
||||
$this->setSetting('file_scan_ignore_directories', ['drupal_system_listing_compatible_test']);
|
||||
$listing = new ExtensionDiscovery(\Drupal::root(), FALSE);
|
||||
$listing->setProfileDirectories(array('core/profiles/testing'));
|
||||
$listing->setProfileDirectories(['core/profiles/testing']);
|
||||
$files = $listing->scan('module');
|
||||
$this->assertArrayNotHasKey('drupal_system_listing_compatible_test', $files);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,13 +38,13 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
/**
|
||||
* The basic functionality of retrieving enabled modules.
|
||||
*/
|
||||
function testModuleList() {
|
||||
public function testModuleList() {
|
||||
$module_list = ['system'];
|
||||
|
||||
$this->assertModuleList($module_list, 'Initial');
|
||||
|
||||
// Try to install a new module.
|
||||
$this->moduleInstaller()->install(array('ban'));
|
||||
$this->moduleInstaller()->install(['ban']);
|
||||
$module_list[] = 'ban';
|
||||
sort($module_list);
|
||||
$this->assertModuleList($module_list, 'After adding a module');
|
||||
|
|
@ -58,10 +58,10 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
$this->assertModuleList($module_list, 'After changing weights');
|
||||
|
||||
// Test the fixed list feature.
|
||||
$fixed_list = array(
|
||||
$fixed_list = [
|
||||
'system' => 'core/modules/system/system.module',
|
||||
'menu' => 'core/modules/menu/menu.module',
|
||||
);
|
||||
];
|
||||
$this->moduleHandler()->setModuleList($fixed_list);
|
||||
$new_module_list = array_combine(array_keys($fixed_list), array_keys($fixed_list));
|
||||
$this->assertModuleList($new_module_list, t('When using a fixed list'));
|
||||
|
|
@ -77,7 +77,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
protected function assertModuleList(array $expected_values, $condition) {
|
||||
$expected_values = array_values(array_unique($expected_values));
|
||||
$enabled_modules = array_keys($this->container->get('module_handler')->getModuleList());
|
||||
$this->assertEqual($expected_values, $enabled_modules, format_string('@condition: extension handler returns correct results', array('@condition' => $condition)));
|
||||
$this->assertEqual($expected_values, $enabled_modules, format_string('@condition: extension handler returns correct results', ['@condition' => $condition]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,8 +92,8 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
* @see module_test_system_info_alter()
|
||||
* @see https://www.drupal.org/files/issues/dep.gv__0.png
|
||||
*/
|
||||
function testDependencyResolution() {
|
||||
$this->enableModules(array('module_test'));
|
||||
public function testDependencyResolution() {
|
||||
$this->enableModules(['module_test']);
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('module_test'), 'Test module is enabled.');
|
||||
|
||||
// Ensure that modules are not enabled.
|
||||
|
|
@ -108,7 +108,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
try {
|
||||
$result = $this->moduleInstaller()->install(array('color'));
|
||||
$result = $this->moduleInstaller()->install(['color']);
|
||||
$this->fail(t('ModuleInstaller::install() throws an exception if dependencies are missing.'));
|
||||
}
|
||||
catch (MissingDependencyException $e) {
|
||||
|
|
@ -122,7 +122,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
\Drupal::state()->set('module_test.dependency', 'dependency');
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
$result = $this->moduleInstaller()->install(array('color'));
|
||||
$result = $this->moduleInstaller()->install(['color']);
|
||||
$this->assertTrue($result, 'ModuleInstaller::install() returns the correct value.');
|
||||
|
||||
// Verify that the fake dependency chain was installed.
|
||||
|
|
@ -132,20 +132,20 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
$this->assertTrue($this->moduleHandler()->moduleExists('color'), 'Module installation with dependencies succeeded.');
|
||||
|
||||
// Verify that the modules were enabled in the correct order.
|
||||
$module_order = \Drupal::state()->get('module_test.install_order') ?: array();
|
||||
$this->assertEqual($module_order, array('help', 'config', 'color'));
|
||||
$module_order = \Drupal::state()->get('module_test.install_order') ?: [];
|
||||
$this->assertEqual($module_order, ['help', 'config', 'color']);
|
||||
|
||||
// Uninstall all three modules explicitly, but in the incorrect order,
|
||||
// and make sure that ModuleInstaller::uninstall() uninstalled them in the
|
||||
// correct sequence.
|
||||
$result = $this->moduleInstaller()->uninstall(array('config', 'help', 'color'));
|
||||
$result = $this->moduleInstaller()->uninstall(['config', 'help', 'color']);
|
||||
$this->assertTrue($result, 'ModuleInstaller::uninstall() returned TRUE.');
|
||||
|
||||
foreach (array('color', 'config', 'help') as $module) {
|
||||
foreach (['color', 'config', 'help'] as $module) {
|
||||
$this->assertEqual(drupal_get_installed_schema_version($module), SCHEMA_UNINSTALLED, "$module module was uninstalled.");
|
||||
}
|
||||
$uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: array();
|
||||
$this->assertEqual($uninstalled_modules, array('color', 'config', 'help'), 'Modules were uninstalled in the correct order.');
|
||||
$uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: [];
|
||||
$this->assertEqual($uninstalled_modules, ['color', 'config', 'help'], 'Modules were uninstalled in the correct order.');
|
||||
|
||||
// Enable Color module again, which should enable both the Config module and
|
||||
// Help module. But, this time do it with Config module declaring a
|
||||
|
|
@ -154,7 +154,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
\Drupal::state()->set('module_test.dependency', 'version dependency');
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
$result = $this->moduleInstaller()->install(array('color'));
|
||||
$result = $this->moduleInstaller()->install(['color']);
|
||||
$this->assertTrue($result, 'ModuleInstaller::install() returns the correct value.');
|
||||
|
||||
// Verify that the fake dependency chain was installed.
|
||||
|
|
@ -164,14 +164,14 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
$this->assertTrue($this->moduleHandler()->moduleExists('color'), 'Module installation with version dependencies succeeded.');
|
||||
|
||||
// Finally, verify that the modules were enabled in the correct order.
|
||||
$enable_order = \Drupal::state()->get('module_test.install_order') ?: array();
|
||||
$this->assertIdentical($enable_order, array('help', 'config', 'color'));
|
||||
$enable_order = \Drupal::state()->get('module_test.install_order') ?: [];
|
||||
$this->assertIdentical($enable_order, ['help', 'config', 'color']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uninstalling a module that is a "dependency" of a profile.
|
||||
*/
|
||||
function testUninstallProfileDependency() {
|
||||
public function testUninstallProfileDependency() {
|
||||
$profile = 'minimal';
|
||||
$dependency = 'dblog';
|
||||
$this->setSetting('install_profile', $profile);
|
||||
|
|
@ -180,23 +180,23 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
// yet have any cached way to retrieve its location.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
drupal_get_filename('profile', $profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
|
||||
$this->enableModules(array('module_test', $profile));
|
||||
$this->enableModules(['module_test', $profile]);
|
||||
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
$data = system_rebuild_module_data();
|
||||
$this->assertTrue(isset($data[$profile]->requires[$dependency]));
|
||||
|
||||
$this->moduleInstaller()->install(array($dependency));
|
||||
$this->moduleInstaller()->install([$dependency]);
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists($dependency));
|
||||
|
||||
// Uninstall the profile module "dependency".
|
||||
$result = $this->moduleInstaller()->uninstall(array($dependency));
|
||||
$result = $this->moduleInstaller()->uninstall([$dependency]);
|
||||
$this->assertTrue($result, 'ModuleInstaller::uninstall() returns TRUE.');
|
||||
$this->assertFalse($this->moduleHandler()->moduleExists($dependency));
|
||||
$this->assertEqual(drupal_get_installed_schema_version($dependency), SCHEMA_UNINSTALLED, "$dependency module was uninstalled.");
|
||||
|
||||
// Verify that the installation profile itself was not uninstalled.
|
||||
$uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: array();
|
||||
$uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: [];
|
||||
$this->assertTrue(in_array($dependency, $uninstalled_modules), "$dependency module is in the list of uninstalled modules.");
|
||||
$this->assertFalse(in_array($profile, $uninstalled_modules), 'The installation profile is not in the list of uninstalled modules.');
|
||||
}
|
||||
|
|
@ -204,8 +204,8 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
/**
|
||||
* Tests uninstalling a module that has content.
|
||||
*/
|
||||
function testUninstallContentDependency() {
|
||||
$this->enableModules(array('module_test', 'entity_test', 'text', 'user', 'help'));
|
||||
public function testUninstallContentDependency() {
|
||||
$this->enableModules(['module_test', 'entity_test', 'text', 'user', 'help']);
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('entity_test'), 'Test module is enabled.');
|
||||
$this->assertTrue($this->moduleHandler()->moduleExists('module_test'), 'Test module is enabled.');
|
||||
|
||||
|
|
@ -224,13 +224,13 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
||||
// Create an entity so that the modules can not be disabled.
|
||||
$entity = EntityTest::create(array('name' => $this->randomString()));
|
||||
$entity = EntityTest::create(['name' => $this->randomString()]);
|
||||
$entity->save();
|
||||
|
||||
// Uninstalling entity_test is not possible when there is content.
|
||||
try {
|
||||
$message = 'ModuleInstaller::uninstall() throws ModuleUninstallValidatorException upon uninstalling a module which does not pass validation.';
|
||||
$this->moduleInstaller()->uninstall(array('entity_test'));
|
||||
$this->moduleInstaller()->uninstall(['entity_test']);
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ModuleUninstallValidatorException $e) {
|
||||
|
|
@ -240,7 +240,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
// Uninstalling help needs entity_test to be un-installable.
|
||||
try {
|
||||
$message = 'ModuleInstaller::uninstall() throws ModuleUninstallValidatorException upon uninstalling a module which does not pass validation.';
|
||||
$this->moduleInstaller()->uninstall(array('help'));
|
||||
$this->moduleInstaller()->uninstall(['help']);
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (ModuleUninstallValidatorException $e) {
|
||||
|
|
@ -250,7 +250,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
// Deleting the entity.
|
||||
$entity->delete();
|
||||
|
||||
$result = $this->moduleInstaller()->uninstall(array('help'));
|
||||
$result = $this->moduleInstaller()->uninstall(['help']);
|
||||
$this->assertTrue($result, 'ModuleInstaller::uninstall() returns TRUE.');
|
||||
$this->assertEqual(drupal_get_installed_schema_version('entity_test'), SCHEMA_UNINSTALLED, "entity_test module was uninstalled.");
|
||||
}
|
||||
|
|
@ -258,7 +258,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
/**
|
||||
* Tests whether the correct module metadata is returned.
|
||||
*/
|
||||
function testModuleMetaData() {
|
||||
public function testModuleMetaData() {
|
||||
// Generate the list of available modules.
|
||||
$modules = system_rebuild_module_data();
|
||||
// Check that the mtime field exists for the system module.
|
||||
|
|
@ -289,7 +289,7 @@ class ModuleHandlerTest extends KernelTestBase {
|
|||
/**
|
||||
* Tests whether the correct theme metadata is returned.
|
||||
*/
|
||||
function testThemeMetaData() {
|
||||
public function testThemeMetaData() {
|
||||
// Generate the list of available themes.
|
||||
$themes = \Drupal::service('theme_handler')->rebuildThemeData();
|
||||
// Check that the mtime field exists for the bartik theme.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,16 @@ class FormElementLabelTest extends KernelTestBase {
|
|||
$this->render($render_array);
|
||||
$elements = $this->xpath($css_selector_converter->toXPath('.kitten'));
|
||||
$this->assertCount(1, $elements);
|
||||
|
||||
// Add label attributes to a form element.
|
||||
$render_array = [
|
||||
'#type' => 'textfield',
|
||||
'#label_attributes' => ['class' => ['meow']],
|
||||
'#title' => 'Kitten sounds',
|
||||
];
|
||||
$this->render($render_array);
|
||||
$elements = $this->xpath($css_selector_converter->toXPath('label.meow'));
|
||||
$this->assertCount(1, $elements);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class MigrateDateFormatTest extends MigrateDrupal6TestBase {
|
|||
// Test that we can re-import using the EntityDateFormat destination.
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('variable')
|
||||
->fields(array('value' => serialize('\S\H\O\R\T d/m/Y - H:i')))
|
||||
->fields(['value' => serialize('\S\H\O\R\T d/m/Y - H:i')])
|
||||
->condition('name', 'date_format_short')
|
||||
->execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,14 +36,14 @@ EOT;
|
|||
// Test that we can re-import using the ConfigEntityBase destination.
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('menu_custom')
|
||||
->fields(array('title' => 'Home Navigation'))
|
||||
->fields(['title' => 'Home Navigation'])
|
||||
->condition('menu_name', 'navigation')
|
||||
->execute();
|
||||
|
||||
$migration = $this->getMigration('d6_menu');
|
||||
\Drupal::database()
|
||||
->truncate($migration->getIdMap()->mapTableName())
|
||||
->execute();
|
||||
->truncate($migration->getIdMap()->mapTableName())
|
||||
->execute();
|
||||
$this->executeMigration($migration);
|
||||
|
||||
$navigation_menu = Menu::load('navigation');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrates various configuration objects owned by the System module.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemConfigurationTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['action', 'file', 'system'];
|
||||
|
||||
protected $expectedConfig = [
|
||||
'system.cron' => [
|
||||
'threshold' => [
|
||||
'requirements_warning' => 172800,
|
||||
'requirements_error' => 1209600,
|
||||
],
|
||||
// logging is not handled by the migration.
|
||||
'logging' => 1,
|
||||
],
|
||||
'system.date' => [
|
||||
// country is not handled by the migration.
|
||||
'country' => [
|
||||
'default' => '',
|
||||
],
|
||||
'first_day' => 4,
|
||||
// timezone is not handled by the migration.
|
||||
'timezone' => [
|
||||
'default' => 'Europe/Paris',
|
||||
'user' => [
|
||||
'configurable' => FALSE,
|
||||
// warn is not handled by the migration.
|
||||
'warn' => FALSE,
|
||||
// default is not handled by the migration.
|
||||
'default' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
'system.file' => [
|
||||
'allow_insecure_uploads' => TRUE,
|
||||
// default_scheme is not handled by the migration.
|
||||
'default_scheme' => 'public',
|
||||
'path' => [
|
||||
'temporary' => 'files/temp',
|
||||
],
|
||||
// temporary_maximum_age is not handled by the migration.
|
||||
'temporary_maximum_age' => 21600,
|
||||
],
|
||||
'system.image.gd' => [
|
||||
'jpeg_quality' => 75,
|
||||
],
|
||||
'system.image' => [
|
||||
'toolkit' => 'gd',
|
||||
],
|
||||
'system.logging' => [
|
||||
'error_level' => 'some',
|
||||
],
|
||||
'system.maintenance' => [
|
||||
'message' => 'Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.',
|
||||
// langcode is not handled by the migration.
|
||||
'langcode' => 'en',
|
||||
],
|
||||
'system.performance' => [
|
||||
'cache' => [
|
||||
'page' => [
|
||||
'max_age' => 0,
|
||||
],
|
||||
],
|
||||
'css' => [
|
||||
'preprocess' => FALSE,
|
||||
// gzip is not handled by the migration.
|
||||
'gzip' => TRUE,
|
||||
],
|
||||
// fast_404 is not handled by the migration.
|
||||
'fast_404' => [
|
||||
'enabled' => TRUE,
|
||||
'paths' => '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i',
|
||||
'exclude_paths' => '/\/(?:styles|imagecache)\//',
|
||||
'html' => '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>',
|
||||
],
|
||||
'js' => [
|
||||
'preprocess' => FALSE,
|
||||
// gzip is not handled by the migration.
|
||||
'gzip' => TRUE,
|
||||
],
|
||||
// stale_file_threshold is not handled by the migration.
|
||||
'stale_file_threshold' => 2592000,
|
||||
'response' => [
|
||||
'gzip' => TRUE,
|
||||
],
|
||||
],
|
||||
'system.rss' => [
|
||||
// channel is not handled by the migration.
|
||||
'channel' => [
|
||||
'description' => '',
|
||||
],
|
||||
'items' => [
|
||||
'limit' => 10,
|
||||
'view_mode' => 'title',
|
||||
],
|
||||
// langcode is not handled by the migration.
|
||||
'langcode' => 'en',
|
||||
],
|
||||
'system.site' => [
|
||||
// uuid is not handled by the migration.
|
||||
'uuid' => '',
|
||||
'name' => 'site_name',
|
||||
'mail' => 'site_mail@example.com',
|
||||
'slogan' => 'Migrate rocks',
|
||||
'page' => [
|
||||
'403' => '/user',
|
||||
'404' => '/page-not-found',
|
||||
'front' => '/node',
|
||||
],
|
||||
'admin_compact_mode' => FALSE,
|
||||
'weight_select_max' => 100,
|
||||
// langcode and default_langcode are not handled by the migration.
|
||||
'langcode' => 'en',
|
||||
'default_langcode' => 'en',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$migrations = [
|
||||
'd6_system_cron',
|
||||
'd6_system_date',
|
||||
'd6_system_file',
|
||||
'system_image_gd',
|
||||
'system_image',
|
||||
'system_logging',
|
||||
'system_maintenance',
|
||||
'd6_system_performance',
|
||||
'system_rss',
|
||||
'system_site',
|
||||
];
|
||||
$this->executeMigrations($migrations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that all expected configuration gets migrated.
|
||||
*/
|
||||
public function testConfigurationMigration() {
|
||||
foreach ($this->expectedConfig as $config_id => $values) {
|
||||
$actual = \Drupal::config($config_id)->get();
|
||||
unset($actual['_core']);
|
||||
$this->assertSame($actual, $values, $config_id . ' matches expected values.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade cron variable to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemCronTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_cron');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (cron) variables to system.cron.yml.
|
||||
*/
|
||||
public function testSystemCron() {
|
||||
$config = $this->config('system.cron');
|
||||
$this->assertIdentical(172800, $config->get('threshold.requirements_warning'));
|
||||
$this->assertIdentical(1209600, $config->get('threshold.requirements_error'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade date time variables to system.date config
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemDateTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of user variables to system_date.yml.
|
||||
*/
|
||||
public function testSystemDate() {
|
||||
$config = $this->config('system.date');
|
||||
$this->assertIdentical(4, $config->get('first_day'));
|
||||
$this->assertIdentical(FALSE, $config->get('timezone.user.configurable'));
|
||||
$this->assertIdentical("Europe/Paris", $config->get('timezone.default'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemFileTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_file');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (file) variables to system.file.yml.
|
||||
*/
|
||||
public function testSystemFile() {
|
||||
$config = \Drupal::configFactory()->getEditable('system.file');
|
||||
$this->assertIdentical('files/temp', $config->get('path.temporary'));
|
||||
$this->assertIdentical(TRUE, $config->get('allow_insecure_uploads'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade image gd variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemImageGdTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('system_image_gd');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (image GD) variables to system.image.gd.yml.
|
||||
*/
|
||||
public function testSystemImageGd() {
|
||||
$config = $this->config('system.image.gd');
|
||||
$this->assertIdentical(75, $config->get('jpeg_quality'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade image variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemImageTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('system_image');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (image) variables to system.image.yml.
|
||||
*/
|
||||
public function testSystemImage() {
|
||||
$config = $this->config('system.image');
|
||||
$this->assertIdentical('gd', $config->get('toolkit'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade error_level variable to system.logging.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemLoggingTest extends MigrateDrupal6TestBase {
|
||||
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('system_logging');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system error_level variables to system.logging.yml.
|
||||
*/
|
||||
public function testSystemLogging() {
|
||||
$config = $this->config('system.logging');
|
||||
$this->assertIdentical('some', $config->get('error_level'));
|
||||
$this->assertConfigSchema(\Drupal::service('config.typed'), 'system.logging', $config->get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade maintenance variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemMaintenanceTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('system_maintenance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (maintenance) variables to system.maintenance.yml.
|
||||
*/
|
||||
public function testSystemMaintenance() {
|
||||
$config = $this->config('system.maintenance');
|
||||
$this->assertIdentical('Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.', $config->get('message'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade performance variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemPerformanceTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_system_performance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (Performance) variables to system.performance.yml.
|
||||
*/
|
||||
public function testSystemPerformance() {
|
||||
$config = $this->config('system.performance');
|
||||
$this->assertIdentical(FALSE, $config->get('css.preprocess'));
|
||||
$this->assertIdentical(FALSE, $config->get('js.preprocess'));
|
||||
$this->assertIdentical(0, $config->get('cache.page.max_age'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade rss variable to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemRssTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('system_rss');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (rss) variables to system.rss.yml.
|
||||
*/
|
||||
public function testSystemRss() {
|
||||
$config = $this->config('system.rss');
|
||||
$this->assertIdentical(10, $config->get('items.limit'));
|
||||
$this->assertIdentical('title', $config->get('items.view_mode'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade site variables to system.*.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateSystemSiteTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('system_site');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of system (site) variables to system.site.yml.
|
||||
*/
|
||||
public function testSystemSite() {
|
||||
$config = $this->config('system.site');
|
||||
$this->assertIdentical('site_name', $config->get('name'));
|
||||
$this->assertIdentical('site_mail@example.com', $config->get('mail'));
|
||||
$this->assertIdentical('Migrate rocks', $config->get('slogan'));
|
||||
$this->assertIdentical('/user', $config->get('page.403'));
|
||||
$this->assertIdentical('/page-not-found', $config->get('page.404'));
|
||||
$this->assertIdentical('/node', $config->get('page.front'));
|
||||
$this->assertIdentical(FALSE, $config->get('admin_compact_mode'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -51,14 +51,14 @@ class MigrateMenuTest extends MigrateDrupal7TestBase {
|
|||
// Test that we can re-import using the ConfigEntityBase destination.
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('menu_custom')
|
||||
->fields(array('title' => 'Home Navigation'))
|
||||
->fields(['title' => 'Home Navigation'])
|
||||
->condition('menu_name', 'navigation')
|
||||
->execute();
|
||||
|
||||
$migration = $this->getMigration('d7_menu');
|
||||
\Drupal::database()
|
||||
->truncate($migration->getIdMap()->mapTableName())
|
||||
->execute();
|
||||
->truncate($migration->getIdMap()->mapTableName())
|
||||
->execute();
|
||||
$this->executeMigration($migration);
|
||||
|
||||
$navigation_menu = Menu::load('tools');
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase {
|
|||
'requirements_warning' => 172800,
|
||||
'requirements_error' => 1209600,
|
||||
],
|
||||
'logging' => 1,
|
||||
],
|
||||
'system.date' => [
|
||||
'country' => [
|
||||
|
|
|
|||
|
|
@ -57,19 +57,19 @@ class PhpStorageFactoryTest extends KernelTestBase {
|
|||
$this->assertTrue($php instanceof MockPhpStorage, 'A MockPhpStorage instance was returned from overridden settings.');
|
||||
|
||||
// Test that the name is used for the bin when it is NULL.
|
||||
$this->setSettings('test', array('bin' => NULL));
|
||||
$this->setSettings('test', ['bin' => NULL]);
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.');
|
||||
$this->assertSame('test', $php->getConfigurationValue('bin'), 'Name value was used for bin.');
|
||||
|
||||
// Test that a default directory is set if it's empty.
|
||||
$this->setSettings('test', array('directory' => NULL));
|
||||
$this->setSettings('test', ['directory' => NULL]);
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.');
|
||||
$this->assertSame(PublicStream::basePath() . '/php', $php->getConfigurationValue('directory'), 'Default file directory was used.');
|
||||
|
||||
// Test that a default storage class is set if it's empty.
|
||||
$this->setSettings('test', array('class' => NULL));
|
||||
$this->setSettings('test', ['class' => NULL]);
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertTrue($php instanceof MTimeProtectedFileStorage, 'An MTimeProtectedFileStorage instance was returned from overridden settings with no class.');
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ class PhpStorageFactoryTest extends KernelTestBase {
|
|||
$this->assertNotEquals('mock hash salt', $php->getConfigurationValue('secret'), 'The default secret is not used if a secret is set in the overridden settings.');
|
||||
|
||||
// Test that a default secret is set if it's empty.
|
||||
$this->setSettings('test', array('secret' => NULL));
|
||||
$this->setSettings('test', ['secret' => NULL]);
|
||||
$php = PhpStorageFactory::get('test');
|
||||
$this->assertSame('mock hash salt', $php->getConfigurationValue('secret'), 'The default secret is used if one is not set in the overridden settings.');
|
||||
}
|
||||
|
|
@ -92,13 +92,13 @@ class PhpStorageFactoryTest extends KernelTestBase {
|
|||
* @param array $configuration
|
||||
* An array of configuration to set. Will be merged with default values.
|
||||
*/
|
||||
protected function setSettings($name = 'default', array $configuration = array()) {
|
||||
$settings['php_storage'][$name] = $configuration + array(
|
||||
protected function setSettings($name = 'default', array $configuration = []) {
|
||||
$settings['php_storage'][$name] = $configuration + [
|
||||
'class' => 'Drupal\system\PhpStorage\MockPhpStorage',
|
||||
'directory' => 'tmp://',
|
||||
'secret' => $this->randomString(),
|
||||
'bin' => 'test',
|
||||
);
|
||||
];
|
||||
$settings['hash_salt'] = 'mock hash salt';
|
||||
new Settings($settings);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class ClassyTest extends KernelTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = array('system', 'twig_theme_test');
|
||||
public static $modules = ['system', 'twig_theme_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
@ -36,12 +36,12 @@ class ClassyTest extends KernelTestBase {
|
|||
/**
|
||||
* Test the classy theme.
|
||||
*/
|
||||
function testClassyTheme() {
|
||||
public function testClassyTheme() {
|
||||
drupal_set_message('An error occurred', 'error');
|
||||
drupal_set_message('But then something nice happened');
|
||||
$messages = array(
|
||||
$messages = [
|
||||
'#type' => 'status_messages',
|
||||
);
|
||||
];
|
||||
$this->render($messages);
|
||||
$this->assertNoText('custom-test-messages-class', 'The custom class attribute value added in the status messages preprocess function is not displayed as page content.');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Tests\system\Kernel\Scripts;
|
||||
|
||||
use Drupal\Core\Command\DbCommandBase;
|
||||
use Drupal\Core\Database\ConnectionNotDefinedException;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
|
@ -42,8 +43,6 @@ class DbCommandBaseTest extends KernelTestBase {
|
|||
|
||||
/**
|
||||
* Invalid database names will throw a useful exception.
|
||||
*
|
||||
* @expectedException \Drupal\Core\Database\ConnectionNotDefinedException
|
||||
*/
|
||||
public function testSpecifyDatabaseDoesNotExist() {
|
||||
$command = new DbCommandBaseTester();
|
||||
|
|
@ -51,6 +50,7 @@ class DbCommandBaseTest extends KernelTestBase {
|
|||
$command_tester->execute([
|
||||
'--database' => 'dne'
|
||||
]);
|
||||
$this->setExpectedException(ConnectionNotDefinedException::class);
|
||||
$command->getDatabaseConnection($command_tester->getInput());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ class DbImportCommandTest extends KernelTestBase {
|
|||
* @requires extension pdo_sqlite
|
||||
*/
|
||||
public function testDbImportCommand() {
|
||||
$connection_info = array(
|
||||
$connection_info = [
|
||||
'driver' => 'sqlite',
|
||||
'database' => ':memory:',
|
||||
);
|
||||
];
|
||||
Database::addConnectionInfo($this->databasePrefix, 'default', $connection_info);
|
||||
|
||||
$command = new DbImportCommand();
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class CronQueueTest extends KernelTestBase {
|
|||
$queue = $this->container->get('queue')->get('cron_queue_test_exception');
|
||||
|
||||
// Enqueue an item for processing.
|
||||
$queue->createItem(array($this->randomMachineName() => $this->randomMachineName()));
|
||||
$queue->createItem([$this->randomMachineName() => $this->randomMachineName()]);
|
||||
|
||||
// Run cron; the worker for this queue should throw an exception and handle
|
||||
// it.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use Drupal\KernelTests\KernelTestBase;
|
|||
*/
|
||||
class InfoAlterTest extends KernelTestBase {
|
||||
|
||||
public static $modules = array('system');
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* Tests that theme .info.yml data is rebuild after enabling a module.
|
||||
|
|
@ -20,13 +20,13 @@ class InfoAlterTest extends KernelTestBase {
|
|||
* hook_system_info_alter() is enabled. Also tests if core *_list() functions
|
||||
* return freshly altered info.
|
||||
*/
|
||||
function testSystemInfoAlter() {
|
||||
public function testSystemInfoAlter() {
|
||||
\Drupal::state()->set('module_required_test.hook_system_info_alter', TRUE);
|
||||
$info = system_rebuild_module_data();
|
||||
$this->assertFalse(isset($info['node']->info['required']), 'Before the module_required_test is installed the node module is not required.');
|
||||
|
||||
// Enable the test module.
|
||||
\Drupal::service('module_installer')->install(array('module_required_test'), FALSE);
|
||||
\Drupal::service('module_installer')->install(['module_required_test'], FALSE);
|
||||
$this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_required_test'), 'Test required module is enabled.');
|
||||
|
||||
$info = system_rebuild_module_data();
|
||||
|
|
|
|||
|
|
@ -29,25 +29,25 @@ class TokenReplaceKernelTest extends TokenReplaceKernelTestBase {
|
|||
*/
|
||||
public function testSystemTokenRecognition() {
|
||||
// Generate prefixes and suffixes for the token context.
|
||||
$tests = array(
|
||||
array('prefix' => 'this is the ', 'suffix' => ' site'),
|
||||
array('prefix' => 'this is the', 'suffix' => 'site'),
|
||||
array('prefix' => '[', 'suffix' => ']'),
|
||||
array('prefix' => '', 'suffix' => ']]]'),
|
||||
array('prefix' => '[[[', 'suffix' => ''),
|
||||
array('prefix' => ':[:', 'suffix' => '--]'),
|
||||
array('prefix' => '-[-', 'suffix' => ':]:'),
|
||||
array('prefix' => '[:', 'suffix' => ']'),
|
||||
array('prefix' => '[site:', 'suffix' => ':name]'),
|
||||
array('prefix' => '[site:', 'suffix' => ']'),
|
||||
);
|
||||
$tests = [
|
||||
['prefix' => 'this is the ', 'suffix' => ' site'],
|
||||
['prefix' => 'this is the', 'suffix' => 'site'],
|
||||
['prefix' => '[', 'suffix' => ']'],
|
||||
['prefix' => '', 'suffix' => ']]]'],
|
||||
['prefix' => '[[[', 'suffix' => ''],
|
||||
['prefix' => ':[:', 'suffix' => '--]'],
|
||||
['prefix' => '-[-', 'suffix' => ':]:'],
|
||||
['prefix' => '[:', 'suffix' => ']'],
|
||||
['prefix' => '[site:', 'suffix' => ':name]'],
|
||||
['prefix' => '[site:', 'suffix' => ']'],
|
||||
];
|
||||
|
||||
// Check if the token is recognized in each of the contexts.
|
||||
foreach ($tests as $test) {
|
||||
$input = $test['prefix'] . '[site:name]' . $test['suffix'];
|
||||
$expected = $test['prefix'] . 'Drupal' . $test['suffix'];
|
||||
$output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId()));
|
||||
$this->assertTrue($output == $expected, format_string('Token recognized in string %string', array('%string' => $input)));
|
||||
$output = $this->tokenService->replace($input, [], ['langcode' => $this->interfaceLanguage->getId()]);
|
||||
$this->assertTrue($output == $expected, format_string('Token recognized in string %string', ['%string' => $input]));
|
||||
}
|
||||
|
||||
// Test token replacement when the string contains no tokens.
|
||||
|
|
@ -67,12 +67,12 @@ class TokenReplaceKernelTest extends TokenReplaceKernelTestBase {
|
|||
|
||||
// Replace with the clear parameter, only the valid token should remain.
|
||||
$target = Html::escape($this->config('system.site')->get('name'));
|
||||
$result = $this->tokenService->replace($source, array(), array('langcode' => $this->interfaceLanguage->getId(), 'clear' => TRUE));
|
||||
$result = $this->tokenService->replace($source, [], ['langcode' => $this->interfaceLanguage->getId(), 'clear' => TRUE]);
|
||||
$this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.');
|
||||
|
||||
$target .= '[user:name]';
|
||||
$target .= '[bogus:token]';
|
||||
$result = $this->tokenService->replace($source, array(), array('langcode' => $this->interfaceLanguage->getId()));
|
||||
$result = $this->tokenService->replace($source, [], ['langcode' => $this->interfaceLanguage->getId()]);
|
||||
$this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.');
|
||||
}
|
||||
|
||||
|
|
@ -80,10 +80,10 @@ class TokenReplaceKernelTest extends TokenReplaceKernelTestBase {
|
|||
* Tests the generation of all system site information tokens.
|
||||
*/
|
||||
public function testSystemSiteTokenReplacement() {
|
||||
$url_options = array(
|
||||
$url_options = [
|
||||
'absolute' => TRUE,
|
||||
'language' => $this->interfaceLanguage,
|
||||
);
|
||||
];
|
||||
|
||||
$slogan = '<blink>Slogan</blink>';
|
||||
$safe_slogan = Xss::filterAdmin($slogan);
|
||||
|
|
@ -98,12 +98,12 @@ class TokenReplaceKernelTest extends TokenReplaceKernelTestBase {
|
|||
|
||||
|
||||
// Generate and test tokens.
|
||||
$tests = array();
|
||||
$tests = [];
|
||||
$tests['[site:name]'] = Html::escape($config->get('name'));
|
||||
$tests['[site:slogan]'] = $safe_slogan;
|
||||
$tests['[site:mail]'] = $config->get('mail');
|
||||
$tests['[site:url]'] = \Drupal::url('<front>', [], $url_options);
|
||||
$tests['[site:url-brief]'] = preg_replace(array('!^https?://!', '!/$!'), '', \Drupal::url('<front>', [], $url_options));
|
||||
$tests['[site:url-brief]'] = preg_replace(['!^https?://!', '!/$!'], '', \Drupal::url('<front>', [], $url_options));
|
||||
$tests['[site:login-url]'] = \Drupal::url('user.page', [], $url_options);
|
||||
|
||||
$base_bubbleable_metadata = new BubbleableMetadata();
|
||||
|
|
@ -122,7 +122,7 @@ class TokenReplaceKernelTest extends TokenReplaceKernelTestBase {
|
|||
|
||||
foreach ($tests as $input => $expected) {
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata);
|
||||
$output = $this->tokenService->replace($input, [], ['langcode' => $this->interfaceLanguage->getId()], $bubbleable_metadata);
|
||||
$this->assertEqual($output, $expected, new FormattableMarkup('System site information token %token replaced.', ['%token' => $input]));
|
||||
$this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
|
||||
}
|
||||
|
|
@ -136,21 +136,21 @@ class TokenReplaceKernelTest extends TokenReplaceKernelTestBase {
|
|||
$date = REQUEST_TIME - 3600;
|
||||
|
||||
// Generate and test tokens.
|
||||
$tests = array();
|
||||
$tests = [];
|
||||
$date_formatter = \Drupal::service('date.formatter');
|
||||
$tests['[date:short]'] = $date_formatter->format($date, 'short', '', NULL, $this->interfaceLanguage->getId());
|
||||
$tests['[date:medium]'] = $date_formatter->format($date, 'medium', '', NULL, $this->interfaceLanguage->getId());
|
||||
$tests['[date:long]'] = $date_formatter->format($date, 'long', '', NULL, $this->interfaceLanguage->getId());
|
||||
$tests['[date:custom:m/j/Y]'] = $date_formatter->format($date, 'custom', 'm/j/Y', NULL, $this->interfaceLanguage->getId());
|
||||
$tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, array('langcode' => $this->interfaceLanguage->getId()));
|
||||
$tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, ['langcode' => $this->interfaceLanguage->getId()]);
|
||||
$tests['[date:raw]'] = Xss::filter($date);
|
||||
|
||||
// Test to make sure that we generated something for each token.
|
||||
$this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
|
||||
|
||||
foreach ($tests as $input => $expected) {
|
||||
$output = $this->tokenService->replace($input, array('date' => $date), array('langcode' => $this->interfaceLanguage->getId()));
|
||||
$this->assertEqual($output, $expected, format_string('Date token %token replaced.', array('%token' => $input)));
|
||||
$output = $this->tokenService->replace($input, ['date' => $date], ['langcode' => $this->interfaceLanguage->getId()]);
|
||||
$this->assertEqual($output, $expected, format_string('Date token %token replaced.', ['%token' => $input]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ abstract class TokenReplaceKernelTestBase extends EntityKernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system');
|
||||
public static $modules = ['system'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Install default system configuration.
|
||||
$this->installConfig(array('system'));
|
||||
$this->installConfig(['system']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
$this->interfaceLanguage = \Drupal::languageManager()->getCurrentLanguage();
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
|
||||
$this->requestMatcher = $this->getMock('\Symfony\Component\Routing\Matcher\RequestMatcherInterface');
|
||||
|
||||
$config_factory = $this->getConfigFactoryStub(array('system.site' => array('front' => 'test_frontpage')));
|
||||
$config_factory = $this->getConfigFactoryStub(['system.site' => ['front' => 'test_frontpage']]);
|
||||
|
||||
$this->pathProcessor = $this->getMock('\Drupal\Core\PathProcessor\InboundPathProcessorInterface');
|
||||
$this->context = $this->getMock('\Drupal\Core\Routing\RequestContext');
|
||||
|
|
@ -182,11 +182,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('matchRequest')
|
||||
->will($this->returnCallback(function(Request $request) use ($route_1) {
|
||||
if ($request->getPathInfo() == '/example') {
|
||||
return array(
|
||||
return [
|
||||
RouteObjectInterface::ROUTE_NAME => 'example',
|
||||
RouteObjectInterface::ROUTE_OBJECT => $route_1,
|
||||
'_raw_variables' => new ParameterBag(array()),
|
||||
);
|
||||
'_raw_variables' => new ParameterBag([]),
|
||||
];
|
||||
}
|
||||
}));
|
||||
|
||||
|
|
@ -218,18 +218,18 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('matchRequest')
|
||||
->will($this->returnCallback(function(Request $request) use ($route_1, $route_2) {
|
||||
if ($request->getPathInfo() == '/example/bar') {
|
||||
return array(
|
||||
return [
|
||||
RouteObjectInterface::ROUTE_NAME => 'example_bar',
|
||||
RouteObjectInterface::ROUTE_OBJECT => $route_1,
|
||||
'_raw_variables' => new ParameterBag(array()),
|
||||
);
|
||||
'_raw_variables' => new ParameterBag([]),
|
||||
];
|
||||
}
|
||||
elseif ($request->getPathInfo() == '/example') {
|
||||
return array(
|
||||
return [
|
||||
RouteObjectInterface::ROUTE_NAME => 'example',
|
||||
RouteObjectInterface::ROUTE_OBJECT => $route_2,
|
||||
'_raw_variables' => new ParameterBag(array()),
|
||||
);
|
||||
'_raw_variables' => new ParameterBag([]),
|
||||
];
|
||||
}
|
||||
}));
|
||||
|
||||
|
|
@ -286,11 +286,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
* @see \Drupal\Tests\system\Unit\Breadcrumbs\PathBasedBreadcrumbBuilderTest::testBuildWithException()
|
||||
*/
|
||||
public function providerTestBuildWithException() {
|
||||
return array(
|
||||
array('Drupal\Core\ParamConverter\ParamNotConvertedException', ''),
|
||||
array('Symfony\Component\Routing\Exception\MethodNotAllowedException', array()),
|
||||
array('Symfony\Component\Routing\Exception\ResourceNotFoundException', ''),
|
||||
);
|
||||
return [
|
||||
['Drupal\Core\ParamConverter\ParamNotConvertedException', ''],
|
||||
['Symfony\Component\Routing\Exception\MethodNotAllowedException', []],
|
||||
['Symfony\Component\Routing\Exception\ResourceNotFoundException', ''],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -310,7 +310,7 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
|
||||
$this->requestMatcher->expects($this->any())
|
||||
->method('matchRequest')
|
||||
->will($this->returnValue(array()));
|
||||
->will($this->returnValue([]));
|
||||
|
||||
$breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface'));
|
||||
|
||||
|
|
@ -348,11 +348,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase {
|
|||
->method('matchRequest')
|
||||
->will($this->returnCallback(function(Request $request) use ($route_1) {
|
||||
if ($request->getPathInfo() == '/user/1') {
|
||||
return array(
|
||||
return [
|
||||
RouteObjectInterface::ROUTE_NAME => 'user_page',
|
||||
RouteObjectInterface::ROUTE_OBJECT => $route_1,
|
||||
'_raw_variables' => new ParameterBag(array()),
|
||||
);
|
||||
'_raw_variables' => new ParameterBag([]),
|
||||
];
|
||||
}
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ class InstallTranslationFilePatternTest extends UnitTestCase {
|
|||
* @return array
|
||||
*/
|
||||
public function providerValidTranslationFiles() {
|
||||
return array(
|
||||
array('hu', 'drupal-8.0.0-alpha1.hu.po'),
|
||||
array('ta', 'drupal-8.10.10-beta12.ta.po'),
|
||||
array('hi', 'drupal-8.0.0.hi.po'),
|
||||
);
|
||||
return [
|
||||
['hu', 'drupal-8.0.0-alpha1.hu.po'],
|
||||
['ta', 'drupal-8.10.10-beta12.ta.po'],
|
||||
['hi', 'drupal-8.0.0.hi.po'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -64,13 +64,13 @@ class InstallTranslationFilePatternTest extends UnitTestCase {
|
|||
* @return array
|
||||
*/
|
||||
public function providerInvalidTranslationFiles() {
|
||||
return array(
|
||||
array('hu', 'drupal-alpha1-*-hu.po'),
|
||||
array('ta', 'drupal-beta12.ta'),
|
||||
array('hi', 'drupal-hi.po'),
|
||||
array('de', 'drupal-dummy-de.po'),
|
||||
array('hu', 'drupal-10.0.1.alpha1-hu.po'),
|
||||
);
|
||||
return [
|
||||
['hu', 'drupal-alpha1-*-hu.po'],
|
||||
['ta', 'drupal-beta12.ta'],
|
||||
['hi', 'drupal-hi.po'],
|
||||
['de', 'drupal-dummy-de.po'],
|
||||
['hu', 'drupal-10.0.1.alpha1-hu.po'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,20 +25,20 @@ class SystemLocalTasksTest extends LocalTaskIntegrationTestBase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->directoryList = array(
|
||||
$this->directoryList = [
|
||||
'system' => 'core/modules/system',
|
||||
);
|
||||
];
|
||||
|
||||
$this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
|
||||
|
||||
$theme = new Extension($this->root, 'theme', '/core/themes/bartik', 'bartik.info.yml');
|
||||
$theme->status = 1;
|
||||
$theme->info = array('name' => 'bartik');
|
||||
$theme->info = ['name' => 'bartik'];
|
||||
$this->themeHandler->expects($this->any())
|
||||
->method('listInfo')
|
||||
->will($this->returnValue(array(
|
||||
->will($this->returnValue([
|
||||
'bartik' => $theme,
|
||||
)));
|
||||
]));
|
||||
$this->themeHandler->expects($this->any())
|
||||
->method('hasUi')
|
||||
->with('bartik')
|
||||
|
|
@ -59,13 +59,13 @@ class SystemLocalTasksTest extends LocalTaskIntegrationTestBase {
|
|||
* Provides a list of routes to test.
|
||||
*/
|
||||
public function getSystemAdminRoutes() {
|
||||
return array(
|
||||
array('system.admin_content', array(array('system.admin_content'))),
|
||||
array('system.theme_settings_theme', array(
|
||||
array('system.themes_page', 'system.theme_settings'),
|
||||
array('system.theme_settings_global', 'system.theme_settings_theme:bartik'),
|
||||
)),
|
||||
);
|
||||
return [
|
||||
['system.admin_content', [['system.admin_content']]],
|
||||
['system.theme_settings_theme', [
|
||||
['system.themes_page', 'system.theme_settings'],
|
||||
['system.theme_settings_global', 'system.theme_settings_theme:bartik'],
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,21 +53,21 @@ class MachineNameControllerTest extends UnitTestCase {
|
|||
* - The expected content of the JSONresponse.
|
||||
*/
|
||||
public function providerTestMachineNameController() {
|
||||
$valid_data = array(
|
||||
array(array('text' => 'Bob', 'langcode' => 'en'), '"Bob"'),
|
||||
array(array('text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE), '"bob"'),
|
||||
array(array('text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Bob'), '"Alice"'),
|
||||
array(array('text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Tom'), '"Bob"'),
|
||||
array(array('text' => 'Äwesome', 'langcode' => 'en', 'lowercase' => TRUE), '"awesome"'),
|
||||
array(array('text' => 'Äwesome', 'langcode' => 'de', 'lowercase' => TRUE), '"aewesome"'),
|
||||
$valid_data = [
|
||||
[['text' => 'Bob', 'langcode' => 'en'], '"Bob"'],
|
||||
[['text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE], '"bob"'],
|
||||
[['text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Bob'], '"Alice"'],
|
||||
[['text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Tom'], '"Bob"'],
|
||||
[['text' => 'Äwesome', 'langcode' => 'en', 'lowercase' => TRUE], '"awesome"'],
|
||||
[['text' => 'Äwesome', 'langcode' => 'de', 'lowercase' => TRUE], '"aewesome"'],
|
||||
// Tests special characters replacement in the input text.
|
||||
array(array('text' => 'B?!"@\/-ob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.]+'), '"b_ob_e"'),
|
||||
[['text' => 'B?!"@\/-ob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.]+'], '"b_ob_e"'],
|
||||
// Tests @ character in the replace_pattern regex.
|
||||
array(array('text' => 'Bob@e\0', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.@]+'), '"bob@e_0"'),
|
||||
[['text' => 'Bob@e\0', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.@]+'], '"bob@e_0"'],
|
||||
// Tests null byte in the replace_pattern regex.
|
||||
array(array('text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"), '"bob"'),
|
||||
array(array('text' => 'Bob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"), '"fail()"'),
|
||||
);
|
||||
[['text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"], '"bob"'],
|
||||
[['text' => 'Bob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"], '"fail()"'],
|
||||
];
|
||||
|
||||
$valid_data = array_map(function ($data) {
|
||||
if (isset($data[0]['replace_pattern'])) {
|
||||
|
|
|
|||
Reference in a new issue