Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176

This commit is contained in:
Pantheon Automation 2015-08-17 17:00:26 -07:00 committed by Greg Anderson
commit 9921556621
13277 changed files with 1459781 additions and 0 deletions

View file

@ -0,0 +1,6 @@
name: 'User access tests'
type: module
description: 'Support module for user access testing.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,24 @@
<?php
/**
* @file
* Dummy module implementing hook_user_access() to test if entity access is respected.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\user\Entity\User;
/**
* Implements hook_ENTITY_TYPE_access() for entity type "user".
*/
function user_access_test_user_access(User $entity, $operation, $account) {
if ($entity->getUsername() == "no_edit" && $operation == "update") {
// Deny edit access.
return AccessResult::forbidden();
}
if ($entity->getUsername() == "no_delete" && $operation == "delete") {
// Deny delete access.
return AccessResult::forbidden();
}
return AccessResult::neutral();
}

View file

@ -0,0 +1,6 @@
name: 'User custom phpass params test'
type: module
description: 'Support module for testing custom phpass password algorithm parameters.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,4 @@
services:
password:
class: Drupal\Core\Password\PhpassHashedPassword
arguments: [19]

View file

@ -0,0 +1,6 @@
name: 'User module form tests'
type: module
description: 'Support module for user form testing.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,14 @@
<?php
/**
* @file
* Support module for user form testing.
*/
/**
* Implements hook_form_FORM_ID_alter() for user_cancel_form().
*/
function user_form_test_form_user_cancel_form_alter(&$form, &$form_state) {
$form['user_cancel_confirm']['#default_value'] = FALSE;
$form['access']['#value'] = \Drupal::currentUser()->hasPermission('cancel other accounts');
}

View file

@ -0,0 +1,2 @@
cancel other accounts:
title: 'Cancel other user accounts'

View file

@ -0,0 +1,7 @@
user_form_test.cancel:
path: '/user_form_test_cancel/{user}'
defaults:
_entity_form: 'user.cancel'
requirements:
_permission: 'cancel other accounts'

View file

@ -0,0 +1,34 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_access_perm
label: ''
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: perm
options:
perm: 'views_test_data test permission'
cache:
type: tag
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,45 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_access_role
label: ''
module: views
description: ''
tag: ''
base_table: views_test_data
base_field: nid
core: '8'
display:
default:
display_options:
fields:
id:
id: id
field: id
table: views_test_data
plugin_id: numeric
access:
type: role
cache:
type: tag
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0
page_1:
display_options:
path: test-role
display_plugin: page
display_title: Page
id: page_1
position: 1

View file

@ -0,0 +1,139 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_field_permission
label: null
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: null
display_options:
access:
type: none
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
uid:
id: uid
table: users_field_data
field: uid
relationship: none
group_type: group
admin_label: ''
label: Uid
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
plugin_id: field
entity_type: user
entity_field: uid
permission:
id: permission
table: user__roles
field: permission
relationship: none
group_type: group
admin_label: ''
label: Permission
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
type: separator
separator: ', '
plugin_id: user_permissions
filters: { }
sorts: { }

View file

@ -0,0 +1,142 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_filter_permission
label: null
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: null
display_options:
access:
type: none
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
uid:
id: uid
table: users
field: uid
relationship: none
group_type: group
admin_label: ''
label: ''
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: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_user: false
plugin_id: user
entity_type: user
entity_field: uid
filters:
permission:
id: permission
table: user__roles
field: permission
relationship: none
group_type: group
admin_label: ''
operator: or
value:
'access user profiles': 'access user profiles'
group: 1
exposed: false
expose:
operator_id: '0'
label: ''
description: ''
use_operator: false
operator: ''
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
reduce_duplicates: true
plugin_id: user_permissions
sorts:
uid:
id: uid
table: users_field_data
field: uid
relationship: none
group_type: group
admin_label: ''
order: ASC
exposed: false
expose:
label: ''
plugin_id: standard
entity_type: user
entity_field: uid

View file

@ -0,0 +1,93 @@
langcode: en
status: true
dependencies:
module:
- node
- user
id: test_groupwise_user
label: test_groupwise_user
module: views
description: ''
tag: default
base_table: users_field_data
base_field: uid
core: 8.0-dev
display:
default:
display_options:
access:
options:
perm: 'access user profiles'
type: perm
cache:
type: tag
exposed_form:
type: basic
fields:
name:
field: name
id: name
table: users_field_data
plugin_id: field
type: user_name
entity_type: user
entity_field: name
nid:
field: nid
id: nid
relationship: uid_representative
table: node_field_data
plugin_id: node
entity_type: node
entity_field: nid
filters:
status:
expose:
operator: '0'
field: status
group: 1
id: status
table: users_field_data
value: true
plugin_id: boolean
entity_type: user
entity_field: status
pager:
options:
items_per_page: 10
type: full
query:
type: views_query
relationships:
uid_representative:
admin_label: 'Representative node'
field: uid_representative
group_type: group
id: uid_representative
relationship: none
required: false
subquery_namespace: ''
subquery_order: DESC
subquery_regenerate: true
subquery_sort: node.nid
subquery_view: ''
table: users_field_data
plugin_id: groupwise_max
row:
type: fields
sorts:
created:
field: uid
id: uid
order: ASC
table: users_field_data
plugin_id: field
entity_type: user
entity_field: uid
style:
type: default
title: test_groupwise_user
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,63 @@
langcode: en
status: true
dependencies:
module:
- node
id: test_plugin_argument_default_current_user
label: ''
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
arguments:
'null':
default_action: default
default_argument_type: current_user
field: 'null'
id: 'null'
must_not_be: false
table: views
plugin_id: 'null'
cache:
type: tag
exposed_form:
type: basic
fields:
title:
alter:
alter_text: false
ellipsis: true
html: false
make_link: false
strip_tags: false
trim: false
word_boundary: true
empty_zero: false
field: title
hide_empty: false
id: title
table: node_field_data
plugin_id: field
entity_type: node
entity_field: title
pager:
options:
id: 0
items_per_page: 10
offset: 0
type: full
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,65 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_bulk_form
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: null
display_options:
style:
type: table
row:
type: fields
fields:
user_bulk_form:
id: user_bulk_form
table: users
field: user_bulk_form
plugin_id: user_bulk_form
entity_type: user
name:
id: name
table: users_field_data
field: name
plugin_id: field
type: user_name
entity_type: user
entity_field: name
sorts:
uid:
id: uid
table: users_field_data
field: uid
order: ASC
plugin_id: user
entity_type: user
entity_field: uid
filters:
status:
id: status
table: users_field_data
field: status
operator: '='
value: true
plugin_id: boolean
entity_type: user
entity_field: status
page_1:
display_plugin: page
id: page_1
display_title: Page
position: null
display_options:
path: test-user-bulk-form

View file

@ -0,0 +1,56 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_changed
label: ''
module: views
description: ''
tag: ''
base_table: users_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
cache:
type: tag
exposed_form:
type: basic
pager:
type: full
row:
type: fields
style:
type: default
fields:
name:
id: uid
table: users_field_data
field: uid
entity_type: user
entity_field: uid
changed:
id: changed
table: users_field_data
field: changed
label: 'Updated date'
date_format: html_date
plugin_id: date
entity_type: user
entity_field: changed
filters: { }
display_plugin: default
display_title: Master
id: default
position: 0
page_1:
display_options:
path: test_user_changed
display_plugin: page
display_title: Page
id: page_1
position: 0

View file

@ -0,0 +1,131 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_data
label: test_user_data
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: null
display_options:
access:
type: perm
options:
perm: 'access user profiles'
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
name:
id: name
table: users_field_data
field: name
label: ''
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
plugin_id: field
type: user_name
entity_type: user
entity_field: name
data:
id: data
table: users
field: data
relationship: none
group_type: group
admin_label: ''
label: Data
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
data_module: views_test_config
data_name: test_value_name
plugin_id: user_data
entity_type: user
filters:
uid:
value:
value: '2'
table: users_field_data
field: uid
id: uid
expose:
operator: '0'
group: 1
plugin_id: numeric
entity_type: user
entity_field: uid
sorts:
created:
id: created
table: users_field_data
field: created
order: DESC
plugin_id: date
entity_type: user
entity_field: created

View file

@ -0,0 +1,62 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_name
label: ''
module: views
description: ''
tag: ''
base_table: users_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
cache:
type: tag
exposed_form:
type: basic
pager:
type: full
row:
type: fields
style:
type: default
fields:
name:
id: uid
table: users_field_data
field: uid
entity_type: user
entity_field: uid
filters:
uid:
id: uid
table: users_field_data
field: uid
exposed: true
expose:
operator_id: uid_op
label: Name
operator: uid_op
identifier: uid
remember_roles:
authenticated: authenticated
anonymous: '0'
entity_type: user
entity_field: uid
display_plugin: default
display_title: Master
id: default
position: 0
page_1:
display_options:
path: test_user_name
display_plugin: page
display_title: Page
id: page_1
position: 0

View file

@ -0,0 +1,115 @@
langcode: en
status: true
dependencies:
module:
- node
- user
id: test_user_relationship
label: test_user_relationship
module: views
description: ''
tag: default
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: perm
cache:
type: tag
exposed_form:
type: basic
fields:
name:
alter:
absolute: false
alter_text: false
ellipsis: true
external: false
html: false
make_link: false
nl2br: false
replace_spaces: false
strip_tags: false
trim: false
trim_whitespace: false
word_boundary: true
element_default_classes: true
element_label_colon: true
empty_zero: false
field: name
hide_alter_empty: false
hide_empty: false
id: name
table: users_field_data
plugin_id: field
type: user_name
entity_type: user
entity_field: name
title:
alter:
absolute: false
alter_text: false
ellipsis: false
html: false
make_link: false
strip_tags: false
trim: false
word_boundary: false
empty_zero: false
field: title
hide_empty: false
id: title
label: ''
table: node_field_data
plugin_id: field
entity_type: node
entity_field: title
uid:
alter:
absolute: false
alter_text: false
ellipsis: true
external: false
html: false
make_link: false
nl2br: false
replace_spaces: false
strip_tags: false
trim: false
trim_whitespace: false
word_boundary: true
element_default_classes: true
element_label_colon: true
empty_zero: false
field: uid
hide_alter_empty: false
hide_empty: false
id: uid
table: users_field_data
plugin_id: field
type: user
entity_type: user
entity_field: uid
pager:
options:
items_per_page: 10
type: full
query:
options:
query_comment: ''
type: views_query
title: test_user_relationship
style:
type: default
row:
type: fields
options:
default_field_elements: true
hide_empty: false
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,38 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_user_uid_argument
label: null
module: views
description: ''
tag: ''
base_table: users_field_data
base_field: nid
core: '8'
display:
default:
display_options:
fields:
uid:
id: uid
table: users_field_data
field: uid
plugin_id: user
entity_type: user
entity_field: uid
arguments:
uid:
id: uid
table: users_field_data
field: uid
title_enable: true
title: '%1'
plugin_id: user_uid
entity_type: user
entity_field: uid
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,40 @@
langcode: en
status: true
dependencies: { }
id: test_view_argument_validate_user
label: ''
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
arguments:
'null':
default_argument_type: fixed
field: 'null'
id: 'null'
must_not_be: false
table: views
validate:
type: 'entity:user'
plugin_id: 'null'
cache:
type: tag
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,40 @@
langcode: en
status: true
dependencies: { }
id: test_view_argument_validate_username
label: ''
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
arguments:
'null':
default_argument_type: fixed
field: 'null'
id: 'null'
must_not_be: false
table: views
validate:
type: user_name
plugin_id: 'null'
cache:
type: tag
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,177 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_views_handler_field_role
label: test_views_handler_field_role
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: null
display_options:
access:
type: perm
options:
perm: 'access user profiles'
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: none
options:
items_per_page: null
style:
type: default
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: 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
plugin_id: field
type: user_name
entity_type: user
entity_field: name
roles_target_id:
id: roles_target_id
table: user__roles
field: roles_target_id
relationship: none
group_type: group
admin_label: ''
label: Roles
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
type: separator
separator: ''
plugin_id: user_roles
filters:
status:
value: true
table: users_field_data
field: status
id: status
expose:
operator: '0'
group: 1
plugin_id: boolean
entity_type: user
entity_field: status
sorts:
uid:
id: uid
table: users_field_data
field: uid
relationship: none
group_type: group
admin_label: ''
order: ASC
exposed: false
expose:
label: ''
entity_type: user
entity_field: uid
plugin_id: standard
title: test_user_role
page_1:
display_plugin: page
id: page_1
display_title: Page
position: null
display_options:
path: test-views-handler-field-role

View file

@ -0,0 +1,57 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_views_handler_field_user_name
label: test_views_handler_field_user_name
module: views
description: ''
tag: default
base_table: users_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
cache:
type: tag
exposed_form:
type: basic
fields:
name:
alter:
absolute: false
alter_text: false
ellipsis: false
html: false
make_link: false
strip_tags: false
trim: false
word_boundary: false
empty_zero: false
field: name
hide_empty: false
id: name
label: ''
table: users_field_data
plugin_id: field
type: user_name
entity_type: user
entity_field: name
pager:
type: full
query:
options:
query_comment: ''
type: views_query
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -0,0 +1,9 @@
name: 'User test views'
type: module
description: 'Provides default views for views user tests.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- user
- views

View file

@ -0,0 +1,91 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Menu\UserLocalTasksTest.
*/
namespace Drupal\Tests\user\Unit\Menu;
use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
/**
* Tests user local tasks.
*
* @group user
*/
class UserLocalTasksTest extends LocalTaskIntegrationTestBase {
protected function setUp() {
$this->directoryList = array('user' => 'core/modules/user');
parent::setUp();
}
/**
* Tests local task existence.
*
* @dataProvider getUserAdminRoutes
*/
public function testUserAdminLocalTasks($route, $expected) {
$this->assertLocalTasks($route, $expected);
}
/**
* Provides a list of routes to test.
*/
public function getUserAdminRoutes() {
return array(
array('entity.user.collection', array(array('entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection'))),
array('user.admin_permissions', array(array('entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection'))),
array('entity.user_role.collection', array(array('entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection'))),
array('entity.user.admin_form', array(array('user.account_settings_tab'))),
);
}
/**
* Checks user listing local tasks.
*
* @dataProvider getUserLoginRoutes
*/
public function testUserLoginLocalTasks($route) {
$tasks = array(
0 => array('user.register', 'user.pass', 'user.login',),
);
$this->assertLocalTasks($route, $tasks);
}
/**
* Provides a list of routes to test.
*/
public function getUserLoginRoutes() {
return array(
array('user.login'),
array('user.register'),
array('user.pass'),
);
}
/**
* Checks user listing local tasks.
*
* @dataProvider getUserPageRoutes
*/
public function testUserPageLocalTasks($route, $subtask = array()) {
$tasks = array(
0 => array('entity.user.canonical', 'entity.user.edit_form',),
);
if ($subtask) $tasks[] = $subtask;
$this->assertLocalTasks($route, $tasks);
}
/**
* Provides a list of routes to test.
*/
public function getUserPageRoutes() {
return array(
array('entity.user.canonical'),
array('entity.user.edit_form'),
);
}
}

View file

@ -0,0 +1,77 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\PermissionAccessCheckTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Core\Access\AccessResult;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Access\PermissionAccessCheck;
use Symfony\Component\Routing\Route;
/**
* @coversDefaultClass \Drupal\user\Access\PermissionAccessCheck
* @group Routing
* @group AccessF
*/
class PermissionAccessCheckTest extends UnitTestCase {
/**
* The tested access checker.
*
* @var \Drupal\user\Access\PermissionAccessCheck
*/
public $accessCheck;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->accessCheck = new PermissionAccessCheck();
}
/**
* Provides data for the testAccess method.
*
* @return array
*/
public function providerTestAccess() {
$allowed = AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions']);
$neutral = AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions']);
return [
[[], AccessResult::allowedIf(FALSE)],
[['_permission' => 'allowed'], $allowed],
[['_permission' => 'denied'], $neutral],
[['_permission' => 'allowed+denied'], $allowed],
[['_permission' => 'allowed+denied+other'], $allowed],
[['_permission' => 'allowed,denied'], $neutral],
];
}
/**
* Tests the access check method.
*
* @dataProvider providerTestAccess
* @covers ::access
*/
public function testAccess($requirements, $access) {
$user = $this->getMock('Drupal\Core\Session\AccountInterface');
$user->expects($this->any())
->method('hasPermission')
->will($this->returnValueMap([
['allowed', TRUE],
['denied', FALSE],
['other', FALSE]
]
));
$route = new Route('', [], $requirements);
$this->assertEquals($access, $this->accessCheck->access($route, $user));
}
}

View file

@ -0,0 +1,403 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\PermissionHandlerTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Core\Extension\Extension;
use Drupal\Tests\UnitTestCase;
use Drupal\user\PermissionHandler;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
use org\bovigo\vfs\vfsStreamWrapper;
/**
* Tests the permission handler.
*
* @group user
*
* @coversDefaultClass \Drupal\user\PermissionHandler
*/
class PermissionHandlerTest extends UnitTestCase {
/**
* The tested permission handler.
*
* @var \Drupal\Tests\user\Unit\TestPermissionHandler|\Drupal\user\PermissionHandler
*/
protected $permissionHandler;
/**
* The mocked module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $moduleHandler;
/**
* The mocked string translation.
*
* @var \Drupal\Core\StringTranslation\TranslationInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $stringTranslation;
/**
* The mocked controller resolver.
*
* @var \Drupal\Core\Controller\ControllerResolverInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $controllerResolver;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->stringTranslation = $this->getStringTranslationStub();
$this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
}
/**
* Provides an extension object for a given module with a human name.
*
* @param string $module
* The module machine name.
* @param string $name
* The module human name.
*
* @return \Drupal\Core\Extension\Extension
* The extension object.
*/
protected function mockModuleExtension($module, $name) {
$extension = new Extension($this->root, $module, "modules/$module");
$extension->info['name'] = $name;
return $extension;
}
/**
* Tests permissions provided by YML files.
*
* @covers ::__construct
* @covers ::getPermissions
* @covers ::buildPermissionsYaml
* @covers ::moduleProvidesPermissions
*/
public function testBuildPermissionsYaml() {
vfsStreamWrapper::register();
$root = new vfsStreamDirectory('modules');
vfsStreamWrapper::setRoot($root);
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->moduleHandler->expects($this->once())
->method('getModuleDirectories')
->willReturn(array(
'module_a' => vfsStream::url('modules/module_a'),
'module_b' => vfsStream::url('modules/module_b'),
'module_c' => vfsStream::url('modules/module_c'),
));
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"access_module_a: single_description"
);
mkdir($url . '/module_b');
file_put_contents($url . '/module_b/module_b.permissions.yml',
"'access module b':
title: 'Access B'
description: 'bla bla'
");
mkdir($url . '/module_c');
file_put_contents($url . '/module_c/module_c.permissions.yml',
"'access_module_c':
title: 'Access C'
description: 'bla bla'
'restrict access': TRUE
");
$modules = array('module_a', 'module_b', 'module_c');
$extensions = array(
'module_a' => $this->mockModuleExtension('module_a', 'Module a'),
'module_b' => $this->mockModuleExtension('module_b', 'Module b'),
'module_c' => $this->mockModuleExtension('module_c', 'Module c'),
);
$this->moduleHandler->expects($this->any())
->method('getImplementations')
->with('permission')
->willReturn(array());
$this->moduleHandler->expects($this->any())
->method('getModuleList')
->willReturn(array_flip($modules));
$this->controllerResolver->expects($this->never())
->method('getControllerFromDefinition');
$this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
// Setup system_rebuild_module_data().
$this->permissionHandler->setSystemRebuildModuleData($extensions);
$actual_permissions = $this->permissionHandler->getPermissions();
$this->assertPermissions($actual_permissions);
$this->assertTrue($this->permissionHandler->moduleProvidesPermissions('module_a'));
$this->assertTrue($this->permissionHandler->moduleProvidesPermissions('module_b'));
$this->assertTrue($this->permissionHandler->moduleProvidesPermissions('module_c'));
$this->assertFalse($this->permissionHandler->moduleProvidesPermissions('module_d'));
}
/**
* Tests permissions sort inside a module.
*
* @covers ::__construct
* @covers ::getPermissions
* @covers ::buildPermissionsYaml
* @covers ::sortPermissions
*/
public function testBuildPermissionsSortPerModule() {
vfsStreamWrapper::register();
$root = new vfsStreamDirectory('modules');
vfsStreamWrapper::setRoot($root);
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->moduleHandler->expects($this->once())
->method('getModuleDirectories')
->willReturn([
'module_a' => vfsStream::url('modules/module_a'),
]);
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"access_module_a2: single_description
access_module_a1: single_description"
);
$modules = ['module_a'];
$extensions = [
'module_a' => $this->mockModuleExtension('module_a', 'Module a'),
];
$this->moduleHandler->expects($this->any())
->method('getImplementations')
->with('permission')
->willReturn([]);
$this->moduleHandler->expects($this->any())
->method('getModuleList')
->willReturn(array_flip($modules));
$this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
// Setup system_rebuild_module_data().
$this->permissionHandler->setSystemRebuildModuleData($extensions);
$actual_permissions = $this->permissionHandler->getPermissions();
$this->assertEquals(['access_module_a1', 'access_module_a2'], array_keys($actual_permissions));
}
/**
* Tests dynamic callback permissions provided by YML files.
*
* @covers ::__construct
* @covers ::getPermissions
* @covers ::buildPermissionsYaml
*/
public function testBuildPermissionsYamlCallback() {
vfsStreamWrapper::register();
$root = new vfsStreamDirectory('modules');
vfsStreamWrapper::setRoot($root);
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->moduleHandler->expects($this->once())
->method('getModuleDirectories')
->willReturn(array(
'module_a' => vfsStream::url('modules/module_a'),
'module_b' => vfsStream::url('modules/module_b'),
'module_c' => vfsStream::url('modules/module_c'),
));
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::singleDescription'
");
mkdir($url . '/module_b');
file_put_contents($url . '/module_b/module_b.permissions.yml',
"permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription'
");
mkdir($url . '/module_c');
file_put_contents($url . '/module_c/module_c.permissions.yml',
"permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescriptionRestrictAccess'
");
$modules = array('module_a', 'module_b', 'module_c');
$extensions = array(
'module_a' => $this->mockModuleExtension('module_a', 'Module a'),
'module_b' => $this->mockModuleExtension('module_b', 'Module b'),
'module_c' => $this->mockModuleExtension('module_c', 'Module c'),
);
$this->moduleHandler->expects($this->any())
->method('getImplementations')
->with('permission')
->willReturn(array());
$this->moduleHandler->expects($this->any())
->method('getModuleList')
->willReturn(array_flip($modules));
$this->controllerResolver->expects($this->at(0))
->method('getControllerFromDefinition')
->with('Drupal\\user\\Tests\\TestPermissionCallbacks::singleDescription')
->willReturn(array(new TestPermissionCallbacks(), 'singleDescription'));
$this->controllerResolver->expects($this->at(1))
->method('getControllerFromDefinition')
->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription')
->willReturn(array(new TestPermissionCallbacks(), 'titleDescription'));
$this->controllerResolver->expects($this->at(2))
->method('getControllerFromDefinition')
->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescriptionRestrictAccess')
->willReturn(array(new TestPermissionCallbacks(), 'titleDescriptionRestrictAccess'));
$this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
// Setup system_rebuild_module_data().
$this->permissionHandler->setSystemRebuildModuleData($extensions);
$actual_permissions = $this->permissionHandler->getPermissions();
$this->assertPermissions($actual_permissions);
}
/**
* Tests a YAML file containing both static permissions and a callback.
*/
public function testPermissionsYamlStaticAndCallback() {
vfsStreamWrapper::register();
$root = new vfsStreamDirectory('modules');
vfsStreamWrapper::setRoot($root);
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->moduleHandler->expects($this->once())
->method('getModuleDirectories')
->willReturn(array(
'module_a' => vfsStream::url('modules/module_a'),
));
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"'access module a':
title: 'Access A'
description: 'bla bla'
permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription'
");
$modules = array('module_a');
$extensions = array(
'module_a' => $this->mockModuleExtension('module_a', 'Module a'),
);
$this->moduleHandler->expects($this->any())
->method('getImplementations')
->with('permission')
->willReturn(array());
$this->moduleHandler->expects($this->any())
->method('getModuleList')
->willReturn(array_flip($modules));
$this->controllerResolver->expects($this->once())
->method('getControllerFromDefinition')
->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription')
->willReturn(array(new TestPermissionCallbacks(), 'titleDescription'));
$this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
// Setup system_rebuild_module_data().
$this->permissionHandler->setSystemRebuildModuleData($extensions);
$actual_permissions = $this->permissionHandler->getPermissions();
$this->assertCount(2, $actual_permissions);
$this->assertEquals($actual_permissions['access module a']['title'], 'Access A');
$this->assertEquals($actual_permissions['access module a']['provider'], 'module_a');
$this->assertEquals($actual_permissions['access module a']['description'], 'bla bla');
$this->assertEquals($actual_permissions['access module b']['title'], 'Access B');
$this->assertEquals($actual_permissions['access module b']['provider'], 'module_a');
$this->assertEquals($actual_permissions['access module b']['description'], 'bla bla');
}
/**
* Checks that the permissions are like expected.
*
* @param array $actual_permissions
* The actual permissions
*/
protected function assertPermissions(array $actual_permissions) {
$this->assertCount(3, $actual_permissions);
$this->assertEquals($actual_permissions['access_module_a']['title'], 'single_description');
$this->assertEquals($actual_permissions['access_module_a']['provider'], 'module_a');
$this->assertEquals($actual_permissions['access module b']['title'], 'Access B');
$this->assertEquals($actual_permissions['access module b']['provider'], 'module_b');
$this->assertEquals($actual_permissions['access_module_c']['title'], 'Access C');
$this->assertEquals($actual_permissions['access_module_c']['provider'], 'module_c');
$this->assertEquals($actual_permissions['access_module_c']['restrict access'], TRUE);
}
}
class TestPermissionHandler extends PermissionHandler {
/**
* Test module data.
*
* @var array
*/
protected $systemModuleData;
protected function systemRebuildModuleData() {
return $this->systemModuleData;
}
public function setSystemRebuildModuleData(array $extensions) {
$this->systemModuleData = $extensions;
}
}
class TestPermissionCallbacks {
public function singleDescription() {
return array(
'access_module_a' => 'single_description'
);
}
public function titleDescription() {
return array(
'access module b' => array(
'title' => 'Access B',
'description' => 'bla bla',
),
);
}
public function titleDescriptionRestrictAccess() {
return array(
'access_module_c' => array(
'title' => 'Access C',
'description' => 'bla bla',
'restrict access' => TRUE,
),
);
}
}

View file

@ -0,0 +1,54 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\Action\AddRoleUserTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\Action;
use Drupal\user\Plugin\Action\AddRoleUser;
/**
* @coversDefaultClass \Drupal\user\Plugin\Action\AddRoleUser
* @group user
*/
class AddRoleUserTest extends RoleUserTestBase {
/**
* Tests the execute method on a user with a role.
*/
public function testExecuteAddExistingRole() {
$this->account->expects($this->never())
->method('addRole');
$this->account->expects($this->any())
->method('hasRole')
->with($this->equalTo('test_role_1'))
->will($this->returnValue(TRUE));
$config = array('rid' => 'test_role_1');
$remove_role_plugin = new AddRoleUser($config, 'user_add_role_action', array('type' => 'user'), $this->userRoleEntityType);
$remove_role_plugin->execute($this->account);
}
/**
* Tests the execute method on a user without a specific role.
*/
public function testExecuteAddNonExistingRole() {
$this->account->expects($this->once())
->method('addRole');
$this->account->expects($this->any())
->method('hasRole')
->with($this->equalTo('test_role_1'))
->will($this->returnValue(FALSE));
$config = array('rid' => 'test_role_1');
$remove_role_plugin = new AddRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType);
$remove_role_plugin->execute($this->account);
}
}

View file

@ -0,0 +1,54 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\Action\RemoveRoleUserTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\Action;
use Drupal\user\Plugin\Action\RemoveRoleUser;
/**
* @coversDefaultClass \Drupal\user\Plugin\Action\RemoveRoleUser
* @group user
*/
class RemoveRoleUserTest extends RoleUserTestBase {
/**
* Tests the execute method on a user with a role.
*/
public function testExecuteRemoveExistingRole() {
$this->account->expects($this->once())
->method('removeRole');
$this->account->expects($this->any())
->method('hasRole')
->with($this->equalTo('test_role_1'))
->will($this->returnValue(TRUE));
$config = array('rid' => 'test_role_1');
$remove_role_plugin = new RemoveRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType);
$remove_role_plugin->execute($this->account);
}
/**
* Tests the execute method on a user without a specific role.
*/
public function testExecuteRemoveNonExistingRole() {
$this->account->expects($this->never())
->method('removeRole');
$this->account->expects($this->any())
->method('hasRole')
->with($this->equalTo('test_role_1'))
->will($this->returnValue(FALSE));
$config = array('rid' => 'test_role_1');
$remove_role_plugin = new RemoveRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType);
$remove_role_plugin->execute($this->account);
}
}

View file

@ -0,0 +1,44 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\Action\RoleUserTestBase.
*/
namespace Drupal\Tests\user\Unit\Plugin\Action;
use Drupal\Tests\UnitTestCase;
/**
* Provides a base class for user role action tests.
*/
abstract class RoleUserTestBase extends UnitTestCase {
/**
* The mocked account.
*
* @var \Drupal\user\UserInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $account;
/**
* The user role entity type.
*
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $userRoleEntityType;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->account = $this
->getMockBuilder('Drupal\user\Entity\User')
->disableOriginalConstructor()
->getMock();
$this->userRoleEntityType = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
}
}

View file

@ -0,0 +1,63 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\Core\Entity\UserTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\Core\Entity;
use Drupal\Tests\Core\Session\UserSessionTest;
use Drupal\user\Entity\User;
use Drupal\user\RoleInterface;
/**
* @coversDefaultClass \Drupal\user\Entity\User
* @group user
*/
class UserTest extends UserSessionTest {
/**
* {@inheritdoc}
*/
protected function createUserSession(array $rids = array(), $authenticated = FALSE) {
$user = $this->getMockBuilder('Drupal\user\Entity\User')
->disableOriginalConstructor()
->setMethods(array('get', 'id'))
->getMock();
$user->expects($this->any())
->method('id')
// @todo Also test the uid = 1 handling.
->will($this->returnValue($authenticated ? 2 : 0));
$roles = array();
foreach ($rids as $rid) {
$roles[] = (object) array(
'target_id' => $rid,
);
}
$user->expects($this->any())
->method('get')
->with('roles')
->will($this->returnValue($roles));
return $user;
}
/**
* Tests the method getRoles exclude or include locked roles based in param.
*
* @see \Drupal\user\Entity\User::getRoles()
* @covers ::getRoles
*/
public function testUserGetRoles() {
// Anonymous user.
$user = $this->createUserSession(array());
$this->assertEquals(array(RoleInterface::ANONYMOUS_ID), $user->getRoles());
$this->assertEquals(array(), $user->getRoles(TRUE));
// Authenticated user.
$user = $this->createUserSession(array(), TRUE);
$this->assertEquals(array(RoleInterface::AUTHENTICATED_ID), $user->getRoles());
$this->assertEquals(array(), $user->getRoles(TRUE));
}
}

View file

@ -0,0 +1,314 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\Validation\Constraint\ProtectedUserFieldConstraintValidatorTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\Validation\Constraint;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraint;
use Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraintValidator;
/**
* @coversDefaultClass \Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraintValidator
* @group user
*/
class ProtectedUserFieldConstraintValidatorTest extends UnitTestCase {
/**
* {@inheritdoc}
*/
protected function createValidator() {
// Setup mocks that don't need to change.
$unchanged_field = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$unchanged_field->expects($this->any())
->method('getValue')
->willReturn('unchanged-value');
$unchanged_account = $this->getMock('Drupal\user\UserInterface');
$unchanged_account->expects($this->any())
->method('get')
->willReturn($unchanged_field);
$user_storage = $this->getMock('Drupal\user\UserStorageInterface');
$user_storage->expects($this->any())
->method('loadUnchanged')
->willReturn($unchanged_account);
$current_user = $this->getMock('Drupal\Core\Session\AccountProxyInterface');
$current_user->expects($this->any())
->method('id')
->willReturn('current-user');
return new ProtectedUserFieldConstraintValidator($user_storage, $current_user);
}
/**
* @covers ::validate
*
* @dataProvider providerTestValidate
*/
public function testValidate($items, $expected_violation, $name = FALSE) {
$constraint = new ProtectedUserFieldConstraint();
// If a violation is expected, then the context's addViolation method will
// be called, otherwise it should not be called.
$context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface');
if ($expected_violation) {
$context->expects($this->once())
->method('addViolation')
->with($constraint->message, array('%name' => $name));
}
else {
$context->expects($this->never())
->method('addViolation');
}
$validator = $this->createValidator();
$validator->initialize($context);
$validator->validate($items, $constraint);
}
/**
* Data provider for ::testValidate().
*/
public function providerTestValidate() {
$cases = [];
// Case 1: Validation context should not be touched if no items are passed.
$cases[] = [NULL, FALSE];
// Case 2: Empty user should be ignored.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn(NULL);
$cases[] = [$items, FALSE];
// Case 3: Account flagged to skip protected user should be ignored.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$account = $this->getMock('Drupal\user\UserInterface');
$account->_skipProtectedUserFieldConstraint = TRUE;
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$cases[] = [$items, FALSE];
// Case 4: New user should be ignored.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(TRUE);
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$cases[] = [$items, FALSE];
// Case 5: Mismatching user IDs should also be ignored.
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->once())
->method('id')
->willReturn('not-current-user');
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$cases[] = [$items, FALSE];
// Case 6: Non-password fields that have not changed should be ignored.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->exactly(2))
->method('getName')
->willReturn('field_not_password');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->exactly(2))
->method('id')
->willReturn('current-user');
$account->expects($this->never())
->method('checkExistingPassword');
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$items->expects($this->once())
->method('getValue')
->willReturn('unchanged-value');
$cases[] = [$items, FALSE];
// Case 7: Password field with no value set should be ignored.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->once())
->method('getName')
->willReturn('pass');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->exactly(2))
->method('id')
->willReturn('current-user');
$account->expects($this->never())
->method('checkExistingPassword');
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$cases[] = [$items, FALSE];
// Case 8: Non-password field changed, but user has passed provided current
// password.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->exactly(2))
->method('getName')
->willReturn('field_not_password');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->exactly(2))
->method('id')
->willReturn('current-user');
$account->expects($this->once())
->method('checkExistingPassword')
->willReturn(TRUE);
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$items->expects($this->once())
->method('getValue')
->willReturn('changed-value');
$cases[] = [$items, FALSE];
// Case 9: Password field changed, current password confirmed.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->exactly(2))
->method('getName')
->willReturn('pass');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->exactly(2))
->method('id')
->willReturn('current-user');
$account->expects($this->once())
->method('checkExistingPassword')
->willReturn(TRUE);
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$items->expects($this->any())
->method('getValue')
->willReturn('changed-value');
$items->expects($this->once())
->method('__get')
->with('value')
->willReturn('changed-value');
$cases[] = [$items, FALSE];
// The below calls should result in a violation.
// Case 10: Password field changed, current password not confirmed.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->exactly(2))
->method('getName')
->willReturn('pass');
$field_definition->expects($this->any())
->method('getLabel')
->willReturn('Password');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->exactly(2))
->method('id')
->willReturn('current-user');
$account->expects($this->once())
->method('checkExistingPassword')
->willReturn(FALSE);
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$items->expects($this->once())
->method('getValue')
->willReturn('changed-value');
$items->expects($this->once())
->method('__get')
->with('value')
->willReturn('changed-value');
$cases[] = [$items, TRUE, 'Password'];
// Case 11: Non-password field changed, current password not confirmed.
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->exactly(2))
->method('getName')
->willReturn('field_not_password');
$field_definition->expects($this->any())
->method('getLabel')
->willReturn('Protected field');
$account = $this->getMock('Drupal\user\UserInterface');
$account->expects($this->once())
->method('isNew')
->willReturn(FALSE);
$account->expects($this->exactly(2))
->method('id')
->willReturn('current-user');
$account->expects($this->once())
->method('checkExistingPassword')
->willReturn(FALSE);
$items = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
$items->expects($this->once())
->method('getFieldDefinition')
->willReturn($field_definition);
$items->expects($this->once())
->method('getEntity')
->willReturn($account);
$items->expects($this->once())
->method('getValue')
->willReturn('changed-value');
$cases[] = [$items, TRUE, 'Protected field'];
return $cases;
}
}

View file

@ -0,0 +1,98 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Plugin\views\field\UserBulkFormTest.
*/
namespace Drupal\Tests\user\Unit\Plugin\views\field;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Plugin\views\field\UserBulkForm;
/**
* @coversDefaultClass \Drupal\user\Plugin\views\field\UserBulkForm
* @group user
*/
class UserBulkFormTest extends UnitTestCase {
/**
* {@inheritdoc}
*/
protected function tearDown() {
parent::tearDown();
$container = new ContainerBuilder();
\Drupal::setContainer($container);
}
/**
* Tests the constructor assignment of actions.
*/
public function testConstructor() {
$actions = array();
for ($i = 1; $i <= 2; $i++) {
$action = $this->getMock('\Drupal\system\ActionConfigEntityInterface');
$action->expects($this->any())
->method('getType')
->will($this->returnValue('user'));
$actions[$i] = $action;
}
$action = $this->getMock('\Drupal\system\ActionConfigEntityInterface');
$action->expects($this->any())
->method('getType')
->will($this->returnValue('node'));
$actions[] = $action;
$entity_storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
$entity_storage->expects($this->any())
->method('loadMultiple')
->will($this->returnValue($actions));
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$entity_manager->expects($this->once())
->method('getStorage')
->with('action')
->will($this->returnValue($entity_storage));
$language_manager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
$views_data = $this->getMockBuilder('Drupal\views\ViewsData')
->disableOriginalConstructor()
->getMock();
$views_data->expects($this->any())
->method('get')
->with('users')
->will($this->returnValue(array('table' => array('entity type' => 'user'))));
$container = new ContainerBuilder();
$container->set('views.views_data', $views_data);
$container->set('string_translation', $this->getStringTranslationStub());
\Drupal::setContainer($container);
$storage = $this->getMock('Drupal\views\ViewEntityInterface');
$storage->expects($this->any())
->method('get')
->with('base_table')
->will($this->returnValue('users'));
$executable = $this->getMockBuilder('Drupal\views\ViewExecutable')
->disableOriginalConstructor()
->getMock();
$executable->storage = $storage;
$display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
->disableOriginalConstructor()
->getMock();
$definition['title'] = '';
$options = array();
$user_bulk_form = new UserBulkForm(array(), 'user_bulk_form', $definition, $entity_manager, $language_manager);
$user_bulk_form->init($executable, $display, $options);
$this->assertAttributeEquals(array_slice($actions, 0, -1, TRUE), 'actions', $user_bulk_form);
}
}

View file

@ -0,0 +1,286 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\PrivateTempStoreTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Tests\UnitTestCase;
use Drupal\user\PrivateTempStore;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* @coversDefaultClass \Drupal\user\PrivateTempStore
* @group user
*/
class PrivateTempStoreTest extends UnitTestCase {
/**
* The mock key value expirable backend.
*
* @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $keyValue;
/**
* The mock lock backend.
*
* @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $lock;
/**
* The user temp store.
*
* @var \Drupal\user\PrivateTempStore
*/
protected $tempStore;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $currentUser;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* A tempstore object belonging to the owner.
*
* @var \stdClass
*/
protected $ownObject;
/**
* A tempstore object not belonging to the owner.
*
* @var \stdClass
*/
protected $otherObject;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->keyValue = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
$this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
$this->currentUser = $this->getMock('Drupal\Core\Session\AccountProxyInterface');
$this->currentUser->expects($this->any())
->method('id')
->willReturn(1);
$this->requestStack = new RequestStack();
$request = Request::createFromGlobals();
$this->requestStack->push($request);
$this->tempStore = new PrivateTempStore($this->keyValue, $this->lock, $this->currentUser, $this->requestStack, 604800);
$this->ownObject = (object) array(
'data' => 'test_data',
'owner' => $this->currentUser->id(),
'updated' => (int) $request->server->get('REQUEST_TIME'),
);
// Clone the object but change the owner.
$this->otherObject = clone $this->ownObject;
$this->otherObject->owner = 2;
}
/**
* Tests the get() method.
*
* @covers ::get
*/
public function testGet() {
$this->keyValue->expects($this->at(0))
->method('get')
->with('1:test_2')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->at(1))
->method('get')
->with('1:test')
->will($this->returnValue($this->ownObject));
$this->keyValue->expects($this->at(2))
->method('get')
->with('1:test')
->will($this->returnValue($this->otherObject));
$this->assertNull($this->tempStore->get('test_2'));
$this->assertSame($this->ownObject->data, $this->tempStore->get('test'));
$this->assertNull($this->tempStore->get('test'));
}
/**
* Tests the set() method with no lock available.
*
* @covers ::set
* @expectedException \Drupal\user\TempStoreException
*/
public function testSetWithNoLockAvailable() {
$this->lock->expects($this->at(0))
->method('acquire')
->with('1:test')
->will($this->returnValue(FALSE));
$this->lock->expects($this->at(1))
->method('wait')
->with('1:test');
$this->lock->expects($this->at(2))
->method('acquire')
->with('1:test')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->once())
->method('getCollectionName');
$this->tempStore->set('test', 'value');
}
/**
* Tests a successful set() call.
*
* @covers ::set
*/
public function testSet() {
$this->lock->expects($this->once())
->method('acquire')
->with('1:test')
->will($this->returnValue(TRUE));
$this->lock->expects($this->never())
->method('wait');
$this->lock->expects($this->once())
->method('release')
->with('1:test');
$this->keyValue->expects($this->once())
->method('setWithExpire')
->with('1:test', $this->ownObject, 604800);
$this->tempStore->set('test', 'test_data');
}
/**
* Tests the getMetadata() method.
*
* @covers ::getMetadata
*/
public function testGetMetadata() {
$this->keyValue->expects($this->at(0))
->method('get')
->with('1:test')
->will($this->returnValue($this->ownObject));
$this->keyValue->expects($this->at(1))
->method('get')
->with('1:test')
->will($this->returnValue(FALSE));
$metadata = $this->tempStore->getMetadata('test');
$this->assertObjectHasAttribute('owner', $metadata);
// Data should get removed.
$this->assertObjectNotHasAttribute('data', $metadata);
$this->assertNull($this->tempStore->getMetadata('test'));
}
/**
* Tests the locking in the delete() method.
*
* @covers ::delete
*/
public function testDeleteLocking() {
$this->keyValue->expects($this->once())
->method('get')
->with('1:test')
->will($this->returnValue($this->ownObject));
$this->lock->expects($this->once())
->method('acquire')
->with('1:test')
->will($this->returnValue(TRUE));
$this->lock->expects($this->never())
->method('wait');
$this->lock->expects($this->once())
->method('release')
->with('1:test');
$this->keyValue->expects($this->once())
->method('delete')
->with('1:test');
$this->assertTrue($this->tempStore->delete('test'));
}
/**
* Tests the delete() method with no lock available.
*
* @covers ::delete
* @expectedException \Drupal\user\TempStoreException
*/
public function testDeleteWithNoLockAvailable() {
$this->keyValue->expects($this->once())
->method('get')
->with('1:test')
->will($this->returnValue($this->ownObject));
$this->lock->expects($this->at(0))
->method('acquire')
->with('1:test')
->will($this->returnValue(FALSE));
$this->lock->expects($this->at(1))
->method('wait')
->with('1:test');
$this->lock->expects($this->at(2))
->method('acquire')
->with('1:test')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->once())
->method('getCollectionName');
$this->tempStore->delete('test');
}
/**
* Tests the delete() method.
*
* @covers ::delete
*/
public function testDelete() {
$this->lock->expects($this->once())
->method('acquire')
->with('1:test_2')
->will($this->returnValue(TRUE));
$this->keyValue->expects($this->at(0))
->method('get')
->with('1:test_1')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->at(1))
->method('get')
->with('1:test_2')
->will($this->returnValue($this->ownObject));
$this->keyValue->expects($this->at(2))
->method('delete')
->with('1:test_2');
$this->keyValue->expects($this->at(3))
->method('get')
->with('1:test_3')
->will($this->returnValue($this->otherObject));
$this->assertTrue($this->tempStore->delete('test_1'));
$this->assertTrue($this->tempStore->delete('test_2'));
$this->assertFalse($this->tempStore->delete('test_3'));
}
}

View file

@ -0,0 +1,358 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\SharedTempStoreTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Tests\UnitTestCase;
use Drupal\user\SharedTempStore;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* @coversDefaultClass \Drupal\user\SharedTempStore
* @group user
*/
class SharedTempStoreTest extends UnitTestCase {
/**
* The mock key value expirable backend.
*
* @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $keyValue;
/**
* The mock lock backend.
*
* @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $lock;
/**
* The user temp store.
*
* @var \Drupal\user\SharedTempStore
*/
protected $tempStore;
/**
* The owner used in this test.
*
* @var int
*/
protected $owner = 1;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* A tempstore object belonging to the owner.
*
* @var \stdClass
*/
protected $ownObject;
/**
* A tempstore object not belonging to the owner.
*
* @var \stdClass
*/
protected $otherObject;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->keyValue = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
$this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
$this->requestStack = new RequestStack();
$request = Request::createFromGlobals();
$this->requestStack->push($request);
$this->tempStore = new SharedTempStore($this->keyValue, $this->lock, $this->owner, $this->requestStack, 604800);
$this->ownObject = (object) array(
'data' => 'test_data',
'owner' => $this->owner,
'updated' => (int) $request->server->get('REQUEST_TIME'),
);
// Clone the object but change the owner.
$this->otherObject = clone $this->ownObject;
$this->otherObject->owner = 2;
}
/**
* @covers ::get
*/
public function testGet() {
$this->keyValue->expects($this->at(0))
->method('get')
->with('test_2')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->at(1))
->method('get')
->with('test')
->will($this->returnValue($this->ownObject));
$this->assertNull($this->tempStore->get('test_2'));
$this->assertSame($this->ownObject->data, $this->tempStore->get('test'));
}
/**
* Tests the getIfOwner() method.
*
* @covers ::getIfOwner
*/
public function testGetIfOwner() {
$this->keyValue->expects($this->at(0))
->method('get')
->with('test_2')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->at(1))
->method('get')
->with('test')
->will($this->returnValue($this->ownObject));
$this->keyValue->expects($this->at(2))
->method('get')
->with('test')
->will($this->returnValue($this->otherObject));
$this->assertNull($this->tempStore->getIfOwner('test_2'));
$this->assertSame($this->ownObject->data, $this->tempStore->getIfOwner('test'));
$this->assertNull($this->tempStore->getIfOwner('test'));
}
/**
* Tests the set() method with no lock available.
*
* @covers ::set
* @expectedException \Drupal\user\TempStoreException
*/
public function testSetWithNoLockAvailable() {
$this->lock->expects($this->at(0))
->method('acquire')
->with('test')
->will($this->returnValue(FALSE));
$this->lock->expects($this->at(1))
->method('wait')
->with('test');
$this->lock->expects($this->at(2))
->method('acquire')
->with('test')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->once())
->method('getCollectionName');
$this->tempStore->set('test', 'value');
}
/**
* Tests a successful set() call.
*
* @covers ::set
*/
public function testSet() {
$this->lock->expects($this->once())
->method('acquire')
->with('test')
->will($this->returnValue(TRUE));
$this->lock->expects($this->never())
->method('wait');
$this->lock->expects($this->once())
->method('release')
->with('test');
$this->keyValue->expects($this->once())
->method('setWithExpire')
->with('test', $this->ownObject, 604800);
$this->tempStore->set('test', 'test_data');
}
/**
* Tests the setIfNotExists() methods.
*
* @covers ::setIfNotExists
*/
public function testSetIfNotExists() {
$this->keyValue->expects($this->once())
->method('setWithExpireIfNotExists')
->with('test', $this->ownObject, 604800)
->will($this->returnValue(TRUE));
$this->assertTrue($this->tempStore->setIfNotExists('test', 'test_data'));
}
/**
* Tests the setIfOwner() method when no key exists.
*
* @covers ::setIfOwner
*/
public function testSetIfOwnerWhenNotExists() {
$this->keyValue->expects($this->once())
->method('setWithExpireIfNotExists')
->will($this->returnValue(TRUE));
$this->assertTrue($this->tempStore->setIfOwner('test', 'test_data'));
}
/**
* Tests the setIfOwner() method when a key already exists but no object.
*
* @covers ::setIfOwner
*/
public function testSetIfOwnerNoObject() {
$this->keyValue->expects($this->once())
->method('setWithExpireIfNotExists')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->once())
->method('get')
->with('test')
->will($this->returnValue(FALSE));
$this->assertFalse($this->tempStore->setIfOwner('test', 'test_data'));
}
/**
* Tests the setIfOwner() method with matching and non matching owners.
*
* @covers ::setIfOwner
*/
public function testSetIfOwner() {
$this->lock->expects($this->once())
->method('acquire')
->with('test')
->will($this->returnValue(TRUE));
$this->keyValue->expects($this->exactly(2))
->method('setWithExpireIfNotExists')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->exactly(2))
->method('get')
->with('test')
->will($this->onConsecutiveCalls($this->ownObject, $this->otherObject));
$this->assertTrue($this->tempStore->setIfOwner('test', 'test_data'));
$this->assertFalse($this->tempStore->setIfOwner('test', 'test_data'));
}
/**
* Tests the getMetadata() method.
*
* @covers ::getMetadata
*/
public function testGetMetadata() {
$this->keyValue->expects($this->at(0))
->method('get')
->with('test')
->will($this->returnValue($this->ownObject));
$this->keyValue->expects($this->at(1))
->method('get')
->with('test')
->will($this->returnValue(FALSE));
$metadata = $this->tempStore->getMetadata('test');
$this->assertObjectHasAttribute('owner', $metadata);
// Data should get removed.
$this->assertObjectNotHasAttribute('data', $metadata);
$this->assertNull($this->tempStore->getMetadata('test'));
}
/**
* Tests the delete() method.
*
* @covers ::delete
*/
public function testDelete() {
$this->lock->expects($this->once())
->method('acquire')
->with('test')
->will($this->returnValue(TRUE));
$this->lock->expects($this->never())
->method('wait');
$this->lock->expects($this->once())
->method('release')
->with('test');
$this->keyValue->expects($this->once())
->method('delete')
->with('test');
$this->tempStore->delete('test');
}
/**
* Tests the delete() method with no lock available.
*
* @covers ::delete
* @expectedException \Drupal\user\TempStoreException
*/
public function testDeleteWithNoLockAvailable() {
$this->lock->expects($this->at(0))
->method('acquire')
->with('test')
->will($this->returnValue(FALSE));
$this->lock->expects($this->at(1))
->method('wait')
->with('test');
$this->lock->expects($this->at(2))
->method('acquire')
->with('test')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->once())
->method('getCollectionName');
$this->tempStore->delete('test');
}
/**
* Tests the deleteIfOwner() method.
*
* @covers ::deleteIfOwner
*/
public function testDeleteIfOwner() {
$this->lock->expects($this->once())
->method('acquire')
->with('test_2')
->will($this->returnValue(TRUE));
$this->keyValue->expects($this->at(0))
->method('get')
->with('test_1')
->will($this->returnValue(FALSE));
$this->keyValue->expects($this->at(1))
->method('get')
->with('test_2')
->will($this->returnValue($this->ownObject));
$this->keyValue->expects($this->at(2))
->method('delete')
->with('test_2');
$this->keyValue->expects($this->at(3))
->method('get')
->with('test_3')
->will($this->returnValue($this->otherObject));
$this->assertTrue($this->tempStore->deleteIfOwner('test_1'));
$this->assertTrue($this->tempStore->deleteIfOwner('test_2'));
$this->assertFalse($this->tempStore->deleteIfOwner('test_3'));
}
}

View file

@ -0,0 +1,419 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\UserAccessControlHandlerTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Access\AccessResult;
use Drupal\Tests\UnitTestCase;
use Drupal\user\UserAccessControlHandler;
/**
* Tests the user access controller.
*
* @group Drupal
* @group User
*
* @coversDefaultClass \Drupal\user\UserAccessControlHandler
*/
class UserAccessControlHandlerTest extends UnitTestCase {
/**
* The user access controller to test.
*
* @var \Drupal\user\UserAccessControlHandler
*/
protected $accessControlHandler;
/**
* The mock user account with view access.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $viewer;
/**
* The mock user account that is able to change their own account name.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $owner;
/**
* The mock administrative test user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $admin;
/**
* The mocked test field items.
*
* @var \Drupal\Core\Field\FieldItemList
*/
protected $items;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->viewer = $this->getMock('\Drupal\Core\Session\AccountInterface');
$this->viewer
->expects($this->any())
->method('hasPermission')
->will($this->returnValue(FALSE));
$this->viewer
->expects($this->any())
->method('id')
->will($this->returnValue(1));
$this->owner = $this->getMock('\Drupal\Core\Session\AccountInterface');
$this->owner
->expects($this->any())
->method('hasPermission')
->will($this->returnValueMap(array(
array('administer users', FALSE),
array('change own username', TRUE),
)));
$this->owner
->expects($this->any())
->method('id')
->will($this->returnValue(2));
$this->admin = $this->getMock('\Drupal\Core\Session\AccountInterface');
$this->admin
->expects($this->any())
->method('hasPermission')
->will($this->returnValue(TRUE));
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$this->accessControlHandler = new UserAccessControlHandler($entity_type);
$module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$module_handler->expects($this->any())
->method('getImplementations')
->will($this->returnValue(array()));
$this->accessControlHandler->setModuleHandler($module_handler);
$this->items = $this->getMockBuilder('Drupal\Core\Field\FieldItemList')
->disableOriginalConstructor()
->getMock();
$this->items
->expects($this->any())
->method('defaultAccess')
->will($this->returnValue(AccessResult::allowed()));
}
/**
* Asserts correct field access grants for a field.
*/
public function assertFieldAccess($field, $viewer, $target, $view, $edit) {
$field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
$field_definition->expects($this->any())
->method('getName')
->will($this->returnValue($field));
$this->items
->expects($this->any())
->method('getEntity')
->will($this->returnValue($this->{$target}));
foreach (array('view' => $view, 'edit' => $edit) as $operation => $result) {
$message = SafeMarkup::format("User @field field access returns @result with operation '@op' for @account accessing @target", array(
'@field' => $field,
'@result' => !isset($result) ? 'null' : ($result ? 'true' : 'false'),
'@op' => $operation,
'@account' => $viewer,
'@target' => $target,
));
$this->assertSame($result, $this->accessControlHandler->fieldAccess($operation, $field_definition, $this->{$viewer}, $this->items), $message);
}
}
/**
* Ensures user name access is working properly.
*
* @dataProvider userNameProvider
*/
public function testUserNameAccess($viewer, $target, $view, $edit) {
$this->assertFieldAccess('name', $viewer, $target, $view, $edit);
}
/**
* Provides test data for estUserNameAccess().
*/
public function userNameProvider() {
$name_access = array(
// The viewer user is allowed to see user names on all accounts.
array(
'viewer' => 'viewer',
'target' => 'viewer',
'view' => TRUE,
'edit' => FALSE,
),
array(
'viewer' => 'owner',
'target' => 'viewer',
'view' => TRUE,
'edit' => FALSE,
),
array(
'viewer' => 'viewer',
'target' => 'owner',
'view' => TRUE,
'edit' => FALSE,
),
// The owner user is allowed to change its own user name.
array(
'viewer' => 'owner',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
),
// The users-administrator user has full access.
array(
'viewer' => 'admin',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
),
);
return $name_access;
}
/**
* Tests that private user settings cannot be viewed by other users.
*
* @dataProvider hiddenUserSettingsProvider
*/
public function testHiddenUserSettings($field, $viewer, $target, $view, $edit) {
$this->assertFieldAccess($field, $viewer, $target, $view, $edit);
}
/**
* Provides test data for testHiddenUserSettings().
*/
public function hiddenUserSettingsProvider() {
$access_info = array();
$fields = array(
'preferred_langcode',
'preferred_admin_langcode',
'timezone',
'mail',
);
foreach ($fields as $field) {
$access_info[] = array(
'field' => $field,
'viewer' => 'viewer',
'target' => 'viewer',
'view' => TRUE,
'edit' => TRUE,
);
$access_info[] = array(
'field' => $field,
'viewer' => 'viewer',
'target' => 'owner',
'view' => FALSE,
// Anyone with edit access to the user can also edit these fields. In
// reality edit access will already be checked on entity level and the
// user without view access will typically not be able to edit.
'edit' => TRUE,
);
$access_info[] = array(
'field' => $field,
'viewer' => 'owner',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
);
$access_info[] = array(
'field' => $field,
'viewer' => 'admin',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
);
}
return $access_info;
}
/**
* Tests that private user settings cannot be viewed by other users.
*
* @dataProvider adminFieldAccessProvider
*/
public function testAdminFieldAccess($field, $viewer, $target, $view, $edit) {
$this->assertFieldAccess($field, $viewer, $target, $view, $edit);
}
/**
* Provides test data for testAdminFieldAccess().
*/
public function adminFieldAccessProvider() {
$access_info = array();
$fields = array(
'roles',
'status',
'access',
'login',
'init',
);
foreach ($fields as $field) {
$access_info[] = array(
'field' => $field,
'viewer' => 'viewer',
'target' => 'viewer',
'view' => FALSE,
'edit' => FALSE,
);
$access_info[] = array(
'field' => $field,
'viewer' => 'viewer',
'target' => 'owner',
'view' => FALSE,
'edit' => FALSE,
);
$access_info[] = array(
'field' => $field,
'viewer' => 'admin',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
);
}
return $access_info;
}
/**
* Tests that passwords cannot be viewed, just edited.
*
* @dataProvider passwordAccessProvider
*/
public function testPasswordAccess($viewer, $target, $view, $edit) {
$this->assertFieldAccess('pass', $viewer, $target, $view, $edit);
}
/**
* Provides test data for passwordAccessProvider().
*/
public function passwordAccessProvider() {
$pass_access = array(
array(
'viewer' => 'viewer',
'target' => 'viewer',
'view' => FALSE,
'edit' => TRUE,
),
array(
'viewer' => 'viewer',
'target' => 'owner',
'view' => FALSE,
// Anyone with edit access to the user can also edit these fields. In
// reality edit access will already be checked on entity level and the
// user without view access will typically not be able to edit.
'edit' => TRUE,
),
array(
'viewer' => 'owner',
'target' => 'viewer',
'view' => FALSE,
'edit' => TRUE,
),
array(
'viewer' => 'admin',
'target' => 'owner',
'view' => FALSE,
'edit' => TRUE,
),
);
return $pass_access;
}
/**
* Tests the user created field access.
*
* @dataProvider createdAccessProvider
*/
public function testCreatedAccess($viewer, $target, $view, $edit) {
$this->assertFieldAccess('created', $viewer, $target, $view, $edit);
}
/**
* Provides test data for testCreatedAccess().
*/
public function createdAccessProvider() {
$created_access = array(
array(
'viewer' => 'viewer',
'target' => 'viewer',
'view' => TRUE,
'edit' => FALSE,
),
array(
'viewer' => 'owner',
'target' => 'viewer',
'view' => TRUE,
'edit' => FALSE,
),
array(
'viewer' => 'admin',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
),
);
return $created_access;
}
/**
* Tests access to a non-existing base field.
*
* @dataProvider NonExistingFieldAccessProvider
*/
public function testNonExistingFieldAccess($viewer, $target, $view, $edit) {
// By default everyone has access to all fields that do not have explicit
// access control.
// @see EntityAccessControlHandler::checkFieldAccess()
$this->assertFieldAccess('some_non_existing_field', $viewer, $target, $view, $edit);
}
/**
* Provides test data for testNonExistingFieldAccess().
*/
public function NonExistingFieldAccessProvider() {
$created_access = array(
array(
'viewer' => 'viewer',
'target' => 'viewer',
'view' => TRUE,
'edit' => TRUE,
),
array(
'viewer' => 'owner',
'target' => 'viewer',
'view' => TRUE,
'edit' => TRUE,
),
array(
'viewer' => 'admin',
'target' => 'owner',
'view' => TRUE,
'edit' => TRUE,
),
);
return $created_access;
}
}

View file

@ -0,0 +1,199 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\UserAuthTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Tests\UnitTestCase;
use Drupal\user\UserAuth;
/**
* @coversDefaultClass \Drupal\user\UserAuth
* @group user
*/
class UserAuthTest extends UnitTestCase {
/**
* The mock user storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $userStorage;
/**
* The mocked password service.
*
* @var \Drupal\Core\Password\PasswordInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $passwordService;
/**
* The mock user.
*
* @var \Drupal\user\Entity\User|\PHPUnit_Framework_MockObject_MockObject
*/
protected $testUser;
/**
* The user auth object under test.
*
* @var \Drupal\user\UserAuth
*/
protected $userAuth;
/**
* The test username.
*
* @var string
*/
protected $username = 'test_user';
/**
* The test password.
*
* @var string
*/
protected $password = 'password';
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->userStorage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$entity_manager->expects($this->any())
->method('getStorage')
->with('user')
->will($this->returnValue($this->userStorage));
$this->passwordService = $this->getMock('Drupal\Core\Password\PasswordInterface');
$this->testUser = $this->getMockBuilder('Drupal\user\Entity\User')
->disableOriginalConstructor()
->setMethods(array('id', 'setPassword', 'save', 'getPassword'))
->getMock();
$this->userAuth = new UserAuth($entity_manager, $this->passwordService);
}
/**
* Tests failing authentication with missing credential parameters.
*
* @covers ::authenticate
*
* @dataProvider providerTestAuthenticateWithMissingCredentials
*/
public function testAuthenticateWithMissingCredentials($username, $password) {
$this->userStorage->expects($this->never())
->method('loadByProperties');
$this->assertFalse($this->userAuth->authenticate($username, $password));
}
/**
* Data provider for testAuthenticateWithMissingCredentials().
*
* @return array
*/
public function providerTestAuthenticateWithMissingCredentials() {
return array(
array(NULL, NULL),
array(NULL, ''),
array('', NULL),
array('', ''),
);
}
/**
* Tests the authenticate method with no account returned.
*
* @covers ::authenticate
*/
public function testAuthenticateWithNoAccountReturned() {
$this->userStorage->expects($this->once())
->method('loadByProperties')
->with(array('name' => $this->username))
->will($this->returnValue(array()));
$this->assertFalse($this->userAuth->authenticate($this->username, $this->password));
}
/**
* Tests the authenticate method with an incorrect password.
*
* @covers ::authenticate
*/
public function testAuthenticateWithIncorrectPassword() {
$this->userStorage->expects($this->once())
->method('loadByProperties')
->with(array('name' => $this->username))
->will($this->returnValue(array($this->testUser)));
$this->passwordService->expects($this->once())
->method('check')
->with($this->password, $this->testUser->getPassword())
->will($this->returnValue(FALSE));
$this->assertFalse($this->userAuth->authenticate($this->username, $this->password));
}
/**
* Tests the authenticate method with a correct password.
*
* @covers ::authenticate
*/
public function testAuthenticateWithCorrectPassword() {
$this->testUser->expects($this->once())
->method('id')
->will($this->returnValue(1));
$this->userStorage->expects($this->once())
->method('loadByProperties')
->with(array('name' => $this->username))
->will($this->returnValue(array($this->testUser)));
$this->passwordService->expects($this->once())
->method('check')
->with($this->password, $this->testUser->getPassword())
->will($this->returnValue(TRUE));
$this->assertsame(1, $this->userAuth->authenticate($this->username, $this->password));
}
/**
* Tests the authenticate method with a correct password and new password hash.
*
* @covers ::authenticate
*/
public function testAuthenticateWithCorrectPasswordAndNewPasswordHash() {
$this->testUser->expects($this->once())
->method('id')
->will($this->returnValue(1));
$this->testUser->expects($this->once())
->method('setPassword')
->with($this->password);
$this->testUser->expects($this->once())
->method('save');
$this->userStorage->expects($this->once())
->method('loadByProperties')
->with(array('name' => $this->username))
->will($this->returnValue(array($this->testUser)));
$this->passwordService->expects($this->once())
->method('check')
->with($this->password, $this->testUser->getPassword())
->will($this->returnValue(TRUE));
$this->passwordService->expects($this->once())
->method('needsRehash')
->with($this->testUser->getPassword())
->will($this->returnValue(TRUE));
$this->assertsame(1, $this->userAuth->authenticate($this->username, $this->password));
}
}

View file

@ -0,0 +1,87 @@
<?php
/**
* @file
* Contains \Drupal\Tests\user\Unit\Views\Argument\RolesRidTest.
*/
namespace Drupal\Tests\user\Unit\Views\Argument;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Entity\Role;
use Drupal\user\Plugin\views\argument\RolesRid;
/**
* @coversDefaultClass \Drupal\user\Plugin\views\argument\RolesRid
* @group user
*/
class RolesRidTest extends UnitTestCase {
/**
* Tests the title_query method.
*
* @see \Drupal\user\Plugin\views\argument\RolesRid::title_query()
*/
public function testTitleQuery() {
$role1 = new Role(array(
'id' => 'test_rid_1',
'label' => 'test rid 1'
), 'user_role');
$role2 = new Role(array(
'id' => 'test_rid_2',
'label' => 'test <strong>rid 2</strong>',
), 'user_role');
// Creates a stub entity storage;
$role_storage = $this->getMockForAbstractClass('Drupal\Core\Entity\EntityStorageInterface');
$role_storage->expects($this->any())
->method('loadMultiple')
->will($this->returnValueMap(array(
array(array(), array()),
array(array('test_rid_1'), array('test_rid_1' => $role1)),
array(array('test_rid_1', 'test_rid_2'), array('test_rid_1' => $role1, 'test_rid_2' => $role2)),
)));
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$entity_type->expects($this->any())
->method('getKey')
->with('label')
->will($this->returnValue('label'));
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$entity_manager->expects($this->any())
->method('getDefinition')
->with($this->equalTo('user_role'))
->will($this->returnValue($entity_type));
$entity_manager
->expects($this->once())
->method('getStorage')
->with($this->equalTo('user_role'))
->will($this->returnValue($role_storage));
// @todo \Drupal\Core\Entity\Entity::entityType() uses a global call to
// entity_get_info(), which in turn wraps \Drupal::entityManager(). Set
// the entity manager until this is fixed.
$container = new ContainerBuilder();
$container->set('entity.manager', $entity_manager);
\Drupal::setContainer($container);
$roles_rid_argument = new RolesRid(array(), 'user__roles_rid', array(), $entity_manager);
$roles_rid_argument->value = array();
$titles = $roles_rid_argument->title_query();
$this->assertEquals(array(), $titles);
$roles_rid_argument->value = array('test_rid_1');
$titles = $roles_rid_argument->title_query();
$this->assertEquals(array('test rid 1'), $titles);
$roles_rid_argument->value = array('test_rid_1', 'test_rid_2');
$titles = $roles_rid_argument->title_query();
$this->assertEquals(array('test rid 1', SafeMarkup::checkPlain('test <strong>rid 2</strong>')), $titles);
}
}

View file

@ -0,0 +1,32 @@
{#
/**
* @file
* Theme override for testing the presence of all user data.
*
* This template is used when viewing a registered user's page,
* e.g., example.com/user/123. 123 being the user's ID.
*
* Available variables:
* - content: A list of content items. Use 'content' to print all content, or
* print a subset such as 'content.field_example'.
* - Field variables: For each field attached to the user a corresponding
* variable is defined; e.g., account.field_example has a variable
* 'field_example' defined. When needing to access a field's raw values,
* developers/themers are strongly encouraged to use these variables.
* Otherwise they will have to explicitly specify the desired field language,
* e.g. account.field_example.en, thus overriding any language negotiation
* rule that was previously applied.
* - attributes: HTML attributes for the container element.
* - user: A Drupal User entity.
*
* @see template_preprocess_user()
*/
#}
<article{{ attributes.addClass('profile') }}>
{% if content %}
{{ content }}
{% endif %}
{% if user %}
<p>{{ user.mail.value }}</p>
{% endif %}
</article>

View file

@ -0,0 +1,5 @@
name: 'User Test theme'
type: theme
description: 'Theme for testing the available fields in user twig template'
version: VERSION
core: 8.x