updated core to 8.6.1 via composer

This commit is contained in:
2018-09-12 13:58:26 +02:00
parent a9a219f2ed
commit ea56b9fba3
4443 changed files with 112098 additions and 40708 deletions
@@ -18,5 +18,5 @@ $connection->insert('config')
->values([
'collection' => '',
'name' => 'user.mail',
'data' => "a:10:{s:14:\"cancel_confirm\";a:2:{s:4:\"body\";s:369:\"[user:name],\n\nA request to cancel your account has been made at [site:name].\n\nYou may now cancel your account on [site:url-brief] by clicking this link or copying and pasting it into your browser:\n\n[user:cancel-url]\n\nNOTE: The cancellation of your account is not reversible.\n\nThis link expires in one day and nothing will happen if it is not used.\n\n-- [site:name] team\";s:7:\"subject\";s:59:\"Account cancellation request for [user:name] at [site:name]\";}s:14:\"password_reset\";a:2:{s:4:\"body\";s:397:\"[user:name],\n\nA request to reset the password for your account has been made at [site:name].\n\nYou may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password. It expires after one day and nothing will happen if it's not used.\n\n-- [site:name] team\";s:7:\"subject\";s:60:\"Replacement login information for [user:name] at [site:name]\";}s:22:\"register_admin_created\";a:2:{s:4:\"body\";s:463:\"[user:name],\n\nA site administrator at [site:name] has created an account for you. You may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:58:\"An administrator created an account for you at [site:name]\";}s:29:\"register_no_approval_required\";a:2:{s:4:\"body\";s:437:\"[user:name],\n\nThank you for registering at [site:name]. You may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:46:\"Account details for [user:name] at [site:name]\";}s:25:\"register_pending_approval\";a:2:{s:4:\"body\";s:281:\"[user:name],\n\nThank you for registering at [site:name]. Your application for an account is currently pending approval. Once it has been approved, you will receive another email containing information about how to log in, set your password, and other details.\n\n\n-- [site:name] team\";s:7:\"subject\";s:71:\"Account details for [user:name] at [site:name] (pending admin approval)\";}s:31:\"register_pending_approval_admin\";a:2:{s:4:\"body\";s:56:\"[user:name] has applied for an account.\n\n[user:edit-url]\";s:7:\"subject\";s:71:\"Account details for [user:name] at [site:name] (pending admin approval)\";}s:16:\"status_activated\";a:2:{s:4:\"body\";s:446:\"[user:name],\n\nYour account at [site:name] has been activated.\n\nYou may now log in by clicking this link or copying and pasting it into your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:57:\"Account details for [user:name] at [site:name] (approved)\";}s:14:\"status_blocked\";a:2:{s:4:\"body\";s:89:\"[user:name],\n\nYour account on [site:account-name] has been blocked.\n\n-- [site:name] team\";s:7:\"subject\";s:56:\"Account details for [user:name] at [site:name] (blocked)\";}s:15:\"status_canceled\";a:2:{s:4:\"body\";s:82:\"[user:name],\n\nYour account on [site:name] has been canceled.\n\n-- [site:name] team\";s:7:\"subject\";s:57:\"Account details for [user:name] at [site:name] (canceled)\";}s:8:\"langcode\";s:2:\"en\";}"
'data' => "a:10:{s:14:\"cancel_confirm\";a:2:{s:4:\"body\";s:369:\"[user:name],\n\nA request to cancel your account has been made at [site:name].\n\nYou may now cancel your account on [site:url-brief] by clicking this link or copying and pasting it into your browser:\n\n[user:cancel-url]\n\nNOTE: The cancellation of your account is not reversible.\n\nThis link expires in one day and nothing will happen if it is not used.\n\n-- [site:name] team\";s:7:\"subject\";s:59:\"Account cancellation request for [user:name] at [site:name]\";}s:14:\"password_reset\";a:2:{s:4:\"body\";s:397:\"[user:name],\n\nA request to reset the password for your account has been made at [site:name].\n\nYou may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password. It expires after one day and nothing will happen if it's not used.\n\n-- [site:name] team\";s:7:\"subject\";s:60:\"Replacement login information for [user:name] at [site:name]\";}s:22:\"register_admin_created\";a:2:{s:4:\"body\";s:463:\"[user:name],\n\nA site administrator at [site:name] has created an account for you. You may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:58:\"An administrator created an account for you at [site:name]\";}s:29:\"register_no_approval_required\";a:2:{s:4:\"body\";s:437:\"[user:name],\n\nThank you for registering at [site:name]. You may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:46:\"Account details for [user:name] at [site:name]\";}s:25:\"register_pending_approval\";a:2:{s:4:\"body\";s:281:\"[user:name],\n\nThank you for registering at [site:name]. Your application for an account is currently pending approval. Once it has been approved, you will receive another email containing information about how to log in, set your password, and other details.\n\n\n-- [site:name] team\";s:7:\"subject\";s:71:\"Account details for [user:name] at [site:name] (pending admin approval)\";}s:31:\"register_pending_approval_admin\";a:2:{s:4:\"body\";s:56:\"[user:name] has applied for an account.\n\n[user:edit-url]\";s:7:\"subject\";s:71:\"Account details for [user:name] at [site:name] (pending admin approval)\";}s:16:\"status_activated\";a:2:{s:4:\"body\";s:446:\"[user:name],\n\nYour account at [site:name] has been activated.\n\nYou may now log in by clicking this link or copying and pasting it into your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:57:\"Account details for [user:name] at [site:name] (approved)\";}s:14:\"status_blocked\";a:2:{s:4:\"body\";s:89:\"[user:name],\n\nYour account on [site:account-name] has been blocked.\n\n-- [site:name] team\";s:7:\"subject\";s:56:\"Account details for [user:name] at [site:name] (blocked)\";}s:15:\"status_canceled\";a:2:{s:4:\"body\";s:82:\"[user:name],\n\nYour account on [site:name] has been canceled.\n\n-- [site:name] team\";s:7:\"subject\";s:57:\"Account details for [user:name] at [site:name] (canceled)\";}s:8:\"langcode\";s:2:\"en\";}",
])->execute();
@@ -6,6 +6,9 @@
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\User;
/**
@@ -22,3 +25,16 @@ function user_access_test_user_access(User $entity, $operation, $account) {
}
return AccessResult::neutral();
}
/**
* Implements hook_entity_field_access().
*/
function user_access_test_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
// Account with role sub-admin can view the status, init and mail fields for user with no roles.
if ($operation === 'view' && in_array($field_definition->getName(), ['status', 'init', 'mail'])) {
if (($items == NULL) || (count($items->getEntity()->getRoles()) == 1)) {
return AccessResult::allowedIfHasPermission($account, 'sub-admin');
}
}
return AccessResult::neutral();
}
@@ -0,0 +1,2 @@
sub-admin:
title: 'Administer users with no roles'
@@ -4,4 +4,3 @@ user_form_test.cancel:
_entity_form: 'user.cancel'
requirements:
_permission: 'cancel other accounts'
@@ -5,7 +5,7 @@
* Support module for user hooks testing.
*/
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Render\FormattableMarkup;
/**
* Implements hook_user_format_name_alter().
@@ -13,7 +13,7 @@ use Drupal\Component\Utility\SafeMarkup;
function user_hooks_test_user_format_name_alter(&$name, $account) {
if (\Drupal::state()->get('user_hooks_test_user_format_name_alter', FALSE)) {
if (\Drupal::state()->get('user_hooks_test_user_format_name_alter_safe', FALSE)) {
$name = SafeMarkup::format('<em>@uid</em>', ['@uid' => $account->id()]);
$name = new FormattableMarkup('<em>@uid</em>', ['@uid' => $account->id()]);
}
else {
$name = '<em>' . $account->id() . '</em>';
@@ -0,0 +1,478 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_fields_access
label: ''
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: mini
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ‹‹
next: ››
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: false
caption: ''
summary: ''
description: ''
columns:
name: name
status: status
mail: mail
init: init
created: created
info:
name:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
status:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
mail:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
init:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
created:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: false
row:
type: fields
fields:
name:
id: name
table: users_field_data
field: name
relationship: none
group_type: group
admin_label: ''
label: Name
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: false
ellipsis: false
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: 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_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: user_name
settings:
link_to_entity: true
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
entity_type: user
entity_field: name
plugin_id: field
status:
id: status
table: users_field_data
field: status
relationship: none
group_type: group
admin_label: ''
label: Status
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: 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_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: boolean
settings:
format: default
format_custom_true: ''
format_custom_false: ''
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
entity_type: user
entity_field: status
plugin_id: field
mail:
id: mail
table: users_field_data
field: mail
relationship: none
group_type: group
admin_label: ''
label: Email
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: 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_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: basic_string
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
entity_type: user
entity_field: mail
plugin_id: field
init:
id: init
table: users_field_data
field: init
relationship: none
group_type: group
admin_label: ''
label: Init
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: 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_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: basic_string
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
entity_type: user
entity_field: init
plugin_id: field
created:
id: created
table: users_field_data
field: created
relationship: none
group_type: group
admin_label: ''
label: Created
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: 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_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: timestamp
settings:
date_format: medium
custom_date_format: ''
timezone: ''
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
entity_type: user
entity_field: created
plugin_id: field
filters: { }
sorts: { }
title: ''
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
tags: { }
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: test_user_fields_access
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
tags: { }
@@ -5,5 +5,5 @@ package: Testing
version: VERSION
core: 8.x
dependencies:
- user
- views
- drupal:user
- drupal:views
@@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\user\Functional\Hal;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\user\Functional\Rest\RoleResourceTestBase;
/**
* @group hal
*/
class RoleHalJsonAnonTest extends RoleResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
}
@@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\user\Functional\Hal;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\user\Functional\Rest\RoleResourceTestBase;
/**
* @group hal
*/
class RoleHalJsonBasicAuthTest extends RoleResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal', 'basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\user\Functional\Hal;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\user\Functional\Rest\RoleResourceTestBase;
/**
* @group hal
*/
class RoleHalJsonCookieTest extends RoleResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,65 @@
<?php
namespace Drupal\Tests\user\Functional\Hal;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\user\Functional\Rest\UserResourceTestBase;
/**
* @group hal
*/
class UserHalJsonAnonTest extends UserResourceTestBase {
use HalEntityNormalizationTrait;
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$default_normalization = parent::getExpectedNormalizedEntity();
$normalization = $this->applyHalFieldNormalization($default_normalization);
return $normalization + [
'_links' => [
'self' => [
'href' => $this->baseUrl . '/user/3?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'_links' => [
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
];
}
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\user\Functional\Hal;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class UserHalJsonBasicAuthTest extends UserHalJsonAnonTest {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,19 @@
<?php
namespace Drupal\Tests\user\Functional\Hal;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class UserHalJsonCookieTest extends UserHalJsonAnonTest {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class RoleJsonAnonTest extends RoleResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class RoleJsonBasicAuthTest extends RoleResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class RoleJsonCookieTest extends RoleResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,69 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
use Drupal\user\Entity\Role;
abstract class RoleResourceTestBase extends EntityResourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['user'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'user_role';
/**
* @var \Drupal\user\RoleInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
$this->grantPermissionsToTestedRole(['administer permissions']);
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
$role = Role::create([
'id' => 'llama',
'name' => $this->randomString(),
]);
$role->save();
return $role;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
return [
'uuid' => $this->entity->uuid(),
'weight' => 2,
'langcode' => 'en',
'status' => TRUE,
'dependencies' => [],
'id' => 'llama',
'label' => NULL,
'is_admin' => NULL,
'permissions' => [],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
// @todo Update in https://www.drupal.org/node/2300677.
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class RoleXmlAnonTest extends RoleResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class RoleXmlBasicAuthTest extends RoleResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class RoleXmlCookieTest extends RoleResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class UserJsonAnonTest extends UserResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class UserJsonBasicAuthTest extends UserResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class UserJsonCookieTest extends UserResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,329 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Core\Url;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
use Drupal\user\Entity\User;
use GuzzleHttp\RequestOptions;
abstract class UserResourceTestBase extends EntityResourceTestBase {
use BcTimestampNormalizerUnixTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['user'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'user';
/**
* {@inheritdoc}
*/
protected static $patchProtectedFieldNames = [
'changed' => NULL,
];
/**
* @var \Drupal\user\UserInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected static $labelFieldName = 'name';
/**
* {@inheritdoc}
*/
protected static $firstCreatedEntityId = 4;
/**
* {@inheritdoc}
*/
protected static $secondCreatedEntityId = 5;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
switch ($method) {
case 'GET':
$this->grantPermissionsToTestedRole(['access user profiles']);
break;
case 'POST':
case 'PATCH':
case 'DELETE':
$this->grantPermissionsToTestedRole(['administer users']);
break;
}
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
// Create a "Llama" user.
$user = User::create(['created' => 123456789]);
$user->setUsername('Llama')
->setChangedTime(123456789)
->activate()
->save();
return $user;
}
/**
* {@inheritdoc}
*/
protected function createAnotherEntity() {
/** @var \Drupal\user\UserInterface $user */
$user = $this->entity->createDuplicate();
$user->setUsername($user->label() . '_dupe');
$user->save();
return $user;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
return [
'uid' => [
['value' => 3],
],
'uuid' => [
['value' => $this->entity->uuid()],
],
'langcode' => [
[
'value' => 'en',
],
],
'name' => [
[
'value' => 'Llama',
],
],
'created' => [
$this->formatExpectedTimestampItemValues(123456789),
],
'changed' => [
$this->formatExpectedTimestampItemValues($this->entity->getChangedTime()),
],
'default_langcode' => [
[
'value' => TRUE,
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return [
'name' => [
[
'value' => 'Dramallama',
],
],
];
}
/**
* Tests PATCHing security-sensitive base fields of the logged in account.
*/
public function testPatchDxForSecuritySensitiveBaseFields() {
// The anonymous user is never allowed to modify itself.
if (!static::$auth) {
$this->markTestSkipped();
}
$this->initAuthentication();
$this->provisionEntityResource();
/** @var \Drupal\user\UserInterface $user */
$user = static::$auth ? $this->account : User::load(0);
// @todo Remove the array_diff_key() call in https://www.drupal.org/node/2821077.
$original_normalization = array_diff_key($this->serializer->normalize($user, static::$format), ['created' => TRUE, 'changed' => TRUE, 'name' => TRUE]);
// Since this test must be performed by the user that is being modified,
// we cannot use $this->getUrl().
$url = $user->toUrl()->setOption('query', ['_format' => static::$format]);
$request_options = [
RequestOptions::HEADERS => ['Content-Type' => static::$mimeType],
];
$request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH'));
// Test case 1: changing email.
$normalization = $original_normalization;
$normalization['mail'] = [['value' => 'new-email@example.com']];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 422 when changing email without providing the password.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response, FALSE, FALSE, FALSE, FALSE);
$normalization['pass'] = [['existing' => 'wrong']];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 422 when changing email while providing a wrong password.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response, FALSE, FALSE, FALSE, FALSE);
$normalization['pass'] = [['existing' => $this->account->passRaw]];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// 200 for well-formed request.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
// Test case 2: changing password.
$normalization = $original_normalization;
$new_password = $this->randomString();
$normalization['pass'] = [['value' => $new_password]];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 422 when changing password without providing the current password.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\npass: Your current password is missing or incorrect; it's required to change the Password.\n", $response, FALSE, FALSE, FALSE, FALSE);
$normalization['pass'][0]['existing'] = $this->account->pass_raw;
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// 200 for well-formed request.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
// Verify that we can log in with the new password.
$this->assertRpcLogin($user->getAccountName(), $new_password);
// Update password in $this->account, prepare for future requests.
$this->account->passRaw = $new_password;
$this->initAuthentication();
$request_options = [
RequestOptions::HEADERS => ['Content-Type' => static::$mimeType],
];
$request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH'));
// Test case 3: changing name.
$normalization = $original_normalization;
$normalization['name'] = [['value' => 'Cooler Llama']];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 403 when modifying username without required permission.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(403, "Access denied on updating field 'name'.", $response);
$this->grantPermissionsToTestedRole(['change own username']);
// 200 for well-formed request.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
// Verify that we can log in with the new username.
$this->assertRpcLogin('Cooler Llama', $new_password);
}
/**
* Verifies that logging in with the given username and password works.
*
* @param string $username
* The username to log in with.
* @param string $password
* The password to log in with.
*/
protected function assertRpcLogin($username, $password) {
$request_body = [
'name' => $username,
'pass' => $password,
];
$request_options = [
RequestOptions::HEADERS => [],
RequestOptions::BODY => $this->serializer->encode($request_body, 'json'),
];
$response = $this->request('POST', Url::fromRoute('user.login.http')->setRouteParameter('_format', 'json'), $request_options);
$this->assertSame(200, $response->getStatusCode());
}
/**
* Tests PATCHing security-sensitive base fields to change other users.
*/
public function testPatchSecurityOtherUser() {
// The anonymous user is never allowed to modify other users.
if (!static::$auth) {
$this->markTestSkipped();
}
$this->initAuthentication();
$this->provisionEntityResource();
/** @var \Drupal\user\UserInterface $user */
$user = $this->account;
$original_normalization = array_diff_key($this->serializer->normalize($user, static::$format), ['changed' => TRUE]);
// Since this test must be performed by the user that is being modified,
// we cannot use $this->getUrl().
$url = $user->toUrl()->setOption('query', ['_format' => static::$format]);
$request_options = [
RequestOptions::HEADERS => ['Content-Type' => static::$mimeType],
];
$request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH'));
$normalization = $original_normalization;
$normalization['mail'] = [['value' => 'new-email@example.com']];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// Try changing user 1's email.
$user1 = [
'mail' => [['value' => 'another_email_address@example.com']],
'uid' => [['value' => 1]],
'name' => [['value' => 'another_user_name']],
'pass' => [['existing' => $this->account->passRaw]],
'uuid' => [['value' => '2e9403a4-d8af-4096-a116-624710140be0']],
] + $original_normalization;
$request_options[RequestOptions::BODY] = $this->serializer->encode($user1, static::$format);
$response = $this->request('PATCH', $url, $request_options);
// Ensure the email address has not changed.
$this->assertEquals('admin@example.com', $this->entityStorage->loadUnchanged(1)->getEmail());
$this->assertResourceErrorResponse(403, "Access denied on updating field 'uid'. The entity ID cannot be changed.", $response);
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessMessage($method) {
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
return parent::getExpectedUnauthorizedAccessMessage($method);
}
switch ($method) {
case 'GET':
return "The 'access user profiles' permission is required and the user must be active.";
case 'PATCH':
return "You are not authorized to update this user entity.";
case 'DELETE':
return 'You are not authorized to delete this user entity.';
default:
return parent::getExpectedUnauthorizedAccessMessage($method);
}
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessCacheability() {
// @see \Drupal\user\UserAccessControlHandler::checkAccess()
return parent::getExpectedUnauthorizedAccessCacheability()
->addCacheTags(['user:3']);
}
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class UserXmlAnonTest extends UserResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
public function testPatchDxForSecuritySensitiveBaseFields() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
}
@@ -0,0 +1,52 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class UserXmlBasicAuthTest extends UserResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
/**
* {@inheritdoc}
*/
public function testPatchDxForSecuritySensitiveBaseFields() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
/**
* {@inheritdoc}
*/
public function testPatchSecurityOtherUser() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
}
@@ -0,0 +1,47 @@
<?php
namespace Drupal\Tests\user\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class UserXmlCookieTest extends UserResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
/**
* {@inheritdoc}
*/
public function testPatchDxForSecuritySensitiveBaseFields() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
/**
* {@inheritdoc}
*/
public function testPatchSecurityOtherUser() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
}
@@ -8,6 +8,7 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
* Tests user email token upgrade path.
*
* @group Update
* @group legacy
*/
class UserUpdateEmailToken extends UpdatePathTestBase {
@@ -3,12 +3,12 @@
namespace Drupal\Tests\user\Functional\Update;
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
use Drupal\user\Entity\Role;
/**
* Tests user permissions sort upgrade path.
*
* @group Update
* @group legacy
*/
class UserUpdateOrderPermissionsTest extends UpdatePathTestBase {
@@ -25,14 +25,14 @@ class UserUpdateOrderPermissionsTest extends UpdatePathTestBase {
* Tests that permissions are ordered by machine name.
*/
public function testPermissionsOrder() {
$authenticated = Role::load('authenticated');
$permissions = $authenticated->getPermissions();
$authenticated = \Drupal::config('user.role.authenticated');
$permissions = $authenticated->get('permissions');
sort($permissions);
$this->assertNotIdentical($permissions, $authenticated->getPermissions());
$this->assertNotSame($permissions, $authenticated->get('permissions'));
$this->runUpdates();
$authenticated = Role::load('authenticated');
$this->assertIdentical($permissions, $authenticated->getPermissions());
$authenticated = \Drupal::config('user.role.authenticated');
$this->assertSame($permissions, $authenticated->get('permissions'));
}
}
@@ -108,7 +108,7 @@ class UserAdminTest extends BrowserTestBase {
$this->drupalPostForm('admin/people', $edit, t('Apply to selected items'), [
// Sort the table by username so that we know reliably which user will be
// targeted with the blocking action.
'query' => ['order' => 'name', 'sort' => 'asc']
'query' => ['order' => 'name', 'sort' => 'asc'],
]);
$site_name = $this->config('system.site')->get('name');
$this->assertMailString('body', 'Your account on ' . $site_name . ' has been blocked.', 1, 'Blocked message found in the mail sent to user C.');
@@ -129,7 +129,7 @@ class UserAdminTest extends BrowserTestBase {
$this->drupalPostForm('admin/people', $editunblock, t('Apply to selected items'), [
// Sort the table by username so that we know reliably which user will be
// targeted with the blocking action.
'query' => ['order' => 'name', 'sort' => 'asc']
'query' => ['order' => 'name', 'sort' => 'asc'],
]);
$user_storage->resetCache([$user_c->id()]);
$account = $user_storage->load($user_c->id());
@@ -2,7 +2,7 @@
namespace Drupal\Tests\user\Functional;
use Drupal\system\Tests\Entity\EntityWithUriCacheTagsTestBase;
use Drupal\Tests\system\Functional\Entity\EntityWithUriCacheTagsTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
use Drupal\user\RoleInterface;
@@ -99,23 +99,6 @@ class UserCancelTest extends BrowserTestBase {
\Drupal::service('module_installer')->install(['views']);
\Drupal::service('router.builder')->rebuild();
// Update uid 1's name and password to we know it.
$password = user_password();
$account = [
'name' => 'user1',
'pass' => $this->container->get('password')->hash(trim($password)),
];
// We cannot use $account->save() here, because this would result in the
// password being hashed again.
db_update('users_field_data')
->fields($account)
->condition('uid', 1)
->execute();
// Reload and log in uid 1.
$user_storage->resetCache([1]);
$user1 = $user_storage->load(1);
$user1->pass_raw = $password;
// Try to cancel uid 1's account with a different user.
$admin_user = $this->drupalCreateUser(['administer users']);
@@ -268,6 +251,12 @@ class UserCancelTest extends BrowserTestBase {
// Confirm account cancellation request.
$this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp));
// Confirm that the user was redirected to the front page.
$this->assertSession()->addressEquals('');
$this->assertSession()->statusCodeEquals(200);
// Confirm that the confirmation message made it through to the end user.
$this->assertRaw(t('%name has been disabled.', ['%name' => $account->getUsername()]), "Confirmation message displayed to user.");
$user_storage->resetCache([$account->id()]);
$account = $user_storage->load($account->id());
$this->assertTrue($account->isBlocked(), 'User has been blocked.');
@@ -283,9 +272,6 @@ class UserCancelTest extends BrowserTestBase {
$storage->resetCache([$comment->id()]);
$comment = $storage->load($comment->id());
$this->assertFalse($comment->isPublished(), 'Comment of the user has been unpublished.');
// Confirm that the confirmation message made it through to the end user.
$this->assertRaw(t('%name has been disabled.', ['%name' => $account->getUsername()]), "Confirmation message displayed to user.");
}
/**
@@ -2,6 +2,7 @@
namespace Drupal\Tests\user\Functional;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\BrowserTestBase;
/**
@@ -29,9 +30,15 @@ class UserEditTest extends BrowserTestBase {
// is the raw value and not a formatted one.
\Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
\Drupal::service('module_installer')->install(['user_hooks_test']);
Cache::invalidateTags(['rendered']);
$this->drupalGet('user/' . $user1->id() . '/edit');
$this->assertFieldByName('name', $user1->getAccountName());
// Ensure the formatted name is displayed when expected.
$this->drupalGet('user/' . $user1->id());
$this->assertSession()->responseContains($user1->getDisplayName());
$this->assertSession()->titleEquals(strip_tags($user1->getDisplayName()) . ' | Drupal');
// Check that filling out a single password field does not validate.
$edit = [];
$edit['pass[pass1]'] = '';
@@ -30,7 +30,7 @@ class UserMailNotifyTest extends EntityKernelTestBase {
['status_canceled', ['status_canceled']],
['register_admin_created', ['register_admin_created']],
['register_no_approval_required', ['register_no_approval_required']],
['register_pending_approval', ['register_pending_approval', 'register_pending_approval_admin']]
['register_pending_approval', ['register_pending_approval', 'register_pending_approval_admin']],
];
}
@@ -75,4 +75,25 @@ class UserTranslationUITest extends ContentTranslationUITestBase {
}
}
/**
* Test translated user deletion.
*/
public function testTranslatedUserDeletion() {
$this->drupalLogin($this->administrator);
$entity_id = $this->createEntity($this->getNewEntityValues('en'), 'en');
$entity = $this->container->get('entity_type.manager')
->getStorage($this->entityTypeId)
->load($entity_id);
$translated_entity = $entity->addTranslation('fr');
$translated_entity->save();
$url = $entity->toUrl(
'edit-form',
['language' => $this->container->get('language_manager')->getLanguage('en')]
);
$this->drupalPostForm($url, [], t('Cancel account'));
$this->assertSession()->statusCodeEquals(200);
}
}
@@ -2,7 +2,7 @@
namespace Drupal\Tests\user\Functional\Views;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\user\Entity\User;
/**
@@ -54,7 +54,7 @@ class BulkFormAccessTest extends UserTestBase {
$this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items'));
$this->assertResponse(200);
$this->assertRaw(SafeMarkup::format('No access to execute %action on the @entity_type_label %entity_label.', [
$this->assertRaw(new FormattableMarkup('No access to execute %action on the @entity_type_label %entity_label.', [
'%action' => 'Block the selected user(s)',
'@entity_type_label' => 'User',
'%entity_label' => $no_edit_user->label(),
@@ -66,7 +66,6 @@ class HandlerFilterUserNameTest extends ViewTestBase {
}
}
/**
* Tests just using the filter.
*/
@@ -96,7 +95,7 @@ class HandlerFilterUserNameTest extends ViewTestBase {
$users = [$this->randomMachineName()];
$users = array_map('strtolower', $users);
$edit = [
'options[value]' => implode(', ', $users)
'options[value]' => implode(', ', $users),
];
$this->drupalPostForm($path, $edit, t('Apply'));
$this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
@@ -106,7 +105,7 @@ class HandlerFilterUserNameTest extends ViewTestBase {
$users = [$random_name, $this->names[0]];
$users = array_map('strtolower', $users);
$edit = [
'options[value]' => implode(', ', $users)
'options[value]' => implode(', ', $users),
];
$users = [$users[0]];
$this->drupalPostForm($path, $edit, t('Apply'));
@@ -116,7 +115,7 @@ class HandlerFilterUserNameTest extends ViewTestBase {
$users = $this->names;
$users = array_map('strtolower', $users);
$edit = [
'options[value]' => implode(', ', $users)
'options[value]' => implode(', ', $users),
];
$this->drupalPostForm($path, $edit, t('Apply'));
$this->assertNoRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
@@ -0,0 +1,53 @@
<?php
namespace Drupal\Tests\user\Functional\Views;
/**
* Checks if user fields access permissions can be modified by other modules.
*
* @group user
*/
class UserFieldsAccessChangeTest extends UserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['user_access_test'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_user_fields_access'];
/**
* Tests if another module can change field access.
*/
public function testUserFieldAccess() {
$path = 'test_user_fields_access';
$this->drupalGet($path);
// User has access to name and created date by default.
$this->assertText(t('Name'));
$this->assertText(t('Created'));
// User does not by default have access to init, mail and status.
$this->assertNoText(t('Init'));
$this->assertNoText(t('Email'));
$this->assertNoText(t('Status'));
// Assign sub-admin role to grant extra access.
$user = $this->drupalCreateUser(['sub-admin']);
$this->drupalLogin($user);
$this->drupalGet($path);
// Access for init, mail and status is added in hook_entity_field_access().
$this->assertText(t('Init'));
$this->assertText(t('Email'));
$this->assertText(t('Status'));
}
}
@@ -0,0 +1,138 @@
<?php
namespace Drupal\Tests\user\FunctionalJavascript;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Tests user registration forms with additional fields.
*
* @group user
*/
class RegistrationWithUserFieldsTest extends WebDriverTestBase {
/**
* WebAssert object.
*
* @var \Drupal\Tests\WebAssert
*/
protected $webAssert;
/**
* DocumentElement object.
*
* @var \Behat\Mink\Element\DocumentElement
*/
protected $page;
/**
* {@inheritdoc}
*/
public static $modules = ['field_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->page = $this->getSession()->getPage();
$this->webAssert = $this->assertSession();
}
/**
* Tests Field API fields on user registration forms.
*/
public function testRegistrationWithUserFields() {
// Create a field on 'user' entity type.
$field_storage = FieldStorageConfig::create([
'field_name' => 'test_user_field',
'entity_type' => 'user',
'type' => 'test_field',
'cardinality' => 1,
]);
$field_storage->save();
$field = FieldConfig::create([
'field_storage' => $field_storage,
'label' => 'Some user field',
'bundle' => 'user',
'required' => TRUE,
]);
$field->save();
entity_get_form_display('user', 'user', 'default')
->setComponent('test_user_field', ['type' => 'test_field_widget'])
->save();
$user_registration_form = entity_get_form_display('user', 'user', 'register');
$user_registration_form->save();
// Check that the field does not appear on the registration form.
$this->drupalGet('user/register');
$this->webAssert->pageTextNotContains($field->label());
// Have the field appear on the registration form.
$user_registration_form->setComponent('test_user_field', ['type' => 'test_field_widget'])->save();
$this->drupalGet('user/register');
$this->webAssert->pageTextContains($field->label());
// In order to check the server side validation the native browser
// validation for required fields needs to be circumvented.
$session = $this->getSession();
$session->executeScript("jQuery('#edit-test-user-field-0-value').prop('required', false);");
// Check that validation errors are correctly reported.
$name = $this->randomMachineName();
$this->page->fillField('edit-name', $name);
$this->page->fillField('edit-mail', $name . '@example.com');
$this->page->pressButton('edit-submit');
$this->webAssert->pageTextContains(t('@name field is required.', ['@name' => $field->label()]));
// Invalid input.
$this->page->fillField('edit-test-user-field-0-value', '-1');
$this->page->pressButton('edit-submit');
$this->webAssert->pageTextContains($field->label() . ' does not accept the value -1.');
// Submit with valid data.
$value = (string) mt_rand(1, 255);
$this->page->fillField('edit-test-user-field-0-value', $value);
$this->page->pressButton('edit-submit');
// Check user fields.
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
->loadByProperties(['name' => $name, 'mail' => $name . '@example.com']);
$new_user = reset($accounts);
$this->assertEquals($value, $new_user->test_user_field->value, 'The field value was correctly saved.');
// Check that the 'add more' button works.
$field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
$field_storage->save();
$name = $this->randomMachineName();
$this->drupalGet('user/register');
$this->page->fillField('edit-name', $name);
$this->page->fillField('edit-mail', $name . '@example.com');
$this->page->fillField('test_user_field[0][value]', $value);
// Add two inputs.
$this->page->pressButton('test_user_field_add_more');
$this->webAssert->waitForElement('css', 'input[name="test_user_field[1][value]"]');
$this->page->fillField('test_user_field[1][value]', $value . '1');
$this->page->pressButton('test_user_field_add_more');
$this->webAssert->waitForElement('css', 'input[name="test_user_field[2][value]"]');
$this->page->fillField('test_user_field[2][value]', $value . '2');
// Submit with three values.
$this->page->pressButton('edit-submit');
// Check user fields.
$accounts = $this->container->get('entity_type.manager')
->getStorage('user')
->loadByProperties(['name' => $name, 'mail' => $name . '@example.com']);
$new_user = reset($accounts);
$this->assertEquals($value, $new_user->test_user_field[0]->value, t('The field value was correctly saved.'));
$this->assertEquals($value . '1', $new_user->test_user_field[1]->value, t('The field value was correctly saved.'));
$this->assertEquals($value . '2', $new_user->test_user_field[2]->value, t('The field value was correctly saved.'));
}
}
@@ -2,7 +2,7 @@
namespace Drupal\Tests\user\Kernel\Condition;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
@@ -151,7 +151,7 @@ class UserRoleConditionTest extends KernelTestBase {
$condition->setConfig('roles', [$this->role->id() => $this->role->id()]);
$condition->setConfig('negate', FALSE);
$this->assertTrue($condition->execute(), 'Authenticated user is a member of the custom role.');
$this->assertEqual($condition->summary(), SafeMarkup::format('The user is a member of @roles', ['@roles' => $this->role->label()]));
$this->assertEqual($condition->summary(), new FormattableMarkup('The user is a member of @roles', ['@roles' => $this->role->label()]));
}
}
@@ -47,6 +47,10 @@ class MigrateUserProfileEntityDisplayTest extends MigrateDrupal6TestBase {
// Test PROFILE_HIDDEN field is hidden.
$this->assertNull($display->getComponent('profile_sold_to'));
// Test a checkbox field.
$component = $display->getComponent('profile_really_really_love_mig');
$this->assertIdentical('list_default', $component['type']);
}
}
@@ -49,7 +49,7 @@ class MigrateUserProfileEntityFormDisplayTest extends MigrateDrupal6TestBase {
$this->assertNull($display->getComponent('profile_sold_to'));
// Test that a checkbox field has the proper display label setting.
$component = $display->getComponent('profile_love_migrations');
$component = $display->getComponent('profile_really_really_love_mig');
$this->assertIdentical('boolean_checkbox', $component['type']);
$this->assertIdentical(TRUE, $component['settings']['display_label']);
}
@@ -68,8 +68,8 @@ class MigrateUserProfileFieldInstanceTest extends MigrateDrupal6TestBase {
$this->assertIdentical("Enter your birth date and we'll send you a coupon.", $field->getDescription());
// Another migrated checkbox field, with a different source visibility setting.
$field = FieldConfig::load('user.user.profile_love_migrations');
$this->assertIdentical('I love migrations', $field->label());
$field = FieldConfig::load('user.user.profile_really_really_love_mig');
$this->assertIdentical('I really, really, really love migrations', $field->label());
$this->assertIdentical("If you check this box, you love migrations.", $field->getDescription());
}
@@ -59,7 +59,13 @@ EOT;
$this->assertNull($user->profile_blog->title);
$this->assertIdentical([], $user->profile_blog->options);
$this->assertIdentical('http://example.com/blog', $user->profile_blog->uri);
$this->assertNull($user->profile_love_migrations->value);
// Check that the source profile field names that are longer than 32
// characters have been migrated.
$this->assertNotNull($user->getFieldDefinition('profile_really_really_love_mig'));
$this->assertNotNull($user->getFieldDefinition('profile_really_really_love_mig1'));
$this->assertSame('1', $user->profile_really_really_love_mig->value);
$this->assertNull($user->profile_really_really_love_mig1->value);
$user = User::load(8);
$this->assertIdentical('Forward/slash', $user->profile_sold_to->value);
@@ -60,7 +60,7 @@ class MigrateUserRoleTest extends MigrateDrupal6TestBase {
'access content',
'migrate test anonymous permission',
// From filter_format tables.
'use text format filtered_html'
'use text format filtered_html',
];
$this->assertRole('anonymous', $permissions, 1, $id_map);
@@ -81,7 +81,7 @@ class MigrateUserRoleTest extends MigrateDrupal6TestBase {
'migrate test role 1 test permission',
// From filter format.
'use text format full_html',
'use text format php_code'
'use text format php_code',
];
$this->assertRole('migrate_test_role_1', $permissions, 3, $id_map);
@@ -126,7 +126,7 @@ class MigrateUserRoleTest extends MigrateDrupal6TestBase {
'administrator1',
'migrate_test_role_11',
'migrate_test_role_21',
'migrate_test_role_3_that_is_longer_than_thirty_two_characters1'
'migrate_test_role_3_that_is_longer_than_thirty_two_characters1',
];
$this->assertEmpty(Role::loadMultiple($roles));
@@ -24,11 +24,14 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
*/
public static $modules = [
'comment',
'content_translation',
'datetime',
'file',
'image',
'language',
'link',
// Required for translation migrations.
'migrate_drupal_multilingual',
'node',
'system',
'taxonomy',
@@ -44,6 +47,9 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
// Prepare to migrate user pictures as well.
$this->installEntitySchema('file');
$this->installEntitySchema('comment');
$this->installEntitySchema('node');
$this->installEntitySchema('taxonomy_term');
$this->createNodeCommentCombination('page');
$this->createNodeCommentCombination('article');
$this->createNodeCommentCombination('blog');
@@ -59,6 +65,8 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
'd7_field',
'd7_field_instance',
'd7_user',
'd7_entity_translation_settings',
'd7_user_entity_translation',
]);
}
@@ -81,8 +89,10 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* The last login time.
* @param bool $blocked
* Whether or not the account is blocked.
* @param string $langcode
* The user account's language code.
* @param string $entity_langcode
* The user entity language code.
* @param string $prefered_langcode
* The user prefered language code.
* @param string $timezone
* The user account's timezone name.
* @param string $init
@@ -96,7 +106,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* @param bool $has_picture
* (optional) Whether the user is expected to have a picture attached.
*/
protected function assertEntity($id, $label, $mail, $password, $created, $access, $login, $blocked, $langcode, $timezone, $init, $roles, $field_integer, $field_file_target_id = FALSE, $has_picture = FALSE) {
protected function assertEntity($id, $label, $mail, $password, $created, $access, $login, $blocked, $entity_langcode, $prefered_langcode, $timezone, $init, $roles, $field_integer, $field_file_target_id = FALSE, $has_picture = FALSE) {
/** @var \Drupal\user\UserInterface $user */
$user = User::load($id);
$this->assertTrue($user instanceof UserInterface);
@@ -115,20 +125,20 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
// test if the value was imported correctly.
$language_manager = $this->container->get('language_manager');
$default_langcode = $language_manager->getDefaultLanguage()->getId();
if ($langcode == '') {
if ($prefered_langcode == '') {
$this->assertSame('en', $user->langcode->value);
$this->assertSame($default_langcode, $user->preferred_langcode->value);
$this->assertSame($default_langcode, $user->preferred_admin_langcode->value);
}
elseif ($language_manager->getLanguage($langcode) === NULL) {
elseif ($language_manager->getLanguage($prefered_langcode) === NULL) {
$this->assertSame($default_langcode, $user->langcode->value);
$this->assertSame($default_langcode, $user->preferred_langcode->value);
$this->assertSame($default_langcode, $user->preferred_admin_langcode->value);
}
else {
$this->assertSame($langcode, $user->langcode->value);
$this->assertSame($langcode, $user->preferred_langcode->value);
$this->assertSame($langcode, $user->preferred_admin_langcode->value);
$this->assertSame($entity_langcode, $user->langcode->value);
$this->assertSame($prefered_langcode, $user->preferred_langcode->value);
$this->assertSame($prefered_langcode, $user->preferred_admin_langcode->value);
}
$this->assertSame($timezone, $user->getTimeZone());
@@ -170,10 +180,21 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
$roles[] = reset($role);
}
$entity_translation = Database::getConnection('default', 'migrate')
->select('entity_translation', 'et')
->fields('et', ['language'])
->condition('et.entity_type', 'user')
->condition('et.entity_id', $source->uid)
->condition('et.source', '')
->execute()
->fetchField();
$entity_language = $entity_translation ?: $source->language;
$field_integer = Database::getConnection('default', 'migrate')
->select('field_data_field_integer', 'fi')
->fields('fi', ['field_integer_value'])
->condition('fi.entity_id', $source->uid)
->condition('fi.language', $entity_language)
->execute()
->fetchCol();
$field_integer = !empty($field_integer) ? $field_integer : NULL;
@@ -194,6 +215,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
$source->access,
$source->login,
$source->status,
$entity_language,
$source->language,
$source->timezone,
$source->init,
@@ -218,4 +240,45 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
}
}
/**
* Tests the Drupal 7 user entity translations to Drupal 8 migration.
*/
public function testUserEntityTranslations() {
$manager = $this->container->get('content_translation.manager');
// Get the user and its translations.
$user = User::load(2);
$user_fr = $user->getTranslation('fr');
$user_is = $user->getTranslation('is');
// Test that fields translated with Entity Translation are migrated.
$this->assertSame('99', $user->field_integer->value);
$this->assertSame('9', $user_fr->field_integer->value);
$this->assertSame('1', $user_is->field_integer->value);
// Test that the French translation metadata is correctly migrated.
$metadata_fr = $manager->getTranslationMetadata($user_fr);
$this->assertSame('en', $metadata_fr->getSource());
$this->assertSame('1', $metadata_fr->getAuthor()->uid->value);
$this->assertSame('1531663916', $metadata_fr->getCreatedTime());
$this->assertFalse($metadata_fr->isOutdated());
$this->assertFalse($metadata_fr->isPublished());
// Test that the Icelandic translation metadata is correctly migrated.
$metadata_is = $manager->getTranslationMetadata($user_is);
$this->assertSame('en', $metadata_is->getSource());
$this->assertSame('2', $metadata_is->getAuthor()->uid->value);
$this->assertSame('1531663925', $metadata_is->getCreatedTime());
$this->assertTrue($metadata_is->isOutdated());
$this->assertTrue($metadata_is->isPublished());
// Test that untranslatable properties are the same as the source language.
$this->assertSame($user->label(), $user_fr->label());
$this->assertSame($user->label(), $user_is->label());
$this->assertSame($user->getEmail(), $user_fr->getEmail());
$this->assertSame($user->getEmail(), $user_is->getEmail());
$this->assertSame($user->getPassword(), $user_fr->getPassword());
$this->assertSame($user->getPassword(), $user_is->getPassword());
}
}
@@ -99,7 +99,7 @@ class ProfileFieldTest extends MigrateSqlSourceTestBase {
'fid' => 4,
'uid' => 1,
'value' => 'yellow',
]
],
];
// Expected options are:
@@ -114,7 +114,7 @@ class ProfileFieldTest extends MigrateSqlSourceTestBase {
'blue' => 'blue',
'green' => 'green',
'yellow' => 'yellow',
]
],
];
$tests[0]['expected_data'] = $profile_fields;
@@ -0,0 +1,199 @@
<?php
namespace Drupal\Tests\user\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 user entity translation source plugin.
*
* @covers \Drupal\user\Plugin\migrate\source\d7\UserEntityTranslation
*
* @group user
*/
class UserEntityTranslationTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['user', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['entity_translation'] = [
[
'entity_type' => 'user',
'entity_id' => 1,
'revision_id' => 1,
'language' => 'en',
'source' => '',
'uid' => 1,
'status' => 1,
'translate' => 0,
'created' => 1531343498,
'changed' => 1531343498,
],
[
'entity_type' => 'user',
'entity_id' => 1,
'revision_id' => 1,
'language' => 'fr',
'source' => 'en',
'uid' => 2,
'status' => 1,
'translate' => 1,
'created' => 1531343508,
'changed' => 1531343508,
],
[
'entity_type' => 'user',
'entity_id' => 1,
'revision_id' => 1,
'language' => 'es',
'source' => 'en',
'uid' => 1,
'status' => 0,
'translate' => 0,
'created' => 1531343456,
'changed' => 1531343456,
],
];
$tests[0]['source_data']['field_config'] = [
[
'id' => 1,
'field_name' => 'field_test',
'type' => 'text',
'module' => 'text',
'active' => 1,
'storage_type' => 'field_sql_storage',
'storage_module' => 'field_sql_storage',
'storage_active' => 1,
'locked' => 1,
'data' => 'a:0:{}',
'cardinality' => 1,
'translatable' => 1,
'deleted' => 0,
],
];
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => 1,
'field_id' => 1,
'field_name' => 'field_test',
'entity_type' => 'user',
'bundle' => 'user',
'data' => 'a:0:{}',
'deleted' => 0,
],
];
$tests[0]['source_data']['field_data_field_test'] = [
[
'entity_type' => 'user',
'bundle' => 'user',
'deleted' => 0,
'entity_id' => 1,
'revision_id' => 1,
'language' => 'en',
'delta' => 0,
'field_test_value' => 'English field',
'field_test_format' => NULL,
],
[
'entity_type' => 'user',
'bundle' => 'user',
'deleted' => 0,
'entity_id' => 1,
'revision_id' => 1,
'language' => 'fr',
'delta' => 0,
'field_test_value' => 'French field',
'field_test_format' => NULL,
],
[
'entity_type' => 'user',
'bundle' => 'user',
'deleted' => 0,
'entity_id' => 1,
'revision_id' => 1,
'language' => 'es',
'delta' => 0,
'field_test_value' => 'Spanish field',
'field_test_format' => NULL,
],
];
$tests[0]['source_data']['users'] = [
[
'uid' => 1,
'name' => 'admin',
'pass' => 'password123',
'mail' => 'admin@example.com',
'theme' => '',
'signature' => '',
'signature_format' => 'filtered_html',
'created' => 1531343456,
'access' => 1531343456,
'login' => 1531343456,
'status' => 1,
'timezone' => 'America/New_York',
'language' => 'fr',
'picture' => 0,
'init' => 'admin@example.com',
'data' => 'a:0:{}',
],
];
$tests[0]['source_data']['users_roles'] = [
[
'uid' => 1,
'rid' => 3,
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'entity_type' => 'user',
'entity_id' => 1,
'revision_id' => 1,
'language' => 'fr',
'source' => 'en',
'uid' => 2,
'status' => 1,
'translate' => 1,
'created' => 1531343508,
'changed' => 1531343508,
'field_test' => [
[
'value' => 'French field',
'format' => NULL,
],
],
],
[
'entity_type' => 'user',
'entity_id' => 1,
'revision_id' => 1,
'language' => 'es',
'source' => 'en',
'uid' => 1,
'status' => 0,
'translate' => 0,
'created' => 1531343456,
'changed' => 1531343456,
'field_test' => [
[
'value' => 'Spanish field',
'format' => NULL,
],
],
],
];
return $tests;
}
}
@@ -24,6 +24,12 @@ class UserTest extends MigrateSqlSourceTestBase {
$tests = [];
// The source data.
$tests[0]['source_data']['field_config'] = [
[
'id' => '11',
'translatable' => '0',
],
];
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => '33',
@@ -24,8 +24,8 @@ class UserAccountFormFieldsTest extends KernelTestBase {
* Tests the root user account form section in the "Configure site" form.
*/
public function testInstallConfigureForm() {
require_once \Drupal::root() . '/core/includes/install.core.inc';
require_once \Drupal::root() . '/core/includes/install.inc';
require_once $this->root . '/core/includes/install.core.inc';
require_once $this->root . '/core/includes/install.inc';
$install_state = install_state_defaults();
$form_state = new FormState();
$form_state->addBuildInfo('args', [&$install_state]);
@@ -28,7 +28,6 @@ class UserInstallTest extends KernelTestBase {
user_install();
}
/**
* Test that the initial users have correct values.
*/
@@ -215,7 +215,7 @@ class UserValidationTest extends KernelTestBase {
protected function assertAllowedValuesViolation(EntityInterface $entity, $field_name) {
$violations = $entity->validate();
$this->assertEqual(count($violations), 1, "Allowed values violation for $field_name found.");
$this->assertEqual($violations[0]->getPropertyPath(), "$field_name.0.value");
$this->assertEqual($violations[0]->getPropertyPath(), $field_name === 'langcode' ? "$field_name.0" : "$field_name.0.value");
$this->assertEqual($violations[0]->getMessage(), t('The value you selected is not a valid choice.'));
}
@@ -0,0 +1,118 @@
<?php
namespace Drupal\Tests\user\Kernel;
use Drupal\block\Entity\Block;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\User;
/**
* Tests the Who's Online Block.
*
* @group user
*/
class WhosOnlineBlockTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user', 'block', 'views'];
/**
* The block being tested.
*
* @var \Drupal\block\Entity\BlockInterface
*/
protected $block;
/**
* The block storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $controller;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['system', 'block', 'views', 'user']);
$this->installSchema('system', ['sequences']);
$this->installEntitySchema('user');
$this->controller = $this->container
->get('entity_type.manager')
->getStorage('block');
// Create a block with only required values.
$this->block = $this->controller->create([
'plugin' => 'views_block:who_s_online-who_s_online_block',
'region' => 'sidebar_first',
'id' => 'views_block__who_s_online_who_s_online_block',
'theme' => \Drupal::configFactory()->get('system.theme')->get('default'),
'label' => "Who's online",
'visibility' => [],
'weight' => 0,
]);
$this->block->save();
$this->container->get('cache.render')->deleteAll();
$this->renderer = $this->container->get('renderer');
}
/**
* Test the Who's Online block.
*/
public function testWhosOnlineBlock() {
$request_time = \Drupal::time()->getRequestTime();
// Generate users.
$user1 = User::create([
'name' => 'user1',
'mail' => 'user1@example.com',
]);
$user1->addRole('administrator');
$user1->activate();
$user1->setLastAccessTime($request_time);
$user1->save();
$user2 = User::create([
'name' => 'user2',
'mail' => 'user2@example.com',
]);
$user2->activate();
$user2->setLastAccessTime($request_time + 1);
$user2->save();
$user3 = User::create([
'name' => 'user3',
'mail' => 'user2@example.com',
]);
$user3->activate();
// Insert an inactive user who should not be seen in the block.
$inactive_time = $request_time - (60 * 60);
$user3->setLastAccessTime($inactive_time);
$user3->save();
// Test block output.
\Drupal::currentUser()->setAccount($user1);
// Test the rendering of a block.
$entity = Block::load('views_block__who_s_online_who_s_online_block');
$output = entity_view($entity, 'block');
$this->setRawContent($this->renderer->renderRoot($output));
$this->assertRaw('2 users', 'Correct number of online users (2 users).');
$this->assertText($user1->getUsername(), 'Active user 1 found in online list.');
$this->assertText($user2->getUsername(), 'Active user 2 found in online list.');
$this->assertNoText($user3->getUsername(), 'Inactive user not found in online list.');
$this->assertTrue(strpos($this->getRawContent(), $user1->getUsername()) > strpos($this->getRawContent(), $user2->getUsername()), 'Online users are ordered correctly.');
}
}
@@ -2,7 +2,7 @@
namespace Drupal\Tests\user\Traits;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
@@ -69,7 +69,7 @@ trait UserCreationTrait {
$account = User::create($edit);
$account->save();
$this->assertTrue($account->id(), SafeMarkup::format('User created with name %name and pass %pass', ['%name' => $edit['name'], '%pass' => $edit['pass']]), 'User login');
$this->assertTrue($account->id(), new FormattableMarkup('User created with name %name and pass %pass', ['%name' => $edit['name'], '%pass' => $edit['pass']]), 'User login');
if (!$account->id()) {
return FALSE;
}
@@ -149,7 +149,7 @@ trait UserCreationTrait {
}
$result = $role->save();
$this->assertIdentical($result, SAVED_NEW, SafeMarkup::format('Created role ID @rid with name @name.', [
$this->assertIdentical($result, SAVED_NEW, new FormattableMarkup('Created role ID @rid with name @name.', [
'@name' => var_export($role->label(), TRUE),
'@rid' => var_export($role->id(), TRUE),
]), 'Role');
@@ -161,10 +161,10 @@ trait UserCreationTrait {
$assigned_permissions = Role::load($role->id())->getPermissions();
$missing_permissions = array_diff($permissions, $assigned_permissions);
if (!$missing_permissions) {
$this->pass(SafeMarkup::format('Created permissions: @perms', ['@perms' => implode(', ', $permissions)]), 'Role');
$this->pass(new FormattableMarkup('Created permissions: @perms', ['@perms' => implode(', ', $permissions)]), 'Role');
}
else {
$this->fail(SafeMarkup::format('Failed to create permissions: @perms', ['@perms' => implode(', ', $missing_permissions)]), 'Role');
$this->fail(new FormattableMarkup('Failed to create permissions: @perms', ['@perms' => implode(', ', $missing_permissions)]), 'Role');
}
}
return $role->id();
@@ -188,7 +188,7 @@ trait UserCreationTrait {
$valid = TRUE;
foreach ($permissions as $permission) {
if (!in_array($permission, $available)) {
$this->fail(SafeMarkup::format('Invalid permission %permission.', ['%permission' => $permission]), 'Role');
$this->fail(new FormattableMarkup('Invalid permission %permission.', ['%permission' => $permission]), 'Role');
$valid = FALSE;
}
}
@@ -79,7 +79,7 @@ class PermissionAccessCheckTest extends UnitTestCase {
->will($this->returnValueMap([
['allowed', TRUE],
['denied', FALSE],
['other', FALSE]
['other', FALSE],
]
));
$route = new Route('', [], $requirements);
@@ -400,7 +400,7 @@ class TestPermissionCallbacks {
public function singleDescription() {
return [
'access_module_a' => 'single_description'
'access_module_a' => 'single_description',
];
}
@@ -54,6 +54,8 @@ class UserBulkFormTest extends UnitTestCase {
$language_manager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
$messenger = $this->getMock('Drupal\Core\Messenger\MessengerInterface');
$views_data = $this->getMockBuilder('Drupal\views\ViewsData')
->disableOriginalConstructor()
->getMock();
@@ -84,7 +86,7 @@ class UserBulkFormTest extends UnitTestCase {
$definition['title'] = '';
$options = [];
$user_bulk_form = new UserBulkForm([], 'user_bulk_form', $definition, $entity_manager, $language_manager);
$user_bulk_form = new UserBulkForm([], 'user_bulk_form', $definition, $entity_manager, $language_manager, $messenger);
$user_bulk_form->init($executable, $display, $options);
$this->assertAttributeEquals(array_slice($actions, 0, -1, TRUE), 'actions', $user_bulk_form);
@@ -96,7 +96,6 @@ class PrivateTempStoreTest extends UnitTestCase {
$this->otherObject->owner = 2;
}
/**
* Tests the get() method.
*
@@ -19,11 +19,18 @@ class RolesRidTest extends UnitTestCase {
* Tests the titleQuery method.
*
* @covers ::titleQuery
*
* @group legacy
*
* Note this is only a legacy test because it triggers a call to
* \Drupal\Core\Entity\EntityTypeInterface::getLabelCallback() which is mocked
* and triggers a deprecation error. Remove when ::getLabelCallback() is
* removed.
*/
public function testTitleQuery() {
$role1 = new Role([
'id' => 'test_rid_1',
'label' => 'test rid 1'
'label' => 'test rid 1',
], 'user_role');
$role2 = new Role([
'id' => 'test_rid_2',