Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 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,15 +5,16 @@
|
|||
* Support module for user hooks testing.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_user_format_name_alter().
|
||||
*/
|
||||
function user_hooks_test_user_format_name_alter(&$name, $account) {
|
||||
function user_hooks_test_user_format_name_alter(&$name, AccountInterface $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,64 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\views_ui\Functional\UITestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
|
||||
/**
|
||||
* Tests views role access plugin UI.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\access\Role
|
||||
*/
|
||||
class AccessRoleUITest extends UITestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_access_role'];
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user', 'user_test_views'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['user_test_views']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the role access plugin UI.
|
||||
*/
|
||||
public function testAccessRoleUI() {
|
||||
$entity_manager = $this->container->get('entity.manager');
|
||||
$entity_manager->getStorage('user_role')->create(['id' => 'custom_role', 'label' => 'Custom role'])->save();
|
||||
$access_url = "admin/structure/views/nojs/display/test_access_role/default/access_options";
|
||||
$this->drupalPostForm($access_url, ['access_options[role][custom_role]' => 1], t('Apply'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$view = $entity_manager->getStorage('view')->load('test_access_role');
|
||||
|
||||
$display = $view->getDisplay('default');
|
||||
$this->assertEqual($display['display_options']['access']['options']['role'], ['custom_role' => 'custom_role']);
|
||||
|
||||
// Test changing access plugin from role to none.
|
||||
$this->drupalPostForm('admin/structure/views/nojs/display/test_access_role/default/access', ['access[type]' => 'none'], t('Apply'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
// Verify that role option is not set.
|
||||
$view = $entity_manager->getStorage('view')->load('test_access_role');
|
||||
$display = $view->getDisplay('default');
|
||||
$this->assertFalse(isset($display['display_options']['access']['options']['role']));
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests user email token upgrade path.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UserUpdateEmailToken extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../fixtures/update/drupal-8.user-email-token-2587275.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that email token in status_blocked of user.mail is updated.
|
||||
*/
|
||||
public function testEmailToken() {
|
||||
$mail = \Drupal::config('user.mail')->get('status_blocked');
|
||||
$this->assertTrue(strpos($mail['body'], '[site:account-name]'));
|
||||
$this->runUpdates();
|
||||
$mail = \Drupal::config('user.mail')->get('status_blocked');
|
||||
$this->assertFalse(strpos($mail['body'], '[site:account-name]'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests user permissions sort upgrade path.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UserUpdateOrderPermissionsTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that permissions are ordered by machine name.
|
||||
*/
|
||||
public function testPermissionsOrder() {
|
||||
$authenticated = \Drupal::config('user.role.authenticated');
|
||||
$permissions = $authenticated->get('permissions');
|
||||
sort($permissions);
|
||||
$this->assertNotSame($permissions, $authenticated->get('permissions'));
|
||||
|
||||
$this->runUpdates();
|
||||
$authenticated = \Drupal::config('user.role.authenticated');
|
||||
$this->assertSame($permissions, $authenticated->get('permissions'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests user-account links.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserAccountLinksTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['menu_ui', 'block', 'test_page_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->drupalPlaceBlock('system_menu_block:account');
|
||||
// Make test-page default.
|
||||
$this->config('system.site')->set('page.front', '/test-page')->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the secondary menu.
|
||||
*/
|
||||
public function testSecondaryMenu() {
|
||||
// Create a regular user.
|
||||
$user = $this->drupalCreateUser([]);
|
||||
|
||||
// Log in and get the homepage.
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet('<front>');
|
||||
|
||||
// For a logged-in user, expect the secondary menu to have links for "My
|
||||
// account" and "Log out".
|
||||
$link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [
|
||||
':menu_class' => 'menu',
|
||||
':href' => 'user',
|
||||
':text' => 'My account',
|
||||
]);
|
||||
$this->assertEqual(count($link), 1, 'My account link is in secondary menu.');
|
||||
|
||||
$link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [
|
||||
':menu_class' => 'menu',
|
||||
':href' => 'user/logout',
|
||||
':text' => 'Log out',
|
||||
]);
|
||||
$this->assertEqual(count($link), 1, 'Log out link is in secondary menu.');
|
||||
|
||||
// Log out and get the homepage.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('<front>');
|
||||
|
||||
// For a logged-out user, expect the secondary menu to have a "Log in" link.
|
||||
$link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [
|
||||
':menu_class' => 'menu',
|
||||
':href' => 'user/login',
|
||||
':text' => 'Log in',
|
||||
]);
|
||||
$this->assertEqual(count($link), 1, 'Log in link is in secondary menu.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests disabling the 'My account' link.
|
||||
*/
|
||||
public function testDisabledAccountLink() {
|
||||
// Create an admin user and log in.
|
||||
$this->drupalLogin($this->drupalCreateUser(['access administration pages', 'administer menu']));
|
||||
|
||||
// Verify that the 'My account' link exists before we check for its
|
||||
// disappearance.
|
||||
$link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [
|
||||
':menu_class' => 'menu',
|
||||
':href' => 'user',
|
||||
':text' => 'My account',
|
||||
]);
|
||||
$this->assertEqual(count($link), 1, 'My account link is in the secondary menu.');
|
||||
|
||||
// Verify that the 'My account' link is enabled. Do not assume the value of
|
||||
// auto-increment is 1. Use XPath to obtain input element id and name using
|
||||
// the consistent label text.
|
||||
$this->drupalGet('admin/structure/menu/manage/account');
|
||||
$label = $this->xpath('//label[contains(.,:text)]/@for', [':text' => 'Enable My account menu link']);
|
||||
$this->assertFieldChecked($label[0]->getText(), "The 'My account' link is enabled by default.");
|
||||
|
||||
// Disable the 'My account' link.
|
||||
$edit['links[menu_plugin_id:user.page][enabled]'] = FALSE;
|
||||
$this->drupalPostForm('admin/structure/menu/manage/account', $edit, t('Save'));
|
||||
|
||||
// Get the homepage.
|
||||
$this->drupalGet('<front>');
|
||||
|
||||
// Verify that the 'My account' link does not appear when disabled.
|
||||
$link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [
|
||||
':menu_class' => 'menu',
|
||||
':href' => 'user',
|
||||
':text' => 'My account',
|
||||
]);
|
||||
$this->assertEqual(count($link), 0, 'My account link is not in the secondary menu.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests page title is set correctly on user account tabs.
|
||||
*/
|
||||
public function testAccountPageTitles() {
|
||||
// Default page titles are suffixed with the site name - Drupal.
|
||||
$title_suffix = ' | Drupal';
|
||||
|
||||
$this->drupalGet('user');
|
||||
$this->assertTitle('Log in' . $title_suffix, "Page title of /user is 'Log in'");
|
||||
|
||||
$this->drupalGet('user/login');
|
||||
$this->assertTitle('Log in' . $title_suffix, "Page title of /user/login is 'Log in'");
|
||||
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertTitle('Create new account' . $title_suffix, "Page title of /user/register is 'Create new account' for anonymous users.");
|
||||
|
||||
$this->drupalGet('user/password');
|
||||
$this->assertTitle('Reset your password' . $title_suffix, "Page title of /user/register is 'Reset your password' for anonymous users.");
|
||||
|
||||
// Check the page title for registered users is "My Account" in menus.
|
||||
$this->drupalLogin($this->drupalCreateUser());
|
||||
// After login, the client is redirected to /user.
|
||||
$this->assertLink(t('My account'), 0, "Page title of /user is 'My Account' in menus for registered users");
|
||||
$this->assertLinkByHref(\Drupal::urlGenerator()->generate('user.page'), 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests users' ability to change their own administration language.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserAdminLanguageTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* A user with permission to access admin pages and administer languages.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* A non-administrator user for this test.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $regularUser;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user', 'language', 'language_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// User to add and remove language.
|
||||
$this->adminUser = $this->drupalCreateUser(['administer languages', 'access administration pages']);
|
||||
// User to check non-admin access.
|
||||
$this->regularUser = $this->drupalCreateUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that admin language is not configurable in single language sites.
|
||||
*/
|
||||
public function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->setLanguageNegotiation();
|
||||
$path = 'user/' . $this->adminUser->id() . '/edit';
|
||||
$this->drupalGet($path);
|
||||
// Ensure administration pages language settings widget is not available.
|
||||
$this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that admin language negotiation is configurable only if enabled.
|
||||
*/
|
||||
public function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->addCustomLanguage();
|
||||
$path = 'user/' . $this->adminUser->id() . '/edit';
|
||||
|
||||
// Checks with user administration pages language negotiation disabled.
|
||||
$this->drupalGet($path);
|
||||
// Ensure administration pages language settings widget is not available.
|
||||
$this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available.');
|
||||
|
||||
// Checks with user administration pages language negotiation enabled.
|
||||
$this->setLanguageNegotiation();
|
||||
$this->drupalGet($path);
|
||||
// Ensure administration pages language settings widget is available.
|
||||
$this->assertFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector is available.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the admin language is configurable only for administrators.
|
||||
*
|
||||
* If a user has the permission "access administration pages", they should
|
||||
* be able to see the setting to pick the language they want those pages in.
|
||||
*
|
||||
* If a user does not have that permission, it would confusing for them to
|
||||
* have a setting for pages they cannot access, so they should not be able to
|
||||
* set a language for those pages.
|
||||
*/
|
||||
public function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIsEnabled() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
// Adds a new language, because with only one language, setting won't show.
|
||||
$this->addCustomLanguage();
|
||||
$this->setLanguageNegotiation();
|
||||
$path = 'user/' . $this->adminUser->id() . '/edit';
|
||||
$this->drupalGet($path);
|
||||
// Ensure administration pages language setting is visible for admin.
|
||||
$this->assertFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector available for admins.');
|
||||
|
||||
// Ensure administration pages language setting is hidden for non-admins.
|
||||
$this->drupalLogin($this->regularUser);
|
||||
$path = 'user/' . $this->regularUser->id() . '/edit';
|
||||
$this->drupalGet($path);
|
||||
$this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available for regular user.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the actual language negotiation.
|
||||
*/
|
||||
public function testActualNegotiation() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->addCustomLanguage();
|
||||
$this->setLanguageNegotiation();
|
||||
|
||||
// Even though we have admin language negotiation, so long as the user has
|
||||
// no preference set, negotiation will fall back further.
|
||||
$path = 'user/' . $this->adminUser->id() . '/edit';
|
||||
$this->drupalGet($path);
|
||||
$this->assertText('Language negotiation method: language-default');
|
||||
$this->drupalGet('xx/' . $path);
|
||||
$this->assertText('Language negotiation method: language-url');
|
||||
|
||||
// Set a preferred language code for the user.
|
||||
$edit = [];
|
||||
$edit['preferred_admin_langcode'] = 'xx';
|
||||
$this->drupalPostForm($path, $edit, t('Save'));
|
||||
|
||||
// Test negotiation with the URL method first. The admin method will only
|
||||
// be used if the URL method did not match.
|
||||
$this->drupalGet($path);
|
||||
$this->assertText('Language negotiation method: language-user-admin');
|
||||
$this->drupalGet('xx/' . $path);
|
||||
$this->assertText('Language negotiation method: language-url');
|
||||
|
||||
// Test negotiation with the admin language method first. The admin method
|
||||
// will be used at all times.
|
||||
$this->setLanguageNegotiation(TRUE);
|
||||
$this->drupalGet($path);
|
||||
$this->assertText('Language negotiation method: language-user-admin');
|
||||
$this->drupalGet('xx/' . $path);
|
||||
$this->assertText('Language negotiation method: language-user-admin');
|
||||
|
||||
// Unset the preferred language code for the user.
|
||||
$edit = [];
|
||||
$edit['preferred_admin_langcode'] = '';
|
||||
$this->drupalPostForm($path, $edit, t('Save'));
|
||||
$this->drupalGet($path);
|
||||
$this->assertText('Language negotiation method: language-default');
|
||||
$this->drupalGet('xx/' . $path);
|
||||
$this->assertText('Language negotiation method: language-url');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the User interface negotiation detection method.
|
||||
*
|
||||
* Enables the "Account preference for administration pages" language
|
||||
* detection method for the User interface language negotiation type.
|
||||
*
|
||||
* @param bool $admin_first
|
||||
* Whether the admin negotiation should be first.
|
||||
*/
|
||||
public function setLanguageNegotiation($admin_first = FALSE) {
|
||||
$edit = [
|
||||
'language_interface[enabled][language-user-admin]' => TRUE,
|
||||
'language_interface[enabled][language-url]' => TRUE,
|
||||
'language_interface[weight][language-user-admin]' => ($admin_first ? -12 : -8),
|
||||
'language_interface[weight][language-url]' => -10,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for adding a custom language.
|
||||
*/
|
||||
public function addCustomLanguage() {
|
||||
$langcode = 'xx';
|
||||
// The English name for the language.
|
||||
$name = $this->randomMachineName(16);
|
||||
$edit = [
|
||||
'predefined_langcode' => 'custom',
|
||||
'langcode' => $langcode,
|
||||
'label' => $name,
|
||||
'direction' => LanguageInterface::DIRECTION_LTR,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests the user admin listing if views is not enabled.
|
||||
*
|
||||
* @group user
|
||||
* @see user_admin_account()
|
||||
*/
|
||||
class UserAdminListingTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Tests the listing.
|
||||
*/
|
||||
public function testUserListing() {
|
||||
$this->drupalGet('admin/people');
|
||||
$this->assertResponse(403, 'Anonymous user does not have access to the user admin listing.');
|
||||
|
||||
// Create a bunch of users.
|
||||
$accounts = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$account = $this->drupalCreateUser();
|
||||
$accounts[$account->label()] = $account;
|
||||
}
|
||||
// Create a blocked user.
|
||||
$account = $this->drupalCreateUser();
|
||||
$account->block();
|
||||
$account->save();
|
||||
$accounts[$account->label()] = $account;
|
||||
|
||||
// Create a user at a certain timestamp.
|
||||
$account = $this->drupalCreateUser();
|
||||
$account->created = 1363219200;
|
||||
$account->save();
|
||||
$accounts[$account->label()] = $account;
|
||||
$timestamp_user = $account->label();
|
||||
|
||||
$rid_1 = $this->drupalCreateRole([], 'custom_role_1', 'custom_role_1');
|
||||
$rid_2 = $this->drupalCreateRole([], 'custom_role_2', 'custom_role_2');
|
||||
|
||||
$account = $this->drupalCreateUser();
|
||||
$account->addRole($rid_1);
|
||||
$account->addRole($rid_2);
|
||||
$account->save();
|
||||
$accounts[$account->label()] = $account;
|
||||
$role_account_name = $account->label();
|
||||
|
||||
// Create an admin user and look at the listing.
|
||||
$admin_user = $this->drupalCreateUser(['administer users']);
|
||||
$accounts[$admin_user->label()] = $admin_user;
|
||||
|
||||
$accounts['admin'] = User::load(1);
|
||||
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalGet('admin/people');
|
||||
$this->assertResponse(200, 'The admin user has access to the user admin listing.');
|
||||
|
||||
$result = $this->xpath('//table[contains(@class, "responsive-enabled")]/tbody/tr');
|
||||
$result_accounts = [];
|
||||
foreach ($result as $account) {
|
||||
$account_columns = $account->findAll('css', 'td');
|
||||
$name = $account_columns[0]->getText();
|
||||
$roles = [];
|
||||
$account_roles = $account_columns[2]->findAll('css', 'td div ul li');
|
||||
if (!empty($account_roles)) {
|
||||
foreach ($account_roles as $element) {
|
||||
$roles[] = $element->getText();
|
||||
}
|
||||
}
|
||||
|
||||
$result_accounts[$name] = [
|
||||
'name' => $name,
|
||||
'status' => $account_columns[1]->getText(),
|
||||
'roles' => $roles,
|
||||
'member_for' => $account_columns[3]->getText(),
|
||||
'last_access' => $account_columns[4]->getText(),
|
||||
];
|
||||
}
|
||||
|
||||
$this->assertFalse(array_keys(array_diff_key($result_accounts, $accounts)), 'Ensure all accounts are listed.');
|
||||
foreach ($result_accounts as $name => $values) {
|
||||
$this->assertEqual($values['status'] == t('active'), $accounts[$name]->status->value, 'Ensure the status is displayed properly.');
|
||||
}
|
||||
|
||||
$expected_roles = ['custom_role_1', 'custom_role_2'];
|
||||
$this->assertEqual($result_accounts[$role_account_name]['roles'], $expected_roles, 'Ensure roles are listed properly.');
|
||||
|
||||
$this->assertEqual($result_accounts[$timestamp_user]['member_for'], \Drupal::service('date.formatter')->formatTimeDiffSince($accounts[$timestamp_user]->created->value), 'Ensure the right member time is displayed.');
|
||||
|
||||
$this->assertEqual($result_accounts[$timestamp_user]['last_access'], 'never', 'Ensure the last access time is "never".');
|
||||
}
|
||||
|
||||
}
|
205
web/core/modules/user/tests/src/Functional/UserAdminTest.php
Normal file
205
web/core/modules/user/tests/src/Functional/UserAdminTest.php
Normal file
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Tests user administration page functionality.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserAdminTest extends BrowserTestBase {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['taxonomy', 'views'];
|
||||
|
||||
/**
|
||||
* Registers a user and deletes it.
|
||||
*/
|
||||
public function testUserAdmin() {
|
||||
$config = $this->config('user.settings');
|
||||
$user_a = $this->drupalCreateUser();
|
||||
$user_a->name = 'User A';
|
||||
$user_a->mail = $this->randomMachineName() . '@example.com';
|
||||
$user_a->save();
|
||||
$user_b = $this->drupalCreateUser(['administer taxonomy']);
|
||||
$user_b->name = 'User B';
|
||||
$user_b->save();
|
||||
$user_c = $this->drupalCreateUser(['administer taxonomy']);
|
||||
$user_c->name = 'User C';
|
||||
$user_c->save();
|
||||
|
||||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
|
||||
// Create admin user to delete registered user.
|
||||
$admin_user = $this->drupalCreateUser(['administer users']);
|
||||
// Use a predictable name so that we can reliably order the user admin page
|
||||
// by name.
|
||||
$admin_user->name = 'Admin user';
|
||||
$admin_user->save();
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalGet('admin/people');
|
||||
$this->assertText($user_a->getUsername(), 'Found user A on admin users page');
|
||||
$this->assertText($user_b->getUsername(), 'Found user B on admin users page');
|
||||
$this->assertText($user_c->getUsername(), 'Found user C on admin users page');
|
||||
$this->assertText($admin_user->getUsername(), 'Found Admin user on admin users page');
|
||||
|
||||
// Test for existence of edit link in table.
|
||||
$link = $user_a->link(t('Edit'), 'edit-form', ['query' => ['destination' => $user_a->url('collection')]]);
|
||||
$this->assertRaw($link, 'Found user A edit link on admin users page');
|
||||
|
||||
// Test exposed filter elements.
|
||||
foreach (['user', 'role', 'permission', 'status'] as $field) {
|
||||
$this->assertField("edit-$field", "$field exposed filter found.");
|
||||
}
|
||||
// Make sure the reduce duplicates element from the ManyToOneHelper is not
|
||||
// displayed.
|
||||
$this->assertNoField('edit-reduce-duplicates', 'Reduce duplicates form element not found in exposed filters.');
|
||||
|
||||
// Filter the users by name/email.
|
||||
$this->drupalGet('admin/people', ['query' => ['user' => $user_a->getUsername()]]);
|
||||
$result = $this->xpath('//table/tbody/tr');
|
||||
$this->assertEqual(1, count($result), 'Filter by username returned the right amount.');
|
||||
$this->assertEqual($user_a->getUsername(), $result[0]->find('xpath', '/td[2]/span')->getText(), 'Filter by username returned the right user.');
|
||||
|
||||
$this->drupalGet('admin/people', ['query' => ['user' => $user_a->getEmail()]]);
|
||||
$result = $this->xpath('//table/tbody/tr');
|
||||
$this->assertEqual(1, count($result), 'Filter by username returned the right amount.');
|
||||
$this->assertEqual($user_a->getUsername(), $result[0]->find('xpath', '/td[2]/span')->getText(), 'Filter by username returned the right user.');
|
||||
|
||||
// Filter the users by permission 'administer taxonomy'.
|
||||
$this->drupalGet('admin/people', ['query' => ['permission' => 'administer taxonomy']]);
|
||||
|
||||
// Check if the correct users show up.
|
||||
$this->assertNoText($user_a->getUsername(), 'User A not on filtered by perm admin users page');
|
||||
$this->assertText($user_b->getUsername(), 'Found user B on filtered by perm admin users page');
|
||||
$this->assertText($user_c->getUsername(), 'Found user C on filtered by perm admin users page');
|
||||
|
||||
// Filter the users by role. Grab the system-generated role name for User C.
|
||||
$roles = $user_c->getRoles();
|
||||
unset($roles[array_search(RoleInterface::AUTHENTICATED_ID, $roles)]);
|
||||
$this->drupalGet('admin/people', ['query' => ['role' => reset($roles)]]);
|
||||
|
||||
// Check if the correct users show up when filtered by role.
|
||||
$this->assertNoText($user_a->getUsername(), 'User A not on filtered by role on admin users page');
|
||||
$this->assertNoText($user_b->getUsername(), 'User B not on filtered by role on admin users page');
|
||||
$this->assertText($user_c->getUsername(), 'User C on filtered by role on admin users page');
|
||||
|
||||
// Test blocking of a user.
|
||||
$account = $user_storage->load($user_c->id());
|
||||
$this->assertTrue($account->isActive(), 'User C not blocked');
|
||||
$edit = [];
|
||||
$edit['action'] = 'user_block_user_action';
|
||||
$edit['user_bulk_form[4]'] = TRUE;
|
||||
$config
|
||||
->set('notify.status_blocked', TRUE)
|
||||
->save();
|
||||
$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'],
|
||||
]);
|
||||
$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.');
|
||||
$user_storage->resetCache([$user_c->id()]);
|
||||
$account = $user_storage->load($user_c->id());
|
||||
$this->assertTrue($account->isBlocked(), 'User C blocked');
|
||||
|
||||
// Test filtering on admin page for blocked users
|
||||
$this->drupalGet('admin/people', ['query' => ['status' => 2]]);
|
||||
$this->assertNoText($user_a->getUsername(), 'User A not on filtered by status on admin users page');
|
||||
$this->assertNoText($user_b->getUsername(), 'User B not on filtered by status on admin users page');
|
||||
$this->assertText($user_c->getUsername(), 'User C on filtered by status on admin users page');
|
||||
|
||||
// Test unblocking of a user from /admin/people page and sending of activation mail
|
||||
$editunblock = [];
|
||||
$editunblock['action'] = 'user_unblock_user_action';
|
||||
$editunblock['user_bulk_form[4]'] = TRUE;
|
||||
$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'],
|
||||
]);
|
||||
$user_storage->resetCache([$user_c->id()]);
|
||||
$account = $user_storage->load($user_c->id());
|
||||
$this->assertTrue($account->isActive(), 'User C unblocked');
|
||||
$this->assertMail("to", $account->getEmail(), "Activation mail sent to user C");
|
||||
|
||||
// Test blocking and unblocking another user from /user/[uid]/edit form and sending of activation mail
|
||||
$user_d = $this->drupalCreateUser([]);
|
||||
$user_storage->resetCache([$user_d->id()]);
|
||||
$account1 = $user_storage->load($user_d->id());
|
||||
$this->drupalPostForm('user/' . $account1->id() . '/edit', ['status' => 0], t('Save'));
|
||||
$user_storage->resetCache([$user_d->id()]);
|
||||
$account1 = $user_storage->load($user_d->id());
|
||||
$this->assertTrue($account1->isBlocked(), 'User D blocked');
|
||||
$this->drupalPostForm('user/' . $account1->id() . '/edit', ['status' => TRUE], t('Save'));
|
||||
$user_storage->resetCache([$user_d->id()]);
|
||||
$account1 = $user_storage->load($user_d->id());
|
||||
$this->assertTrue($account1->isActive(), 'User D unblocked');
|
||||
$this->assertMail("to", $account1->getEmail(), "Activation mail sent to user D");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the alternate notification email address for user mails.
|
||||
*/
|
||||
public function testNotificationEmailAddress() {
|
||||
// Test that the Notification Email address field is on the config page.
|
||||
$admin_user = $this->drupalCreateUser(['administer users', 'administer account settings']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalGet('admin/config/people/accounts');
|
||||
$this->assertRaw('id="edit-mail-notification-address"', 'Notification Email address field exists');
|
||||
$this->drupalLogout();
|
||||
|
||||
// Test custom user registration approval email address(es).
|
||||
$config = $this->config('user.settings');
|
||||
// Allow users to register with admin approval.
|
||||
$config
|
||||
->set('verify_mail', TRUE)
|
||||
->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)
|
||||
->save();
|
||||
// Set the site and notification email addresses.
|
||||
$system = $this->config('system.site');
|
||||
$server_address = $this->randomMachineName() . '@example.com';
|
||||
$notify_address = $this->randomMachineName() . '@example.com';
|
||||
$system
|
||||
->set('mail', $server_address)
|
||||
->set('mail_notification', $notify_address)
|
||||
->save();
|
||||
// Register a new user account.
|
||||
$edit = [];
|
||||
$edit['name'] = $this->randomMachineName();
|
||||
$edit['mail'] = $edit['name'] . '@example.com';
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$subject = 'Account details for ' . $edit['name'] . ' at ' . $system->get('name') . ' (pending admin approval)';
|
||||
// Ensure that admin notification mail is sent to the configured
|
||||
// Notification Email address.
|
||||
$admin_mail = $this->drupalGetMails([
|
||||
'to' => $notify_address,
|
||||
'from' => $server_address,
|
||||
'subject' => $subject,
|
||||
]);
|
||||
$this->assertTrue(count($admin_mail), 'New user mail to admin is sent to configured Notification Email address');
|
||||
// Ensure that user notification mail is sent from the configured
|
||||
// Notification Email address.
|
||||
$user_mail = $this->drupalGetMails([
|
||||
'to' => $edit['mail'],
|
||||
'from' => $server_address,
|
||||
'reply-to' => $notify_address,
|
||||
'subject' => $subject,
|
||||
]);
|
||||
$this->assertTrue(count($user_mail), 'New user mail to user is sent from configured Notification Email address');
|
||||
}
|
||||
|
||||
}
|
134
web/core/modules/user/tests/src/Functional/UserBlocksTest.php
Normal file
134
web/core/modules/user/tests/src/Functional/UserBlocksTest.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests user blocks.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserBlocksTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'views'];
|
||||
|
||||
/**
|
||||
* A user with the 'administer blocks' permission.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->adminUser = $this->drupalCreateUser(['administer blocks']);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalPlaceBlock('user_login_block');
|
||||
$this->drupalLogout($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that user login block is hidden from user/login.
|
||||
*/
|
||||
public function testUserLoginBlockVisibility() {
|
||||
// Array keyed list where key being the URL address and value being expected
|
||||
// visibility as boolean type.
|
||||
$paths = [
|
||||
'node' => TRUE,
|
||||
'user/login' => FALSE,
|
||||
'user/register' => TRUE,
|
||||
'user/password' => TRUE,
|
||||
];
|
||||
foreach ($paths as $path => $expected_visibility) {
|
||||
$this->drupalGet($path);
|
||||
$elements = $this->xpath('//div[contains(@class,"block-user-login-block") and @role="form"]');
|
||||
if ($expected_visibility) {
|
||||
$this->assertTrue(!empty($elements), 'User login block in path "' . $path . '" should be visible');
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(empty($elements), 'User login block in path "' . $path . '" should not be visible');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user login block.
|
||||
*/
|
||||
public function testUserLoginBlock() {
|
||||
// Create a user with some permission that anonymous users lack.
|
||||
$user = $this->drupalCreateUser(['administer permissions']);
|
||||
|
||||
// Log in using the block.
|
||||
$edit = [];
|
||||
$edit['name'] = $user->getUsername();
|
||||
$edit['pass'] = $user->passRaw;
|
||||
$this->drupalPostForm('admin/people/permissions', $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
|
||||
// Check that we are still on the same page.
|
||||
$this->assertUrl(\Drupal::url('user.admin_permissions', [], ['absolute' => TRUE]), [], 'Still on the same page after login for access denied page');
|
||||
|
||||
// Now, log out and repeat with a non-403 page.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('filter/tips');
|
||||
$this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
$this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
|
||||
|
||||
// Log out again and repeat with a non-403 page including query arguments.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('filter/tips', ['query' => ['foo' => 'bar']]);
|
||||
$this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
$this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
|
||||
$this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=bar') !== FALSE, 'Correct query arguments are displayed after login');
|
||||
|
||||
// Repeat with different query arguments.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('filter/tips', ['query' => ['foo' => 'baz']]);
|
||||
$this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertNoText(t('User login'), 'Logged in.');
|
||||
$this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
|
||||
$this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=baz') !== FALSE, 'Correct query arguments are displayed after login');
|
||||
|
||||
// Check that the user login block is not vulnerable to information
|
||||
// disclosure to third party sites.
|
||||
$this->drupalLogout();
|
||||
$this->drupalPostForm('http://example.com/', $edit, t('Log in'), ['external' => FALSE]);
|
||||
// Check that we remain on the site after login.
|
||||
$this->assertUrl($user->url('canonical', ['absolute' => TRUE]), [], 'Redirected to user profile page after login from the frontpage');
|
||||
|
||||
// Verify that form validation errors are displayed immediately for forms
|
||||
// in blocks and not on subsequent page requests.
|
||||
$this->drupalLogout();
|
||||
$edit = [];
|
||||
$edit['name'] = 'foo';
|
||||
$edit['pass'] = 'invalid password';
|
||||
$this->drupalPostForm('filter/tips', $edit, t('Log in'));
|
||||
$this->assertText(t('Unrecognized username or password. Forgot your password?'));
|
||||
$this->drupalGet('filter/tips');
|
||||
$this->assertNoText(t('Unrecognized username or password. Forgot your password?'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the access column for a user.
|
||||
*/
|
||||
private function updateAccess($uid, $access = REQUEST_TIME) {
|
||||
db_update('users_field_data')
|
||||
->condition('uid', $uid)
|
||||
->fields(['access' => $access])
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -328,7 +314,8 @@ class UserCancelTest extends BrowserTestBase {
|
|||
$revision = $revision_node->getRevisionId();
|
||||
$settings = get_object_vars($revision_node);
|
||||
$settings['revision'] = 1;
|
||||
$settings['uid'] = 1; // Set new/current revision to someone else.
|
||||
// Set new/current revision to someone else.
|
||||
$settings['uid'] = 1;
|
||||
$revision_node = $this->drupalCreateNode($settings);
|
||||
|
||||
// Attempt to cancel account.
|
||||
|
@ -454,7 +441,8 @@ class UserCancelTest extends BrowserTestBase {
|
|||
$revision = $revision_node->getRevisionId();
|
||||
$settings = get_object_vars($revision_node);
|
||||
$settings['revision'] = 1;
|
||||
$settings['uid'] = 1; // Set new/current revision to someone else.
|
||||
// Set new/current revision to someone else.
|
||||
$settings['uid'] = 1;
|
||||
$revision_node = $this->drupalCreateNode($settings);
|
||||
|
||||
// Attempt to cancel account.
|
||||
|
|
135
web/core/modules/user/tests/src/Functional/UserCreateTest.php
Normal file
135
web/core/modules/user/tests/src/Functional/UserCreateTest.php
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the create user administration page.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserCreateTest extends BrowserTestBase {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['image'];
|
||||
|
||||
/**
|
||||
* Create a user through the administration interface and ensure that it
|
||||
* displays in the user list.
|
||||
*/
|
||||
public function testUserAdd() {
|
||||
$user = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
$this->assertEqual($user->getCreatedTime(), REQUEST_TIME, 'Creating a user sets default "created" timestamp.');
|
||||
$this->assertEqual($user->getChangedTime(), REQUEST_TIME, 'Creating a user sets default "changed" timestamp.');
|
||||
|
||||
// Create a field.
|
||||
$field_name = 'test_field';
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'user',
|
||||
'module' => 'image',
|
||||
'type' => 'image',
|
||||
'cardinality' => 1,
|
||||
'locked' => FALSE,
|
||||
'indexes' => ['target_id' => ['target_id']],
|
||||
'settings' => [
|
||||
'uri_scheme' => 'public',
|
||||
],
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'user',
|
||||
'label' => 'Picture',
|
||||
'bundle' => 'user',
|
||||
'description' => t('Your virtual face or picture.'),
|
||||
'required' => FALSE,
|
||||
'settings' => [
|
||||
'file_extensions' => 'png gif jpg jpeg',
|
||||
'file_directory' => 'pictures',
|
||||
'max_filesize' => '30 KB',
|
||||
'alt_field' => 0,
|
||||
'title_field' => 0,
|
||||
'max_resolution' => '85x85',
|
||||
'min_resolution' => '',
|
||||
],
|
||||
])->save();
|
||||
|
||||
// Test user creation page for valid fields.
|
||||
$this->drupalGet('admin/people/create');
|
||||
$this->assertFieldbyId('edit-status-0', 0, 'The user status option Blocked exists.', 'User login');
|
||||
$this->assertFieldbyId('edit-status-1', 1, 'The user status option Active exists.', 'User login');
|
||||
$this->assertFieldByXPath('//input[@type="radio" and @id="edit-status-1" and @checked="checked"]', NULL, 'Default setting for user status is active.');
|
||||
|
||||
// Test that browser autocomplete behavior does not occur.
|
||||
$this->assertNoRaw('data-user-info-from-browser', 'Ensure form attribute, data-user-info-from-browser, does not exist.');
|
||||
|
||||
// Test that the password strength indicator displays.
|
||||
$config = $this->config('user.settings');
|
||||
|
||||
$config->set('password_strength', TRUE)->save();
|
||||
$this->drupalGet('admin/people/create');
|
||||
$this->assertRaw(t('Password strength:'), 'The password strength indicator is displayed.');
|
||||
|
||||
$config->set('password_strength', FALSE)->save();
|
||||
$this->drupalGet('admin/people/create');
|
||||
$this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.');
|
||||
|
||||
// We create two users, notifying one and not notifying the other, to
|
||||
// ensure that the tests work in both cases.
|
||||
foreach ([FALSE, TRUE] as $notify) {
|
||||
$name = $this->randomMachineName();
|
||||
$edit = [
|
||||
'name' => $name,
|
||||
'mail' => $this->randomMachineName() . '@example.com',
|
||||
'pass[pass1]' => $pass = $this->randomString(),
|
||||
'pass[pass2]' => $pass,
|
||||
'notify' => $notify,
|
||||
];
|
||||
$this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
|
||||
|
||||
if ($notify) {
|
||||
$this->assertText(t('A welcome message with further instructions has been emailed to the new user @name.', ['@name' => $edit['name']]), 'User created');
|
||||
$this->assertEqual(count($this->drupalGetMails()), 1, 'Notification email sent');
|
||||
}
|
||||
else {
|
||||
$this->assertText(t('Created a new user account for @name. No email has been sent.', ['@name' => $edit['name']]), 'User created');
|
||||
$this->assertEqual(count($this->drupalGetMails()), 0, 'Notification email not sent');
|
||||
}
|
||||
|
||||
$this->drupalGet('admin/people');
|
||||
$this->assertText($edit['name'], 'User found in list of users');
|
||||
$user = user_load_by_name($name);
|
||||
$this->assertTrue($user->isActive(), 'User is not blocked');
|
||||
}
|
||||
|
||||
// Test that the password '0' is considered a password.
|
||||
// @see https://www.drupal.org/node/2563751.
|
||||
$name = $this->randomMachineName();
|
||||
$edit = [
|
||||
'name' => $name,
|
||||
'mail' => $this->randomMachineName() . '@example.com',
|
||||
'pass[pass1]' => 0,
|
||||
'pass[pass2]' => 0,
|
||||
'notify' => FALSE,
|
||||
];
|
||||
$this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
|
||||
$this->assertText("Created a new user account for $name. No email has been sent");
|
||||
$this->assertNoText('Password field is required');
|
||||
}
|
||||
|
||||
}
|
154
web/core/modules/user/tests/src/Functional/UserEditTest.php
Normal file
154
web/core/modules/user/tests/src/Functional/UserEditTest.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests user edit page.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserEditTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Test user edit page.
|
||||
*/
|
||||
public function testUserEdit() {
|
||||
// Test user edit functionality.
|
||||
$user1 = $this->drupalCreateUser(['change own username']);
|
||||
$user2 = $this->drupalCreateUser([]);
|
||||
$this->drupalLogin($user1);
|
||||
|
||||
// Test that error message appears when attempting to use a non-unique user name.
|
||||
$edit['name'] = $user2->getUsername();
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t('The username %name is already taken.', ['%name' => $edit['name']]));
|
||||
|
||||
// Check that the default value in user name field
|
||||
// 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]'] = '';
|
||||
$edit['pass[pass2]'] = $this->randomMachineName();
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertText(t("The specified passwords do not match."), 'Typing mismatched passwords displays an error message.');
|
||||
|
||||
$edit['pass[pass1]'] = $this->randomMachineName();
|
||||
$edit['pass[pass2]'] = '';
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertText(t("The specified passwords do not match."), 'Typing mismatched passwords displays an error message.');
|
||||
|
||||
// Test that the error message appears when attempting to change the mail or
|
||||
// pass without the current password.
|
||||
$edit = [];
|
||||
$edit['mail'] = $this->randomMachineName() . '@new.example.com';
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", ['%name' => t('Email')]));
|
||||
|
||||
$edit['current_pass'] = $user1->passRaw;
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t("The changes have been saved."));
|
||||
|
||||
// Test that the user must enter current password before changing passwords.
|
||||
$edit = [];
|
||||
$edit['pass[pass1]'] = $new_pass = $this->randomMachineName();
|
||||
$edit['pass[pass2]'] = $new_pass;
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", ['%name' => t('Password')]));
|
||||
|
||||
// Try again with the current password.
|
||||
$edit['current_pass'] = $user1->passRaw;
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t("The changes have been saved."));
|
||||
|
||||
// Make sure the changed timestamp is updated.
|
||||
$this->assertEqual($user1->getChangedTime(), REQUEST_TIME, 'Changing a user sets "changed" timestamp.');
|
||||
|
||||
// Make sure the user can log in with their new password.
|
||||
$this->drupalLogout();
|
||||
$user1->passRaw = $new_pass;
|
||||
$this->drupalLogin($user1);
|
||||
$this->drupalLogout();
|
||||
|
||||
// Test that the password strength indicator displays.
|
||||
$config = $this->config('user.settings');
|
||||
$this->drupalLogin($user1);
|
||||
|
||||
$config->set('password_strength', TRUE)->save();
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t('Password strength:'), 'The password strength indicator is displayed.');
|
||||
|
||||
$config->set('password_strength', FALSE)->save();
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.');
|
||||
|
||||
// Check that the user status field has the correct value and that it is
|
||||
// properly displayed.
|
||||
$admin_user = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalGet('user/' . $user1->id() . '/edit');
|
||||
$this->assertNoFieldChecked('edit-status-0');
|
||||
$this->assertFieldChecked('edit-status-1');
|
||||
|
||||
$edit = ['status' => 0];
|
||||
$this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save'));
|
||||
$this->assertText(t('The changes have been saved.'));
|
||||
$this->assertFieldChecked('edit-status-0');
|
||||
$this->assertNoFieldChecked('edit-status-1');
|
||||
|
||||
$edit = ['status' => 1];
|
||||
$this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save'));
|
||||
$this->assertText(t('The changes have been saved.'));
|
||||
$this->assertNoFieldChecked('edit-status-0');
|
||||
$this->assertFieldChecked('edit-status-1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting the password to "0".
|
||||
*
|
||||
* We discovered in https://www.drupal.org/node/2563751 that logging in with a
|
||||
* password that is literally "0" was not possible. This test ensures that
|
||||
* this regression can't happen again.
|
||||
*/
|
||||
public function testUserWith0Password() {
|
||||
$admin = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($admin);
|
||||
// Create a regular user.
|
||||
$user1 = $this->drupalCreateUser([]);
|
||||
|
||||
$edit = ['pass[pass1]' => '0', 'pass[pass2]' => '0'];
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertRaw(t("The changes have been saved."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests editing of a user account without an email address.
|
||||
*/
|
||||
public function testUserWithoutEmailEdit() {
|
||||
// Test that an admin can edit users without an email address.
|
||||
$admin = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($admin);
|
||||
// Create a regular user.
|
||||
$user1 = $this->drupalCreateUser([]);
|
||||
// This user has no email address.
|
||||
$user1->mail = '';
|
||||
$user1->save();
|
||||
$this->drupalPostForm("user/" . $user1->id() . "/edit", ['mail' => ''], t('Save'));
|
||||
$this->assertRaw(t("The changes have been saved."));
|
||||
}
|
||||
|
||||
}
|
|
@ -11,13 +11,6 @@ use Drupal\Tests\BrowserTestBase;
|
|||
*/
|
||||
class UserEditedOwnAccountTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user_form_test'];
|
||||
|
||||
public function testUserEditedOwnAccount() {
|
||||
// Change account setting 'Who can register accounts?' to Administrators
|
||||
// only.
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests whether proper language is stored for new users and access to language
|
||||
* selector.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserLanguageCreationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user', 'language'];
|
||||
|
||||
/**
|
||||
* Functional test for language handling during user creation.
|
||||
*/
|
||||
public function testLocalUserCreation() {
|
||||
// User to add and remove language and create new users.
|
||||
$admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages', 'administer users']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Add predefined language.
|
||||
$langcode = 'fr';
|
||||
ConfigurableLanguage::createFromLangcode($langcode)->save();
|
||||
|
||||
// Set language negotiation.
|
||||
$edit = [
|
||||
'language_interface[enabled][language-url]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
||||
$this->assertText(t('Language detection configuration saved.'), 'Set language negotiation.');
|
||||
|
||||
// Check if the language selector is available on admin/people/create and
|
||||
// set to the currently active language.
|
||||
$this->drupalGet($langcode . '/admin/people/create');
|
||||
$this->assertOptionSelected("edit-preferred-langcode", $langcode, 'Global language set in the language selector.');
|
||||
|
||||
// Create a user with the admin/people/create form and check if the correct
|
||||
// language is set.
|
||||
$username = $this->randomMachineName(10);
|
||||
$edit = [
|
||||
'name' => $username,
|
||||
'mail' => $this->randomMachineName(4) . '@example.com',
|
||||
'pass[pass1]' => $username,
|
||||
'pass[pass2]' => $username,
|
||||
];
|
||||
|
||||
$this->drupalPostForm($langcode . '/admin/people/create', $edit, t('Create new account'));
|
||||
|
||||
$user = user_load_by_name($username);
|
||||
$this->assertEqual($user->getPreferredLangcode(), $langcode, 'New user has correct preferred language set.');
|
||||
$this->assertEqual($user->language()->getId(), $langcode, 'New user has correct profile language set.');
|
||||
|
||||
// Register a new user and check if the language selector is hidden.
|
||||
$this->drupalLogout();
|
||||
|
||||
$this->drupalGet($langcode . '/user/register');
|
||||
$this->assertNoFieldByName('language[fr]', 'Language selector is not accessible.');
|
||||
|
||||
$username = $this->randomMachineName(10);
|
||||
$edit = [
|
||||
'name' => $username,
|
||||
'mail' => $this->randomMachineName(4) . '@example.com',
|
||||
];
|
||||
|
||||
$this->drupalPostForm($langcode . '/user/register', $edit, t('Create new account'));
|
||||
|
||||
$user = user_load_by_name($username);
|
||||
$this->assertEqual($user->getPreferredLangcode(), $langcode, 'New user has correct preferred language set.');
|
||||
$this->assertEqual($user->language()->getId(), $langcode, 'New user has correct profile language set.');
|
||||
|
||||
// Test if the admin can use the language selector and if the
|
||||
// correct language is was saved.
|
||||
$user_edit = $langcode . '/user/' . $user->id() . '/edit';
|
||||
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalGet($user_edit);
|
||||
$this->assertOptionSelected("edit-preferred-langcode", $langcode, 'Language selector is accessible and correct language is selected.');
|
||||
|
||||
// Set passRaw so we can log in the new user.
|
||||
$user->passRaw = $this->randomMachineName(10);
|
||||
$edit = [
|
||||
'pass[pass1]' => $user->passRaw,
|
||||
'pass[pass2]' => $user->passRaw,
|
||||
];
|
||||
|
||||
$this->drupalPostForm($user_edit, $edit, t('Save'));
|
||||
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalGet($user_edit);
|
||||
$this->assertOptionSelected("edit-preferred-langcode", $langcode, 'Language selector is accessible and correct language is selected.');
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Core\Flood\DatabaseBackend;
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Controller\UserAuthenticationController;
|
||||
|
@ -14,12 +15,16 @@ use Drupal\hal\Encoder\JsonEncoder as HALJsonEncoder;
|
|||
use Symfony\Component\Serializer\Serializer;
|
||||
|
||||
/**
|
||||
* Tests login via direct HTTP.
|
||||
* Tests login and password reset via direct HTTP.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserLoginHttpTest extends BrowserTestBase {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
|
@ -61,7 +66,7 @@ class UserLoginHttpTest extends BrowserTestBase {
|
|||
* @param string $format
|
||||
* The format to use to make the request.
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface The HTTP response.
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
* The HTTP response.
|
||||
*/
|
||||
protected function loginRequest($name, $pass, $format = 'json') {
|
||||
|
@ -92,99 +97,153 @@ class UserLoginHttpTest extends BrowserTestBase {
|
|||
* Tests user session life cycle.
|
||||
*/
|
||||
public function testLogin() {
|
||||
// Without the serialization module only JSON is supported.
|
||||
$this->doTestLogin('json');
|
||||
|
||||
// Enable serialization so we have access to additional formats.
|
||||
$this->container->get('module_installer')->install(['serialization']);
|
||||
$this->doTestLogin('json');
|
||||
$this->doTestLogin('xml');
|
||||
$this->doTestLogin('hal_json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Do login testing for a given serialization format.
|
||||
*
|
||||
* @param string $format
|
||||
* Serialization format.
|
||||
*/
|
||||
protected function doTestLogin($format) {
|
||||
$client = \Drupal::httpClient();
|
||||
foreach ([FALSE, TRUE] as $serialization_enabled_option) {
|
||||
if ($serialization_enabled_option) {
|
||||
/** @var \Drupal\Core\Extension\ModuleInstaller $module_installer */
|
||||
$module_installer = $this->container->get('module_installer');
|
||||
$module_installer->install(['serialization']);
|
||||
$formats = ['json', 'xml', 'hal_json'];
|
||||
}
|
||||
else {
|
||||
// Without the serialization module only JSON is supported.
|
||||
$formats = ['json'];
|
||||
}
|
||||
foreach ($formats as $format) {
|
||||
// Create new user for each iteration to reset flood.
|
||||
// Grant the user administer users permissions to they can see the
|
||||
// 'roles' field.
|
||||
$account = $this->drupalCreateUser(['administer users']);
|
||||
$name = $account->getUsername();
|
||||
$pass = $account->passRaw;
|
||||
// Create new user for each iteration to reset flood.
|
||||
// Grant the user administer users permissions to they can see the
|
||||
// 'roles' field.
|
||||
$account = $this->drupalCreateUser(['administer users']);
|
||||
$name = $account->getUsername();
|
||||
$pass = $account->passRaw;
|
||||
|
||||
$login_status_url = $this->getLoginStatusUrlString($format);
|
||||
$response = $client->get($login_status_url);
|
||||
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
|
||||
$login_status_url = $this->getLoginStatusUrlString($format);
|
||||
$response = $client->get($login_status_url);
|
||||
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
|
||||
|
||||
// Flooded.
|
||||
$this->config('user.flood')
|
||||
->set('user_limit', 3)
|
||||
->save();
|
||||
// Flooded.
|
||||
$this->config('user.flood')
|
||||
->set('user_limit', 3)
|
||||
->save();
|
||||
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 403, 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.', $format);
|
||||
$response = $this->loginRequest($name, 'wrong-pass', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 403, 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.', $format);
|
||||
|
||||
// After testing the flood control we can increase the limit.
|
||||
$this->config('user.flood')
|
||||
->set('user_limit', 100)
|
||||
->save();
|
||||
// After testing the flood control we can increase the limit.
|
||||
$this->config('user.flood')
|
||||
->set('user_limit', 100)
|
||||
->save();
|
||||
|
||||
$response = $this->loginRequest(NULL, NULL, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.', $format);
|
||||
$response = $this->loginRequest(NULL, NULL, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.', $format);
|
||||
|
||||
$response = $this->loginRequest(NULL, $pass, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format);
|
||||
$response = $this->loginRequest(NULL, $pass, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format);
|
||||
|
||||
$response = $this->loginRequest($name, NULL, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format);
|
||||
$response = $this->loginRequest($name, NULL, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format);
|
||||
|
||||
// Blocked.
|
||||
$account
|
||||
->block()
|
||||
->save();
|
||||
// Blocked.
|
||||
$account
|
||||
->block()
|
||||
->save();
|
||||
|
||||
$response = $this->loginRequest($name, $pass, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
|
||||
$response = $this->loginRequest($name, $pass, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
|
||||
|
||||
$account
|
||||
->activate()
|
||||
->save();
|
||||
$account
|
||||
->activate()
|
||||
->save();
|
||||
|
||||
$response = $this->loginRequest($name, 'garbage', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
$response = $this->loginRequest($name, 'garbage', $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
|
||||
$response = $this->loginRequest('garbage', $pass, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
$response = $this->loginRequest('garbage', $pass, $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format);
|
||||
|
||||
$response = $this->loginRequest($name, $pass, $format);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$result_data = $this->serializer->decode($response->getBody(), $format);
|
||||
$this->assertEquals($name, $result_data['current_user']['name']);
|
||||
$this->assertEquals($account->id(), $result_data['current_user']['uid']);
|
||||
$this->assertEquals($account->getRoles(), $result_data['current_user']['roles']);
|
||||
$logout_token = $result_data['logout_token'];
|
||||
$response = $this->loginRequest($name, $pass, $format);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$result_data = $this->serializer->decode($response->getBody(), $format);
|
||||
$this->assertEquals($name, $result_data['current_user']['name']);
|
||||
$this->assertEquals($account->id(), $result_data['current_user']['uid']);
|
||||
$this->assertEquals($account->getRoles(), $result_data['current_user']['roles']);
|
||||
$logout_token = $result_data['logout_token'];
|
||||
|
||||
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
|
||||
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN);
|
||||
// Logging in while already logged in results in a 403 with helpful message.
|
||||
$response = $this->loginRequest($name, $pass, $format);
|
||||
$this->assertSame(403, $response->getStatusCode());
|
||||
$this->assertSame(['message' => 'This route can only be accessed by anonymous users.'], $this->serializer->decode($response->getBody(), $format));
|
||||
|
||||
$response = $this->logoutRequest($format, $logout_token);
|
||||
$this->assertEquals(204, $response->getStatusCode());
|
||||
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
|
||||
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN);
|
||||
|
||||
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
|
||||
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
|
||||
$response = $this->logoutRequest($format, $logout_token);
|
||||
$this->assertEquals(204, $response->getStatusCode());
|
||||
|
||||
$this->resetFlood();
|
||||
}
|
||||
}
|
||||
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
|
||||
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
|
||||
|
||||
$this->resetFlood();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a password HTTP request.
|
||||
*
|
||||
* @param array $request_body
|
||||
* The request body.
|
||||
* @param string $format
|
||||
* The format to use to make the request.
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
* The HTTP response.
|
||||
*/
|
||||
protected function passwordRequest(array $request_body, $format = 'json') {
|
||||
$password_reset_url = Url::fromRoute('user.pass.http')
|
||||
->setRouteParameter('_format', $format)
|
||||
->setAbsolute();
|
||||
|
||||
$result = \Drupal::httpClient()->post($password_reset_url->toString(), [
|
||||
'body' => $this->serializer->encode($request_body, $format),
|
||||
'headers' => [
|
||||
'Accept' => "application/$format",
|
||||
],
|
||||
'http_errors' => FALSE,
|
||||
'cookies' => $this->cookies,
|
||||
]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests user password reset.
|
||||
*/
|
||||
public function testPasswordReset() {
|
||||
// Create a user account.
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
// Without the serialization module only JSON is supported.
|
||||
$this->doTestPasswordReset('json', $account);
|
||||
|
||||
// Enable serialization so we have access to additional formats.
|
||||
$this->container->get('module_installer')->install(['serialization']);
|
||||
|
||||
$this->doTestPasswordReset('json', $account);
|
||||
$this->doTestPasswordReset('xml', $account);
|
||||
$this->doTestPasswordReset('hal_json', $account);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,7 +402,7 @@ class UserLoginHttpTest extends BrowserTestBase {
|
|||
* @param string $logout_token
|
||||
* The csrf token for user logout.
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface The HTTP response.
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
* The HTTP response.
|
||||
*/
|
||||
protected function logoutRequest($format = 'json', $logout_token = '') {
|
||||
|
@ -426,4 +485,60 @@ class UserLoginHttpTest extends BrowserTestBase {
|
|||
return $user_login_status_url->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do password reset testing for given format and account.
|
||||
*
|
||||
* @param string $format
|
||||
* Serialization format.
|
||||
* @param \Drupal\user\UserInterface $account
|
||||
* Test account.
|
||||
*/
|
||||
protected function doTestPasswordReset($format, $account) {
|
||||
$response = $this->passwordRequest([], $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name or credentials.mail', $format);
|
||||
|
||||
$response = $this->passwordRequest(['name' => 'dramallama'], $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Unrecognized username or email address.', $format);
|
||||
|
||||
$response = $this->passwordRequest(['mail' => 'llama@drupal.org'], $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'Unrecognized username or email address.', $format);
|
||||
|
||||
$account
|
||||
->block()
|
||||
->save();
|
||||
|
||||
$response = $this->passwordRequest(['name' => $account->getAccountName()], $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
|
||||
|
||||
$response = $this->passwordRequest(['mail' => $account->getEmail()], $format);
|
||||
$this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
|
||||
|
||||
$account
|
||||
->activate()
|
||||
->save();
|
||||
|
||||
$response = $this->passwordRequest(['name' => $account->getAccountName()], $format);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->loginFromResetEmail();
|
||||
$this->drupalLogout();
|
||||
|
||||
$response = $this->passwordRequest(['mail' => $account->getEmail()], $format);
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->loginFromResetEmail();
|
||||
$this->drupalLogout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Login from reset password email.
|
||||
*/
|
||||
protected function loginFromResetEmail() {
|
||||
$_emails = $this->drupalGetMails();
|
||||
$email = end($_emails);
|
||||
$urls = [];
|
||||
preg_match('#.+user/reset/.+#', $email['body'], $urls);
|
||||
$resetURL = $urls[0];
|
||||
$this->drupalGet($resetURL);
|
||||
$this->drupalPostForm(NULL, NULL, 'Log in');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
178
web/core/modules/user/tests/src/Functional/UserLoginTest.php
Normal file
178
web/core/modules/user/tests/src/Functional/UserLoginTest.php
Normal file
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Ensure that login works as expected.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserLoginTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Tests login with destination.
|
||||
*/
|
||||
public function testLoginCacheTagsAndDestination() {
|
||||
$this->drupalGet('user/login');
|
||||
// The user login form says "Enter your <site name> username.", hence it
|
||||
// depends on config:system.site, and its cache tags should be present.
|
||||
$this->assertCacheTag('config:system.site');
|
||||
|
||||
$user = $this->drupalCreateUser([]);
|
||||
$this->drupalGet('user/login', ['query' => ['destination' => 'foo']]);
|
||||
$edit = ['name' => $user->getUserName(), 'pass' => $user->passRaw];
|
||||
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||
$this->assertUrl('foo', [], 'Redirected to the correct URL');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the global login flood control.
|
||||
*/
|
||||
public function testGlobalLoginFloodControl() {
|
||||
$this->config('user.flood')
|
||||
->set('ip_limit', 10)
|
||||
// Set a high per-user limit out so that it is not relevant in the test.
|
||||
->set('user_limit', 4000)
|
||||
->save();
|
||||
|
||||
$user1 = $this->drupalCreateUser([]);
|
||||
$incorrect_user1 = clone $user1;
|
||||
$incorrect_user1->passRaw .= 'incorrect';
|
||||
|
||||
// Try 2 failed logins.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$this->assertFailedLogin($incorrect_user1);
|
||||
}
|
||||
|
||||
// A successful login will not reset the IP-based flood control count.
|
||||
$this->drupalLogin($user1);
|
||||
$this->drupalLogout();
|
||||
|
||||
// Try 8 more failed logins, they should not trigger the flood control
|
||||
// mechanism.
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$this->assertFailedLogin($incorrect_user1);
|
||||
}
|
||||
|
||||
// The next login trial should result in an IP-based flood error message.
|
||||
$this->assertFailedLogin($incorrect_user1, 'ip');
|
||||
|
||||
// A login with the correct password should also result in a flood error
|
||||
// message.
|
||||
$this->assertFailedLogin($user1, 'ip');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the per-user login flood control.
|
||||
*/
|
||||
public function testPerUserLoginFloodControl() {
|
||||
$this->config('user.flood')
|
||||
// Set a high global limit out so that it is not relevant in the test.
|
||||
->set('ip_limit', 4000)
|
||||
->set('user_limit', 3)
|
||||
->save();
|
||||
|
||||
$user1 = $this->drupalCreateUser([]);
|
||||
$incorrect_user1 = clone $user1;
|
||||
$incorrect_user1->passRaw .= 'incorrect';
|
||||
|
||||
$user2 = $this->drupalCreateUser([]);
|
||||
|
||||
// Try 2 failed logins.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$this->assertFailedLogin($incorrect_user1);
|
||||
}
|
||||
|
||||
// A successful login will reset the per-user flood control count.
|
||||
$this->drupalLogin($user1);
|
||||
$this->drupalLogout();
|
||||
|
||||
// Try 3 failed logins for user 1, they will not trigger flood control.
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$this->assertFailedLogin($incorrect_user1);
|
||||
}
|
||||
|
||||
// Try one successful attempt for user 2, it should not trigger any
|
||||
// flood control.
|
||||
$this->drupalLogin($user2);
|
||||
$this->drupalLogout();
|
||||
|
||||
// Try one more attempt for user 1, it should be rejected, even if the
|
||||
// correct password has been used.
|
||||
$this->assertFailedLogin($user1, 'user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that user password is re-hashed upon login after changing $count_log2.
|
||||
*/
|
||||
public function testPasswordRehashOnLogin() {
|
||||
// Determine default log2 for phpass hashing algorithm
|
||||
$default_count_log2 = 16;
|
||||
|
||||
// Retrieve instance of password hashing algorithm
|
||||
$password_hasher = $this->container->get('password');
|
||||
|
||||
// Create a new user and authenticate.
|
||||
$account = $this->drupalCreateUser([]);
|
||||
$password = $account->passRaw;
|
||||
$this->drupalLogin($account);
|
||||
$this->drupalLogout();
|
||||
// Load the stored user. The password hash should reflect $default_count_log2.
|
||||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
$account = User::load($account->id());
|
||||
$this->assertIdentical($password_hasher->getCountLog2($account->getPassword()), $default_count_log2);
|
||||
|
||||
// Change the required number of iterations by loading a test-module
|
||||
// containing the necessary container builder code and then verify that the
|
||||
// users password gets rehashed during the login.
|
||||
$overridden_count_log2 = 19;
|
||||
\Drupal::service('module_installer')->install(['user_custom_phpass_params_test']);
|
||||
$this->resetAll();
|
||||
|
||||
$account->passRaw = $password;
|
||||
$this->drupalLogin($account);
|
||||
// Load the stored user, which should have a different password hash now.
|
||||
$user_storage->resetCache([$account->id()]);
|
||||
$account = $user_storage->load($account->id());
|
||||
$this->assertIdentical($password_hasher->getCountLog2($account->getPassword()), $overridden_count_log2);
|
||||
$this->assertTrue($password_hasher->check($password, $account->getPassword()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an unsuccessful login attempt.
|
||||
*
|
||||
* @param \Drupal\user\Entity\User $account
|
||||
* A user object with name and passRaw attributes for the login attempt.
|
||||
* @param mixed $flood_trigger
|
||||
* (optional) Whether or not to expect that the flood control mechanism
|
||||
* will be triggered. Defaults to NULL.
|
||||
* - Set to 'user' to expect a 'too many failed logins error.
|
||||
* - Set to any value to expect an error for too many failed logins per IP
|
||||
* .
|
||||
* - Set to NULL to expect a failed login.
|
||||
*/
|
||||
public function assertFailedLogin($account, $flood_trigger = NULL) {
|
||||
$edit = [
|
||||
'name' => $account->getUsername(),
|
||||
'pass' => $account->passRaw,
|
||||
];
|
||||
$this->drupalPostForm('user/login', $edit, t('Log in'));
|
||||
$this->assertNoFieldByXPath("//input[@name='pass' and @value!='']", NULL, 'Password value attribute is blank.');
|
||||
if (isset($flood_trigger)) {
|
||||
if ($flood_trigger == 'user') {
|
||||
$this->assertRaw(\Drupal::translation()->formatPlural($this->config('user.flood')->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', [':url' => \Drupal::url('user.pass')]));
|
||||
}
|
||||
else {
|
||||
// No uid, so the limit is IP-based.
|
||||
$this->assertRaw(t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href=":url">request a new password</a>.', [':url' => \Drupal::url('user.pass')]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->assertText(t('Unrecognized username or password. Forgot your password?'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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']],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\system\Functional\Cache\PageCacheTagsTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Ensure that password reset methods work as expected.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserPasswordResetTest extends PageCacheTagsTestBase {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user object to test password resetting.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalPlaceBlock('system_menu_block:account');
|
||||
|
||||
// Create a user.
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
// Activate user by logging in.
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$this->account = User::load($account->id());
|
||||
$this->account->passRaw = $account->passRaw;
|
||||
$this->drupalLogout();
|
||||
|
||||
// Set the last login time that is used to generate the one-time link so
|
||||
// that it is definitely over a second ago.
|
||||
$account->login = REQUEST_TIME - mt_rand(10, 100000);
|
||||
db_update('users_field_data')
|
||||
->fields(['login' => $account->getLastLoginTime()])
|
||||
->condition('uid', $account->id())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests password reset functionality.
|
||||
*/
|
||||
public function testUserPasswordReset() {
|
||||
// Verify that accessing the password reset form without having the session
|
||||
// variables set results in an access denied message.
|
||||
$this->drupalGet(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()]));
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Try to reset the password for an invalid account.
|
||||
$this->drupalGet('user/password');
|
||||
|
||||
$edit = ['name' => $this->randomMachineName(32)];
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
|
||||
$this->assertText(t('@name is not recognized as a username or an email address.', ['@name' => $edit['name']]), 'Validation error message shown when trying to request password for invalid account.');
|
||||
$this->assertEqual(count($this->drupalGetMails(['id' => 'user_password_reset'])), 0, 'No email was sent when requesting a password for an invalid account.');
|
||||
|
||||
// Reset the password by username via the password reset page.
|
||||
$edit['name'] = $this->account->getUsername();
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
|
||||
// Verify that the user was sent an email.
|
||||
$this->assertMail('to', $this->account->getEmail(), 'Password email sent to user.');
|
||||
$subject = t('Replacement login information for @username at @site', ['@username' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]);
|
||||
$this->assertMail('subject', $subject, 'Password reset email subject is correct.');
|
||||
|
||||
$resetURL = $this->getResetURL();
|
||||
$this->drupalGet($resetURL);
|
||||
// Ensure that the current url does not contain the hash and timestamp.
|
||||
$this->assertUrl(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()]));
|
||||
|
||||
$this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'));
|
||||
|
||||
// Ensure the password reset URL is not cached.
|
||||
$this->drupalGet($resetURL);
|
||||
$this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'));
|
||||
|
||||
// Check the one-time login page.
|
||||
$this->assertText($this->account->getUsername(), 'One-time login page contains the correct username.');
|
||||
$this->assertText(t('This login can be used only once.'), 'Found warning about one-time login.');
|
||||
$this->assertTitle(t('Reset password | Drupal'), 'Page title is "Reset password".');
|
||||
|
||||
// Check successful login.
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
$this->assertLink(t('Log out'));
|
||||
$this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.');
|
||||
|
||||
// Change the forgotten password.
|
||||
$password = user_password();
|
||||
$edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(t('The changes have been saved.'), 'Forgotten password changed.');
|
||||
|
||||
// Verify that the password reset session has been destroyed.
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(t("Your current password is missing or incorrect; it's required to change the Password."), 'Password needed to make profile changes.');
|
||||
|
||||
// Log out, and try to log in again using the same one-time link.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet($resetURL);
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
$this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');
|
||||
|
||||
// Request a new password again, this time using the email address.
|
||||
$this->drupalGet('user/password');
|
||||
// Count email messages before to compare with after.
|
||||
$before = count($this->drupalGetMails(['id' => 'user_password_reset']));
|
||||
$edit = ['name' => $this->account->getEmail()];
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$this->assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before + 1, 'Email sent when requesting password reset using email address.');
|
||||
|
||||
// Visit the user edit page without pass-reset-token and make sure it does
|
||||
// not cause an error.
|
||||
$resetURL = $this->getResetURL();
|
||||
$this->drupalGet($resetURL);
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
$this->drupalGet('user/' . $this->account->id() . '/edit');
|
||||
$this->assertNoText('Expected user_string to be a string, NULL given');
|
||||
$this->drupalLogout();
|
||||
|
||||
// Create a password reset link as if the request time was 60 seconds older than the allowed limit.
|
||||
$timeout = $this->config('user.settings')->get('password_reset_timeout');
|
||||
$bogus_timestamp = REQUEST_TIME - $timeout - 60;
|
||||
$_uid = $this->account->id();
|
||||
$this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account, $bogus_timestamp));
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
$this->assertText(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'Expired password reset request rejected.');
|
||||
|
||||
// Create a user, block the account, and verify that a login link is denied.
|
||||
$timestamp = REQUEST_TIME - 1;
|
||||
$blocked_account = $this->drupalCreateUser()->block();
|
||||
$blocked_account->save();
|
||||
$this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp));
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Verify a blocked user can not request a new password.
|
||||
$this->drupalGet('user/password');
|
||||
// Count email messages before to compare with after.
|
||||
$before = count($this->drupalGetMails(['id' => 'user_password_reset']));
|
||||
$edit = ['name' => $blocked_account->getUsername()];
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$this->assertRaw(t('%name is blocked or has not been activated yet.', ['%name' => $blocked_account->getUsername()]), 'Notified user blocked accounts can not request a new password');
|
||||
$this->assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before, 'No email was sent when requesting password reset for a blocked account');
|
||||
|
||||
// Verify a password reset link is invalidated when the user's email address changes.
|
||||
$this->drupalGet('user/password');
|
||||
$edit = ['name' => $this->account->getUsername()];
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$old_email_reset_link = $this->getResetURL();
|
||||
$this->account->setEmail("1" . $this->account->getEmail());
|
||||
$this->account->save();
|
||||
$this->drupalGet($old_email_reset_link);
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
$this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');
|
||||
|
||||
// Verify a password reset link will automatically log a user when /login is
|
||||
// appended.
|
||||
$this->drupalGet('user/password');
|
||||
$edit = ['name' => $this->account->getUsername()];
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
$reset_url = $this->getResetURL();
|
||||
$this->drupalGet($reset_url . '/login');
|
||||
$this->assertLink(t('Log out'));
|
||||
$this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.');
|
||||
|
||||
// Ensure blocked and deleted accounts can't access the user.reset.login
|
||||
// route.
|
||||
$this->drupalLogout();
|
||||
$timestamp = REQUEST_TIME - 1;
|
||||
$blocked_account = $this->drupalCreateUser()->block();
|
||||
$blocked_account->save();
|
||||
$this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp) . '/login');
|
||||
$this->assertResponse(403);
|
||||
|
||||
$blocked_account->delete();
|
||||
$this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp) . '/login');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves password reset email and extracts the login link.
|
||||
*/
|
||||
public function getResetURL() {
|
||||
// Assume the most recent email.
|
||||
$_emails = $this->drupalGetMails();
|
||||
$email = end($_emails);
|
||||
$urls = [];
|
||||
preg_match('#.+user/reset/.+#', $email['body'], $urls);
|
||||
|
||||
return $urls[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test user password reset while logged in.
|
||||
*/
|
||||
public function testUserPasswordResetLoggedIn() {
|
||||
$another_account = $this->drupalCreateUser();
|
||||
$this->drupalLogin($another_account);
|
||||
$this->drupalGet('user/password');
|
||||
$this->drupalPostForm(NULL, NULL, t('Submit'));
|
||||
|
||||
// Click the reset URL while logged and change our password.
|
||||
$resetURL = $this->getResetURL();
|
||||
// Log in as a different user.
|
||||
$this->drupalLogin($this->account);
|
||||
$this->drupalGet($resetURL);
|
||||
$this->assertRaw(new FormattableMarkup(
|
||||
'Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please <a href=":logout">log out</a> and try using the link again.',
|
||||
['%other_user' => $this->account->getUsername(), '%resetting_user' => $another_account->getUsername(), ':logout' => Url::fromRoute('user.logout')->toString()]
|
||||
));
|
||||
|
||||
$another_account->delete();
|
||||
$this->drupalGet($resetURL);
|
||||
$this->assertText('The one-time login link you clicked is invalid.');
|
||||
|
||||
// Log in.
|
||||
$this->drupalLogin($this->account);
|
||||
|
||||
// Reset the password by username via the password reset page.
|
||||
$this->drupalGet('user/password');
|
||||
$this->drupalPostForm(NULL, NULL, t('Submit'));
|
||||
|
||||
// Click the reset URL while logged and change our password.
|
||||
$resetURL = $this->getResetURL();
|
||||
$this->drupalGet($resetURL);
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
|
||||
// Change the password.
|
||||
$password = user_password();
|
||||
$edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(t('The changes have been saved.'), 'Password changed.');
|
||||
|
||||
// Logged in users should not be able to access the user.reset.login or the
|
||||
// user.reset.form routes.
|
||||
$timestamp = REQUEST_TIME - 1;
|
||||
$this->drupalGet("user/reset/" . $this->account->id() . "/$timestamp/" . user_pass_rehash($this->account, $timestamp) . '/login');
|
||||
$this->assertResponse(403);
|
||||
$this->drupalGet("user/reset/" . $this->account->id());
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefill the text box on incorrect login via link to password reset page.
|
||||
*/
|
||||
public function testUserResetPasswordTextboxFilled() {
|
||||
$this->drupalGet('user/login');
|
||||
$edit = [
|
||||
'name' => $this->randomMachineName(),
|
||||
'pass' => $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm('user/login', $edit, t('Log in'));
|
||||
$this->assertRaw(t('Unrecognized username or password. <a href=":password">Forgot your password?</a>',
|
||||
[':password' => \Drupal::url('user.pass', [], ['query' => ['name' => $edit['name']]])]));
|
||||
unset($edit['pass']);
|
||||
$this->drupalGet('user/password', ['query' => ['name' => $edit['name']]]);
|
||||
$this->assertFieldByName('name', $edit['name'], 'User name found.');
|
||||
// Ensure the name field value is not cached.
|
||||
$this->drupalGet('user/password');
|
||||
$this->assertNoFieldByName('name', $edit['name'], 'User name not found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that users cannot forge password reset URLs of other users.
|
||||
*/
|
||||
public function testResetImpersonation() {
|
||||
// Create two identical user accounts except for the user name. They must
|
||||
// have the same empty password, so we can't use $this->drupalCreateUser().
|
||||
$edit = [];
|
||||
$edit['name'] = $this->randomMachineName();
|
||||
$edit['mail'] = $edit['name'] . '@example.com';
|
||||
$edit['status'] = 1;
|
||||
$user1 = User::create($edit);
|
||||
$user1->save();
|
||||
|
||||
$edit['name'] = $this->randomMachineName();
|
||||
$user2 = User::create($edit);
|
||||
$user2->save();
|
||||
|
||||
// Unique password hashes are automatically generated, the only way to
|
||||
// change that is to update it directly in the database.
|
||||
db_update('users_field_data')
|
||||
->fields(['pass' => NULL])
|
||||
->condition('uid', [$user1->id(), $user2->id()], 'IN')
|
||||
->execute();
|
||||
\Drupal::entityManager()->getStorage('user')->resetCache();
|
||||
$user1 = User::load($user1->id());
|
||||
$user2 = User::load($user2->id());
|
||||
|
||||
$this->assertEqual($user1->getPassword(), $user2->getPassword(), 'Both users have the same password hash.');
|
||||
|
||||
// The password reset URL must not be valid for the second user when only
|
||||
// the user ID is changed in the URL.
|
||||
$reset_url = user_pass_reset_url($user1);
|
||||
$attack_reset_url = str_replace("user/reset/{$user1->id()}", "user/reset/{$user2->id()}", $reset_url);
|
||||
$this->drupalGet($attack_reset_url);
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
$this->assertNoText($user2->getUsername(), 'The invalid password reset page does not show the user name.');
|
||||
$this->assertUrl('user/password', [], 'The user is redirected to the password reset request page.');
|
||||
$this->assertText('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\user\Entity\Role;
|
||||
|
||||
/**
|
||||
* Verify that role permissions can be added and removed via the permissions
|
||||
* page.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserPermissionsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* User with admin privileges.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* User's role ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rid;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->adminUser = $this->drupalCreateUser(['administer permissions', 'access user profiles', 'administer site configuration', 'administer modules', 'administer account settings']);
|
||||
|
||||
// Find the new role ID.
|
||||
$all_rids = $this->adminUser->getRoles();
|
||||
unset($all_rids[array_search(RoleInterface::AUTHENTICATED_ID, $all_rids)]);
|
||||
$this->rid = reset($all_rids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test changing user permissions through the permissions page.
|
||||
*/
|
||||
public function testUserPermissionChanges() {
|
||||
$permissions_hash_generator = $this->container->get('user_permissions_hash_generator');
|
||||
|
||||
$storage = $this->container->get('entity.manager')->getStorage('user_role');
|
||||
|
||||
// Create an additional role and mark it as admin role.
|
||||
Role::create(['is_admin' => TRUE, 'id' => 'administrator', 'label' => 'Administrator'])->save();
|
||||
$storage->resetCache();
|
||||
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$rid = $this->rid;
|
||||
$account = $this->adminUser;
|
||||
$previous_permissions_hash = $permissions_hash_generator->generate($account);
|
||||
$this->assertIdentical($previous_permissions_hash, $permissions_hash_generator->generate($this->loggedInUser));
|
||||
|
||||
// Add a permission.
|
||||
$this->assertFalse($account->hasPermission('administer users'), 'User does not have "administer users" permission.');
|
||||
$edit = [];
|
||||
$edit[$rid . '[administer users]'] = TRUE;
|
||||
$this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions'));
|
||||
$this->assertText(t('The changes have been saved.'), 'Successful save message displayed.');
|
||||
$storage->resetCache();
|
||||
$this->assertTrue($account->hasPermission('administer users'), 'User now has "administer users" permission.');
|
||||
$current_permissions_hash = $permissions_hash_generator->generate($account);
|
||||
$this->assertIdentical($current_permissions_hash, $permissions_hash_generator->generate($this->loggedInUser));
|
||||
$this->assertNotEqual($previous_permissions_hash, $current_permissions_hash, 'Permissions hash has changed.');
|
||||
$previous_permissions_hash = $current_permissions_hash;
|
||||
|
||||
// Remove a permission.
|
||||
$this->assertTrue($account->hasPermission('access user profiles'), 'User has "access user profiles" permission.');
|
||||
$edit = [];
|
||||
$edit[$rid . '[access user profiles]'] = FALSE;
|
||||
$this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions'));
|
||||
$this->assertText(t('The changes have been saved.'), 'Successful save message displayed.');
|
||||
$storage->resetCache();
|
||||
$this->assertFalse($account->hasPermission('access user profiles'), 'User no longer has "access user profiles" permission.');
|
||||
$current_permissions_hash = $permissions_hash_generator->generate($account);
|
||||
$this->assertIdentical($current_permissions_hash, $permissions_hash_generator->generate($this->loggedInUser));
|
||||
$this->assertNotEqual($previous_permissions_hash, $current_permissions_hash, 'Permissions hash has changed.');
|
||||
|
||||
// Ensure that the admin role doesn't have any checkboxes.
|
||||
$this->drupalGet('admin/people/permissions');
|
||||
foreach (array_keys($this->container->get('user.permissions')->getPermissions()) as $permission) {
|
||||
$this->assertSession()->checkboxChecked('administrator[' . $permission . ']');
|
||||
$this->assertSession()->fieldDisabled('administrator[' . $permission . ']');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test assigning of permissions for the administrator role.
|
||||
*/
|
||||
public function testAdministratorRole() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalGet('admin/config/people/accounts');
|
||||
|
||||
// Verify that the administration role is none by default.
|
||||
$this->assertOptionSelected('edit-user-admin-role', '', 'Administration role defaults to none.');
|
||||
|
||||
$this->assertFalse(Role::load($this->rid)->isAdmin());
|
||||
|
||||
// Set the user's role to be the administrator role.
|
||||
$edit = [];
|
||||
$edit['user_admin_role'] = $this->rid;
|
||||
$this->drupalPostForm('admin/config/people/accounts', $edit, t('Save configuration'));
|
||||
|
||||
\Drupal::entityManager()->getStorage('user_role')->resetCache();
|
||||
$this->assertTrue(Role::load($this->rid)->isAdmin());
|
||||
|
||||
// Enable aggregator module and ensure the 'administer news feeds'
|
||||
// permission is assigned by default.
|
||||
\Drupal::service('module_installer')->install(['aggregator']);
|
||||
|
||||
$this->assertTrue($this->adminUser->hasPermission('administer news feeds'), 'The permission was automatically assigned to the administrator role');
|
||||
|
||||
// Ensure that selecting '- None -' removes the admin role.
|
||||
$edit = [];
|
||||
$edit['user_admin_role'] = '';
|
||||
$this->drupalPostForm('admin/config/people/accounts', $edit, t('Save configuration'));
|
||||
|
||||
\Drupal::entityManager()->getStorage('user_role')->resetCache();
|
||||
\Drupal::configFactory()->reset();
|
||||
$this->assertFalse(Role::load($this->rid)->isAdmin());
|
||||
|
||||
// Manually create two admin roles, in that case the single select should be
|
||||
// hidden.
|
||||
Role::create(['id' => 'admin_role_0', 'is_admin' => TRUE, 'label' => 'Admin role 0'])->save();
|
||||
Role::create(['id' => 'admin_role_1', 'is_admin' => TRUE, 'label' => 'Admin role 1'])->save();
|
||||
$this->drupalGet('admin/config/people/accounts');
|
||||
$this->assertNoFieldByName('user_admin_role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify proper permission changes by user_role_change_permissions().
|
||||
*/
|
||||
public function testUserRoleChangePermissions() {
|
||||
$permissions_hash_generator = $this->container->get('user_permissions_hash_generator');
|
||||
|
||||
$rid = $this->rid;
|
||||
$account = $this->adminUser;
|
||||
$previous_permissions_hash = $permissions_hash_generator->generate($account);
|
||||
|
||||
// Verify current permissions.
|
||||
$this->assertFalse($account->hasPermission('administer users'), 'User does not have "administer users" permission.');
|
||||
$this->assertTrue($account->hasPermission('access user profiles'), 'User has "access user profiles" permission.');
|
||||
$this->assertTrue($account->hasPermission('administer site configuration'), 'User has "administer site configuration" permission.');
|
||||
|
||||
// Change permissions.
|
||||
$permissions = [
|
||||
'administer users' => 1,
|
||||
'access user profiles' => 0,
|
||||
];
|
||||
user_role_change_permissions($rid, $permissions);
|
||||
|
||||
// Verify proper permission changes.
|
||||
$this->assertTrue($account->hasPermission('administer users'), 'User now has "administer users" permission.');
|
||||
$this->assertFalse($account->hasPermission('access user profiles'), 'User no longer has "access user profiles" permission.');
|
||||
$this->assertTrue($account->hasPermission('administer site configuration'), 'User still has "administer site configuration" permission.');
|
||||
|
||||
// Verify the permissions hash has changed.
|
||||
$current_permissions_hash = $permissions_hash_generator->generate($account);
|
||||
$this->assertNotEqual($previous_permissions_hash, $current_permissions_hash, 'Permissions hash has changed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify 'access content' is listed in the correct location.
|
||||
*/
|
||||
public function testAccessContentPermission() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// When Node is not installed the 'access content' permission is listed next
|
||||
// to 'access site reports'.
|
||||
$this->drupalGet('admin/people/permissions');
|
||||
$next_row = $this->xpath('//tr[@data-drupal-selector=\'edit-permissions-access-content\']/following-sibling::tr[1]');
|
||||
$this->assertEqual('edit-permissions-access-site-reports', $next_row[0]->getAttribute('data-drupal-selector'));
|
||||
|
||||
// When Node is installed the 'access content' permission is listed next to
|
||||
// to 'view own unpublished content'.
|
||||
\Drupal::service('module_installer')->install(['node']);
|
||||
$this->drupalGet('admin/people/permissions');
|
||||
$next_row = $this->xpath('//tr[@data-drupal-selector=\'edit-permissions-access-content\']/following-sibling::tr[1]');
|
||||
$this->assertEqual('edit-permissions-view-own-unpublished-content', $next_row[0]->getAttribute('data-drupal-selector'));
|
||||
}
|
||||
|
||||
}
|
154
web/core/modules/user/tests/src/Functional/UserPictureTest.php
Normal file
154
web/core/modules/user/tests/src/Functional/UserPictureTest.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests user picture functionality.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserPictureTest extends BrowserTestBase {
|
||||
|
||||
use TestFileCreationTrait {
|
||||
getTestFiles as drupalGetTestFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The profile to install as a basis for testing.
|
||||
*
|
||||
* Using the standard profile to test user picture config provided by the
|
||||
* standard profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'standard';
|
||||
|
||||
/**
|
||||
* A regular user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// This test expects unused managed files to be marked temporary and then
|
||||
// cleaned up by file_cron().
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
|
||||
$this->webUser = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'access comments',
|
||||
'post comments',
|
||||
'skip comment approval',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creation, display, and deletion of user pictures.
|
||||
*/
|
||||
public function testCreateDeletePicture() {
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Save a new picture.
|
||||
$image = current($this->drupalGetTestFiles('image'));
|
||||
$file = $this->saveUserPicture($image);
|
||||
|
||||
// Verify that the image is displayed on the user account page.
|
||||
$this->drupalGet('user');
|
||||
$this->assertRaw(file_uri_target($file->getFileUri()), 'User picture found on user account page.');
|
||||
|
||||
// Delete the picture.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('user/' . $this->webUser->id() . '/edit', $edit, t('Remove'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
|
||||
// Call file_cron() to clean up the file. Make sure the timestamp
|
||||
// of the file is older than the system.file.temporary_maximum_age
|
||||
// configuration value.
|
||||
db_update('file_managed')
|
||||
->fields([
|
||||
'changed' => REQUEST_TIME - ($this->config('system.file')->get('temporary_maximum_age') + 1),
|
||||
])
|
||||
->condition('fid', $file->id())
|
||||
->execute();
|
||||
\Drupal::service('cron')->run();
|
||||
|
||||
// Verify that the image has been deleted.
|
||||
$this->assertFalse(File::load($file->id()), 'File was removed from the database.');
|
||||
// Clear out PHP's file stat cache so we see the current value.
|
||||
clearstatcache(TRUE, $file->getFileUri());
|
||||
$this->assertFalse(is_file($file->getFileUri()), 'File was removed from the file system.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests embedded users on node pages.
|
||||
*/
|
||||
public function testPictureOnNodeComment() {
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Save a new picture.
|
||||
$image = current($this->drupalGetTestFiles('image'));
|
||||
$file = $this->saveUserPicture($image);
|
||||
|
||||
$node = $this->drupalCreateNode(['type' => 'article']);
|
||||
|
||||
// Enable user pictures on nodes.
|
||||
$this->config('system.theme.global')->set('features.node_user_picture', TRUE)->save();
|
||||
|
||||
$image_style_id = $this->config('core.entity_view_display.user.user.compact')->get('content.user_picture.settings.image_style');
|
||||
$style = ImageStyle::load($image_style_id);
|
||||
$image_url = file_url_transform_relative($style->buildUrl($file->getfileUri()));
|
||||
$alt_text = 'Profile picture for user ' . $this->webUser->getUsername();
|
||||
|
||||
// Verify that the image is displayed on the node page.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$elements = $this->cssSelect('.node__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]');
|
||||
$this->assertEqual(count($elements), 1, 'User picture with alt text found on node page.');
|
||||
|
||||
// Enable user pictures on comments, instead of nodes.
|
||||
$this->config('system.theme.global')
|
||||
->set('features.node_user_picture', FALSE)
|
||||
->set('features.comment_user_picture', TRUE)
|
||||
->save();
|
||||
|
||||
$edit = [
|
||||
'comment_body[0][value]' => $this->randomString(),
|
||||
];
|
||||
$this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit, t('Save'));
|
||||
$elements = $this->cssSelect('.comment__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]');
|
||||
$this->assertEqual(count($elements), 1, 'User picture with alt text found on the comment.');
|
||||
|
||||
// Disable user pictures on comments and nodes.
|
||||
$this->config('system.theme.global')
|
||||
->set('features.node_user_picture', FALSE)
|
||||
->set('features.comment_user_picture', FALSE)
|
||||
->save();
|
||||
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertNoRaw(file_uri_target($file->getFileUri()), 'User picture not found on node and comment.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the user picture for the test user.
|
||||
*/
|
||||
public function saveUserPicture($image) {
|
||||
$edit = ['files[user_picture_0]' => \Drupal::service('file_system')->realpath($image->uri)];
|
||||
$this->drupalPostForm('user/' . $this->webUser->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Load actual user data from database.
|
||||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
$user_storage->resetCache([$this->webUser->id()]);
|
||||
$account = $user_storage->load($this->webUser->id());
|
||||
return File::load($account->user_picture->target_id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,384 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests registration of user under different configurations.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserRegistrationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field_test'];
|
||||
|
||||
public function testRegistrationWithEmailVerification() {
|
||||
$config = $this->config('user.settings');
|
||||
// Require email verification.
|
||||
$config->set('verify_mail', TRUE)->save();
|
||||
|
||||
// Set registration to administrator only.
|
||||
$config->set('register', USER_REGISTER_ADMINISTRATORS_ONLY)->save();
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertResponse(403, 'Registration page is inaccessible when only administrators can create accounts.');
|
||||
|
||||
// Allow registration by site visitors without administrator approval.
|
||||
$config->set('register', USER_REGISTER_VISITORS)->save();
|
||||
$edit = [];
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertText(t('A welcome message with further instructions has been sent to your email address.'), 'User registered successfully.');
|
||||
|
||||
/** @var EntityStorageInterface $storage */
|
||||
$storage = $this->container->get('entity_type.manager')->getStorage('user');
|
||||
$accounts = $storage->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertTrue($new_user->isActive(), 'New account is active after registration.');
|
||||
$resetURL = user_pass_reset_url($new_user);
|
||||
$this->drupalGet($resetURL);
|
||||
$this->assertTitle(t('Set password | Drupal'), 'Page title is "Set password".');
|
||||
|
||||
// Allow registration by site visitors, but require administrator approval.
|
||||
$config->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save();
|
||||
$edit = [];
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->container->get('entity.manager')->getStorage('user')->resetCache();
|
||||
$accounts = $storage->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertFalse($new_user->isActive(), 'New account is blocked until approved by an administrator.');
|
||||
}
|
||||
|
||||
public function testRegistrationWithoutEmailVerification() {
|
||||
$config = $this->config('user.settings');
|
||||
// Don't require email verification and allow registration by site visitors
|
||||
// without administrator approval.
|
||||
$config
|
||||
->set('verify_mail', FALSE)
|
||||
->set('register', USER_REGISTER_VISITORS)
|
||||
->save();
|
||||
|
||||
$edit = [];
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
|
||||
// Try entering a mismatching password.
|
||||
$edit['pass[pass1]'] = '99999.0';
|
||||
$edit['pass[pass2]'] = '99999';
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertText(t('The specified passwords do not match.'), 'Typing mismatched passwords displays an error message.');
|
||||
|
||||
// Enter a correct password.
|
||||
$edit['pass[pass1]'] = $new_pass = $this->randomMachineName();
|
||||
$edit['pass[pass2]'] = $new_pass;
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->container->get('entity.manager')->getStorage('user')->resetCache();
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertNotNull($new_user, 'New account successfully created with matching passwords.');
|
||||
$this->assertText(t('Registration successful. You are now logged in.'), 'Users are logged in after registering.');
|
||||
$this->drupalLogout();
|
||||
|
||||
// Allow registration by site visitors, but require administrator approval.
|
||||
$config->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save();
|
||||
$edit = [];
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$edit['pass[pass1]'] = $pass = $this->randomMachineName();
|
||||
$edit['pass[pass2]'] = $pass;
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertText(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.'), 'Users are notified of pending approval');
|
||||
|
||||
// Try to log in before administrator approval.
|
||||
$auth = [
|
||||
'name' => $name,
|
||||
'pass' => $pass,
|
||||
];
|
||||
$this->drupalPostForm('user/login', $auth, t('Log in'));
|
||||
$this->assertText(t('The username @name has not been activated or is blocked.', ['@name' => $name]), 'User cannot log in yet.');
|
||||
|
||||
// Activate the new account.
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$admin_user = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$edit = [
|
||||
'status' => 1,
|
||||
];
|
||||
$this->drupalPostForm('user/' . $new_user->id() . '/edit', $edit, t('Save'));
|
||||
$this->drupalLogout();
|
||||
|
||||
// Log in after administrator approval.
|
||||
$this->drupalPostForm('user/login', $auth, t('Log in'));
|
||||
$this->assertText(t('Member for'), 'User can log in after administrator approval.');
|
||||
}
|
||||
|
||||
public function testRegistrationEmailDuplicates() {
|
||||
// Don't require email verification and allow registration by site visitors
|
||||
// without administrator approval.
|
||||
$this->config('user.settings')
|
||||
->set('verify_mail', FALSE)
|
||||
->set('register', USER_REGISTER_VISITORS)
|
||||
->save();
|
||||
|
||||
// Set up a user to check for duplicates.
|
||||
$duplicate_user = $this->drupalCreateUser();
|
||||
|
||||
$edit = [];
|
||||
$edit['name'] = $this->randomMachineName();
|
||||
$edit['mail'] = $duplicate_user->getEmail();
|
||||
|
||||
// Attempt to create a new account using an existing email address.
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertText(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()]), 'Supplying an exact duplicate email address displays an error message');
|
||||
|
||||
// Attempt to bypass duplicate email registration validation by adding spaces.
|
||||
$edit['mail'] = ' ' . $duplicate_user->getEmail() . ' ';
|
||||
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertText(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()]), 'Supplying a duplicate email address with added whitespace displays an error message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that UUID isn't cached in form state on register form.
|
||||
*
|
||||
* This is a regression test for https://www.drupal.org/node/2500527 to ensure
|
||||
* that the form is not cached on GET requests.
|
||||
*/
|
||||
public function testUuidFormState() {
|
||||
\Drupal::service('module_installer')->install(['image']);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
// Add a picture field in order to ensure that no form cache is written,
|
||||
// which breaks registration of more than 1 user every 6 hours.
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'user_picture',
|
||||
'entity_type' => 'user',
|
||||
'type' => 'image',
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => 'user_picture',
|
||||
'entity_type' => 'user',
|
||||
'bundle' => 'user',
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
$form_display = EntityFormDisplay::create([
|
||||
'targetEntityType' => 'user',
|
||||
'bundle' => 'user',
|
||||
'mode' => 'default',
|
||||
'status' => TRUE,
|
||||
]);
|
||||
$form_display->setComponent('user_picture', [
|
||||
'type' => 'image_image',
|
||||
]);
|
||||
$form_display->save();
|
||||
|
||||
// Don't require email verification and allow registration by site visitors
|
||||
// without administrator approval.
|
||||
$this->config('user.settings')
|
||||
->set('verify_mail', FALSE)
|
||||
->set('register', USER_REGISTER_VISITORS)
|
||||
->save();
|
||||
|
||||
$edit = [];
|
||||
$edit['name'] = $this->randomMachineName();
|
||||
$edit['mail'] = $edit['name'] . '@example.com';
|
||||
$edit['pass[pass2]'] = $edit['pass[pass1]'] = $this->randomMachineName();
|
||||
|
||||
// Create one account.
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
$user_storage = \Drupal::entityManager()->getStorage('user');
|
||||
|
||||
$this->assertTrue($user_storage->loadByProperties(['name' => $edit['name']]));
|
||||
$this->drupalLogout();
|
||||
|
||||
// Create a second account.
|
||||
$edit['name'] = $this->randomMachineName();
|
||||
$edit['mail'] = $edit['name'] . '@example.com';
|
||||
$edit['pass[pass2]'] = $edit['pass[pass1]'] = $this->randomMachineName();
|
||||
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
$this->assertTrue($user_storage->loadByProperties(['name' => $edit['name']]));
|
||||
}
|
||||
|
||||
public function testRegistrationDefaultValues() {
|
||||
// Don't require email verification and allow registration by site visitors
|
||||
// without administrator approval.
|
||||
$config_user_settings = $this->config('user.settings')
|
||||
->set('verify_mail', FALSE)
|
||||
->set('register', USER_REGISTER_VISITORS)
|
||||
->save();
|
||||
|
||||
// Set the default timezone to Brussels.
|
||||
$config_system_date = $this->config('system.date')
|
||||
->set('timezone.user.configurable', 1)
|
||||
->set('timezone.default', 'Europe/Brussels')
|
||||
->save();
|
||||
|
||||
// Check the presence of expected cache tags.
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertCacheTag('config:user.settings');
|
||||
|
||||
$edit = [];
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$edit['pass[pass1]'] = $new_pass = $this->randomMachineName();
|
||||
$edit['pass[pass2]'] = $new_pass;
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
|
||||
// Check user fields.
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertEqual($new_user->getUsername(), $name, 'Username matches.');
|
||||
$this->assertEqual($new_user->getEmail(), $mail, 'Email address matches.');
|
||||
$this->assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20), 'Correct creation time.');
|
||||
$this->assertEqual($new_user->isActive(), $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.');
|
||||
$this->assertEqual($new_user->getTimezone(), $config_system_date->get('timezone.default'), 'Correct time zone field.');
|
||||
$this->assertEqual($new_user->langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct language field.');
|
||||
$this->assertEqual($new_user->preferred_langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct preferred language field.');
|
||||
$this->assertEqual($new_user->init->value, $mail, 'Correct init field.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests username and email field constraints on user registration.
|
||||
*
|
||||
* @see \Drupal\user\Plugin\Validation\Constraint\UserNameUnique
|
||||
* @see \Drupal\user\Plugin\Validation\Constraint\UserMailUnique
|
||||
*/
|
||||
public function testUniqueFields() {
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
$edit = ['mail' => 'test@example.com', 'name' => $account->getUsername()];
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertRaw(new FormattableMarkup('The username %value is already taken.', ['%value' => $account->getUsername()]));
|
||||
|
||||
$edit = ['mail' => $account->getEmail(), 'name' => $this->randomString()];
|
||||
$this->drupalPostForm('user/register', $edit, t('Create new account'));
|
||||
$this->assertRaw(new FormattableMarkup('The email address %value is already taken.', ['%value' => $account->getEmail()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
entity_get_form_display('user', 'user', 'register')
|
||||
->save();
|
||||
|
||||
// Check that the field does not appear on the registration form.
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertNoText($field->label(), 'The field does not appear on user registration form');
|
||||
$this->assertCacheTag('config:core.entity_form_display.user.user.register');
|
||||
$this->assertCacheTag('config:user.settings');
|
||||
|
||||
// Have the field appear on the registration form.
|
||||
entity_get_form_display('user', 'user', 'register')
|
||||
->setComponent('test_user_field', ['type' => 'test_field_widget'])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertText($field->label(), 'The field appears on user registration form');
|
||||
$this->assertRegistrationFormCacheTagsWithUserFields();
|
||||
|
||||
// Check that validation errors are correctly reported.
|
||||
$edit = [];
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
// Missing input in required field.
|
||||
$edit['test_user_field[0][value]'] = '';
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
$this->assertRegistrationFormCacheTagsWithUserFields();
|
||||
$this->assertRaw(t('@name field is required.', ['@name' => $field->label()]), 'Field validation error was correctly reported.');
|
||||
// Invalid input.
|
||||
$edit['test_user_field[0][value]'] = '-1';
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
$this->assertRegistrationFormCacheTagsWithUserFields();
|
||||
$this->assertRaw(t('%name does not accept the value -1.', ['%name' => $field->label()]), 'Field validation error was correctly reported.');
|
||||
|
||||
// Submit with valid data.
|
||||
$value = rand(1, 255);
|
||||
$edit['test_user_field[0][value]'] = $value;
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
// Check user fields.
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertEqual($new_user->test_user_field->value, $value, 'The field value was correctly saved.');
|
||||
|
||||
// Check that the 'add more' button works.
|
||||
$field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
$field_storage->save();
|
||||
$this->drupalGet('user/register');
|
||||
$this->assertRegistrationFormCacheTagsWithUserFields();
|
||||
// Add two inputs.
|
||||
$value = rand(1, 255);
|
||||
$edit = [];
|
||||
$edit['test_user_field[0][value]'] = $value;
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
// Submit with three values.
|
||||
$edit['test_user_field[1][value]'] = $value + 1;
|
||||
$edit['test_user_field[2][value]'] = $value + 2;
|
||||
$edit['name'] = $name = $this->randomMachineName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$this->drupalPostForm(NULL, $edit, t('Create new account'));
|
||||
// Check user fields.
|
||||
$accounts = $this->container->get('entity_type.manager')->getStorage('user')
|
||||
->loadByProperties(['name' => $name, 'mail' => $mail]);
|
||||
$new_user = reset($accounts);
|
||||
$this->assertEqual($new_user->test_user_field[0]->value, $value, 'The field value was correctly saved.');
|
||||
$this->assertEqual($new_user->test_user_field[1]->value, $value + 1, 'The field value was correctly saved.');
|
||||
$this->assertEqual($new_user->test_user_field[2]->value, $value + 2, 'The field value was correctly saved.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the presence of cache tags on registration form with user fields.
|
||||
*/
|
||||
protected function assertRegistrationFormCacheTagsWithUserFields() {
|
||||
$this->assertCacheTag('config:core.entity_form_display.user.user.register');
|
||||
$this->assertCacheTag('config:field.field.user.user.test_user_field');
|
||||
$this->assertCacheTag('config:field.storage.user.test_user_field');
|
||||
$this->assertCacheTag('config:user.settings');
|
||||
}
|
||||
|
||||
}
|
132
web/core/modules/user/tests/src/Functional/UserRoleAdminTest.php
Normal file
132
web/core/modules/user/tests/src/Functional/UserRoleAdminTest.php
Normal file
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Tests adding, editing and deleting user roles and changing role weights.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserRoleAdminTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* User with admin privileges.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->adminUser = $this->drupalCreateUser(['administer permissions', 'administer users']);
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding, renaming and deleting roles.
|
||||
*/
|
||||
public function testRoleAdministration() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
|
||||
// Test presence of tab.
|
||||
$this->drupalGet('admin/people/permissions');
|
||||
$tabs = $this->xpath('//ul[@class=:classes and //a[contains(., :text)]]', [
|
||||
':classes' => 'tabs primary',
|
||||
':text' => 'Roles',
|
||||
]);
|
||||
$this->assertEqual(count($tabs), 1, 'Found roles tab');
|
||||
|
||||
// Test adding a role. (In doing so, we use a role name that happens to
|
||||
// correspond to an integer, to test that the role administration pages
|
||||
// correctly distinguish between role names and IDs.)
|
||||
$role_name = '123';
|
||||
$edit = ['label' => $role_name, 'id' => $role_name];
|
||||
$this->drupalPostForm('admin/people/roles/add', $edit, t('Save'));
|
||||
$this->assertRaw(t('Role %label has been added.', ['%label' => 123]));
|
||||
$role = Role::load($role_name);
|
||||
$this->assertTrue(is_object($role), 'The role was successfully retrieved from the database.');
|
||||
|
||||
// Check that the role was created in site default language.
|
||||
$this->assertEqual($role->language()->getId(), $default_langcode);
|
||||
|
||||
// Try adding a duplicate role.
|
||||
$this->drupalPostForm('admin/people/roles/add', $edit, t('Save'));
|
||||
$this->assertRaw(t('The machine-readable name is already in use. It must be unique.'), 'Duplicate role warning displayed.');
|
||||
|
||||
// Test renaming a role.
|
||||
$role_name = '456';
|
||||
$edit = ['label' => $role_name];
|
||||
$this->drupalPostForm("admin/people/roles/manage/{$role->id()}", $edit, t('Save'));
|
||||
$this->assertRaw(t('Role %label has been updated.', ['%label' => $role_name]));
|
||||
\Drupal::entityManager()->getStorage('user_role')->resetCache([$role->id()]);
|
||||
$new_role = Role::load($role->id());
|
||||
$this->assertEqual($new_role->label(), $role_name, 'The role name has been successfully changed.');
|
||||
|
||||
// Test deleting a role.
|
||||
$this->drupalGet("admin/people/roles/manage/{$role->id()}");
|
||||
$this->clickLink(t('Delete'));
|
||||
$this->drupalPostForm(NULL, [], t('Delete'));
|
||||
$this->assertRaw(t('The role %label has been deleted.', ['%label' => $role_name]));
|
||||
$this->assertNoLinkByHref("admin/people/roles/manage/{$role->id()}", 'Role edit link removed.');
|
||||
\Drupal::entityManager()->getStorage('user_role')->resetCache([$role->id()]);
|
||||
$this->assertFalse(Role::load($role->id()), 'A deleted role can no longer be loaded.');
|
||||
|
||||
// Make sure that the system-defined roles can be edited via the user
|
||||
// interface.
|
||||
$this->drupalGet('admin/people/roles/manage/' . RoleInterface::ANONYMOUS_ID);
|
||||
$this->assertResponse(200, 'Access granted when trying to edit the built-in anonymous role.');
|
||||
$this->assertNoText(t('Delete role'), 'Delete button for the anonymous role is not present.');
|
||||
$this->drupalGet('admin/people/roles/manage/' . RoleInterface::AUTHENTICATED_ID);
|
||||
$this->assertResponse(200, 'Access granted when trying to edit the built-in authenticated role.');
|
||||
$this->assertNoText(t('Delete role'), 'Delete button for the authenticated role is not present.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test user role weight change operation and ordering.
|
||||
*/
|
||||
public function testRoleWeightOrdering() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$roles = user_roles();
|
||||
$weight = count($roles);
|
||||
$new_role_weights = [];
|
||||
$saved_rids = [];
|
||||
|
||||
// Change the role weights to make the roles in reverse order.
|
||||
$edit = [];
|
||||
foreach ($roles as $role) {
|
||||
$edit['entities[' . $role->id() . '][weight]'] = $weight;
|
||||
$new_role_weights[$role->id()] = $weight;
|
||||
$saved_rids[] = $role->id();
|
||||
$weight--;
|
||||
}
|
||||
$this->drupalPostForm('admin/people/roles', $edit, t('Save'));
|
||||
$this->assertText(t('The role settings have been updated.'), 'The role settings form submitted successfully.');
|
||||
|
||||
// Load up the user roles with the new weights.
|
||||
drupal_static_reset('user_roles');
|
||||
$roles = user_roles();
|
||||
$rids = [];
|
||||
// Test that the role weights have been correctly saved.
|
||||
foreach ($roles as $role) {
|
||||
$this->assertEqual($role->getWeight(), $new_role_weights[$role->id()]);
|
||||
$rids[] = $role->id();
|
||||
}
|
||||
// The order of the roles should be reversed.
|
||||
$this->assertIdentical($rids, array_reverse($saved_rids));
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,7 @@ class UserRolesAssignmentTest extends BrowserTestBase {
|
|||
* Tests that a user can be assigned a role and that the role can be removed
|
||||
* again.
|
||||
*/
|
||||
public function testAssignAndRemoveRole() {
|
||||
public function testAssignAndRemoveRole() {
|
||||
$rid = $this->drupalCreateRole(['administer users']);
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Set a user time zone and verify that dates are displayed in local time.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserTimeZoneTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'system_test'];
|
||||
|
||||
/**
|
||||
* Tests the display of dates and time when user-configurable time zones are set.
|
||||
*/
|
||||
public function testUserTimeZone() {
|
||||
// Setup date/time settings for Los Angeles time.
|
||||
$this->config('system.date')
|
||||
->set('timezone.user.configurable', 1)
|
||||
->set('timezone.default', 'America/Los_Angeles')
|
||||
->save();
|
||||
|
||||
// Load the 'medium' date format, which is the default for node creation
|
||||
// time, and override it. Since we are testing time zones with Daylight
|
||||
// Saving Time, and need to future proof against changes to the zoneinfo
|
||||
// database, we choose the 'I' format placeholder instead of a
|
||||
// human-readable zone name. With 'I', a 1 means the date is in DST, and 0
|
||||
// if not.
|
||||
DateFormat::load('medium')
|
||||
->setPattern('Y-m-d H:i I')
|
||||
->save();
|
||||
|
||||
// Create a user account and login.
|
||||
$web_user = $this->drupalCreateUser();
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create some nodes with different authored-on dates.
|
||||
// Two dates in PST (winter time):
|
||||
$date1 = '2007-03-09 21:00:00 -0800';
|
||||
$date2 = '2007-03-11 01:00:00 -0800';
|
||||
// One date in PDT (summer time):
|
||||
$date3 = '2007-03-20 21:00:00 -0700';
|
||||
$this->drupalCreateContentType(['type' => 'article']);
|
||||
$node1 = $this->drupalCreateNode(['created' => strtotime($date1), 'type' => 'article']);
|
||||
$node2 = $this->drupalCreateNode(['created' => strtotime($date2), 'type' => 'article']);
|
||||
$node3 = $this->drupalCreateNode(['created' => strtotime($date3), 'type' => 'article']);
|
||||
|
||||
// Confirm date format and time zone.
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertText('2007-03-09 21:00 0', 'Date should be PST.');
|
||||
$this->drupalGet('node/' . $node2->id());
|
||||
$this->assertText('2007-03-11 01:00 0', 'Date should be PST.');
|
||||
$this->drupalGet('node/' . $node3->id());
|
||||
$this->assertText('2007-03-20 21:00 1', 'Date should be PDT.');
|
||||
|
||||
// Change user time zone to Santiago time.
|
||||
$edit = [];
|
||||
$edit['mail'] = $web_user->getEmail();
|
||||
$edit['timezone'] = 'America/Santiago';
|
||||
$this->drupalPostForm("user/" . $web_user->id() . "/edit", $edit, t('Save'));
|
||||
$this->assertText(t('The changes have been saved.'), 'Time zone changed to Santiago time.');
|
||||
|
||||
// Confirm date format and time zone.
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertText('2007-03-10 02:00 1', 'Date should be Chile summer time; five hours ahead of PST.');
|
||||
$this->drupalGet('node/' . $node2->id());
|
||||
$this->assertText('2007-03-11 05:00 0', 'Date should be Chile time; four hours ahead of PST');
|
||||
$this->drupalGet('node/' . $node3->id());
|
||||
$this->assertText('2007-03-21 00:00 0', 'Date should be Chile time; three hours ahead of PDT.');
|
||||
|
||||
// Ensure that anonymous users also use the default timezone.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertText('2007-03-09 21:00 0', 'Date should be PST.');
|
||||
$this->drupalGet('node/' . $node2->id());
|
||||
$this->assertText('2007-03-11 01:00 0', 'Date should be PST.');
|
||||
$this->drupalGet('node/' . $node3->id());
|
||||
$this->assertText('2007-03-20 21:00 1', 'Date should be PDT.');
|
||||
|
||||
// Format a date without accessing the current user at all and
|
||||
// ensure that it uses the default timezone.
|
||||
$this->drupalGet('/system-test/date');
|
||||
$this->assertText('2016-01-13 08:29 0', 'Date should be PST.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional;
|
||||
|
||||
use Drupal\Tests\content_translation\Functional\ContentTranslationUITestBase;
|
||||
|
||||
/**
|
||||
* Tests the User Translation UI.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserTranslationUITest extends ContentTranslationUITestBase {
|
||||
|
||||
/**
|
||||
* The user name of the test user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['language', 'content_translation', 'user', 'views'];
|
||||
|
||||
protected function setUp() {
|
||||
$this->entityTypeId = 'user';
|
||||
$this->testLanguageSelector = FALSE;
|
||||
$this->name = $this->randomMachineName();
|
||||
parent::setUp();
|
||||
|
||||
\Drupal::entityManager()->getStorage('user')->resetCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getTranslatorPermissions() {
|
||||
return array_merge(parent::getTranslatorPermissions(), ['administer users']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNewEntityValues($langcode) {
|
||||
// User name is not translatable hence we use a fixed value.
|
||||
return ['name' => $this->name] + parent::getNewEntityValues($langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doTestTranslationEdit() {
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId);
|
||||
$storage->resetCache([$this->entityId]);
|
||||
$entity = $storage->load($this->entityId);
|
||||
$languages = $this->container->get('language_manager')->getLanguages();
|
||||
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
// We only want to test the title for non-english translations.
|
||||
if ($langcode != 'en') {
|
||||
$options = ['language' => $languages[$langcode]];
|
||||
$url = $entity->urlInfo('edit-form', $options);
|
||||
$this->drupalGet($url);
|
||||
|
||||
$title = t('@title [%language translation]', [
|
||||
'@title' => $entity->getTranslation($langcode)->label(),
|
||||
'%language' => $languages[$langcode]->getName(),
|
||||
]);
|
||||
$this->assertRaw($title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\user\Plugin\views\access\Permission;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests views perm access plugin.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\access\Permission
|
||||
*/
|
||||
class AccessPermissionTest extends AccessTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_access_perm'];
|
||||
|
||||
/**
|
||||
* Tests perm access plugin.
|
||||
*/
|
||||
public function testAccessPerm() {
|
||||
$view = Views::getView('test_access_perm');
|
||||
$view->setDisplay();
|
||||
|
||||
$access_plugin = $view->display_handler->getPlugin('access');
|
||||
$this->assertTrue($access_plugin instanceof Permission, 'Make sure the right class got instantiated.');
|
||||
$this->assertEqual($access_plugin->pluginTitle(), t('Permission'));
|
||||
|
||||
$this->assertFalse($view->display_handler->access($this->webUser));
|
||||
$this->assertTrue($view->display_handler->access($this->normalUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests access on render caching.
|
||||
*/
|
||||
public function testRenderCaching() {
|
||||
$view = Views::getView('test_access_perm');
|
||||
$display = &$view->storage->getDisplay('default');
|
||||
$display['display_options']['cache'] = [
|
||||
'type' => 'tag',
|
||||
];
|
||||
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
/** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */
|
||||
$account_switcher = \Drupal::service('account_switcher');
|
||||
|
||||
// First access as user without access.
|
||||
$build = DisplayPluginBase::buildBasicRenderable('test_access_perm', 'default');
|
||||
$account_switcher->switchTo($this->normalUser);
|
||||
$result = $renderer->renderPlain($build);
|
||||
$this->assertNotEqual($result, '');
|
||||
|
||||
// Then with access.
|
||||
$build = DisplayPluginBase::buildBasicRenderable('test_access_perm', 'default');
|
||||
$account_switcher->switchTo($this->webUser);
|
||||
$result = $renderer->renderPlain($build);
|
||||
$this->assertEqual($result, '');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\user\Plugin\views\access\Role;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests views role access plugin.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\access\Role
|
||||
*/
|
||||
class AccessRoleTest extends AccessTestBase {
|
||||
|
||||
use AssertPageCacheContextsAndTagsTrait;
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_access_role'];
|
||||
|
||||
/**
|
||||
* Tests role access plugin.
|
||||
*/
|
||||
public function testAccessRole() {
|
||||
/** @var \Drupal\views\ViewEntityInterface $view */
|
||||
$view = \Drupal::entityManager()->getStorage('view')->load('test_access_role');
|
||||
$display = &$view->getDisplay('default');
|
||||
$display['display_options']['access']['options']['role'] = [
|
||||
$this->normalRole => $this->normalRole,
|
||||
];
|
||||
$view->save();
|
||||
$this->container->get('router.builder')->rebuildIfNeeded();
|
||||
$expected = [
|
||||
'config' => ['user.role.' . $this->normalRole],
|
||||
'module' => ['user', 'views_test_data'],
|
||||
];
|
||||
$this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
|
||||
|
||||
$executable = Views::executableFactory()->get($view);
|
||||
$executable->setDisplay('page_1');
|
||||
|
||||
$access_plugin = $executable->display_handler->getPlugin('access');
|
||||
$this->assertTrue($access_plugin instanceof Role, 'Make sure the right class got instantiated.');
|
||||
|
||||
// Test the access() method on the access plugin.
|
||||
$this->assertFalse($executable->display_handler->access($this->webUser));
|
||||
$this->assertTrue($executable->display_handler->access($this->normalUser));
|
||||
|
||||
$this->drupalLogin($this->webUser);
|
||||
$this->drupalGet('test-role');
|
||||
$this->assertResponse(403);
|
||||
$this->assertCacheContext('user.roles');
|
||||
|
||||
$this->drupalLogin($this->normalUser);
|
||||
$this->drupalGet('test-role');
|
||||
$this->assertResponse(200);
|
||||
$this->assertCacheContext('user.roles');
|
||||
|
||||
// Test allowing multiple roles.
|
||||
$view = Views::getView('test_access_role')->storage;
|
||||
$display = &$view->getDisplay('default');
|
||||
$display['display_options']['access']['options']['role'] = [
|
||||
$this->normalRole => $this->normalRole,
|
||||
'anonymous' => 'anonymous',
|
||||
];
|
||||
$view->save();
|
||||
$this->container->get('router.builder')->rebuildIfNeeded();
|
||||
|
||||
// Ensure that the list of roles is sorted correctly, if the generated role
|
||||
// ID comes before 'anonymous', see https://www.drupal.org/node/2398259.
|
||||
$roles = ['user.role.anonymous', 'user.role.' . $this->normalRole];
|
||||
sort($roles);
|
||||
$expected = [
|
||||
'config' => $roles,
|
||||
'module' => ['user', 'views_test_data'],
|
||||
];
|
||||
$this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
|
||||
$this->drupalLogin($this->webUser);
|
||||
$this->drupalGet('test-role');
|
||||
$this->assertResponse(403);
|
||||
$this->assertCacheContext('user.roles');
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('test-role');
|
||||
$this->assertResponse(200);
|
||||
$this->assertCacheContext('user.roles');
|
||||
$this->drupalLogin($this->normalUser);
|
||||
$this->drupalGet('test-role');
|
||||
$this->assertResponse(200);
|
||||
$this->assertCacheContext('user.roles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests access on render caching.
|
||||
*/
|
||||
public function testRenderCaching() {
|
||||
$view = Views::getView('test_access_role');
|
||||
$display = &$view->storage->getDisplay('default');
|
||||
$display['display_options']['cache'] = [
|
||||
'type' => 'tag',
|
||||
];
|
||||
$display['display_options']['access']['options']['role'] = [
|
||||
$this->normalRole => $this->normalRole,
|
||||
];
|
||||
$view->save();
|
||||
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
/** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */
|
||||
$account_switcher = \Drupal::service('account_switcher');
|
||||
|
||||
// First access as user with access.
|
||||
$build = DisplayPluginBase::buildBasicRenderable('test_access_role', 'default');
|
||||
$account_switcher->switchTo($this->normalUser);
|
||||
$result = $renderer->renderPlain($build);
|
||||
$this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
|
||||
$this->assertEqual(['config:views.view.test_access_role'], $build['#cache']['tags']);
|
||||
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
|
||||
$this->assertNotEqual($result, '');
|
||||
|
||||
// Then without access.
|
||||
$build = DisplayPluginBase::buildBasicRenderable('test_access_role', 'default');
|
||||
$account_switcher->switchTo($this->webUser);
|
||||
$result = $renderer->renderPlain($build);
|
||||
// @todo Fix this in https://www.drupal.org/node/2551037,
|
||||
// DisplayPluginBase::applyDisplayCacheabilityMetadata() is not invoked when
|
||||
// using buildBasicRenderable() and a Views access plugin returns FALSE.
|
||||
// $this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
|
||||
// $this->assertEqual([], $build['#cache']['tags']);
|
||||
$this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']);
|
||||
$this->assertEqual($result, '');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
/**
|
||||
* A common test base class for the user access plugin tests.
|
||||
*/
|
||||
abstract class AccessTestBase extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* Contains a user object that has no special permissions.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* Contains a user object that has the 'views_test_data test permission'.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $normalUser;
|
||||
|
||||
/**
|
||||
* Contains a role ID that is used by the webUser.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $webRole;
|
||||
|
||||
/**
|
||||
* Contains a role ID that is used by the normalUser.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $normalRole;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
$this->drupalPlaceBlock('system_breadcrumb_block');
|
||||
|
||||
$this->enableViewsTestModule();
|
||||
|
||||
$this->webUser = $this->drupalCreateUser();
|
||||
$roles = $this->webUser->getRoles();
|
||||
$this->webRole = $roles[0];
|
||||
|
||||
$this->normalRole = $this->drupalCreateRole([]);
|
||||
$this->normalUser = $this->drupalCreateUser(['views_test_data test permission']);
|
||||
$this->normalUser->addRole($this->normalRole);
|
||||
$this->normalUser->save();
|
||||
// @todo when all the plugin information is cached make a reset function and
|
||||
// call it here.
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests views user argument default plugin.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class ArgumentDefaultTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_plugin_argument_default_current_user'];
|
||||
|
||||
public function test_plugin_argument_default_current_user() {
|
||||
// Create a user to test.
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
// Switch the user.
|
||||
\Drupal::service('account_switcher')->switchTo($account);
|
||||
|
||||
$view = Views::getView('test_plugin_argument_default_current_user');
|
||||
$view->initHandlers();
|
||||
|
||||
$this->assertEqual($view->argument['null']->getDefaultArgument(), $account->id(), 'Uid of the current user is used.');
|
||||
// Switch back.
|
||||
\Drupal::service('account_switcher')->switchBack();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests user argument validators for ID and name.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class ArgumentValidateTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_view_argument_validate_user', 'test_view_argument_validate_username'];
|
||||
|
||||
/**
|
||||
* A user for this test.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
$this->account = $this->drupalCreateUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the User (ID) argument validator.
|
||||
*/
|
||||
public function testArgumentValidateUserUid() {
|
||||
$account = $this->account;
|
||||
|
||||
$view = Views::getView('test_view_argument_validate_user');
|
||||
$this->executeView($view);
|
||||
|
||||
$this->assertTrue($view->argument['null']->validateArgument($account->id()));
|
||||
// Reset argument validation.
|
||||
$view->argument['null']->argument_validated = NULL;
|
||||
// Fail for a valid numeric, but for a user that doesn't exist
|
||||
$this->assertFalse($view->argument['null']->validateArgument(32));
|
||||
|
||||
$form = [];
|
||||
$form_state = new FormState();
|
||||
$view->argument['null']->buildOptionsForm($form, $form_state);
|
||||
$sanitized_id = ArgumentPluginBase::encodeValidatorId('entity:user');
|
||||
$this->assertTrue($form['validate']['options'][$sanitized_id]['roles']['#states']['visible'][':input[name="options[validate][options][' . $sanitized_id . '][restrict_roles]"]']['checked']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the UserName argument validator.
|
||||
*/
|
||||
public function testArgumentValidateUserName() {
|
||||
$account = $this->account;
|
||||
|
||||
$view = Views::getView('test_view_argument_validate_username');
|
||||
$this->executeView($view);
|
||||
|
||||
$this->assertTrue($view->argument['null']->validateArgument($account->getUsername()));
|
||||
// Reset argument validation.
|
||||
$view->argument['null']->argument_validated = NULL;
|
||||
// Fail for a valid string, but for a user that doesn't exist
|
||||
$this->assertFalse($view->argument['null']->validateArgument($this->randomMachineName()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests if entity access is respected on a user bulk form.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\field\UserBulkForm
|
||||
* @see \Drupal\user\Tests\Views\BulkFormTest
|
||||
*/
|
||||
class BulkFormAccessTest 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_bulk_form'];
|
||||
|
||||
/**
|
||||
* Tests if users that may not be edited, can not be edited in bulk.
|
||||
*/
|
||||
public function testUserEditAccess() {
|
||||
// Create an authenticated user.
|
||||
$no_edit_user = $this->drupalCreateUser([], 'no_edit');
|
||||
// Ensure this account is not blocked.
|
||||
$this->assertFalse($no_edit_user->isBlocked(), 'The user is not blocked.');
|
||||
|
||||
// Log in as user admin.
|
||||
$admin_user = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Ensure that the account "no_edit" can not be edited.
|
||||
$this->drupalGet('user/' . $no_edit_user->id() . '/edit');
|
||||
$this->assertFalse($no_edit_user->access('update', $admin_user));
|
||||
$this->assertResponse(403, 'The user may not be edited.');
|
||||
|
||||
// Test blocking the account "no_edit".
|
||||
$edit = [
|
||||
'user_bulk_form[' . ($no_edit_user->id() - 1) . ']' => TRUE,
|
||||
'action' => 'user_block_user_action',
|
||||
];
|
||||
$this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
$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(),
|
||||
]));
|
||||
|
||||
// Re-load the account "no_edit" and ensure it is not blocked.
|
||||
$no_edit_user = User::load($no_edit_user->id());
|
||||
$this->assertFalse($no_edit_user->isBlocked(), 'The user is not blocked.');
|
||||
|
||||
// Create a normal user which can be edited by the admin user
|
||||
$normal_user = $this->drupalCreateUser();
|
||||
$this->assertTrue($normal_user->access('update', $admin_user));
|
||||
|
||||
$edit = [
|
||||
'user_bulk_form[' . ($normal_user->id() - 1) . ']' => TRUE,
|
||||
'action' => 'user_block_user_action',
|
||||
];
|
||||
$this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items'));
|
||||
|
||||
$normal_user = User::load($normal_user->id());
|
||||
$this->assertTrue($normal_user->isBlocked(), 'The user is blocked.');
|
||||
|
||||
// Log in as user without the 'administer users' permission.
|
||||
$this->drupalLogin($this->drupalCreateUser());
|
||||
|
||||
$edit = [
|
||||
'user_bulk_form[' . ($normal_user->id() - 1) . ']' => TRUE,
|
||||
'action' => 'user_unblock_user_action',
|
||||
];
|
||||
$this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items'));
|
||||
|
||||
// Re-load the normal user and ensure it is still blocked.
|
||||
$normal_user = User::load($normal_user->id());
|
||||
$this->assertTrue($normal_user->isBlocked(), 'The user is still blocked.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if users that may not be deleted, can not be deleted in bulk.
|
||||
*/
|
||||
public function testUserDeleteAccess() {
|
||||
// Create two authenticated users.
|
||||
$account = $this->drupalCreateUser([], 'no_delete');
|
||||
$account2 = $this->drupalCreateUser([], 'may_delete');
|
||||
|
||||
// Log in as user admin.
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer users']));
|
||||
|
||||
// Ensure that the account "no_delete" can not be deleted.
|
||||
$this->drupalGet('user/' . $account->id() . '/cancel');
|
||||
$this->assertResponse(403, 'The user "no_delete" may not be deleted.');
|
||||
// Ensure that the account "may_delete" *can* be deleted.
|
||||
$this->drupalGet('user/' . $account2->id() . '/cancel');
|
||||
$this->assertResponse(200, 'The user "may_delete" may be deleted.');
|
||||
|
||||
// Test deleting the accounts "no_delete" and "may_delete".
|
||||
$edit = [
|
||||
'user_bulk_form[' . ($account->id() - 1) . ']' => TRUE,
|
||||
'user_bulk_form[' . ($account2->id() - 1) . ']' => TRUE,
|
||||
'action' => 'user_cancel_user_action',
|
||||
];
|
||||
$this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items'));
|
||||
$edit = [
|
||||
'user_cancel_method' => 'user_cancel_delete',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Cancel accounts'));
|
||||
|
||||
// Ensure the account "no_delete" still exists.
|
||||
$account = User::load($account->id());
|
||||
$this->assertNotNull($account, 'The user "no_delete" is not deleted.');
|
||||
// Ensure the account "may_delete" no longer exists.
|
||||
$account = User::load($account2->id());
|
||||
$this->assertNull($account, 'The user "may_delete" is deleted.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests a user bulk form.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\field\UserBulkForm
|
||||
*/
|
||||
class BulkFormTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views_ui'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_user_bulk_form', 'test_user_bulk_form_combine_filter'];
|
||||
|
||||
/**
|
||||
* Tests the user bulk form.
|
||||
*/
|
||||
public function testBulkForm() {
|
||||
// Log in as a user without 'administer users'.
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer permissions']));
|
||||
$user_storage = $this->container->get('entity.manager')->getStorage('user');
|
||||
|
||||
// Create an user which actually can change users.
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer users']));
|
||||
$this->drupalGet('test-user-bulk-form');
|
||||
$result = $this->cssSelect('#edit-action option');
|
||||
$this->assertTrue(count($result) > 0);
|
||||
|
||||
// Test submitting the page with no selection.
|
||||
$edit = [
|
||||
'action' => 'user_block_user_action',
|
||||
];
|
||||
$this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items'));
|
||||
$this->assertText(t('No users selected.'));
|
||||
|
||||
// Assign a role to a user.
|
||||
$account = $user_storage->load($this->users[0]->id());
|
||||
$roles = user_role_names(TRUE);
|
||||
unset($roles[RoleInterface::AUTHENTICATED_ID]);
|
||||
$role = key($roles);
|
||||
|
||||
$this->assertFalse($account->hasRole($role), 'The user currently does not have a custom role.');
|
||||
$edit = [
|
||||
'user_bulk_form[1]' => TRUE,
|
||||
'action' => 'user_add_role_action.' . $role,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
// Re-load the user and check their roles.
|
||||
$user_storage->resetCache([$account->id()]);
|
||||
$account = $user_storage->load($account->id());
|
||||
$this->assertTrue($account->hasRole($role), 'The user now has the custom role.');
|
||||
|
||||
$edit = [
|
||||
'user_bulk_form[1]' => TRUE,
|
||||
'action' => 'user_remove_role_action.' . $role,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
// Re-load the user and check their roles.
|
||||
$user_storage->resetCache([$account->id()]);
|
||||
$account = $user_storage->load($account->id());
|
||||
$this->assertFalse($account->hasRole($role), 'The user no longer has the custom role.');
|
||||
|
||||
// Block a user using the bulk form.
|
||||
$this->assertTrue($account->isActive(), 'The user is not blocked.');
|
||||
$this->assertRaw($account->label(), 'The user is found in the table.');
|
||||
$edit = [
|
||||
'user_bulk_form[1]' => TRUE,
|
||||
'action' => 'user_block_user_action',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
// Re-load the user and check their status.
|
||||
$user_storage->resetCache([$account->id()]);
|
||||
$account = $user_storage->load($account->id());
|
||||
$this->assertTrue($account->isBlocked(), 'The user is blocked.');
|
||||
$this->assertNoRaw($account->label(), 'The user is not found in the table.');
|
||||
|
||||
// Remove the user status filter from the view.
|
||||
$view = Views::getView('test_user_bulk_form');
|
||||
$view->removeHandler('default', 'filter', 'status');
|
||||
$view->storage->save();
|
||||
|
||||
// Ensure the anonymous user is found.
|
||||
$this->drupalGet('test-user-bulk-form');
|
||||
$this->assertText($this->config('user.settings')->get('anonymous'));
|
||||
|
||||
// Attempt to block the anonymous user.
|
||||
$edit = [
|
||||
'user_bulk_form[0]' => TRUE,
|
||||
'action' => 'user_block_user_action',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
$anonymous_account = $user_storage->load(0);
|
||||
$this->assertTrue($anonymous_account->isBlocked(), 'Ensure the anonymous user got blocked.');
|
||||
|
||||
// Test the list of available actions with a value that contains a dot.
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer permissions', 'administer views', 'administer users']));
|
||||
$action_id = 'user_add_role_action.' . $role;
|
||||
$edit = [
|
||||
'options[include_exclude]' => 'exclude',
|
||||
"options[selected_actions][$action_id]" => $action_id,
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/views/nojs/handler/test_user_bulk_form/default/field/user_bulk_form', $edit, t('Apply'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$this->drupalGet('test-user-bulk-form');
|
||||
$this->assertNoOption('edit-action', $action_id);
|
||||
$edit['options[include_exclude]'] = 'include';
|
||||
$this->drupalPostForm('admin/structure/views/nojs/handler/test_user_bulk_form/default/field/user_bulk_form', $edit, t('Apply'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$this->drupalGet('test-user-bulk-form');
|
||||
$this->assertOption('edit-action', $action_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the user bulk form with a combined field filter on the bulk column.
|
||||
*/
|
||||
public function testBulkFormCombineFilter() {
|
||||
// Add a user.
|
||||
User::load($this->users[0]->id());
|
||||
$view = Views::getView('test_user_bulk_form_combine_filter');
|
||||
$errors = $view->validate();
|
||||
$this->assertEqual(reset($errors['default']), t('Field %field set in %filter is not usable for this filter type. Combined field filter only works for simple fields.', ['%field' => 'User: Bulk update', '%filter' => 'Global: Combine fields filter']));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
|
||||
/**
|
||||
* Tests the permission field handler ui.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\filter\Permissions
|
||||
*/
|
||||
class FilterPermissionUiTest extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_filter_permission'];
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user', 'user_test_views', 'views_ui'];
|
||||
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['user_test_views']);
|
||||
$this->enableViewsTestModule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests basic filter handler settings in the UI.
|
||||
*/
|
||||
public function testHandlerUI() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer views', 'administer users']));
|
||||
|
||||
$this->drupalGet('admin/structure/views/view/test_filter_permission/edit/default');
|
||||
// Verify that the handler summary is correctly displaying the selected
|
||||
// permission.
|
||||
$this->assertLink('User: Permission (= View user information)');
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
// Verify that we can save the view.
|
||||
$this->assertNoText('No valid values found on filter: User: Permission.');
|
||||
$this->assertText('The view test_filter_permission has been saved.');
|
||||
|
||||
// Verify that the handler summary is also correct when multiple values are
|
||||
// selected in the filter.
|
||||
$edit = [
|
||||
'options[value][]' => [
|
||||
'access user profiles',
|
||||
'administer views',
|
||||
],
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_permission/default/filter/permission', $edit, 'Apply');
|
||||
$this->assertLink('User: Permission (or View us…)');
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
// Verify that we can save the view.
|
||||
$this->assertNoText('No valid values found on filter: User: Permission.');
|
||||
$this->assertText('The view test_filter_permission has been saved.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the handler of the user: uid Argument.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class HandlerArgumentUserUidTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_user_uid_argument'];
|
||||
|
||||
/**
|
||||
* Tests the generated title of an user: uid argument.
|
||||
*/
|
||||
public function testArgumentTitle() {
|
||||
$view = Views::getView('test_user_uid_argument');
|
||||
|
||||
// Tests an invalid user uid.
|
||||
$this->executeView($view, [rand(1000, 10000)]);
|
||||
$this->assertFalse($view->getTitle());
|
||||
$view->destroy();
|
||||
|
||||
// Tests a valid user.
|
||||
$account = $this->drupalCreateUser();
|
||||
$this->executeView($view, [$account->id()]);
|
||||
$this->assertEqual($view->getTitle(), $account->label());
|
||||
$view->destroy();
|
||||
|
||||
// Tests the anonymous user.
|
||||
$anonymous = $this->config('user.settings')->get('anonymous');
|
||||
$this->executeView($view, [0]);
|
||||
$this->assertEqual($view->getTitle(), $anonymous);
|
||||
$view->destroy();
|
||||
|
||||
$view->getDisplay()->getHandler('argument', 'uid')->options['break_phrase'] = TRUE;
|
||||
$this->executeView($view, [$account->id() . ',0']);
|
||||
$this->assertEqual($view->getTitle(), $account->label() . ', ' . $anonymous);
|
||||
$view->destroy();
|
||||
|
||||
$view->getDisplay()->getHandler('argument', 'uid')->options['break_phrase'] = TRUE;
|
||||
$this->executeView($view, ['0,' . $account->id()]);
|
||||
$this->assertEqual($view->getTitle(), $anonymous . ', ' . $account->label());
|
||||
$view->destroy();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests the handler of the user: role field.
|
||||
*
|
||||
* @group user
|
||||
* @see views_handler_field_user_name
|
||||
*/
|
||||
class HandlerFieldRoleTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_views_handler_field_role'];
|
||||
|
||||
public function testRole() {
|
||||
// Create a couple of roles for the view.
|
||||
$rolename_a = 'a' . $this->randomMachineName(8);
|
||||
$this->drupalCreateRole(['access content'], $rolename_a, '<em>' . $rolename_a . '</em>', 9);
|
||||
|
||||
$rolename_b = 'b' . $this->randomMachineName(8);
|
||||
$this->drupalCreateRole(['access content'], $rolename_b, $rolename_b, 8);
|
||||
|
||||
$rolename_not_assigned = $this->randomMachineName(8);
|
||||
$this->drupalCreateRole(['access content'], $rolename_not_assigned, $rolename_not_assigned);
|
||||
|
||||
// Add roles to user 1.
|
||||
$user = User::load(1);
|
||||
$user->addRole($rolename_a);
|
||||
$user->addRole($rolename_b);
|
||||
$user->save();
|
||||
|
||||
$this->drupalLogin($this->createUser(['access user profiles']));
|
||||
$this->drupalGet('/test-views-handler-field-role');
|
||||
$this->assertText($rolename_b . Html::escape('<em>' . $rolename_a . '</em>'), 'View test_views_handler_field_role renders role assigned to user in the correct order and markup in role names is escaped.');
|
||||
$this->assertNoText($rolename_not_assigned, 'View test_views_handler_field_role does not render a role not assigned to a user.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the handler of the user: name field.
|
||||
*
|
||||
* @group user
|
||||
* @see views_handler_field_user_name
|
||||
*/
|
||||
class HandlerFieldUserNameTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_views_handler_field_user_name'];
|
||||
|
||||
public function testUserName() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$new_user = $this->drupalCreateUser(['access user profiles']);
|
||||
$this->drupalLogin($new_user);
|
||||
|
||||
// Set defaults.
|
||||
$view = Views::getView('test_views_handler_field_user_name');
|
||||
$view->initHandlers();
|
||||
$view->field['name']->options['link_to_user'] = TRUE;
|
||||
$view->field['name']->options['type'] = 'user_name';
|
||||
$view->field['name']->init($view, $view->getDisplay('default'));
|
||||
$view->field['name']->options['id'] = 'name';
|
||||
$this->executeView($view);
|
||||
|
||||
$anon_name = $this->config('user.settings')->get('anonymous');
|
||||
$view->result[0]->_entity->setUsername('');
|
||||
$view->result[0]->_entity->uid->value = 0;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertTrue(strpos($render, $anon_name) !== FALSE, 'For user 0 it should use the default anonymous name by default.');
|
||||
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view, $new_user) {
|
||||
return $view->field['name']->advancedRender($view->result[$new_user->id()]);
|
||||
});
|
||||
$this->assertTrue(strpos($render, $new_user->getDisplayName()) !== FALSE, 'If link to user is checked the username should be part of the output.');
|
||||
$this->assertTrue(strpos($render, 'user/' . $new_user->id()) !== FALSE, 'If link to user is checked the link to the user should appear as well.');
|
||||
|
||||
$view->field['name']->options['link_to_user'] = FALSE;
|
||||
$view->field['name']->options['type'] = 'string';
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view, $new_user) {
|
||||
return $view->field['name']->advancedRender($view->result[$new_user->id()]);
|
||||
});
|
||||
$this->assertEqual($render, $new_user->getDisplayName(), 'If the user is not linked the username should be printed out for a normal user.');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the field handler works when no additional fields are added.
|
||||
*/
|
||||
public function testNoAdditionalFields() {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
$view = Views::getView('test_views_handler_field_user_name');
|
||||
$this->executeView($view);
|
||||
|
||||
$username = $this->randomMachineName();
|
||||
$view->result[0]->_entity->setUsername($username);
|
||||
$view->result[0]->_entity->uid->value = 1;
|
||||
$render = $renderer->executeInRenderContext(new RenderContext(), function () use ($view) {
|
||||
return $view->field['name']->advancedRender($view->result[0]);
|
||||
});
|
||||
$this->assertTrue(strpos($render, $username) !== FALSE, 'If link to user is checked the username should be part of the output.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\views\Views;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
|
||||
/**
|
||||
* Tests the handler of the user: name filter.
|
||||
*
|
||||
* @group user
|
||||
* @see Views\user\Plugin\views\filter\Name
|
||||
*/
|
||||
class HandlerFilterUserNameTest extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views_ui', 'user_test_views'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_user_name'];
|
||||
|
||||
/**
|
||||
* Accounts used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $accounts = [];
|
||||
|
||||
/**
|
||||
* Usernames of $accounts.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $names = [];
|
||||
|
||||
/**
|
||||
* Stores the column map for this testCase.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $columnMap = [
|
||||
'uid' => 'uid',
|
||||
];
|
||||
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['user_test_views']);
|
||||
|
||||
$this->enableViewsTestModule();
|
||||
|
||||
$this->accounts = [];
|
||||
$this->names = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$this->accounts[] = $account = $this->drupalCreateUser();
|
||||
$this->names[] = $account->label();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests just using the filter.
|
||||
*/
|
||||
public function testUserNameApi() {
|
||||
$view = Views::getView('test_user_name');
|
||||
|
||||
$view->initHandlers();
|
||||
$view->filter['uid']->value = [$this->accounts[0]->id()];
|
||||
|
||||
$this->executeView($view);
|
||||
$this->assertIdenticalResultset($view, [['uid' => $this->accounts[0]->id()]], $this->columnMap);
|
||||
|
||||
$this->assertEqual($view->filter['uid']->getValueOptions(), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using the user interface.
|
||||
*/
|
||||
public function testAdminUserInterface() {
|
||||
$admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$path = 'admin/structure/views/nojs/handler/test_user_name/default/filter/uid';
|
||||
$this->drupalGet($path);
|
||||
|
||||
// Pass in an invalid username, the validation should catch it.
|
||||
$users = [$this->randomMachineName()];
|
||||
$users = array_map('strtolower', $users);
|
||||
$edit = [
|
||||
'options[value]' => implode(', ', $users),
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Apply'));
|
||||
$this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
|
||||
|
||||
// Pass in an invalid username and a valid username.
|
||||
$random_name = $this->randomMachineName();
|
||||
$users = [$random_name, $this->names[0]];
|
||||
$users = array_map('strtolower', $users);
|
||||
$edit = [
|
||||
'options[value]' => implode(', ', $users),
|
||||
];
|
||||
$users = [$users[0]];
|
||||
$this->drupalPostForm($path, $edit, t('Apply'));
|
||||
$this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
|
||||
|
||||
// Pass in just valid usernames.
|
||||
$users = $this->names;
|
||||
$users = array_map('strtolower', $users);
|
||||
$edit = [
|
||||
'options[value]' => implode(', ', $users),
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Apply'));
|
||||
$this->assertNoRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests exposed filters.
|
||||
*/
|
||||
public function testExposedFilter() {
|
||||
$path = 'test_user_name';
|
||||
|
||||
$options = [];
|
||||
|
||||
// Pass in an invalid username, the validation should catch it.
|
||||
$users = [$this->randomMachineName()];
|
||||
$users = array_map('strtolower', $users);
|
||||
$options['query']['uid'] = implode(', ', $users);
|
||||
$this->drupalGet($path, $options);
|
||||
$this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
|
||||
|
||||
// Pass in an invalid target_id in for the entity_autocomplete value format.
|
||||
// There should be no errors, but all results should be returned as the
|
||||
// default value for the autocomplete will not match any users so should
|
||||
// be empty.
|
||||
$options['query']['uid'] = [['target_id' => 9999]];
|
||||
$this->drupalGet($path, $options);
|
||||
// The actual result should contain all of the user ids.
|
||||
foreach ($this->accounts as $account) {
|
||||
$this->assertRaw($account->id());
|
||||
}
|
||||
|
||||
// Pass in an invalid username and a valid username.
|
||||
$users = [$this->randomMachineName(), $this->names[0]];
|
||||
$users = array_map('strtolower', $users);
|
||||
$options['query']['uid'] = implode(', ', $users);
|
||||
$users = [$users[0]];
|
||||
|
||||
$this->drupalGet($path, $options);
|
||||
$this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)]));
|
||||
|
||||
// Pass in just valid usernames.
|
||||
$users = $this->names;
|
||||
$options['query']['uid'] = implode(', ', $users);
|
||||
|
||||
$this->drupalGet($path, $options);
|
||||
$this->assertNoRaw('Unable to find user');
|
||||
// The actual result should contain all of the user ids.
|
||||
foreach ($this->accounts as $account) {
|
||||
$this->assertRaw($account->id());
|
||||
}
|
||||
|
||||
// Pass in just valid user IDs in the entity_autocomplete target_id format.
|
||||
$options['query']['uid'] = array_map(function ($account) {
|
||||
return ['target_id' => $account->id()];
|
||||
}, $this->accounts);
|
||||
|
||||
$this->drupalGet($path, $options);
|
||||
$this->assertNoRaw('Unable to find user');
|
||||
// The actual result should contain all of the user ids.
|
||||
foreach ($this->accounts as $account) {
|
||||
$this->assertRaw($account->id());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the representative node relationship for users.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class RelationshipRepresentativeNodeTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_groupwise_user'];
|
||||
|
||||
/**
|
||||
* Tests the relationship.
|
||||
*/
|
||||
public function testRelationship() {
|
||||
$view = Views::getView('test_groupwise_user');
|
||||
$this->executeView($view);
|
||||
$map = ['node_field_data_users_field_data_nid' => 'nid', 'uid' => 'uid'];
|
||||
$expected_result = [
|
||||
[
|
||||
'uid' => $this->users[1]->id(),
|
||||
'nid' => $this->nodes[1]->id(),
|
||||
],
|
||||
[
|
||||
'uid' => $this->users[0]->id(),
|
||||
'nid' => $this->nodes[0]->id(),
|
||||
],
|
||||
];
|
||||
$this->assertIdenticalResultset($view, $expected_result, $map);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
/**
|
||||
* Tests the handler of the user: roles argument.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\argument\RolesRid
|
||||
*/
|
||||
class RolesRidArgumentTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_user_roles_rid'];
|
||||
|
||||
/**
|
||||
* Tests the generated title of a user: roles argument.
|
||||
*/
|
||||
public function testArgumentTitle() {
|
||||
$role_id = $this->createRole([], 'markup_role_name', '<em>Role name with markup</em>');
|
||||
$user = $this->createUser();
|
||||
$user->addRole($role_id);
|
||||
$user->save();
|
||||
|
||||
$this->drupalGet('/user_roles_rid_test/markup_role_name');
|
||||
$this->assertEscaped('<em>Role name with markup</em>');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
|
||||
/**
|
||||
* Tests the changed field.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserChangedTest extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views_ui', 'user_test_views'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_user_changed'];
|
||||
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['user_test_views']);
|
||||
|
||||
$this->enableViewsTestModule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests changed field.
|
||||
*/
|
||||
public function testChangedField() {
|
||||
$path = 'test_user_changed';
|
||||
|
||||
$options = [];
|
||||
|
||||
$this->drupalGet($path, $options);
|
||||
|
||||
$this->assertText(t('Updated date') . ': ' . date('Y-m-d', REQUEST_TIME));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the user data service field handler.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\user\Plugin\views\field\UserData
|
||||
*/
|
||||
class UserDataTest extends UserTestBase {
|
||||
|
||||
/**
|
||||
* Provides the user data service object.
|
||||
*
|
||||
* @var \Drupal\user\UserDataInterface
|
||||
*/
|
||||
protected $userData;
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_user_data'];
|
||||
|
||||
/**
|
||||
* Tests field handler.
|
||||
*/
|
||||
public function testDataField() {
|
||||
// But some random values into the user data service.
|
||||
$this->userData = $this->container->get('user.data');
|
||||
$random_value = $this->randomMachineName();
|
||||
$this->userData->set('views_test_config', $this->users[0]->id(), 'test_value_name', $random_value);
|
||||
|
||||
$view = Views::getView('test_user_data');
|
||||
$this->executeView($view);
|
||||
|
||||
$output = $view->field['data']->render($view->result[0]);
|
||||
$this->assertEqual($output, $random_value, 'A valid user data got rendered.');
|
||||
|
||||
$view->field['data']->options['data_name'] = $this->randomMachineName();
|
||||
$output = $view->field['data']->render($view->result[0]);
|
||||
$this->assertFalse($output, 'An invalid configuration does not return anything');
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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,46 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Functional\Views;
|
||||
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* @todo.
|
||||
*/
|
||||
abstract class UserTestBase extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user_test_views', 'node'];
|
||||
|
||||
/**
|
||||
* Users to use during this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $users = [];
|
||||
|
||||
/**
|
||||
* Nodes to use during this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $nodes = [];
|
||||
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['user_test_views']);
|
||||
|
||||
$this->users[] = $this->drupalCreateUser();
|
||||
$this->users[] = User::load(1);
|
||||
$this->nodes[] = $this->drupalCreateNode(['uid' => $this->users[0]->id()]);
|
||||
$this->nodes[] = $this->drupalCreateNode(['uid' => 1]);
|
||||
}
|
||||
|
||||
}
|
|
@ -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.'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\FunctionalJavascript;
|
||||
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Ensure that password reset methods work as expected.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserPasswordResetTest extends WebDriverTestBase {
|
||||
|
||||
use AssertMailTrait {
|
||||
getMails as drupalGetMails;
|
||||
}
|
||||
|
||||
use TestFileCreationTrait {
|
||||
getTestFiles as drupalGetTestFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The profile to install as a basis for testing.
|
||||
*
|
||||
* This test uses the standard profile to test the password reset in
|
||||
* combination with an ajax request provided by the user picture configuration
|
||||
* in the standard profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'standard';
|
||||
|
||||
/**
|
||||
* The user object to test password resetting.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a user.
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
// Activate user by logging in.
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$this->account = User::load($account->id());
|
||||
$this->account->pass_raw = $account->pass_raw;
|
||||
$this->drupalLogout();
|
||||
|
||||
// Set the last login time that is used to generate the one-time link so
|
||||
// that it is definitely over a second ago.
|
||||
$account->login = REQUEST_TIME - mt_rand(10, 100000);
|
||||
db_update('users_field_data')
|
||||
->fields(['login' => $account->getLastLoginTime()])
|
||||
->condition('uid', $account->id())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests password reset functionality with an AJAX form.
|
||||
*
|
||||
* Make sure the ajax request from uploading a user picture does not
|
||||
* invalidate the reset token.
|
||||
*/
|
||||
public function testUserPasswordResetWithAdditionalAjaxForm() {
|
||||
$this->drupalGet(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()]));
|
||||
|
||||
// Try to reset the password for an invalid account.
|
||||
$this->drupalGet('user/password');
|
||||
|
||||
// Reset the password by username via the password reset page.
|
||||
$edit['name'] = $this->account->getUsername();
|
||||
$this->drupalPostForm(NULL, $edit, t('Submit'));
|
||||
|
||||
$resetURL = $this->getResetURL();
|
||||
$this->drupalGet($resetURL);
|
||||
|
||||
// Login
|
||||
$this->drupalPostForm(NULL, NULL, t('Log in'));
|
||||
|
||||
// Generate file.
|
||||
$image_file = current($this->drupalGetTestFiles('image'));
|
||||
$image_path = \Drupal::service('file_system')->realpath($image_file->uri);
|
||||
|
||||
// Upload file.
|
||||
$this->getSession()->getPage()->attachFileToField('Picture', $image_path);
|
||||
$this->assertSession()->waitForButton('Remove');
|
||||
|
||||
// Change the forgotten password.
|
||||
$password = user_password();
|
||||
$edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
// Verify that the password reset session has been destroyed.
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
// Password needed to make profile changes.
|
||||
$this->assertSession()->pageTextContains("Your current password is missing or incorrect; it's required to change the Password.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves password reset email and extracts the login link.
|
||||
*/
|
||||
public function getResetURL() {
|
||||
// Assume the most recent email.
|
||||
$_emails = $this->drupalGetMails();
|
||||
$email = end($_emails);
|
||||
$urls = [];
|
||||
preg_match('#.+user/reset/.+#', $email['body'], $urls);
|
||||
|
||||
return $urls[0];
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
namespace Drupal\Tests\user\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\comment\Entity\CommentType;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\Tests\migrate\Kernel\NodeCommentCombinationTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
@ -18,16 +17,21 @@ use Drupal\user\UserInterface;
|
|||
*/
|
||||
class MigrateUserTest extends MigrateDrupal7TestBase {
|
||||
|
||||
use NodeCommentCombinationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'comment',
|
||||
'content_translation',
|
||||
'datetime',
|
||||
'file',
|
||||
'image',
|
||||
'language',
|
||||
'link',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
'node',
|
||||
'system',
|
||||
'taxonomy',
|
||||
|
@ -43,12 +47,15 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
|
|||
|
||||
// Prepare to migrate user pictures as well.
|
||||
$this->installEntitySchema('file');
|
||||
$this->createType('page');
|
||||
$this->createType('article');
|
||||
$this->createType('blog');
|
||||
$this->createType('book');
|
||||
$this->createType('forum');
|
||||
$this->createType('test_content_type');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->createNodeCommentCombination('page');
|
||||
$this->createNodeCommentCombination('article');
|
||||
$this->createNodeCommentCombination('blog');
|
||||
$this->createNodeCommentCombination('book');
|
||||
$this->createNodeCommentCombination('forum', 'comment_forum');
|
||||
$this->createNodeCommentCombination('test_content_type');
|
||||
Vocabulary::create(['vid' => 'test_vocabulary'])->save();
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
|
@ -58,28 +65,11 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
|
|||
'd7_field',
|
||||
'd7_field_instance',
|
||||
'd7_user',
|
||||
'd7_entity_translation_settings',
|
||||
'd7_user_entity_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node type with a corresponding comment type.
|
||||
*
|
||||
* @param string $id
|
||||
* The node type ID.
|
||||
*/
|
||||
protected function createType($id) {
|
||||
NodeType::create([
|
||||
'type' => $id,
|
||||
'label' => $this->randomString(),
|
||||
])->save();
|
||||
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_' . $id,
|
||||
'label' => $this->randomString(),
|
||||
'target_entity_type_id' => 'node',
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a user account.
|
||||
*
|
||||
|
@ -99,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
|
||||
|
@ -114,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);
|
||||
|
@ -133,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());
|
||||
|
@ -188,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;
|
||||
|
@ -212,6 +215,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
|
|||
$source->access,
|
||||
$source->login,
|
||||
$source->status,
|
||||
$entity_language,
|
||||
$source->language,
|
||||
$source->timezone,
|
||||
$source->init,
|
||||
|
@ -236,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',
|
||||
|
|
|
@ -12,7 +12,8 @@ use Drupal\Core\Database\Database;
|
|||
* Tests the temporary object storage system.
|
||||
*
|
||||
* @group user
|
||||
* @see \Drupal\Core\TempStore\TempStore.
|
||||
* @group legacy
|
||||
* @see \Drupal\user\SharedTempStore
|
||||
*/
|
||||
class TempStoreDatabaseTest extends KernelTestBase {
|
||||
|
||||
|
@ -67,6 +68,9 @@ class TempStoreDatabaseTest extends KernelTestBase {
|
|||
|
||||
/**
|
||||
* Tests the UserTempStore API.
|
||||
*
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStoreFactory is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStoreFactory instead. See https://www.drupal.org/node/2935639.
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testUserTempStore() {
|
||||
// Create a key/value collection.
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Kernel;
|
||||
|
||||
use Drupal\KernelTests\ConfigFormTestBase;
|
||||
use Drupal\user\AccountSettingsForm;
|
||||
|
||||
/**
|
||||
* Configuration object user.mail and user.settings save test.
|
||||
*
|
||||
* @group user
|
||||
*/
|
||||
class UserAdminSettingsFormTest extends ConfigFormTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['user', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->form = AccountSettingsForm::create($this->container);
|
||||
$this->values = [
|
||||
'anonymous' => [
|
||||
'#value' => $this->randomString(10),
|
||||
'#config_name' => 'user.settings',
|
||||
'#config_key' => 'anonymous',
|
||||
],
|
||||
'user_mail_cancel_confirm_body' => [
|
||||
'#value' => $this->randomString(),
|
||||
'#config_name' => 'user.mail',
|
||||
'#config_key' => 'cancel_confirm.body',
|
||||
],
|
||||
'user_mail_cancel_confirm_subject' => [
|
||||
'#value' => $this->randomString(20),
|
||||
'#config_name' => 'user.mail',
|
||||
'#config_key' => 'cancel_confirm.subject',
|
||||
],
|
||||
'register_pending_approval_admin_body' => [
|
||||
'#value' => $this->randomString(),
|
||||
'#config_name' => 'user.mail',
|
||||
'#config_key' => 'register_pending_approval_admin.body',
|
||||
],
|
||||
'register_pending_approval_admin_subject' => [
|
||||
'#value' => $this->randomString(20),
|
||||
'#config_name' => 'user.mail',
|
||||
'#config_key' => 'register_pending_approval_admin.subject',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace Drupal\Tests\user\Kernel;
|
||||
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Drupal\user\Entity\Role;
|
||||
|
||||
/**
|
||||
|
@ -77,7 +77,6 @@ class UserEntityReferenceTest extends EntityKernelTestBase {
|
|||
$user3->addRole($this->role2->id());
|
||||
$user3->save();
|
||||
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityAutocompleteMatcher $autocomplete */
|
||||
$autocomplete = \Drupal::service('entity.autocomplete_matcher');
|
||||
|
||||
|
|
|
@ -21,6 +21,14 @@ class UserEntityTest extends KernelTestBase {
|
|||
*/
|
||||
public static $modules = ['system', 'user', 'field'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests some of the methods.
|
||||
*
|
||||
|
@ -65,4 +73,22 @@ class UserEntityTest extends KernelTestBase {
|
|||
$this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_two'], $user->getRoles());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that all user fields validate properly.
|
||||
*
|
||||
* @see \Drupal\Core\Field\FieldItemListInterface::generateSampleItems
|
||||
* @see \Drupal\Core\Field\FieldItemInterface::generateSampleValue()
|
||||
* @see \Drupal\Core\Entity\FieldableEntityInterface::validate()
|
||||
*/
|
||||
public function testUserValidation() {
|
||||
$user = User::create([]);
|
||||
foreach ($user as $field_name => $field) {
|
||||
if (!in_array($field_name, ['uid'])) {
|
||||
$user->$field_name->generateSampleItems();
|
||||
}
|
||||
}
|
||||
$violations = $user->validate();
|
||||
$this->assertFalse((bool) $violations->count());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ class UserInstallTest extends KernelTestBase {
|
|||
user_install();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test that the initial users have correct values.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Kernel;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests \Drupal\user\UserServiceProvider.
|
||||
*
|
||||
* @group user
|
||||
* @group legacy
|
||||
*/
|
||||
class UserServiceProviderFallbackTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user'];
|
||||
|
||||
/**
|
||||
* Tests that user.tempstore.expire equals tempstore.expire if not customized.
|
||||
*/
|
||||
public function testUserServiceProvider() {
|
||||
$this->assertEquals(1000, $this->container->getParameter('user.tempstore.expire'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
$container->setParameter('tempstore.expire', 1000);
|
||||
parent::register($container);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Kernel;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests \Drupal\user\UserServiceProvider.
|
||||
*
|
||||
* @group user
|
||||
* @group legacy
|
||||
*/
|
||||
class UserServiceProviderTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['user'];
|
||||
|
||||
/**
|
||||
* Tests that tempstore.expire is set to user.tempstore.expire.
|
||||
*
|
||||
* @expectedDeprecation The container parameter "user.tempstore.expire" is deprecated. Use "tempstore.expire" instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testUserServiceProvider() {
|
||||
$this->assertEquals(1000, $this->container->getParameter('tempstore.expire'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
$container->setParameter('user.tempstore.expire', 1000);
|
||||
parent::register($container);
|
||||
}
|
||||
|
||||
}
|
|
@ -40,23 +40,29 @@ class UserValidationTest extends KernelTestBase {
|
|||
* Tests user name validation.
|
||||
*/
|
||||
public function testUsernames() {
|
||||
$test_cases = [ // '<username>' => array('<description>', 'assert<testName>'),
|
||||
$test_cases = [
|
||||
// '<username>' => ['<description>', 'assert<testName>'].
|
||||
'foo' => ['Valid username', 'assertNull'],
|
||||
'FOO' => ['Valid username', 'assertNull'],
|
||||
'Foo O\'Bar' => ['Valid username', 'assertNull'],
|
||||
'foo@bar' => ['Valid username', 'assertNull'],
|
||||
'foo@example.com' => ['Valid username', 'assertNull'],
|
||||
'foo@-example.com' => ['Valid username', 'assertNull'], // invalid domains are allowed in usernames
|
||||
// invalid domains are allowed in usernames.
|
||||
'foo@-example.com' => ['Valid username', 'assertNull'],
|
||||
'þòøÇߪř€' => ['Valid username', 'assertNull'],
|
||||
'foo+bar' => ['Valid username', 'assertNull'], // '+' symbol is allowed
|
||||
'ᚠᛇᚻ᛫ᛒᛦᚦ' => ['Valid UTF8 username', 'assertNull'], // runes
|
||||
// '+' symbol is allowed.
|
||||
'foo+bar' => ['Valid username', 'assertNull'],
|
||||
// runes.
|
||||
'ᚠᛇᚻ᛫ᛒᛦᚦ' => ['Valid UTF8 username', 'assertNull'],
|
||||
' foo' => ['Invalid username that starts with a space', 'assertNotNull'],
|
||||
'foo ' => ['Invalid username that ends with a space', 'assertNotNull'],
|
||||
'foo bar' => ['Invalid username that contains 2 spaces \' \'', 'assertNotNull'],
|
||||
'' => ['Invalid empty username', 'assertNotNull'],
|
||||
'foo/' => ['Invalid username containing invalid chars', 'assertNotNull'],
|
||||
'foo' . chr(0) . 'bar' => ['Invalid username containing chr(0)', 'assertNotNull'], // NULL
|
||||
'foo' . chr(13) . 'bar' => ['Invalid username containing chr(13)', 'assertNotNull'], // CR
|
||||
// NULL.
|
||||
'foo' . chr(0) . 'bar' => ['Invalid username containing chr(0)', 'assertNotNull'],
|
||||
// CR.
|
||||
'foo' . chr(13) . 'bar' => ['Invalid username containing chr(13)', 'assertNotNull'],
|
||||
str_repeat('x', USERNAME_MAX_LENGTH + 1) => ['Invalid excessively long username', 'assertNotNull'],
|
||||
];
|
||||
foreach ($test_cases as $name => $test_case) {
|
||||
|
@ -209,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.'));
|
||||
}
|
||||
|
||||
|
|
118
web/core/modules/user/tests/src/Kernel/WhosOnlineBlockTest.php
Normal file
118
web/core/modules/user/tests/src/Kernel/WhosOnlineBlockTest.php
Normal file
|
@ -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.');
|
||||
}
|
||||
|
||||
}
|
213
web/core/modules/user/tests/src/Traits/UserCreationTrait.php
Normal file
213
web/core/modules/user/tests/src/Traits/UserCreationTrait.php
Normal file
|
@ -0,0 +1,213 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\user\Traits;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Provides methods to create additional test users and switch the currently
|
||||
* logged in one.
|
||||
*
|
||||
* This trait is meant to be used only by test classes.
|
||||
*/
|
||||
trait UserCreationTrait {
|
||||
|
||||
/**
|
||||
* Switch the current logged in user.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user account object.
|
||||
*/
|
||||
protected function setCurrentUser(AccountInterface $account) {
|
||||
\Drupal::currentUser()->setAccount($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a user with a given set of permissions.
|
||||
*
|
||||
* @param array $permissions
|
||||
* Array of permission names to assign to user. Note that the user always
|
||||
* has the default permissions derived from the "authenticated users" role.
|
||||
* @param string $name
|
||||
* The user name.
|
||||
* @param bool $admin
|
||||
* (optional) Whether the user should be an administrator
|
||||
* with all the available permissions.
|
||||
*
|
||||
* @return \Drupal\user\Entity\User|false
|
||||
* A fully loaded user object with pass_raw property, or FALSE if account
|
||||
* creation fails.
|
||||
*/
|
||||
protected function createUser(array $permissions = [], $name = NULL, $admin = FALSE) {
|
||||
// Create a role with the given permission set, if any.
|
||||
$rid = FALSE;
|
||||
if ($permissions) {
|
||||
$rid = $this->createRole($permissions);
|
||||
if (!$rid) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a user assigned to that role.
|
||||
$edit = [];
|
||||
$edit['name'] = !empty($name) ? $name : $this->randomMachineName();
|
||||
$edit['mail'] = $edit['name'] . '@example.com';
|
||||
$edit['pass'] = user_password();
|
||||
$edit['status'] = 1;
|
||||
if ($rid) {
|
||||
$edit['roles'] = [$rid];
|
||||
}
|
||||
|
||||
if ($admin) {
|
||||
$edit['roles'][] = $this->createAdminRole();
|
||||
}
|
||||
|
||||
$account = User::create($edit);
|
||||
$account->save();
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
// Add the raw password so that we can log in as this user.
|
||||
$account->pass_raw = $edit['pass'];
|
||||
// Support BrowserTestBase as well.
|
||||
$account->passRaw = $account->pass_raw;
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an administrative role.
|
||||
*
|
||||
* @param string $rid
|
||||
* (optional) The role ID (machine name). Defaults to a random name.
|
||||
* @param string $name
|
||||
* (optional) The label for the role. Defaults to a random string.
|
||||
* @param int $weight
|
||||
* (optional) The weight for the role. Defaults NULL so that entity_create()
|
||||
* sets the weight to maximum + 1.
|
||||
*
|
||||
* @return string
|
||||
* Role ID of newly created role, or FALSE if role creation failed.
|
||||
*/
|
||||
protected function createAdminRole($rid = NULL, $name = NULL, $weight = NULL) {
|
||||
$rid = $this->createRole([], $rid, $name, $weight);
|
||||
if ($rid) {
|
||||
/** @var \Drupal\user\RoleInterface $role */
|
||||
$role = Role::load($rid);
|
||||
$role->setIsAdmin(TRUE);
|
||||
$role->save();
|
||||
}
|
||||
return $rid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a role with specified permissions.
|
||||
*
|
||||
* @param array $permissions
|
||||
* Array of permission names to assign to role.
|
||||
* @param string $rid
|
||||
* (optional) The role ID (machine name). Defaults to a random name.
|
||||
* @param string $name
|
||||
* (optional) The label for the role. Defaults to a random string.
|
||||
* @param int $weight
|
||||
* (optional) The weight for the role. Defaults NULL so that entity_create()
|
||||
* sets the weight to maximum + 1.
|
||||
*
|
||||
* @return string
|
||||
* Role ID of newly created role, or FALSE if role creation failed.
|
||||
*/
|
||||
protected function createRole(array $permissions, $rid = NULL, $name = NULL, $weight = NULL) {
|
||||
// Generate a random, lowercase machine name if none was passed.
|
||||
if (!isset($rid)) {
|
||||
$rid = strtolower($this->randomMachineName(8));
|
||||
}
|
||||
// Generate a random label.
|
||||
if (!isset($name)) {
|
||||
// In the role UI role names are trimmed and random string can start or
|
||||
// end with a space.
|
||||
$name = trim($this->randomString(8));
|
||||
}
|
||||
|
||||
// Check the all the permissions strings are valid.
|
||||
if (!$this->checkPermissions($permissions)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Create new role.
|
||||
$role = Role::create([
|
||||
'id' => $rid,
|
||||
'label' => $name,
|
||||
]);
|
||||
if (isset($weight)) {
|
||||
$role->set('weight', $weight);
|
||||
}
|
||||
$result = $role->save();
|
||||
|
||||
$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');
|
||||
|
||||
if ($result === SAVED_NEW) {
|
||||
// Grant the specified permissions to the role, if any.
|
||||
if (!empty($permissions)) {
|
||||
$this->grantPermissions($role, $permissions);
|
||||
$assigned_permissions = Role::load($role->id())->getPermissions();
|
||||
$missing_permissions = array_diff($permissions, $assigned_permissions);
|
||||
if (!$missing_permissions) {
|
||||
$this->pass(new FormattableMarkup('Created permissions: @perms', ['@perms' => implode(', ', $permissions)]), 'Role');
|
||||
}
|
||||
else {
|
||||
$this->fail(new FormattableMarkup('Failed to create permissions: @perms', ['@perms' => implode(', ', $missing_permissions)]), 'Role');
|
||||
}
|
||||
}
|
||||
return $role->id();
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given list of permission names is valid.
|
||||
*
|
||||
* @param array $permissions
|
||||
* The permission names to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the permissions are valid, FALSE otherwise.
|
||||
*/
|
||||
protected function checkPermissions(array $permissions) {
|
||||
$available = array_keys(\Drupal::service('user.permissions')->getPermissions());
|
||||
$valid = TRUE;
|
||||
foreach ($permissions as $permission) {
|
||||
if (!in_array($permission, $available)) {
|
||||
$this->fail(new FormattableMarkup('Invalid permission %permission.', ['%permission' => $permission]), 'Role');
|
||||
$valid = FALSE;
|
||||
}
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant permissions to a user role.
|
||||
*
|
||||
* @param \Drupal\user\RoleInterface $role
|
||||
* The ID of a user role to alter.
|
||||
* @param array $permissions
|
||||
* (optional) A list of permission names to grant.
|
||||
*/
|
||||
protected function grantPermissions(RoleInterface $role, array $permissions) {
|
||||
foreach ($permissions as $permission) {
|
||||
$role->grantPermission($permission);
|
||||
}
|
||||
$role->trustData()->save();
|
||||
}
|
||||
|
||||
}
|
|
@ -69,7 +69,9 @@ class UserLocalTasksTest extends LocalTaskIntegrationTestBase {
|
|||
$tasks = [
|
||||
0 => ['entity.user.canonical', 'entity.user.edit_form'],
|
||||
];
|
||||
if ($subtask) $tasks[] = $subtask;
|
||||
if ($subtask) {
|
||||
$tasks[] = $subtask;
|
||||
}
|
||||
$this->assertLocalTasks($route, $tasks);
|
||||
}
|
||||
|
||||
|
|
|
@ -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',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ class AddRoleUserTest extends RoleUserTestBase {
|
|||
->will($this->returnValue(TRUE));
|
||||
|
||||
$config = ['rid' => 'test_role_1'];
|
||||
$remove_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType);
|
||||
$add_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType);
|
||||
|
||||
$remove_role_plugin->execute($this->account);
|
||||
$add_role_plugin->execute($this->account);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,9 @@ class AddRoleUserTest extends RoleUserTestBase {
|
|||
->will($this->returnValue(FALSE));
|
||||
|
||||
$config = ['rid' => 'test_role_1'];
|
||||
$remove_role_plugin = new AddRoleUser($config, 'user_remove_role_action', ['type' => 'user'], $this->userRoleEntityType);
|
||||
$add_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType);
|
||||
|
||||
$remove_role_plugin->execute($this->account);
|
||||
$add_role_plugin->execute($this->account);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -11,6 +11,9 @@ use Symfony\Component\HttpFoundation\RequestStack;
|
|||
/**
|
||||
* @coversDefaultClass \Drupal\user\PrivateTempStore
|
||||
* @group user
|
||||
* @group legacy
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
class PrivateTempStoreTest extends UnitTestCase {
|
||||
|
||||
|
@ -93,11 +96,11 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
$this->otherObject->owner = 2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the get() method.
|
||||
*
|
||||
* @covers ::get
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testGet() {
|
||||
$this->keyValue->expects($this->at(0))
|
||||
|
@ -122,6 +125,7 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
* Tests the set() method with no lock available.
|
||||
*
|
||||
* @covers ::set
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSetWithNoLockAvailable() {
|
||||
$this->lock->expects($this->at(0))
|
||||
|
@ -147,6 +151,7 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
* Tests a successful set() call.
|
||||
*
|
||||
* @covers ::set
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSet() {
|
||||
$this->lock->expects($this->once())
|
||||
|
@ -170,6 +175,7 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
* Tests the getMetadata() method.
|
||||
*
|
||||
* @covers ::getMetadata
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testGetMetadata() {
|
||||
$this->keyValue->expects($this->at(0))
|
||||
|
@ -194,6 +200,7 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
* Tests the locking in the delete() method.
|
||||
*
|
||||
* @covers ::delete
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testDeleteLocking() {
|
||||
$this->keyValue->expects($this->once())
|
||||
|
@ -221,6 +228,7 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
* Tests the delete() method with no lock available.
|
||||
*
|
||||
* @covers ::delete
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testDeleteWithNoLockAvailable() {
|
||||
$this->keyValue->expects($this->once())
|
||||
|
@ -250,6 +258,7 @@ class PrivateTempStoreTest extends UnitTestCase {
|
|||
* Tests the delete() method.
|
||||
*
|
||||
* @covers ::delete
|
||||
* @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testDelete() {
|
||||
$this->lock->expects($this->once())
|
||||
|
|
|
@ -11,6 +11,9 @@ use Symfony\Component\HttpFoundation\RequestStack;
|
|||
/**
|
||||
* @coversDefaultClass \Drupal\user\SharedTempStore
|
||||
* @group user
|
||||
* @group legacy
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
class SharedTempStoreTest extends UnitTestCase {
|
||||
|
||||
|
@ -90,6 +93,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
|
||||
/**
|
||||
* @covers ::get
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testGet() {
|
||||
$this->keyValue->expects($this->at(0))
|
||||
|
@ -109,6 +113,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the getIfOwner() method.
|
||||
*
|
||||
* @covers ::getIfOwner
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testGetIfOwner() {
|
||||
$this->keyValue->expects($this->at(0))
|
||||
|
@ -133,6 +138,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the set() method with no lock available.
|
||||
*
|
||||
* @covers ::set
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSetWithNoLockAvailable() {
|
||||
$this->lock->expects($this->at(0))
|
||||
|
@ -158,6 +164,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests a successful set() call.
|
||||
*
|
||||
* @covers ::set
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSet() {
|
||||
$this->lock->expects($this->once())
|
||||
|
@ -181,6 +188,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the setIfNotExists() methods.
|
||||
*
|
||||
* @covers ::setIfNotExists
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSetIfNotExists() {
|
||||
$this->keyValue->expects($this->once())
|
||||
|
@ -195,6 +203,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the setIfOwner() method when no key exists.
|
||||
*
|
||||
* @covers ::setIfOwner
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSetIfOwnerWhenNotExists() {
|
||||
$this->keyValue->expects($this->once())
|
||||
|
@ -208,6 +217,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the setIfOwner() method when a key already exists but no object.
|
||||
*
|
||||
* @covers ::setIfOwner
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSetIfOwnerNoObject() {
|
||||
$this->keyValue->expects($this->once())
|
||||
|
@ -226,6 +236,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the setIfOwner() method with matching and non matching owners.
|
||||
*
|
||||
* @covers ::setIfOwner
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testSetIfOwner() {
|
||||
$this->lock->expects($this->once())
|
||||
|
@ -250,6 +261,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the getMetadata() method.
|
||||
*
|
||||
* @covers ::getMetadata
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testGetMetadata() {
|
||||
$this->keyValue->expects($this->at(0))
|
||||
|
@ -274,6 +286,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the delete() method.
|
||||
*
|
||||
* @covers ::delete
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testDelete() {
|
||||
$this->lock->expects($this->once())
|
||||
|
@ -297,6 +310,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the delete() method with no lock available.
|
||||
*
|
||||
* @covers ::delete
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testDeleteWithNoLockAvailable() {
|
||||
$this->lock->expects($this->at(0))
|
||||
|
@ -322,6 +336,7 @@ class SharedTempStoreTest extends UnitTestCase {
|
|||
* Tests the deleteIfOwner() method.
|
||||
*
|
||||
* @covers ::deleteIfOwner
|
||||
* @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
|
||||
*/
|
||||
public function testDeleteIfOwner() {
|
||||
$this->lock->expects($this->once())
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue