3 namespace Drupal\Tests\user\Kernel\Migrate\d7;
5 use Drupal\Core\Database\Database;
6 use Drupal\taxonomy\Entity\Vocabulary;
7 use Drupal\Tests\migrate\Kernel\NodeCommentCombinationTrait;
8 use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
9 use Drupal\user\Entity\User;
10 use Drupal\user\RoleInterface;
11 use Drupal\user\UserInterface;
18 class MigrateUserTest extends MigrateDrupal7TestBase {
20 use NodeCommentCombinationTrait;
25 public static $modules = [
27 'content_translation',
33 // Required for translation migrations.
34 'migrate_drupal_multilingual',
45 protected function setUp() {
48 // Prepare to migrate user pictures as well.
49 $this->installEntitySchema('file');
50 $this->installEntitySchema('comment');
51 $this->installEntitySchema('node');
52 $this->installEntitySchema('taxonomy_term');
53 $this->createNodeCommentCombination('page');
54 $this->createNodeCommentCombination('article');
55 $this->createNodeCommentCombination('blog');
56 $this->createNodeCommentCombination('book');
57 $this->createNodeCommentCombination('forum', 'comment_forum');
58 $this->createNodeCommentCombination('test_content_type');
59 Vocabulary::create(['vid' => 'test_vocabulary'])->save();
60 $this->executeMigrations([
63 'user_picture_field_instance',
68 'd7_entity_translation_settings',
69 'd7_user_entity_translation',
74 * Asserts various aspects of a user account.
78 * @param string $label
81 * The user's email address.
82 * @param string $password
83 * The password for this user.
85 * The user's creation time.
87 * The last access time.
89 * The last login time.
90 * @param bool $blocked
91 * Whether or not the account is blocked.
92 * @param string $entity_langcode
93 * The user entity language code.
94 * @param string $prefered_langcode
95 * The user prefered language code.
96 * @param string $timezone
97 * The user account's timezone name.
99 * The user's initial email address.
100 * @param string[] $roles
101 * Role IDs the user account is expected to have.
102 * @param int $field_integer
103 * The value of the integer field.
104 * @param int|false $field_file_target_id
105 * (optional) The target ID of the file field.
106 * @param bool $has_picture
107 * (optional) Whether the user is expected to have a picture attached.
109 protected function assertEntity($id, $label, $mail, $password, $created, $access, $login, $blocked, $entity_langcode, $prefered_langcode, $timezone, $init, $roles, $field_integer, $field_file_target_id = FALSE, $has_picture = FALSE) {
110 /** @var \Drupal\user\UserInterface $user */
111 $user = User::load($id);
112 $this->assertTrue($user instanceof UserInterface);
113 $this->assertSame($label, $user->label());
114 $this->assertSame($mail, $user->getEmail());
115 $this->assertSame($password, $user->getPassword());
116 $this->assertSame($created, $user->getCreatedTime());
117 $this->assertSame($access, $user->getLastAccessedTime());
118 $this->assertSame($login, $user->getLastLoginTime());
119 $this->assertNotSame($blocked, $user->isBlocked());
121 // Ensure the user's langcode, preferred_langcode and
122 // preferred_admin_langcode are valid.
123 // $user->getPreferredLangcode() might fallback to default language if the
124 // user preferred language is not configured on the site. We just want to
125 // test if the value was imported correctly.
126 $language_manager = $this->container->get('language_manager');
127 $default_langcode = $language_manager->getDefaultLanguage()->getId();
128 if ($prefered_langcode == '') {
129 $this->assertSame('en', $user->langcode->value);
130 $this->assertSame($default_langcode, $user->preferred_langcode->value);
131 $this->assertSame($default_langcode, $user->preferred_admin_langcode->value);
133 elseif ($language_manager->getLanguage($prefered_langcode) === NULL) {
134 $this->assertSame($default_langcode, $user->langcode->value);
135 $this->assertSame($default_langcode, $user->preferred_langcode->value);
136 $this->assertSame($default_langcode, $user->preferred_admin_langcode->value);
139 $this->assertSame($entity_langcode, $user->langcode->value);
140 $this->assertSame($prefered_langcode, $user->preferred_langcode->value);
141 $this->assertSame($prefered_langcode, $user->preferred_admin_langcode->value);
144 $this->assertSame($timezone, $user->getTimeZone());
145 $this->assertSame($init, $user->getInitialEmail());
146 $this->assertSame($roles, $user->getRoles());
147 $this->assertSame($has_picture, !$user->user_picture->isEmpty());
148 if (!is_null($field_integer)) {
149 $this->assertTrue($user->hasField('field_integer'));
150 $this->assertEquals($field_integer[0], $user->field_integer->value);
152 if (!empty($field_file_target_id)) {
153 $this->assertTrue($user->hasField('field_file'));
154 $this->assertSame($field_file_target_id, $user->field_file->target_id);
159 * Tests the Drupal 7 user to Drupal 8 migration.
161 public function testUser() {
162 $users = Database::getConnection('default', 'migrate')
163 ->select('users', 'u')
165 ->condition('uid', 1, '>')
169 foreach ($users as $source) {
170 $rids = Database::getConnection('default', 'migrate')
171 ->select('users_roles', 'ur')
172 ->fields('ur', ['rid'])
173 ->condition('ur.uid', $source->uid)
176 $roles = [RoleInterface::AUTHENTICATED_ID];
177 $id_map = $this->getMigration('d7_user_role')->getIdMap();
178 foreach ($rids as $rid) {
179 $role = $id_map->lookupDestinationId([$rid]);
180 $roles[] = reset($role);
183 $entity_translation = Database::getConnection('default', 'migrate')
184 ->select('entity_translation', 'et')
185 ->fields('et', ['language'])
186 ->condition('et.entity_type', 'user')
187 ->condition('et.entity_id', $source->uid)
188 ->condition('et.source', '')
191 $entity_language = $entity_translation ?: $source->language;
193 $field_integer = Database::getConnection('default', 'migrate')
194 ->select('field_data_field_integer', 'fi')
195 ->fields('fi', ['field_integer_value'])
196 ->condition('fi.entity_id', $source->uid)
197 ->condition('fi.language', $entity_language)
200 $field_integer = !empty($field_integer) ? $field_integer : NULL;
202 $field_file = Database::getConnection('default', 'migrate')
203 ->select('field_data_field_file', 'ff')
204 ->fields('ff', ['field_file_fid'])
205 ->condition('ff.entity_id', $source->uid)
227 // Ensure that the user can authenticate.
228 $this->assertEquals($source->uid, $this->container->get('user.auth')->authenticate($source->name, 'a password'));
229 // After authenticating the password will be rehashed because the password
230 // stretching iteration count has changed from 15 in Drupal 7 to 16 in
232 $user = User::load($source->uid);
233 $rehash = $user->getPassword();
234 $this->assertNotEquals($source->pass, $rehash);
236 // Authenticate again and there should be no re-hash.
237 $this->assertEquals($source->uid, $this->container->get('user.auth')->authenticate($source->name, 'a password'));
238 $user = User::load($source->uid);
239 $this->assertEquals($rehash, $user->getPassword());
244 * Tests the Drupal 7 user entity translations to Drupal 8 migration.
246 public function testUserEntityTranslations() {
247 $manager = $this->container->get('content_translation.manager');
249 // Get the user and its translations.
250 $user = User::load(2);
251 $user_fr = $user->getTranslation('fr');
252 $user_is = $user->getTranslation('is');
254 // Test that fields translated with Entity Translation are migrated.
255 $this->assertSame('99', $user->field_integer->value);
256 $this->assertSame('9', $user_fr->field_integer->value);
257 $this->assertSame('1', $user_is->field_integer->value);
259 // Test that the French translation metadata is correctly migrated.
260 $metadata_fr = $manager->getTranslationMetadata($user_fr);
261 $this->assertSame('en', $metadata_fr->getSource());
262 $this->assertSame('1', $metadata_fr->getAuthor()->uid->value);
263 $this->assertSame('1531663916', $metadata_fr->getCreatedTime());
264 $this->assertFalse($metadata_fr->isOutdated());
265 $this->assertFalse($metadata_fr->isPublished());
267 // Test that the Icelandic translation metadata is correctly migrated.
268 $metadata_is = $manager->getTranslationMetadata($user_is);
269 $this->assertSame('en', $metadata_is->getSource());
270 $this->assertSame('2', $metadata_is->getAuthor()->uid->value);
271 $this->assertSame('1531663925', $metadata_is->getCreatedTime());
272 $this->assertTrue($metadata_is->isOutdated());
273 $this->assertTrue($metadata_is->isPublished());
275 // Test that untranslatable properties are the same as the source language.
276 $this->assertSame($user->label(), $user_fr->label());
277 $this->assertSame($user->label(), $user_is->label());
278 $this->assertSame($user->getEmail(), $user_fr->getEmail());
279 $this->assertSame($user->getEmail(), $user_is->getEmail());
280 $this->assertSame($user->getPassword(), $user_fr->getPassword());
281 $this->assertSame($user->getPassword(), $user_is->getPassword());