Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0

This commit is contained in:
Pantheon Automation 2016-10-06 15:16:20 -07:00 committed by Greg Anderson
parent 2f563ab520
commit f1c8716f57
1732 changed files with 52334 additions and 11780 deletions

View file

@ -14,8 +14,8 @@ $connection = Database::getConnection();
// already.
$connection->delete('config')->condition('name', 'user.mail')->execute();
$connection->insert('config')
->fields(array('collection', 'name', 'data'))
->values(array(
->fields(array('collection', 'name', 'data'))
->values(array(
'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\";}"

View file

@ -48,7 +48,7 @@ display:
group: 1
id: status
table: users_field_data
value: true
value: '1'
plugin_id: boolean
entity_type: user
entity_field: status

View file

@ -52,7 +52,7 @@ display:
table: users_field_data
field: status
operator: '='
value: true
value: '1'
plugin_id: boolean
entity_type: user
entity_field: status

View file

@ -126,7 +126,7 @@ display:
field_api_classes: false
filters:
status:
value: true
value: '1'
table: users_field_data
field: status
plugin_id: boolean

View file

@ -142,7 +142,7 @@ display:
plugin_id: user_roles
filters:
status:
value: true
value: '1'
table: users_field_data
field: status
id: status

View file

@ -0,0 +1,421 @@
<?php
namespace Drupal\Tests\user\Functional;
use Drupal\Core\Flood\DatabaseBackend;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Controller\UserAuthenticationController;
use GuzzleHttp\Cookie\CookieJar;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Serializer;
/**
* Tests login via direct HTTP.
*
* @group user
*/
class UserLoginHttpTest extends BrowserTestBase {
/**
* The cookie jar.
*
* @var \GuzzleHttp\Cookie\CookieJar
*/
protected $cookies;
/**
* The serializer.
*
* @var \Symfony\Component\Serializer\Serializer
*/
protected $serializer;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->cookies = new CookieJar();
$encoders = [new JsonEncoder(), new XmlEncoder()];
$this->serializer = new Serializer([], $encoders);
}
/**
* Executes a login HTTP request.
*
* @param string $name
* The username.
* @param string $pass
* The user password.
* @param string $format
* The format to use to make the request.
*
* @return \Psr\Http\Message\ResponseInterface The HTTP response.
* The HTTP response.
*/
protected function loginRequest($name, $pass, $format = 'json') {
$user_login_url = Url::fromRoute('user.login.http')
->setRouteParameter('_format', $format)
->setAbsolute();
$request_body = [];
if (isset($name)) {
$request_body['name'] = $name;
}
if (isset($pass)) {
$request_body['pass'] = $pass;
}
$result = \Drupal::httpClient()->post($user_login_url->toString(), [
'body' => $this->serializer->encode($request_body, $format),
'headers' => [
'Accept' => "application/$format",
],
'http_errors' => FALSE,
'cookies' => $this->cookies,
]);
return $result;
}
/**
* Tests user session life cycle.
*/
public function testLogin() {
$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'];
}
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;
$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();
$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);
// 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, $pass, $format);
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format);
$response = $this->loginRequest($name, NULL, $format);
$this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format);
// Blocked.
$account
->block()
->save();
$response = $this->loginRequest($name, $pass, $format);
$this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format);
$account
->activate()
->save();
$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($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);
$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_OUT);
$this->resetFlood();
}
}
}
/**
* Gets a value for a given key from the response.
*
* @param \Psr\Http\Message\ResponseInterface $response
* The response object.
* @param string $key
* The key for the value.
* @param string $format
* The encoded format.
*
* @return mixed
* The value for the key.
*/
protected function getResultValue(ResponseInterface $response, $key, $format) {
$decoded = $this->serializer->decode((string) $response->getBody(), $format);
if (is_array($decoded)) {
return $decoded[$key];
}
else {
return $decoded->{$key};
}
}
/**
* Resets all flood entries.
*/
protected function resetFlood() {
$this->container->get('database')->delete(DatabaseBackend::TABLE_NAME)->execute();
}
/**
* Tests the global login flood control.
*
* @see \Drupal\basic_auth\Tests\Authentication\BasicAuthTest::testGlobalLoginFloodControl
* @see \Drupal\user\Tests\UserLoginTest::testGlobalLoginFloodControl
*/
public function testGlobalLoginFloodControl() {
$this->config('user.flood')
->set('ip_limit', 2)
// Set a high per-user limit out so that it is not relevant in the test.
->set('user_limit', 4000)
->save();
$user = $this->drupalCreateUser([]);
$incorrect_user = clone $user;
$incorrect_user->passRaw .= 'incorrect';
// Try 2 failed logins.
for ($i = 0; $i < 2; $i++) {
$response = $this->loginRequest($incorrect_user->getUsername(), $incorrect_user->passRaw);
$this->assertEquals('400', $response->getStatusCode());
}
// IP limit has reached to its limit. Even valid user credentials will fail.
$response = $this->loginRequest($user->getUsername(), $user->passRaw);
$this->assertHttpResponseWithMessage($response, '403', 'Access is blocked because of IP based flood prevention.');
}
/**
* Checks a response for status code and body.
*
* @param \Psr\Http\Message\ResponseInterface $response
* The response object.
* @param int $expected_code
* The expected status code.
* @param mixed $expected_body
* The expected response body.
*/
protected function assertHttpResponse(ResponseInterface $response, $expected_code, $expected_body) {
$this->assertEquals($expected_code, $response->getStatusCode());
$this->assertEquals($expected_body, (string) $response->getBody());
}
/**
* Checks a response for status code and message.
*
* @param \Psr\Http\Message\ResponseInterface $response
* The response object.
* @param int $expected_code
* The expected status code.
* @param string $expected_message
* The expected message encoded in response.
* @param string $format
* The format that the response is encoded in.
*/
protected function assertHttpResponseWithMessage(ResponseInterface $response, $expected_code, $expected_message, $format = 'json') {
$this->assertEquals($expected_code, $response->getStatusCode());
$this->assertEquals($expected_message, $this->getResultValue($response, 'message', $format));
}
/**
* Test the per-user login flood control.
*
* @see \Drupal\user\Tests\UserLoginTest::testPerUserLoginFloodControl
* @see \Drupal\basic_auth\Tests\Authentication\BasicAuthTest::testPerUserLoginFloodControl
*/
public function testPerUserLoginFloodControl() {
foreach ([TRUE, FALSE] as $uid_only_setting) {
$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)
->set('uid_only', $uid_only_setting)
->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++) {
$response = $this->loginRequest($incorrect_user1->getUsername(), $incorrect_user1->passRaw);
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.');
}
// A successful login will reset the per-user flood control count.
$response = $this->loginRequest($user1->getUsername(), $user1->passRaw);
$result_data = $this->serializer->decode($response->getBody(), 'json');
$this->logoutRequest('json', $result_data['logout_token']);
// Try 3 failed logins for user 1, they will not trigger flood control.
for ($i = 0; $i < 3; $i++) {
$response = $this->loginRequest($incorrect_user1->getUsername(), $incorrect_user1->passRaw);
$this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.');
}
// 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.
$response = $this->loginRequest($user1->getUsername(), $user1->passRaw);
// Depending on the uid_only setting the error message will be different.
if ($uid_only_setting) {
$excepted_message = 'There have been more than 3 failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.';
}
else {
$excepted_message = 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.';
}
$this->assertHttpResponseWithMessage($response, 403, $excepted_message);
}
}
/**
* Executes a logout HTTP request.
*
* @param string $format
* The format to use to make the request.
* @param string $logout_token
* The csrf token for user logout.
*
* @return \Psr\Http\Message\ResponseInterface The HTTP response.
* The HTTP response.
*/
protected function logoutRequest($format = 'json', $logout_token = '') {
/** @var \GuzzleHttp\Client $client */
$client = $this->container->get('http_client');
$user_logout_url = Url::fromRoute('user.logout.http')
->setRouteParameter('_format', $format)
->setAbsolute();
if ($logout_token) {
$user_logout_url->setOption('query', ['token' => $logout_token]);
}
$post_options = [
'headers' => [
'Accept' => "application/$format",
],
'http_errors' => FALSE,
'cookies' => $this->cookies,
];
$response = $client->post($user_logout_url->toString(), $post_options);
return $response;
}
/**
* Test csrf protection of User Logout route.
*/
public function testLogoutCsrfProtection() {
$client = \Drupal::httpClient();
$login_status_url = $this->getLoginStatusUrlString();
$account = $this->drupalCreateUser();
$name = $account->getUsername();
$pass = $account->passRaw;
$response = $this->loginRequest($name, $pass);
$this->assertEquals(200, $response->getStatusCode());
$result_data = $this->serializer->decode($response->getBody(), 'json');
$logout_token = $result_data['logout_token'];
// Test third party site posting to current site with logout request.
// This should not logout the current user because it lacks the CSRF
// token.
$response = $this->logoutRequest('json');
$this->assertEquals(403, $response->getStatusCode());
// Ensure still logged in.
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN);
// Try with an incorrect token.
$response = $this->logoutRequest('json', 'not-the-correct-token');
$this->assertEquals(403, $response->getStatusCode());
// Ensure still logged in.
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN);
// Try a logout request with correct token.
$response = $this->logoutRequest('json', $logout_token);
$this->assertEquals(204, $response->getStatusCode());
// Ensure actually logged out.
$response = $client->get($login_status_url, ['cookies' => $this->cookies]);
$this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT);
}
/**
* Gets the URL string for checking login.
*
* @param string $format
* The format to use to make the request.
*
* @return string
* The URL string.
*/
protected function getLoginStatusUrlString($format = 'json') {
$user_login_status_url = Url::fromRoute('user.login_status.http');
$user_login_status_url->setRouteParameter('_format', $format);
$user_login_status_url->setAbsolute();
return $user_login_status_url->toString();
}
}

View file

@ -3,6 +3,7 @@
namespace Drupal\Tests\user\Kernel\Migrate\d6;
use Drupal\file\Entity\File;
use Drupal\Tests\file\Kernel\Migrate\d6\FileMigrationTestTrait;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
@ -12,6 +13,8 @@ use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
*/
class MigrateUserPictureFileTest extends MigrateDrupal6TestBase {
use FileMigrationTestTrait;
/**
* {@inheritdoc}
*/
@ -19,13 +22,7 @@ class MigrateUserPictureFileTest extends MigrateDrupal6TestBase {
parent::setUp();
$this->installEntitySchema('file');
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
$migration = $this->getMigration('d6_user_picture_file');
$source = $migration->getSourceConfiguration();
$source['site_path'] = 'core/modules/simpletest';
$migration->set('source', $source);
$this->executeMigration($migration);
$this->executeMigration('d6_user_picture_file');
}
/**

View file

@ -3,6 +3,7 @@
namespace Drupal\Tests\user\Kernel\Migrate\d6;
use Drupal\migrate\MigrateExecutable;
use Drupal\Tests\file\Kernel\Migrate\d6\FileMigrationTestTrait;
use Drupal\user\Entity\User;
use Drupal\file\Entity\File;
use Drupal\Core\Database\Database;
@ -16,6 +17,8 @@ use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
*/
class MigrateUserTest extends MigrateDrupal6TestBase {
use FileMigrationTestTrait;
/**
* {@inheritdoc}
*/

View file

@ -29,7 +29,7 @@ class MigrateUserRoleTest extends MigrateDrupal7TestBase {
* The role ID.
* @param string $label
* The role's expected label.
* @param int|NULL $original_rid
* @param int|null $original_rid
* The original (integer) ID of the role, to check permissions.
*/
protected function assertEntity($id, $label, $original_rid) {

View file

@ -2,6 +2,9 @@
namespace Drupal\Tests\user\Kernel\Migrate\d7;
use Drupal\comment\Entity\CommentType;
use Drupal\node\Entity\NodeType;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
use Drupal\user\Entity\User;
use Drupal\user\RoleInterface;
@ -17,7 +20,18 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['file', 'image'];
public static $modules = [
'comment',
'datetime',
'file',
'image',
'link',
'node',
'system',
'taxonomy',
'telephone',
'text',
];
/**
* {@inheritdoc}
@ -27,14 +41,42 @@ 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');
Vocabulary::create(['vid' => 'test_vocabulary'])->save();
$this->executeMigrations([
'user_picture_field',
'user_picture_field_instance',
'd7_user_role',
'd7_field',
'd7_field_instance',
'd7_user',
]);
}
/**
* 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.
*
@ -60,8 +102,10 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
* Role IDs the user account is expected to have.
* @param bool $has_picture
* Whether the user is expected to have a picture attached.
* @param int $field_integer
* The value of the integer field.
*/
protected function assertEntity($id, $label, $mail, $password, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) {
protected function assertEntity($id, $label, $mail, $password, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE, $field_integer = NULL) {
/** @var \Drupal\user\UserInterface $user */
$user = User::load($id);
$this->assertTrue($user instanceof UserInterface);
@ -80,6 +124,10 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
$this->assertIdentical($roles, $user->getRoles());
$this->assertIdentical($has_picture, !$user->user_picture->isEmpty());
$this->assertIdentical($password, $user->getPassword());
if (!is_null($field_integer)) {
$this->assertTrue($user->hasField('field_integer'));
$this->assertEquals($field_integer, $user->field_integer->value);
}
}
/**
@ -87,7 +135,7 @@ class MigrateUserTest extends MigrateDrupal7TestBase {
*/
public function testUser() {
$password = '$S$DGFZUE.FhrXbe4y52eC7p0ZVRGD/gOPtVctDlmC89qkujnBokAlJ';
$this->assertEntity(2, 'Odo', 'odo@local.host', $password, '0', '0', FALSE, '', 'odo@local.host');
$this->assertEntity(2, 'Odo', 'odo@local.host', $password, '0', '0', FALSE, 'en', 'odo@local.host', [RoleInterface::AUTHENTICATED_ID], FALSE, 99);
// Ensure that the user can authenticate.
$this->assertEquals(2, \Drupal::service('user.auth')->authenticate('Odo', 'a password'));

View file

@ -0,0 +1,72 @@
<?php
namespace Drupal\Tests\user\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests the d7_user_role source plugin.
*
* @covers \Drupal\user\Plugin\migrate\source\d7\Role
* @group user
*/
class RoleTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['migrate_drupal', 'user'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$expected = [
[
'rid' => 1,
'name' => 'anonymous user',
'permissions' => [
'access content',
],
],
[
'rid' => 2,
'name' => 'authenticated user',
'permissions' => [
'access comments',
'access content',
'post comments',
'post comments without approval',
],
],
[
'rid' => 3,
'name' => 'administrator',
'permissions' => [
'access comments',
'administer comments',
'post comments',
'post comments without approval',
'access content',
'administer content types',
'administer nodes',
],
],
];
$data = [
[[], $expected],
];
foreach ($expected as $row) {
foreach ($row['permissions'] as $permission) {
$data[0][0]['role_permission'][] = [
'permission' => $permission,
'rid' => $row['rid'],
];
}
unset($row['permissions']);
$data[0][0]['role'][] = $row;
}
return $data;
}
}

View file

@ -135,7 +135,7 @@ class UserAccountFormFieldsTest extends KernelTestBase {
$entity = $this->container->get('entity.manager')
->getStorage($entity_type)
->create($fields);
$form_object = $this->container->get('entity.manager')
$this->container->get('entity.manager')
->getFormObject($entity_type, $operation)
->setEntity($entity);

View file

@ -48,6 +48,7 @@ class UserValidationTest extends KernelTestBase {
'foo@example.com' => array('Valid username', 'assertNull'),
'foo@-example.com' => array('Valid username', 'assertNull'), // invalid domains are allowed in usernames
'þòøÇߪř€' => array('Valid username', 'assertNull'),
'foo+bar' => array('Valid username', 'assertNull'), // '+' symbol is allowed
'ᚠᛇᚻ᛫ᛒᛦᚦ' => array('Valid UTF8 username', 'assertNull'), // runes
' foo' => array('Invalid username that starts with a space', 'assertNotNull'),
'foo ' => array('Invalid username that ends with a space', 'assertNotNull'),

View file

@ -105,25 +105,25 @@ class PermissionHandlerTest extends UnitTestCase {
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"access_module_a: single_description"
);
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':
file_put_contents($url . '/module_b/module_b.permissions.yml', <<<EOF
'access module b':
title: 'Access B'
description: 'bla bla'
'access module a via module b':
title: 'Access A via B'
provider: 'module_a'
");
EOF
);
mkdir($url . '/module_c');
file_put_contents($url . '/module_c/module_c.permissions.yml',
"'access_module_c':
file_put_contents($url . '/module_c/module_c.permissions.yml', <<<EOF
'access_module_c':
title: 'Access C'
description: 'bla bla'
'restrict access': TRUE
");
EOF
);
$modules = array('module_a', 'module_b', 'module_c');
$extensions = array(
'module_a' => $this->mockModuleExtension('module_a', 'Module a'),
@ -187,9 +187,10 @@ class PermissionHandlerTest extends UnitTestCase {
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"access_module_a2: single_description2
access_module_a1: single_description1"
file_put_contents($url . '/module_a/module_a.permissions.yml', <<<EOF
access_module_a2: single_description2
access_module_a1: single_description1
EOF
);
mkdir($url . '/module_b');
file_put_contents($url . '/module_b/module_b.permissions.yml',
@ -234,21 +235,24 @@ access_module_a1: single_description1"
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"permission_callbacks:
file_put_contents($url . '/module_a/module_a.permissions.yml', <<<EOF
permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::singleDescription'
");
EOF
);
mkdir($url . '/module_b');
file_put_contents($url . '/module_b/module_b.permissions.yml',
"permission_callbacks:
file_put_contents($url . '/module_b/module_b.permissions.yml', <<<EOF
permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription'
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleProvider'
");
EOF
);
mkdir($url . '/module_c');
file_put_contents($url . '/module_c/module_c.permissions.yml',
"permission_callbacks:
file_put_contents($url . '/module_c/module_c.permissions.yml', <<<EOF
permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescriptionRestrictAccess'
");
EOF
);
$modules = array('module_a', 'module_b', 'module_c');
$extensions = array(
@ -309,13 +313,14 @@ access_module_a1: single_description1"
$url = vfsStream::url('modules');
mkdir($url . '/module_a');
file_put_contents($url . '/module_a/module_a.permissions.yml',
"'access module a':
file_put_contents($url . '/module_a/module_a.permissions.yml', <<<EOF
'access module a':
title: 'Access A'
description: 'bla bla'
permission_callbacks:
- 'Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription'
");
EOF
);
$modules = array('module_a');
$extensions = array(

View file

@ -5,7 +5,7 @@ namespace Drupal\Tests\user\Unit\Plugin\Core\Entity;
use Drupal\Tests\Core\Session\UserSessionTest;
use Drupal\user\RoleInterface;
/**
/**
* @coversDefaultClass \Drupal\user\Entity\User
* @group user
*/

View file

@ -1,73 +0,0 @@
<?php
namespace Drupal\Tests\user\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 role source plugin.
*
* @group user
*/
class RoleTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\user\Plugin\migrate\source\d7\Role';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_user_role',
),
);
protected $expectedResults = array(
array(
'rid' => 1,
'name' => 'anonymous user',
'permissions' => array(
'access content',
),
),
array(
'rid' => 2,
'name' => 'authenticated user',
'permissions' => array(
'access comments',
'access content',
'post comments',
'post comments without approval',
),
),
array(
'rid' => 3,
'name' => 'administrator',
'permissions' => array(
'access comments',
'administer comments',
'post comments',
'post comments without approval',
'access content',
'administer content types',
'administer nodes',
),
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $row) {
foreach ($row['permissions'] as $permission) {
$this->databaseContents['role_permission'][] = array(
'permission' => $permission,
'rid' => $row['rid'],
);
}
unset($row['permissions']);
$this->databaseContents['role'][] = $row;
}
parent::setUp();
}
}