},
{
"name": "drupal/core",
- "version": "8.3.4",
+ "version": "8.3.7",
"source": {
"type": "git",
"url": "https://github.com/drupal/core.git",
- "reference": "f34eee7255142ab5416107972ef13d011f11e163"
+ "reference": "32f66ed9cc593f8e9ab0eaaaeff4cadbd859d5ff"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/drupal/core/zipball/f34eee7255142ab5416107972ef13d011f11e163",
- "reference": "f34eee7255142ab5416107972ef13d011f11e163",
+ "url": "https://api.github.com/repos/drupal/core/zipball/32f66ed9cc593f8e9ab0eaaaeff4cadbd859d5ff",
+ "reference": "32f66ed9cc593f8e9ab0eaaaeff4cadbd859d5ff",
"shasum": ""
},
"require": {
"GPL-2.0+"
],
"description": "Drupal is an open source content management platform powering millions of websites and applications.",
- "time": "2017-06-21T18:13:27+00:00"
+ "time": "2017-08-16T17:10:35+00:00"
},
{
"name": "drupal/crop",
"homepage": "https://www.drupal.org/project/security_review",
"support": {
"source": "http://cgit.drupalcode.org/security_review"
- },
- "time": "2016-10-20 15:43:48"
+ }
},
{
"name": "drupal/simple_sitemap",
"standards",
"syntax"
],
- "time": "2015-09-20 22:14:29"
+ "time": "2015-09-20T22:14:29+00:00"
},
{
"name": "guzzlehttp/guzzle",
"source": "http://cgit.drupalcode.org/layouter"
}
},
- {
- "name": "drupal/core",
- "version": "8.3.4",
- "version_normalized": "8.3.4.0",
- "source": {
- "type": "git",
- "url": "https://github.com/drupal/core.git",
- "reference": "f34eee7255142ab5416107972ef13d011f11e163"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/drupal/core/zipball/f34eee7255142ab5416107972ef13d011f11e163",
- "reference": "f34eee7255142ab5416107972ef13d011f11e163",
- "shasum": ""
- },
- "require": {
- "asm89/stack-cors": "~1.0",
- "composer/semver": "~1.0",
- "doctrine/annotations": "1.2.*",
- "doctrine/common": "^2.5",
- "easyrdf/easyrdf": "0.9.*",
- "egulias/email-validator": "1.2.*",
- "guzzlehttp/guzzle": "^6.2.1",
- "masterminds/html5": "~2.1",
- "paragonie/random_compat": "^1.0|^2.0",
- "php": ">=5.5.9",
- "stack/builder": "1.0.*",
- "symfony-cmf/routing": "~1.4",
- "symfony/class-loader": "~2.8",
- "symfony/console": "~2.8",
- "symfony/dependency-injection": "~2.8",
- "symfony/event-dispatcher": "~2.8",
- "symfony/http-foundation": "~2.8",
- "symfony/http-kernel": "~2.8",
- "symfony/polyfill-iconv": "~1.0",
- "symfony/process": "~2.8",
- "symfony/psr-http-message-bridge": "^1.0",
- "symfony/routing": "~2.8",
- "symfony/serializer": "~2.8",
- "symfony/translation": "~2.8",
- "symfony/validator": "~2.8",
- "symfony/yaml": "~2.8",
- "twig/twig": "^1.23.1",
- "zendframework/zend-diactoros": "~1.1",
- "zendframework/zend-feed": "~2.4"
- },
- "conflict": {
- "drush/drush": "<8.1.10"
- },
- "replace": {
- "drupal/action": "self.version",
- "drupal/aggregator": "self.version",
- "drupal/automated_cron": "self.version",
- "drupal/ban": "self.version",
- "drupal/bartik": "self.version",
- "drupal/basic_auth": "self.version",
- "drupal/big_pipe": "self.version",
- "drupal/block": "self.version",
- "drupal/block_content": "self.version",
- "drupal/block_place": "self.version",
- "drupal/book": "self.version",
- "drupal/breakpoint": "self.version",
- "drupal/ckeditor": "self.version",
- "drupal/classy": "self.version",
- "drupal/color": "self.version",
- "drupal/comment": "self.version",
- "drupal/config": "self.version",
- "drupal/config_translation": "self.version",
- "drupal/contact": "self.version",
- "drupal/content_moderation": "self.version",
- "drupal/content_translation": "self.version",
- "drupal/contextual": "self.version",
- "drupal/core-annotation": "self.version",
- "drupal/core-assertion": "self.version",
- "drupal/core-bridge": "self.version",
- "drupal/core-datetime": "self.version",
- "drupal/core-dependency-injection": "self.version",
- "drupal/core-diff": "self.version",
- "drupal/core-discovery": "self.version",
- "drupal/core-event-dispatcher": "self.version",
- "drupal/core-file-cache": "self.version",
- "drupal/core-filesystem": "self.version",
- "drupal/core-gettext": "self.version",
- "drupal/core-graph": "self.version",
- "drupal/core-http-foundation": "self.version",
- "drupal/core-php-storage": "self.version",
- "drupal/core-plugin": "self.version",
- "drupal/core-proxy-builder": "self.version",
- "drupal/core-render": "self.version",
- "drupal/core-serialization": "self.version",
- "drupal/core-transliteration": "self.version",
- "drupal/core-utility": "self.version",
- "drupal/core-uuid": "self.version",
- "drupal/datetime": "self.version",
- "drupal/datetime_range": "self.version",
- "drupal/dblog": "self.version",
- "drupal/dynamic_page_cache": "self.version",
- "drupal/editor": "self.version",
- "drupal/entity_reference": "self.version",
- "drupal/field": "self.version",
- "drupal/field_layout": "self.version",
- "drupal/field_ui": "self.version",
- "drupal/file": "self.version",
- "drupal/filter": "self.version",
- "drupal/forum": "self.version",
- "drupal/hal": "self.version",
- "drupal/help": "self.version",
- "drupal/history": "self.version",
- "drupal/image": "self.version",
- "drupal/inline_form_errors": "self.version",
- "drupal/language": "self.version",
- "drupal/layout_discovery": "self.version",
- "drupal/link": "self.version",
- "drupal/locale": "self.version",
- "drupal/menu_link_content": "self.version",
- "drupal/menu_ui": "self.version",
- "drupal/migrate": "self.version",
- "drupal/migrate_drupal": "self.version",
- "drupal/migrate_drupal_ui": "self.version",
- "drupal/minimal": "self.version",
- "drupal/node": "self.version",
- "drupal/options": "self.version",
- "drupal/outside_in": "self.version",
- "drupal/page_cache": "self.version",
- "drupal/path": "self.version",
- "drupal/quickedit": "self.version",
- "drupal/rdf": "self.version",
- "drupal/responsive_image": "self.version",
- "drupal/rest": "self.version",
- "drupal/search": "self.version",
- "drupal/serialization": "self.version",
- "drupal/seven": "self.version",
- "drupal/shortcut": "self.version",
- "drupal/simpletest": "self.version",
- "drupal/standard": "self.version",
- "drupal/stark": "self.version",
- "drupal/statistics": "self.version",
- "drupal/syslog": "self.version",
- "drupal/system": "self.version",
- "drupal/taxonomy": "self.version",
- "drupal/telephone": "self.version",
- "drupal/text": "self.version",
- "drupal/toolbar": "self.version",
- "drupal/tour": "self.version",
- "drupal/tracker": "self.version",
- "drupal/update": "self.version",
- "drupal/user": "self.version",
- "drupal/views": "self.version",
- "drupal/views_ui": "self.version",
- "drupal/workflows": "self.version"
- },
- "require-dev": {
- "behat/mink": "1.7.x-dev",
- "behat/mink-goutte-driver": "~1.2",
- "drupal/coder": "8.2.12",
- "jcalderonzumba/gastonjs": "~1.0.2",
- "jcalderonzumba/mink-phantomjs-driver": "~0.3.1",
- "mikey179/vfsstream": "~1.2",
- "phpunit/phpunit": ">=4.8.28 <5",
- "symfony/browser-kit": ">=2.8.13 <3.0",
- "symfony/css-selector": "~2.8"
- },
- "time": "2017-06-21T18:13:27+00:00",
- "type": "drupal-core",
- "installation-source": "dist",
- "autoload": {
- "psr-4": {
- "Drupal\\Core\\": "lib/Drupal/Core",
- "Drupal\\Component\\": "lib/Drupal/Component",
- "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver"
- },
- "classmap": [
- "lib/Drupal.php",
- "lib/Drupal/Component/Utility/Timer.php",
- "lib/Drupal/Component/Utility/Unicode.php",
- "lib/Drupal/Core/Database/Database.php",
- "lib/Drupal/Core/DrupalKernel.php",
- "lib/Drupal/Core/DrupalKernelInterface.php",
- "lib/Drupal/Core/Site/Settings.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "GPL-2.0+"
- ],
- "description": "Drupal is an open source content management platform powering millions of websites and applications."
- },
{
"name": "drupal-composer/drupal-scaffold",
"version": "2.3.0",
}
],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it"
+ },
+ {
+ "name": "drupal/core",
+ "version": "8.3.7",
+ "version_normalized": "8.3.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/drupal/core.git",
+ "reference": "32f66ed9cc593f8e9ab0eaaaeff4cadbd859d5ff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/drupal/core/zipball/32f66ed9cc593f8e9ab0eaaaeff4cadbd859d5ff",
+ "reference": "32f66ed9cc593f8e9ab0eaaaeff4cadbd859d5ff",
+ "shasum": ""
+ },
+ "require": {
+ "asm89/stack-cors": "~1.0",
+ "composer/semver": "~1.0",
+ "doctrine/annotations": "1.2.*",
+ "doctrine/common": "^2.5",
+ "easyrdf/easyrdf": "0.9.*",
+ "egulias/email-validator": "1.2.*",
+ "guzzlehttp/guzzle": "^6.2.1",
+ "masterminds/html5": "~2.1",
+ "paragonie/random_compat": "^1.0|^2.0",
+ "php": ">=5.5.9",
+ "stack/builder": "1.0.*",
+ "symfony-cmf/routing": "~1.4",
+ "symfony/class-loader": "~2.8",
+ "symfony/console": "~2.8",
+ "symfony/dependency-injection": "~2.8",
+ "symfony/event-dispatcher": "~2.8",
+ "symfony/http-foundation": "~2.8",
+ "symfony/http-kernel": "~2.8",
+ "symfony/polyfill-iconv": "~1.0",
+ "symfony/process": "~2.8",
+ "symfony/psr-http-message-bridge": "^1.0",
+ "symfony/routing": "~2.8",
+ "symfony/serializer": "~2.8",
+ "symfony/translation": "~2.8",
+ "symfony/validator": "~2.8",
+ "symfony/yaml": "~2.8",
+ "twig/twig": "^1.23.1",
+ "zendframework/zend-diactoros": "~1.1",
+ "zendframework/zend-feed": "~2.4"
+ },
+ "conflict": {
+ "drush/drush": "<8.1.10"
+ },
+ "replace": {
+ "drupal/action": "self.version",
+ "drupal/aggregator": "self.version",
+ "drupal/automated_cron": "self.version",
+ "drupal/ban": "self.version",
+ "drupal/bartik": "self.version",
+ "drupal/basic_auth": "self.version",
+ "drupal/big_pipe": "self.version",
+ "drupal/block": "self.version",
+ "drupal/block_content": "self.version",
+ "drupal/block_place": "self.version",
+ "drupal/book": "self.version",
+ "drupal/breakpoint": "self.version",
+ "drupal/ckeditor": "self.version",
+ "drupal/classy": "self.version",
+ "drupal/color": "self.version",
+ "drupal/comment": "self.version",
+ "drupal/config": "self.version",
+ "drupal/config_translation": "self.version",
+ "drupal/contact": "self.version",
+ "drupal/content_moderation": "self.version",
+ "drupal/content_translation": "self.version",
+ "drupal/contextual": "self.version",
+ "drupal/core-annotation": "self.version",
+ "drupal/core-assertion": "self.version",
+ "drupal/core-bridge": "self.version",
+ "drupal/core-datetime": "self.version",
+ "drupal/core-dependency-injection": "self.version",
+ "drupal/core-diff": "self.version",
+ "drupal/core-discovery": "self.version",
+ "drupal/core-event-dispatcher": "self.version",
+ "drupal/core-file-cache": "self.version",
+ "drupal/core-filesystem": "self.version",
+ "drupal/core-gettext": "self.version",
+ "drupal/core-graph": "self.version",
+ "drupal/core-http-foundation": "self.version",
+ "drupal/core-php-storage": "self.version",
+ "drupal/core-plugin": "self.version",
+ "drupal/core-proxy-builder": "self.version",
+ "drupal/core-render": "self.version",
+ "drupal/core-serialization": "self.version",
+ "drupal/core-transliteration": "self.version",
+ "drupal/core-utility": "self.version",
+ "drupal/core-uuid": "self.version",
+ "drupal/datetime": "self.version",
+ "drupal/datetime_range": "self.version",
+ "drupal/dblog": "self.version",
+ "drupal/dynamic_page_cache": "self.version",
+ "drupal/editor": "self.version",
+ "drupal/entity_reference": "self.version",
+ "drupal/field": "self.version",
+ "drupal/field_layout": "self.version",
+ "drupal/field_ui": "self.version",
+ "drupal/file": "self.version",
+ "drupal/filter": "self.version",
+ "drupal/forum": "self.version",
+ "drupal/hal": "self.version",
+ "drupal/help": "self.version",
+ "drupal/history": "self.version",
+ "drupal/image": "self.version",
+ "drupal/inline_form_errors": "self.version",
+ "drupal/language": "self.version",
+ "drupal/layout_discovery": "self.version",
+ "drupal/link": "self.version",
+ "drupal/locale": "self.version",
+ "drupal/menu_link_content": "self.version",
+ "drupal/menu_ui": "self.version",
+ "drupal/migrate": "self.version",
+ "drupal/migrate_drupal": "self.version",
+ "drupal/migrate_drupal_ui": "self.version",
+ "drupal/minimal": "self.version",
+ "drupal/node": "self.version",
+ "drupal/options": "self.version",
+ "drupal/outside_in": "self.version",
+ "drupal/page_cache": "self.version",
+ "drupal/path": "self.version",
+ "drupal/quickedit": "self.version",
+ "drupal/rdf": "self.version",
+ "drupal/responsive_image": "self.version",
+ "drupal/rest": "self.version",
+ "drupal/search": "self.version",
+ "drupal/serialization": "self.version",
+ "drupal/seven": "self.version",
+ "drupal/shortcut": "self.version",
+ "drupal/simpletest": "self.version",
+ "drupal/standard": "self.version",
+ "drupal/stark": "self.version",
+ "drupal/statistics": "self.version",
+ "drupal/syslog": "self.version",
+ "drupal/system": "self.version",
+ "drupal/taxonomy": "self.version",
+ "drupal/telephone": "self.version",
+ "drupal/text": "self.version",
+ "drupal/toolbar": "self.version",
+ "drupal/tour": "self.version",
+ "drupal/tracker": "self.version",
+ "drupal/update": "self.version",
+ "drupal/user": "self.version",
+ "drupal/views": "self.version",
+ "drupal/views_ui": "self.version",
+ "drupal/workflows": "self.version"
+ },
+ "require-dev": {
+ "behat/mink": "1.7.x-dev",
+ "behat/mink-goutte-driver": "~1.2",
+ "drupal/coder": "8.2.12",
+ "jcalderonzumba/gastonjs": "~1.0.2",
+ "jcalderonzumba/mink-phantomjs-driver": "~0.3.1",
+ "mikey179/vfsstream": "~1.2",
+ "phpunit/phpunit": ">=4.8.28 <5",
+ "symfony/browser-kit": ">=2.8.13 <3.0",
+ "symfony/css-selector": "~2.8"
+ },
+ "time": "2017-08-16T17:10:35+00:00",
+ "type": "drupal-core",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Drupal\\Core\\": "lib/Drupal/Core",
+ "Drupal\\Component\\": "lib/Drupal/Component",
+ "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver"
+ },
+ "classmap": [
+ "lib/Drupal.php",
+ "lib/Drupal/Component/Utility/Timer.php",
+ "lib/Drupal/Component/Utility/Unicode.php",
+ "lib/Drupal/Core/Database/Database.php",
+ "lib/Drupal/Core/DrupalKernel.php",
+ "lib/Drupal/Core/DrupalKernelInterface.php",
+ "lib/Drupal/Core/Site/Settings.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-2.0+"
+ ],
+ "description": "Drupal is an open source content management platform powering millions of websites and applications."
}
]
+Drupal 8.3.7, 2017-08-16
+------------------------
+- Fixed security issues. See SA-CORE-2017-004.
+
Drupal 8.3.4, 2017-06-21
------------------------
- Fixed security issues. See SA-CORE-2017-003.
directory within your web server's document root or your public HTML
directory, continue with this command:
- mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc drupal-x.y.z/.gitattributes /path/to/your/installation
+ mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc.json drupal-x.y.z/.gitattributes /path/to/your/installation
You can also download the latest version of Drupal using Git on the command
line and set up a repository by following the instructions at
(Framework Manager - Frontend)
- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
(Product Manager)
+- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
+ (Framework Manager)
- Roy Scholten 'yoroy' https://www.drupal.org/u/yoroy
(Product Manager)
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Database API
-- Larry Garfield 'Crell' https://www.drupal.org/u/crell
MySQL DB driver
- - Larry Garfield 'Crell' https://www.drupal.org/u/crell
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
PostgreSQL DB driver
Markup
- ?
+Menu
+- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
+- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
+
+Menu Link Content
+- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
+- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
+
+Menu UI
+- ?
+
Migrate
- Adam Globus-Hoenich 'phenaproxima' https://www.drupal.org/u/phenaproxima
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan
- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone
-Menu
-- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
-- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
-
-Menu Link Content
-- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
-- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
-
-Menu UI
-- ?
-
Node
- Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
Request Processing
-- Larry Garfield 'Crell' https://www.drupal.org/u/crell
+- ?
REST
-- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
Responsive Image
- Jelle Sebreghts 'Jelle_S' https://www.drupal.org/u/jelle_s
Routing
-- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Search
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude
+Workflows
+- Sam Becker 'Sam152' https://www.drupal.org/u/sam152
+
Topic maintainers
-----------------
*
* @section sec_dispatch Dispatching events
* To dispatch an event, call the
- * \Symfony\Component\EventDispatcher\EventDispatchInterface::dispatch() method
- * on the 'event_dispatcher' service (see the
+ * \Symfony\Component\EventDispatcher\EventDispatcherInterface::dispatch()
+ * method on the 'event_dispatcher' service (see the
* @link container Services topic @endlink for more information about how to
* interact with services). The first argument is the unique event name, which
* you should normally define as a constant in a separate static class (see
- { name: backend_overridable }
# @deprecated in Drupal 8.0.x and will be removed before 9.0.0. Use
# config.storage.sync instead.
+ # @see https://www.drupal.org/node/2574957
config.storage.staging:
class: Drupal\Core\Config\FileStorage
factory: Drupal\Core\Config\FileStorageFactory::getSync
*
* @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
* If the entity form display is available in configuration use:
- * @code
- * \Drupal::entityTypeManager()
- * ->getStorage('entity_form_display')
- * ->load($entity_type . '.' . $bundle . '.' . $form_mode);
- * @endcode
+ * @code
+ * \Drupal::entityTypeManager()
+ * ->getStorage('entity_form_display')
+ * ->load($entity_type . '.' . $bundle . '.' . $form_mode);
+ * @endcode
* When the entity form display is not available in configuration, you can
* create a new EntityFormDisplay object using:
- * @code
- * $values = array(
- * 'targetEntityType' => $entity_type,
- * 'bundle' => $bundle,
- * 'mode' => $form_mode,
- * 'status' => TRUE,
- * );
- * \Drupal::entityTypeManager()
- * ->getStorage('entity_form_display')
- * ->create($values);
- * @endcode
+ * @code
+ * $values = array(
+ * 'targetEntityType' => $entity_type,
+ * 'bundle' => $bundle,
+ * 'mode' => $form_mode,
+ * 'status' => TRUE,
+ * );
+ * \Drupal::entityTypeManager()
+ * ->getStorage('entity_form_display')
+ * ->create($values);
+ * @endcode
*
* @see \Drupal\Core\Entity\EntityStorageInterface::create()
* @see \Drupal\Core\Entity\EntityStorageInterface::load()
/**
* The current system version.
*/
- const VERSION = '8.3.4';
+ const VERSION = '8.3.7';
/**
* Core API compatibility.
* @link sanitization sanitization functions @endlink or the @link theme_render theme and render systems @endlink
* so that the output can can be themed, escaped, and altered properly.
*
+ * @see https://www.drupal.org/node/2549395
+ *
* @see TwigExtension::escapeFilter()
* @see twig_render_template()
* @see sanitization
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
* Instead, you should just check if a variable is an instance of
* \Drupal\Component\Render\MarkupInterface.
+ *
+ * @see https://www.drupal.org/node/2549395
*/
public static function isSafe($string, $strategy = 'html') {
return $string instanceof MarkupInterface;
* possible, \Drupal\Component\Utility\Html::escape() can be used in places
* where explicit escaping is needed.
*
+ * @see https://www.drupal.org/node/2549395
* @see drupal_validate_utf8()
*/
public static function checkPlain($text) {
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
* Use \Drupal\Component\Render\FormattableMarkup.
+ *
+ * @see https://www.drupal.org/node/2549395
*/
public static function format($string, array $args) {
return new FormattableMarkup($string, $args);
use CategorizingPluginManagerTrait {
getSortedDefinitions as traitGetSortedDefinitions;
- getGroupedDefinitions as traitGetGroupedDefinitions;
}
use ContextAwarePluginManagerTrait;
* {@inheritdoc}
*/
public function getSortedDefinitions(array $definitions = NULL) {
- // Sort the plugins first by category, then by label.
+ // Sort the plugins first by category, then by admin label.
$definitions = $this->traitGetSortedDefinitions($definitions, 'admin_label');
// Do not display the 'broken' plugin in the UI.
unset($definitions['broken']);
return $definitions;
}
- /**
- * {@inheritdoc}
- */
- public function getGroupedDefinitions(array $definitions = NULL) {
- $definitions = $this->traitGetGroupedDefinitions($definitions, 'admin_label');
- // Do not display the 'broken' plugin in the UI.
- unset($definitions[$this->t('Block')]['broken']);
- return $definitions;
- }
-
/**
* {@inheritdoc}
*/
}
$data = array_merge($cache->data, $data);
}
+ elseif ($this->cacheCreated) {
+ // Getting here indicates that there was a cache entry at the
+ // beginning of the request, but now it's gone (some other process
+ // must have cleared it). We back out to prevent corrupting the cache
+ // with incomplete data, since we won't be able to properly merge
+ // the existing cache data from earlier with the new data.
+ // A future request will properly hydrate the cache from scratch.
+ if ($lock) {
+ $this->lock->release($lock_name);
+ }
+ return;
+ }
// Remove keys marked for deletion.
foreach ($this->keysToRemove as $delete_key) {
unset($data[$delete_key]);
*
* @param $conjunction
* - AND (default): this is the equivalent of andConditionGroup().
- * - OR: this is the equivalent of andConditionGroup().
+ * - OR: this is the equivalent of orConditionGroup().
*
* @return \Drupal\Core\Database\Query\ConditionInterface
* An object holding a group of conditions.
$operation = 'view';
}
- if (($return = $this->getCache($entity->uuid(), $operation, $langcode, $account)) !== NULL) {
+ // If an entity does not have a UUID, either from not being set or from not
+ // having them, use the 'entity type:ID' pattern as the cache $cid.
+ $cid = $entity->uuid() ?: $entity->getEntityTypeId() . ':' . $entity->id();
+
+ // If the entity is revisionable, then append the revision ID to allow
+ // individual revisions to have specific access control and be cached
+ // separately.
+ if ($entity instanceof RevisionableInterface) {
+ /** @var $entity \Drupal\Core\Entity\RevisionableInterface */
+ $cid .= ':' . $entity->getRevisionId();
+ }
+
+ if (($return = $this->getCache($cid, $operation, $langcode, $account)) !== NULL) {
// Cache hit, no work necessary.
return $return_as_object ? $return : $return->isAllowed();
}
if (!$return->isForbidden()) {
$return = $return->orIf($this->checkAccess($entity, $operation, $account));
}
- $result = $this->setCache($return, $entity->uuid(), $operation, $langcode, $account);
+ $result = $this->setCache($return, $cid, $operation, $langcode, $account);
return $return_as_object ? $result : $result->isAllowed();
}
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::clearCachedDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function clearCachedDefinitions() {
$this->container->get('entity_type.manager')->clearCachedDefinitions();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getDefinition()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getDefinition($entity_type_id, $exception_on_invalid = TRUE) {
return $this->container->get('entity_type.manager')->getDefinition($entity_type_id, $exception_on_invalid);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::hasHandler()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function hasHandler($entity_type, $handler_type) {
return $this->container->get('entity_type.manager')->hasHandler($entity_type, $handler_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage() instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getStorage($entity_type) {
return $this->container->get('entity_type.manager')->getStorage($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getListBuilder()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getListBuilder($entity_type) {
return $this->container->get('entity_type.manager')->getListBuilder($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getFormObject()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFormObject($entity_type, $operation) {
return $this->container->get('entity_type.manager')->getFormObject($entity_type, $operation);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getRouteProviders()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getRouteProviders($entity_type) {
return $this->container->get('entity_type.manager')->getRouteProviders($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getViewBuilder()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getViewBuilder($entity_type) {
return $this->container->get('entity_type.manager')->getViewBuilder($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getAccessControlHandler()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getAccessControlHandler($entity_type) {
return $this->container->get('entity_type.manager')->getAccessControlHandler($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getHandler() instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getHandler($entity_type, $handler_type) {
return $this->container->get('entity_type.manager')->getHandler($entity_type, $handler_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::createHandlerInstance()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function createHandlerInstance($class, EntityTypeInterface $definition = NULL) {
return $this->container->get('entity_type.manager')->createHandlerInstance($class, $definition);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::getBaseFieldDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getBaseFieldDefinitions($entity_type_id) {
return $this->container->get('entity_field.manager')->getBaseFieldDefinitions($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::getFieldDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFieldDefinitions($entity_type_id, $bundle) {
return $this->container->get('entity_field.manager')->getFieldDefinitions($entity_type_id, $bundle);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::getFieldStorageDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFieldStorageDefinitions($entity_type_id) {
return $this->container->get('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::setFieldMap()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function setFieldMap(array $field_map) {
return $this->container->get('entity_field.manager')->setFieldMap($field_map);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::getFieldMap()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFieldMap() {
return $this->container->get('entity_field.manager')->getFieldMap();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::getFieldMapByFieldType()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFieldMapByFieldType($field_type) {
return $this->container->get('entity_field.manager')->getFieldMapByFieldType($field_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Field\FieldDefinitionListenerInterface::onFieldDefinitionCreate()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onFieldDefinitionCreate(FieldDefinitionInterface $field_definition) {
$this->container->get('field_definition.listener')->onFieldDefinitionCreate($field_definition);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Field\FieldDefinitionListenerInterface::onFieldDefinitionUpdate()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onFieldDefinitionUpdate(FieldDefinitionInterface $field_definition, FieldDefinitionInterface $original) {
$this->container->get('field_definition.listener')->onFieldDefinitionUpdate($field_definition, $original);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Field\FieldDefinitionListenerInterface::onFieldDefinitionDelete()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onFieldDefinitionDelete(FieldDefinitionInterface $field_definition) {
$this->container->get('field_definition.listener')->onFieldDefinitionDelete($field_definition);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityFieldManagerInterface::clearCachedFieldDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function clearCachedFieldDefinitions() {
$this->container->get('entity_field.manager')->clearCachedFieldDefinitions();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeBundleManagerInterface::clearCachedBundles()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function clearCachedBundles() {
$this->container->get('entity_type.bundle.info')->clearCachedBundles();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeBundleManagerInterface::getBundleInfo()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getBundleInfo($entity_type) {
return $this->container->get('entity_type.bundle.info')->getBundleInfo($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeBundleManagerInterface::getAllBundleInfo()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getAllBundleInfo() {
return $this->container->get('entity_type.bundle.info')->getAllBundleInfo();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeRepositoryInterface::getEntityTypeLabels()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getEntityTypeLabels($group = FALSE) {
return $this->container->get('entity_type.repository')->getEntityTypeLabels($group);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityRepositoryInterface::getTranslationFromContext()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = []) {
return $this->container->get('entity.repository')->getTranslationFromContext($entity, $langcode, $context);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getAllViewModes()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getAllViewModes() {
return $this->container->get('entity_display.repository')->getAllViewModes();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getViewModes()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getViewModes($entity_type_id) {
return $this->container->get('entity_display.repository')->getViewModes($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getAllFormModes()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getAllFormModes() {
return $this->container->get('entity_display.repository')->getAllFormModes();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getFormModes()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFormModes($entity_type_id) {
return $this->container->get('entity_display.repository')->getFormModes($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getViewModeOptions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getViewModeOptions($entity_type_id) {
return $this->container->get('entity_display.repository')->getViewModeOptions($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getFormModeOptions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFormModeOptions($entity_type_id) {
return $this->container->get('entity_display.repository')->getFormModeOptions($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getViewModeOptionsByBundle()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getViewModeOptionsByBundle($entity_type_id, $bundle) {
return $this->container->get('entity_display.repository')->getViewModeOptionsByBundle($entity_type_id, $bundle);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::getFormModeOptionsByBundle()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getFormModeOptionsByBundle($entity_type_id, $bundle) {
return $this->container->get('entity_display.repository')->getFormModeOptionsByBundle($entity_type_id, $bundle);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityDisplayRepositoryInterface::clearDisplayModeInfo()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function clearDisplayModeInfo() {
$this->container->get('entity_display.repository')->clearDisplayModeInfo();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityRepositoryInterface::loadEntityByUuid()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function loadEntityByUuid($entity_type_id, $uuid) {
return $this->container->get('entity.repository')->loadEntityByUuid($entity_type_id, $uuid);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityRepositoryInterface::loadEntityByConfigTarget()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function loadEntityByConfigTarget($entity_type_id, $target) {
return $this->container->get('entity.repository')->loadEntityByConfigTarget($entity_type_id, $target);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeRepositoryInterface::getEntityTypeFromClass()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getEntityTypeFromClass($class_name) {
return $this->container->get('entity_type.repository')->getEntityTypeFromClass($class_name);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeListenerInterface::onEntityTypeUpdate()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
$this->container->get('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeListenerInterface::onEntityTypeDelete()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onEntityTypeDelete(EntityTypeInterface $entity_type) {
$this->container->get('entity_type.listener')->onEntityTypeDelete($entity_type);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Field\FieldStorageDefinitionListenerInterface::onFieldStorageDefinitionCreate()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) {
$this->container->get('field_storage_definition.listener')->onFieldStorageDefinitionCreate($storage_definition);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Field\FieldStorageDefinitionListenerInterface::onFieldStorageDefinitionUpdate()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
$this->container->get('field_storage_definition.listener')->onFieldStorageDefinitionUpdate($storage_definition, $original);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Field\FieldStorageDefinitionListenerInterface::onFieldStorageDefinitionDelete()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
$this->container->get('field_storage_definition.listener')->onFieldStorageDefinitionDelete($storage_definition);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityBundleListenerInterface::onBundleCreate()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onBundleCreate($bundle, $entity_type_id) {
$this->container->get('entity_bundle.listener')->onBundleCreate($bundle, $entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityBundleListenerInterface::onBundleDelete()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function onBundleDelete($bundle, $entity_type_id) {
$this->container->get('entity_bundle.listener')->onBundleDelete($bundle, $entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface::getLastInstalledDefinition()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getLastInstalledDefinition($entity_type_id) {
return $this->container->get('entity.last_installed_schema.repository')->getLastInstalledDefinition($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface::getLastInstalledFieldStorageDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getLastInstalledFieldStorageDefinitions($entity_type_id) {
return $this->container->get('entity.last_installed_schema.repository')->getLastInstalledFieldStorageDefinitions($entity_type_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getDefinitions()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getDefinitions() {
return $this->container->get('entity_type.manager')->getDefinitions();
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::hasDefinition()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function hasDefinition($plugin_id) {
return $this->container->get('entity_type.manager')->hasDefinition($plugin_id);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::createInstance()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function createInstance($plugin_id, array $configuration = []) {
return $this->container->get('entity_type.manager')->createInstance($plugin_id, $configuration);
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\Entity\EntityTypeManagerInterface::getInstance()
+ * instead.
+ *
+ * @see https://www.drupal.org/node/2549139
*/
public function getInstance(array $options) {
return $this->container->get('entity_type.manager')->getInstance($options);
* // Load node.admin.inc from the node module.
* $this->loadInclude('node', 'inc', 'node.admin');
* // Load content_types.inc from the node module.
- * $this->loadInclude('node', 'inc', ''content_types');
+ * $this->loadInclude('node', 'inc', 'content_types');
* @endcode
*
* @param string $module
*/
protected $constraints = [];
+ /**
+ * Array of property constraint options keyed by property ID. The values are
+ * associative array of constraint options keyed by constraint plugin ID.
+ *
+ * @var array[]
+ */
+ protected $propertyConstraints = [];
+
/**
* {@inheritdoc}
*/
if (!isset($this->itemDefinition)) {
$this->itemDefinition = FieldItemDataDefinition::create($this)
->setSettings($this->getSettings());
+
+ // Add any custom property constraints, overwriting as required.
+ $item_constraints = $this->itemDefinition->getConstraint('ComplexData') ?: [];
+ foreach ($this->propertyConstraints as $name => $constraints) {
+ if (isset($item_constraints[$name])) {
+ $item_constraints[$name] = $constraints + $item_constraints[$name];
+ }
+ else {
+ $item_constraints[$name] = $constraints;
+ }
+ $this->itemDefinition->addConstraint('ComplexData', $item_constraints);
+ }
}
+
return $this->itemDefinition;
}
* {@inheritdoc}
*/
public function setPropertyConstraints($name, array $constraints) {
- $item_constraints = $this->getItemDefinition()->getConstraints();
- $item_constraints['ComplexData'][$name] = $constraints;
- $this->getItemDefinition()->setConstraints($item_constraints);
+ $this->propertyConstraints[$name] = $constraints;
+
+ // Reset the field item definition so the next time it is instantiated it
+ // will receive the new constraints.
+ $this->itemDefinition = NULL;
+
return $this;
}
* {@inheritdoc}
*/
public function addPropertyConstraints($name, array $constraints) {
- $item_constraints = $this->getItemDefinition()->getConstraint('ComplexData') ?: [];
- if (isset($item_constraints[$name])) {
- // Add the new property constraints, overwriting as required.
- $item_constraints[$name] = $constraints + $item_constraints[$name];
- }
- else {
- $item_constraints[$name] = $constraints;
+ foreach ($constraints as $constraint_name => $options) {
+ $this->propertyConstraints[$name][$constraint_name] = $options;
}
- $this->getItemDefinition()->addConstraint('ComplexData', $item_constraints);
+
+ // Reset the field item definition so the next time it is instantiated it
+ // will receive the new constraints.
+ $this->itemDefinition = NULL;
+
return $this;
}
/**
* Provides an interface for a Form that has a base form ID.
*
- * This will become the $form_state->getBaseInfo()['base_form_id'] used to
+ * This will become the $form_state->getBuildInfo()['base_form_id'] used to
* generate the name of hook_form_BASE_FORM_ID_alter().
*/
interface BaseFormIdInterface extends FormInterface {
function hook_theme_suggestions_HOOK(array $variables) {
$suggestions = [];
- $suggestions[] = 'node__' . $variables['elements']['#langcode'];
+ $suggestions[] = 'hookname__' . $variables['elements']['#langcode'];
return $suggestions;
}
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
/**
* Add feed test.
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
/**
* Tests aggregator admin pages.
// Check if the amount of feeds in the overview matches the amount created.
$this->assertEqual(1, count($result), 'Created feed is found in the overview');
// Check if the fields in the table match with what's expected.
- $this->assertEqual($feed->label(), (string) $result[0]->td[0]->a);
+ $link = $this->xpath('//table/tbody/tr//td[1]/a');
+ $this->assertEquals($feed->label(), $link[0]->getText());
$count = $this->container->get('entity.manager')->getStorage('aggregator_item')->getItemCount($feed);
- $this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), (string) $result[0]->td[1]);
+ $td = $this->xpath('//table/tbody/tr//td[2]');
+ $this->assertEquals(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), $td[0]->getText());
// Update the items of the first feed.
$feed->refreshItems();
$this->drupalGet('admin/config/services/aggregator');
$result = $this->xpath('//table/tbody/tr');
// Check if the fields in the table match with what's expected.
- $this->assertEqual($feed->label(), (string) $result[0]->td[0]->a);
+ $link = $this->xpath('//table/tbody/tr//td[1]/a');
+ $this->assertEquals($feed->label(), $link[0]->getText());
$count = $this->container->get('entity.manager')->getStorage('aggregator_item')->getItemCount($feed);
- $this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), (string) $result[0]->td[1]);
+ $td = $this->xpath('//table/tbody/tr//td[2]');
+ $this->assertEquals(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), $td[0]->getText());
}
}
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
+
+use Drupal\Tests\Traits\Core\CronRunTrait;
/**
* Update feeds on cron.
* @group aggregator
*/
class AggregatorCronTest extends AggregatorTestBase {
+
+ use CronRunTrait;
+
/**
* Adds feeds and updates them via cron process.
*/
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\views\Entity\View;
// Check the opml aggregator page.
$this->drupalGet('aggregator/opml');
- $outline = $this->xpath('//outline[1]');
- $this->assertEqual($outline[0]['type'], 'rss', 'The correct type attribute is used for rss OPML.');
- $this->assertEqual($outline[0]['text'], $feed->label(), 'The correct text attribute is used for rss OPML.');
- $this->assertEqual($outline[0]['xmlurl'], $feed->getUrl(), 'The correct xmlUrl attribute is used for rss OPML.');
+ $content = $this->getSession()->getPage()->getContent();
+ // We can't use Mink xpath queries here because it only supports HTML pages,
+ // but we are dealing with XML here.
+ $xml = simplexml_load_string($content);
+ $attributes = $xml->xpath('//outline[1]')[0]->attributes();
+ $this->assertEquals('rss', $attributes->type);
+ $this->assertEquals($feed->label(), $attributes->text);
+ $this->assertEquals($feed->getUrl(), $attributes->xmlUrl);
// Check for the presence of a pager.
$this->drupalGet('aggregator/sources/' . $feed->id());
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
/**
* Tests the display of a feed on the Aggregator list page.
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\Tests\Traits\Core\CronRunTrait;
/**
* Tests aggregator feeds in multiple languages.
*/
class FeedLanguageTest extends AggregatorTestBase {
+ use CronRunTrait;
+
/**
* Modules to install.
*
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
use Drupal\aggregator\Entity\Feed;
/**
<?php
-namespace Drupal\aggregator\Tests;
+namespace Drupal\Tests\aggregator\Functional;
/**
* Update feed test.
* The block content entity.
*/
protected function getEntity() {
- $uuid = $this->getDerivativeId();
if (!isset($this->blockContent)) {
+ $uuid = $this->getDerivativeId();
$this->blockContent = $this->entityManager->loadEntityByUuid('block_content', $uuid);
}
return $this->blockContent;
namespace Drupal\block_content\Tests\Views;
+@trigger_error('\Drupal\block_content\Tests\Views\BlockContentTestBase is deprecated in 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\block_content\Functional\Views\BlockContentTestBase.', E_USER_DEPRECATED);
+
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Utility\SafeMarkup;
/**
* Base class for all block_content tests.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ * Use \Drupal\Tests\block_content\Functional\Views\BlockContentTestBase.
*/
abstract class BlockContentTestBase extends ViewTestBase {
<?php
-namespace Drupal\block_content\Tests;
+namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\Component\Utility\Unicode;
// Go to the configure page and verify the view mode has changed.
$this->drupalGet('admin/structure/block/manage/testblock');
- $this->assertFieldByXPath('//select[@name="settings[view_mode]"]/option[@selected="selected"]/@value', 'test_view_mode', 'View mode changed to Test View Mode');
+ $this->assertFieldByXPath('//select[@name="settings[view_mode]"]/option[@selected="selected"]', 'test_view_mode', 'View mode changed to Test View Mode');
// Check that the block exists in the database.
$blocks = entity_load_multiple_by_properties('block_content', ['info' => $edit['info[0][value]']]);
<?php
-namespace Drupal\block_content\Tests;
+namespace Drupal\Tests\block_content\Functional;
/**
* Tests the listing of custom blocks.
// Test the contents of each th cell.
$expected_items = [t('Block description'), t('Operations')];
foreach ($elements as $key => $element) {
- $this->assertEqual($element[0], $expected_items[$key]);
+ $this->assertEqual($element->getText(), $expected_items[$key]);
}
$label = 'Antelope';
// Check the contents of each row cell. The first cell contains the label,
// the second contains the machine name, and the third contains the
// operations list.
- $this->assertIdentical((string) $elements[0], $label);
+ $this->assertIdentical($elements[0]->getText(), $label);
// Edit the entity using the operations link.
$blocks = $this->container
<?php
-namespace Drupal\block_content\Tests;
+namespace Drupal\Tests\block_content\Functional;
/**
* Tests the Views-powered listing of custom blocks.
$this->assertEqual(count($elements), 4, 'Correct number of table header cells found.');
// Test the contents of each th cell.
- $expected_items = ['Block description', 'Block type', 'Updated', 'Operations'];
+ $expected_items = ['Block description', 'Block type', 'Updated Sort ascending', 'Operations'];
foreach ($elements as $key => $element) {
- if ($element->xpath('a')) {
- $this->assertIdentical(trim((string) $element->xpath('a')[0]), $expected_items[$key]);
+ if ($element->find('xpath', 'a')) {
+ $this->assertIdentical(trim($element->find('xpath', 'a')->getText()), $expected_items[$key]);
}
else {
- $this->assertIdentical(trim((string) $element[0]), $expected_items[$key]);
+ $this->assertIdentical(trim($element->getText()), $expected_items[$key]);
}
}
// Check the contents of each row cell. The first cell contains the label,
// the second contains the machine name, and the third contains the
// operations list.
- $this->assertIdentical((string) $elements[0]->xpath('a')[0], $label);
+ $this->assertIdentical($elements[0]->find('xpath', 'a')->getText(), $label);
// Edit the entity using the operations link.
$blocks = $this->container
<?php
-namespace Drupal\block_content\Tests;
+namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
<?php
-namespace Drupal\block_content\Tests;
+namespace Drupal\Tests\block_content\Functional;
/**
* Tests block content validation constraints.
<?php
-namespace Drupal\block_content\Tests\Views;
+namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* {@inheritdoc}
*/
- public function setUp() {
- parent::setUp();
+ public function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Add two new languages.
ConfigurableLanguage::createFromLangcode('fr')->save();
<?php
-namespace Drupal\block_content\Tests\Views;
+namespace Drupal\Tests\block_content\Functional\Views;
/**
* Tests the block_content integration into views.
$result = $this->xpath('//span[@class="field-content"]');
$ids = [];
foreach ($result as $element) {
- $ids[] = (int) $element;
+ $ids[] = $element->getText();
}
$this->assertEqual($ids, $expected_ids);
}
<?php
-namespace Drupal\block_content\Tests\Views;
+namespace Drupal\Tests\block_content\Functional\Views;
/**
* Tests the redirect destination on block content on entity operations.
--- /dev/null
+<?php
+
+namespace Drupal\Tests\block_content\Functional\Views;
+
+use Drupal\block_content\Entity\BlockContent;
+use Drupal\block_content\Entity\BlockContentType;
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Tests\views\Functional\ViewTestBase;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Base class for all block_content tests.
+ */
+abstract class BlockContentTestBase extends ViewTestBase {
+
+ /**
+ * Admin user
+ *
+ * @var object
+ */
+ protected $adminUser;
+
+ /**
+ * Permissions to grant admin user.
+ *
+ * @var array
+ */
+ protected $permissions = [
+ 'administer blocks',
+ ];
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = ['block', 'block_content', 'block_content_test_views'];
+
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
+ // Ensure the basic bundle exists. This is provided by the standard profile.
+ $this->createBlockContentType(['id' => 'basic']);
+
+ $this->adminUser = $this->drupalCreateUser($this->permissions);
+
+ if ($import_test_views) {
+ ViewTestData::createTestViews(get_class($this), ['block_content_test_views']);
+ }
+ }
+
+ /**
+ * Creates a custom block.
+ *
+ * @param array $settings
+ * (optional) An associative array of settings for the block_content, as
+ * used in entity_create().
+ *
+ * @return \Drupal\block_content\Entity\BlockContent
+ * Created custom block.
+ */
+ protected function createBlockContent(array $settings = []) {
+ $status = 0;
+ $settings += [
+ 'info' => $this->randomMachineName(),
+ 'type' => 'basic',
+ 'langcode' => 'en',
+ ];
+ if ($block_content = BlockContent::create($settings)) {
+ $status = $block_content->save();
+ }
+ $this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content %info.', ['%info' => $block_content->label()]));
+ return $block_content;
+ }
+
+ /**
+ * Creates a custom block type (bundle).
+ *
+ * @param array $values
+ * An array of settings to change from the defaults.
+ *
+ * @return \Drupal\block_content\Entity\BlockContentType
+ * Created custom block type.
+ */
+ protected function createBlockContentType(array $values = []) {
+ // Find a non-existent random type name.
+ if (!isset($values['id'])) {
+ do {
+ $id = strtolower($this->randomMachineName(8));
+ } while (BlockContentType::load($id));
+ }
+ else {
+ $id = $values['id'];
+ }
+ $values += [
+ 'id' => $id,
+ 'label' => $id,
+ 'revision' => FALSE
+ ];
+ $bundle = BlockContentType::create($values);
+ $status = $bundle->save();
+ block_content_add_body_field($bundle->id());
+
+ $this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content type %bundle.', ['%bundle' => $bundle->id()]));
+ return $bundle;
+ }
+
+}
<?php
-namespace Drupal\block_content\Tests\Views;
+namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\views\Views;
<?php
-namespace Drupal\block_content\Tests\Views;
+namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\block_content\Entity\BlockContent;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Views;
use Drupal\views\Tests\ViewTestData;
*/
public static $testViews = ['test_block_content_revision_id', 'test_block_content_revision_revision_id'];
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
BlockContentType::create([
'id' => 'basic',
'label' => 'basic',
<?php
-namespace Drupal\book\Tests\Views;
+namespace Drupal\Tests\book\Functional\Views;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Create users.
$this->bookAuthor = $this->drupalCreateUser(
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
- if (is_null($this->get('status')->value)) {
- if (\Drupal::currentUser()->hasPermission('skip comment approval')) {
- $this->setPublished();
- }
- else {
- $this->setUnpublished();
- }
- }
if ($this->isNew()) {
// Add the comment to database. This next section builds the thread field.
// @see \Drupal\comment\CommentViewBuilder::buildComponents()
$fields['langcode']->setDescription(t('The comment language code.'));
+ // Set the default value callback for the status field.
+ $fields['status']->setDefaultValueCallback('Drupal\comment\Entity\Comment::getDefaultStatus');
+
$fields['pid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Parent ID'))
->setDescription(t('The parent comment ID if this is a reply to a comment.'))
return $this->bundle();
}
+ /**
+ * Default value callback for 'status' base field definition.
+ *
+ * @see ::baseFieldDefinitions()
+ *
+ * @return bool
+ * TRUE if the comment should be published, FALSE otherwise.
+ */
+ public static function getDefaultStatus() {
+ return \Drupal::currentUser()->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED;
+ }
+
}
$comment->expects($this->any())
->method('getEntityType')
->will($this->returnValue($entity_type));
- $comment->expects($this->at(1))
- ->method('get')
- ->with('status')
- ->will($this->returnValue((object) ['value' => NULL]));
$storage = $this->getMock('Drupal\comment\CommentStorageInterface');
// preSave() should acquire the lock. (This is what's really being tested.)
<?php
-namespace Drupal\config_translation\Tests;
+namespace Drupal\Tests\config_translation\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests for altering configuration translation forms.
*
* @group config_translation
*/
-class ConfigTranslationFormTest extends WebTestBase {
+class ConfigTranslationFormTest extends BrowserTestBase {
/**
* Modules to enable.
<?php
-namespace Drupal\config_translation\Tests;
+namespace Drupal\Tests\config_translation\Functional;
use Drupal\Component\Utility\Html;
use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Translate settings and entities to various languages.
*
* @group config_translation
*/
-class ConfigTranslationOverviewTest extends WebTestBase {
+class ConfigTranslationOverviewTest extends BrowserTestBase {
/**
* Modules to enable.
// Make sure there is only a single operation for each dropbutton, either
// 'List' or 'Translate'.
foreach ($this->cssSelect('ul.dropbutton') as $i => $dropbutton) {
- $this->assertIdentical(1, $dropbutton->count());
- foreach ($dropbutton->li as $link) {
- $this->assertTrue(((string) $link->a === 'Translate') || ((string) $link->a === 'List'));
- }
+ $this->assertIdentical(1, count($dropbutton->find('xpath', 'li')));
+ $this->assertTrue(($dropbutton->getText() === 'Translate') || ($dropbutton->getText() === 'List'));
}
$labels = [
// Make sure there is only a single 'Translate' operation for each
// dropbutton.
foreach ($this->cssSelect('ul.dropbutton') as $i => $dropbutton) {
- $this->assertIdentical(1, $dropbutton->count());
- foreach ($dropbutton->li as $link) {
- $this->assertIdentical('Translate', (string) $link->a);
- }
+ $this->assertIdentical(1, count($dropbutton->find('xpath', 'li')));
+ $this->assertIdentical('Translate', $dropbutton->getText());
}
$entity_type = \Drupal::entityManager()->getDefinition($test_entity->getEntityTypeId());
<?php
-namespace Drupal\config_translation\Tests;
+namespace Drupal\Tests\config_translation\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Verifies theme configuration translation settings.
*
* @group config_translation
*/
-class ConfigTranslationUiThemeTest extends WebTestBase {
+class ConfigTranslationUiThemeTest extends BrowserTestBase {
/**
* Modules to enable.
':label' => 'Install and set as default',
':theme' => $theme,
]);
- $this->drupalGet($GLOBALS['base_root'] . $elements[0]['href'], ['external' => TRUE]);
+ $this->drupalGet($GLOBALS['base_root'] . $elements[0]->getAttribute('href'), ['external' => TRUE]);
$translation_base_url = 'admin/config/development/performance/translate';
$this->drupalGet($translation_base_url);
<?php
-namespace Drupal\config_translation\Tests;
+namespace Drupal\Tests\config_translation\Functional;
-use Drupal\views_ui\Tests\UITestBase;
+use Drupal\Tests\views_ui\Functional\UITestBase;
/**
* Visit view list and test if translate is available.
*/
public static $modules = ['config_translation', 'views_ui'];
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$permissions = [
'administer views',
<?php
-namespace Drupal\contact\Tests\Views;
+namespace Drupal\Tests\contact\Functional\Views;
use Drupal\field\Entity\FieldConfig;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\contact\Entity\ContactForm;
*/
protected $fieldStorage;
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$this->fieldStorage = FieldStorageConfig::create([
'field_name' => strtolower($this->randomMachineName()),
<?php
-namespace Drupal\contact\Tests\Views;
+namespace Drupal\Tests\contact\Functional\Views;
use Drupal\Core\Cache\Cache;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\user\Entity\User;
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
ViewTestData::createTestViews(get_class($this), ['contact_test_views']);
*/
public function getInitialState(WorkflowInterface $workflow, $entity = NULL) {
if ($entity instanceof EntityPublishedInterface) {
- return $workflow->getState($entity->isPublished() ? 'published' : 'draft');
+ return $workflow->getState($entity->isPublished() && !$entity->isNew() ? 'published' : 'draft');
}
return parent::getInitialState($workflow);
}
$this->assertEquals('draft', $loaded_unpublished_node->moderation_state->value);
$this->assertEquals('published', $loaded_published_node->moderation_state->value);
$this->assertEquals('draft', $loaded_entity_test->moderation_state->value);
+
+ $presave_node = Node::create([
+ 'type' => 'example',
+ 'title' => 'Presave node',
+ ]);
+ $this->assertEquals('draft', $presave_node->moderation_state->value);
}
}
* Test the field item list when accessing an index.
*/
public function testArrayIndex() {
- $this->assertEquals('published', $this->testNode->moderation_state[0]->value);
+ $this->assertFalse($this->testNode->isPublished());
+ $this->assertEquals('draft', $this->testNode->moderation_state[0]->value);
}
/**
foreach ($this->testNode->moderation_state as $item) {
$states[] = $item->value;
}
- $this->assertEquals(['published'], $states);
+ $this->assertEquals(['draft'], $states);
}
}
<?php
-namespace Drupal\content_translation\Tests;
+namespace Drupal\Tests\content_translation\Functional;
/**
* Tests the test content translation UI with the test entity.
<?php
-namespace Drupal\content_translation\Tests;
+namespace Drupal\Tests\content_translation\Functional;
use Drupal\Tests\BrowserTestBase;
<?php
-namespace Drupal\content_translation\Tests;
+namespace Drupal\Tests\content_translation\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Test enabling content translation module.
*
* @group content_translation
*/
-class ContentTranslationEnableTest extends WebTestBase {
+class ContentTranslationEnableTest extends BrowserTestBase {
/**
* {@inheritdoc}
// No pending updates should be available.
$this->drupalGet('admin/reports/status');
$requirement_value = $this->cssSelect("details.system-status-report__entry summary:contains('Entity/field definitions') + div");
- $this->assertEqual(t('Up to date'), trim((string) $requirement_value[0]));
+ $this->assertEqual(t('Up to date'), trim($requirement_value[0]->getText()));
$this->drupalGet('admin/config/regional/content-language');
// The node entity type should not be an option because it has no bundles.
// No pending updates should be available.
$this->drupalGet('admin/reports/status');
$requirement_value = $this->cssSelect("details.system-status-report__entry summary:contains('Entity/field definitions') + div");
- $this->assertEqual(t('Up to date'), trim((string) $requirement_value[0]));
+ $this->assertEqual(t('Up to date'), trim($requirement_value[0]->getText()));
// Create a node type and check the content translation settings are now
// available for nodes.
<?php
-namespace Drupal\content_translation\Tests;
+namespace Drupal\Tests\content_translation\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Tests\NodeTestBase;
<?php
-namespace Drupal\content_translation\Tests;
+namespace Drupal\Tests\content_translation\Functional;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Core\Language\Language;
use Drupal\field\Entity\FieldConfig;
use Drupal\language\Entity\ContentLanguageSettings;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests the content translation settings UI.
*
* @group content_translation
*/
-class ContentTranslationSettingsTest extends WebTestBase {
+class ContentTranslationSettingsTest extends BrowserTestBase {
use CommentTestTrait;
$elements = $this->xpath('//select[@id="edit-settings-node-article-settings-language-langcode"]/option');
// Compare values inside the option elements with expected values.
for ($i = 0; $i < count($elements); $i++) {
- $this->assertEqual($elements[$i]->attributes()->{'value'}, $expected_elements[$i]);
+ $this->assertEqual($elements[$i]->getValue(), $expected_elements[$i]);
}
}
<?php
-namespace Drupal\content_translation\Tests;
+namespace Drupal\Tests\content_translation\Functional;
use Drupal\Core\Entity\EntityInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\file\Entity\File;
+use Drupal\Tests\TestFileCreationTrait;
/**
* Tests the field synchronization behavior for the image field.
*/
class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
+ use TestFileCreationTrait {
+ getTestFiles as drupalGetTestFiles;
+ }
+
/**
* The cardinality of the image field.
*
<?php
-namespace Drupal\content_translation\Tests\Views;
+namespace Drupal\Tests\content_translation\Functional\Views;
-use Drupal\views_ui\Tests\UITestBase;
+use Drupal\Tests\views_ui\Functional\UITestBase;
/**
* Tests the views UI when content_translation is enabled.
<?php
-namespace Drupal\content_translation\Tests\Views;
+namespace Drupal\Tests\content_translation\Functional\Views;
-use Drupal\content_translation\Tests\ContentTranslationTestBase;
+use Drupal\Tests\content_translation\Functional\ContentTranslationTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\Core\Language\Language;
use Drupal\user\Entity\User;
* Implements hook_entity_bundle_field_info_alter().
*/
function field_test_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
- if (($field_name = \Drupal::state()->get('field_test_set_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
+ if (($field_name = \Drupal::state()->get('field_test_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
+ // Set a property constraint using
+ // \Drupal\Core\Field\FieldConfigInterface::setPropertyConstraints().
$fields[$field_name]->setPropertyConstraints('value', [
- 'Range' => [
- 'min' => 0,
- 'max' => 32,
+ 'TestField' => [
+ 'value' => -2,
+ 'message' => t('%name does not accept the value @value.', ['%name' => $field_name, '@value' => -2]),
],
]);
- }
- if (($field_name = \Drupal::state()->get('field_test_add_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
+
+ // Add a property constraint using
+ // \Drupal\Core\Field\FieldConfigInterface::addPropertyConstraints().
$fields[$field_name]->addPropertyConstraints('value', [
'Range' => [
'min' => 0,
/**
* Create field entities by attaching fields to entities.
*
+ * @coversDefaultClass \Drupal\Core\Field\FieldConfigBase
+ *
* @group field
*/
class FieldCrudTest extends FieldKernelTestBase {
* Test the creation of a field.
*/
public function testCreateField() {
- // Set a state flag so that field_test.module knows to add an in-memory
- // constraint for this field.
- \Drupal::state()->set('field_test_add_constraint', $this->fieldStorage->getName());
- /** @var \Drupal\Core\Field\FieldConfigInterface $field */
$field = FieldConfig::create($this->fieldDefinition);
$field->save();
// Check that the denormalized 'field_type' was properly written.
$this->assertEqual($config['field_type'], $this->fieldStorageDefinition['type']);
- // Test constraints are applied. A Range constraint is added dynamically to
- // limit the field to values between 0 and 32.
- // @see field_test_entity_bundle_field_info_alter()
- $this->doFieldValidationTests();
-
- // Test FieldConfigBase::setPropertyConstraints().
- \Drupal::state()->set('field_test_set_constraint', $this->fieldStorage->getName());
- \Drupal::state()->set('field_test_add_constraint', FALSE);
- \Drupal::entityManager()->clearCachedFieldDefinitions();
- $this->doFieldValidationTests();
-
// Guarantee that the field/bundle combination is unique.
try {
FieldConfig::create($this->fieldDefinition)->save();
// TODO: test other failures.
}
+ /**
+ * Tests setting and adding property constraints to a configurable field.
+ *
+ * @covers ::setPropertyConstraints
+ * @covers ::addPropertyConstraints
+ */
+ public function testFieldPropertyConstraints() {
+ $field = FieldConfig::create($this->fieldDefinition);
+ $field->save();
+ $field_name = $this->fieldStorage->getName();
+
+ // Test that constraints are applied to configurable fields. A TestField and
+ // a Range constraint are added dynamically to limit the field to values
+ // between 0 and 32.
+ // @see field_test_entity_bundle_field_info_alter()
+ \Drupal::state()->set('field_test_constraint', $field_name);
+
+ // Clear the field definitions cache so the new constraints added by
+ // field_test_entity_bundle_field_info_alter() are taken into consideration.
+ \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
+
+ // Test the newly added property constraints in the same request as when the
+ // caches were cleared. This will test the field definitions that are stored
+ // in the static cache of
+ // \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions().
+ $this->doFieldPropertyConstraintsTests();
+
+ // In order to test a real-world scenario where the property constraints are
+ // only stored in the persistent cache of
+ // \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions(), we need to
+ // simulate a new request by removing the 'entity_field.manager' service,
+ // thus forcing it to be re-initialized without static caches.
+ \Drupal::getContainer()->set('entity_field.manager', NULL);
+
+ // This will test the field definitions that are stored in the persistent
+ // cache by \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions().
+ $this->doFieldPropertyConstraintsTests();
+ }
+
+ /**
+ * Tests configurable field validation.
+ *
+ * @see field_test_entity_bundle_field_info_alter()
+ */
+ protected function doFieldPropertyConstraintsTests() {
+ $field_name = $this->fieldStorage->getName();
+
+ // Check that a valid value (not -2 and between 0 and 32) doesn't trigger
+ // any violation.
+ $entity = EntityTest::create();
+ $entity->set($field_name, 1);
+ $violations = $entity->validate();
+ $this->assertCount(0, $violations, 'No violations found when in-range value passed.');
+
+ // Check that a value that is specifically restricted triggers both
+ // violations.
+ $entity->set($field_name, -2);
+ $violations = $entity->validate();
+ $this->assertCount(2, $violations, 'Two violations found when using a null and outside the range value.');
+
+ $this->assertEquals($field_name . '.0.value', $violations[0]->getPropertyPath());
+ $this->assertEquals(t('%name does not accept the value @value.', ['%name' => $field_name, '@value' => -2]), $violations[0]->getMessage());
+
+ $this->assertEquals($field_name . '.0.value', $violations[1]->getPropertyPath());
+ $this->assertEquals(t('This value should be %limit or more.', ['%limit' => 0]), $violations[1]->getMessage());
+
+ // Check that a value that is not specifically restricted but outside the
+ // range triggers the expected violation.
+ $entity->set($field_name, 33);
+ $violations = $entity->validate();
+ $this->assertCount(1, $violations, 'Violations found when using value outside the range.');
+ $this->assertEquals($field_name . '.0.value', $violations[0]->getPropertyPath());
+ $this->assertEquals(t('This value should be %limit or less.', ['%limit' => 32]), $violations[0]->getMessage());
+ }
+
/**
* Test creating a field with custom storage set.
*/
$this->assertFalse(FieldStorageConfig::loadByName('entity_test', $field_storage->getName()));
}
- /**
- * Tests configurable field validation.
- *
- * @see field_test_entity_bundle_field_info_alter()
- */
- protected function doFieldValidationTests() {
- $entity = EntityTest::create();
- $entity->set($this->fieldStorage->getName(), 1);
- $violations = $entity->validate();
- $this->assertEqual(count($violations), 0, 'No violations found when in-range value passed.');
-
- $entity->set($this->fieldStorage->getName(), 33);
- $violations = $entity->validate();
- $this->assertEqual(count($violations), 1, 'Violations found when using value outside the range.');
- $this->assertEqual($violations[0]->getPropertyPath(), $this->fieldStorage->getName() . '.0.value');
- $this->assertEqual($violations[0]->getMessage(), t('This value should be %limit or less.', [
- '%limit' => 32,
- ]));
- }
-
}
- Drupal 7
source:
plugin: d7_file
+ scheme: public
constants:
# The tool configuring this migration must set source_base_path. It
# represents the fully qualified path relative to which URIs in the files
--- /dev/null
+id: d7_file_private
+label: Files
+migration_tags:
+ - Drupal 7
+source:
+ plugin: d7_file
+ scheme: private
+ constants:
+ # source_base_path must be set by the tool configuring this migration.
+ # It represents the fully qualified path relative to which uris in the files
+ # table are specified, and must end with a /. See source_full_path
+ # configuration in this migration's process pipeline as an example.
+ source_base_path: ''
+process:
+ # If you are using this file to build a custom migration consider removing
+ # the fid field to allow incremental migrations.
+ fid: fid
+ filename: filename
+ source_full_path:
+ -
+ plugin: concat
+ delimiter: /
+ source:
+ - constants/source_base_path
+ - filepath
+ uri:
+ plugin: file_copy
+ source:
+ - '@source_full_path'
+ - uri
+ filemime: filemime
+ status: status
+ # Drupal 7 didn't keep track of the file's creation or update time -- all it
+ # had was the vague "timestamp" column. So we'll use it for both.
+ created: timestamp
+ changed: timestamp
+ uid: uid
+destination:
+ plugin: entity:file
--- /dev/null
+<?php
+
+namespace Drupal\Tests\file\Kernel\Migrate\d7;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\file\Entity\File;
+use Drupal\file\FileInterface;
+use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
+
+/**
+ * Tests private files migration.
+ *
+ * @group file
+ */
+class MigratePrivateFileTest extends MigrateDrupal7TestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['file'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->setSetting('file_private_path', $this->container->get('site.path') . '/private');
+ $this->installEntitySchema('file');
+ $fs = $this->container->get('file_system');
+
+ // Ensure that the private files directory exists.
+ $fs->mkdir('private://sites/default/private/', NULL, TRUE);
+ // Put test file in the source directory.
+ file_put_contents('private://sites/default/private/Babylon5.txt', str_repeat('*', 3));
+
+ /** @var \Drupal\migrate\Plugin\Migration $migration */
+ $migration = $this->getMigration('d7_file_private');
+ // Set the source plugin's source_file_private_path configuration value,
+ // which would normally be set by the user running the migration.
+ $source = $migration->getSourceConfiguration();
+ $source['constants']['source_base_path'] = $fs->realpath('private://');
+ $migration->set('source', $source);
+ $this->executeMigration($migration);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function register(ContainerBuilder $container) {
+ parent::register($container);
+ $container->register('stream_wrapper.private', 'Drupal\Core\StreamWrapper\PrivateStream')
+ ->addTag('stream_wrapper', ['scheme' => 'private']);
+ }
+
+ /**
+ * Tests a single file entity.
+ *
+ * @param int $id
+ * The file ID.
+ * @param string $name
+ * The expected file name.
+ * @param string $uri
+ * The expected URI.
+ * @param string $mime
+ * The expected MIME type.
+ * @param int $size
+ * The expected file size.
+ * @param int $created
+ * The expected creation time.
+ * @param int $changed
+ * The expected modification time.
+ * @param int $uid
+ * The expected owner ID.
+ */
+ protected function assertEntity($id, $name, $uri, $mime, $size, $created, $changed, $uid) {
+ /** @var \Drupal\file\FileInterface $file */
+ $file = File::load($id);
+ $this->assertInstanceOf(FileInterface::class, $file);
+ $this->assertSame($name, $file->getFilename());
+ $this->assertSame($uri, $file->getFileUri());
+ $this->assertFileExists($uri);
+ $this->assertSame($mime, $file->getMimeType());
+ $this->assertSame($size, $file->getSize());
+ // isPermanent(), isTemporary(), etc. are determined by the status column.
+ $this->assertTrue($file->isPermanent());
+ $this->assertSame($created, $file->getCreatedTime());
+ $this->assertSame($changed, $file->getChangedTime());
+ $this->assertSame($uid, $file->getOwnerId());
+ }
+
+ /**
+ * Tests that all expected files are migrated.
+ */
+ public function testFileMigration() {
+ $this->assertEntity(3, 'Babylon5.txt', 'private://Babylon5.txt', 'text/plain', '3', '1486104045', '1486104045', '1');
+ }
+
+}
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
+ $migration_plugin_configuration = $configuration + [
+ 'migration' => 'd6_filter_format',
+ ];
+
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$migration,
- $container->get('plugin.manager.migrate.process')->createInstance('migration', ['migration' => 'd6_filter_format'], $migration)
+ $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_plugin_configuration, $migration)
);
}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\filter\Kernel\Migrate\d6;
+
+use Drupal\filter\Plugin\migrate\process\d6\FilterFormatPermission;
+use Drupal\migrate\Plugin\Migration;
+use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
+
+/**
+ * Tests conversion of format serial to string id in permission name.
+ *
+ * @coversDefaultClass \Drupal\filter\Plugin\migrate\process\d6\FilterFormatPermission
+ *
+ * @group filter
+ */
+class FilterFormatPermissionTest extends MigrateDrupalTestBase {
+
+ /**
+ * Tests configurability of filter_format migration name.
+ *
+ * @covers ::__construct
+ */
+ public function testConfigurableFilterFormat() {
+ $migration = Migration::create($this->container, [], 'custom_migration', []);
+ $filterFormatPermissionMigration = FilterFormatPermission::create($this->container, ['migration' => 'custom_filter_format'], 'custom_filter_format', [], $migration);
+ $migrationPlugin = $this->readAttribute($filterFormatPermissionMigration, 'migrationPlugin');
+ $config = $this->readAttribute($migrationPlugin, 'configuration');
+
+ $this->assertEquals($config['migration'], 'custom_filter_format');
+ }
+
+}
<?php
-namespace Drupal\forum\Tests\Views;
+namespace Drupal\Tests\forum\Functional\Views;
use Drupal\node\NodeInterface;
use Drupal\views\Views;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
*/
public static $testViews = ['test_forum_index'];
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
ViewTestData::createTestViews(get_class($this), ['forum_test_views']);
}
$this->moduleHandler->alter('hal_relation_uri', $uri, $context);
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This
// hook is invoked to maintain backwards compatibility
+ // @see https://www.drupal.org/node/2830467
$this->moduleHandler->alter('rest_relation_uri', $uri, $context);
return $uri;
}
$this->moduleHandler->alter('hal_type_uri', $uri, $context);
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This
// hook is invoked to maintain backwards compatibility
+ // @see https://www.drupal.org/node/2830467
$this->moduleHandler->alter('rest_type_uri', $uri, $context);
return $uri;
}
* Implements hook_rest_type_uri_alter().
*
* @deprecated Kept only for BC test coverage, see \Drupal\Tests\hal\Kernel\HalLinkManagerTest::testGetTypeUri().
+ *
+ * @see https://www.drupal.org/node/2830467
*/
function hal_test_rest_type_uri_alter(&$uri, $context = []) {
if (!empty($context['rest_test'])) {
* Implements hook_rest_relation_uri_alter().
*
* @deprecated Kept only for BC test coverage, see \Drupal\Tests\hal\Kernel\HalLinkManagerTest::testGetRelationUri().
+ *
+ * @see https://www.drupal.org/node/2830467
*/
function hal_test_rest_relation_uri_alter(&$uri, $context = []) {
if (!empty($context['rest_test'])) {
use Drupal\Tests\rest\Functional\EntityResource\ImageStyle\ImageStyleResourceTestBase;
/**
- * @group rest
+ * @group hal
*/
class ImageStyleHalJsonAnonTest extends ImageStyleResourceTestBase {
use Drupal\Tests\rest\Functional\EntityResource\ImageStyle\ImageStyleResourceTestBase;
/**
- * @group rest
+ * @group hal
*/
class ImageStyleHalJsonBasicAuthTest extends ImageStyleResourceTestBase {
use Drupal\Tests\rest\Functional\EntityResource\ImageStyle\ImageStyleResourceTestBase;
/**
- * @group rest
+ * @group hal
*/
class ImageStyleHalJsonCookieTest extends ImageStyleResourceTestBase {
namespace Drupal\Tests\image\Functional;
use Drupal\image\Entity\ImageStyle;
-use Drupal\system\Tests\Image\ToolkitTestBase;
+use Drupal\FunctionalTests\Image\ToolkitTestBase;
/**
* Tests that the image effects pass parameters to the toolkit correctly.
--- /dev/null
+<?php
+
+namespace Drupal\Tests\language\Kernel\Plugin\migrate\source\d6;
+
+use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
+
+/**
+ * Tests menu source plugin.
+ *
+ * @covers \Drupal\language\Plugin\migrate\source\d6\LanguageContentSettings
+ *
+ * @group language
+ */
+class LanguageContentSettingsTest extends MigrateSqlSourceTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['language', 'migrate_drupal'];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function providerSource() {
+ $tests = [];
+
+ // The source data.
+ $tests[0]['source_data']['node_type'] = [
+ [
+ 'type' => 'article',
+ 'name' => 'Article',
+ 'module' => 'node',
+ 'description' => 'An <em>article</em>, content type.',
+ 'help' => '',
+ 'has_title' => 1,
+ 'title_label' => 'Title',
+ 'has_body' => 1,
+ 'body_label' => 'Body',
+ 'min_word_count' => 0,
+ 'custom' => 1,
+ 'modified' => 1,
+ 'locked' => 0,
+ 'orig_type' => 'story',
+ ],
+ [
+ 'type' => 'company',
+ 'name' => 'Company',
+ 'module' => 'node',
+ 'description' => 'Company node type',
+ 'help' => '',
+ 'has_title' => 1,
+ 'title_label' => 'Name',
+ 'has_body' => 1,
+ 'body_label' => 'Description',
+ 'min_word_count' => 0,
+ 'custom' => 0,
+ 'modified' => 1,
+ 'locked' => 0,
+ 'orig_type' => 'company',
+ ],
+ ];
+
+ foreach ($tests[0]['source_data']['node_type'] as $node_type) {
+ $tests[0]['expected_data'][] = [
+ 'type' => $node_type['type'],
+ 'language_content_type' => NULL,
+ 'i18n_lock_node' => 0,
+ ];
+ }
+
+ return $tests;
+ }
+
+}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\language\Kernel\Plugin\migrate\source\d7;
+
+use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
+
+/**
+ * Tests menu source plugin.
+ *
+ * @covers \Drupal\language\Plugin\migrate\source\d7\LanguageContentSettings
+ *
+ * @group language
+ */
+class LanguageContentSettingsTest extends MigrateSqlSourceTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['language', 'migrate_drupal'];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function providerSource() {
+ $tests = [];
+
+ // The source data.
+ $tests[0]['source_data']['node_type'] = [
+ [
+ 'type' => 'article',
+ 'name' => 'Article',
+ 'base' => 'node_content',
+ 'module' => 'node',
+ 'description' => 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.',
+ 'help' => 'Help text for articles',
+ 'has_title' => 1,
+ 'title_label' => 'Title',
+ 'custom' => 1,
+ 'modified' => 1,
+ 'locked' => 0,
+ 'disabled' => 0,
+ 'orig_type' => 'article',
+ ],
+ [
+ 'type' => 'blog',
+ 'name' => 'Blog entry',
+ 'base' => 'blog',
+ 'module' => 'blog',
+ 'description' => 'Use for multi-user blogs. Every user gets a personal blog.',
+ 'help' => 'Blog away, good sir!',
+ 'has_title' => 1,
+ 'title_label' => 'Title',
+ 'custom' => 0,
+ 'modified' => 1,
+ 'locked' => 1,
+ 'disabled' => 0,
+ 'orig_type' => 'blog',
+ ],
+ ];
+
+ foreach ($tests[0]['source_data']['node_type'] as $node_type) {
+ $tests[0]['expected_data'][] = [
+ 'type' => $node_type['type'],
+ 'language_content_type' => NULL,
+ 'i18n_lock_node' => 0,
+ ];
+ }
+
+ return $tests;
+ }
+
+}
@media screen and (min-width: 40em) {
.layout--threecol-33-34-33 > .layout__region--first,
- .layout--threecol-33-34-33 > .layout__region--second,
.layout--threecol-33-34-33 > .layout__region--third {
flex: 0 1 33%;
}
+ .layout--threecol-33-34-33 > .layout__region--second {
+ flex: 0 1 34%;
+ }
}
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\locale\Locale;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
/**
*
* @group locale
*/
-class LocaleConfigTranslationImportTest extends WebTestBase {
+class LocaleConfigTranslationImportTest extends BrowserTestBase {
/**
* Modules to enable.
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => '',
];
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Language\LanguageInterface;
/**
*
* @group locale
*/
-class LocaleConfigTranslationTest extends WebTestBase {
+class LocaleConfigTranslationTest extends BrowserTestBase {
/**
* The language code used.
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $message,
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => 'D',
];
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $image_style_label,
];
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $category_label,
];
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests the exportation of locale files.
*
* @group locale
*/
-class LocaleExportTest extends WebTestBase {
+class LocaleExportTest extends BrowserTestBase {
/**
* Modules to enable.
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests the locale functionality in the altered file settings form.
*
* @group locale
*/
-class LocaleFileSystemFormTest extends WebTestBase {
+class LocaleFileSystemFormTest extends BrowserTestBase {
/**
* Modules to enable.
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Language\LanguageInterface;
/**
*
* @group locale
*/
-class LocaleImportFunctionalTest extends WebTestBase {
+class LocaleImportFunctionalTest extends BrowserTestBase {
/**
* Modules to enable.
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\Core\Language\LanguageInterface;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
use Drupal\Component\Utility\SafeMarkup;
/**
*
* @group locale
*/
-class LocaleJavascriptTranslationTest extends WebTestBase {
+class LocaleJavascriptTranslationTest extends BrowserTestBase {
/**
* Modules to enable.
public static $modules = ['locale', 'locale_test'];
public function testFileParsing() {
- $filename = __DIR__ . '/../../tests/locale_test.js';
+ $filename = __DIR__ . '/../../locale_test.js';
// Parse the file to look for source strings.
_locale_parse_js_file($filename);
$js_translation_files = \Drupal::state()->get('locale.translation.javascript');
$js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js';
+ $content = $this->getSession()->getPage()->getContent();
// Assert translations JS is included before drupal.js.
- $this->assertTrue(strpos($this->content, $js_filename) < strpos($this->content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
+ $this->assertTrue(strpos($content, $js_filename) < strpos($content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.');
}
}
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\Core\Asset\AttachedAssets;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests localization of the JavaScript libraries.
*
* @group locale
*/
-class LocaleLibraryAlterTest extends WebTestBase {
+class LocaleLibraryAlterTest extends BrowserTestBase {
/**
* Modules to enable.
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests plural handling for various languages.
*
* @group locale
*/
-class LocalePluralFormatTest extends WebTestBase {
+class LocalePluralFormatTest extends BrowserTestBase {
/**
* An admin user.
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\tour\Tests\TourTestBase;
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Component\Utility\SafeMarkup;
*
* @group locale
*/
-class LocaleTranslationUiTest extends WebTestBase {
+class LocaleTranslationUiTest extends BrowserTestBase {
/**
* Modules to enable.
// Code for the language.
$langcode = 'xx';
// The English name for the language. This will be translated.
- $name = $this->randomMachineName(16);
+ $name = 'cucurbitaceae';
// This will be the translation of $name.
$translation = $this->randomMachineName(16);
$translation_to_en = $this->randomMachineName(16);
// Assume this is the only result, given the random name.
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation,
];
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation_to_en,
];
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => 'Please enter your Llama username.',
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
// Assume this is the only result, given the random name.
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => '',
];
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $this->randomMachineName(),
];
// Find the edit path.
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
foreach ($bad_translations as $translation) {
$edit = [
$lid => $translation,
$this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
// Check for a form error on the textarea.
$form_class = $this->xpath('//form[@id="locale-translate-edit-form"]//textarea/@class');
- $this->assertNotIdentical(FALSE, strpos($form_class[0], 'error'), 'The string was rejected as unsafe.');
+ $this->assertContains('error', $form_class[0]->getText(), 'The string was rejected as unsafe.');
$this->assertNoText(t('The string has been saved.'), 'The string was not saved.');
}
}
// Assume this is the only result, given the random name.
// We save the lid from the path.
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation,
];
// Submit the translations without changing the translation.
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $translation->getString(),
];
// Submit the translations with a new translation.
$textarea = current($this->xpath('//textarea'));
- $lid = (string) $textarea[0]['name'];
+ $lid = $textarea->getAttribute('name');
$edit = [
$lid => $this->randomMachineName(100),
];
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\file\Entity\File;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
use Drupal\Component\Utility\SafeMarkup;
/**
* Base class for testing updates to string translations.
*/
-abstract class LocaleUpdateBase extends WebTestBase {
+abstract class LocaleUpdateBase extends BrowserTestBase {
/**
* Timestamp for an old translation.
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
+
+use Drupal\Tests\Traits\Core\CronRunTrait;
/**
* Tests for using cron to update project interface translations.
*/
class LocaleUpdateCronTest extends LocaleUpdateBase {
+ use CronRunTrait;
+
protected $batchOutput = [];
/**
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Test for proper version fallback in case of a development release.
*
* @group language
*/
-class LocaleUpdateDevelopmentReleaseTest extends WebTestBase {
+class LocaleUpdateDevelopmentReleaseTest extends BrowserTestBase {
public static $modules = ['locale', 'locale_test_development_release'];
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\SafeMarkup;
<?php
-namespace Drupal\locale\Tests;
+namespace Drupal\Tests\locale\Functional;
use Drupal\Core\Language\LanguageInterface;
$values[$source_id] = $source_id_values[$migration->id()][$index];
}
- $stub_row = new Row($values + $migration->getSourceConfiguration(), $source_ids, TRUE);
+ $stub_row = $this->createStubRow($values + $migration->getSourceConfiguration(), $source_ids);
// Do a normal migration with the stub row.
$migrate_executable->processRow($stub_row, $process);
}
}
+ /**
+ * Create a stub row source for later import as stub data.
+ *
+ * This simple wrapper of the Row constructor allows sub-classing plugins to
+ * have more control over the row.
+ *
+ * @param array $values
+ * An array of values to add as properties on the object.
+ * @param array $source_ids
+ * An array containing the IDs of the source using the keys as the field
+ * names.
+ *
+ * @return \Drupal\migrate\Row
+ * The stub row.
+ */
+ protected function createStubRow(array $values, array $source_ids) {
+ return new Row($values, $source_ids, TRUE);
+ }
+
}
*
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
* \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface instead.
+ *
+ * @see https://www.drupal.org/node/2751897
*/
interface MigrateCckFieldPluginManagerInterface extends MigrateFieldPluginManagerInterface { }
--- /dev/null
+<?php
+
+namespace Drupal\migrate_drupal\Plugin\migrate\field;
+
+use Drupal\migrate\Plugin\MigrationInterface;
+
+/**
+ * @MigrateField(
+ * id = "userreference",
+ * core = {6},
+ * type_map = {
+ * "userreference" = "entity_reference",
+ * },
+ * )
+ */
+class UserReference extends FieldPluginBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFieldFormatterMap() {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
+ $process = [
+ 'plugin' => 'iterator',
+ 'source' => $field_name,
+ 'process' => [
+ 'target_id' => [
+ 'plugin' => 'migration_lookup',
+ 'migration' => 'd6_user',
+ 'source' => 'uid',
+ ],
+ ],
+ ];
+ $migration->setProcessOfProperty($field_name, $process);
+ }
+
+}
->values(array(
'tid' => '1',
'vid' => '1',
- 'name' => 'term 1 of vocabulary 1',
- 'description' => 'description of term 1 of vocabulary 1',
+ 'name' => 'zu - term 1 of vocabulary 1',
+ 'description' => 'zu - description of term 1 of vocabulary 1',
'weight' => '0',
- 'language' => '',
+ 'language' => 'zu',
'trid' => '0',
))
->values(array(
'tid' => '2',
'vid' => '2',
- 'name' => 'term 2 of vocabulary 2',
- 'description' => 'description of term 2 of vocabulary 2',
+ 'name' => 'fr - term 2 of vocabulary 2',
+ 'description' => 'fr - description of term 2 of vocabulary 2',
'weight' => '3',
- 'language' => '',
+ 'language' => 'fr',
'trid' => '0',
))
->values(array(
'tid' => '3',
'vid' => '2',
- 'name' => 'term 3 of vocabulary 2',
- 'description' => 'description of term 3 of vocabulary 2',
+ 'name' => 'fr - term 3 of vocabulary 2',
+ 'description' => 'fr - description of term 3 of vocabulary 2',
'weight' => '4',
- 'language' => '',
+ 'language' => 'fr',
'trid' => '0',
))
->values(array(
'language' => '',
'trid' => '0',
))
+->values(array(
+ 'tid' => '7',
+ 'vid' => '1',
+ 'name' => 'fr - term 2 of vocabulary 1',
+ 'description' => 'fr - desc of term 2 vocab 1',
+ 'weight' => '0',
+ 'language' => 'fr',
+ 'trid' => '0',
+))
->execute();
$connection->schema()->createTable('term_hierarchy', array(
'tid' => '4',
'parent' => '0',
))
+->values(array(
+ 'tid' => '7',
+ 'parent' => '0',
+))
->values(array(
'tid' => '3',
'parent' => '2',
'vid' => '1',
'tid' => '1',
))
+->values(array(
+ 'nid' => '1',
+ 'vid' => '1',
+ 'tid' => '2',
+))
->values(array(
'nid' => '2',
'vid' => '3',
'name' => 'i18nstrings_allowed_formats',
'value' => 'a:2:{i:0;i:1;i:1;i:2;}',
))
+->values(array(
+ 'name' => 'i18ntaxonomy_vocabulary',
+ 'value' => 'a:2:{i:1;s:1:"3";i:2;s:1:"2";}',
+))
->values(array(
'name' => 'i18n_lock_node_article',
'value' => 'i:1;',
'tags' => '1',
'module' => 'taxonomy',
'weight' => '5',
- 'language' => '',
+ 'language' => 'fr',
))
->values(array(
'vid' => '3',
'translatable' => '0',
'deleted' => '0',
))
+->values(array(
+ 'id' => '25',
+ 'field_name' => 'field_private_file',
+ 'type' => 'file',
+ 'module' => 'file',
+ 'active' => '1',
+ 'storage_type' => 'field_sql_storage',
+ 'storage_module' => 'field_sql_storage',
+ 'storage_active' => '1',
+ 'locked' => '0',
+ 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:13:"display_field";i:0;s:15:"display_default";i:0;s:10:"uri_scheme";s:7:"private";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:29:"field_data_field_private_file";a:3:{s:3:"fid";s:22:"field_private_file_fid";s:7:"display";s:26:"field_private_file_display";s:11:"description";s:30:"field_private_file_description";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:33:"field_revision_field_private_file";a:3:{s:3:"fid";s:22:"field_private_file_fid";s:7:"display";s:26:"field_private_file_display";s:11:"description";s:30:"field_private_file_description";}}}}}s:12:"foreign keys";a:1:{s:3:"fid";a:2:{s:5:"table";s:12:"file_managed";s:7:"columns";a:1:{s:3:"fid";s:3:"fid";}}}s:7:"indexes";a:1:{s:3:"fid";a:1:{i:0;s:3:"fid";}}s:2:"id";s:2:"25";}',
+ 'cardinality' => '1',
+ 'translatable' => '0',
+ 'deleted' => '0',
+))
->execute();
$connection->schema()->createTable('field_config_instance', array(
'data' => 'a:7:{s:5:"label";s:14:"Term Reference";s:6:"widget";a:5:{s:6:"weight";s:2:"14";s:4:"type";s:21:"taxonomy_autocomplete";s:6:"module";s:8:"taxonomy";s:6:"active";i:0;s:8:"settings";a:2:{s:4:"size";i:60;s:17:"autocomplete_path";s:21:"taxonomy/autocomplete";}}s:8:"settings";a:1:{s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:4:{s:5:"label";s:5:"above";s:4:"type";s:6:"hidden";s:6:"weight";s:2:"13";s:8:"settings";a:0:{}}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
'deleted' => '0',
))
+->values(array(
+ 'id' => '42',
+ 'field_id' => '25',
+ 'field_name' => 'field_private_file',
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'data' => 'a:6:{s:5:"label";s:12:"Private file";s:6:"widget";a:5:{s:6:"weight";s:2:"19";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:18;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
+ 'deleted' => '0',
+))
->execute();
$connection->schema()->createTable('field_data_body', array(
'bundle' => 'test_content_type',
'deleted' => '0',
'entity_id' => '1',
- 'revision_id' => '1',
+ 'revision_id' => '6',
'language' => 'und',
'delta' => '0',
'field_phone_value' => '99-99-99-99',
))
->execute();
+$connection->schema()->createTable('field_data_field_private_file', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_private_file_fid' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_private_file_display' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '1',
+ 'unsigned' => TRUE,
+ ),
+ 'field_private_file_description' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_private_file_fid' => array(
+ 'field_private_file_fid',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_data_field_private_file')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_private_file_fid',
+ 'field_private_file_display',
+ 'field_private_file_description',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '6',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_private_file_fid' => '4',
+ 'field_private_file_display' => '1',
+ 'field_private_file_description' => '',
+))
+->execute();
+
$connection->schema()->createTable('field_data_field_tags', array(
'fields' => array(
'entity_type' => array(
'delta' => '0',
'field_phone_value' => '99-99-99-99',
))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '6',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_phone_value' => '99-99-99-99',
+))
+->execute();
+
+$connection->schema()->createTable('field_revision_field_private_file', array(
+ 'fields' => array(
+ 'entity_type' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'bundle' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '128',
+ 'default' => '',
+ ),
+ 'deleted' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '0',
+ ),
+ 'entity_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'revision_id' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'not null' => TRUE,
+ 'length' => '32',
+ 'default' => '',
+ ),
+ 'delta' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_private_file_fid' => array(
+ 'type' => 'int',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ 'unsigned' => TRUE,
+ ),
+ 'field_private_file_display' => array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'size' => 'tiny',
+ 'default' => '1',
+ 'unsigned' => TRUE,
+ ),
+ 'field_private_file_description' => array(
+ 'type' => 'text',
+ 'not null' => FALSE,
+ 'size' => 'normal',
+ ),
+ ),
+ 'primary key' => array(
+ 'entity_type',
+ 'entity_id',
+ 'revision_id',
+ 'deleted',
+ 'delta',
+ 'language',
+ ),
+ 'indexes' => array(
+ 'entity_type' => array(
+ 'entity_type',
+ ),
+ 'bundle' => array(
+ 'bundle',
+ ),
+ 'deleted' => array(
+ 'deleted',
+ ),
+ 'entity_id' => array(
+ 'entity_id',
+ ),
+ 'revision_id' => array(
+ 'revision_id',
+ ),
+ 'language' => array(
+ 'language',
+ ),
+ 'field_private_file_fid' => array(
+ 'field_private_file_fid',
+ ),
+ ),
+ 'mysql_character_set' => 'utf8',
+));
+
+$connection->insert('field_revision_field_private_file')
+->fields(array(
+ 'entity_type',
+ 'bundle',
+ 'deleted',
+ 'entity_id',
+ 'revision_id',
+ 'language',
+ 'delta',
+ 'field_private_file_fid',
+ 'field_private_file_display',
+ 'field_private_file_description',
+))
+->values(array(
+ 'entity_type' => 'node',
+ 'bundle' => 'test_content_type',
+ 'deleted' => '0',
+ 'entity_id' => '1',
+ 'revision_id' => '6',
+ 'language' => 'und',
+ 'delta' => '0',
+ 'field_private_file_fid' => '4',
+ 'field_private_file_display' => '1',
+ 'field_private_file_description' => '',
+))
->execute();
$connection->schema()->createTable('field_revision_field_tags', array(
'status' => '1',
'timestamp' => '1421727516',
))
+->values(array(
+ 'fid' => '3',
+ 'uid' => '1',
+ 'filename' => 'Babylon5.txt',
+ 'uri' => 'private://Babylon5.txt',
+ 'filemime' => 'text/plain',
+ 'filesize' => '4',
+ 'status' => '1',
+ 'timestamp' => '1486104045',
+))
->execute();
$connection->schema()->createTable('file_usage', array(
'module' => 'file',
'type' => 'node',
'id' => '1',
- 'count' => '2',
+ 'count' => '3',
))
->values(array(
'fid' => '2',
'module' => 'file',
'type' => 'node',
'id' => '1',
- 'count' => '1',
+ 'count' => '2',
))
->values(array(
'fid' => '2',
'id' => '2',
'count' => '1',
))
+->values(array(
+ 'fid' => '3',
+ 'module' => 'file',
+ 'type' => 'node',
+ 'id' => '1',
+ 'count' => '1',
+))
->execute();
$connection->schema()->createTable('filter', array(
))
->values(array(
'name' => 'file_private_path',
- 'value' => 's:0:"";',
+ 'value' => 's:21:"sites/default/private";',
))
->values(array(
'name' => 'file_public_path',
// @todo Find a way to avoid this in https://www.drupal.org/node/2804611.
if ($definition['destination']['plugin'] === 'entity:file') {
// Make sure we have a single trailing slash.
+ if ($definition['source']['plugin'] === 'd7_file_private') {
+ $configuration['source']['constants']['source_base_path'] = rtrim($config['source_private_file_path'], '/') . '/';
+ }
$configuration['source']['constants']['source_base_path'] = rtrim($config['source_base_path'], '/') . '/';
}
'source_module' => 'file',
'destination_module' => 'file',
],
+ 'd7_file_private' => [
+ 'source_module' => 'file',
+ 'destination_module' => 'file',
+ ],
'd6_filter_format' => [
'source_module' => 'filter',
'destination_module' => 'filter',
'source_module' => 'taxonomy',
'destination_module' => 'taxonomy',
],
+ 'd6_taxonomy_term_translation' => [
+ 'source_module' => 'i18n',
+ 'destination_module' => 'taxonomy',
+ ],
'd6_taxonomy_vocabulary' => [
'source_module' => 'taxonomy',
'destination_module' => 'taxonomy',
],
+ 'd6_taxonomy_vocabulary_translation' => [
+ 'source_module' => 'i18n',
+ 'destination_module' => 'taxonomy',
+ ],
'd6_term_node' => [
'source_module' => 'taxonomy',
'destination_module' => 'taxonomy',
$default_options = [];
+
+ $form['version'] = [
+ '#type' => 'radios',
+ '#default_value' => 7,
+ '#title' => $this->t('Drupal version of the source site'),
+ '#options' => [6 => $this->t('Drupal 6'), 7 => $this->t('Drupal 7')],
+ '#required' => TRUE,
+ ];
+
$form['database'] = [
'#type' => 'details',
'#title' => $this->t('Source database'),
'#title' => $this->t('Source files'),
'#open' => TRUE,
];
- $form['source']['source_base_path'] = [
+ $form['source']['d6_source_base_path'] = [
'#type' => 'textfield',
'#title' => $this->t('Files directory'),
'#description' => $this->t('To import files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (for example http://example.com).'),
+ '#states' => [
+ 'visible' => [
+ ':input[name="version"]' => ['value' => 6],
+ ],
+ ],
+ ];
+
+ $form['source']['source_base_path'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Public files directory'),
+ '#description' => $this->t('To import public files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (for example http://example.com).'),
+ '#states' => [
+ 'visible' => [
+ ':input[name="version"]' => ['value' => 7],
+ ],
+ ],
+ ];
+
+ $form['source']['source_private_file_path'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Private file directory'),
+ '#default_value' => '',
+ '#description' => $this->t('To import private files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot).'),
+ '#states' => [
+ 'visible' => [
+ ':input[name="version"]' => ['value' => 7],
+ ],
+ ],
];
$form['actions'] = ['#type' => 'actions'];
if (!$version) {
$form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database does not contain a recognizable Drupal version.'));
}
+ elseif ($version != $form_state->getValue('version')) {
+ $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database is Drupal version @version but version @selected was selected.', [
+ '@version' => $version,
+ '@selected' => $form_state->getValue('version'),
+ ]));
+ }
else {
$this->createDatabaseStateSettings($database, $version);
$migrations = $this->getMigrations('migrate_drupal_' . $version, $version);
// Store the retrieved migration IDs in form storage.
$form_state->set('migrations', $migration_array);
$form_state->set('source_base_path', $form_state->getValue('source_base_path'));
+ $form_state->set('source_private_file_path', $form_state->getValue('source_private_file_path'));
// Store the retrived system data in form storage.
$form_state->set('system_data', $system_data);
namespace Drupal\migrate_drupal_ui\Tests;
+@trigger_error('\Drupal\migrate_drupal_ui\Tests\MigrateUpgradeTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase instead.', E_USER_DEPRECATED);
+
use Drupal\Core\Database\Database;
use Drupal\migrate\Plugin\MigrateIdMapInterface;
use Drupal\migrate_drupal\MigrationConfigurationTrait;
/**
* Provides a base class for testing migration upgrades in the UI.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use
+ * \Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase instead.
*/
abstract class MigrateUpgradeTestBase extends WebTestBase {
use MigrationConfigurationTrait;
<?php
-namespace Drupal\migrate_drupal_ui\Tests;
+namespace Drupal\Tests\migrate_drupal_ui\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests that only user 1 can access the migrate UI.
*
* @group migrate_drupal_ui
*/
-class MigrateAccessTest extends WebTestBase {
+class MigrateAccessTest extends BrowserTestBase {
/**
* Modules to enable.
--- /dev/null
+<?php
+
+namespace Drupal\Tests\migrate_drupal_ui\Functional;
+
+use Drupal\Core\Database\Database;
+use Drupal\migrate\Plugin\MigrateIdMapInterface;
+use Drupal\migrate_drupal\MigrationConfigurationTrait;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Provides a base class for testing migration upgrades in the UI.
+ */
+abstract class MigrateUpgradeTestBase extends BrowserTestBase {
+ use MigrationConfigurationTrait;
+
+ /**
+ * Use the Standard profile to test help implementations of many core modules.
+ */
+ protected $profile = 'standard';
+
+ /**
+ * The source database connection.
+ *
+ * @var \Drupal\Core\Database\Connection
+ */
+ protected $sourceDatabase;
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = [
+ 'language',
+ 'content_translation',
+ 'migrate_drupal_ui',
+ 'telephone',
+ 'aggregator',
+ 'book',
+ 'forum',
+ 'statistics',
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->createMigrationConnection();
+ $this->sourceDatabase = Database::getConnection('default', 'migrate_drupal_ui');
+
+ // Log in as user 1. Migrations in the UI can only be performed as user 1.
+ $this->drupalLogin($this->rootUser);
+ }
+
+ /**
+ * Loads a database fixture into the source database connection.
+ *
+ * @param string $path
+ * Path to the dump file.
+ */
+ protected function loadFixture($path) {
+ $default_db = Database::getConnection()->getKey();
+ Database::setActiveConnection($this->sourceDatabase->getKey());
+
+ if (substr($path, -3) == '.gz') {
+ $path = 'compress.zlib://' . $path;
+ }
+ require $path;
+
+ Database::setActiveConnection($default_db);
+ }
+
+ /**
+ * Changes the database connection to the prefixed one.
+ *
+ * @todo Remove when we don't use global. https://www.drupal.org/node/2552791
+ */
+ protected function createMigrationConnection() {
+ $connection_info = Database::getConnectionInfo('default')['default'];
+ if ($connection_info['driver'] === 'sqlite') {
+ // Create database file in the test site's public file directory so that
+ // \Drupal\simpletest\TestBase::restoreEnvironment() will delete this once
+ // the test is complete.
+ $file = $this->publicFilesDirectory . '/' . $this->testId . '-migrate.db.sqlite';
+ touch($file);
+ $connection_info['database'] = $file;
+ $connection_info['prefix'] = '';
+ }
+ else {
+ $prefix = is_array($connection_info['prefix']) ? $connection_info['prefix']['default'] : $connection_info['prefix'];
+ // Simpletest uses fixed length prefixes. Create a new prefix for the
+ // source database. Adding to the end of the prefix ensures that
+ // \Drupal\simpletest\TestBase::restoreEnvironment() will remove the
+ // additional tables.
+ $connection_info['prefix'] = $prefix . '0';
+ }
+
+ Database::addConnectionInfo('migrate_drupal_ui', 'default', $connection_info);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function tearDown() {
+ Database::removeConnection('migrate_drupal_ui');
+ parent::tearDown();
+ }
+
+ /**
+ * Executes all steps of migrations upgrade.
+ */
+ public function testMigrateUpgrade() {
+ $connection_options = $this->sourceDatabase->getConnectionOptions();
+ $this->drupalGet('/upgrade');
+ $this->assertText('Upgrade a site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the online documentation for Drupal site upgrades for more detailed information.');
+
+ $this->drupalPostForm(NULL, [], t('Continue'));
+ $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.');
+ $this->assertFieldByName('mysql[host]');
+
+ $driver = $connection_options['driver'];
+ $connection_options['prefix'] = $connection_options['prefix']['default'];
+
+ // Use the driver connection form to get the correct options out of the
+ // database settings. This supports all of the databases we test against.
+ $drivers = drupal_get_database_types();
+ $form = $drivers[$driver]->getFormOptions($connection_options);
+ $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']);
+ $version = $this->getLegacyDrupalVersion($this->sourceDatabase);
+ $edit = [
+ $driver => $connection_options,
+ 'source_base_path' => $this->getSourceBasePath(),
+ 'source_private_file_path' => $this->getSourceBasePath(),
+ 'version' => $version,
+ ];
+ if (count($drivers) !== 1) {
+ $edit['driver'] = $driver;
+ }
+ $edits = $this->translatePostValues($edit);
+
+ // Ensure submitting the form with invalid database credentials gives us a
+ // nice warning.
+ $this->drupalPostForm(NULL, [$driver . '[database]' => 'wrong'] + $edits, t('Review upgrade'));
+ $this->assertText('Resolve the issue below to continue the upgrade.');
+
+ $this->drupalPostForm(NULL, $edits, t('Review upgrade'));
+ $this->assertResponse(200);
+ $this->assertText('Are you sure?');
+ $this->drupalPostForm(NULL, [], t('Perform upgrade'));
+ $this->assertText(t('Congratulations, you upgraded Drupal!'));
+
+ // Have to reset all the statics after migration to ensure entities are
+ // loadable.
+ $this->resetAll();
+
+ $expected_counts = $this->getEntityCounts();
+ foreach (array_keys(\Drupal::entityTypeManager()
+ ->getDefinitions()) as $entity_type) {
+ $real_count = \Drupal::entityQuery($entity_type)->count()->execute();
+ $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0;
+ $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count.");
+ }
+
+ $plugin_manager = \Drupal::service('plugin.manager.migration');
+ /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */
+ $all_migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version);
+ foreach ($all_migrations as $migration) {
+ $id_map = $migration->getIdMap();
+ foreach ($id_map as $source_id => $map) {
+ // Convert $source_id into a keyless array so that
+ // \Drupal\migrate\Plugin\migrate\id_map\Sql::getSourceHash() works as
+ // expected.
+ $source_id_values = array_values(unserialize($source_id));
+ $row = $id_map->getRowBySource($source_id_values);
+ $destination = serialize($id_map->currentDestination());
+ $message = "Migration of $source_id to $destination as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status'];
+ // A completed migration should have maps with
+ // MigrateIdMapInterface::STATUS_IGNORED or
+ // MigrateIdMapInterface::STATUS_IMPORTED.
+ if ($row['source_row_status'] == MigrateIdMapInterface::STATUS_FAILED || $row['source_row_status'] == MigrateIdMapInterface::STATUS_NEEDS_UPDATE) {
+ $this->fail($message);
+ }
+ else {
+ $this->pass($message);
+ }
+ }
+ }
+ \Drupal::service('module_installer')->install(['forum']);
+ \Drupal::service('module_installer')->install(['book']);
+ }
+
+ /**
+ * Transforms a nested array into a flat array suitable for BrowserTestBase::drupalPostForm().
+ *
+ * @param array $values
+ * A multi-dimensional form values array to convert.
+ *
+ * @return array
+ * The flattened $edit array suitable for BrowserTestBase::drupalPostForm().
+ */
+ protected function translatePostValues(array $values) {
+ $edit = [];
+ // The easiest and most straightforward way to translate values suitable for
+ // BrowserTestBase::drupalPostForm() is to actually build the POST data string
+ // and convert the resulting key/value pairs back into a flat array.
+ $query = http_build_query($values);
+ foreach (explode('&', $query) as $item) {
+ list($key, $value) = explode('=', $item);
+ $edit[urldecode($key)] = urldecode($value);
+ }
+ return $edit;
+ }
+
+ /**
+ * Gets the source base path for the concrete test.
+ *
+ * @return string
+ * The source base path.
+ */
+ abstract protected function getSourceBasePath();
+
+ /**
+ * Gets the expected number of entities per entity type after migration.
+ *
+ * @return int[]
+ * An array of expected counts keyed by entity type ID.
+ */
+ abstract protected function getEntityCounts();
+
+}
<?php
-namespace Drupal\migrate_drupal_ui\Tests\d6;
+namespace Drupal\Tests\migrate_drupal_ui\Functional\d6;
-use Drupal\migrate_drupal_ui\Tests\MigrateUpgradeTestBase;
+use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase;
use Drupal\user\Entity\User;
/**
'shortcut_set' => 1,
'action' => 22,
'menu' => 8,
- 'taxonomy_term' => 6,
+ 'taxonomy_term' => 7,
'taxonomy_vocabulary' => 6,
'tour' => 4,
'user' => 7,
// Ensure migrated users can log in.
$user = User::load(2);
- $user->pass_raw = 'john.doe_pass';
+ $user->passRaw = 'john.doe_pass';
$this->drupalLogin($user);
}
<?php
-namespace Drupal\migrate_drupal_ui\Tests\d7;
+namespace Drupal\Tests\migrate_drupal_ui\Functional\d7;
-use Drupal\migrate_drupal_ui\Tests\MigrateUpgradeTestBase;
+use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase;
use Drupal\user\Entity\User;
/**
*/
class MigrateUpgrade7Test extends MigrateUpgradeTestBase {
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['file'];
+
/**
* {@inheritdoc}
*/
'configurable_language' => 4,
'contact_form' => 3,
'editor' => 2,
- 'field_config' => 52,
- 'field_storage_config' => 39,
- 'file' => 2,
+ 'field_config' => 53,
+ 'field_storage_config' => 40,
+ 'file' => 3,
'filter_format' => 7,
'image_style' => 6,
'language_content_settings' => 2,
// Ensure migrated users can log in.
$user = User::load(2);
- $user->pass_raw = 'a password';
+ $user->passRaw = 'a password';
$this->drupalLogin($user);
}
$this->assertSame('Klingon Empire', $node->field_company[0]->entity->label());
$this->assertSame('Romulan Empire', $node->field_company[1]->entity->label());
+ // Test that user reference field values were migrated.
+ $this->assertCount(1, $node->field_commander);
+ $this->assertSame('joe.roe', $node->field_commander[0]->entity->getUsername());
+
$node = Node::load(2);
$this->assertIdentical('Test title rev 3', $node->getTitle());
$this->assertIdentical('test rev 3', $node->body->value);
-moz-transition: all .7s ease;
transition: all .7s ease;
}
-
-/* Transition the position of the toolbar. */
-.toolbar-fixed,
-.toolbar-tray-open {
- -webkit-transition: all .5s ease;
- -moz-transition: all .5s ease;
- transition: all .5s ease;
-}
-
-/* Transition the administration tray.
-#toolbar-administration,
-#toolbar-administration * {
- -webkit-transition: all .7s ease;
- -moz-transition: all .7s ease;
- transition: all .7s ease;
-}*/
/* Style the edit mode toolbar and tabs. */
#toolbar-bar.js-outside-in-edit-mode {
- background-color: #fff;
+ background-image: linear-gradient(to bottom,#0c97ed,#1f86c7);
}
.js-outside-in-edit-mode .toolbar-item:not(.toolbar-icon-edit) {
color: #999;
*/
class OpenOffCanvasDialogCommand extends OpenDialogCommand {
+ /**
+ * The dialog width to use if none is provided.
+ */
+ const DEFAULT_DIALOG_WIDTH = 300;
+
/**
* Constructs an OpenOffCanvasDialogCommand object.
*
// @todo drupal.ajax.js does not respect drupalAutoButtons properly, pass an
// empty set of buttons until https://www.drupal.org/node/2793343 is in.
$this->dialogOptions['buttons'] = [];
+ // If no width option is provided then use the default width to avoid the
+ // dialog staying at the width of the previous instance when opened
+ // more than once, with different widths, on a single page.
+ if (!isset($this->dialogOptions['width'])) {
+ $this->dialogOptions['width'] = static::DEFAULT_DIALOG_WIDTH;
+ }
}
/**
}
$form['advanced_link'] = [
'#type' => 'link',
- '#title' => $this->t('Advanced options'),
+ '#title' => $this->t('Advanced block options'),
'#url' => $this->entity->toUrl('edit-form', ['query' => $query]),
'#weight' => 1000,
];
// Remove the ID and region elements.
unset($form['id'], $form['region'], $form['settings']['admin_label']);
+ if (isset($form['settings']['label_display']) && isset($form['settings']['label'])) {
+ // Only show the label input if the label will be shown on the page.
+ $form['settings']['label_display']['#weight'] = -100;
+ $form['settings']['label']['#states']['visible'] = [
+ ':input[name="settings[label_display]"]' => ['checked' => TRUE],
+ ];
+
+ // Relabel to "Block title" because on the front-end this may be confused
+ // with page title.
+ $form['settings']['label']['#title'] = $this->t("Block title");
+ $form['settings']['label_display']['#title'] = $this->t("Display block title");
+ }
return $form;
}
'draggable' => FALSE,
'drupalAutoButtons' => FALSE,
'buttons' => [],
+ 'width' => 300,
],
'effect' => 'fade',
'speed' => 1000,
*
* For consistent wrapping to {{ page }} render in all themes. The
* "data-off-canvas-main-canvas" attribute is required by the off-canvas dialog.
- * It cannot be removed without breaking the off-canvas dialog functionality.
+ * This is used by the outside_in/drupal.off_canvas library to select the
+ * "main canvas" page element as opposed to the "off canvas" which is the tray
+ * itself. The "main canvas" element must be resized according to the width of
+ * the "off canvas" tray so that no portion of the "main canvas" is obstructed
+ * by the tray. The tray can vary in width when opened and can be resized by the
+ * user. The "data-off-canvas-main-canvas" attribute cannot be removed without
+ * breaking the off-canvas dialog functionality.
*
* Available variables:
* - children: Contains the child elements of the page.
$this->assertEquals('', $header_text);
$style = $page->find('css', '.ui-dialog-off-canvas')->getAttribute('style');
- self::assertTrue(strstr($style, 'width: 555px;') !== FALSE, 'Dialog width respected.');
+ $this->assertTrue(strstr($style, 'width: 555px;') !== FALSE, 'Dialog width respected.');
+ $page->clickLink("Click Me 1!");
+ $this->waitForOffCanvasToOpen();
+ $style = $page->find('css', '.ui-dialog-off-canvas')->getAttribute('style');
+ $this->assertTrue(strstr($style, 'width: 555px;') === FALSE, 'Dialog width reset to default.');
}
else {
// Check that header is correct.
const TOOLBAR_EDIT_LINK_SELECTOR = '#toolbar-bar div.contextual-toolbar-tab button';
+ const LABEL_INPUT_SELECTOR = 'input[data-drupal-selector="edit-settings-label"]';
+
/**
* {@inheritdoc}
*/
$this->waitForNoElement("#toolbar-administration a.is-active");
}
$page->find('css', $toolbar_item)->click();
- $web_assert->waitForElementVisible('css', "{$toolbar_item}.is-active");
+ $this->assertElementVisibleAfterWait('css', "{$toolbar_item}.is-active");
}
$this->enableEditMode();
if (isset($toolbar_item)) {
$this->openBlockForm($block_selector);
switch ($block_plugin) {
case 'system_powered_by_block':
+ // Confirm "Display Title" is not checked.
+ $web_assert->checkboxNotChecked('settings[label_display]');
+ // Confirm Title is not visible.
+ $this->assertEquals($this->isLabelInputVisible(), FALSE, 'Label is not visible');
+ $page->checkField('settings[label_display]');
+ $this->assertEquals($this->isLabelInputVisible(), TRUE, 'Label is visible');
// Fill out form, save the form.
$page->fillField('settings[label]', $new_page_text);
- $page->checkField('settings[label_display]');
+
break;
case 'system_branding_block':
*/
protected function assertOffCanvasBlockFormIsValid() {
$web_assert = $this->assertSession();
+ // Confirm that Block title display label has been changed.
+ $web_assert->elementTextContains('css', '.form-item-settings-label-display label', 'Display block title');
+ // Confirm Block title label is shown if checkbox is checked.
+ if ($this->getSession()->getPage()->find('css', 'input[name="settings[label_display]"]')->isChecked()) {
+ $this->assertEquals($this->isLabelInputVisible(), TRUE, 'Label is visible');
+ $web_assert->elementTextContains('css', '.form-item-settings-label label', 'Block title');
+ }
+ else {
+ $this->assertEquals($this->isLabelInputVisible(), FALSE, 'Label is not visible');
+ }
+
// Check that common block form elements exist.
- $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label"]');
+ $web_assert->elementExists('css', static::LABEL_INPUT_SELECTOR);
$web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label-display"]');
// Check that advanced block form elements do not exist.
$web_assert->elementNotExists('css', 'input[data-drupal-selector="edit-visibility-request-path-pages"]');
$this->drupalGet('node/' . $node->id());
// Waiting for Toolbar module.
// @todo Remove the hack after https://www.drupal.org/node/2542050.
- $web_assert->waitForElementVisible('css', '.toolbar-fixed');
+ $this->assertElementVisibleAfterWait('css', '.toolbar-fixed');
// Waiting for Toolbar animation.
$web_assert->assertWaitOnAjaxRequest();
// The 2nd page load we should already be in edit mode.
}
// In Edit mode clicking field should open QuickEdit toolbar.
$page->find('css', $body_selector)->click();
- $web_assert->waitForElementVisible('css', $quick_edit_selector);
+ $this->assertElementVisibleAfterWait('css', $quick_edit_selector);
$this->disableEditMode();
// Exiting Edit mode should close QuickEdit toolbar.
$this->enableEditMode();
$this->openBlockForm($block_selector);
$page->find('css', $body_selector)->click();
- $web_assert->waitForElementVisible('css', $quick_edit_selector);
+ $this->assertElementVisibleAfterWait('css', $quick_edit_selector);
// Off-canvas dialog should be closed when opening QuickEdit toolbar.
$this->waitForOffCanvasToClose();
$this->disableEditMode();
// Open QuickEdit toolbar before going into Edit mode.
$this->clickContextualLink($node_selector, "Quick edit");
- $web_assert->waitForElementVisible('css', $quick_edit_selector);
+ $this->assertElementVisibleAfterWait('css', $quick_edit_selector);
// Open off-canvas and enter Edit mode via contextual link.
$this->clickContextualLink($block_selector, "Quick edit");
$this->waitForOffCanvasToOpen();
// Open QuickEdit toolbar via contextual link while in Edit mode.
$this->clickContextualLink($node_selector, "Quick edit", FALSE);
$this->waitForOffCanvasToClose();
- $web_assert->waitForElementVisible('css', $quick_edit_selector);
+ $this->assertElementVisibleAfterWait('css', $quick_edit_selector);
$this->disableEditMode();
}
}
return '#block-' . $block->id();
}
+ /**
+ * Determines if the label input is visible.
+ *
+ * @return bool
+ * TRUE if the label is visible, FALSE if it is not.
+ */
+ protected function isLabelInputVisible() {
+ return $this->getSession()->getPage()->find('css', static::LABEL_INPUT_SELECTOR)->isVisible();
+ }
+
}
protected function waitForOffCanvasToOpen() {
$web_assert = $this->assertSession();
$web_assert->assertWaitOnAjaxRequest();
- $web_assert->waitForElementVisible('css', '#drupal-off-canvas');
+ $this->assertElementVisibleAfterWait('css', '#drupal-off-canvas');
}
/**
$web_assert = $this->assertSession();
// Waiting for Toolbar module.
// @todo Remove the hack after https://www.drupal.org/node/2542050.
- $web_assert->waitForElementVisible('css', '.toolbar-fixed');
+ $this->assertElementVisibleAfterWait('css', '.toolbar-fixed');
// Waiting for Toolbar animation.
$web_assert->assertWaitOnAjaxRequest();
}
return ['bartik', 'stark', 'classy', 'stable'];
}
+ /**
+ * Asserts the specified selector is visible after a wait.
+ *
+ * @param string $selector
+ * The selector engine name. See ElementInterface::findAll() for the
+ * supported selectors.
+ * @param string|array $locator
+ * The selector locator.
+ * @param int $timeout
+ * (Optional) Timeout in milliseconds, defaults to 10000.
+ */
+ protected function assertElementVisibleAfterWait($selector, $locator, $timeout = 10000) {
+ $this->assertNotEmpty($this->assertSession()->waitForElementVisible($selector, $locator, $timeout));
+ }
+
}
'draggable' => FALSE,
'drupalAutoButtons' => FALSE,
'buttons' => [],
+ 'width' => 300,
],
'effect' => 'fade',
'speed' => 1000,
namespace Drupal\Tests\rdf\Functional;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
-use Drupal\taxonomy\Tests\TaxonomyTestBase;
+use Drupal\Tests\taxonomy\Functional\TaxonomyTestBase;
/**
* Tests RDFa markup generation for taxonomy term fields.
namespace Drupal\Tests\rdf\Functional;
-use Drupal\taxonomy\Tests\TaxonomyTestBase;
+use Drupal\Tests\taxonomy\Functional\TaxonomyTestBase;
/**
* Tests the RDFa markup of Taxonomy terms.
label: 'REST settings'
mapping:
# @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
+ # @see https://www.drupal.org/node/2830467
link_domain:
type: string
label: 'Domain of the relation'
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use
* hook_serialization_type_uri_alter() instead. This exists solely for BC.
*
+ * @see https://www.drupal.org/node/2830467
+ *
* Modules may wish to alter the type URI generated for a resource based on the
* context of the serializer/normalizer operation.
*
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use
* hook_serialization_relation_uri_alter() instead. This exists solely for BC.
*
+ * @see https://www.drupal.org/node/2830467
+ *
* Modules may wish to alter the relation URI generated for a resource based on
* the context of the serializer/normalizer operation.
*
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
interface ConfigurableLinkManagerInterface extends MovedConfigurableLinkManagerInterface {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
class LinkManager extends MovedLinkManager implements LinkManagerInterface {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
abstract class LinkManagerBase extends MovedLinkManagerBase {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
interface LinkManagerInterface extends MovedLinkManagerInterface {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
class RelationLinkManager extends MovedLinkRelationManager implements RelationLinkManagerInterface {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
interface RelationLinkManagerInterface extends MovedRelationLinkManagerInterface {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
class TypeLinkManager extends MovedTypeLinkManager implements TypeLinkManagerInterface {}
/**
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has
* been moved to the hal module. This exists solely for BC.
+ *
+ * @see https://www.drupal.org/node/2830467
*/
interface TypeLinkManagerInterface extends MovedTypeLinkManagerInterface {}
* @deprecated in Drupal 8.2.0.
* Use Drupal\rest\Plugin\Type\ResourcePluginManager::createInstance()
* instead.
+ *
+ * @see https://www.drupal.org/node/2874934
*/
public function getInstance(array $options){
if (isset($options['id'])) {
if (isset($modules['hal'])) {
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
// Use hal.link_manager instead.
+ // @see https://www.drupal.org/node/2830467
$service_definition = new DefinitionDecorator(new Reference('hal.link_manager'));
$service_definition->setClass(LinkManager::class);
$container->setDefinition('rest.link_manager', $service_definition);
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
// Use hal.link_manager.type instead.
+ // @see https://www.drupal.org/node/2830467
$service_definition = new DefinitionDecorator(new Reference('hal.link_manager.type'));
$service_definition->setClass(TypeLinkManager::class);
$container->setDefinition('rest.link_manager.type', $service_definition);
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
// Use hal.link_manager.relation instead.
+ // @see https://www.drupal.org/node/2830467
$service_definition = new DefinitionDecorator(new Reference('hal.link_manager.relation'));
$service_definition->setClass(RelationLinkManager::class);
$container->setDefinition('rest.link_manager.relation', $service_definition);
}
}
+ /**
+ * Tests POSTing a comment with and without 'skip comment approval'
+ */
+ public function testPostSkipCommentApproval() {
+ $this->initAuthentication();
+ $this->provisionEntityResource();
+ $this->setUpAuthorization('POST');
+
+ // Create request.
+ $request_options = [];
+ $request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType;
+ $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType;
+ $request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('POST'));
+ $request_options[RequestOptions::BODY] = $this->serializer->encode($this->getNormalizedPostEntity(), static::$format);
+
+ $url = $this->getEntityResourcePostUrl()->setOption('query', ['_format' => static::$format]);
+
+ // Status should be FALSE when posting as anonymous.
+ $response = $this->request('POST', $url, $request_options);
+ $unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format);
+ $this->assertResourceResponse(201, FALSE, $response);
+ $this->assertFalse($unserialized->getStatus());
+
+ // Grant anonymous permission to skip comment approval.
+ $this->grantPermissionsToTestedRole(['skip comment approval']);
+
+ // Status should be TRUE when posting as anonymous and skip comment approval.
+ $response = $this->request('POST', $url, $request_options);
+ $unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format);
+ $this->assertResourceResponse(201, FALSE, $response);
+ $this->assertTrue($unserialized->getStatus());
+ }
+
}
<?php
-/**
- * @file
- * Contains \Drupal\Tests\simpletest\Unit\TestInfoParsingTest.
- */
-
namespace Drupal\Tests\simpletest\Unit;
use Composer\Autoload\ClassLoader;
* @coversDefaultClass \Drupal\simpletest\TestDiscovery
* @group simpletest
*/
-class TestInfoParsingTest extends UnitTestCase {
+class TestDiscoveryTest extends UnitTestCase {
/**
* @covers ::getTestInfo
$tests[] = [
// Expected result.
[
- 'name' => 'Drupal\Tests\simpletest\Unit\TestInfoParsingTest',
+ 'name' => 'Drupal\Tests\simpletest\Unit\TestDiscoveryTest',
'group' => 'simpletest',
'description' => 'Tests \Drupal\simpletest\TestDiscovery.',
'type' => 'PHPUnit-Unit',
],
// Classname.
- 'Drupal\Tests\simpletest\Unit\TestInfoParsingTest',
+ 'Drupal\Tests\simpletest\Unit\TestDiscoveryTest',
];
// A core unit test.
], $result);
}
-}
-
-class TestTestDiscovery extends TestDiscovery {
-
- /**
- * @var \Drupal\Core\Extension\Extension[]
- */
- protected $extensions = [];
-
- public function setExtensions(array $extensions) {
- $this->extensions = $extensions;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getExtensions() {
- return $this->extensions;
- }
-
/**
* @covers ::getPhpunitTestSuite
* @dataProvider providerTestGetPhpunitTestSuite
}
+class TestTestDiscovery extends TestDiscovery {
+
+ /**
+ * @var \Drupal\Core\Extension\Extension[]
+ */
+ protected $extensions = [];
+
+ public function setExtensions(array $extensions) {
+ $this->extensions = $extensions;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtensions() {
+ return $this->extensions;
+ }
+
+}
+
namespace Drupal\simpletest\Tests;
use Drupal\simpletest\WebTestBase;
namespace Drupal\system\Tests\Database;
+@trigger_error(__NAMESPACE__ . '\DatabaseWebTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Database\DatabaseTestBase', E_USER_DEPRECATED);
+
use Drupal\KernelTests\Core\Database\DatabaseTestBase;
use Drupal\simpletest\WebTestBase;
/**
* Base class for databases database tests.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead
+ * use \Drupal\Tests\system\Functional\Database\DatabaseTestBase.
*/
abstract class DatabaseWebTestBase extends WebTestBase {
namespace Drupal\system\Tests\Database;
+@trigger_error(__NAMESPACE__ . '\FakeRecord is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Database\FakeRecord', E_USER_DEPRECATED);
+
/**
* Fetches into a class.
*
* PDO supports using a new instance of an arbitrary class for records
* rather than just a stdClass or array. This class is for testing that
* functionality. (See testQueryFetchClass() below)
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead
+ * use \Drupal\Tests\system\Functional\Database\FakeRecord.
*/
class FakeRecord { }
namespace Drupal\system\Tests\Image;
+@trigger_error(__FILE__ . ' is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use Drupal\FunctionalTests\Image\ToolkitTestBase instead. See https://www.drupal.org/node/2862641.', E_USER_DEPRECATED);
+
use Drupal\simpletest\WebTestBase;
use Drupal\Component\Utility\SafeMarkup;
/**
* Base class for image manipulation testing.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ * Use Drupal\FunctionalTests\Image\ToolkitTestBase instead.
+ *
+ * @see https://www.drupal.org/node/2862641
*/
abstract class ToolkitTestBase extends WebTestBase {
}
}
-/**
- * Implements hook_entity_field_storage_info().
- */
-function entity_test_entity_field_storage_info(EntityTypeInterface $entity_type) {
- if ($entity_type->id() == 'entity_test_update') {
- return \Drupal::state()->get('entity_test_update.additional_field_storage_definitions', []);
- }
-}
-
/**
* Creates a new bundle for entity_test entities.
*
return AccessResult::allowed();
}
+ // Create specific labels to allow or deny access based on certain test
+ // conditions.
+ // @see \Drupal\KernelTests\Core\Entity\EntityAccessControlHandlerTest
+ if ($entity->label() == 'Accessible') {
+ return AccessResult::allowed();
+ }
+ if ($entity->label() == 'Inaccessible') {
+ return AccessResult::forbidden();
+ }
+
// Uncacheable because the access result depends on a State key-value pair and
// might therefore change at any time.
$condition = \Drupal::state()->get("entity_test_entity_access.{$operation}." . $entity->id(), FALSE);
--- /dev/null
+<?php
+
+namespace Drupal\entity_test\Entity;
+
+/**
+ * Test entity class with revisions but without UUIDs.
+ *
+ * @ContentEntityType(
+ * id = "entity_test_no_uuid",
+ * label = @Translation("Test entity without UUID"),
+ * handlers = {
+ * "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
+ * },
+ * base_table = "entity_test_no_uuid",
+ * revision_table = "entity_test_no_uuid_revision",
+ * admin_permission = "administer entity_test content",
+ * persistent_cache = FALSE,
+ * entity_keys = {
+ * "id" = "id",
+ * "revision" = "vid",
+ * "bundle" = "type",
+ * "label" = "name",
+ * "langcode" = "langcode",
+ * },
+ * )
+ */
+class EntityTestNoUuid extends EntityTest {
+
+}
+++ /dev/null
-<?php
-
-namespace Drupal\entity_test\Entity;
-
-use Drupal\Core\Entity\EntityTypeInterface;
-
-/**
- * Defines the test entity class for testing definition updates.
- *
- * This entity type starts out non-revisionable by lacking a "revision_id" key,
- * but during an update test, can be made revisionable by adding that key.
- *
- * @ContentEntityType(
- * id = "entity_test_update",
- * label = @Translation("Test entity update"),
- * handlers = {
- * "storage_schema" = "Drupal\entity_test\EntityTestStorageSchema"
- * },
- * base_table = "entity_test_update",
- * revision_table = "entity_test_update_revision",
- * persistent_cache = FALSE,
- * entity_keys = {
- * "id" = "id",
- * "uuid" = "uuid",
- * "bundle" = "type",
- * "label" = "name",
- * "langcode" = "langcode",
- * }
- * )
- */
-class EntityTestUpdate extends EntityTestRev {
-
- /**
- * {@inheritdoc}
- */
- public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
- $fields = parent::baseFieldDefinitions($entity_type);
- $fields += \Drupal::state()->get('entity_test_update.additional_base_field_definitions', []);
- return $fields;
- }
-
- /**
- * {@inheritdoc}
- */
- public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
- $fields = parent::bundleFieldDefinitions($entity_type, $bundle, $base_field_definitions);
- $fields += \Drupal::state()->get('entity_test_update.additional_bundle_field_definitions.' . $bundle, []);
- return $fields;
- }
-
-}
}
}
+/**
+ * Implements hook_entity_field_storage_info().
+ */
+function entity_test_update_entity_field_storage_info(EntityTypeInterface $entity_type) {
+ if ($entity_type->id() == 'entity_test_update') {
+ return \Drupal::state()->get('entity_test_update.additional_field_storage_definitions', []);
+ }
+}
+
/**
* Implements hook_entity_type_alter().
*/
* @param array $args
* Values passed to hook.
*
- * @see \Drupal\system\Tests\Image\ToolkitTestBase::imageTestReset()
- * @see \Drupal\system\Tests\Image\ToolkitTestBase::imageTestGetAllCalls()
+ * @see \Drupal\Tests\system\Functional\Image\ToolkitTestBase::imageTestReset()
+ * @see \Drupal\Tests\system\Functional\Image\ToolkitTestBase::imageTestGetAllCalls()
*/
protected function logCall($op, $args) {
$results = $this->state->get('image_test.results') ?: [];
--- /dev/null
+<?php
+
+namespace Drupal\Tests\system\Functional\Database;
+
+use Drupal\KernelTests\Core\Database\DatabaseTestBase as DatabaseKernelTestBase;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Base class for databases database tests.
+ */
+abstract class DatabaseTestBase extends BrowserTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['database_test'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ DatabaseKernelTestBase::addSampleData();
+ }
+
+}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\system\Functional\Database;
+
+/**
+ * Fetches into a class.
+ *
+ * PDO supports using a new instance of an arbitrary class for records
+ * rather than just a stdClass or array. This class is for testing that
+ * functionality. (See testQueryFetchClass() below)
+ */
+class FakeRecord {}
<?php
-namespace Drupal\system\Tests\Database;
+namespace Drupal\Tests\system\Functional\Database;
+
use Symfony\Component\HttpFoundation\Request;
/**
*
* @group Database
*/
-class SelectPagerDefaultTest extends DatabaseWebTestBase {
+class SelectPagerDefaultTest extends DatabaseTestBase {
/**
* Confirms that a pager query returns the correct results.
for ($page = 0; $page <= $num_pages; ++$page) {
$this->drupalGet('database_test/pager_query_even/' . $limit, ['query' => ['page' => $page]]);
- $data = json_decode($this->getRawContent());
+ $data = json_decode($this->getSession()->getPage()->getContent());
if ($page == $num_pages) {
$correct_number = $count - ($limit * $page);
}
- $this->assertEqual(count($data->names), $correct_number, format_string('Correct number of records returned by pager: @number', ['@number' => $correct_number]));
+ $this->assertCount($correct_number, $data->names, format_string('Correct number of records returned by pager: @number', ['@number' => $correct_number]));
}
}
for ($page = 0; $page <= $num_pages; ++$page) {
$this->drupalGet('database_test/pager_query_odd/' . $limit, ['query' => ['page' => $page]]);
- $data = json_decode($this->getRawContent());
+ $data = json_decode($this->getSession()->getPage()->getContent());
if ($page == $num_pages) {
$correct_number = $count - ($limit * $page);
}
- $this->assertEqual(count($data->names), $correct_number, format_string('Correct number of records returned by pager: @number', ['@number' => $correct_number]));
+ $this->assertCount($correct_number, $data->names, format_string('Correct number of records returned by pager: @number', ['@number' => $correct_number]));
}
}
<?php
-namespace Drupal\system\Tests\Database;
+namespace Drupal\Tests\system\Functional\Database;
/**
* Tests the tablesort query extender.
*
* @group Database
*/
-class SelectTableSortDefaultTest extends DatabaseWebTestBase {
+class SelectTableSortDefaultTest extends DatabaseTestBase {
/**
* Confirms that a tablesort query returns the correct results.
foreach ($sorts as $sort) {
$this->drupalGet('database_test/tablesort/', ['query' => ['order' => $sort['field'], 'sort' => $sort['sort']]]);
- $data = json_decode($this->getRawContent());
+ $data = json_decode($this->getSession()->getPage()->getContent());
$first = array_shift($data->tasks);
$last = array_pop($data->tasks);
foreach ($sorts as $sort) {
$this->drupalGet('database_test/tablesort_first/', ['query' => ['order' => $sort['field'], 'sort' => $sort['sort']]]);
- $data = json_decode($this->getRawContent());
+ $data = json_decode($this->getSession()->getPage()->getContent());
$first = array_shift($data->tasks);
$last = array_pop($data->tasks);
* are correct.
*/
public function testTableSortDefaultSort() {
+ $assert = $this->assertSession();
+
$this->drupalGet('database_test/tablesort_default_sort');
// Verify that the table was displayed. Just the header is checked for
// because if there were any fatal errors or exceptions in displaying the
// sorted table, it would not print the table.
- $this->assertText(t('Username'));
+ $assert->pageTextContains(t('Username'));
// Verify that the header links are built properly.
- $this->assertLinkByHref('database_test/tablesort_default_sort');
- $this->assertPattern('/\<a.*title\=\"' . t('sort by Username') . '\".*\>/');
+ $assert->linkByHrefExists('database_test/tablesort_default_sort');
+ $assert->responseMatches('/\<a.*title\=\"' . t('sort by Username') . '\".*\>/');
}
}
<?php
-namespace Drupal\system\Tests\Database;
+namespace Drupal\Tests\system\Functional\Database;
/**
* Tests the temporary query functionality.
*
* @group Database
*/
-class TemporaryQueryTest extends DatabaseWebTestBase {
+class TemporaryQueryTest extends DatabaseTestBase {
/**
- * Modules to enable.
- *
- * @var array
+ * {@inheritdoc}
*/
public static $modules = ['database_test'];
*/
public function testTemporaryQuery() {
$this->drupalGet('database_test/db_query_temporary');
- $data = json_decode($this->getRawContent());
+ $data = json_decode($this->getSession()->getPage()->getContent());
if ($data) {
$this->assertEqual($this->countTableRows('test'), $data->row_count, 'The temporary table contains the correct amount of rows.');
$this->assertFalse(db_table_exists($data->table_name), 'The temporary table is, indeed, temporary.');
<?php
-namespace Drupal\system\Tests\DrupalKernel;
+namespace Drupal\Tests\system\Functional\DrupalKernel;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Ensures that the container rebuild works as expected.
*
* @group DrupalKernel
*/
-class ContainerRebuildWebTest extends WebTestBase {
+class ContainerRebuildWebTest extends BrowserTestBase {
/**
* {@inheritdoc}
* Sets a different deployment identifier.
*/
public function testSetContainerRebuildWithDifferentDeploymentIdentifier() {
+ $assert = $this->assertSession();
+
+ // Ensure the parameter is not set.
$this->drupalGet('<front>');
- $this->assertHeader('container_rebuild_indicator', FALSE);
+ $assert->responseHeaderEquals('container_rebuild_indicator', NULL);
$this->writeSettings(['settings' => ['deployment_identifier' => (object) ['value' => 'new-identifier', 'required' => TRUE]]]);
$this->drupalGet('<front>');
- $this->assertHeader('container_rebuild_indicator', 'new-identifier');
+ $assert->responseHeaderEquals('container_rebuild_indicator', 'new-identifier');
}
/**
* Tests container invalidation.
*/
public function testContainerInvalidation() {
+ $assert = $this->assertSession();
// Ensure that parameter is not set.
$this->drupalGet('<front>');
- $this->assertHeader('container_rebuild_test_parameter', FALSE);
+ $assert->responseHeaderEquals('container_rebuild_test_parameter', NULL);
// Ensure that after setting the parameter, without a container rebuild the
// parameter is still not set.
$this->writeSettings(['settings' => ['container_rebuild_test_parameter' => (object) ['value' => 'rebuild_me_please', 'required' => TRUE]]]);
$this->drupalGet('<front>');
- $this->assertHeader('container_rebuild_test_parameter', FALSE);
+ $assert->responseHeaderEquals('container_rebuild_test_parameter', NULL);
// Ensure that after container invalidation the parameter is set.
\Drupal::service('kernel')->invalidateContainer();
$this->drupalGet('<front>');
- $this->assertHeader('container_rebuild_test_parameter', 'rebuild_me_please');
+ $assert->responseHeaderEquals('container_rebuild_test_parameter', 'rebuild_me_please');
}
}
--- /dev/null
+id: d6_taxonomy_term_translation
+label: Taxonomy terms
+migration_tags:
+ - Drupal 6
+source:
+ plugin: d6_taxonomy_term
+ translations: true
+process:
+ # If you are using this file to build a custom migration consider removing
+ # the tid field to allow incremental migrations.
+ tid: tid
+ langcode: language
+ vid:
+ plugin: migration
+ migration: d6_taxonomy_vocabulary
+ source: vid
+ name: name
+ description: description
+ weight: weight
+ # Only attempt to stub real (non-zero) parents.
+ parent_id:
+ -
+ plugin: skip_on_empty
+ method: process
+ source: parent
+ -
+ plugin: migration
+ migration: d6_taxonomy_term
+ parent:
+ plugin: default_value
+ default_value: 0
+ source: '@parent_id'
+ changed: timestamp
+destination:
+ plugin: entity:taxonomy_term
+migration_dependencies:
+ required:
+ - d6_taxonomy_vocabulary
+ - d6_taxonomy_term
--- /dev/null
+id: d6_taxonomy_vocabulary_translation
+label: Taxonomy vocabularies
+migration_tags:
+ - Drupal 6
+source:
+ plugin: d6_taxonomy_vocabulary_translation
+process:
+ vid:
+ -
+ plugin: machine_name
+ source: name
+ -
+ plugin: substr
+ length: 32
+ langcode: language
+ property:
+ plugin: static_map
+ source: property
+ map:
+ name: name
+ description: description
+ translation: translation
+destination:
+ plugin: entity:taxonomy_vocabulary
+migration_dependencies:
+ required:
+ - d6_taxonomy_vocabulary
'weight' => $this->t('Weight'),
'parent' => $this->t("The Drupal term IDs of the term's parents."),
];
+ if (isset($this->configuration['translations'])) {
+ $fields['language'] = $this->t('The term language.');
+ $fields['trid'] = $this->t('Translation ID.');
+ }
return $fields;
}
--- /dev/null
+<?php
+
+namespace Drupal\taxonomy\Plugin\migrate\source\d6;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Drupal 6 vocabulary translations from source database.
+ *
+ * @MigrateSource(
+ * id = "d6_taxonomy_vocabulary_translation",
+ * source_provider = "taxonomy"
+ * )
+ */
+class VocabularyTranslation extends DrupalSqlBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function query() {
+ $query = $this->select('vocabulary', 'v')
+ ->fields('v', ['vid', 'name', 'description'])
+ ->fields('i18n', ['lid', 'type', 'property', 'objectid'])
+ ->fields('lt', ['lid', 'translation'])
+ ->condition('i18n.type', 'vocabulary');
+ $query->addField('lt', 'language', 'language');
+ // The i18n_strings table has two columns containing the object ID, objectid
+ // and objectindex. The objectid column is a text field. Therefore, for the
+ // join to work in PostgreSQL, use the objectindex field as this is numeric
+ // like the vid field.
+ $query->join('i18n_strings', 'i18n', 'v.vid = i18n.objectindex');
+ $query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
+
+ return $query;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fields() {
+ return [
+ 'vid' => $this->t('The vocabulary ID.'),
+ 'language' => $this->t('Language for this field.'),
+ 'property' => $this->t('Name of property being translated.'),
+ 'translation' => $this->t('Translation of either the title or explanation.'),
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIds() {
+ $ids['vid']['type'] = 'integer';
+ return $ids;
+ }
+
+}
namespace Drupal\taxonomy\Tests;
+@trigger_error(__NAMESPACE__ . '\TaxonomyTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTestBase', E_USER_DEPRECATED);
+
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait;
/**
* Provides common helper methods for Taxonomy module tests.
namespace Drupal\taxonomy\Tests;
+@trigger_error(__NAMESPACE__ . '\TaxonomyTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait', E_USER_DEPRECATED);
+
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Language\LanguageInterface;
use Drupal\taxonomy\Entity\Vocabulary;
/**
* Provides common helper methods for Taxonomy module tests.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ * Use \Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait
*/
trait TaxonomyTestTrait {
namespace Drupal\taxonomy\Tests;
+@trigger_error(__NAMESPACE__ . '\TaxonomyTranslationTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTranslationTestTrait', E_USER_DEPRECATED);
+
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Provides common testing base for translated taxonomy terms.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ * Use \Drupal\Tests\taxonomy\Functional\TaxonomyTranslationTestTrait
*/
trait TaxonomyTranslationTestTrait {
<?php
-namespace Drupal\taxonomy\Tests;
+namespace Drupal\Tests\taxonomy\Functional;
use Drupal\field\Entity\FieldConfig;
+use Drupal\Tests\TestFileCreationTrait;
use Drupal\user\RoleInterface;
use Drupal\file\Entity\File;
use Drupal\field\Entity\FieldStorageConfig;
*/
class TaxonomyImageTest extends TaxonomyTestBase {
+ use TestFileCreationTrait {
+ getTestFiles as drupalGetTestFiles;
+ compareFiles as drupalCompareFiles;
+ }
+
/**
* Used taxonomy vocabulary.
*
<?php
-namespace Drupal\taxonomy\Tests;
+namespace Drupal\Tests\taxonomy\Functional;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests that appropriate query tags are added.
*
* @group taxonomy
*/
-class TaxonomyQueryAlterTest extends WebTestBase {
+class TaxonomyQueryAlterTest extends BrowserTestBase {
use TaxonomyTestTrait;
<?php
-namespace Drupal\taxonomy\Tests;
+namespace Drupal\Tests\taxonomy\Functional;
/**
* Ensures that the term pager works properly.
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\Tests\BrowserTestBase;
-use Drupal\taxonomy\Tests\TaxonomyTestTrait;
/**
* Provides common helper methods for Taxonomy module tests.
--- /dev/null
+<?php
+
+namespace Drupal\Tests\taxonomy\Functional;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\taxonomy\Entity\Vocabulary;
+use Drupal\taxonomy\Entity\Term;
+
+/**
+ * Provides common helper methods for Taxonomy module tests.
+ */
+trait TaxonomyTestTrait {
+
+ /**
+ * Returns a new vocabulary with random properties.
+ */
+ public function createVocabulary() {
+ // Create a vocabulary.
+ $vocabulary = Vocabulary::create([
+ 'name' => $this->randomMachineName(),
+ 'description' => $this->randomMachineName(),
+ 'vid' => Unicode::strtolower($this->randomMachineName()),
+ 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+ 'weight' => mt_rand(0, 10),
+ ]);
+ $vocabulary->save();
+ return $vocabulary;
+ }
+
+ /**
+ * Returns a new term with random properties in vocabulary $vid.
+ *
+ * @param \Drupal\taxonomy\Entity\Vocabulary $vocabulary
+ * The vocabulary object.
+ * @param array $values
+ * (optional) An array of values to set, keyed by property name. If the
+ * entity type has bundles, the bundle key has to be specified.
+ *
+ * @return \Drupal\taxonomy\Entity\Term
+ * The new taxonomy term object.
+ */
+ public function createTerm(Vocabulary $vocabulary, $values = []) {
+ $filter_formats = filter_formats();
+ $format = array_pop($filter_formats);
+ $term = Term::create($values + [
+ 'name' => $this->randomMachineName(),
+ 'description' => [
+ 'value' => $this->randomMachineName(),
+ // Use the first available text format.
+ 'format' => $format->id(),
+ ],
+ 'vid' => $vocabulary->id(),
+ 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+ ]);
+ $term->save();
+ return $term;
+ }
+
+}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\taxonomy\Functional;
+
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\language\Entity\ConfigurableLanguage;
+
+/**
+ * Provides common testing base for translated taxonomy terms.
+ */
+trait TaxonomyTranslationTestTrait {
+
+ use EntityReferenceTestTrait;
+
+ /**
+ * The vocabulary.
+ *
+ * @var \Drupal\taxonomy\Entity\Vocabulary;
+ */
+ protected $vocabulary;
+
+ /**
+ * The field name for our taxonomy term field.
+ *
+ * @var string
+ */
+ protected $termFieldName = 'field_tag';
+
+ /**
+ * The langcode of the source language.
+ *
+ * @var string
+ */
+ protected $baseLangcode = 'en';
+
+ /**
+ * Target langcode for translation.
+ *
+ * @var string
+ */
+ protected $translateToLangcode = 'hu';
+
+ /**
+ * The node to check the translated value on.
+ *
+ * @var \Drupal\node\Entity\Node
+ */
+ protected $node;
+
+ /**
+ * Adds additional languages.
+ */
+ protected function setupLanguages() {
+ ConfigurableLanguage::createFromLangcode($this->translateToLangcode)->save();
+ $this->rebuildContainer();
+ }
+
+ /**
+ * Enables translations where it needed.
+ */
+ protected function enableTranslation() {
+ // Enable translation for the current entity type and ensure the change is
+ // picked up.
+ \Drupal::service('content_translation.manager')->setEnabled('node', 'article', TRUE);
+ \Drupal::service('content_translation.manager')->setEnabled('taxonomy_term', $this->vocabulary->id(), TRUE);
+ drupal_static_reset();
+ \Drupal::entityManager()->clearCachedDefinitions();
+ \Drupal::service('router.builder')->rebuild();
+ \Drupal::service('entity.definition_update_manager')->applyUpdates();
+ }
+
+ /**
+ * Adds term reference field for the article content type.
+ *
+ * @param bool $translatable
+ * (optional) If TRUE, create a translatable term reference field. Defaults
+ * to FALSE.
+ */
+ protected function setUpTermReferenceField() {
+ $handler_settings = [
+ 'target_bundles' => [
+ $this->vocabulary->id() => $this->vocabulary->id(),
+ ],
+ 'auto_create' => TRUE,
+ ];
+ $this->createEntityReferenceField('node', 'article', $this->termFieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
+ $field_storage = FieldStorageConfig::loadByName('node', $this->termFieldName);
+ $field_storage->setTranslatable(FALSE);
+ $field_storage->save();
+
+ entity_get_form_display('node', 'article', 'default')
+ ->setComponent($this->termFieldName, [
+ 'type' => 'entity_reference_autocomplete_tags',
+ ])
+ ->save();
+ entity_get_display('node', 'article', 'default')
+ ->setComponent($this->termFieldName, [
+ 'type' => 'entity_reference_label',
+ ])
+ ->save();
+ }
+
+}
namespace Drupal\Tests\taxonomy\Functional;
use Drupal\node\Entity\Node;
-use Drupal\taxonomy\Tests\TaxonomyTranslationTestTrait;
/**
* Tests the translation of taxonomy terms field on nodes.
<?php
-namespace Drupal\taxonomy\Tests;
+namespace Drupal\Tests\taxonomy\Functional;
-use Drupal\content_translation\Tests\ContentTranslationUITestBase;
+use Drupal\Tests\content_translation\Functional\ContentTranslationUITestBase;
use Drupal\Core\Language\LanguageInterface;
use Drupal\taxonomy\Entity\Vocabulary;
<?php
-namespace Drupal\taxonomy\Tests;
+namespace Drupal\Tests\taxonomy\Functional;
/**
* Verifies that various taxonomy pages use the expected theme.
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Views;
*/
public static $testViews = ['test_argument_validator_term'];
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Add three terms to the 'tags' vocabulary.
for ($i = 0; $i < 3; $i++) {
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Views;
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Views;
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\field\Entity\FieldConfig;
use Drupal\views\Views;
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Views;
use Drupal\taxonomy\Entity\Vocabulary;
$actual = $this->xpath('//a[@href="' . $this->term1->url() . '"]');
$this->assertEqual(count($actual), 2, 'Correct number of taxonomy term1 links');
- $this->assertEqual($actual[0]->__toString(), $this->term1->label());
- $this->assertEqual($actual[1]->__toString(), $this->term1->label());
+ $this->assertEqual($actual[0]->getText(), $this->term1->label());
+ $this->assertEqual($actual[1]->getText(), $this->term1->label());
$this->assertEscaped($this->term1->label());
$actual = $this->xpath('//a[@href="' . $this->term2->url() . '"]');
$this->assertEqual(count($actual), 2, 'Correct number of taxonomy term2 links');
- $this->assertEqual($actual[0]->__toString(), $this->term2->label());
- $this->assertEqual($actual[1]->__toString(), $this->term2->label());
+ $this->assertEqual($actual[0]->getText(), $this->term2->label());
+ $this->assertEqual($actual[1]->getText(), $this->term2->label());
}
/**
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\Core\Language\LanguageInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Views;
use Drupal\field\Entity\FieldStorageConfig;
*/
public $termNames = [];
- public function setUp() {
- parent::setUp();
+ public function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Add two new languages.
ConfigurableLanguage::createFromLangcode('fr')->save();
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\Core\Render\RenderContext;
use Drupal\views\Views;
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
/**
* {@inheritdoc}
*/
- protected function setUp() {
+ protected function setUp($import_test_views = TRUE) {
parent::setUp(FALSE);
// Setup vocabulary and terms so the initial import is valid.
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
+use Drupal\Tests\views_ui\Functional\UITestBase;
use Drupal\views\Tests\ViewTestData;
-use Drupal\views_ui\Tests\UITestBase;
use Drupal\views\Entity\View;
/**
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$this->adminUser = $this->drupalCreateUser(['administer taxonomy', 'administer views']);
$this->drupalLogin($this->adminUser);
for ($j = 0; $j <= $i; $j++) {
$option = $result[$counter++];
$prefix = $this->terms[$i][$j]->parent->target_id ? '-' : '';
- $attributes = $option->attributes();
- $tid = (string) $attributes->value;
+ $tid = $option->getAttribute('value');
- $this->assertEqual($prefix . $this->terms[$i][$j]->getName(), (string) $option);
+ $this->assertEqual($prefix . $this->terms[$i][$j]->getName(), $option->getText());
$this->assertEqual($this->terms[$i][$j]->id(), $tid);
}
}
$display['display_options']['filters']['tid']['type'] = 'textfield';
$view->save();
$this->drupalGet('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid');
- $this->assertFieldByXPath('//input[@id="edit-options-value"]');
+ $this->assertFieldById('edit-options-value', NULL);
// Tests \Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid::calculateDependencies().
$expected = [
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Tests\ViewTestData;
-use Drupal\views_ui\Tests\UITestBase;
+use Drupal\Tests\views_ui\Functional\UITestBase;
/**
* Tests views taxonomy parent plugin UI.
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
ViewTestData::createTestViews(get_class($this), ['taxonomy_test_views']);
}
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\TermInterface;
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Make term2 parent of term1.
$this->term1->set('parent', $this->term2->id());
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
/**
* Tests the taxonomy term with depth argument.
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Create a term with markup in the label.
$first = $this->createTerm(['name' => '<em>First</em>']);
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Views;
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Create a hierarchy 3 deep. Note the parent setup function creates two
// top-level terms w/o children.
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Create an administrative user.
$this->adminUser = $this->drupalCreateUser(['administer taxonomy', 'bypass node access']);
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\taxonomy\Entity\Term;
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\taxonomy\Entity\Vocabulary;
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
// Add default vocabulary to list of vocabularies.
$this->vocabularies[] = $this->vocabulary;
<?php
-namespace Drupal\taxonomy\Tests\Views;
+namespace Drupal\Tests\taxonomy\Functional\Views;
use Drupal\views\Views;
<?php
-namespace Drupal\taxonomy\Tests;
+namespace Drupal\Tests\taxonomy\Functional;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Url;
$site_name = $this->config('system.site')->get('name');
$this->assertTitle(t('Don\'t Panic | @site-name', ['@site-name' => $site_name]), 'The page title contains the escaped character.');
- $this->assertNoTitle(t('Don't Panic | @site-name', ['@site-name' => $site_name]), 'The page title does not contain an encoded character.');
}
/**
'vid' => 'vocabulary_1_i_0_',
'weight' => 0,
'parent' => [0],
+ 'language' => 'zu',
],
'2' => [
'source_vid' => 2,
'vid' => 'vocabulary_2_i_1_',
'weight' => 3,
'parent' => [0],
+ 'language' => 'fr',
],
'3' => [
'source_vid' => 2,
'vid' => 'vocabulary_2_i_1_',
'weight' => 4,
'parent' => [2],
+ 'language' => 'fr',
],
'4' => [
'source_vid' => 3,
foreach ($expected_results as $tid => $values) {
/** @var Term $term */
$term = $terms[$tid];
- $this->assertIdentical("term {$tid} of vocabulary {$values['source_vid']}", $term->name->value);
- $this->assertIdentical("description of term {$tid} of vocabulary {$values['source_vid']}", $term->description->value);
+ $language = isset($values['language']) ? $values['language'] . ' - ' : '';
+ $this->assertSame("{$language}term {$tid} of vocabulary {$values['source_vid']}", $term->name->value);
+ $this->assertSame("{$language}description of term {$tid} of vocabulary {$values['source_vid']}", $term->description->value);
$this->assertIdentical($values['vid'], $term->vid->target_id);
$this->assertIdentical((string) $values['weight'], $term->weight->value);
if ($values['parent'] === [0]) {
--- /dev/null
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Migrate\d6;
+
+use Drupal\taxonomy\Entity\Term;
+use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
+use Drupal\taxonomy\TermInterface;
+
+/**
+ * Test migration of translated taxonomy terms.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateTaxonomyTermTranslationTest extends MigrateDrupal6TestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = [
+ 'language',
+ 'menu_ui',
+ 'node',
+ 'taxonomy',
+ ];
+
+ /**
+ * The cached taxonomy tree items, keyed by vid and tid.
+ *
+ * @var array
+ */
+ protected $treeData = [];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->installEntitySchema('taxonomy_term');
+ $this->installConfig(static::$modules);
+ $this->executeMigrations([
+ 'd6_node_type',
+ 'd6_field',
+ 'd6_taxonomy_vocabulary',
+ 'd6_field_instance',
+ 'd6_taxonomy_term',
+ 'd6_taxonomy_term_translation',
+ ]);
+ }
+
+ /**
+ * Validate a migrated term contains the expected values.
+ *
+ * @param int $id
+ * Entity ID to load and check.
+ * @param string $expected_language
+ * The language code for this term.
+ * @param string $expected_label
+ * The label the migrated entity should have.
+ * @param string $expected_vid
+ * The parent vocabulary the migrated entity should have.
+ * @param string $expected_description
+ * The description the migrated entity should have.
+ * @param string $expected_format
+ * The format the migrated entity should have.
+ * @param int $expected_weight
+ * The weight the migrated entity should have.
+ * @param array $expected_parents
+ * The parent terms the migrated entity should have.
+ * @param int $expected_field_integer_value
+ * The value the migrated entity field should have.
+ * @param int $expected_term_reference_tid
+ * The term reference ID the migrated entity field should have.
+ */
+ protected function assertEntity($id, $expected_language, $expected_label, $expected_vid, $expected_description = '', $expected_format = NULL, $expected_weight = 0, $expected_parents = [], $expected_field_integer_value = NULL, $expected_term_reference_tid = NULL) {
+ /** @var \Drupal\taxonomy\TermInterface $entity */
+ $entity = Term::load($id);
+ $this->assertInstanceOf(TermInterface::class, $entity);
+ $this->assertSame($expected_language, $entity->language()->getId());
+ $this->assertSame($expected_label, $entity->label());
+ $this->assertSame($expected_vid, $entity->getVocabularyId());
+ $this->assertSame($expected_description, $entity->getDescription());
+ $this->assertSame($expected_format, $entity->getFormat());
+ $this->assertSame($expected_weight, $entity->getWeight());
+ $this->assertHierarchy($expected_vid, $id, $expected_parents);
+ }
+
+ /**
+ * Assert that a term is present in the tree storage, with the right parents.
+ *
+ * @param string $vid
+ * Vocabulary ID.
+ * @param int $tid
+ * ID of the term to check.
+ * @param array $parent_ids
+ * The expected parent term IDs.
+ */
+ protected function assertHierarchy($vid, $tid, array $parent_ids) {
+ if (!isset($this->treeData[$vid])) {
+ $tree = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
+ $this->treeData[$vid] = [];
+ foreach ($tree as $item) {
+ $this->treeData[$vid][$item->tid] = $item;
+ }
+ }
+
+ $this->assertArrayHasKey($tid, $this->treeData[$vid], "Term $tid exists in taxonomy tree");
+ $term = $this->treeData[$vid][$tid];
+ $this->assertEquals($parent_ids, array_filter($term->parents), "Term $tid has correct parents in taxonomy tree");
+ }
+
+ /**
+ * Tests the Drupal 6 i18n taxonomy term to Drupal 8 migration.
+ */
+ public function testTranslatedTaxonomyTerms() {
+ $this->assertEntity(1, 'zu', 'zu - term 1 of vocabulary 1', 'vocabulary_1_i_0_', 'zu - description of term 1 of vocabulary 1', NULL, '0', []);
+ $this->assertEntity(2, 'fr', 'fr - term 2 of vocabulary 2', 'vocabulary_2_i_1_', 'fr - description of term 2 of vocabulary 2', NULL, '3', []);
+ $this->assertEntity(3, 'fr', 'fr - term 3 of vocabulary 2', 'vocabulary_2_i_1_', 'fr - description of term 3 of vocabulary 2', NULL, '4', ['2']);
+ $this->assertEntity(4, 'en', 'term 4 of vocabulary 3', 'vocabulary_3_i_2_', 'description of term 4 of vocabulary 3', NULL, '6', []);
+ $this->assertEntity(5, 'en', 'term 5 of vocabulary 3', 'vocabulary_3_i_2_', 'description of term 5 of vocabulary 3', NULL, '7', ['4']);
+ $this->assertEntity(6, 'en', 'term 6 of vocabulary 3', 'vocabulary_3_i_2_', 'description of term 6 of vocabulary 3', NULL, '8', ['4', '5']);
+ $this->assertEntity(7, 'fr', 'fr - term 2 of vocabulary 1', 'vocabulary_1_i_0_', 'fr - desc of term 2 vocab 1', NULL, '0', []);
+ }
+
+}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Migrate\d6;
+
+use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
+
+/**
+ * Migrate taxonomy vocabularies to taxonomy.vocabulary.*.yml.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateTaxonomyVocabularyTranslationTest extends MigrateDrupal6TestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['language', 'taxonomy'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->executeMigrations([
+ 'd6_taxonomy_vocabulary',
+ 'd6_taxonomy_vocabulary_translation',
+ ]);
+ }
+
+ /**
+ * Tests the Drupal 6 i18n taxonomy vocabularies to Drupal 8 migration.
+ */
+ public function testTaxonomyVocabularyTranslation() {
+ $language_manager = \Drupal::service('language_manager');
+ $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_1_i_0_');
+ $this->assertSame('fr - vocabulary 1 (i=0)', $config->get('name'));
+ $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_2_i_1_');
+ $this->assertSame('fr - vocabulary 2 (i=1)', $config->get('name'));
+ $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_3_i_2_');
+ $this->assertSame('fr - vocabulary 3 (i=2)', $config->get('name'));
+ $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_name_much_longer_than');
+ $this->assertSame('Nom de vocabulaire beaucoup plus long que trente-deux caractères', $config->get('name'));
+ $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.tags');
+ $this->assertSame('fr - Tags', $config->get('name'));
+ }
+
+}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Plugin\migrate\source\d6;
+
+use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
+
+/**
+ * Tests taxonomy term source plugin.
+ *
+ * @covers \Drupal\taxonomy\Plugin\migrate\source\d6\Term
+ * @group taxonomy
+ */
+class TermTranslationTest extends MigrateSqlSourceTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['taxonomy', 'migrate_drupal'];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function providerSource() {
+ $tests = [];
+
+ // The source data.
+ $tests[0]['source_data']['term_data'] = [
+ [
+ 'tid' => 1,
+ 'vid' => 5,
+ 'name' => 'name value 1',
+ 'description' => 'description value 1',
+ 'weight' => 0,
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 2,
+ 'vid' => 6,
+ 'name' => 'name value 2',
+ 'description' => 'description value 2',
+ 'weight' => 0,
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 3,
+ 'vid' => 6,
+ 'name' => 'name value 3',
+ 'description' => 'description value 3',
+ 'weight' => 0,
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 4,
+ 'vid' => 5,
+ 'name' => 'name value 4',
+ 'description' => 'description value 4',
+ 'weight' => 1,
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 5,
+ 'vid' => 6,
+ 'name' => 'name value 5',
+ 'description' => 'description value 5',
+ 'weight' => 1,
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 6,
+ 'vid' => 6,
+ 'name' => 'name value 6',
+ 'description' => 'description value 6',
+ 'weight' => 0,
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 10,
+ 'vid' => 6,
+ 'name' => 'zu - name value 2',
+ 'description' => 'zu - description value 2',
+ 'weight' => 0,
+ 'language' => 'zu',
+ 'trid' => 0,
+ ],
+ ];
+ $tests[0]['source_data']['term_hierarchy'] = [
+ [
+ 'tid' => 1,
+ 'parent' => 0,
+ ],
+ [
+ 'tid' => 2,
+ 'parent' => 0,
+ ],
+ [
+ 'tid' => 3,
+ 'parent' => 0,
+ ],
+ [
+ 'tid' => 4,
+ 'parent' => 1,
+ ],
+ [
+ 'tid' => 5,
+ 'parent' => 2,
+ ],
+ [
+ 'tid' => 6,
+ 'parent' => 3,
+ ],
+ [
+ 'tid' => 6,
+ 'parent' => 2,
+ ],
+ [
+ 'tid' => 10,
+ 'parent' => 0,
+ ],
+ ];
+
+ // The expected results.
+ $tests[0]['expected_data'] = [
+ [
+ 'tid' => 1,
+ 'vid' => 5,
+ 'name' => 'name value 1',
+ 'description' => 'description value 1',
+ 'weight' => 0,
+ 'parent' => [0],
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 10,
+ 'vid' => 6,
+ 'name' => 'zu - name value 2',
+ 'description' => 'zu - description value 2',
+ 'weight' => 0,
+ 'parent' => [0],
+ 'language' => 'zu',
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 2,
+ 'vid' => 6,
+ 'name' => 'name value 2',
+ 'description' => 'description value 2',
+ 'weight' => 0,
+ 'parent' => [0],
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 3,
+ 'vid' => 6,
+ 'name' => 'name value 3',
+ 'description' => 'description value 3',
+ 'weight' => 0,
+ 'parent' => [0],
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 4,
+ 'vid' => 5,
+ 'name' => 'name value 4',
+ 'description' => 'description value 4',
+ 'weight' => 1,
+ 'parent' => [1],
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 5,
+ 'vid' => 6,
+ 'name' => 'name value 5',
+ 'description' => 'description value 5',
+ 'weight' => 1,
+ 'parent' => [2],
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ [
+ 'tid' => 6,
+ 'vid' => 6,
+ 'name' => 'name value 6',
+ 'description' => 'description value 6',
+ 'weight' => 0,
+ 'parent' => [3, 2],
+ 'language' => NULL,
+ 'trid' => 0,
+ ],
+ ];
+
+ $tests[0]['expected_count'] = NULL;
+
+ return $tests;
+ }
+
+}
--- /dev/null
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Plugin\migrate\source\d6;
+
+use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
+
+/**
+ * Tests D6 i18n vocabulary source plugin.
+ *
+ * @covers \Drupal\taxonomy\Plugin\migrate\source\d6\VocabularyTranslation
+ * @group taxonomy
+ */
+class VocabularyTranslationTest extends MigrateSqlSourceTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['taxonomy', 'migrate_drupal'];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function providerSource() {
+ $tests = [];
+
+ // The source data.
+ $tests[0][0]['i18n_strings'] = [
+ [
+ 'lid' => 1,
+ 'objectid' => 1,
+ 'type' => 'vocabulary',
+ 'property' => 'name',
+ 'objectindex' => 1,
+ 'format' => 0,
+ ],
+ [
+ 'lid' => 2,
+ 'objectid' => 2,
+ 'type' => 'vocabulary',
+ 'property' => 'name',
+ 'objectindex' => 2,
+ 'format' => 0,
+ ],
+ ];
+
+ $tests[0][0]['locales_target'] = [
+ [
+ 'lid' => 1,
+ 'language' => 'fr',
+ 'translation' => 'fr - vocabulary 1',
+ 'plid' => 0,
+ 'plural' => 0,
+ 'i18n_status' => 0,
+ ],
+ [
+ 'lid' => 2,
+ 'language' => 'fr',
+ 'translation' => 'fr - vocabulary 2',
+ 'plid' => 0,
+ 'plural' => 0,
+ 'i18n_status' => 0,
+ ],
+ ];
+
+ $tests[0][0]['vocabulary'] = [
+ [
+ 'vid' => 1,
+ 'name' => 'vocabulary 1',
+ 'description' => 'description of vocabulary 1',
+ 'help' => 1,
+ 'relations' => 1,
+ 'hierarchy' => 1,
+ 'multiple' => 0,
+ 'required' => 0,
+ 'tags' => 0,
+ 'module' => 'taxonomy',
+ 'weight' => 4,
+ 'language' => '',
+ ],
+ [
+ 'vid' => 2,
+ 'name' => 'vocabulary 2',
+ 'description' => 'description of vocabulary 2',
+ 'help' => 1,
+ 'relations' => 1,
+ 'hierarchy' => 1,
+ 'multiple' => 0,
+ 'required' => 0,
+ 'tags' => 0,
+ 'module' => 'taxonomy',
+ 'weight' => 5,
+ 'language' => '',
+ ],
+ ];
+
+ $tests[0]['expected_results'] = [
+ [
+ 'vid' => 1,
+ 'name' => 'vocabulary 1',
+ 'description' => 'description of vocabulary 1',
+ 'lid' => '1',
+ 'type' => 'vocabulary',
+ 'property' => 'name',
+ 'objectid' => '1',
+ 'lt_lid' => '1',
+ 'translation' => 'fr - vocabulary 1',
+ 'language' => 'fr',
+ ],
+ [
+ 'vid' => 2,
+ 'name' => 'vocabulary 2',
+ 'description' => 'description of vocabulary 2',
+ 'lid' => '2',
+ 'type' => 'vocabulary',
+ 'property' => 'name',
+ 'objectid' => '2',
+ 'lt_lid' => '2',
+ 'translation' => 'fr - vocabulary 2',
+ 'language' => 'fr',
+ ],
+ ];
+ return $tests;
+ }
+
+}
use Drupal\taxonomy\Entity\Term;
use Drupal\KernelTests\KernelTestBase;
-use Drupal\taxonomy\Tests\TaxonomyTestTrait;
+use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait;
/**
* Kernel tests for taxonomy term functions.
namespace Drupal\update\Tests;
+@trigger_error(__NAMESPACE__ . '\UpdateTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\update\Functional\UpdateTestBase', E_USER_DEPRECATED);
+
use Drupal\Core\DrupalKernel;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
* (via the 'update_test_xml_map' variable), and then performs a series of
* assertions that the report matches our expectations given the specific
* initial state and availability scenario.
+ *
+ * @deprecated Scheduled for removal in Drupal 9.0.0.
+ * Use \Drupal\Tests\update\Functional\UpdateTestBase instead.
*/
abstract class UpdateTestBase extends WebTestBase {
* (optional) A string containing the URL to fetch update data from.
* Defaults to 'update-test'.
*
- * @see Drupal\update_test\Controller\UpdateTestController::updateTest()
+ * @see \Drupal\update_test\Controller\UpdateTestController::updateTest()
*/
protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
// Tell the Update Manager module to fetch from the URL provided by
<?php
-namespace Drupal\update\Tests;
+namespace Drupal\Tests\update\Functional;
/**
* Tests the Update Manager module upload via authorize.php functionality.
// Create a local cache so the module is not downloaded from drupal.org.
$cache_directory = _update_manager_cache_directory(TRUE);
- $validArchiveFile = __DIR__ . '/../../tests/update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
+ $validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
copy($validArchiveFile, $cache_directory . '/update_test_new_module.tar.gz');
}
<?php
-namespace Drupal\update\Tests;
+namespace Drupal\Tests\update\Functional;
use Drupal\Core\Url;
use Drupal\Core\Utility\ProjectInfo;
<?php
-namespace Drupal\update\Tests;
+namespace Drupal\Tests\update\Functional;
use Drupal\Core\Url;
+use Drupal\Tests\Traits\Core\CronRunTrait;
/**
* Tests the Update Manager module through a series of functional tests using
*/
class UpdateCoreTest extends UpdateTestBase {
+ use CronRunTrait;
+
/**
* Modules to enable.
*
$this->standardTests();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
+ $this->checkForMetaRefresh();
$this->assertNoText(t('Security update required!'));
$this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.');
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.');
$this->standardTests();
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
+ $this->checkForMetaRefresh();
$this->assertNoText(t('Security update required!'));
$this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.');
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.');
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
+ $this->checkForMetaRefresh();
$this->assertText(t('Checked available update data for one project.'));
$this->drupalGet('admin/modules');
$this->assertNoText(t('There are updates available for your version of Drupal.'));
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
+ $this->checkForMetaRefresh();
$this->assertText(t('Checked available update data for one project.'));
$this->drupalGet('admin/modules');
$this->assertText(t('There are updates available for your version of Drupal.'));
$this->drupalGet('admin/reports/updates');
$this->clickLink(t('Check manually'));
+ $this->checkForMetaRefresh();
$this->assertText(t('Checked available update data for one project.'));
$this->drupalGet('admin/modules');
$this->assertNoText(t('There are updates available for your version of Drupal.'));
<?php
-namespace Drupal\update\Tests;
+namespace Drupal\Tests\update\Functional;
/**
* Tests the update_delete_file_if_stale() function.
--- /dev/null
+<?php
+
+namespace Drupal\Tests\update\Functional;
+
+use Drupal\Core\DrupalKernel;
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Defines some shared functions used by all update tests.
+ *
+ * The overarching methodology of these tests is we need to compare a given
+ * state of installed modules and themes (e.g., version, project grouping,
+ * timestamps, etc) against a current state of what the release history XML
+ * files we fetch say is available. We have dummy XML files (in the
+ * core/modules/update/tests directory) that describe various scenarios of
+ * what's available for different test projects, and we have dummy .info file
+ * data (specified via hook_system_info_alter() in the update_test helper
+ * module) describing what's currently installed. Each test case defines a set
+ * of projects to install, their current state (via the
+ * 'update_test_system_info' variable) and the desired available update data
+ * (via the 'update_test_xml_map' variable), and then performs a series of
+ * assertions that the report matches our expectations given the specific
+ * initial state and availability scenario.
+ */
+abstract class UpdateTestBase extends BrowserTestBase {
+
+ protected function setUp() {
+ parent::setUp();
+
+ // Change the root path which Update Manager uses to install and update
+ // projects to be inside the testing site directory. See
+ // \Drupal\update\UpdateRootFactory::get() for equivalent changes to the
+ // test child site.
+ $request = \Drupal::request();
+ $update_root = $this->container->get('update.root') . '/' . DrupalKernel::findSitePath($request);
+ $this->container->set('update.root', $update_root);
+ \Drupal::setContainer($this->container);
+
+ // Create the directories within the root path within which the Update
+ // Manager will install projects.
+ foreach (drupal_get_updaters() as $updater_info) {
+ $updater = $updater_info['class'];
+ $install_directory = $update_root . '/' . $updater::getRootDirectoryRelativePath();
+ if (!is_dir($install_directory)) {
+ mkdir($install_directory);
+ }
+ }
+ }
+
+ /**
+ * Refreshes the update status based on the desired available update scenario.
+ *
+ * @param $xml_map
+ * Array that maps project names to availability scenarios to fetch. The key
+ * '#all' is used if a project-specific mapping is not defined.
+ * @param $url
+ * (optional) A string containing the URL to fetch update data from.
+ * Defaults to 'update-test'.
+ *
+ * @see \Drupal\update_test\Controller\UpdateTestController::updateTest()
+ */
+ protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
+ // Tell the Update Manager module to fetch from the URL provided by
+ // update_test module.
+ $this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, ['absolute' => TRUE])->toString())->save();
+ // Save the map for UpdateTestController::updateTest() to use.
+ $this->config('update_test.settings')->set('xml_map', $xml_map)->save();
+ // Manually check the update status.
+ $this->drupalGet('admin/reports/updates');
+ $this->clickLink(t('Check manually'));
+ $this->checkForMetaRefresh();
+ }
+
+ /**
+ * Runs a series of assertions that are applicable to all update statuses.
+ */
+ protected function standardTests() {
+ $this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
+ $this->assertRaw(\Drupal::l(t('Drupal'), Url::fromUri('http://example.com/project/drupal')), 'Link to the Drupal project appears.');
+ $this->assertNoText(t('No available releases found'));
+ }
+
+}
<?php
-namespace Drupal\update\Tests;
+namespace Drupal\Tests\update\Functional;
use Drupal\Core\Extension\InfoParserDynamic;
use Drupal\Core\Updater\Updater;
use Drupal\Core\Url;
+use Drupal\Tests\TestFileCreationTrait;
/**
* Tests the Update Manager module's upload and extraction functionality.
*/
class UpdateUploadTest extends UpdateTestBase {
+ use TestFileCreationTrait {
+ getTestFiles as drupalGetTestFiles;
+ }
+
/**
* Modules to enable.
*
// Check to ensure an existing module can't be reinstalled. Also checks that
// the archive was extracted since we can't know if the module is already
// installed until after extraction.
- $validArchiveFile = __DIR__ . '/../../tests/aaa_update_test.tar.gz';
+ $validArchiveFile = __DIR__ . '/../../aaa_update_test.tar.gz';
$edit = [
'files[project_upload]' => $validArchiveFile,
];
$moduleUpdater = $updaters['module']['class'];
$installedInfoFilePath = $this->container->get('update.root') . '/' . $moduleUpdater::getRootDirectoryRelativePath() . '/update_test_new_module/update_test_new_module.info.yml';
$this->assertFalse(file_exists($installedInfoFilePath), 'The new module does not exist in the filesystem before it is installed with the Update Manager.');
- $validArchiveFile = __DIR__ . '/../../tests/update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
+ $validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
$edit = [
'files[project_upload]' => $validArchiveFile,
];
$query->condition('name', $name);
}
$result = $query->execute();
- // If $module, $uid, and $name was passed, return the value.
+ // If $module, $uid, and $name were passed, return the value.
if (isset($name) && isset($uid)) {
$result = $result->fetchAllAssoc('uid');
if (isset($result[$uid])) {
}
return NULL;
}
- // If $module and $uid was passed, return the name/value pairs.
+ // If $module and $uid were passed, return data keyed by name.
elseif (isset($uid)) {
$return = [];
foreach ($result as $record) {
}
return $return;
}
- // If $module and $name was passed, return the uid/value pairs.
+ // If $module and $name were passed, return data keyed by uid.
elseif (isset($name)) {
$return = [];
foreach ($result as $record) {
<?php
-namespace Drupal\user\Tests\Views;
+namespace Drupal\Tests\user\Functional;
+use Drupal\Tests\views_ui\Functional\UITestBase;
use Drupal\views\Tests\ViewTestData;
-use Drupal\views_ui\Tests\UITestBase;
/**
* Tests views role access plugin UI.
*
* @group user
- * @see Drupal\user\Plugin\views\access\Role
+ * @see \Drupal\user\Plugin\views\access\Role
*/
class AccessRoleUITest extends UITestBase {
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
ViewTestData::createTestViews(get_class($this), ['user_test_views']);
}
* Tests user session life cycle.
*/
public function testLogin() {
+ // Without the serialization module only JSON is supported.
+ $this->doTestLogin('json');
+
+ // Enable serialization so we have access to additional formats.
+ $this->container->get('module_installer')->install(['serialization']);
+ $this->doTestLogin('json');
+ $this->doTestLogin('xml');
+ $this->doTestLogin('hal_json');
+ }
+
+ /**
+ * Do login testing for a given serialization format.
+ *
+ * @param string $format
+ * Serialization format.
+ */
+ protected function doTestLogin($format) {
$client = \Drupal::httpClient();
- foreach ([FALSE, TRUE] as $serialization_enabled_option) {
- if ($serialization_enabled_option) {
- /** @var \Drupal\Core\Extension\ModuleInstaller $module_installer */
- $module_installer = $this->container->get('module_installer');
- $module_installer->install(['serialization']);
- $formats = ['json', 'xml', 'hal_json'];
- }
- else {
- // Without the serialization module only JSON is supported.
- $formats = ['json'];
- }
- foreach ($formats as $format) {
- // Create new user for each iteration to reset flood.
- // Grant the user administer users permissions to they can see the
- // 'roles' field.
- $account = $this->drupalCreateUser(['administer users']);
- $name = $account->getUsername();
- $pass = $account->passRaw;
+ // Create new user for each iteration to reset flood.
+ // Grant the user administer users permissions to they can see the
+ // 'roles' field.
+ $account = $this->drupalCreateUser(['administer users']);
+ $name = $account->getUsername();
+ $pass = $account->passRaw;
- $login_status_url = $this->getLoginStatusUrlString($format);
- $response = $client->get($login_status_url);
- $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
+ $login_status_url = $this->getLoginStatusUrlString($format);
+ $response = $client->get($login_status_url);
+ $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
- // Flooded.
- $this->config('user.flood')
- ->set('user_limit', 3)
- ->save();
+ // Flooded.
+ $this->config('user.flood')
+ ->set('user_limit', 3)
+ ->save();
- $response = $this->loginRequest($name, 'wrong-pass', $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
+ $response = $this->loginRequest($name, 'wrong-pass', $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
- $response = $this->loginRequest($name, 'wrong-pass', $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
+ $response = $this->loginRequest($name, 'wrong-pass', $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
- $response = $this->loginRequest($name, 'wrong-pass', $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
+ $response = $this->loginRequest($name, 'wrong-pass', $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
- $response = $this->loginRequest($name, 'wrong-pass', $format);
- $this->assertHttpResponseWithMessage($response, 403, 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.', $format);
+ $response = $this->loginRequest($name, 'wrong-pass', $format);
+ $this->assertHttpResponseWithMessage($response, 403, 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.', $format);
- // After testing the flood control we can increase the limit.
- $this->config('user.flood')
- ->set('user_limit', 100)
- ->save();
+ // After testing the flood control we can increase the limit.
+ $this->config('user.flood')
+ ->set('user_limit', 100)
+ ->save();
- $response = $this->loginRequest(NULL, NULL, $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.', $format);
+ $response = $this->loginRequest(NULL, NULL, $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.', $format);
- $response = $this->loginRequest(NULL, $pass, $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format);
+ $response = $this->loginRequest(NULL, $pass, $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format);
- $response = $this->loginRequest($name, NULL, $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format);
+ $response = $this->loginRequest($name, NULL, $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format);
- // Blocked.
- $account
- ->block()
- ->save();
+ // Blocked.
+ $account
+ ->block()
+ ->save();
- $response = $this->loginRequest($name, $pass, $format);
- $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
+ $response = $this->loginRequest($name, $pass, $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
- $account
- ->activate()
- ->save();
+ $account
+ ->activate()
+ ->save();
- $response = $this->loginRequest($name, 'garbage', $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
+ $response = $this->loginRequest($name, 'garbage', $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
- $response = $this->loginRequest('garbage', $pass, $format);
- $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
+ $response = $this->loginRequest('garbage', $pass, $format);
+ $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
- $response = $this->loginRequest($name, $pass, $format);
- $this->assertEquals(200, $response->getStatusCode());
- $result_data = $this->serializer->decode($response->getBody(), $format);
- $this->assertEquals($name, $result_data['current_user']['name']);
- $this->assertEquals($account->id(), $result_data['current_user']['uid']);
- $this->assertEquals($account->getRoles(), $result_data['current_user']['roles']);
- $logout_token = $result_data['logout_token'];
+ $response = $this->loginRequest($name, $pass, $format);
+ $this->assertEquals(200, $response->getStatusCode());
+ $result_data = $this->serializer->decode($response->getBody(), $format);
+ $this->assertEquals($name, $result_data['current_user']['name']);
+ $this->assertEquals($account->id(), $result_data['current_user']['uid']);
+ $this->assertEquals($account->getRoles(), $result_data['current_user']['roles']);
+ $logout_token = $result_data['logout_token'];
- $response = $client->get($login_status_url, ['cookies' => $this->cookies]);
- $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN);
+ $response = $client->get($login_status_url, ['cookies' => $this->cookies]);
+ $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN);
- $response = $this->logoutRequest($format, $logout_token);
- $this->assertEquals(204, $response->getStatusCode());
+ $response = $this->logoutRequest($format, $logout_token);
+ $this->assertEquals(204, $response->getStatusCode());
- $response = $client->get($login_status_url, ['cookies' => $this->cookies]);
- $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
+ $response = $client->get($login_status_url, ['cookies' => $this->cookies]);
+ $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
- $this->resetFlood();
- }
- }
+ $this->resetFlood();
}
/**
->will($this->returnValue(TRUE));
$config = ['rid' => 'test_role_1'];
- $remove_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType);
+ $add_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType);
- $remove_role_plugin->execute($this->account);
+ $add_role_plugin->execute($this->account);
}
/**
->will($this->returnValue(FALSE));
$config = ['rid' => 'test_role_1'];
- $remove_role_plugin = new AddRoleUser($config, 'user_remove_role_action', ['type' => 'user'], $this->userRoleEntityType);
+ $add_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType);
- $remove_role_plugin->execute($this->account);
+ $add_role_plugin->execute($this->account);
}
}
throw new NotFoundHttpException();
}
$view = $this->executableFactory->get($entity);
- if ($view && $view->access($display_id)) {
+ if ($view && $view->access($display_id) && $view->setDisplay($display_id) && $view->display_handler->getOption('use_ajax')) {
$response->setView($view);
// Fix the current path for paging.
if (!empty($path)) {
* {@inheritdoc}
*/
public function elementClasses($row_index = NULL) {
- $classes = explode(' ', $this->options['element_class']);
+ $classes = $this->tokenizeValue($this->options['element_class'], $row_index);
+ $classes = explode(' ', $classes);
foreach ($classes as &$class) {
- $class = $this->tokenizeValue($class, $row_index);
$class = Html::cleanCssIdentifier($class);
}
return implode(' ', $classes);
* {@inheritdoc}
*/
public function elementLabelClasses($row_index = NULL) {
- $classes = explode(' ', $this->options['element_label_class']);
+ $classes = $this->tokenizeValue($this->options['element_label_class'], $row_index);
+ $classes = explode(' ', $classes);
foreach ($classes as &$class) {
- $class = $this->tokenizeValue($class, $row_index);
$class = Html::cleanCssIdentifier($class);
}
return implode(' ', $classes);
* {@inheritdoc}
*/
public function elementWrapperClasses($row_index = NULL) {
- $classes = explode(' ', $this->options['element_wrapper_class']);
+ $classes = $this->tokenizeValue($this->options['element_wrapper_class'], $row_index);
+ $classes = explode(' ', $classes);
foreach ($classes as &$class) {
- $class = $this->tokenizeValue($class, $row_index);
$class = Html::cleanCssIdentifier($class);
}
return implode(' ', $classes);
class DefaultStyle extends StylePluginBase {
/**
- * Does the style plugin allows to use style plugins.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
class Grid extends StylePluginBase {
/**
- * Does the style plugin allows to use style plugins.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
class HtmlList extends StylePluginBase {
/**
- * Does the style plugin allows to use style plugins.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
class Opml extends StylePluginBase {
/**
- * Does the style plugin for itself support to add fields to its output.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
class Rss extends StylePluginBase {
/**
- * Does the style plugin for itself support to add fields to it's output.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
protected $rowTokens = [];
/**
- * Does the style plugin allows to use style plugins.
+ * Whether or not this style uses a row plugin.
*
* @var bool
*/
protected $usesFields = TRUE;
/**
- * Does the style plugin allows to use style plugins.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = FALSE;
*
* @var array
*/
- public static $testViews = ['test_ajax_view'];
+ public static $testViews = ['test_ajax_view', 'test_view'];
protected function setUp() {
parent::setUp();
$this->assertEqual(count($result), 2, 'Ensure that two items are rendered in the HTML.');
}
+ /**
+ * Ensures that non-ajax view cannot be accessed via an ajax HTTP request.
+ */
+ public function testNonAjaxViewViaAjax() {
+ $this->drupalPost('views/ajax', '', ['view_name' => 'test_ajax_view', 'view_display_id' => 'default'], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+ $this->assertResponse(200);
+ $this->drupalPost('views/ajax', '', ['view_name' => 'test_view', 'view_display_id' => 'default'], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+ $this->assertResponse(403);
+ }
+
}
class StyleTemplateTest extends StylePluginBase {
/**
- * Can the style plugin use row plugins.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
public $output;
/**
- * Can the style plugin use row plugins.
- *
- * @var bool
+ * {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
namespace Drupal\Tests\views\Functional;
-use Drupal\taxonomy\Tests\TaxonomyTestTrait;
+use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait;
/**
* Tests glossary functionality of taxonomy views.
*/
class ViewAjaxControllerTest extends UnitTestCase {
+ const USE_AJAX = TRUE;
+ const USE_NO_AJAX = FALSE;
+
/**
* The mocked view entity storage.
*
list($view, $executable) = $this->setupValidMocks();
- $display_handler = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
- ->disableOriginalConstructor()
- ->getMock();
- // Ensure that the pager element is not set.
- $display_handler->expects($this->never())
- ->method('setOption');
-
- $display_collection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection')
- ->disableOriginalConstructor()
- ->getMock();
- $display_collection->expects($this->any())
- ->method('get')
- ->with('page_1')
- ->will($this->returnValue($display_handler));
-
- $executable->displayHandlers = $display_collection;
-
$this->redirectDestination->expects($this->atLeastOnce())
->method('set')
->with('/test-page?type=article');
$this->assertViewResultCommand($response);
}
+ /**
+ * Tests a valid view without ajax enabled.
+ */
+ public function testAjaxViewWithoutAjax() {
+ $request = new Request();
+ $request->request->set('view_name', 'test_view');
+ $request->request->set('view_display_id', 'page_1');
+ $request->request->set('view_path', '/test-page');
+ $request->request->set('_wrapper_format', 'ajax');
+ $request->request->set('ajax_page_state', 'drupal.settings[]');
+ $request->request->set('type', 'article');
+
+ $this->setupValidMocks(static::USE_NO_AJAX);
+
+ $this->setExpectedException(AccessDeniedHttpException::class);
+ $this->viewAjaxController->ajaxView($request);
+ }
+
/**
* Tests a valid view with arguments.
*/
/**
* Sets up a bunch of valid mocks like the view entity and executable.
+ *
+ * @param bool $use_ajax
+ * Whether the 'use_ajax' option is set on the view display. Defaults to
+ * using ajax (TRUE).
+ *
+ * @return array
+ * A pair of view storage entity and executable.
*/
- protected function setupValidMocks() {
+ protected function setupValidMocks($use_ajax = self::USE_AJAX) {
$view = $this->getMockBuilder('Drupal\views\Entity\View')
->disableOriginalConstructor()
->getMock();
$executable->expects($this->once())
->method('access')
->will($this->returnValue(TRUE));
- $executable->expects($this->once())
+ $executable->expects($this->any())
+ ->method('setDisplay')
+ ->willReturn(TRUE);
+ $executable->expects($this->atMost(1))
->method('preview')
->will($this->returnValue(['#markup' => 'View result']));
->with($view)
->will($this->returnValue($executable));
+ $display_handler = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
+ ->disableOriginalConstructor()
+ ->getMock();
+ // Ensure that the pager element is not set.
+ $display_handler->expects($this->never())
+ ->method('setOption');
+ $display_handler->expects($this->any())
+ ->method('getOption')
+ ->with('use_ajax')
+ ->willReturn($use_ajax);
+
+ $display_collection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $display_collection->expects($this->any())
+ ->method('get')
+ ->with('page_1')
+ ->will($this->returnValue($display_handler));
+
+ $executable->display_handler = $display_handler;
+ $executable->displayHandlers = $display_collection;
+
return [$view, $executable];
}
$this->assertEquals($expected, $field->getRenderTokens([]));
}
+ /**
+ * Ensures proper token replacement when generating CSS classes.
+ *
+ * @covers ::elementClasses
+ * @covers ::elementLabelClasses
+ * @covers ::elementWrapperClasses
+ */
+ public function testElementClassesWithTokens() {
+ $functions = [
+ 'elementClasses' => 'element_class',
+ 'elementLabelClasses' => 'element_label_class',
+ 'elementWrapperClasses' => 'element_wrapper_class',
+ ];
+
+ $tokens = ['test_token' => 'foo'];
+ $test_class = 'test-class-without-token test-class-with-{{ test_token }}-token';
+ $expected_result = 'test-class-without-token test-class-with-foo-token';
+
+ // Inline template to render the tokens.
+ $build = [
+ '#type' => 'inline_template',
+ '#template' => $test_class,
+ '#context' => $tokens,
+ '#post_render' => [function() {}],
+ ];
+
+ // We're not testing the token rendering itself, just that the function
+ // being tested correctly handles tokens when generating the element's class
+ // attribute.
+ $this->renderer->expects($this->any())
+ ->method('renderPlain')
+ ->with($build)
+ ->willReturn($expected_result);
+
+ foreach ($functions as $callable => $option_name) {
+ $field = $this->setupTestField([$option_name => $test_class]);
+ $field->view->style_plugin = new \stdClass();
+ $field->view->style_plugin->render_tokens[] = $tokens;
+
+ $result = $field->{$callable}(0);
+ $this->assertEquals($expected_result, $result);
+ }
+ }
+
}
class FieldPluginBaseTestField extends FieldPluginBase {
$settings->set('ui.show.sql_query.where', 'below')->save();
$this->drupalPostForm(NULL, $edit = ['view_args' => '100'], t('Update preview'));
$this->assertTrue(strpos($this->getRawContent(), 'view-test-preview') < strpos($this->getRawContent(), 'views-query-info'), 'Statistics shown below the preview.');
+
+ // Test that the preview title isn't double escaped.
+ $this->drupalPostForm("admin/structure/views/nojs/display/test_preview/default/title", $edit = ['title' => 'Double & escaped'], t('Apply'));
+ $this->drupalPostForm(NULL, [], t('Update preview'));
+ $elements = $this->xpath('//div[@id="views-live-preview"]/div[contains(@class, views-query-info)]//td[text()=:text]', [':text' => t('Double & escaped')]);
+ $this->assertEqual(1, count($elements));
}
/**
/**
* Provides a base class for testing the Views UI.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.x.
+ * Use \Drupal\Tests\views_ui\Functional\UITestBase.
*/
abstract class UITestBase extends ViewTestBase {
'administer permissions',
]);
$this->drupalLogin($this->fullAdminUser);
+
+ @trigger_error('\Drupal\views_ui\Tests\UITestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.x. Instead, use \Drupal\Tests\views_ui\Functional\UITestBase', E_USER_DEPRECATED);
}
/**
$this->assertIdentical($displays['test_1']['id'], 'test_1', 'New display ID matches the display ID key.');
$this->assertFalse(array_key_exists('attachment_1', $displays), 'Old display ID not found.');
+ // Set to the same machine name and save the View.
+ $edit = ['display_id' => 'test_1'];
+ $this->drupalPostForm('admin/structure/views/nojs/display/test_view/test_1/display_id', $edit, 'Apply');
+ $this->drupalPostForm(NULL, [], 'Save');
+ $this->assertLink(t('test_1'));
+
// Test the form validation with invalid IDs.
$machine_name_edit_url = 'admin/structure/views/nojs/display/test_view/test_1/display_id';
$error_text = t('Display name must be letters, numbers, or underscores only.');
// Rename display ids if needed.
foreach ($executable->displayHandlers as $id => $display) {
- if (!empty($display->display['new_id']) && empty($display->display['deleted'])) {
+ if (!empty($display->display['new_id']) && $display->display['new_id'] !== $display->display['id'] && empty($display->display['deleted'])) {
$new_id = $display->display['new_id'];
$display->display['id'] = $new_id;
unset($display->display['new_id']);
'display_id' => $new_id,
]);
}
+ elseif (isset($display->display['new_id'])) {
+ unset($display->display['new_id']);
+ }
}
$view->set('display', $displays);
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Timer;
-use Drupal\Component\Utility\Xss;
use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Views;
'#template' => "<strong>{% trans 'Title' %}</strong>",
],
],
- Xss::filterAdmin($executable->getTitle()),
+ [
+ 'data' => [
+ '#markup' => $executable->getTitle(),
+ ],
+ ],
];
if (isset($path)) {
// @todo Views should expect and store a leading /. See:
<?php
-namespace Drupal\views_ui\Tests;
-
-use Drupal\views\Tests\ViewTestBase;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the views analyze system.
*
* @group views_ui
*/
-class AnalyzeTest extends ViewTestBase {
+class AnalyzeTest extends UITestBase {
/**
* Modules to enable.
*/
public static $testViews = ['test_view'];
- protected function setUp() {
- parent::setUp();
-
- $this->enableViewsTestModule();
-
- // Add an admin user will full rights;
- $this->admin = $this->drupalCreateUser(['administer views']);
- }
-
/**
* Tests that analyze works in general.
*/
public function testAnalyzeBasic() {
- $this->drupalLogin($this->admin);
+ $this->drupalLogin($this->adminUser);
$this->drupalGet('admin/structure/views/view/test_view/edit');
$this->assertLink(t('Analyze view'));
// This redirects the user to the analyze form.
$this->clickLink(t('Analyze view'));
- $this->assertText(t('View analysis'));
+ $this->assertSession()->titleEquals('View analysis | Drupal');
foreach (['ok', 'warning', 'error'] as $type) {
$xpath = $this->xpath('//div[contains(@class, :class)]', [':class' => $type]);
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\block\Entity\Block;
use Drupal\entity_test\Entity\EntityTest;
$this->drupalGet($view->urlInfo('edit-form'));
// Add a global NULL argument to the view for testing argument placeholders.
- $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/argument", ['name[views.null]' => 1], 'Add and configure contextual filters');
+ $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/argument", ['name[views.null]' => TRUE], 'Add and configure contextual filters');
$this->drupalPostForm(NULL, [], 'Apply');
// Configure both the entity_test area header and the block header to
// reference the given entities.
- $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_block]' => 1], 'Add and configure header');
+ $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_block]' => TRUE], 'Add and configure header');
$this->drupalPostForm(NULL, ['options[target]' => $block->id()], 'Apply');
- $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_entity_test]' => 1], 'Add and configure header');
+ $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_entity_test]' => TRUE], 'Add and configure header');
$this->drupalPostForm(NULL, ['options[target]' => $entity_test->id()], 'Apply');
$this->drupalPostForm(NULL, [], 'Save');
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the user tempstore cache in the UI.
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\views\Views;
$this->{$values['test']}(strpos($output, $values['false']), SafeMarkup::format('Expected custom boolean FALSE value %value in output for %type', ['%value' => $values['false'], '%type' => $type]));
// Assert that we are using the correct template.
- $this->setRawContent($output);
- $this->assertText('llama', 'Loaded the correct views-view-field.html.twig template');
+ $this->assertContains('llama', (string) $output);
}
}
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\Core\Url;
use Drupal\user\Entity\Role;
*/
public static $testViews = ['test_view_status', 'test_page_display_menu', 'test_page_display_arguments'];
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
- protected function setUp() {
- parent::setUp();
-
- $this->drupalPlaceBlock('page_title_block');
+ $this->placeBlock('page_title_block');
}
/**
* failure. Failure also results in a failed assertion.
*/
public function clickViewsOperationLink($label, $unique_href_part) {
- $links = $this->xpath('//a[normalize-space(text())=:label]', [':label' => $label]);
+ $links = $this->xpath('//a[normalize-space(text())=:label]', [':label' => (string) $label]);
foreach ($links as $link_index => $link) {
- $position = strpos($link['href'], $unique_href_part);
+ $position = strpos($link->getAttribute('href'), $unique_href_part);
if ($position !== FALSE) {
$index = $link_index;
break;
}
$this->assertTrue(isset($index), format_string('Link to "@label" containing @part found.', ['@label' => $label, '@part' => $unique_href_part]));
if (isset($index)) {
- return $this->clickLink($label, $index);
+ return $this->clickLink((string) $label, $index);
}
else {
return FALSE;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
* Views used by this test.
*
* @var array
+ * .
*/
public static $testViews = ['test_attachment_ui'];
$this->assertEscaped('<em>Page</em>');
$this->assertNoRaw('<em>Page</em>');
$result = $this->xpath('//a[@id = :id]', [':id' => 'views-attachment-1-displays']);
- $this->assertEqual($result[0]->attributes()->title, t('Page'));
+ $this->assertEqual($result[0]->getAttribute('title'), t('Page'));
$this->drupalPostForm(NULL, [], t('Save'));
$view = Views::getView('test_attachment_ui');
$this->drupalPostForm($attachment_display_url, ['displays[default]' => 1, 'displays[page_1]' => 1], t('Apply'));
$result = $this->xpath('//a[@id = :id]', [':id' => 'views-attachment-1-displays']);
- $this->assertEqual($result[0]->attributes()->title, t('Multiple displays'));
+ $this->assertEqual($result[0]->getAttribute('title'), t('Multiple displays'));
$this->drupalPostForm(NULL, [], t('Save'));
$view = Views::getView('test_attachment_ui');
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the UI for feed display plugin.
$result = $this->xpath('//div[@id="edit-displays"]/div');
$options = [];
foreach ($result as $item) {
- foreach ($item->input->attributes() as $attribute => $value) {
- if ($attribute == 'value') {
- $options[] = (string) $value;
- }
+ $input_node = $item->find('css', 'input');
+ if ($input_node->hasAttribute('value')) {
+ $options[] = $input_node->getAttribute('value');
}
}
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
+
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\menu_link_content\Entity\MenuLinkContent;
+use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
/**
* Tests the UI of generic display path plugin.
* @see \Drupal\views\Plugin\views\display\PathPluginBase
*/
class DisplayPathTest extends UITestBase {
+ use AssertPageCacheContextsAndTagsTrait;
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
- $this->drupalPlaceBlock('page_title_block');
+ $this->placeBlock('page_title_block');
}
/**
$this->drupalGet('admin/structure/views/nojs/display/test_page_display_menu/page_5/menu');
$this->assertResponse(200);
$menu_parent = $this->xpath('//select[@id="edit-menu-parent"]');
- $menu_options = (array) $menu_parent[0]->option;
+ $menu_options = (array) $menu_parent[0]->findAll('css', 'option');
unset($menu_options['@attributes']);
+ // Convert array to make the next assertion possible.
+ $menu_options = array_map(function($element) {
+ return $element->getText();
+ }, $menu_options);
+
$this->assertEqual([
'<User account menu>',
'-- My account',
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
-use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\SafeMarkup;
-use Drupal\Core\Template\Attribute;
use Drupal\views\Entity\View;
use Drupal\views\Views;
$this->drupalPostForm(NULL, [], t('Add @display', ['@display' => 'Block']));
$this->assertText('Block');
$this->assertNoText('Block 2');
-
- // Views has special form handling in views_ui_form_button_was_clicked()
- // to be able to change the submit button text via JS, this simulates what
- // the JS is doing.
- $this->drupalPostForm(NULL, [], NULL, [], [], NULL, '&op=Block');
- $this->assertText('Block');
- $this->assertText('Block 2');
}
/**
$this->drupalGet($path_prefix);
$this->assertFalse($this->xpath('//div[contains(@class, :class)]', [':class' => 'views-display-disabled']), 'Make sure the disabled display css class does not appear after initial adding of a view.');
- $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', '', 'Make sure the disable button is visible.');
- $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', '', 'Make sure the enable button is not visible.');
+ $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', NULL, 'Make sure the disable button is visible.');
+ $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', NULL, 'Make sure the enable button is not visible.');
$this->drupalPostForm(NULL, [], 'Disable Page');
$this->assertTrue($this->xpath('//div[contains(@class, :class)]', [':class' => 'views-display-disabled']), 'Make sure the disabled display css class appears once the display is marked as such.');
- $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', '', 'Make sure the disable button is not visible.');
- $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', '', 'Make sure the enable button is visible.');
+ $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', NULL, 'Make sure the disable button is not visible.');
+ $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', NULL, 'Make sure the enable button is visible.');
$this->drupalPostForm(NULL, [], 'Enable Page');
$this->assertFalse($this->xpath('//div[contains(@class, :class)]', [':class' => 'views-display-disabled']), 'Make sure the disabled display css class does not appears once the display is enabled again.');
}
// Assert that the expected text is found in each area category.
foreach ($areas as $type) {
$element = $this->xpath('//div[contains(@class, :class)]/div', [':class' => $type]);
- $this->assertEqual((string) $element[0], SafeMarkup::format('The selected display type does not use @type plugins', ['@type' => $type]));
+ $this->assertEqual($element[0]->getHtml(), SafeMarkup::format('The selected display type does not use @type plugins', ['@type' => $type]));
}
}
// Test the link text displays 'None' and not 'Block 1'
$this->drupalGet($path);
$result = $this->xpath("//a[contains(@href, :path)]", [':path' => $link_display_path]);
- $this->assertEqual($result[0], t('None'), 'Make sure that the link option summary shows "None" by default.');
+ $this->assertEqual($result[0]->getHtml(), t('None'), 'Make sure that the link option summary shows "None" by default.');
$this->drupalGet($link_display_path);
$this->assertFieldChecked('edit-link-display-0');
$this->drupalGet($path);
$result = $this->xpath("//a[contains(@href, :path)]", [':path' => $link_display_path]);
- $this->assertEqual($result[0], 'Page', 'Make sure that the link option summary shows the right linked display.');
+ $this->assertEqual($result[0]->getHtml(), 'Page', 'Make sure that the link option summary shows the right linked display.');
$this->drupalPostForm($link_display_path, ['link_display' => 'custom_url', 'link_url' => 'a-custom-url'], t('Apply'));
// The form redirects to the master display.
$this->assertFieldByName('link_url', 'a-custom-url');
}
- /**
- * Tests contextual links on Views page displays.
- */
- public function testPageContextualLinks() {
- $this->drupalLogin($this->drupalCreateUser(['administer views', 'access contextual links']));
- $view = View::load('test_display');
- $view->enable()->save();
- $this->container->get('router.builder')->rebuildIfNeeded();
-
- // When no "main content" block is placed, we find a contextual link
- // placeholder for editing just the view.
- $this->drupalGet('test-display');
- $id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en';
- // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
- $this->assertRaw('<div' . new Attribute(['data-contextual-id' => $id]) . '></div>', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id]));
-
- // Get server-rendered contextual links.
- // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks()
- $post = ['ids[0]' => $id];
- $response = $this->drupalPostWithFormat('contextual/render', 'json', $post, ['query' => ['destination' => 'test-display']]);
- $this->assertResponse(200);
- $json = Json::decode($response);
- $this->assertIdentical($json[$id], '<ul class="contextual-links"><li class="entityviewedit-form"><a href="' . base_path() . 'admin/structure/views/view/test_display/edit/page_1">Edit view</a></li></ul>');
-
- // When a "main content" is placed, we still find a contextual link
- // placeholder for editing just the view (not the main content block).
- // @see system_block_view_system_main_block_alter()
- $this->drupalPlaceBlock('system_main_block', ['id' => 'main_content']);
- $this->drupalGet('test-display');
- $id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en';
- // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
- $this->assertRaw('<div' . new Attribute(['data-contextual-id' => $id]) . '></div>', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id]));
- }
-
/**
* Tests that the view status is correctly reflected on the edit form.
*/
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the UI for view duplicate tool.
*/
class DuplicateTest extends UITestBase {
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
- $this->drupalPlaceBlock('page_title_block');
+ $this->placeBlock('page_title_block');
}
/**
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\views\Views;
$edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/age';
$this->drupalGet($edit_handler_url);
$result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/ul/li');
- $this->assertEqual((string) $result[0], '{{ age }} == Age');
+ $this->assertEqual($result[0]->getHtml(), '{{ age }} == Age');
$edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/id';
$this->drupalGet($edit_handler_url);
$result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/ul/li');
- $this->assertEqual((string) $result[0], '{{ age }} == Age');
- $this->assertEqual((string) $result[1], '{{ id }} == ID');
+ $this->assertEqual(trim($result[0]->getHtml()), '{{ age }} == Age');
+ $this->assertEqual(trim($result[1]->getHtml()), '{{ id }} == ID');
$edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/name';
$this->drupalGet($edit_handler_url);
$result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/ul/li');
- $this->assertEqual((string) $result[0], '{{ age }} == Age');
- $this->assertEqual((string) $result[1], '{{ id }} == ID');
- $this->assertEqual((string) $result[2], '{{ name }} == Name');
+ $this->assertEqual(trim($result[0]->getHtml()), '{{ age }} == Age');
+ $this->assertEqual(trim($result[1]->getHtml()), '{{ id }} == ID');
+ $this->assertEqual(trim($result[2]->getHtml()), '{{ name }} == Name');
$result = $this->xpath('//details[@id="edit-options-more"]');
$this->assertEqual(empty($result), TRUE, "Container 'more' is empty and should not be displayed.");
$edit_handler_url = '/admin/structure/views/ajax/handler-group/test_view/default/field/name';
$this->drupalGet($edit_handler_url);
- $data = Json::decode($this->getRawContent());
+ $data = Json::decode($this->getSession()->getPage()->getContent());
$this->assertEqual($data[3]['dialogOptions']['title'], 'Configure aggregation settings for field Views test: Name');
}
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the boolean filter UI.
// Check the field widget label. 'title' should be used as a fallback.
$result = $this->cssSelect('#edit-options-value--wrapper legend span');
- $this->assertEqual((string) $result[0], 'Status');
+ $this->assertEqual($result[0]->getHtml(), 'Status');
$this->drupalPostForm(NULL, [], t('Expose filter'));
$this->drupalPostForm(NULL, [], t('Grouped filters'));
$this->drupalGet('admin/structure/views/nojs/handler/test_view/default/filter/status');
$result = $this->xpath('//input[@name="options[group_info][group_items][1][value]"]');
- $this->assertEqual((int) $result[1]->attributes()->checked, 'checked');
+ $this->assertEqual($result[1]->getAttribute('checked'), 'checked');
$result = $this->xpath('//input[@name="options[group_info][group_items][2][value]"]');
- $this->assertEqual((int) $result[2]->attributes()->checked, 'checked');
+ $this->assertEqual($result[2]->getAttribute('checked'), 'checked');
$result = $this->xpath('//input[@name="options[group_info][group_items][3][value]"]');
- $this->assertEqual((int) $result[1]->attributes()->checked, 'checked');
+ $this->assertEqual($result[1]->getAttribute('checked'), 'checked');
// Test that there is a remove link for each group.
$this->assertEqual(count($this->cssSelect('a.views-remove-link')), 3);
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\Tests\SchemaCheckTestTrait;
* Tests the filter numeric UI.
*/
public function testFilterNumericUI() {
+ // Add a page display to the test_view to be able to test the filtering.
+ $path = 'test_view-path';
+ $this->drupalPostForm('admin/structure/views/view/test_view/edit', [], 'Add Page');
+ $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => $path], 'Apply');
+ $this->drupalPostForm(NULL, [], t('Save'));
+
$this->drupalPostForm('admin/structure/views/nojs/add-handler/test_view/default/filter', ['name[views_test_data.age]' => TRUE], t('Add and configure @handler', ['@handler' => t('filter criteria')]));
$this->drupalPostForm(NULL, [], t('Expose filter'));
$this->assertConfigSchemaByName('views.view.test_view');
// Test that the exposed filter works as expected.
- $this->drupalPostForm(NULL, [], t('Update preview'));
+ $this->drupalGet('test_view-path');
$this->assertText('John');
$this->assertText('Paul');
$this->assertText('Ringo');
$this->assertText('George');
$this->assertText('Meredith');
- $this->drupalPostForm(NULL, ['age' => '2'], t('Update preview'));
+ $this->drupalPostForm(NULL, ['age' => '2'], 'Apply');
$this->assertText('John');
$this->assertText('Paul');
$this->assertNoText('Ringo');
$this->assertConfigSchemaByName('views.view.test_view');
// Test that the filter works as expected.
- $this->drupalPostForm(NULL, [], t('Update preview'));
+ $this->drupalGet('test_view-path');
$this->assertText('John');
$this->assertNoText('Paul');
$this->assertNoText('Ringo');
$this->assertNoText('George');
$this->assertNoText('Meredith');
- $this->drupalPostForm(NULL, ['age' => '26'], t('Update preview'));
+ $this->drupalPostForm(NULL, ['age' => '26'], t('Apply'));
$this->assertNoText('John');
$this->assertText('Paul');
$this->assertNoText('Ringo');
$this->assertRaw('<label for="edit-age-max">And</label>', 'Max field label found');
$this->assertRaw('<label for="edit-age-min">Age between</label>', 'Min field label found');
// Check that the description is shown in the right place.
- $this->assertEqual(trim($this->cssSelect('.form-item-age-min .description')[0]), 'Description of the exposed filter');
+ $this->assertEqual(trim($this->cssSelect('.form-item-age-min .description')[0]->getText()), 'Description of the exposed filter');
}
}
<?php
-namespace Drupal\views_ui\Tests;
-
-use Drupal\views\Tests\ViewTestBase;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests for the filters from the UI.
*
* @group views_ui
*/
-class FilterUITest extends ViewTestBase {
+class FilterUITest extends UITestBase {
/**
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$this->drupalCreateContentType(['type' => 'page']);
- $this->enableViewsTestModule();
}
/**
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests UI of aggregate functionality..
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\field\Entity\FieldConfig;
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
- $this->drupalPlaceBlock('page_title_block');
+ $this->placeBlock('page_title_block');
ViewTestData::createTestViews(get_class($this), ['node_test_views']);
}
$text = 'Broken/missing handler';
- $this->assertIdentical((string) $result[0], $text, 'Ensure the broken handler text was found.');
+ $this->assertIdentical($result[0]->getText(), $text, 'Ensure the broken handler text was found.');
$this->drupalGet($href);
$result = $this->xpath('//h1[@class="page-title"]');
- $this->assertTrue(strpos((string) $result[0], $text) !== FALSE, 'Ensure the broken handler text was found.');
+ $this->assertContains($text, $result[0]->getText(), 'Ensure the broken handler text was found.');
$original_configuration = [
'field' => 'id_broken',
<?php
-namespace Drupal\views_ui\Tests;
-
-use Drupal\simpletest\WebTestBase;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests configuration schema against new views.
*
* @group views_ui
*/
-class NewViewConfigSchemaTest extends WebTestBase {
+class NewViewConfigSchemaTest extends UITestBase {
/**
* Modules to enable.
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests that displays can be correctly overridden via the user interface.
*/
class OverrideDisplaysTest extends UITestBase {
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$this->drupalPlaceBlock('page_title_block');
}
// Confirm that the view block is available in the block administration UI.
$this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default'));
- $this->clickLinkPartialName('Place block');
+ $this->clickLink('Place block');
$this->assertText($view['label']);
// Place the block.
// Confirm that the block is available in the block administration UI.
$this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default'));
- $this->clickLinkPartialName('Place block');
+ $this->clickLink('Place block');
$this->assertText($view['label']);
// Put the block into the first sidebar region, and make sure it will not
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
use Drupal\views\Entity\View;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the redirecting after saving a views.
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
<?php
-namespace Drupal\views_ui\Tests;
-use Drupal\simpletest\WebTestBase;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests existence of the views plugin report.
*
* @group views_ui
*/
-class ReportTest extends WebTestBase {
+class ReportTest extends UITestBase {
/**
* Modules to enable.
*/
protected $adminUser;
- protected function setUp() {
- parent::setUp();
- $this->adminUser = $this->drupalCreateUser(['administer views']);
- }
-
/**
* Tests the existence of the views plugin report.
*/
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests all ui related settings under admin/structure/views/settings.
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$this->drupalPlaceBlock('local_tasks_block');
}
$view['id'] = strtolower($this->randomMachineName());
$this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit'));
- $this->assertFieldById('edit-displays-top-add-display-embed');
+ $this->assertFieldById('edit-displays-top-add-display-embed', NULL);
$edit = [
'ui_show_display_embed' => FALSE,
$this->drupalPostForm(NULL, [], t('Update preview'));
$xpath = $this->xpath('//div[@class="views-query-info"]//pre');
$this->assertEqual(count($xpath), 1, 'The views sql is shown.');
- $this->assertFalse(strpos($xpath[0], 'db_condition_placeholder') !== FALSE, 'No placeholders are shown in the views sql.');
- $this->assertTrue(strpos($xpath[0], "node_field_data.status = '1'") !== FALSE, 'The placeholders in the views sql is replace by the actual value.');
+ $this->assertFalse(strpos($xpath[0]->getText(), 'db_condition_placeholder') !== FALSE, 'No placeholders are shown in the views sql.');
+ $this->assertTrue(strpos($xpath[0]->getText(), "node_field_data.status = '1'") !== FALSE, 'The placeholders in the views sql is replace by the actual value.');
// Test the advanced settings form.
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\views\Views;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\views\Entity\View;
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
/**
* Tests that translated strings in views UI don't override original strings.
*
* @group views_ui
*/
-class TranslatedViewTest extends WebTestBase {
+class TranslatedViewTest extends UITestBase {
/**
* Modules to enable.
*/
protected $adminUser;
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$permissions = [
'administer site configuration',
--- /dev/null
+<?php
+
+namespace Drupal\Tests\views_ui\Functional;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
+
+/**
+ * Provides a base class for testing the Views UI.
+ */
+abstract class UITestBase extends ViewTestBase {
+
+ /**
+ * An admin user with the 'administer views' permission.
+ *
+ * @var \Drupal\user\UserInterface
+ */
+ protected $adminUser;
+
+ /**
+ * An admin user with administrative permissions for views, blocks, and nodes.
+ *
+ * @var \Drupal\user\UserInterface
+ */
+ protected $fullAdminUser;
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = ['node', 'views_ui', 'block', 'taxonomy'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
+
+ $this->enableViewsTestModule();
+
+ $this->adminUser = $this->drupalCreateUser(['administer views']);
+
+ $this->fullAdminUser = $this->drupalCreateUser(['administer views',
+ 'administer blocks',
+ 'bypass node access',
+ 'access user profiles',
+ 'view all revisions',
+ 'administer permissions',
+ ]);
+ $this->drupalLogin($this->fullAdminUser);
+ }
+
+ /**
+ * A helper method which creates a random view.
+ */
+ public function randomView(array $view = []) {
+ // Create a new view in the UI.
+ $default = [];
+ $default['label'] = $this->randomMachineName(16);
+ $default['id'] = strtolower($this->randomMachineName(16));
+ $default['description'] = $this->randomMachineName(16);
+ $default['page[create]'] = TRUE;
+ $default['page[path]'] = $default['id'];
+
+ $view += $default;
+
+ $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit'));
+
+ return $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function drupalGet($path, array $options = [], array $headers = []) {
+ $url = $this->buildUrl($path, $options);
+
+ // Ensure that each nojs page is accessible via ajax as well.
+ if (strpos($url, 'nojs') !== FALSE) {
+ $url = str_replace('nojs', 'ajax', $url);
+ $result = $this->drupalGet($url, $options);
+ $this->assertSession()->statusCodeEquals(200);
+ $this->assertEquals('application/json', $this->getSession()->getResponseHeader('Content-Type'));
+ $this->assertTrue(json_decode($result), 'Ensure that the AJAX request returned valid content.');
+ }
+
+ return parent::drupalGet($path, $options, $headers);
+ }
+
+}
<?php
-namespace Drupal\views_ui\Tests;
-
-use Drupal\views\Tests\ViewTestBase;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests covering Preview of unsaved Views.
*
* @group views_ui
*/
-class UnsavedPreviewTest extends ViewTestBase {
+class UnsavedPreviewTest extends UITestBase {
/**
* Views used by this test.
/**
* Sets up a Drupal site for running functional and integration tests.
*/
- protected function setUp() {
+ protected function setUp($import_test_views = TRUE) {
parent::setUp(FALSE);
$this->adminUser = $this->drupalCreateUser(['administer views']);
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
-use Drupal\simpletest\WebTestBase;
use Drupal\views\Entity\View;
use Drupal\views\Views;
*
* @group views_ui
*/
-class ViewsListTest extends WebTestBase {
+class ViewsListTest extends UITestBase {
/**
* Modules to enable.
/**
* {@inheritdoc}
*/
- protected function setUp() {
- parent::setUp();
+ protected function setUp($import_test_views = TRUE) {
+ parent::setUp($import_test_views);
$this->drupalPlaceBlock('local_tasks_block');
$this->drupalPlaceBlock('local_actions_block');
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
-use Drupal\views\Tests\Wizard\WizardTestBase;
+use Drupal\Tests\views\Functional\Wizard\WizardTestBase;
/**
* Tests the wizard.
<?php
-namespace Drupal\views_ui\Tests;
+namespace Drupal\Tests\views_ui\Functional;
/**
* Tests the Xss vulnerability.
--- /dev/null
+<?php
+
+namespace Drupal\Tests\views_ui\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\simpletest\NodeCreationTrait;
+use Drupal\views\Entity\View;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the display UI.
+ *
+ * @group views_ui
+ */
+class DisplayTest extends JavascriptTestBase {
+
+ use NodeCreationTrait;
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = [
+ 'block',
+ 'contextual',
+ 'node',
+ 'views',
+ 'views_ui',
+ 'views_test_config',
+ ];
+
+ public static $testViews = ['test_content_ajax', 'test_display'];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setUp() {
+ parent::setUp();
+
+ ViewTestData::createTestViews(self::class, ['views_test_config']);
+
+ $admin_user = $this->drupalCreateUser([
+ 'administer site configuration',
+ 'administer views',
+ 'administer nodes',
+ 'access content overview',
+ 'access contextual links',
+ ]);
+
+ // Disable automatic live preview to make the sequence of calls clearer.
+ \Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save();
+ $this->drupalLogin($admin_user);
+ }
+
+ /**
+ * Tests adding a display.
+ */
+ public function testAddDisplay() {
+ $this->drupalGet('admin/structure/views/view/test_content_ajax');
+ $page = $this->getSession()->getPage();
+
+ $page->find('css', '#views-display-menu-tabs .add')->click();
+
+ // Wait for the animation to complete.
+ $this->assertSession()->assertWaitOnAjaxRequest();
+
+ // Add the diplay.
+ $page->find('css', '#edit-displays-top-add-display-block')->click();
+
+ $element = $page->findById('views-display-menu-tabs')->findLink('Block');
+ $this->assertNotEmpty($element);
+ }
+
+ /**
+ * Tests contextual links on Views page displays.
+ */
+ public function testPageContextualLinks() {
+ $view = View::load('test_display');
+ $view->enable()->save();
+ $this->container->get('router.builder')->rebuildIfNeeded();
+
+ // Create node so the view has content and the contextual area is higher
+ // than 0 pixels.
+ $this->drupalCreateContentType(['type' => 'page']);
+ $this->createNode();
+
+ // When no "main content" block is placed, we find a contextual link
+ // placeholder for editing just the view.
+ $this->drupalGet('test-display');
+ $page = $this->getSession()->getPage();
+ $this->assertSession()->assertWaitOnAjaxRequest();
+
+ $selector = '.view-test-display';
+ $this->toggleContextualTriggerVisibility($selector);
+
+ $element = $this->getSession()->getPage()->find('css', $selector);
+ $element->find('css', '.contextual button')->press();
+
+ $contextual_container_id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en';
+ $contextual_container = $page->find('css', '[data-contextual-id="' . $contextual_container_id . '"]');
+ $this->assertNotEmpty($contextual_container);
+
+ $edit_link = $contextual_container->findLink('Edit view');
+ $this->assertNotEmpty($edit_link);
+
+ // When a "main content" is placed, we still find a contextual link
+ // placeholder for editing just the view (not the main content block).
+ // @see system_block_view_system_main_block_alter()
+ $this->drupalPlaceBlock('system_main_block', ['id' => 'main_content']);
+ $contextual_container = $page->find('css', '[data-contextual-id="' . $contextual_container_id . '"]');
+ $this->assertNotEmpty($contextual_container);
+ }
+
+ /**
+ * Toggles the visibility of a contextual trigger.
+ *
+ * @param string $selector
+ * The selector for the element that contains the contextual Rink.
+ */
+ protected function toggleContextualTriggerVisibility($selector) {
+ // Hovering over the element itself with should be enough, but does not
+ // work. Manually remove the visually-hidden class.
+ $this->getSession()->executeScript("jQuery('{$selector} .contextual .trigger').toggleClass('visually-hidden');");
+ }
+
+}
$this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists");
}
+ /**
+ * Tests the assumption that local time is in 'Australia/Sydney'.
+ */
+ public function testLocalTimeZone() {
+ // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php
+ $this->assertEquals('Australia/Sydney', date_default_timezone_get());
+
+ // The 'Australia/Sydney' time zone is also set in
+ // FunctionalTestSetupTrait::initConfig().
+ $config_factory = $this->container->get('config.factory');
+ $value = $config_factory->get('system.date')->get('timezone.default');
+ $this->assertEquals('Australia/Sydney', $value);
+ }
+
}
<?php
-namespace Drupal\system\Tests\Image;
+namespace Drupal\FunctionalTests\Image;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
/**
* Tests image toolkit setup form.
*
* @group Image
*/
-class ToolkitSetupFormTest extends WebTestBase {
+class ToolkitSetupFormTest extends BrowserTestBase {
/**
* Admin user account.
<?php
-namespace Drupal\system\Tests\Image;
+namespace Drupal\FunctionalTests\Image;
/**
* Tests image toolkit functions.
--- /dev/null
+<?php
+
+namespace Drupal\FunctionalTests\Image;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\TestFileCreationTrait;
+
+
+/**
+ * Base class for image manipulation testing.
+ */
+abstract class ToolkitTestBase extends BrowserTestBase {
+
+ use TestFileCreationTrait {
+ getTestFiles as drupalGetTestFiles;
+ }
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = ['image_test'];
+
+ /**
+ * The URI for the file.
+ *
+ * @var string
+ */
+ protected $file;
+
+ /**
+ * The image factory service.
+ *
+ * @var \Drupal\Core\Image\ImageFactory
+ */
+ protected $imageFactory;
+
+ /**
+ * The image object for the test file.
+ *
+ * @var \Drupal\Core\Image\ImageInterface
+ */
+ protected $image;
+
+ protected function setUp() {
+ parent::setUp();
+
+ // Set the image factory service.
+ $this->imageFactory = $this->container->get('image.factory');
+
+ // Pick a file for testing.
+ $file = current($this->drupalGetTestFiles('image'));
+ $this->file = $file->uri;
+
+ // Setup a dummy image to work with.
+ $this->image = $this->getImage();
+
+ // Clear out any hook calls.
+ $this->imageTestReset();
+ }
+
+ /**
+ * Sets up an image with the custom toolkit.
+ *
+ * @return \Drupal\Core\Image\ImageInterface
+ * The image object.
+ */
+ protected function getImage() {
+ $image = $this->imageFactory->get($this->file, 'test');
+ $this->assertTrue($image->isValid(), 'Image file was parsed.');
+ return $image;
+ }
+
+ /**
+ * Assert that all of the specified image toolkit operations were called
+ * exactly once once, other values result in failure.
+ *
+ * @param $expected
+ * Array with string containing with the operation name, e.g. 'load',
+ * 'save', 'crop', etc.
+ */
+ public function assertToolkitOperationsCalled(array $expected) {
+ // If one of the image operations is expected, apply should be expected as
+ // well.
+ $operations = [
+ 'resize',
+ 'rotate',
+ 'crop',
+ 'desaturate',
+ 'create_new',
+ 'scale',
+ 'scale_and_crop',
+ 'my_operation',
+ 'convert',
+ ];
+ if (count(array_intersect($expected, $operations)) > 0 && !in_array('apply', $expected)) {
+ $expected[] = 'apply';
+ }
+
+ // Determine which operations were called.
+ $actual = array_keys(array_filter($this->imageTestGetAllCalls()));
+
+ // Determine if there were any expected that were not called.
+ $uncalled = array_diff($expected, $actual);
+ if (count($uncalled)) {
+ $this->assertTrue(FALSE, SafeMarkup::format('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)]));
+ }
+ else {
+ $this->assertTrue(TRUE, SafeMarkup::format('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)]));
+ }
+
+ // Determine if there were any unexpected calls.
+ // If all unexpected calls are operations and apply was expected, we do not
+ // count it as an error.
+ $unexpected = array_diff($actual, $expected);
+ if (count($unexpected) && (!in_array('apply', $expected) || count(array_intersect($unexpected, $operations)) !== count($unexpected))) {
+ $this->assertTrue(FALSE, SafeMarkup::format('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)]));
+ }
+ else {
+ $this->assertTrue(TRUE, 'No unexpected operations were called.');
+ }
+ }
+
+ /**
+ * Resets/initializes the history of calls to the test toolkit functions.
+ */
+ protected function imageTestReset() {
+ // Keep track of calls to these operations
+ $results = [
+ 'parseFile' => [],
+ 'save' => [],
+ 'settings' => [],
+ 'apply' => [],
+ 'resize' => [],
+ 'rotate' => [],
+ 'crop' => [],
+ 'desaturate' => [],
+ 'create_new' => [],
+ 'scale' => [],
+ 'scale_and_crop' => [],
+ 'convert' => [],
+ ];
+ \Drupal::state()->set('image_test.results', $results);
+ }
+
+ /**
+ * Gets an array of calls to the test toolkit.
+ *
+ * @return array
+ * An array keyed by operation name ('parseFile', 'save', 'settings',
+ * 'resize', 'rotate', 'crop', 'desaturate') with values being arrays of
+ * parameters passed to each call.
+ */
+ protected function imageTestGetAllCalls() {
+ return \Drupal::state()->get('image_test.results') ?: [];
+ }
+
+}
use Drupal\Core\Database\RowCountException;
use Drupal\Core\Database\StatementInterface;
-use Drupal\system\Tests\Database\FakeRecord;
+use Drupal\Tests\system\Functional\Database\FakeRecord;
/**
* Tests the Database system's various fetch capabilities.
*/
public function testQueryFetchClass() {
$records = [];
- $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => 'Drupal\system\Tests\Database\FakeRecord']);
+ $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => FakeRecord::class]);
foreach ($result as $record) {
$records[] = $record;
if ($this->assertTrue($record instanceof FakeRecord, 'Record is an object of class FakeRecord.')) {
use Drupal\Core\Session\AnonymousUserSession;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\entity_test\Entity\EntityTestDefaultAccess;
+use Drupal\entity_test\Entity\EntityTestNoUuid;
use Drupal\entity_test\Entity\EntityTestLabel;
+use Drupal\entity_test\Entity\EntityTestRev;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\user\Entity\User;
*/
class EntityAccessControlHandlerTest extends EntityLanguageTestBase {
+ /**
+ * {@inheritdoc}
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $this->installEntitySchema('entity_test_no_uuid');
+ $this->installEntitySchema('entity_test_rev');
+ }
+
/**
* Asserts entity access correctly grants or denies access.
*/
], $translation);
}
+ /**
+ * Ensures the static access cache works correctly in the absence of an UUID.
+ *
+ * @see entity_test_entity_access()
+ */
+ public function testEntityWithoutUuidAccessCache() {
+ $account = $this->createUser();
+
+ $entity1 = EntityTestNoUuid::create([
+ 'name' => 'Accessible',
+ ]);
+ $entity1->save();
+
+ $entity2 = EntityTestNoUuid::create([
+ 'name' => 'Inaccessible',
+ ]);
+ $entity2->save();
+
+ $this->assertTrue($entity1->access('delete', $account), 'Entity 1 can be deleted.');
+ $this->assertFalse($entity2->access('delete', $account), 'Entity 2 CANNOT be deleted.');
+
+ $entity1
+ ->setName('Inaccessible')
+ ->setNewRevision();
+ $entity1->save();
+
+ $this->assertFalse($entity1->access('delete', $account), 'Entity 1 revision 2 CANNOT be deleted.');
+ }
+
+ /**
+ * Ensures the static access cache works correctly with a UUID and revisions.
+ *
+ * @see entity_test_entity_access()
+ */
+ public function testEntityWithUuidAccessCache() {
+ $account = $this->createUser();
+
+ $entity1 = EntityTestRev::create([
+ 'name' => 'Accessible',
+ ]);
+ $entity1->save();
+
+ $entity2 = EntityTestRev::create([
+ 'name' => 'Inaccessible',
+ ]);
+ $entity2->save();
+
+ $this->assertTrue($entity1->access('delete', $account), 'Entity 1 can be deleted.');
+ $this->assertFalse($entity2->access('delete', $account), 'Entity 2 CANNOT be deleted.');
+
+ $entity1
+ ->setName('Inaccessible')
+ ->setNewRevision();
+ $entity1->save();
+
+ $this->assertFalse($entity1->access('delete', $account), 'Entity 1 revision 2 CANNOT be deleted.');
+ }
+
/**
* Tests hook invocations.
*/
$this->assertEqual($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 0);
}
+ /**
+ * Tests situation where the whitelist cache is deleted mid-request.
+ */
+ public function testWhitelistCacheDeletionMidRequest() {
+ // Prepare database table.
+ $connection = Database::getConnection();
+ $this->fixtures->createTables($connection);
+
+ $memoryCounterBackend = new MemoryCounterBackend();
+
+ // Create AliasManager and Path object.
+ $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
+ $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage);
+ $aliasManager = new AliasManager($aliasStorage, $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
+
+ // Whitelist cache should not exist at all yet.
+ $this->assertFalse($memoryCounterBackend->get('path_alias_whitelist'));
+
+ // Add some aliases for both menu routes we have.
+ $aliasStorage->save('/admin/something', '/' . $this->randomMachineName());
+ $aliasStorage->save('/user/something', '/' . $this->randomMachineName());
+ $aliasManager->cacheClear();
+
+ // Lookup admin path in whitelist. It will query the DB and figure out
+ // that it indeed has an alias, and add it to the internal whitelist and
+ // flag it to be peristed to cache.
+ $this->assertTrue($whitelist->get('admin'));
+
+ // Destruct the whitelist so it persists its cache.
+ $whitelist->destruct();
+ $this->assertEquals($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 1);
+ // Cache data should have data for 'user' and 'admin', even though just
+ // 'admin' was looked up. This is because the cache is primed with all
+ // menu router base paths.
+ $this->assertEquals(['user' => FALSE, 'admin' => TRUE], $memoryCounterBackend->get('path_alias_whitelist')->data);
+ $memoryCounterBackend->resetCounter();
+
+ // Re-initialize the the whitelist and lookup an alias for the 'user' path.
+ // Whitelist should load data from its cache, see that it hasn't done a
+ // check for 'user' yet, perform the check, then mark the result to be
+ // persisted to cache.
+ $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage);
+ $this->assertTrue($whitelist->get('user'));
+
+ // Delete the whitelist cache. This could happen from an outside process,
+ // like a code deployment that performs a cache rebuild.
+ $memoryCounterBackend->delete('path_alias_whitelist');
+
+ // Destruct whitelist so it attempts to save the whitelist data to cache.
+ // However it should recognize that the previous cache entry was deleted
+ // from underneath it and not save anything to cache, to protect from
+ // cache corruption.
+ $whitelist->destruct();
+ $this->assertEquals($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 0);
+ $this->assertFalse($memoryCounterBackend->get('path_alias_whitelist'));
+ $memoryCounterBackend->resetCounter();
+ }
+
}
$this->assertEquals('public', \Drupal::config('system.file')->get('default_scheme'));
}
+ /**
+ * Tests the assumption that local time is in 'Australia/Sydney'.
+ */
+ public function testLocalTimeZone() {
+ // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php
+ $this->assertEquals('Australia/Sydney', date_default_timezone_get());
+ }
+
/**
* {@inheritdoc}
*/
--- /dev/null
+<?php
+
+namespace Drupal\Tests\Core\Block;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Core\Block\BlockManager;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Block\BlockManager
+ *
+ * @group block
+ */
+class BlockManagerTest extends UnitTestCase {
+
+ /**
+ * The block manager under test.
+ *
+ * @var \Drupal\Core\Block\BlockManager
+ */
+ protected $blockManager;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ $cache_backend = $this->prophesize(CacheBackendInterface::class);
+ $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+ $this->blockManager = new BlockManager(new \ArrayObject(), $cache_backend->reveal(), $module_handler->reveal());
+ $this->blockManager->setStringTranslation($this->getStringTranslationStub());
+
+ $discovery = $this->prophesize(DiscoveryInterface::class);
+ // Specify the 'broken' block, as well as 3 other blocks with admin labels
+ // that are purposefully not in alphabetical order.
+ $discovery->getDefinitions()->willReturn([
+ 'broken' => [
+ 'admin_label' => 'Broken/Missing',
+ 'category' => 'Block',
+ ],
+ 'block1' => [
+ 'admin_label' => 'Coconut',
+ 'category' => 'Group 2',
+ ],
+ 'block2' => [
+ 'admin_label' => 'Apple',
+ 'category' => 'Group 1',
+ ],
+ 'block3' => [
+ 'admin_label' => 'Banana',
+ 'category' => 'Group 2',
+ ],
+ ]);
+ // Force the discovery object onto the block manager.
+ $property = new \ReflectionProperty(BlockManager::class, 'discovery');
+ $property->setAccessible(TRUE);
+ $property->setValue($this->blockManager, $discovery->reveal());
+ }
+
+ /**
+ * @covers ::getDefinitions
+ */
+ public function testDefinitions() {
+ $definitions = $this->blockManager->getDefinitions();
+ $this->assertSame(['broken', 'block1', 'block2', 'block3'], array_keys($definitions));
+ }
+
+ /**
+ * @covers ::getSortedDefinitions
+ */
+ public function testSortedDefinitions() {
+ $definitions = $this->blockManager->getSortedDefinitions();
+ $this->assertSame(['block2', 'block3', 'block1'], array_keys($definitions));
+ }
+
+ /**
+ * @covers ::getGroupedDefinitions
+ */
+ public function testGroupedDefinitions() {
+ $definitions = $this->blockManager->getGroupedDefinitions();
+ $this->assertSame(['Group 1', 'Group 2'], array_keys($definitions));
+ $this->assertSame(['block2'], array_keys($definitions['Group 1']));
+ $this->assertSame(['block3', 'block1'], array_keys($definitions['Group 2']));
+ }
+
+}
// invalidation.
$this->cacheBackend->expects($this->at(0))
->method('get')
- ->with($this->cid, TRUE);
+ ->with($this->cid, TRUE)
+ ->will($this->returnValue($cache));
$this->cacheBackend->expects($this->once())
->method('set')
->with($this->cid, [], Cache::PERMANENT, []);
$this->assertEmpty(array_diff_assoc($expected_tests, $stub->testFiles));
}
+ /**
+ * Tests the assumption that local time is in 'Australia/Sydney'.
+ */
+ public function testLocalTimeZone() {
+ // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php
+ $this->assertEquals('Australia/Sydney', date_default_timezone_get());
+ }
+
}
/**