Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / user / tests / src / Functional / UserTokenReplaceTest.php
1 <?php
2
3 namespace Drupal\Tests\user\Functional;
4
5 use Drupal\Component\Render\FormattableMarkup;
6 use Drupal\Core\Render\BubbleableMetadata;
7 use Drupal\language\Entity\ConfigurableLanguage;
8 use Drupal\Tests\BrowserTestBase;
9 use Drupal\user\Entity\User;
10
11 /**
12  * Generates text using placeholders for dummy content to check user token
13  * replacement.
14  *
15  * @group user
16  */
17 class UserTokenReplaceTest extends BrowserTestBase {
18
19   /**
20    * Modules to enable.
21    *
22    * @var array
23    */
24   public static $modules = ['language', 'user_hooks_test'];
25
26   /**
27    * {@inheritdoc}
28    */
29   protected function setUp() {
30     parent::setUp();
31     ConfigurableLanguage::createFromLangcode('de')->save();
32   }
33
34   /**
35    * Creates a user, then tests the tokens generated from it.
36    */
37   public function testUserTokenReplacement() {
38     $token_service = \Drupal::token();
39     $language_interface = \Drupal::languageManager()->getCurrentLanguage();
40     $url_options = [
41       'absolute' => TRUE,
42       'language' => $language_interface,
43     ];
44
45     \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
46     \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
47
48     // Create two users and log them in one after another.
49     $user1 = $this->drupalCreateUser([]);
50     $user2 = $this->drupalCreateUser([]);
51     $this->drupalLogin($user1);
52     $this->drupalLogout();
53     $this->drupalLogin($user2);
54
55     $account = User::load($user1->id());
56     $global_account = User::load(\Drupal::currentUser()->id());
57
58     // Generate and test tokens.
59     $tests = [];
60     $tests['[user:uid]'] = $account->id();
61     $tests['[user:name]'] = $account->getAccountName();
62     $tests['[user:account-name]'] = $account->getAccountName();
63     $tests['[user:display-name]'] = $account->getDisplayName();
64     $tests['[user:mail]'] = $account->getEmail();
65     $tests['[user:url]'] = $account->url('canonical', $url_options);
66     $tests['[user:edit-url]'] = $account->url('edit-form', $url_options);
67     $tests['[user:last-login]'] = format_date($account->getLastLoginTime(), 'medium', '', NULL, $language_interface->getId());
68     $tests['[user:last-login:short]'] = format_date($account->getLastLoginTime(), 'short', '', NULL, $language_interface->getId());
69     $tests['[user:created]'] = format_date($account->getCreatedTime(), 'medium', '', NULL, $language_interface->getId());
70     $tests['[user:created:short]'] = format_date($account->getCreatedTime(), 'short', '', NULL, $language_interface->getId());
71     $tests['[current-user:name]'] = $global_account->getAccountName();
72     $tests['[current-user:account-name]'] = $global_account->getAccountName();
73     $tests['[current-user:display-name]'] = $global_account->getDisplayName();
74
75     $base_bubbleable_metadata = BubbleableMetadata::createFromObject($account);
76     $metadata_tests = [];
77     $metadata_tests['[user:uid]'] = $base_bubbleable_metadata;
78     $metadata_tests['[user:name]'] = $base_bubbleable_metadata;
79     $metadata_tests['[user:account-name]'] = $base_bubbleable_metadata;
80     $metadata_tests['[user:display-name]'] = $base_bubbleable_metadata;
81     $metadata_tests['[user:mail]'] = $base_bubbleable_metadata;
82     $metadata_tests['[user:url]'] = $base_bubbleable_metadata;
83     $metadata_tests['[user:edit-url]'] = $base_bubbleable_metadata;
84     $bubbleable_metadata = clone $base_bubbleable_metadata;
85     // This test runs with the Language module enabled, which means config is
86     // overridden by LanguageConfigFactoryOverride (to provide translations of
87     // config). This causes the interface language cache context to be added for
88     // config entities. The four next tokens use DateFormat Config entities, and
89     // therefore have the interface language cache context.
90     $bubbleable_metadata->addCacheContexts(['languages:language_interface']);
91     $metadata_tests['[user:last-login]'] = $bubbleable_metadata->addCacheTags(['rendered']);
92     $metadata_tests['[user:last-login:short]'] = $bubbleable_metadata;
93     $metadata_tests['[user:created]'] = $bubbleable_metadata;
94     $metadata_tests['[user:created:short]'] = $bubbleable_metadata;
95     $metadata_tests['[current-user:name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
96     $metadata_tests['[current-user:account-name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
97     $metadata_tests['[current-user:display-name]'] = $base_bubbleable_metadata->merge(BubbleableMetadata::createFromObject($global_account)->addCacheContexts(['user']));
98
99     // Test to make sure that we generated something for each token.
100     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
101
102     foreach ($tests as $input => $expected) {
103       $bubbleable_metadata = new BubbleableMetadata();
104       $output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId()], $bubbleable_metadata);
105       $this->assertEqual($output, $expected, new FormattableMarkup('User token %token replaced.', ['%token' => $input]));
106       $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
107     }
108
109     // Generate tokens for the anonymous user.
110     $anonymous_user = User::load(0);
111     $tests = [];
112     $tests['[user:uid]'] = t('not yet assigned');
113     $tests['[user:display-name]'] = $anonymous_user->getDisplayName();
114
115     $base_bubbleable_metadata = BubbleableMetadata::createFromObject($anonymous_user);
116     $metadata_tests = [];
117     $metadata_tests['[user:uid]'] = $base_bubbleable_metadata;
118     $bubbleable_metadata = clone $base_bubbleable_metadata;
119     $bubbleable_metadata->addCacheableDependency(\Drupal::config('user.settings'));
120     $metadata_tests['[user:display-name]'] = $bubbleable_metadata;
121
122     foreach ($tests as $input => $expected) {
123       $bubbleable_metadata = new BubbleableMetadata();
124       $output = $token_service->replace($input, ['user' => $anonymous_user], ['langcode' => $language_interface->getId()], $bubbleable_metadata);
125       $this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', ['%token' => $input]));
126       $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
127     }
128
129     // Generate login and cancel link.
130     $tests = [];
131     $tests['[user:one-time-login-url]'] = user_pass_reset_url($account);
132     $tests['[user:cancel-url]'] = user_cancel_url($account);
133
134     // Generate tokens with interface language.
135     $link = \Drupal::url('user.page', [], ['absolute' => TRUE]);
136     foreach ($tests as $input => $expected) {
137       $output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId(), 'callback' => 'user_mail_tokens', 'clear' => TRUE]);
138       $this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.');
139     }
140
141     // Generate tokens with the user's preferred language.
142     $account->preferred_langcode = 'de';
143     $account->save();
144     $link = \Drupal::url('user.page', [], ['language' => \Drupal::languageManager()->getLanguage($account->getPreferredLangcode()), 'absolute' => TRUE]);
145     foreach ($tests as $input => $expected) {
146       $output = $token_service->replace($input, ['user' => $account], ['callback' => 'user_mail_tokens', 'clear' => TRUE]);
147       $this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language.");
148     }
149
150     // Generate tokens with one specific language.
151     $link = \Drupal::url('user.page', [], ['language' => \Drupal::languageManager()->getLanguage('de'), 'absolute' => TRUE]);
152     foreach ($tests as $input => $expected) {
153       foreach ([$user1, $user2] as $account) {
154         $output = $token_service->replace($input, ['user' => $account], ['langcode' => 'de', 'callback' => 'user_mail_tokens', 'clear' => TRUE]);
155         $this->assertTrue(strpos($output, $link) === 0, "Generated URL in the requested language.");
156       }
157     }
158
159     // Generate user display name tokens when safe markup is returned.
160     // @see user_hooks_test_user_format_name_alter()
161     \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
162     $input = '[user:display-name] [current-user:display-name]';
163     $expected = "<em>{$user1->id()}</em> <em>{$user2->id()}</em>";
164     $output = $token_service->replace($input, ['user' => $user1]);
165     $this->assertEqual($output, $expected, new FormattableMarkup('User token %token does not escape safe markup.', ['%token' => 'display-name']));
166   }
167
168 }