Move all files to 2017/

This commit is contained in:
Oliver Davies 2025-09-29 22:25:17 +01:00
parent ac7370f67f
commit 2875863330
15717 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,6 @@
id: token_module_test
label: 'Token test'
status: true
langcode: en
locked: true
pattern: Y

View file

@ -0,0 +1,37 @@
<?php
namespace Drupal\token_module_test\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Request;
class TokenTreeBrowseController extends ControllerBase {
/**
* Page callback to output a link.
*/
function outputLink(Request $request) {
$build['tree']['#theme'] = 'token_tree_link';
$build['tokenarea'] = [
'#markup' => \Drupal::token()->replace('[current-page:title]'),
'#type' => 'markup',
];
return $build;
}
/**
* Title callback for the page outputting a link.
*
* We are using a title callback instead of directly defining the title in the
* routing YML file. This is so that we could return an array instead of a
* simple string. This allows us to test if [current-page:title] works with
* render arrays and other objects as titles.
*/
public function getTitle() {
return [
'#type' => 'markup',
'#markup' => 'Available Tokens',
];
}
}

View file

@ -0,0 +1,130 @@
langcode: en
status: true
dependencies:
module:
- user
id: token_views_test
label: token_views_test
module: views
description: ''
tag: ''
base_table: users_field_data
base_field: uid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: some
options:
items_per_page: 5
offset: 0
style:
type: default
row:
type: fields
options:
default_field_elements: true
inline: { }
separator: ''
hide_empty: false
fields:
name:
id: name
table: users_field_data
field: name
entity_type: user
entity_field: name
label: ''
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
plugin_id: field
relationship: none
group_type: group
admin_label: ''
exclude: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_alter_empty: true
click_sort_column: value
type: user_name
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
filters: { }
sorts: { }
title: token_views_test
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
filter_groups:
operator: AND
groups: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
tags: { }
block_1:
display_plugin: block
id: block_1
display_title: Block
position: 1
display_options:
display_extenders: { }

View file

@ -0,0 +1,12 @@
type: module
name: Token Module Test
description: Testing module for token functionality.
package: Testing
# core: 8.x
hidden: TRUE
# Information added by Drupal.org packaging script on 2018-09-21
version: '8.x-1.5'
core: '8.x'
project: 'token'
datestamp: 1537557488

View file

@ -0,0 +1,33 @@
<?php
/**
* @file
* Helper module for token tests.
*/
use Drupal\node\NodeInterface;
/**
* Implements hook_page_attachments().
*/
function token_module_test_page_attachments() {
if ($debug = \Drupal::state()->get('token_page_tokens', [])) {
$debug += ['tokens' => [], 'data' => [], 'options' => []];
foreach (array_keys($debug['tokens']) as $token) {
$debug['values'][$token] = \Drupal::token()->replace($token, $debug['data'], $debug['options']);
}
\Drupal::state()->set('token_page_tokens', $debug);
}
}
/**
* Implements hook_ENTITY_TYPE_presave for Node entities.
*/
function token_module_test_node_presave(NodeInterface $node) {
// Transform tokens in the body.
// @see \Drupal\token\Tests\TokenMenuTest::testMenuTokens()
if ($node->hasField('body')) {
$node->body->value = \Drupal::token()
->replace($node->body->value, ['node' => $node]);
}
}

View file

@ -0,0 +1,7 @@
token_module_test.browse:
path: '/token_module_test/browse'
defaults:
_controller: '\Drupal\token_module_test\Controller\TokenTreeBrowseController::outputLink'
_title_callback: '\Drupal\token_module_test\Controller\TokenTreeBrowseController::getTitle'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,13 @@
<?php
/**
* Implements hook_token_info()
*/
function token_module_test_token_info() {
$info['tokens']['node']['colons:in:name'] = [
'name' => t('A test token with colons in the name'),
'description' => NULL,
];
return $info;
}

View file

@ -0,0 +1,23 @@
langcode: de
status: true
dependencies:
module:
- image
- user
id: user.user.default
targetEntityType: user
bundle: user
mode: default
content:
account:
weight: -10
user_picture:
type: image_image
settings:
progress_indicator: throbber
preview_image_style: thumbnail
third_party_settings: { }
weight: -1
timezone:
weight: 6
hidden: { }

View file

@ -0,0 +1,31 @@
id: user.user.user_picture
status: true
langcode: en
entity_type: user
bundle: user
field_name: user_picture
label: Picture
description: 'Your virtual face or picture.'
required: false
default_value: { }
default_value_function: ''
settings:
file_extensions: 'png gif jpg jpeg'
file_directory: pictures
max_filesize: '30 KB'
alt_field: false
title_field: false
max_resolution: 85x85
min_resolution: ''
default_image:
uuid: null
alt: ''
title: ''
width: null
height: null
alt_field_required: false
title_field_required: false
field_type: image
dependencies:
config:
- field.storage.user.user_picture

View file

@ -0,0 +1,25 @@
id: user.user_picture
status: true
langcode: en
field_name: user_picture
entity_type: user
type: image
settings:
uri_scheme: public
default_image:
uuid: null
alt: ''
title: ''
width: null
height: null
module: image
locked: false
cardinality: 1
translatable: false
indexes:
target_id:
- target_id
dependencies:
module:
- image
- user

View file

@ -0,0 +1,14 @@
type: module
name: Token User picture
description: Testing module that provides user pictures field.
package: Testing
# core: 8.x
hidden: TRUE
dependencies:
- image
# Information added by Drupal.org packaging script on 2018-09-21
version: '8.x-1.5'
core: '8.x'
project: 'token'
datestamp: 1537557488

View file

@ -0,0 +1,137 @@
<?php
namespace Drupal\Tests\token\Functional;
use Drupal\block\Entity\Block;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
/**
* Tests URL tokens.
*
* @group token
*/
class UrlTest extends BrowserTestBase {
use AssertPageCacheContextsAndTagsTrait;
/**
* The first testing node.
*
* @var \Drupal\node\NodeInterface
*/
protected $node1;
/**
* The second testing node.
*
* @var \Drupal\node\NodeInterface
*/
protected $node2;
/**
* Modules to install.
*
* @var string[]
*/
public static $modules = ['node', 'token', 'block'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$node_type = NodeType::create(['type' => 'article', 'name' => 'Article']);
$node_type->save();
$this->node1 = Node::create([
'type' => 'article',
'title' => 'Test Node 1',
]);
$this->node1->save();
$this->node2 = Node::create([
'type' => 'article',
'title' => 'Test Node 2',
]);
$this->node2->save();
}
/**
* Creates a block with token for title and tests cache contexts.
*
* @throws \Behat\Mink\Exception\ElementHtmlException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function testBlockUrlTokenReplacement() {
$node1_url = $this->node1->toUrl();
$node2_url = $this->node2->toUrl();
// Using a @dataprovider causes repeated database installations and takes a
// very long time.
$tests = [];
$tests[] = [
'token' => 'prefix_[current-page:url:path]_suffix',
'expected1' => 'prefix_/' . $node1_url->getInternalPath() . '_suffix',
'expected2' => 'prefix_/' . $node2_url->getInternalPath() . '_suffix',
// A path can only be generated from a routed path.
'expected3' => 'prefix_/_suffix',
];
$tests[] = [
'token' => 'prefix_[current-page:url]_suffix',
'expected1' => 'prefix_' . $node1_url->setAbsolute()->toString() . '_suffix',
'expected2' => 'prefix_' . $node2_url->setAbsolute()->toString() . '_suffix',
'expected3' => 'prefix_' . $this->getAbsoluteUrl('does-not-exist') . '_suffix',
];
// Place a standard block and use a token in the label.
$edit = [
'id' => 'token_url_test_block',
'label' => 'label',
'label_display' => TRUE,
];
$this->placeBlock('system_powered_by_block', $edit);
$block = Block::load('token_url_test_block');
$assert_session = $this->assertSession();
foreach ($tests as $test) {
// Set the block label.
$block->getPlugin()->setConfigurationValue('label', $test['token']);
$block->save();
// Go to the first node page and test that the token is correct.
$this->drupalGet($node1_url);
$assert_session->elementContains('css', '#block-token-url-test-block', $test['expected1']);
// Go to the second node page and check that the block title has changed.
$this->drupalGet($node2_url);
$assert_session->elementContains('css', '#block-token-url-test-block', $test['expected2']);
// Test the current page url on a 404 page.
$this->drupalGet('does-not-exist');
$assert_session->statusCodeEquals(404);
$assert_session->elementContains('css', '#block-token-url-test-block', $test['expected3']);
}
// Can't do this test in the for loop above, it's too different.
$block->getPlugin()->setConfigurationValue('label', 'prefix_[current-page:query:unicorns]_suffix');
$block->save();
// Test the parameter token.
$this->drupalGet($node1_url->setOption('query', ['unicorns' => 'fluffy']));
$this->assertCacheContext('url.query_args');
$assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_fluffy_suffix');
// Change the parameter on the same page.
$this->drupalGet($node1_url->setOption('query', ['unicorns' => 'dead']));
$assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_dead_suffix');
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace Drupal\Tests\token\Kernel;
/**
* Tests array tokens.
*
* @group token
*/
class ArrayTest extends KernelTestBase {
function testArrayTokens() {
// Test a simple array.
$array = [0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd'];
$tokens = [
'first' => 'a',
'last' => 'd',
'value:0' => 'a',
'value:2' => 'c',
'count' => 4,
'keys' => '0, 1, 2, 4',
'keys:value:3' => '4',
'keys:join' => '0124',
'reversed' => 'd, c, b, a',
'reversed:keys' => '4, 2, 1, 0',
'join:/' => 'a/b/c/d',
'join' => 'abcd',
'join:, ' => 'a, b, c, d',
'join: ' => 'a b c d',
];
$this->assertTokens('array', ['array' => $array], $tokens);
// Test a mixed simple and render array.
// 2 => c, 0 => a, 4 => d, 1 => b
$array = [
'#property' => 'value',
0 => 'a',
1 => ['#markup' => 'b', '#weight' => 0.01],
2 => ['#markup' => 'c', '#weight' => -10],
4 => ['#markup' => 'd', '#weight' => 0],
];
$tokens = [
'first' => 'c',
'last' => 'b',
'value:0' => 'a',
'value:2' => 'c',
'count' => 4,
'keys' => '2, 0, 4, 1',
'keys:value:3' => '1',
'keys:join' => '2041',
'reversed' => 'b, d, a, c',
'reversed:keys' => '1, 4, 0, 2',
'join:/' => 'c/a/d/b',
'join' => 'cadb',
'join:, ' => 'c, a, d, b',
'join: ' => 'c a d b',
];
$this->assertTokens('array', ['array' => $array], $tokens);
}
}

View file

@ -0,0 +1,108 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\node\Entity\Node;
use Drupal\Core\Url;
/**
* Test the book tokens.
*
* @group token
*/
class BookTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['user', 'field', 'filter', 'text', 'node', 'book'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('node');
$this->installSchema('book', ['book']);
$this->installSchema('node', ['node_access']);
$this->installConfig(['node', 'book', 'field']);
}
function testBookTokens() {
$book = Node::create([
'type' => 'book',
'title' => 'Book Main Page',
'book' => ['bid' => 'new'],
]);
$book->save();
$page1 = Node::create([
'type' => 'book',
'title' => '1st Page',
'book' => ['bid' => $book->id(), 'pid' => $book->id()],
]);
$page1->save();
$page2 = Node::create([
'type' => 'book',
'title' => '2nd Page',
'book' => ['bid' => $book->id(), 'pid' => $page1->id()],
]);
$page2->save();
$book_title = $book->getTitle();
$tokens = [
'nid' => $book->id(),
'title' => $book_title,
'book:title' => $book_title,
'book:root' => $book_title,
'book:root:nid' => $book->id(),
'book:root:title' => $book_title,
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:root:content-type' => 'Book page',
'book:parent' => null,
'book:parents' => null,
];
$this->assertTokens('node', ['node' => $book], $tokens);
$tokens = [
'nid' => $page1->id(),
'title' => $page1->getTitle(),
'book:title' => $book_title,
'book:root' => $book_title,
'book:root:nid' => $book->id(),
'book:root:title' => $book_title,
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:root:content-type' => 'Book page',
'book:parent:nid' => $book->id(),
'book:parent:title' => $book_title,
'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:parents:count' => 1,
'book:parents:join:/' => $book_title,
];
$this->assertTokens('node', ['node' => $page1], $tokens);
$tokens = [
'nid' => $page2->id(),
'title' => $page2->getTitle(),
'book:title' => $book_title,
'book:root' => $book_title,
'book:root:nid' => $book->id(),
'book:root:title' => $book_title,
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:root:content-type' => 'Book page',
'book:parent:nid' => $page1->id(),
'book:parent:title' => $page1->getTitle(),
'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], ['absolute' => TRUE])->toString(),
'book:parents:count' => 2,
'book:parents:join:/' => $book_title . '/' . $page1->getTitle(),
];
$this->assertTokens('node', ['node' => $page2], $tokens);
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\comment\Entity\Comment;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Core\Url;
/**
* Tests comment tokens.
*
* @group token
*/
class CommentTest extends KernelTestBase {
use CommentTestTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['node', 'comment', 'field', 'text', 'entity_reference'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('node');
$this->installEntitySchema('user');
$this->installEntitySchema('comment');
$this->installSchema('comment', ['comment_entity_statistics']);
$node_type = NodeType::create(['type' => 'page', 'name' => t('Page')]);
$node_type->save();
$this->installConfig(['comment']);
$this->addDefaultCommentField('node', 'page');
}
function testCommentTokens() {
$node = Node::create([
'type' => 'page',
'title' => $this->randomMachineName()
]);
$node->save();
$parent_comment = Comment::create([
'entity_id' => $node->id(),
'entity_type' => 'node',
'field_name' => 'comment',
'name' => 'anonymous user',
'mail' => 'anonymous@example.com',
'subject' => $this->randomMachineName(),
'body' => $this->randomMachineName(),
]);
$parent_comment->save();
// Fix http://example.com/index.php/comment/1 fails 'url:path' test.
$parent_comment_path = $parent_comment->url();
$tokens = [
'url' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
'url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
'url:relative' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(),
'url:path' => $parent_comment_path,
'parent:url:absolute' => NULL,
];
$this->assertTokens('comment', ['comment' => $parent_comment], $tokens);
$comment = Comment::create([
'entity_id' => $node->id(),
'pid' => $parent_comment->id(),
'entity_type' => 'node',
'field_name' => 'comment',
'name' => 'anonymous user',
'mail' => 'anonymous@example.com',
'subject' => $this->randomMachineName(),
'body' => $this->randomMachineName(),
]);
$comment->save();
// Fix http://example.com/index.php/comment/1 fails 'url:path' test.
$comment_path = Url::fromRoute('entity.comment.canonical', ['comment' => $comment->id()])->toString();
$tokens = [
'url' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
'url:absolute' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
'url:relative' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(),
'url:path' => $comment_path,
'parent:url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
];
$this->assertTokens('comment', ['comment' => $comment], $tokens);
}
}

View file

@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\token\Kernel;
/**
* Tests date tokens.
*
* @group token
*/
class DateTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['system', 'token_module_test']);
}
function testDateTokens() {
$tokens = [
'token_module_test' => '1984',
'invalid_format' => NULL,
];
$this->assertTokens('date', ['date' => 453859200], $tokens);
}
}

View file

@ -0,0 +1,106 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\taxonomy\VocabularyInterface;
/**
* Tests entity tokens.
*
* @group token
*/
class EntityTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['node', 'taxonomy', 'text'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
// Create the default tags vocabulary.
$vocabulary = Vocabulary::create([
'name' => 'Tags',
'vid' => 'tags',
]);
$vocabulary->save();
$this->installEntitySchema('taxonomy_term');
$this->installEntitySchema('user');
$this->installEntitySchema('node');
$this->vocab = $vocabulary;
}
function testEntityMapping() {
/** @var \Drupal\token\TokenEntityMapperInterface $mapper */
$mapper = \Drupal::service('token.entity_mapper');
$this->assertIdentical($mapper->getEntityTypeForTokenType('node'), 'node');
$this->assertIdentical($mapper->getEntityTypeForTokenType('term'), 'taxonomy_term');
$this->assertIdentical($mapper->getEntityTypeForTokenType('vocabulary'), 'taxonomy_vocabulary');
$this->assertIdentical($mapper->getEntityTypeForTokenType('invalid'), FALSE);
$this->assertIdentical($mapper->getEntityTypeForTokenType('invalid', TRUE), 'invalid');
$this->assertIdentical($mapper->getTokenTypeForEntityType('node'), 'node');
$this->assertIdentical($mapper->getTokenTypeForEntityType('taxonomy_term'), 'term');
$this->assertIdentical($mapper->getTokenTypeForEntityType('taxonomy_vocabulary'), 'vocabulary');
$this->assertIdentical($mapper->getTokenTypeForEntityType('invalid'), FALSE);
$this->assertIdentical($mapper->getTokenTypeForEntityType('invalid', TRUE), 'invalid');
// Test that when we send the mis-matched entity type into
// Drupal\Core\Utility\Token::replace() that we still get the tokens
// replaced.
$vocabulary = Vocabulary::load('tags');
$term = $this->addTerm($vocabulary);
$this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', ['taxonomy_vocabulary' => $vocabulary]), $vocabulary->label());
$this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', ['taxonomy_term' => $term]), $term->label() . $vocabulary->label());
}
function addTerm(VocabularyInterface $vocabulary, array $term = []) {
$term += [
'name' => mb_strtolower($this->randomMachineName(5)),
'vid' => $vocabulary->id(),
];
$term = Term::create($term);
$term->save();
return $term;
}
/**
* Test the [entity:original:*] tokens.
*/
function testEntityOriginal() {
$node = Node::create(['type' => 'page', 'title' => 'Original title']);
$node->save();
$tokens = [
'nid' => $node->id(),
'title' => 'Original title',
'original' => NULL,
'original:nid' => NULL,
];
$this->assertTokens('node', ['node' => $node], $tokens);
// Emulate the original entity property that would be available from
// node_save() and change the title for the node.
$node->original = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($node->id());
$node->title = 'New title';
$tokens = [
'nid' => $node->id(),
'title' => 'New title',
'original' => 'Original title',
'original:nid' => $node->id(),
];
$this->assertTokens('node', ['node' => $node], $tokens);
}
}

View file

@ -0,0 +1,731 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\Component\Utility\Unicode;
use Drupal\contact\Entity\ContactForm;
use Drupal\Core\Entity\Entity\EntityViewMode;
use Drupal\Core\Render\Markup;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\filter\Entity\FilterFormat;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\contact\Entity\Message;
use Drupal\Component\Utility\Html;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait;
/**
* Tests field tokens.
*
* @group token
*/
class FieldTest extends KernelTestBase {
use TaxonomyTestTrait;
/**
* @var \Drupal\filter\FilterFormatInterface
*/
protected $testFormat;
/**
* Vocabulary for testing chained token support.
*
* @var \Drupal\taxonomy\VocabularyInterface
*/
protected $vocabulary;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['node', 'text', 'field', 'filter', 'contact', 'options', 'taxonomy', 'language', 'datetime', 'datetime_range'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('node');
$this->installEntitySchema('taxonomy_term');
// Create the article content type with a text field.
$node_type = NodeType::create([
'type' => 'article',
]);
$node_type->save();
$field_storage = FieldStorageConfig::create([
'field_name' => 'test_field',
'entity_type' => 'node',
'type' => 'text',
]);
$field_storage->save();
$field = FieldConfig::create([
'field_name' => 'test_field',
'entity_type' => 'node',
'bundle' => 'article',
'label' => 'Test field',
]);
$field->save();
// Create a reference field with the same name on user.
$field_storage = FieldStorageConfig::create([
'field_name' => 'test_field',
'entity_type' => 'user',
'type' => 'entity_reference',
]);
$field_storage->save();
$field = FieldConfig::create([
'field_name' => 'test_field',
'entity_type' => 'user',
'bundle' => 'user',
'label' => 'Test field',
]);
$field->save();
$this->testFormat = FilterFormat::create([
'format' => 'test',
'weight' => 1,
'filters' => [
'filter_html_escape' => ['status' => TRUE],
],
]);
$this->testFormat->save();
// Create a multi-value list_string field.
$field_storage = FieldStorageConfig::create([
'field_name' => 'test_list',
'entity_type' => 'node',
'type' => 'list_string',
'cardinality' => 2,
'settings' => [
'allowed_values' => [
'key1' => 'value1',
'key2' => 'value2',
]
],
]);
$field_storage->save();
$this->field = FieldConfig::create([
'field_name' => 'test_list',
'entity_type' => 'node',
'bundle' => 'article',
])->save();
// Add an untranslatable node reference field.
FieldStorageConfig::create([
'field_name' => 'test_reference',
'type' => 'entity_reference',
'entity_type' => 'node',
'settings' => [
'target_type' => 'node',
],
'translatable' => FALSE,
])->save();
FieldConfig::create([
'field_name' => 'test_reference',
'entity_type' => 'node',
'bundle' => 'article',
'label' => 'Test reference',
])->save();
// Add an untranslatable taxonomy term reference field.
$this->vocabulary = $this->createVocabulary();
FieldStorageConfig::create([
'field_name' => 'test_term_reference',
'type' => 'entity_reference',
'entity_type' => 'node',
'settings' => [
'target_type' => 'taxonomy_term',
],
'translatable' => FALSE,
])->save();
FieldConfig::create([
'field_name' => 'test_term_reference',
'entity_type' => 'node',
'bundle' => 'article',
'label' => 'Test term reference',
'settings' => [
'handler' => 'default:taxonomy_term',
'handler_settings' => [
'target_bundles' => [
$this->vocabulary->id() => $this->vocabulary->id(),
],
],
],
])->save();
// Add a field to terms of the created vocabulary.
$storage = FieldStorageConfig::create([
'field_name' => 'term_field',
'entity_type' => 'taxonomy_term',
'type' => 'text',
]);
$storage->save();
$field = FieldConfig::create([
'field_name' => 'term_field',
'entity_type' => 'taxonomy_term',
'bundle' => $this->vocabulary->id(),
]);
$field->save();
// Add a second language.
$language = ConfigurableLanguage::create([
'id' => 'de',
'label' => 'German',
]);
$language->save();
// Add a datetime field.
$field_datetime_storage = FieldStorageConfig::create([
'field_name' => 'field_datetime',
'type' => 'datetime',
'entity_type' => 'node',
'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATETIME],
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
]);
$field_datetime_storage->save();
$field_datetime = FieldConfig::create([
'field_storage' => $field_datetime_storage,
'bundle' => 'article',
]);
$field_datetime->save();
// Add a daterange field.
$field_daterange_storage = FieldStorageConfig::create([
'field_name' => 'field_daterange',
'type' => 'daterange',
'entity_type' => 'node',
'settings' => ['datetime_type' => DateRangeItem::DATETIME_TYPE_DATETIME],
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
]);
$field_daterange_storage->save();
$field_daterange = FieldConfig::create([
'field_storage' => $field_daterange_storage,
'bundle' => 'article',
]);
$field_daterange->save();
}
/**
* Tests [entity:field_name] tokens.
*/
public function testEntityFieldTokens() {
// Create a node with a value in its fields and test its tokens.
$entity = Node::create([
'title' => 'Test node title',
'type' => 'article',
'test_field' => [
'value' => 'foo',
'format' => $this->testFormat->id(),
],
'test_list' => [
'value1',
'value2',
],
]);
$entity->save();
$this->assertTokens('node', ['node' => $entity], [
'test_field' => Markup::create('foo'),
'test_field:0' => Markup::create('foo'),
'test_field:0:value' => 'foo',
'test_field:value' => 'foo',
'test_field:0:format' => $this->testFormat->id(),
'test_field:format' => $this->testFormat->id(),
'test_list:0' => Markup::create('value1'),
'test_list:1' => Markup::create('value2'),
'test_list:0:value' => Markup::create('value1'),
'test_list:value' => Markup::create('value1'),
'test_list:1:value' => Markup::create('value2'),
]);
// Verify that no third token was generated for the list_string field.
$this->assertNoTokens('node', ['node' => $entity], [
'test_list:2',
'test_list:2:value',
]);
// Test the test_list token metadata.
$tokenService = \Drupal::service('token');
$token_info = $tokenService->getTokenInfo('node', 'test_list');
$this->assertEqual($token_info['name'], 'test_list');
$this->assertEqual($token_info['module'], 'token');
$this->assertEqual($token_info['type'], 'list<node-test_list>');
$typeInfo = $tokenService->getTypeInfo('list<node-test_list>');
$this->assertEqual($typeInfo['name'], 'List of test_list values');
$this->assertEqual($typeInfo['type'], 'list<node-test_list>');
// Create a node type that does not have test_field field.
$node_type = NodeType::create([
'type' => 'page',
]);
$node_type->save();
$node_without_test_field = Node::create([
'title' => 'Node without test_field',
'type' => 'page',
]);
$node_without_test_field->save();
// Ensure that trying to generate tokens for a non-existing field does not
// throw an exception.
$this->assertNoTokens('node', ['node' => $node_without_test_field], ['test_field']);
// Create a node without a value in the text field and test its token.
$entity = Node::create([
'title' => 'Test node title',
'type' => 'article',
]);
$entity->save();
$this->assertNoTokens('node', ['node' => $entity], [
'test_field',
]);
}
/**
* Tests the token metadata for a field token.
*/
public function testFieldTokenInfo() {
/** @var \Drupal\token\Token $tokenService */
$tokenService = \Drupal::service('token');
// Test the token info of the text field of the artcle content type.
$token_info = $tokenService->getTokenInfo('node', 'test_field');
$this->assertEqual($token_info['name'], 'Test field', 'The token info name is correct.');
$this->assertEqual($token_info['description'], 'Text (formatted) field.', 'The token info description is correct.');
$this->assertEqual($token_info['module'], 'token', 'The token info module is correct.');
// Now create two more content types that share the field but the last
// of them sets a different label. This should show an alternative label
// at the token info.
$node_type = NodeType::create([
'type' => 'article2',
]);
$node_type->save();
$field = FieldConfig::create([
'field_name' => 'test_field',
'entity_type' => 'node',
'bundle' => 'article2',
'label' => 'Test field',
]);
$field->save();
$node_type = NodeType::create([
'type' => 'article3',
]);
$node_type->save();
$field = FieldConfig::create([
'field_name' => 'test_field',
'entity_type' => 'node',
'bundle' => 'article3',
'label' => 'Different test field',
]);
$field->save();
$token_info = $tokenService->getTokenInfo('node', 'test_field');
$this->assertEqual($token_info['name'], 'Test field', 'The token info name is correct.');
$this->assertEqual((string) $token_info['description'], 'Text (formatted) field. Also known as <em class="placeholder">Different test field</em>.', 'When a field is used in several bundles with different labels, this is noted at the token info description.');
$this->assertEqual($token_info['module'], 'token', 'The token info module is correct.');
$this->assertEqual($token_info['type'], 'node-test_field', 'The field property token info type is correct.');
// Test field property token info.
$token_info = $tokenService->getTokenInfo('node-test_field', 'value');
$this->assertEqual($token_info['name'], 'Text', 'The field property token info name is correct.');
// This particular field property description happens to be empty.
$this->assertEqual((string) $token_info['description'], '', 'The field property token info description is correct.');
$this->assertEqual($token_info['module'], 'token', 'The field property token info module is correct.');
}
/**
* Test tokens on node with the token view mode overriding default formatters.
*/
public function testTokenViewMode() {
$value = 'A really long string that should be trimmed by the special formatter on token view we are going to have.';
// The formatter we are going to use will eventually call Unicode::strlen.
// This expects that the Unicode has already been explicitly checked, which
// happens in DrupalKernel. But since that doesn't run in kernel tests, we
// explicitly call this here.
Unicode::check();
// Create a node with a value in the text field and test its token.
$entity = Node::create([
'title' => 'Test node title',
'type' => 'article',
'test_field' => [
'value' => $value,
'format' => $this->testFormat->id(),
],
]);
$entity->save();
$this->assertTokens('node', ['node' => $entity], [
'test_field' => Markup::create($value),
]);
// Now, create a token view mode which sets a different format for
// test_field. When replacing tokens, this formatter should be picked over
// the default formatter for the field type.
// @see field_tokens().
$view_mode = EntityViewMode::create([
'id' => 'node.token',
'targetEntityType' => 'node',
]);
$view_mode->save();
$entity_display = entity_get_display('node', 'article', 'token');
$entity_display->setComponent('test_field', [
'type' => 'text_trimmed',
'settings' => [
'trim_length' => 50,
]
]);
$entity_display->save();
$this->assertTokens('node', ['node' => $entity], [
'test_field' => Markup::create(substr($value, 0, 50)),
]);
}
/**
* Test that tokens are properly created for an entity's base fields.
*/
public function testBaseFieldTokens() {
// Create a new contact_message entity and verify that tokens are generated
// for its base fields. The contact_message entity type is used because it
// provides no tokens by default.
$contact_form = ContactForm::create([
'id' => 'form_id',
]);
$contact_form->save();
$entity = Message::create([
'contact_form' => 'form_id',
'uuid' => '123',
'langcode' => 'en',
'name' => 'Test name',
'mail' => 'Test mail',
'subject' => 'Test subject',
'message' => 'Test message',
'copy' => FALSE,
]);
$entity->save();
$this->assertTokens('contact_message', ['contact_message' => $entity], [
'uuid' => Markup::create('123'),
'langcode' => Markup::create('English'),
'name' => Markup::create('Test name'),
'mail' => Markup::create('Test mail'),
'subject' => Markup::create('Test subject'),
'message' => Markup::create('Test message'),
'copy' => 'Off',
]);
// Test the metadata of one of the tokens.
$tokenService = \Drupal::service('token');
$token_info = $tokenService->getTokenInfo('contact_message', 'subject');
$this->assertEquals($token_info['name'], 'Subject');
$this->assertEquals($token_info['description'], 'Text (plain) field.');
$this->assertEquals($token_info['module'], 'token');
// Verify that node entity type doesn't have a uid token.
$this->assertNull($tokenService->getTokenInfo('node', 'uid'));
}
/*
* Tests chaining entity reference tokens.
*/
public function testEntityReferenceTokens() {
$reference = Node::create([
'title' => 'Test node to reference',
'type' => 'article',
'test_field' => [
'value' => 'foo',
'format' => $this->testFormat->id(),
]
]);
$reference->save();
$term_reference_field_value = $this->randomString();
$term_reference = $this->createTerm($this->vocabulary, [
'name' => 'Term to reference',
'term_field' => [
'value' => $term_reference_field_value,
'format' => $this->testFormat->id(),
],
]);
$entity = Node::create([
'title' => 'Test entity reference',
'type' => 'article',
'test_reference' => ['target_id' => $reference->id()],
'test_term_reference' => ['target_id' => $term_reference->id()],
]);
$entity->save();
$this->assertTokens('node', ['node' => $entity], [
'test_reference:entity:title' => Markup::create('Test node to reference'),
'test_reference:entity:test_field' => Markup::create('foo'),
'test_term_reference:entity:term_field' => Html::escape($term_reference_field_value),
'test_reference:target_id' => $reference->id(),
'test_term_reference:target_id' => $term_reference->id(),
'test_term_reference:entity:url:path' => '/' . $term_reference->toUrl('canonical')->getInternalPath(),
// Expects the entity's label to be returned for :entity tokens.
'test_reference:entity' => $reference->label(),
'test_term_reference:entity' => $term_reference->label(),
]);
// Test some non existent tokens.
$this->assertNoTokens('node', ['node' => $entity], [
'test_reference:1:title',
'test_reference:entity:does_not_exist',
'test_reference:does_not:exist',
'test_term_reference:does_not_exist',
'test_term_reference:does:not:exist',
'test_term_reference:does_not_exist:0',
'non_existing_field:entity:title',
]);
/** @var \Drupal\token\Token $token_service */
$token_service = \Drupal::service('token');
$token_info = $token_service->getTokenInfo('node', 'test_reference');
$this->assertEquals('Test reference', $token_info['name']);
$this->assertEquals('Entity reference field.', (string) $token_info['description']);
$this->assertEquals('token', $token_info['module']);
$this->assertEquals('node-test_reference', $token_info['type']);
// Test target_id field property token info.
$token_info = $token_service->getTokenInfo('node-test_reference', 'target_id');
$this->assertEquals('Content ID', $token_info['name']);
$this->assertEquals('token', $token_info['module']);
$this->assertEquals('token', $token_info['module']);
// Test entity field property token info.
$token_info = $token_service->getTokenInfo('node-test_reference', 'entity');
$this->assertEquals('Content', $token_info['name']);
$this->assertEquals('The referenced entity', $token_info['description']);
$this->assertEquals('token', $token_info['module']);
$this->assertEquals('node', $token_info['type']);
// Test entity field property token info of the term reference.
$token_info = $token_service->getTokenInfo('node-test_term_reference', 'entity');
$this->assertEquals('Taxonomy term', $token_info['name']);
$this->assertEquals('The referenced entity', $token_info['description']);
$this->assertEquals('token', $token_info['module']);
$this->assertEquals('term', $token_info['type']);
}
/**
* Tests support for cardinality > 1 for entity reference tokens.
*/
public function testEntityReferenceTokensCardinality() {
/** @var \Drupal\field\FieldStorageConfigInterface $storage */
$storage = FieldStorageConfig::load('node.test_term_reference');
$storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
$storage->save();
// Add a few terms.
$terms = [];
$terms_value = [];
foreach (range(1, 3) as $i) {
$terms_value[$i] = $this->randomString();
$terms[$i] = $this->createTerm($this->vocabulary, [
'name' => $this->randomString(),
'term_field' => [
'value' => $terms_value[$i],
'format' => $this->testFormat->id(),
],
]);
}
$entity = Node::create([
'title' => 'Test multivalue chained tokens',
'type' => 'article',
'test_term_reference' => [
['target_id' => $terms[1]->id()],
['target_id' => $terms[2]->id()],
['target_id' => $terms[3]->id()],
],
]);
$entity->save();
$this->assertTokens('node', ['node' => $entity], [
'test_term_reference:0:entity:term_field' => Html::escape($terms[1]->term_field->value),
'test_term_reference:1:entity:term_field' => Html::escape($terms[2]->term_field->value),
'test_term_reference:2:entity:term_field' => Html::escape($terms[3]->term_field->value),
'test_term_reference:0:target_id' => $terms[1]->id(),
'test_term_reference:1:target_id' => $terms[2]->id(),
'test_term_reference:2:target_id' => $terms[3]->id(),
// Expects the entity's label to be returned for :entity tokens.
'test_term_reference:0:entity' => $terms[1]->label(),
'test_term_reference:1:entity' => $terms[2]->label(),
'test_term_reference:2:entity' => $terms[3]->label(),
// To make sure tokens without an explicit delta can also be replaced in
// the same token replacement call.
'test_term_reference:entity:term_field' => Html::escape($terms[1]->term_field->value),
'test_term_reference:target_id' => $terms[1]->id(),
]);
// Test some non existent tokens.
$this->assertNoTokens('node', ['node' => $entity], [
'test_term_reference:3:term_field',
'test_term_reference:0:does_not_exist',
'test_term_reference:1:does:not:exist',
'test_term_reference:1:2:does_not_exist',
]);
}
/**
* Test tokens for multilingual fields and entities.
*/
public function testMultilingualFields() {
// Create an english term and add a german translation for it.
$term = $this->createTerm($this->vocabulary, [
'name' => 'english-test-term',
'langcode' => 'en',
'term_field' => [
'value' => 'english-term-field-value',
'format' => $this->testFormat->id(),
],
]);
$term->addTranslation('de', [
'name' => 'german-test-term',
'term_field' => [
'value' => 'german-term-field-value',
'format' => $this->testFormat->id(),
],
])->save();
$german_term = $term->getTranslation('de');
// Create an english node, add a german translation for it and add the
// english term to the english node's entity reference field and the
// german term to the german's entity reference field.
$node = Node::create([
'title' => 'english-node-title',
'type' => 'article',
'test_term_reference' => [
'target_id' => $term->id(),
],
'test_field' => [
'value' => 'test-english-field',
'format' => $this->testFormat->id(),
],
]);
$node->addTranslation('de', [
'title' => 'german-node-title',
'test_term_reference' => [
'target_id' => $german_term->id(),
],
'test_field' => [
'value' => 'test-german-field',
'format' => $this->testFormat->id(),
],
])->save();
// Verify the :title token of the english node and the :name token of the
// english term it refers to. Also verify the value of the term's field.
$this->assertTokens('node', ['node' => $node], [
'title' => 'english-node-title',
'test_term_reference:entity:name' => 'english-test-term',
'test_term_reference:entity:term_field:value' => 'english-term-field-value',
'test_term_reference:entity:term_field' => 'english-term-field-value',
'test_field' => 'test-english-field',
'test_field:value' => 'test-english-field',
]);
// Same test for the german node and its german term.
$german_node = $node->getTranslation('de');
$this->assertTokens('node', ['node' => $german_node], [
'title' => 'german-node-title',
'test_term_reference:entity:name' => 'german-test-term',
'test_term_reference:entity:term_field:value' => 'german-term-field-value',
'test_term_reference:entity:term_field' => 'german-term-field-value',
'test_field' => 'test-german-field',
'test_field:value' => 'test-german-field',
]);
// If the langcode is specified, it should have priority over the node's
// active language.
$tokens = [
'test_field' => 'test-german-field',
'test_field:value' => 'test-german-field',
'test_term_reference:entity:term_field' => 'german-term-field-value',
'test_term_reference:entity:term_field:value' => 'german-term-field-value',
];
$this->assertTokens('node', ['node' => $node], $tokens, ['langcode' => 'de']);
}
/**
* Tests support for a datetime fields.
*/
public function testDatetimeFieldTokens() {
$node = Node::create([
'title' => 'Node for datetime field',
'type' => 'article',
]);
$node->set('field_datetime', ['1925-09-28T00:00:00', '1930-10-28T00:00:00'])->save();
$this->assertTokens('node', ['node' => $node], [
'field_datetime:date:custom:Y' => '1925',
'field_datetime:date:html_month' => '1925-09',
'field_datetime:date' => $node->get('field_datetime')->date->getTimestamp(),
'field_datetime:0:date:custom:Y' => '1925',
'field_datetime:0:date:html_month' => '1925-09',
'field_datetime:0:date' => $node->get('field_datetime')->date->getTimestamp(),
'field_datetime:1:date:custom:Y' => '1930',
'field_datetime:1:date:html_month' => '1930-10',
'field_datetime:1:date' => $node->get('field_datetime')->get(1)->date->getTimestamp(),
]);
}
/**
* Tests support for a daterange fields.
*/
public function testDatetimeRangeFieldTokens() {
/** @var \Drupal\node\NodeInterface $node */
$node = Node::create([
'title' => 'Node for daterange field',
'type' => 'article',
]);
$node->get('field_daterange')->value = '2013-12-22T00:00:00';
$node->get('field_daterange')->end_value = '2016-08-26T00:00:00';
$node->get('field_daterange')->appendItem([
'value' => '2014-08-22T00:00:00',
'end_value' => '2017-12-20T00:00:00',
]);
$node->get('field_daterange')->value = '2013-12-22T00:00:00';
$node->get('field_daterange')->end_value = '2016-08-26T00:00:00';
$node->save();
$this->assertTokens('node', ['node' => $node], [
'field_daterange:start_date:html_month' => '2013-12',
'field_daterange:start_date:custom:Y' => '2013',
'field_daterange:end_date:custom:Y' => '2016',
'field_daterange:start_date' => $node->get('field_daterange')->start_date->getTimestamp(),
'field_daterange:0:start_date:html_month' => '2013-12',
'field_daterange:0:start_date:custom:Y' => '2013',
'field_daterange:0:end_date:custom:Y' => '2016',
'field_daterange:0:start_date' => $node->get('field_daterange')->start_date->getTimestamp(),
'field_daterange:1:start_date:html_month' => '2014-08',
'field_daterange:1:start_date:custom:Y' => '2014',
'field_daterange:1:end_date:custom:Y' => '2017',
'field_daterange:1:end_date' => $node->get('field_daterange')->get(1)->end_date->getTimestamp(),
]);
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\file\Entity\File;
/**
* Tests file tokens.
*
* @group token
*/
class FileTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['file'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installEntitySchema('file');
}
function testFileTokens() {
// Create a test file object.
$file = File::create([
'fid' => 1,
'filename' => 'test.png',
'filesize' => 100,
'uri' => 'public://images/test.png',
'filemime' => 'image/png',
]);
$tokens = [
'basename' => 'test.png',
'extension' => 'png',
'size-raw' => 100,
];
$this->assertTokens('file', ['file' => $file], $tokens);
// Test a file with no extension and a fake name.
$file->filename = 'Test PNG image';
$file->uri = 'public://images/test';
$tokens = [
'basename' => 'test',
'extension' => '',
'size-raw' => 100,
];
$this->assertTokens('file', ['file' => $file], $tokens);
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\KernelTests\KernelTestBase as BaseKernelTestBase;
use Drupal\token\Tests\TokenTestTrait;
/**
* Helper test class with some added functions for testing.
*/
abstract class KernelTestBase extends BaseKernelTestBase {
use TokenTestTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['path', 'token', 'token_module_test', 'system', 'user'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', ['router', 'url_alias']);
\Drupal::service('router.builder')->rebuild();
$this->installConfig(['system']);
}
}

View file

@ -0,0 +1,100 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Core\Url;
/**
* Test the node and content type tokens.
*
* @group token
*/
class NodeTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['node', 'field', 'text'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('node');
$node_type = NodeType::create([
'type' => 'page',
'name' => 'Basic page',
'description' => "Use <em>basic pages</em> for your static content, such as an 'About us' page.",
]);
$node_type->save();
$node_type = NodeType::create([
'type' => 'article',
'name' => 'Article',
'description' => "Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.",
]);
$node_type->save();
}
function testNodeTokens() {
$page = Node::create([
'type' => 'page',
'title' => 'Source Title',
'revision_log' => $this->randomMachineName(),
'path' => ['alias' => '/content/source-node']
]);
$page->save();
$tokens = [
'log' => $page->revision_log->value,
'url:path' => '/content/source-node',
'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => TRUE])->toString(),
'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => FALSE])->toString(),
'url:unaliased:path' => "/node/{$page->id()}",
'content-type' => 'Basic page',
'content-type:name' => 'Basic page',
'content-type:machine-name' => 'page',
'content-type:description' => "Use <em>basic pages</em> for your static content, such as an 'About us' page.",
'content-type:node-count' => 1,
'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], ['absolute' => TRUE])->toString(),
'source:title' => 'Source Title',
// Deprecated tokens.
'type' => 'page',
'type-name' => 'Basic page',
'url:alias' => '/content/source-node',
];
$this->assertTokens('node', ['node' => $page], $tokens);
$article = Node::create([
'type' => 'article',
'title' => 'Source Title',
]);
$article->save();
$tokens = [
'log' => '',
'url:path' => "/node/{$article->id()}",
'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => TRUE])->toString(),
'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => FALSE])->toString(),
'url:unaliased:path' => "/node/{$article->id()}",
'content-type' => 'Article',
'content-type:name' => 'Article',
'content-type:machine-name' => 'article',
'content-type:description' => "Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.",
'content-type:node-count' => 1,
'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], ['absolute' => TRUE])->toString(),
'source:title' => 'Source Title',
// Deprecated tokens.
'type' => 'article',
'type-name' => 'Article',
'url:alias' => "/node/{$article->id()}",
];
$this->assertTokens('node', ['node' => $article], $tokens);
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace Drupal\Tests\token\Kernel;
/**
* Tests random tokens.
*
* @group token
*/
class RandomTest extends KernelTestBase {
function testRandomTokens() {
$tokens = [
'number' => '[0-9]{1,}',
'hash:md5' => '[0-9a-f]{32}',
'hash:sha1' => '[0-9a-f]{40}',
'hash:sha256' => '[0-9a-f]{64}',
'hash:invalid-algo' => NULL,
];
$first_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]);
$second_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]);
foreach ($first_set as $token => $value) {
$this->assertNotIdentical($first_set[$token], $second_set[$token]);
}
}
}

View file

@ -0,0 +1,154 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Core\Url;
/**
* Tests taxonomy tokens.
*
* @group token
*/
class TaxonomyTest extends KernelTestBase {
protected $vocab;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['taxonomy', 'text', 'language'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installEntitySchema('taxonomy_term');
// Create the default tags vocabulary.
$vocabulary = Vocabulary::create([
'name' => 'Tags',
'vid' => 'tags',
]);
$vocabulary->save();
$this->vocab = $vocabulary;
}
/**
* Test the additional taxonomy term tokens.
*/
function testTaxonomyTokens() {
$root_term = $this->addTerm($this->vocab, ['name' => 'Root term', 'path' => ['alias' => '/root-term']]);
$tokens = [
'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => FALSE])->toString(),
'url:path' => '/root-term',
'url:unaliased:path' => "/taxonomy/term/{$root_term->id()}",
'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
'parents' => NULL,
'parents:count' => NULL,
'parents:keys' => NULL,
'root' => NULL,
// Deprecated tokens
'url:alias' => '/root-term',
];
$this->assertTokens('term', ['term' => $root_term], $tokens);
$parent_term = $this->addTerm($this->vocab, ['name' => 'Parent term', 'parent' => $root_term->id()]);
$tokens = [
'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => FALSE])->toString(),
'url:path' => "/taxonomy/term/{$parent_term->id()}",
'url:unaliased:path' => "/taxonomy/term/{$parent_term->id()}",
'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
'parents' => 'Root term',
'parents:count' => 1,
'parents:keys' => $root_term->id(),
'root' => $root_term->label(),
'root:tid' => $root_term->id(),
// Deprecated tokens
'url:alias' => "/taxonomy/term/{$parent_term->id()}",
];
$this->assertTokens('term', ['term' => $parent_term], $tokens);
$term = $this->addTerm($this->vocab, ['name' => 'Test term', 'parent' => $parent_term->id()]);
$tokens = [
'parents' => 'Root term, Parent term',
'parents:count' => 2,
'parents:keys' => implode(', ', [$root_term->id(), $parent_term->id()]),
];
$this->assertTokens('term', ['term' => $term], $tokens);
}
/**
* Test the additional vocabulary tokens.
*/
function testVocabularyTokens() {
$vocabulary = $this->vocab;
$tokens = [
'machine-name' => 'tags',
'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], ['absolute' => TRUE])->toString(),
];
$this->assertTokens('vocabulary', ['vocabulary' => $vocabulary], $tokens);
}
function addVocabulary(array $vocabulary = []) {
$vocabulary += [
'name' => mb_strtolower($this->randomMachineName(5)),
'nodes' => ['article' => 'article'],
];
$vocabulary = Vocabulary::create($vocabulary)->save();
return $vocabulary;
}
function addTerm($vocabulary, array $term = []) {
$term += [
'name' => mb_strtolower($this->randomMachineName(5)),
'vid' => $vocabulary->id(),
];
$term = Term::create($term);
$term->save();
return $term;
}
/**
* Test the multilingual terms.
*/
function testMultilingualTerms() {
// Add a second language.
$language = ConfigurableLanguage::createFromLangcode('de');
$language->save();
// Create an english parent term and add a german translation for it.
$parent_term = $this->addTerm($this->vocab, [
'name' => 'english-parent-term',
'langcode' => 'en',
]);
$parent_term->addTranslation('de', [
'name' => 'german-parent-term',
])->save();
// Create a term related to the parent term.
$child_term = $this->addTerm($this->vocab, [
'name' => 'english-child-term',
'langcode' => 'en',
'parent' => $parent_term->id(),
]);
$child_term->addTranslation('de', [
'name' => 'german-child-term',
])->save();
// Expect the parent term to be in the specified language.
$this->assertTokens('term', ['term' => $child_term], ['parents' => 'german-parent-term'], ['langcode' => 'de']);
$this->assertTokens('term', ['term' => $child_term], ['root' => 'german-parent-term'], ['langcode' => 'de']);
}
}

View file

@ -0,0 +1,120 @@
<?php
namespace Drupal\Tests\token\Kernel;
/**
* Test basic, low-level token functions.
*
* @group token
*/
class UnitTest extends KernelTestBase {
/**
* @var \Drupal\token\Token
*/
protected $tokenService;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['file', 'node'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->tokenService = \Drupal::token();
}
/**
* Test invalid tokens.
*/
public function testGetInvalidTokens() {
$tests = [];
$tests[] = [
'valid tokens' => [
'[node:title]',
'[node:created:short]',
'[node:created:custom:invalid]',
'[node:created:custom:mm-YYYY]',
'[node:colons:in:name]',
'[site:name]',
'[site:slogan]',
'[current-date:short]',
'[current-user:uid]',
'[current-user:ip-address]',
],
'invalid tokens' => [
'[node:title:invalid]',
'[node:created:invalid]',
'[node:created:short:invalid]',
'[node:colons:in:name:invalid]',
'[invalid:title]',
'[site:invalid]',
'[user:ip-address]',
'[user:uid]',
'[comment:cid]',
// Deprecated tokens
'[node:tnid]',
'[node:type]',
'[node:type-name]',
'[date:short]',
],
'types' => ['node'],
];
$tests[] = [
'valid tokens' => [
'[node:title]',
'[node:created:short]',
'[node:created:custom:invalid]',
'[node:created:custom:mm-YYYY]',
'[node:colons:in:name]',
'[site:name]',
'[site:slogan]',
'[user:uid]',
'[current-date:short]',
'[current-user:uid]',
],
'invalid tokens' => [
'[node:title:invalid]',
'[node:created:invalid]',
'[node:created:short:invalid]',
'[node:colons:in:name:invalid]',
'[invalid:title]',
'[site:invalid]',
'[user:ip-address]',
'[comment:cid]',
// Deprecated tokens
'[node:tnid]',
'[node:type]',
'[node:type-name]',
],
'types' => ['all'],
];
foreach ($tests as $test) {
$tokens = array_merge($test['valid tokens'], $test['invalid tokens']);
shuffle($tokens);
$invalid_tokens = $this->tokenService->getInvalidTokensByContext(implode(' ', $tokens), $test['types']);
sort($invalid_tokens);
sort($test['invalid tokens']);
$this->assertEqual($invalid_tokens, $test['invalid tokens'], 'Invalid tokens detected properly: ' . implode(', ', $invalid_tokens));
}
}
/**
* Test that tokens are generated only for content entities.
*/
public function testContentEntityOnlyTokens() {
// Verify that type and token info for a config entity is not generated.
$this->assertNull($this->tokenService->getTokenInfo('user_role', 'original'));
$this->assertNull($this->tokenService->getTokenInfo('user_role', 'url'));
$this->assertNull($this->tokenService->getTypeInfo('user_role'));
}
}

View file

@ -0,0 +1,88 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\Request;
/**
* Test generic url token replacements.
*
* @group token
*/
class UrlTest extends KernelTestBase {
/**
* The token service.
*
* @var \Drupal\Core\Utility\Token
*/
protected $token;
/**
* The current request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The current route match.
*
* @var \Drupal\Core\Routing\CurrentRouteMatch
*/
protected $currentRouteMatch;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->token = $this->container->get('token');
$this->requestStack = $this->container->get('request_stack');
$this->currentRouteMatch = $this->container->get('current_route_match');
}
/**
* Test the url token replacements for current requests.
*
* The method ::expectedCurrentRequestUrlResults() is not declared
* as a regular data provider, because it might use services from
* the global Drupal container, which is not initialized yet during
* the invocation of data providers.
*/
public function testCurrentRequestUrls() {
foreach ($this->expectedCurrentRequestUrlResults() as $data_set) {
list ($request, $text, $data, $options, $expected_output) = $data_set;
// Set the request as the current one.
$this->requestStack->pop();
$this->requestStack->push($request);
$this->currentRouteMatch->resetRouteMatch();
$this->assertEquals($expected_output, $this->token->replace($text, $data, $options));
}
}
/**
* Provides a list of results to expect for ::testRequestUrls().
*
* Each data set of this array holds the following order:
* - The request object to test for.
* - The input text as string.
* - The token data as array.
* - Further options for the token replacement as array.
* - The output to expect after token replacement.
*
* @return array
* The list of results to expect.
*/
public function expectedCurrentRequestUrlResults() {
return [
[Request::createFromGlobals(), '[current-page:url]', [], [], Url::createFromRequest(Request::createFromGlobals())->setAbsolute()->toString()],
[Request::create('/should-not-exist'), '[current-page:url:path]', [], [], '/'],
[Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], [], '[current-page:url:absolute]'],
[Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], ['clear' => TRUE], ''],
];
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace Drupal\Tests\token\Kernel;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Views;
/**
* Test the views tokens.
*
* @group token
*/
class ViewsTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['views', 'block'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['token_views_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
ViewTestData::createTestViews(get_class($this), ['token_module_test']);
}
/**
* Tests path token replacements generated from a view without a path.
*/
public function testTokenReplacementNoPath() {
$token_handler = \Drupal::token();
$view = Views::getView('token_views_test');
$view->setDisplay('block_1');
$view->execute();
$this->assertSame('', $token_handler->replace('[view:url]', ['view' => $view]), 'Token [view:url] is empty for views without path.');
}
}