7564fceeca0de9ef6e370ca3e5b8649a5568c066
[yaffs-website] / web / core / modules / user / tests / src / Kernel / Migrate / d7 / MigrateUserTest.php
1 <?php
2
3 namespace Drupal\Tests\user\Kernel\Migrate\d7;
4
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;
12
13 /**
14  * Users migration.
15  *
16  * @group user
17  */
18 class MigrateUserTest extends MigrateDrupal7TestBase {
19
20   use NodeCommentCombinationTrait;
21
22   /**
23    * {@inheritdoc}
24    */
25   public static $modules = [
26     'comment',
27     'content_translation',
28     'datetime',
29     'file',
30     'image',
31     'language',
32     'link',
33     // Required for translation migrations.
34     'migrate_drupal_multilingual',
35     'node',
36     'system',
37     'taxonomy',
38     'telephone',
39     'text',
40   ];
41
42   /**
43    * {@inheritdoc}
44    */
45   protected function setUp() {
46     parent::setUp();
47
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([
61       'language',
62       'user_picture_field',
63       'user_picture_field_instance',
64       'd7_user_role',
65       'd7_field',
66       'd7_field_instance',
67       'd7_user',
68       'd7_entity_translation_settings',
69       'd7_user_entity_translation',
70     ]);
71   }
72
73   /**
74    * Asserts various aspects of a user account.
75    *
76    * @param string $id
77    *   The user ID.
78    * @param string $label
79    *   The username.
80    * @param string $mail
81    *   The user's email address.
82    * @param string $password
83    *   The password for this user.
84    * @param int $created
85    *   The user's creation time.
86    * @param int $access
87    *   The last access time.
88    * @param int $login
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.
98    * @param string $init
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.
108    */
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());
120
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);
132     }
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);
137     }
138     else {
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);
142     }
143
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);
151     }
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);
155     }
156   }
157
158   /**
159    * Tests the Drupal 7 user to Drupal 8 migration.
160    */
161   public function testUser() {
162     $users = Database::getConnection('default', 'migrate')
163       ->select('users', 'u')
164       ->fields('u')
165       ->condition('uid', 1, '>')
166       ->execute()
167       ->fetchAll();
168
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)
174         ->execute()
175         ->fetchCol();
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);
181       }
182
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', '')
189         ->execute()
190         ->fetchField();
191       $entity_language = $entity_translation ?: $source->language;
192
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)
198         ->execute()
199         ->fetchCol();
200       $field_integer = !empty($field_integer) ? $field_integer : NULL;
201
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)
206         ->execute()
207         ->fetchField();
208
209       $this->assertEntity(
210         $source->uid,
211         $source->name,
212         $source->mail,
213         $source->pass,
214         $source->created,
215         $source->access,
216         $source->login,
217         $source->status,
218         $entity_language,
219         $source->language,
220         $source->timezone,
221         $source->init,
222         $roles,
223         $field_integer,
224         $field_file
225       );
226
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
231       // Drupal 8.
232       $user = User::load($source->uid);
233       $rehash = $user->getPassword();
234       $this->assertNotEquals($source->pass, $rehash);
235
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());
240     }
241   }
242
243   /**
244    * Tests the Drupal 7 user entity translations to Drupal 8 migration.
245    */
246   public function testUserEntityTranslations() {
247     $manager = $this->container->get('content_translation.manager');
248
249     // Get the user and its translations.
250     $user = User::load(2);
251     $user_fr = $user->getTranslation('fr');
252     $user_is = $user->getTranslation('is');
253
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);
258
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());
266
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());
274
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());
282   }
283
284 }