PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/web/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/ContentEntityTest.php

https://gitlab.com/mohamed_hussein/prodt
PHP | 474 lines | 336 code | 36 blank | 102 comment | 14 complexity | f2ca743d0fb68d0418861805c0d1030e MD5 | raw file
  1. <?php
  2. namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source;
  3. use Drupal\Component\Plugin\PluginBase;
  4. use Drupal\Core\Field\FieldStorageDefinitionInterface;
  5. use Drupal\Core\Language\LanguageInterface;
  6. use Drupal\file\Entity\File;
  7. use Drupal\KernelTests\KernelTestBase;
  8. use Drupal\language\Entity\ConfigurableLanguage;
  9. use Drupal\media\Entity\Media;
  10. use Drupal\migrate\Plugin\MigrateSourceInterface;
  11. use Drupal\node\Entity\Node;
  12. use Drupal\node\Entity\NodeType;
  13. use Drupal\taxonomy\Entity\Term;
  14. use Drupal\taxonomy\Entity\Vocabulary;
  15. use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
  16. use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
  17. use Drupal\user\Entity\User;
  18. /**
  19. * Tests the entity content source plugin.
  20. *
  21. * @group migrate_drupal
  22. */
  23. class ContentEntityTest extends KernelTestBase {
  24. use EntityReferenceTestTrait;
  25. use MediaTypeCreationTrait;
  26. /**
  27. * {@inheritdoc}
  28. */
  29. protected static $modules = [
  30. 'user',
  31. 'migrate',
  32. 'migrate_drupal',
  33. 'system',
  34. 'node',
  35. 'taxonomy',
  36. 'field',
  37. 'file',
  38. 'image',
  39. 'media',
  40. 'media_test_source',
  41. 'text',
  42. 'filter',
  43. 'language',
  44. 'content_translation',
  45. ];
  46. /**
  47. * The bundle used in this test.
  48. *
  49. * @var string
  50. */
  51. protected $bundle = 'article';
  52. /**
  53. * The name of the field used in this test.
  54. *
  55. * @var string
  56. */
  57. protected $fieldName = 'field_entity_reference';
  58. /**
  59. * The vocabulary ID.
  60. *
  61. * @var string
  62. */
  63. protected $vocabulary = 'fruit';
  64. /**
  65. * The test user.
  66. *
  67. * @var \Drupal\user\Entity\User
  68. */
  69. protected $user;
  70. /**
  71. * The migration plugin manager.
  72. *
  73. * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
  74. */
  75. protected $migrationPluginManager;
  76. /**
  77. * {@inheritdoc}
  78. */
  79. protected function setUp(): void {
  80. parent::setUp();
  81. $this->installEntitySchema('node');
  82. $this->installEntitySchema('file');
  83. $this->installEntitySchema('media');
  84. $this->installEntitySchema('taxonomy_term');
  85. $this->installEntitySchema('taxonomy_vocabulary');
  86. $this->installEntitySchema('user');
  87. $this->installSchema('system', ['sequences']);
  88. $this->installSchema('user', 'users_data');
  89. $this->installSchema('file', 'file_usage');
  90. $this->installSchema('node', ['node_access']);
  91. $this->installConfig(static::$modules);
  92. ConfigurableLanguage::createFromLangcode('fr')->save();
  93. // Create article content type.
  94. $node_type = NodeType::create(['type' => $this->bundle, 'name' => 'Article']);
  95. $node_type->save();
  96. // Create a vocabulary.
  97. $vocabulary = Vocabulary::create([
  98. 'name' => $this->vocabulary,
  99. 'description' => $this->vocabulary,
  100. 'vid' => $this->vocabulary,
  101. 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
  102. ]);
  103. $vocabulary->save();
  104. // Create a term reference field on node.
  105. $this->createEntityReferenceField(
  106. 'node',
  107. $this->bundle,
  108. $this->fieldName,
  109. 'Term reference',
  110. 'taxonomy_term',
  111. 'default',
  112. ['target_bundles' => [$this->vocabulary]],
  113. FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
  114. );
  115. // Create a term reference field on user.
  116. $this->createEntityReferenceField(
  117. 'user',
  118. 'user',
  119. $this->fieldName,
  120. 'Term reference',
  121. 'taxonomy_term',
  122. 'default',
  123. ['target_bundles' => [$this->vocabulary]],
  124. FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
  125. );
  126. // Create a node, with data in a term reference field, and then add a French
  127. // translation of the node.
  128. $this->user = User::create([
  129. 'name' => 'user123',
  130. 'uid' => 1,
  131. 'mail' => 'example@example.com',
  132. ]);
  133. $this->user->save();
  134. // Add the anonymous user so we can test later that it is not provided in a
  135. // source row.
  136. User::create([
  137. 'name' => 'anon',
  138. 'uid' => 0,
  139. ])->save();
  140. $term = Term::create([
  141. 'vid' => $this->vocabulary,
  142. 'name' => 'Apples',
  143. 'uid' => $this->user->id(),
  144. ]);
  145. $term->save();
  146. $this->user->set($this->fieldName, $term->id());
  147. $this->user->save();
  148. $node = Node::create([
  149. 'type' => $this->bundle,
  150. 'title' => 'Apples',
  151. $this->fieldName => $term->id(),
  152. 'uid' => $this->user->id(),
  153. ]);
  154. $node->save();
  155. $node->addTranslation('fr', [
  156. 'title' => 'Pommes',
  157. $this->fieldName => $term->id(),
  158. ])->save();
  159. $this->migrationPluginManager = $this->container->get('plugin.manager.migration');
  160. }
  161. /**
  162. * Helper to assert IDs structure.
  163. *
  164. * @param \Drupal\migrate\Plugin\MigrateSourceInterface $source
  165. * The source plugin.
  166. * @param array $configuration
  167. * The source plugin configuration (Nope, no getter available).
  168. *
  169. * @internal
  170. */
  171. protected function assertIds(MigrateSourceInterface $source, array $configuration): void {
  172. $ids = $source->getIds();
  173. [, $entity_type_id] = explode(PluginBase::DERIVATIVE_SEPARATOR, $source->getPluginId());
  174. $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id);
  175. $this->assertArrayHasKey($entity_type->getKey('id'), $ids);
  176. $ids_count_expected = 1;
  177. if ($entity_type->isTranslatable()) {
  178. $ids_count_expected++;
  179. $this->assertArrayHasKey($entity_type->getKey('langcode'), $ids);
  180. }
  181. if ($entity_type->isRevisionable() && $configuration['add_revision_id']) {
  182. $ids_count_expected++;
  183. $this->assertArrayHasKey($entity_type->getKey('revision'), $ids);
  184. }
  185. $this->assertCount($ids_count_expected, $ids);
  186. }
  187. /**
  188. * Tests user source plugin.
  189. *
  190. * @dataProvider migrationConfigurationProvider
  191. */
  192. public function testUserSource(array $configuration) {
  193. $migration = $this->migrationPluginManager
  194. ->createStubMigration($this->migrationDefinition('content_entity:user', $configuration));
  195. $user_source = $migration->getSourcePlugin();
  196. $this->assertSame('users', $user_source->__toString());
  197. if (!$configuration['include_translations']) {
  198. // Confirm that the anonymous user is in the source database but not
  199. // included in the rows returned by the content_entity.
  200. $this->assertNotNull(User::load(0));
  201. $this->assertEquals(1, $user_source->count());
  202. }
  203. $this->assertIds($user_source, $configuration);
  204. $fields = $user_source->fields();
  205. $this->assertArrayHasKey('name', $fields);
  206. $this->assertArrayHasKey('pass', $fields);
  207. $this->assertArrayHasKey('mail', $fields);
  208. $this->assertArrayHasKey('uid', $fields);
  209. $this->assertArrayHasKey('roles', $fields);
  210. $user_source->rewind();
  211. $values = $user_source->current()->getSource();
  212. $this->assertEquals('example@example.com', $values['mail'][0]['value']);
  213. $this->assertEquals('user123', $values['name'][0]['value']);
  214. $this->assertEquals(1, $values['uid']);
  215. $this->assertEquals(1, $values['field_entity_reference'][0]['target_id']);
  216. }
  217. /**
  218. * Tests file source plugin.
  219. *
  220. * @dataProvider migrationConfigurationProvider
  221. */
  222. public function testFileSource(array $configuration) {
  223. $file = File::create([
  224. 'filename' => 'foo.txt',
  225. 'uid' => $this->user->id(),
  226. 'uri' => 'public://foo.txt',
  227. ]);
  228. $file->save();
  229. $migration = $this->migrationPluginManager
  230. ->createStubMigration($this->migrationDefinition('content_entity:file', $configuration));
  231. $file_source = $migration->getSourcePlugin();
  232. $this->assertSame('files', $file_source->__toString());
  233. if (!$configuration['include_translations']) {
  234. $this->assertEquals(1, $file_source->count());
  235. }
  236. $this->assertIds($file_source, $configuration);
  237. $fields = $file_source->fields();
  238. $this->assertArrayHasKey('fid', $fields);
  239. $this->assertArrayHasKey('filemime', $fields);
  240. $this->assertArrayHasKey('filename', $fields);
  241. $this->assertArrayHasKey('uid', $fields);
  242. $this->assertArrayHasKey('uri', $fields);
  243. $file_source->rewind();
  244. $values = $file_source->current()->getSource();
  245. $this->assertEquals('text/plain', $values['filemime'][0]['value']);
  246. $this->assertEquals('public://foo.txt', $values['uri'][0]['value']);
  247. $this->assertEquals('foo.txt', $values['filename'][0]['value']);
  248. $this->assertEquals(1, $values['fid']);
  249. }
  250. /**
  251. * Tests node source plugin.
  252. *
  253. * @dataProvider migrationConfigurationProvider
  254. */
  255. public function testNodeSource(array $configuration) {
  256. $configuration += ['bundle' => $this->bundle];
  257. $migration = $this->migrationPluginManager
  258. ->createStubMigration($this->migrationDefinition('content_entity:node', $configuration));
  259. $node_source = $migration->getSourcePlugin();
  260. $this->assertSame('content items', $node_source->__toString());
  261. $this->assertIds($node_source, $configuration);
  262. $fields = $node_source->fields();
  263. $this->assertArrayHasKey('nid', $fields);
  264. $this->assertArrayHasKey('vid', $fields);
  265. $this->assertArrayHasKey('title', $fields);
  266. $this->assertArrayHasKey('uid', $fields);
  267. $this->assertArrayHasKey('sticky', $fields);
  268. $node_source->rewind();
  269. $values = $node_source->current()->getSource();
  270. $this->assertEquals($this->bundle, $values['type'][0]['target_id']);
  271. $this->assertEquals(1, $values['nid']);
  272. if ($configuration['add_revision_id']) {
  273. $this->assertEquals(1, $values['vid']);
  274. }
  275. else {
  276. $this->assertEquals([['value' => '1']], $values['vid']);
  277. }
  278. $this->assertEquals('en', $values['langcode']);
  279. $this->assertEquals(1, $values['status'][0]['value']);
  280. $this->assertEquals('Apples', $values['title'][0]['value']);
  281. $this->assertEquals(1, $values['default_langcode'][0]['value']);
  282. $this->assertEquals(1, $values['field_entity_reference'][0]['target_id']);
  283. if ($configuration['include_translations']) {
  284. $node_source->next();
  285. $values = $node_source->current()->getSource();
  286. $this->assertEquals($this->bundle, $values['type'][0]['target_id']);
  287. $this->assertEquals(1, $values['nid']);
  288. if ($configuration['add_revision_id']) {
  289. $this->assertEquals(1, $values['vid']);
  290. }
  291. else {
  292. $this->assertEquals([0 => ['value' => 1]], $values['vid']);
  293. }
  294. $this->assertEquals('fr', $values['langcode']);
  295. $this->assertEquals(1, $values['status'][0]['value']);
  296. $this->assertEquals('Pommes', $values['title'][0]['value']);
  297. $this->assertEquals(0, $values['default_langcode'][0]['value']);
  298. $this->assertEquals(1, $values['field_entity_reference'][0]['target_id']);
  299. }
  300. }
  301. /**
  302. * Tests media source plugin.
  303. *
  304. * @dataProvider migrationConfigurationProvider
  305. */
  306. public function testMediaSource(array $configuration) {
  307. $values = [
  308. 'id' => 'image',
  309. 'label' => 'Image',
  310. 'source' => 'test',
  311. 'new_revision' => FALSE,
  312. ];
  313. $media_type = $this->createMediaType('test', $values);
  314. $media = Media::create([
  315. 'name' => 'Foo media',
  316. 'uid' => $this->user->id(),
  317. 'bundle' => $media_type->id(),
  318. ]);
  319. $media->save();
  320. $configuration += [
  321. 'bundle' => 'image',
  322. ];
  323. $migration = $this->migrationPluginManager
  324. ->createStubMigration($this->migrationDefinition('content_entity:media', $configuration));
  325. $media_source = $migration->getSourcePlugin();
  326. $this->assertSame('media items', $media_source->__toString());
  327. if (!$configuration['include_translations']) {
  328. $this->assertEquals(1, $media_source->count());
  329. }
  330. $this->assertIds($media_source, $configuration);
  331. $fields = $media_source->fields();
  332. $this->assertArrayHasKey('bundle', $fields);
  333. $this->assertArrayHasKey('mid', $fields);
  334. $this->assertArrayHasKey('vid', $fields);
  335. $this->assertArrayHasKey('name', $fields);
  336. $this->assertArrayHasKey('status', $fields);
  337. $media_source->rewind();
  338. $values = $media_source->current()->getSource();
  339. $this->assertEquals(1, $values['mid']);
  340. if ($configuration['add_revision_id']) {
  341. $this->assertEquals(1, $values['vid']);
  342. }
  343. else {
  344. $this->assertEquals([['value' => 1]], $values['vid']);
  345. }
  346. $this->assertEquals('Foo media', $values['name'][0]['value']);
  347. $this->assertNull($values['thumbnail'][0]['title']);
  348. $this->assertEquals(1, $values['uid'][0]['target_id']);
  349. $this->assertEquals('image', $values['bundle'][0]['target_id']);
  350. }
  351. /**
  352. * Tests term source plugin.
  353. *
  354. * @dataProvider migrationConfigurationProvider
  355. */
  356. public function testTermSource(array $configuration) {
  357. $term2 = Term::create([
  358. 'vid' => $this->vocabulary,
  359. 'name' => 'Granny Smith',
  360. 'uid' => $this->user->id(),
  361. 'parent' => 1,
  362. ]);
  363. $term2->save();
  364. $configuration += [
  365. 'bundle' => $this->vocabulary,
  366. ];
  367. $migration = $this->migrationPluginManager
  368. ->createStubMigration($this->migrationDefinition('content_entity:taxonomy_term', $configuration));
  369. $term_source = $migration->getSourcePlugin();
  370. $this->assertSame('taxonomy terms', $term_source->__toString());
  371. if (!$configuration['include_translations']) {
  372. $this->assertEquals(2, $term_source->count());
  373. }
  374. $this->assertIds($term_source, $configuration);
  375. $fields = $term_source->fields();
  376. $this->assertArrayHasKey('vid', $fields);
  377. $this->assertArrayHasKey('revision_id', $fields);
  378. $this->assertArrayHasKey('tid', $fields);
  379. $this->assertArrayHasKey('name', $fields);
  380. $term_source->rewind();
  381. $values = $term_source->current()->getSource();
  382. $this->assertEquals($this->vocabulary, $values['vid'][0]['target_id']);
  383. $this->assertEquals(1, $values['tid']);
  384. $this->assertEquals('Apples', $values['name'][0]['value']);
  385. $this->assertSame([['target_id' => '0']], $values['parent']);
  386. $term_source->next();
  387. $values = $term_source->current()->getSource();
  388. $this->assertEquals($this->vocabulary, $values['vid'][0]['target_id']);
  389. $this->assertEquals(2, $values['tid']);
  390. $this->assertEquals('Granny Smith', $values['name'][0]['value']);
  391. $this->assertSame([['target_id' => '1']], $values['parent']);
  392. }
  393. /**
  394. * Data provider for several test methods.
  395. *
  396. * @see \Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\ContentEntityTest::testUserSource
  397. * @see \Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\ContentEntityTest::testFileSource
  398. * @see \Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\ContentEntityTest::testNodeSource
  399. * @see \Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\ContentEntityTest::testMediaSource
  400. * @see \Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\ContentEntityTest::testTermSource
  401. */
  402. public function migrationConfigurationProvider() {
  403. $data = [];
  404. foreach ([FALSE, TRUE] as $include_translations) {
  405. foreach ([FALSE, TRUE] as $add_revision_id) {
  406. $configuration = [
  407. 'include_translations' => $include_translations,
  408. 'add_revision_id' => $add_revision_id,
  409. ];
  410. // Add an array key for this data set.
  411. $data[http_build_query($configuration)] = [$configuration];
  412. }
  413. }
  414. return $data;
  415. }
  416. /**
  417. * Get a migration definition.
  418. *
  419. * @param string $plugin_id
  420. * The plugin id.
  421. * @param array $configuration
  422. * The plugin configuration.
  423. *
  424. * @return array
  425. * The definition.
  426. */
  427. protected function migrationDefinition($plugin_id, array $configuration = []) {
  428. return [
  429. 'source' => [
  430. 'plugin' => $plugin_id,
  431. ] + $configuration,
  432. 'process' => [],
  433. 'destination' => [
  434. 'plugin' => 'null',
  435. ],
  436. ];
  437. }
  438. }