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

This commit is contained in:
Pantheon Automation 2016-11-02 11:43:31 -07:00 committed by Greg Anderson
parent 23ffed3665
commit 507b45a0ed
378 changed files with 11434 additions and 5542 deletions

View file

@ -0,0 +1,62 @@
<?php
namespace Drupal\Tests\action\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests actions source plugin.
*
* @covers \Drupal\action\Plugin\migrate\source\Action
* @group action
*/
class ActionTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['action', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0][0]['actions'] = [
[
'aid' => 'Redirect to node list page',
'type' => 'system',
'callback' => 'system_goto_action',
'parameters' => 'a:1:{s:3:"url";s:4:"node";}',
'description' => 'Redirect to node list page',
],
[
'aid' => 'Test notice email',
'type' => 'system',
'callback' => 'system_send_email_action',
'parameters' => 'a:3:{s:9:"recipient";s:7:"%author";s:7:"subject";s:4:"Test";s:7:"message";s:4:"Test',
'description' => 'Test notice email',
],
[
'aid' => 'comment_publish_action',
'type' => 'comment',
'callback' => 'comment_publish_action',
'parameters' => NULL,
'description' => NULL,
],
[
'aid' => 'node_publish_action',
'type' => 'comment',
'callback' => 'node_publish_action',
'parameters' => NULL,
'description' => NULL,
],
];
// The expected results are identical to the source data.
$tests[0][1] = $tests[0][0]['actions'];
return $tests;
}
}

View file

@ -1,68 +0,0 @@
<?php
namespace Drupal\Tests\action\Unit\Plugin\migrate\source;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests actions source plugin.
*
* @group action
*/
class ActionTest extends MigrateSqlSourceTestCase {
// The plugin system is not working during unit testing so the source plugin
// class needs to be manually specified.
const PLUGIN_CLASS = 'Drupal\action\Plugin\migrate\source\Action';
// The fake Migration configuration entity.
protected $migrationConfiguration = array(
// The ID of the entity, can be any string.
'id' => 'test',
'source' => array(
'plugin' => 'action',
),
);
// We need to set up the database contents; it's easier to do that below.
protected $expectedResults = array(
array(
'aid' => 'Redirect to node list page',
'type' => 'system',
'callback' => 'system_goto_action',
'parameters' => 'a:1:{s:3:"url";s:4:"node";}',
'description' => 'Redirect to node list page',
),
array(
'aid' => 'Test notice email',
'type' => 'system',
'callback' => 'system_send_email_action',
'parameters' => 'a:3:{s:9:"recipient";s:7:"%author";s:7:"subject";s:4:"Test";s:7:"message";s:4:"Test',
'description' => 'Test notice email',
),
array(
'aid' => 'comment_publish_action',
'type' => 'comment',
'callback' => 'comment_publish_action',
'parameters' => NULL,
'description' => NULL,
),
array(
'aid' => 'node_publish_action',
'type' => 'comment',
'callback' => 'node_publish_action',
'parameters' => NULL,
'description' => NULL,
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['actions'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace Drupal\Tests\aggregator\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 aggregator feed source plugin.
*
* @covers \Drupal\aggregator\Plugin\migrate\source\AggregatorFeed
* @group aggregator
*/
class AggregatorFeedTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['aggregator', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['database']['aggregator_feed'] = [
[
'fid' => 1,
'title' => 'feed title 1',
'url' => 'http://example.com/feed.rss',
'refresh' => 900,
'checked' => 0,
'link' => 'http://example.com',
'description' => 'A vague description',
'image' => '',
'etag' => '',
'modified' => 0,
'block' => 5,
],
[
'fid' => 2,
'title' => 'feed title 2',
'url' => 'http://example.net/news.rss',
'refresh' => 1800,
'checked' => 0,
'link' => 'http://example.net',
'description' => 'An even more vague description',
'image' => '',
'etag' => '',
'modified' => 0,
'block' => 5,
],
];
// The expected results are identical to the source data.
$tests[0]['expected_results'] = $tests[0]['database']['aggregator_feed'];
return $tests;
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace Drupal\Tests\aggregator\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests aggregator item source plugin.
*
* @covers \Drupal\aggregator\Plugin\migrate\source\AggregatorItem
* @group aggregator
*/
class AggregatorItemTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['aggregator', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['database']['aggregator_item'] = [
[
'iid' => 1,
'fid' => 1,
'title' => 'This (three) weeks in Drupal Core - January 10th 2014',
'link' => 'https://groups.drupal.org/node/395218',
'author' => 'larowlan',
'description' => "<h2 id='new'>What's new with Drupal 8?</h2>",
'timestamp' => 1389297196,
'guid' => '395218 at https://groups.drupal.org',
],
];
// The expected results are identical to the source data.
$tests[0]['expected_results'] = $tests[0]['database']['aggregator_item'];
return $tests;
}
}

View file

@ -1,44 +0,0 @@
<?php
namespace Drupal\Tests\aggregator\Unit\Plugin\migrate\source;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests aggregator item source plugin.
*
* @group aggregator
*/
class AggregatorItemTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\aggregator\Plugin\migrate\source\AggregatorItem';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'aggregator_item',
),
);
protected $expectedResults = array(
array(
'iid' => 1,
'fid' => 1,
'title' => 'This (three) weeks in Drupal Core - January 10th 2014',
'link' => 'https://groups.drupal.org/node/395218',
'author' => 'larowlan',
'description' => "<h2 id='new'>What's new with Drupal 8?</h2>",
'timestamp' => 1389297196,
'guid' => '395218 at https://groups.drupal.org',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['aggregator_item'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -1,60 +0,0 @@
<?php
namespace Drupal\Tests\aggregator\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 aggregator feed source plugin.
*
* @group aggregator
*/
class AggregatorFeedTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\aggregator\Plugin\migrate\source\AggregatorFeed';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_aggregator_feed',
),
);
protected $expectedResults = array(
array(
'fid' => 1,
'title' => 'feed title 1',
'url' => 'http://example.com/feed.rss',
'refresh' => 900,
'checked' => 0,
'link' => 'http://example.com',
'description' => 'A vague description',
'image' => '',
'etag' => '',
'modified' => 0,
'block' => 5,
),
array(
'fid' => 2,
'title' => 'feed title 2',
'url' => 'http://example.net/news.rss',
'refresh' => 1800,
'checked' => 0,
'link' => 'http://example.net',
'description' => 'An even more vague description',
'image' => '',
'etag' => '',
'modified' => 0,
'block' => 5,
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['aggregator_feed'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -1,62 +0,0 @@
<?php
namespace Drupal\Tests\aggregator\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 aggregator feed source plugin.
*
* @group aggregator
*/
class AggregatorFeedTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\aggregator\Plugin\migrate\source\AggregatorFeed';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_aggregator_feed',
),
);
protected $expectedResults = array(
array(
'fid' => 1,
'title' => 'feed title 1',
'url' => 'http://example.com/feed.rss',
'refresh' => 900,
'checked' => 0,
'queued' => 0,
'link' => 'http://example.com',
'description' => 'A vague description',
'image' => '',
'etag' => '',
'modified' => 0,
'block' => 5,
),
array(
'fid' => 2,
'title' => 'feed title 2',
'url' => 'http://example.net/news.rss',
'refresh' => 1800,
'checked' => 0,
'queued' => 0,
'link' => 'http://example.net',
'description' => 'An even more vague description',
'image' => '',
'etag' => '',
'modified' => 0,
'block' => 5,
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['aggregator_feed'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\ban\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 blocked_ip source plugin.
*
* @covers \Drupal\ban\Plugin\migrate\source\d7\BlockedIps
* @group ban
*/
class BlockedIpsTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['ban', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['blocked_ips'] = [
[
'iid' => 1,
'ip' => '127.0.0.1',
]
];
$tests[0]['expected_data'] = [
[
'ip' => '127.0.0.1',
],
];
return $tests;
}
}

View file

@ -1,43 +0,0 @@
<?php
namespace Drupal\Tests\ban\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 blocked_ip source plugin.
*
* @coversDefaultClass \Drupal\ban\Plugin\migrate\source\d7\BlockedIps
* @group ban
*/
class BlockedIpsTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\ban\Plugin\migrate\source\d7\BlockedIps';
protected $migrationConfiguration = [
'id' => 'test',
'source' => [
'plugin' => 'd7_blocked_ips',
],
];
protected $expectedResults = [
[
'ip' => '127.0.0.1',
],
];
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['blocked_ips'] = [
[
'iid' => 1,
'ip' => '127.0.0.1',
]
];
parent::setUp();
}
}

View file

@ -237,7 +237,7 @@ class BlockForm extends EntityForm {
// @todo Allow list of conditions to be configured in
// https://www.drupal.org/node/2284687.
$visibility = $this->entity->getVisibility();
foreach ($this->manager->getDefinitions() as $condition_id => $definition) {
foreach ($this->manager->getDefinitionsForContexts($form_state->getTemporaryValue('gathered_contexts')) as $condition_id => $definition) {
// Don't display the current theme condition.
if ($condition_id == 'current_theme') {
continue;

View file

@ -8,7 +8,6 @@ use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Menu\LocalActionManagerInterface;
use Drupal\Core\Plugin\Context\LazyContextRepository;
use Drupal\Core\Routing\RedirectDestinationInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -47,13 +46,6 @@ class BlockLibraryController extends ControllerBase {
*/
protected $localActionManager;
/**
* The redirect destination.
*
* @var \Drupal\Core\Routing\RedirectDestinationInterface
*/
protected $redirectDestination;
/**
* Constructs a BlockLibraryController object.
*
@ -65,15 +57,12 @@ class BlockLibraryController extends ControllerBase {
* The current route match.
* @param \Drupal\Core\Menu\LocalActionManagerInterface $local_action_manager
* The local action manager.
* @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
* The redirect destination.
*/
public function __construct(BlockManagerInterface $block_manager, LazyContextRepository $context_repository, RouteMatchInterface $route_match, LocalActionManagerInterface $local_action_manager, RedirectDestinationInterface $redirect_destination) {
public function __construct(BlockManagerInterface $block_manager, LazyContextRepository $context_repository, RouteMatchInterface $route_match, LocalActionManagerInterface $local_action_manager) {
$this->blockManager = $block_manager;
$this->routeMatch = $route_match;
$this->localActionManager = $local_action_manager;
$this->contextRepository = $context_repository;
$this->redirectDestination = $redirect_destination;
}
/**
@ -84,8 +73,7 @@ class BlockLibraryController extends ControllerBase {
$container->get('plugin.manager.block'),
$container->get('context.repository'),
$container->get('current_route_match'),
$container->get('plugin.manager.menu.local_action'),
$container->get('redirect.destination')
$container->get('plugin.manager.menu.local_action')
);
}
@ -148,10 +136,6 @@ class BlockLibraryController extends ControllerBase {
if (isset($weight)) {
$links['add']['query']['weight'] = $weight;
}
$destination = $this->redirectDestination->get();
if ($destination) {
$links['add']['query']['destination'] = $destination;
}
$row['operations']['data'] = [
'#type' => 'operations',
'#links' => $links,

View file

@ -128,49 +128,6 @@ class BlockTest extends BlockTestBase {
$this->assertNoText($title, 'Block was not displayed to anonymous users on the front page.');
}
/**
* Tests adding a block from the library page with a destination query string.
*/
public function testAddBlockFromLibrary() {
$default_theme = $this->config('system.theme')->get('default');
$help_url = Url::fromRoute('help.page', ['name' => 'block']);
// Set up the request so we land on the block help page after creation.
$options = [
'query' => [
'region' => 'sidebar_first',
'destination' => $help_url->toString(),
],
];
$this->drupalGet(Url::fromRoute('block.admin_library', ['theme' => $default_theme], $options));
$block_name = 'system_powered_by_block';
$add_url = Url::fromRoute('block.admin_add', ['plugin_id' => $block_name, 'theme' => $default_theme]);
$links = $this->xpath('//a[contains(@href, :href)]', [':href' => $add_url->toString()]);
$this->assertEqual(1, count($links), 'Found one matching link');
list($path, $query_string) = explode('?', $links[0]['href'], 2);
parse_str($query_string, $query_parts);
$this->assertEqual(t('Place block'), (string) $links[0]);
$this->assertEqual($help_url->toString(), $query_parts['destination'], 'Expected destination query string is in href');
// Create a random title for the block.
$title = $this->randomMachineName(8);
$block_id = strtolower($this->randomMachineName(8));
$edit = [
'id' => $block_id,
'settings[label]' => $title,
];
// Create the block using the link parsed from the library page.
$this->drupalPostForm($this->getAbsoluteUrl($links[0]['href']), $edit, t('Save block'));
// Verify that we are redirected according to the original request.
$this->assertUrl($help_url);
// Ensure that the block was created.
/** @var \Drupal\block\BlockInterface $block */
$block = Block::load($block_id);
$this->assertEqual($title, $block->label(), 'Found the block with expected title.');
}
/**
* Tests adding a block from the library page with a weight query string.
*/

View file

@ -17,7 +17,7 @@ class BlockUiTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('block', 'block_test', 'help');
public static $modules = array('block', 'block_test', 'help', 'condition_test');
protected $regions;
@ -248,6 +248,11 @@ class BlockUiTest extends WebTestBase {
$this->drupalGet('');
$this->assertText('No context mapping selected.');
$this->assertNoText('User context found.');
// Tests that conditions with missing context are not displayed.
$this->drupalGet('admin/structure/block/manage/testcontextawareblock');
$this->assertNoRaw('No existing type');
$this->assertNoFieldByXPath('//*[@name="visibility[condition_test_no_existing_type][negate]"]');
}
/**

View file

@ -0,0 +1,127 @@
<?php
namespace Drupal\Tests\block\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests block source plugin.
*
* @covers \Drupal\block\Plugin\migrate\source\Block
* @group block
*/
class BlockTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['blocks'] = [
[
'bid' => 1,
'module' => 'block',
'delta' => '1',
'theme' => 'garland',
'status' => 1,
'weight' => 0,
'region' => 'left',
'visibility' => 0,
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
],
[
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'status' => 1,
'weight' => 5,
'region' => 'right',
'visibility' => 0,
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
],
];
$tests[0]['source_data']['blocks_roles'] = [
[
'module' => 'block',
'delta' => 1,
'rid' => 2,
],
[
'module' => 'block',
'delta' => 2,
'rid' => 2,
],
[
'module' => 'block',
'delta' => 2,
'rid' => 100,
],
];
$tests[0]['source_data']['role'] = [
[
'rid' => 2,
'name' => 'authenticated user',
],
];
$tests[0]['source_data']['system'] = [
[
'filename' => 'modules/system/system.module',
'name' => 'system',
'type' => 'module',
'owner' => '',
'status' => '1',
'throttle' => '0',
'bootstrap' => '0',
'schema_version' => '6055',
'weight' => '0',
'info' => 'a:0:{}',
]
];
// The expected results.
$tests[0]['expected_data'] = [
[
'bid' => 1,
'module' => 'block',
'delta' => '1',
'theme' => 'garland',
'status' => 1,
'weight' => 0,
'region' => 'left',
'visibility' => 0,
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
'roles' => [2]
],
[
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'status' => 1,
'weight' => 5,
'region' => 'right',
'visibility' => 0,
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
'roles' => [2]
],
];
return $tests;
}
}

View file

@ -1,144 +0,0 @@
<?php
namespace Drupal\Tests\block\Unit\Plugin\migrate\source;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests block source plugin.
*
* @coversDefaultClass \Drupal\block\Plugin\migrate\source\Block
* @group block
*/
class BlockTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\block\Plugin\migrate\source\Block';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'block',
),
);
/**
* Sample block instance query results from the source.
*/
protected $expectedResults = array(
array(
'bid' => 1,
'module' => 'block',
'delta' => '1',
'theme' => 'garland',
'status' => 1,
'weight' => 0,
'region' => 'left',
'visibility' => 0,
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
'roles' => [2]
),
array(
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'status' => 1,
'weight' => 5,
'region' => 'right',
'visibility' => 0,
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
'roles' => [2]
),
);
/**
* Sample block table.
*/
protected $expectedBlocks = array(
array(
'bid' => 1,
'module' => 'block',
'delta' => '1',
'theme' => 'garland',
'status' => 1,
'weight' => 0,
'region' => 'left',
'visibility' => 0,
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
),
array(
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'status' => 1,
'weight' => 5,
'region' => 'right',
'visibility' => 0,
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
),
);
/**
* Sample block roles table.
*/
protected $expectedBlocksRoles = array(
array(
'module' => 'block',
'delta' => 1,
'rid' => 2,
),
array(
'module' => 'block',
'delta' => 2,
'rid' => 2,
),
array(
'module' => 'block',
'delta' => 2,
'rid' => 100,
),
);
/**
* Sample role table.
*/
protected $expectedRole = array(
array(
'rid' => 2,
'name' => 'authenticated user',
),
);
/**
* Prepopulate database contents.
*/
protected function setUp() {
$this->databaseContents['blocks'] = $this->expectedBlocks;
$this->databaseContents['blocks_roles'] = $this->expectedBlocksRoles;
$this->databaseContents['role'] = $this->expectedRole;
$this->databaseContents['system'] = array(
array(
'filename' => 'modules/system/system.module',
'name' => 'system',
'type' => 'module',
'owner' => '',
'status' => '1',
'throttle' => '0',
'bootstrap' => '0',
'schema_version' => '6055',
'weight' => '0',
'info' => 'a:0:{}',
)
);
parent::setUp();
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\block_content\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 block boxes source plugin.
*
* @covers \Drupal\block_content\Plugin\migrate\source\d6\Box
* @group block_content
*/
class BoxTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block_content', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['boxes'] = [
[
'bid' => 1,
'body' => '<p>I made some custom content.</p>',
'info' => 'Static Block',
'format' => 1,
],
[
'bid' => 2,
'body' => '<p>I made some more custom content.</p>',
'info' => 'Test Content',
'format' => 1,
],
];
// The expected results are identical to the source data.
$tests[0]['expected_data'] = $tests[0]['source_data']['boxes'];
return $tests;
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\block_content\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests d7_block_custom source plugin.
*
* @covers \Drupal\block_content\Plugin\migrate\source\d7\BlockCustom
* @group block_content
*/
class BlockCustomTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block_content', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['block_custom'] = [
[
'bid' => '1',
'body' => "I don't feel creative enough to write anything clever here.",
'info' => 'Meh',
'format' => 'filtered_html',
],
];
// The expected results are identical to the source data.
$tests[0]['expected_data'] = $tests[0]['source_data']['block_custom'];
return $tests;
}
}

View file

@ -1,46 +0,0 @@
<?php
namespace Drupal\Tests\block_content\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 block boxes source plugin.
*
* @group block_content
*/
class BoxTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\block_content\Plugin\migrate\source\d6\Box';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_boxes',
),
);
protected $expectedResults = array(
array(
'bid' => 1,
'body' => '<p>I made some custom content.</p>',
'info' => 'Static Block',
'format' => 1,
),
array(
'bid' => 2,
'body' => '<p>I made some more custom content.</p>',
'info' => 'Test Content',
'format' => 1,
),
);
/**
* Prepopulate contents with results.
*/
protected function setUp() {
$this->databaseContents['boxes'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -1,40 +0,0 @@
<?php
namespace Drupal\Tests\block_content\Unit\Plugin\migrate\source\d7;
use Drupal\block_content\Plugin\migrate\source\d7\BlockCustom;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* @coversDefaultClass \Drupal\block_content\Plugin\migrate\source\d7\BlockCustom
* @group block_content
*/
class BlockCustomTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = BlockCustom::class;
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_block_custom',
),
);
protected $expectedResults = array(
array(
'bid' => '1',
'body' => "I don't feel creative enough to write anything clever here.",
'info' => 'Meh',
'format' => 'filtered_html',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['block_custom'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -17,7 +17,7 @@ function block_place_help($route_name, RouteMatchInterface $route_match) {
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Place Blocks module allows you to place blocks from every page. For more information, see the <a href=":blocks-documentation">online documentation for the Place Blocks module</a>.', [':blocks-documentation' => 'https://www.drupal.org/documentation/modules/block_place/']) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<p>' . t('Block placement is specific to each theme on your site. This module allows you to place blocks in the context of your content pages') . '</p>';
$output .= '<p>' . t('Block placement is specific to each theme on your site. This module allows you to place blocks in the context of your content pages.') . '</p>';
return $output;
}
}

View file

@ -156,9 +156,12 @@ class BookNavigationBlock extends BlockBase implements ContainerFactoryPluginInt
}
}
elseif ($current_bid) {
// Only display this block when the user is browsing a book.
$query = \Drupal::entityQuery('node');
$nid = $query->condition('nid', $node->book['bid'], '=')->execute();
// Only display this block when the user is browsing a book and do
// not show unpublished books.
$nid = \Drupal::entityQuery('node')
->condition('nid', $node->book['bid'], '=')
->condition('status', NODE_PUBLISHED)
->execute();
// Only show the block if the user has view access for the top-level node.
if ($nid) {

View file

@ -570,34 +570,6 @@ class BookTest extends WebTestBase {
$this->assertEqual($child->id(), $second->book['bid'], '3rd-level child node is now second level when top-level node is deleted.');
}
/**
* Tests re-ordering of books.
*/
public function testBookOrdering() {
// Create new book.
$this->createBook();
$book = $this->book;
$this->drupalLogin($this->adminUser);
$node1 = $this->createBookNode($book->id());
$node2 = $this->createBookNode($book->id());
$pid = $node1->book['nid'];
// Head to admin screen and attempt to re-order.
$this->drupalGet('admin/structure/book/' . $book->id());
$edit = array(
"table[book-admin-{$node1->id()}][weight]" => 1,
"table[book-admin-{$node2->id()}][weight]" => 2,
// Put node 2 under node 1.
"table[book-admin-{$node2->id()}][pid]" => $pid,
);
$this->drupalPostForm(NULL, $edit, t('Save book pages'));
// Verify weight was updated.
$this->assertFieldByName("table[book-admin-{$node1->id()}][weight]", 1);
$this->assertFieldByName("table[book-admin-{$node2->id()}][weight]", 2);
$this->assertFieldByName("table[book-admin-{$node2->id()}][pid]", $pid);
}
/**
* Tests outline of a book.
*/
@ -752,4 +724,29 @@ class BookTest extends WebTestBase {
$this->assertEqual($book_node->book['bid'], $this->book->id());
}
/**
* Tests the book navigation block when book is unpublished.
*
* There was a fatal error with "Show block only on book pages" block mode.
*/
public function testBookNavigationBlockOnUnpublishedBook() {
// Create a new book.
$this->createBook();
// Create administrator user.
$administratorUser = $this->drupalCreateUser(['administer blocks', 'administer nodes', 'bypass node access']);
$this->drupalLogin($administratorUser);
// Enable the block with "Show block only on book pages" mode.
$this->drupalPlaceBlock('book_navigation', ['block_mode' => 'book pages']);
// Unpublish book node.
$edit = [];
$this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save and unpublish'));
// Test node page.
$this->drupalGet('node/' . $this->book->id());
$this->assertText($this->book->label(), 'Unpublished book with "Show block only on book pages" book navigation settings.');
}
}

View file

@ -0,0 +1,160 @@
<?php
namespace Drupal\Tests\book\FunctionalJavascript;
use Behat\Mink\Exception\ExpectationException;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
use Drupal\node\Entity\Node;
/**
* Tests Book javascript functionality.
*
* @group book
*/
class BookJavascriptTest extends JavascriptTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['book'];
/**
* Tests re-ordering of books.
*/
public function testBookOrdering() {
$book = Node::create([
'type' => 'book',
'title' => 'Book',
'book' => ['bid' => 'new'],
]);
$book->save();
$page1 = Node::create([
'type' => 'book',
'title' => '1st page',
'book' => ['bid' => $book->id(), 'pid' => $book->id(), 'weight' => 0],
]);
$page1->save();
$page2 = Node::create([
'type' => 'book',
'title' => '2nd page',
'book' => ['bid' => $book->id(), 'pid' => $book->id(), 'weight' => 1],
]);
$page2->save();
// Head to admin screen and attempt to re-order.
$this->drupalLogin($this->drupalCreateUser(['administer book outlines']));
$this->drupalGet('admin/structure/book/' . $book->id());
$page = $this->getSession()->getPage();
$weight_select1 = $page->findField("table[book-admin-{$page1->id()}][weight]");
$weight_select2 = $page->findField("table[book-admin-{$page2->id()}][weight]");
// Check that rows weight selects are hidden.
$this->assertFalse($weight_select1->isVisible());
$this->assertFalse($weight_select2->isVisible());
// Check that '2nd page' row is heavier than '1st page' row.
$this->assertGreaterThan($weight_select1->getValue(), $weight_select2->getValue());
// Check that '1st page' precedes the '2nd page'.
$this->assertOrderInPage(['1st page', '2nd page']);
// Check that the 'unsaved changes' text is not present in the message area.
$this->assertSession()->pageTextNotContains('You have unsaved changes.');
// Drag and drop the '1st page' row over the '2nd page' row.
// @todo: Test also the reverse, '2nd page' over '1st page', when
// https://www.drupal.org/node/2769825 is fixed.
// @see https://www.drupal.org/node/2769825
$dragged = $this->xpath("//tr[@data-drupal-selector='edit-table-book-admin-{$page1->id()}']//a[@class='tabledrag-handle']")[0];
$target = $this->xpath("//tr[@data-drupal-selector='edit-table-book-admin-{$page2->id()}']//a[@class='tabledrag-handle']")[0];
$dragged->dragTo($target);
// Give javascript some time to manipulate the DOM.
$this->getSession()->wait(1000, 'jQuery(".tabledrag-changed-warning").is(":visible")');
// Check that the 'unsaved changes' text appeared in the message area.
$this->assertSession()->pageTextContains('You have unsaved changes.');
// Check that '2nd page' page precedes the '1st page'.
$this->assertOrderInPage(['2nd page', '1st page']);
$this->submitForm([], 'Save book pages');
$this->assertSession()->pageTextContains(new FormattableMarkup('Updated book @book.', ['@book' => $book->getTitle()]));
// Check that page reordering was done in the backend for drag-n-drop.
$page1 = Node::load($page1->id());
$page2 = Node::load($page2->id());
$this->assertGreaterThan($page2->book['weight'], $page1->book['weight']);
// Check again that '2nd page' is on top after form submit in the UI.
$this->assertOrderInPage(['2nd page', '1st page']);
// Toggle row weight selects as visible.
$page->findButton('Show row weights')->click();
// Check that rows weight selects are visible.
$this->assertTrue($weight_select1->isVisible());
$this->assertTrue($weight_select2->isVisible());
// Check that '1st page' row became heavier than '2nd page' row.
$this->assertGreaterThan($weight_select2->getValue(), $weight_select1->getValue());
// Reverse again using the weight fields. Use the current values so the test
// doesn't rely on knowing the values in the select boxes.
$value1 = $weight_select1->getValue();
$value2 = $weight_select2->getValue();
$weight_select1->setValue($value2);
$weight_select2->setValue($value1);
// Toggle row weight selects back to hidden.
$page->findButton('Hide row weights')->click();
// Check that rows weight selects are hidden again.
$this->assertFalse($weight_select1->isVisible());
$this->assertFalse($weight_select2->isVisible());
$this->submitForm([], 'Save book pages');
$this->assertSession()->pageTextContains(new FormattableMarkup('Updated book @book.', ['@book' => $book->getTitle()]));
// Check that the '1st page' is first again.
$this->assertOrderInPage(['1st page', '2nd page']);
// Check that page reordering was done in the backend for manual weight
// field usage.
$page1 = Node::load($page1->id());
$page2 = Node::load($page2->id());
$this->assertGreaterThan($page2->book['weight'], $page1->book['weight']);
}
/**
* Asserts that several pieces of markup are in a given order in the page.
*
* @param string[] $items
* An ordered list of strings.
*
* @throws \Behat\Mink\Exception\ExpectationException
* When any of the given string is not found.
*
* @todo Remove this once https://www.drupal.org/node/2817657 is committed.
*/
protected function assertOrderInPage(array $items) {
$session = $this->getSession();
$text = $session->getPage()->getHtml();
$strings = [];
foreach ($items as $item) {
if (($pos = strpos($text, $item)) === FALSE) {
throw new ExpectationException("Cannot find '$item' in the page", $session->getDriver());
}
$strings[$pos] = $item;
}
ksort($strings);
$ordered = implode(', ', array_map(function ($item) {
return "'$item'";
}, $items));
$this->assertSame($items, array_values($strings), "Found strings, ordered as: $ordered.");
}
}

View file

@ -0,0 +1,84 @@
<?php
namespace Drupal\Tests\book\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* @covers \Drupal\book\Plugin\migrate\source\d6\Book
* @group book
*/
class BookTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['book', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['book'] = [
[
'mlid' => '1',
'nid' => '4',
'bid' => '4',
],
];
$tests[0]['source_data']['menu_links'] = [
[
'menu_name' => 'book-toc-1',
'mlid' => '1',
'plid' => '0',
'link_path' => 'node/4',
'router_path' => 'node/%',
'link_title' => 'Test top book title',
'options' => 'a:0:{}',
'module' => 'book',
'hidden' => '0',
'external' => '0',
'has_children' => '1',
'expanded' => '0',
'weight' => '-10',
'depth' => '1',
'customized' => '0',
'p1' => '1',
'p2' => '0',
'p3' => '0',
'p4' => '0',
'p5' => '0',
'p6' => '0',
'p7' => '0',
'p8' => '0',
'p9' => '0',
'updated' => '0',
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'nid' => '4',
'bid' => '4',
'mlid' => '1',
'plid' => '0',
'weight' => '-10',
'p1' => '1',
'p2' => '0',
'p3' => '0',
'p4' => '0',
'p5' => '0',
'p6' => '0',
'p7' => '0',
'p8' => '0',
'p9' => '0',
],
];
return $tests;
}
}

View file

@ -1,85 +0,0 @@
<?php
namespace Drupal\Tests\book\Unit\Plugin\migrate\source\d6;
use Drupal\book\Plugin\migrate\source\d6\Book;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* @coversDefaultClass \Drupal\book\Plugin\migrate\source\d6\Book
* @group book
*/
class BookTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = Book::class;
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_book',
),
);
protected $expectedResults = array(
array(
'nid' => '4',
'bid' => '4',
'mlid' => '1',
'plid' => '0',
'weight' => '-10',
'p1' => '1',
'p2' => '0',
'p3' => '0',
'p4' => '0',
'p5' => '0',
'p6' => '0',
'p7' => '0',
'p8' => '0',
'p9' => '0',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['book'] = array(
array(
'mlid' => '1',
'nid' => '4',
'bid' => '4',
),
);
$this->databaseContents['menu_links'] = array(
array(
'menu_name' => 'book-toc-1',
'mlid' => '1',
'plid' => '0',
'link_path' => 'node/4',
'router_path' => 'node/%',
'link_title' => 'Test top book title',
'options' => 'a:0:{}',
'module' => 'book',
'hidden' => '0',
'external' => '0',
'has_children' => '1',
'expanded' => '0',
'weight' => '-10',
'depth' => '1',
'customized' => '0',
'p1' => '1',
'p2' => '0',
'p3' => '0',
'p4' => '0',
'p5' => '0',
'p6' => '0',
'p7' => '0',
'p8' => '0',
'p9' => '0',
'updated' => '0',
),
);
parent::setUp();
}
}

View file

@ -5,6 +5,7 @@ namespace Drupal\ckeditor\Plugin\CKEditorPlugin;
use Drupal\ckeditor\CKEditorPluginBase;
use Drupal\ckeditor\CKEditorPluginContextualInterface;
use Drupal\ckeditor\CKEditorPluginManager;
use Drupal\Component\Utility\Html;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@ -369,7 +370,7 @@ class Internal extends CKEditorPluginBase implements ContainerFactoryPluginInter
foreach ($possible_format_tags as $tag) {
$input = '<' . $tag . '>TEST</' . $tag . '>';
$output = trim(check_markup($input, $editor->id()));
if ($input == $output) {
if (Html::load($output)->getElementsByTagName($tag)->length !== 0) {
$format_tags[] = $tag;
}
}

View file

@ -5,3 +5,12 @@ ckeditor.plugin.llama_contextual_and_button:
ultra_llama_mode:
type: boolean
label: 'Ultra llama mode'
filter_settings.test_attribute_filter:
type: filter
label: 'Test Attribute Filter'
mapping:
tags:
type: sequence
sequence:
type: string

View file

@ -0,0 +1,38 @@
<?php
namespace Drupal\ckeditor_test\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
/**
* A filter that adds a test attribute to any configured HTML tags.
*
* @Filter(
* id = "test_attribute_filter",
* title = @Translation("Test Attribute Filter"),
* type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE,
* settings = {
* "tags" = {},
* },
* weight = -10
* )
*/
class TestAttributeFilter extends FilterBase {
/**
* {@inheritdoc}
*/
public function process($text, $langcode) {
$document = Html::load($text);
foreach ($this->settings['tags'] as $tag) {
$tag_elements = $document->getElementsByTagName($tag);
foreach ($tag_elements as $tag_element) {
$tag_element->setAttribute('test_attribute', 'test attribute value');
}
}
return new FilterProcessResult(Html::serialize($document));
}
}

View file

@ -0,0 +1,140 @@
<?php
namespace Drupal\Tests\ckeditor\Kernel\Plugin\CKEditorPlugin;
use Drupal\editor\Entity\Editor;
use Drupal\filter\Entity\FilterFormat;
use Drupal\KernelTests\KernelTestBase;
/**
* @coversDefaultClass \Drupal\ckeditor\Plugin\CKEditorPlugin\Internal
*
* @group ckeditor
*/
class InternalTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'ckeditor',
'ckeditor_test',
'filter',
'editor',
];
/**
* A testing text format.
*
* @var \Drupal\filter\Entity\FilterFormat
*/
protected $format;
/**
* A testing text editor.
*
* @var \Drupal\editor\Entity\Editor
*/
protected $editor;
/**
* The CKEditor plugin manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $ckeditorPluginManager;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('editor');
$this->installEntitySchema('filter_format');
$this->format = FilterFormat::create([
'format' => 'test_format',
'name' => $this->randomMachineName(),
]);
$this->format->save();
$this->editor = Editor::create([
'editor' => 'ckeditor',
'format' => 'test_format',
'settings' => [
'toolbar' => [
'rows' => [
[
[
'name' => 'Enabled Buttons',
'items' => [
'Format',
],
],
],
],
],
],
]);
$this->editor->save();
$this->ckeditorPluginManager = $this->container->get('plugin.manager.ckeditor.plugin');
}
/**
* Test the format tags settings.
*
* @dataProvider formatTagsSettingsTestCases
*/
public function testFormatTagsSettings($filter_plugins, $expected_format_tags) {
foreach ($filter_plugins as $filter_plugin_id => $filter_plugin_settings) {
$this->format->setFilterConfig($filter_plugin_id, $filter_plugin_settings);
}
$this->format->save();
$internal_plugin = $this->ckeditorPluginManager->createInstance('internal', []);
$plugin_config = $internal_plugin->getConfig($this->editor);
$this->assertEquals($expected_format_tags, explode(';', $plugin_config['format_tags']));
}
/**
* A data provider for testFormatTagsSettings.
*/
public function formatTagsSettingsTestCases() {
$all_tags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre'];
return [
'No filter plugins enabled (all tags allowed)' => [
[],
$all_tags,
],
'HTML filter plugin enabled (some tags filtered out)' => [
[
'filter_html' => [
'status' => 1,
'settings' => [
'allowed_html' => '<h1> <h2>',
'filter_html_help' => 1,
'filter_html_nofollow' => 0,
],
],
],
['p', 'h1', 'h2'],
],
'Test attribute filter enabled (all tags allowed)' => [
[
'test_attribute_filter' => [
'status' => 1,
'settings' => [
'tags' => ['h1', 'h2'],
],
],
],
$all_tags,
],
];
}
}

View file

@ -12,8 +12,8 @@ process:
source: category
-
plugin: dedupe_entity
entity_type: user_role
field: cid
entity_type: contact_form
field: id
length: 32
label: category
recipients: recipients

View file

@ -122,7 +122,14 @@ class MailHandler implements MailHandlerInterface {
if (!$message->isPersonal() && $contact_form->getReply()) {
// User contact forms do not support an auto-reply message, so this
// message always originates from the site.
$this->mailManager->mail('contact', 'page_autoreply', $sender_cloned->getEmail(), $current_langcode, $params);
if (!$sender_cloned->getEmail()) {
$this->logger->error('Error sending auto-reply, missing sender e-mail address in %contact_form', [
'%contact_form' => $contact_form->label(),
]);
}
else {
$this->mailManager->mail('contact', 'page_autoreply', $sender_cloned->getEmail(), $current_langcode, $params);
}
}
if (!$message->isPersonal()) {

View file

@ -27,7 +27,7 @@ class ContactSitewideTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('text', 'contact', 'field_ui', 'contact_test', 'block');
public static $modules = ['text', 'contact', 'field_ui', 'contact_test', 'block', 'error_service_test', 'dblog'];
/**
* {@inheritdoc}
@ -44,13 +44,13 @@ class ContactSitewideTest extends WebTestBase {
*/
function testSiteWideContact() {
// Create and log in administrative user.
$admin_user = $this->drupalCreateUser(array(
$admin_user = $this->drupalCreateUser([
'access site-wide contact form',
'administer contact forms',
'administer users',
'administer account settings',
'administer contact_message fields',
));
]);
$this->drupalLogin($admin_user);
// Check the presence of expected cache tags.
@ -346,7 +346,13 @@ class ContactSitewideTest extends WebTestBase {
*/
function testAutoReply() {
// Create and log in administrative user.
$admin_user = $this->drupalCreateUser(array('access site-wide contact form', 'administer contact forms', 'administer permissions', 'administer users'));
$admin_user = $this->drupalCreateUser([
'access site-wide contact form',
'administer contact forms',
'administer permissions',
'administer users',
'access site reports'
]);
$this->drupalLogin($admin_user);
// Set up three forms, 2 with an auto-reply and one without.
@ -384,6 +390,20 @@ class ContactSitewideTest extends WebTestBase {
$this->submitContact($this->randomMachineName(16), $email, $this->randomString(64), 'no_autoreply', $this->randomString(128));
$captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email));
$this->assertEqual(count($captured_emails), 0);
// Verify that the current error message doesn't show, that the auto-reply
// doesn't get sent and the correct silent error gets logged.
$email = '';
entity_get_form_display('contact_message', 'foo', 'default')
->removeComponent('mail')
->save();
$this->submitContact($this->randomMachineName(16), $email, $this->randomString(64), 'foo', $this->randomString(128));
$this->assertNoText('Unable to send email. Contact the site administrator if the problem persists.');
$captured_emails = $this->drupalGetMails(['id' => 'contact_page_autoreply', 'to' => $email]);
$this->assertEqual(count($captured_emails), 0);
$this->drupalLogin($admin_user);
$this->drupalGet('admin/reports/dblog');
$this->assertRaw('Error sending auto-reply, missing sender e-mail address in foo');
}
/**

View file

@ -47,6 +47,29 @@ class MigrateContactCategoryTest extends MigrateDrupal6TestBase {
$this->assertIdentical(array('fortyninechars@example.com'), $contact_form->getRecipients());
$this->assertIdentical('', $contact_form->getReply());
$this->assertIdentical(2, $contact_form->getWeight());
// Test there are no duplicated roles.
$contact_forms = [
'website_feedback1',
'some_other_category1',
'a_category_much_longer_than_thir1',
];
$this->assertEmpty(ContactForm::loadMultiple($contact_forms));
/*
* Remove the map row for the Website feedback contact form so that it
* can be migrated again.
*/
$id_map = $this->getMigration('contact_category')->getIdMap();
$id_map->delete(['cid' => '1']);
$this->executeMigration('contact_category');
// Test there is a duplicate Website feedback form.
$contact_form = ContactForm::load('website_feedback1');
$this->assertSame('Website feedback', $contact_form->label());
$this->assertSame(array('admin@example.com'), $contact_form->getRecipients());
$this->assertSame('', $contact_form->getReply());
$this->assertSame(0, $contact_form->getWeight());
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace Drupal\Tests\contact\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 contact category source plugin.
*
* @covers \Drupal\contact\Plugin\migrate\source\ContactCategory
* @group contact
*/
class ContactCategoryTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['contact', 'migrate_drupal', 'user'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
$tests[0]['expected_data'] = [
[
'cid' => 1,
'category' => 'contact category value 1',
'recipients' => ['admin@example.com', 'user@example.com'],
'reply' => 'auto reply value 1',
'weight' => 0,
'selected' => 0,
],
[
'cid' => 2,
'category' => 'contact category value 2',
'recipients' => ['admin@example.com', 'user@example.com'],
'reply' => 'auto reply value 2',
'weight' => 0,
'selected' => 0,
],
];
foreach ($tests[0]['expected_data'] as $k => $row) {
$row['recipients'] = implode(',', $row['recipients']);
$tests[0]['source_data']['contact'][$k] = $row;
}
return $tests;
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace Drupal\Tests\contact\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 contact settings source plugin.
*
* @covers \Drupal\contact\Plugin\migrate\source\ContactSettings
* @group contact
*/
class ContactSettingsTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['contact', 'migrate_drupal', 'user'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['variable'] = [
[
'name' => 'site_name',
'value' => serialize('Blorf!'),
],
];
$tests[0]['source_data']['contact'] = [
[
'cid' => '1',
'category' => 'Website feedback',
'recipients' => 'admin@example.com',
'reply' => '',
'weight' => '0',
'selected' => '1',
]
];
$tests[0]['expected_data'] = [
[
'default_category' => '1',
'site_name' => 'Blorf!',
],
];
$tests[0]['expected_count'] = NULL;
$tests[0]['configuration']['variables'] = ['site_name'];
return $tests;
}
}

View file

@ -1,54 +0,0 @@
<?php
namespace Drupal\Tests\contact\Unit\Plugin\migrate\source;
use Drupal\contact\Plugin\migrate\source\ContactCategory;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests contact_category source plugin.
*
* @group contact
*/
class ContactCategoryTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = ContactCategory::class;
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'contact_category',
),
);
protected $expectedResults = array(
array(
'cid' => 1,
'category' => 'contact category value 1',
'recipients' => array('admin@example.com', 'user@example.com'),
'reply' => 'auto reply value 1',
'weight' => 0,
'selected' => 0,
),
array(
'cid' => 2,
'category' => 'contact category value 2',
'recipients' => array('admin@example.com', 'user@example.com'),
'reply' => 'auto reply value 2',
'weight' => 0,
'selected' => 0,
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $k => $row) {
$this->databaseContents['contact'][$k] = $row;
$this->databaseContents['contact'][$k]['recipients'] = implode(',', $row['recipients']);
}
parent::setUp();
}
}

View file

@ -1,55 +0,0 @@
<?php
namespace Drupal\Tests\contact\Unit\Plugin\migrate\source\d6;
use Drupal\contact\Plugin\migrate\source\ContactSettings;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 contact settings source plugin.
*
* @group contact
*/
class ContactSettingsTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = ContactSettings::class;
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_contact_settings',
'variables' => array('site_name'),
),
);
protected $expectedResults = array(
array(
'default_category' => '1',
'site_name' => 'Blorf!',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['variable'] = array(
array(
'name' => 'site_name',
'value' => serialize('Blorf!'),
),
);
$this->databaseContents['contact'] = array(
array(
'cid' => '1',
'category' => 'Website feedback',
'recipients' => 'admin@example.com',
'reply' => '',
'weight' => '0',
'selected' => '1',
)
);
parent::setUp();
}
}

View file

@ -4,7 +4,6 @@ namespace Drupal\content_moderation\Entity;
use Drupal\content_moderation\ContentModerationStateInterface;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\TypedData\TranslatableInterface;
@ -42,8 +41,6 @@ use Drupal\user\UserInterface;
*/
class ContentModerationState extends ContentEntityBase implements ContentModerationStateInterface {
use EntityChangedTrait;
/**
* {@inheritdoc}
*/

View file

@ -4,7 +4,6 @@ namespace Drupal\content_moderation;
use Drupal\content_moderation\Entity\ContentModerationState;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
@ -77,32 +76,6 @@ class EntityOperations implements ContainerInjectionInterface {
);
}
/**
* Determines the default moderation state on load for an entity.
*
* This method is only applicable when an entity is loaded that has
* no moderation state on it, but should. In those cases, failing to set
* one may result in NULL references elsewhere when other code tries to check
* the moderation state of the entity.
*
* The amount of indirection here makes performance a concern, but
* given how Entity API works I don't know how else to do it.
* This reliably gets us *A* valid state. However, that state may be
* not the ideal one. Suggestions on how to better select the default
* state here are welcome.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity for which we want a default state.
*
* @return string
* The default state for the given entity.
*/
protected function getDefaultLoadStateId(ContentEntityInterface $entity) {
return $this->moderationInfo
->loadBundleEntity($entity->getEntityType()->getBundleEntityType(), $entity->bundle())
->getThirdPartySetting('content_moderation', 'default_moderation_state');
}
/**
* Acts on an entity and set published status based on the moderation state.
*
@ -170,8 +143,8 @@ class EntityOperations implements ContainerInjectionInterface {
$moderation_state = $entity->moderation_state->target_id;
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
if (!$moderation_state) {
$moderation_state = $this->moderationInfo
->loadBundleEntity($entity->getEntityType()->getBundleEntityType(), $entity->bundle())
$moderation_state = $this->entityTypeManager
->getStorage($entity->getEntityType()->getBundleEntityType())->load($entity->bundle())
->getThirdPartySetting('content_moderation', 'default_moderation_state');
}

View file

@ -49,21 +49,15 @@ class ModerationInformation implements ModerationInformationInterface {
return $entity_type->hasHandlerClass('moderation');
}
/**
* {@inheritdoc}
*/
public function loadBundleEntity($bundle_entity_type_id, $bundle_id) {
if ($bundle_entity_type_id) {
return $this->entityTypeManager->getStorage($bundle_entity_type_id)->load($bundle_id);
}
}
/**
* {@inheritdoc}
*/
public function shouldModerateEntitiesOfBundle(EntityTypeInterface $entity_type, $bundle) {
if ($bundle_entity = $this->loadBundleEntity($entity_type->getBundleEntityType(), $bundle)) {
return $bundle_entity->getThirdPartySetting('content_moderation', 'enabled', FALSE);
if ($this->canModerateEntitiesOfEntityType($entity_type)) {
$bundle_entity = $this->entityTypeManager->getStorage($entity_type->getBundleEntityType())->load($bundle);
if ($bundle_entity) {
return $bundle_entity->getThirdPartySetting('content_moderation', 'enabled', FALSE);
}
}
return FALSE;
}

View file

@ -11,19 +11,6 @@ use Drupal\Core\Entity\EntityTypeInterface;
*/
interface ModerationInformationInterface {
/**
* Loads a specific bundle entity.
*
* @param string $bundle_entity_type_id
* The bundle entity type ID.
* @param string $bundle_id
* The bundle ID.
*
* @return \Drupal\Core\Config\Entity\ConfigEntityInterface|null
* The bundle entity.
*/
public function loadBundleEntity($bundle_entity_type_id, $bundle_id);
/**
* Determines if an entity is moderated.
*

View file

@ -57,8 +57,9 @@ class ModerationStateFieldItemList extends EntityReferenceFieldItemList {
// It is possible that the bundle does not exist at this point. For example,
// the node type form creates a fake Node entity to get default values.
// @see \Drupal\node\NodeTypeForm::form()
$bundle_entity = \Drupal::service('content_moderation.moderation_information')
->loadBundleEntity($entity->getEntityType()->getBundleEntityType(), $entity->bundle());
$bundle_entity = \Drupal::entityTypeManager()
->getStorage($entity->getEntityType()->getBundleEntityType())
->load($entity->bundle());
if ($bundle_entity && ($default = $bundle_entity->getThirdPartySetting('content_moderation', 'default_moderation_state'))) {
return ModerationState::load($default);
}
@ -71,7 +72,24 @@ class ModerationStateFieldItemList extends EntityReferenceFieldItemList {
if ($index !== 0) {
throw new \InvalidArgumentException('An entity can not have multiple moderation states at the same time.');
}
$this->computeModerationFieldItemList();
return isset($this->list[$index]) ? $this->list[$index] : NULL;
}
/**
* {@inheritdoc}
*/
public function getIterator() {
$this->computeModerationFieldItemList();
return parent::getIterator();
}
/**
* Recalculate the moderation field item list.
*/
protected function computeModerationFieldItemList() {
// Compute the value of the moderation state.
$index = 0;
if (!isset($this->list[$index]) || $this->list[$index]->isEmpty()) {
$moderation_state = $this->getModerationState();
// Do not store NULL values in the static cache.
@ -79,8 +97,6 @@ class ModerationStateFieldItemList extends EntityReferenceFieldItemList {
$this->list[$index] = $this->createItem($index, ['entity' => $moderation_state]);
}
}
return isset($this->list[$index]) ? $this->list[$index] : NULL;
}
}

View file

@ -97,8 +97,8 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
$new_state_id = $entity->moderation_state->target_id;
}
else {
$new_state_id = $default = $this->moderationInformation
->loadBundleEntity($entity->getEntityType()->getBundleEntityType(), $entity->bundle())
$new_state_id = $default = $this->entityTypeManager
->getStorage($entity->getEntityType()->getBundleEntityType())->load($entity->bundle())
->getThirdPartySetting('content_moderation', 'default_moderation_state');
}
if ($new_state_id) {

View file

@ -0,0 +1,78 @@
<?php
namespace Drupal\Tests\content_moderation\Kernel;
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
/**
* @coversDefaultClass \Drupal\content_moderation\Plugin\Field\ModerationStateFieldItemList
*
* @group content_moderation
*/
class ModerationStateFieldItemListTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'node',
'content_moderation',
'user',
'system',
'language',
];
/**
* @var \Drupal\node\NodeInterface
*/
protected $testNode;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('node', 'node_access');
$this->installEntitySchema('node');
$this->installEntitySchema('user');
$this->installEntitySchema('content_moderation_state');
$this->installConfig('content_moderation');
$node_type = NodeType::create([
'type' => 'example',
]);
$node_type->setThirdPartySetting('content_moderation', 'enabled', TRUE);
$node_type->setThirdPartySetting('content_moderation', 'allowed_moderation_states', ['draft']);
$node_type->setThirdPartySetting('content_moderation', 'default_moderation_state', 'draft');
$node_type->save();
$this->testNode = Node::create([
'type' => 'example',
'title' => 'Test title',
]);
$this->testNode->save();
\Drupal::entityTypeManager()->getStorage('node')->resetCache();
$this->testNode = Node::load($this->testNode->id());
}
/**
* Test the field item list when accessing an index.
*/
public function testArrayIndex() {
$this->assertEquals('draft', $this->testNode->moderation_state[0]->entity->id());
}
/**
* Test the field item list when iterating.
*/
public function testArrayIteration() {
$states = [];
foreach ($this->testNode->moderation_state as $item) {
$states[] = $item->entity->id();
}
$this->assertEquals(['draft'], $states);
}
}

View file

@ -2,6 +2,7 @@
namespace Drupal\Tests\content_moderation\Unit;
use Drupal\content_moderation\Entity\Handler\ModerationHandler;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\ContentEntityType;
@ -70,6 +71,7 @@ class ModerationInformationTest extends \PHPUnit_Framework_TestCase {
$entity_type = new ContentEntityType([
'id' => 'test_entity_type',
'bundle_entity_type' => 'entity_test_bundle',
'handlers' => ['moderation' => ModerationHandler::class],
]);
$entity = $this->prophesize(ContentEntityInterface::class);
$entity->getEntityType()->willReturn($entity_type);
@ -104,6 +106,7 @@ class ModerationInformationTest extends \PHPUnit_Framework_TestCase {
$entity_type = new ContentEntityType([
'id' => 'test_entity_type',
'bundle_entity_type' => 'entity_test_bundle',
'handlers' => ['moderation' => ModerationHandler::class],
]);
$moderation_information = new ModerationInformation($this->setupModerationEntityManager($status), $this->getUser());

View file

@ -92,11 +92,19 @@ class DateTimeFieldItemList extends FieldItemList {
$default_value = parent::processDefaultValue($default_value, $entity, $definition);
if (isset($default_value[0]['default_date_type'])) {
// A default value should be in the format and timezone used for date
// storage.
$date = new DrupalDateTime($default_value[0]['default_date'], DATETIME_STORAGE_TIMEZONE);
$storage_format = $definition->getSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT;
$value = $date->format($storage_format);
if ($definition->getSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE) {
// A default date only value should be in the format used for date
// storage but in the user's local timezone.
$date = new DrupalDateTime($default_value[0]['default_date'], drupal_get_user_timezone());
$format = DATETIME_DATE_STORAGE_FORMAT;
}
else {
// A default date+time value should be in the format and timezone used
// for date storage.
$date = new DrupalDateTime($default_value[0]['default_date'], DATETIME_STORAGE_TIMEZONE);
$format = DATETIME_DATETIME_STORAGE_FORMAT;
}
$value = $date->format($format);
// We only provide a default value for the first item, as do all fields.
// Otherwise, there is no way to clear out unwanted values on multiple value
// fields.

View file

@ -594,83 +594,103 @@ class DateTimeFieldTest extends DateTestBase {
]);
$field->save();
// Set now as default_value.
$field_edit = array(
'default_value_input[default_date_type]' => 'now',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Loop through defined timezones to test that date-only defaults work at
// the extremes.
foreach (static::$timezones as $timezone) {
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', 'now', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page');
$this->setSiteTimezone($timezone);
// Check if default_date has been stored successfully.
$config_entity = $this->config('field.field.node.date_content.' . $field_name)->get();
$this->assertEqual($config_entity['default_value'][0], array('default_date_type' => 'now', 'default_date' => 'now'), 'Default value has been stored successfully');
// Set now as default_value.
$field_edit = array(
'default_value_input[default_date_type]' => 'now',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', 'now', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page');
// Create a new node to check that datetime field default value is today.
$new_node = Node::create(['type' => 'date_content']);
$expected_date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE);
$this->assertEqual($new_node->get($field_name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Check if default_date has been stored successfully.
$config_entity = $this->config('field.field.node.date_content.' . $field_name)
->get();
$this->assertEqual($config_entity['default_value'][0], array(
'default_date_type' => 'now',
'default_date' => 'now',
), 'Default value has been stored successfully');
// Set an invalid relative default_value to test validation.
$field_edit = array(
'default_value_input[default_date_type]' => 'relative',
'default_value_input[default_date]' => 'invalid date',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
$this->assertText('The relative date value entered is invalid.');
// Create a new node to check that datetime field default value is today.
$new_node = Node::create(['type' => 'date_content']);
$expected_date = new DrupalDateTime('now', drupal_get_user_timezone());
$this->assertEqual($new_node->get($field_name)
->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Set a relative default_value.
$field_edit = array(
'default_value_input[default_date_type]' => 'relative',
'default_value_input[default_date]' => '+90 days',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Set an invalid relative default_value to test validation.
$field_edit = array(
'default_value_input[default_date_type]' => 'relative',
'default_value_input[default_date]' => 'invalid date',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', 'relative', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '+90 days', 'The relative default value is displayed in instance settings page');
$this->assertText('The relative date value entered is invalid.');
// Check if default_date has been stored successfully.
$config_entity = $this->config('field.field.node.date_content.' . $field_name)->get();
$this->assertEqual($config_entity['default_value'][0], array('default_date_type' => 'relative', 'default_date' => '+90 days'), 'Default value has been stored successfully');
// Set a relative default_value.
$field_edit = array(
'default_value_input[default_date_type]' => 'relative',
'default_value_input[default_date]' => '+90 days',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', 'relative', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '+90 days', 'The relative default value is displayed in instance settings page');
// Create a new node to check that datetime field default value is +90 days.
$new_node = Node::create(['type' => 'date_content']);
$expected_date = new DrupalDateTime('+90 days', DATETIME_STORAGE_TIMEZONE);
$this->assertEqual($new_node->get($field_name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Check if default_date has been stored successfully.
$config_entity = $this->config('field.field.node.date_content.' . $field_name)
->get();
$this->assertEqual($config_entity['default_value'][0], array(
'default_date_type' => 'relative',
'default_date' => '+90 days',
), 'Default value has been stored successfully');
// Remove default value.
$field_edit = array(
'default_value_input[default_date_type]' => '',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', '', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page');
// Create a new node to check that datetime field default value is +90
// days.
$new_node = Node::create(['type' => 'date_content']);
$expected_date = new DrupalDateTime('+90 days', drupal_get_user_timezone());
$this->assertEqual($new_node->get($field_name)
->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT));
// Check if default_date has been stored successfully.
$config_entity = $this->config('field.field.node.date_content.' . $field_name)->get();
$this->assertTrue(empty($config_entity['default_value']), 'Empty default value has been stored successfully');
// Remove default value.
$field_edit = array(
'default_value_input[default_date_type]' => '',
);
$this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings'));
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Check that default value is selected in default value form.
$this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name);
$this->assertOptionSelected('edit-default-value-input-default-date-type', '', 'The default value is selected in instance settings page');
$this->assertFieldByName('default_value_input[default_date]', '', 'The relative default value is empty in instance settings page');
// Create a new node to check that datetime field default value is not set.
$new_node = Node::create(['type' => 'date_content']);
$this->assertNull($new_node->get($field_name)->value, 'Default value is not set');
// Check if default_date has been stored successfully.
$config_entity = $this->config('field.field.node.date_content.' . $field_name)
->get();
$this->assertTrue(empty($config_entity['default_value']), 'Empty default value has been stored successfully');
// Clear field cache in order to avoid stale cache values.
\Drupal::entityManager()->clearCachedFieldDefinitions();
// Create a new node to check that datetime field default value is not
// set.
$new_node = Node::create(['type' => 'date_content']);
$this->assertNull($new_node->get($field_name)->value, 'Default value is not set');
}
}
/**

View file

@ -32,24 +32,27 @@ field.formatter.settings.daterange_default:
label: 'Date range default display format settings'
mapping:
separator:
type: string
type: label
label: 'Separator'
translation context: 'Date range separator'
field.formatter.settings.daterange_plain:
type: field.formatter.settings.datetime_plain
label: 'Date range plain display format settings'
mapping:
separator:
type: string
type: label
label: 'Separator'
translation context: 'Date range separator'
field.formatter.settings.daterange_custom:
type: field.formatter.settings.datetime_custom
label: 'Date range custom display format settings'
mapping:
separator:
type: string
type: label
label: 'Separator'
translation context: 'Date range separator'
field.widget.settings.daterange_datelist:
type: mapping

View file

@ -0,0 +1,22 @@
<?php
/**
* @file
* Post-update functions for Datetime Range module.
*/
/**
* @addtogroup updates-8.2.x
* @{
*/
/**
* Clear caches to ensure schema changes are read.
*/
function datetime_range_post_update_translatable_separator() {
// Empty post-update hook to cause a cache rebuild.
}
/**
* @} End of "addtogroup updates-8.2.x".
*/

View file

@ -58,13 +58,12 @@ class DateRangeDefaultFormatter extends DateTimeDefaultFormatter {
}
else {
$elements[$delta] = $this->buildDateWithIsoAttribute($start_date);
}
if (!empty($item->_attributes)) {
$elements[$delta]['#attributes'] += $item->_attributes;
// Unset field item attributes since they have been included in the
// formatter output and should not be rendered in the field template.
unset($item->_attributes);
if (!empty($item->_attributes)) {
$elements[$delta]['#attributes'] += $item->_attributes;
// Unset field item attributes since they have been included in the
// formatter output and should not be rendered in the field template.
unset($item->_attributes);
}
}
}
}

View file

@ -140,6 +140,11 @@ class DateRangeFieldTest extends DateTestBase {
]));
$this->assertText(' THESEPARATOR ', 'Found proper separator');
// Verify that hook_entity_prepare_view can add attributes.
// @see entity_test_entity_prepare_view()
$this->drupalGet('entity_test/' . $id);
$this->assertFieldByXPath('//div[@data-field-item-attr="foobar"]');
// Verify that the plain formatter works.
$this->displayOptions['type'] = 'daterange_plain';
$this->displayOptions['settings'] = $this->defaultSettings;
@ -203,6 +208,11 @@ class DateRangeFieldTest extends DateTestBase {
]));
$this->assertNoText(' THESEPARATOR ', 'Separator not found on page');
// Verify that hook_entity_prepare_view can add attributes.
// @see entity_test_entity_prepare_view()
$this->drupalGet('entity_test/' . $id);
$this->assertFieldByXPath('//time[@data-field-item-attr="foobar"]');
$this->displayOptions['type'] = 'daterange_plain';
$this->displayOptions['settings'] = $this->defaultSettings;
entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')
@ -289,6 +299,11 @@ class DateRangeFieldTest extends DateTestBase {
$this->assertFieldByXPath('//time[@datetime="' . $end_expected_iso . '"]', $end_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $end_expected, '%expected_iso' => $end_expected_iso]));
$this->assertText(' THESEPARATOR ', 'Found proper separator');
// Verify that hook_entity_prepare_view can add attributes.
// @see entity_test_entity_prepare_view()
$this->drupalGet('entity_test/' . $id);
$this->assertFieldByXPath('//div[@data-field-item-attr="foobar"]');
// Verify that the plain formatter works.
$this->displayOptions['type'] = 'daterange_plain';
$this->displayOptions['settings'] = $this->defaultSettings;
@ -360,6 +375,11 @@ class DateRangeFieldTest extends DateTestBase {
$this->assertFieldByXPath('//time[@datetime="' . $start_expected_iso . '"]', $start_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso]));
$this->assertNoText(' THESEPARATOR ', 'Separator not found on page');
// Verify that hook_entity_prepare_view can add attributes.
// @see entity_test_entity_prepare_view()
$this->drupalGet('entity_test/' . $id);
$this->assertFieldByXPath('//time[@data-field-item-attr="foobar"]');
$this->displayOptions['type'] = 'daterange_plain';
$this->displayOptions['settings'] = $this->defaultSettings;
entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')
@ -440,6 +460,11 @@ class DateRangeFieldTest extends DateTestBase {
$this->assertFieldByXPath('//time[@datetime="' . $end_expected_iso . '"]', $end_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $end_expected, '%expected_iso' => $end_expected_iso]));
$this->assertText(' THESEPARATOR ', 'Found proper separator');
// Verify that hook_entity_prepare_view can add attributes.
// @see entity_test_entity_prepare_view()
$this->drupalGet('entity_test/' . $id);
$this->assertFieldByXPath('//div[@data-field-item-attr="foobar"]');
// Verify that the plain formatter works.
$this->displayOptions['type'] = 'daterange_plain';
$this->displayOptions['settings'] = $this->defaultSettings;
@ -513,6 +538,11 @@ class DateRangeFieldTest extends DateTestBase {
$this->assertFieldByXPath('//time[@datetime="' . $end_expected_iso . '"]', $end_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $end_expected, '%expected_iso' => $end_expected_iso]));
$this->assertText(' THESEPARATOR ', 'Found proper separator');
// Verify that hook_entity_prepare_view can add attributes.
// @see entity_test_entity_prepare_view()
$this->drupalGet('entity_test/' . $id);
$this->assertFieldByXPath('//div[@data-field-item-attr="foobar"]');
$this->displayOptions['type'] = 'daterange_plain';
entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')
->setComponent($field_name, $this->displayOptions)

View file

@ -0,0 +1,131 @@
<?php
namespace Drupal\Tests\datetime_range\Kernel;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Language\Language;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\KernelTests\KernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* Test to ensure the datetime range separator is translatable.
*
* @group datetime
*/
class SeparatorTranslationTest extends KernelTestBase {
/**
* A field storage to use in this test class.
*
* @var \Drupal\field\Entity\FieldStorageConfig
*/
protected $fieldStorage;
/**
* The field used in this test class.
*
* @var \Drupal\field\Entity\FieldConfig
*/
protected $field;
/**
* {@inheritdoc}
*/
public static $modules = [
'datetime',
'datetime_range',
'entity_test',
'field',
'language',
'system',
'user',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('entity_test');
$this->installEntitySchema('user');
$this->installConfig(['system']);
$this->installSchema('system', ['sequences', 'key_value']);
// Add a datetime range field.
$this->fieldStorage = FieldStorageConfig::create([
'field_name' => Unicode::strtolower($this->randomMachineName()),
'entity_type' => 'entity_test',
'type' => 'daterange',
'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATE],
]);
$this->fieldStorage->save();
$this->field = FieldConfig::create([
'field_storage' => $this->fieldStorage,
'bundle' => 'entity_test',
'required' => TRUE,
]);
$this->field->save();
$display_options = [
'type' => 'daterange_default',
'label' => 'hidden',
'settings' => [
'format_type' => 'fallback',
'separator' => 'UNTRANSLATED',
],
];
EntityViewDisplay::create([
'targetEntityType' => $this->field->getTargetEntityTypeId(),
'bundle' => $this->field->getTargetBundle(),
'mode' => 'default',
'status' => TRUE,
])->setComponent($this->fieldStorage->getName(), $display_options)
->save();
}
/**
* Tests the translation of the range separator.
*/
public function testSeparatorTranslation() {
// Create an entity.
$entity = EntityTest::create([
'name' => $this->randomString(),
$this->fieldStorage->getName() => [
'value' => '2016-09-20',
'end_value' => '2016-09-21',
],
]);
// Verify the untranslated separator.
$display = EntityViewDisplay::collectRenderDisplay($entity, 'default');
$build = $display->build($entity);
$output = $this->container->get('renderer')->renderRoot($build);
$this->verbose($output);
$this->assertContains('UNTRANSLATED', (string) $output);
// Translate the separator.
ConfigurableLanguage::createFromLangcode('nl')->save();
/** @var \Drupal\language\ConfigurableLanguageManagerInterface $language_manager */
$language_manager = $this->container->get('language_manager');
$language_manager->getLanguageConfigOverride('nl', 'core.entity_view_display.entity_test.entity_test.default')
->set('content.' . $this->fieldStorage->getName() . '.settings.separator', 'NL_TRANSLATED!')
->save();
$this->container->get('language.config_factory_override')
->setLanguage(new Language(['id' => 'nl']));
$this->container->get('cache_tags.invalidator')->invalidateTags($entity->getCacheTags());
$display = EntityViewDisplay::collectRenderDisplay($entity, 'default');
$build = $display->build($entity);
$output = $this->container->get('renderer')->renderRoot($build);
$this->verbose($output);
$this->assertContains('NL_TRANSLATED!', (string) $output);
}
}

View file

@ -467,6 +467,78 @@ function _editor_delete_file_usage(array $uuids, EntityInterface $entity, $count
}
}
/**
* Implements hook_file_download().
*
* @see file_file_download()
* @see file_get_file_references()
*/
function editor_file_download($uri) {
// Get the file record based on the URI. If not in the database just return.
/** @var \Drupal\file\FileInterface[] $files */
$files = \Drupal::entityTypeManager()
->getStorage('file')
->loadByProperties(['uri' => $uri]);
if (count($files)) {
foreach ($files as $item) {
// Since some database servers sometimes use a case-insensitive comparison
// by default, double check that the filename is an exact match.
if ($item->getFileUri() === $uri) {
$file = $item;
break;
}
}
}
if (!isset($file)) {
return;
}
// Temporary files are handled by file_file_download(), so nothing to do here
// about them.
// @see file_file_download()
// Find out if any editor-backed field contains the file.
$usage_list = \Drupal::service('file.usage')->listUsage($file);
// Stop processing if there are no references in order to avoid returning
// headers for files controlled by other modules. Make an exception for
// temporary files where the host entity has not yet been saved (for example,
// an image preview on a node creation form) in which case, allow download by
// the file's owner.
if (empty($usage_list['editor']) && ($file->isPermanent() || $file->getOwnerId() != \Drupal::currentUser()->id())) {
return;
}
// Editor.module MUST NOT call $file->access() here (like file_file_download()
// does) as checking the 'download' access to a file entity would end up in
// FileAccessControlHandler->checkAccess() and ->getFileReferences(), which
// calls file_get_file_references(). This latter one would allow downloading
// files only handled by the file.module, which is exactly not the case right
// here. So instead we must check if the current user is allowed to view any
// of the entities that reference the image using the 'editor' module.
if ($file->isPermanent()) {
$referencing_entity_is_accessible = FALSE;
$references = empty($usage_list['editor']) ? [] : $usage_list['editor'];
foreach ($references as $entity_type => $entity_ids) {
$referencing_entities = entity_load_multiple($entity_type, $entity_ids);
/** @var \Drupal\Core\Entity\EntityInterface $referencing_entity */
foreach ($referencing_entities as $referencing_entity) {
if ($referencing_entity->access('view', NULL, TRUE)->isAllowed()) {
$referencing_entity_is_accessible = TRUE;
break 2;
}
}
}
if (!$referencing_entity_is_accessible) {
return -1;
}
}
// Access is granted.
$headers = file_get_content_headers($file);
return $headers;
}
/**
* Finds all files referenced (data-entity-uuid) by formatted text fields.
*

View file

@ -0,0 +1,100 @@
<?php
namespace Drupal\editor\Tests;
use Drupal\file\Entity\File;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
/**
* Tests Editor module's file reference filter with private files.
*
* @group editor
*/
class EditorPrivateFileReferenceFilterTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
// Needed for the config: this is the only module in core that utilizes the
// functionality in editor.module to be tested, and depends on that.
'ckeditor',
// Depends on filter.module (indirectly).
'node',
// Pulls in the config we're using during testing which create a text format
// - with the filter_html_image_secure filter DISABLED,
// - with the editor set to CKEditor,
// - with drupalimage.image_upload.scheme set to 'private',
// - with drupalimage.image_upload.directory set to ''.
'editor_private_test',
];
/**
* Tests the editor file reference filter with private files.
*/
function testEditorPrivateFileReferenceFilter() {
$author = $this->drupalCreateUser();
$this->drupalLogin($author);
// Create a content type with a body field.
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
// Create a file in the 'private:// ' stream.
$filename = 'test.png';
$src = '/system/files/' . $filename;
/** @var \Drupal\file\FileInterface $file */
$file = File::create([
'uri' => 'private://' . $filename,
]);
$file->setTemporary();
$file->setOwner($author);
// Create the file itself.
file_put_contents($file->getFileUri(), $this->randomString());
$file->save();
// The image should be visible for its author.
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(200);
// The not-yet-permanent image should NOT be visible for anonymous.
$this->drupalLogout();
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(403);
// Resave the file to be permanent.
$file->setPermanent();
$file->save();
// Create a node with its body field properly pointing to the just-created
// file.
$node = $this->drupalCreateNode([
'type' => 'page',
'body' => [
'value' => '<img alt="alt" data-entity-type="file" data-entity-uuid="' . $file->uuid() . '" src="' . $src . '" />',
'format' => 'private_images',
],
'uid' => $author->id(),
]);
// Do the actual test. The image should be visible for anonymous users,
// because they can view the referencing entity.
$this->drupalGet($node->toUrl());
$this->assertSession()->statusCodeEquals(200);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(200);
// Disallow anonymous users to view the entity, which then should also
// disallow them to view the image.
Role::load(RoleInterface::ANONYMOUS_ID)
->revokePermission('access content')
->save();
$this->drupalGet($node->toUrl());
$this->assertSession()->statusCodeEquals(403);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(403);
}
}

View file

@ -0,0 +1,34 @@
format: private_images
status: true
langcode: en
editor: ckeditor
settings:
toolbar:
rows:
-
-
name: Media
items:
- DrupalImage
-
name: Tools
items:
- Source
plugins:
language:
language_list: un
stylescombo:
styles: ''
image_upload:
status: true
scheme: private
directory: ''
max_size: ''
max_dimensions:
width: null
height: null
dependencies:
config:
- filter.format.private_images
module:
- ckeditor

View file

@ -0,0 +1,23 @@
format: private_images
name: 'Private images'
status: true
langcode: en
filters:
editor_file_reference:
id: editor_file_reference
provider: editor
status: true
weight: 0
settings: { }
filter_html:
id: filter_html
provider: filter
status: false
weight: -10
settings:
allowed_html: '<img src alt data-entity-type data-entity-uuid>'
filter_html_help: true
filter_html_nofollow: false
dependencies:
module:
- editor

View file

@ -0,0 +1,9 @@
name: 'Text Editor Private test'
type: module
description: 'Support module for the Text Editor Private module tests.'
core: 8.x
package: Testing
version: VERSION
dependencies:
- filter
- ckeditor

View file

@ -15,105 +15,101 @@ process:
langcode: 'constants/langcode'
field_name: field_name
type:
-
plugin: field_type
source:
- type
- widget_type
map:
number_integer:
number: integer
optionwidgets_select: list_integer
optionwidgets_buttons: list_integer
optionwidgets_onoff: boolean
number_decimal:
number: decimal
optionwidgets_select: list_float
optionwidgets_buttons: list_float
optionwidgets_onoff: boolean
number_float:
number: float
optionwidgets_select: list_float
optionwidgets_buttons: list_float
optionwidgets_onoff: boolean
email:
email_textfield: email
filefield:
imagefield_widget: image
filefield_widget: file
date:
date_select: datetime
datestamp:
date_select: datetime
datetime:
date_select: datetime
fr_phone:
phone_textfield: telephone
be_phone:
phone_textfield: telephone
it_phone:
phone_textfield: telephone
el_phone:
phone_textfield: telephone
ch_phone:
phone_textfield: telephone
ca_phone:
phone_textfield: telephone
cr_phone:
phone_textfield: telephone
pa_phone:
phone_textfield: telephone
gb_phone:
phone_textfield: telephone
ru_phone:
phone_textfield: telephone
ua_phone:
phone_textfield: telephone
es_phone:
phone_textfield: telephone
au_phone:
phone_textfield: telephone
cs_phone:
phone_textfield: telephone
hu_phone:
phone_textfield: telephone
pl_phone:
phone_textfield: telephone
nl_phone:
phone_textfield: telephone
se_phone:
phone_textfield: telephone
za_phone:
phone_textfield: telephone
il_phone:
phone_textfield: telephone
nz_phone:
phone_textfield: telephone
br_phone:
phone_textfield: telephone
cl_phone:
phone_textfield: telephone
cn_phone:
phone_textfield: telephone
hk_phone:
phone_textfield: telephone
mo_phone:
phone_textfield: telephone
ph_phone:
phone_textfield: telephone
sg_phone:
phone_textfield: telephone
jo_phone:
phone_textfield: telephone
eg_phone:
phone_textfield: telephone
pk_phone:
phone_textfield: telephone
int_phone:
phone_textfield: telephone
-
plugin: skip_on_empty
method: row
plugin: field_type
source:
- type
- widget_type
map:
number_integer:
number: integer
optionwidgets_select: list_integer
optionwidgets_buttons: list_integer
optionwidgets_onoff: boolean
number_decimal:
number: decimal
optionwidgets_select: list_float
optionwidgets_buttons: list_float
optionwidgets_onoff: boolean
number_float:
number: float
optionwidgets_select: list_float
optionwidgets_buttons: list_float
optionwidgets_onoff: boolean
email:
email_textfield: email
filefield:
imagefield_widget: image
filefield_widget: file
date:
date_select: datetime
datestamp:
date_select: datetime
datetime:
date_select: datetime
fr_phone:
phone_textfield: telephone
be_phone:
phone_textfield: telephone
it_phone:
phone_textfield: telephone
el_phone:
phone_textfield: telephone
ch_phone:
phone_textfield: telephone
ca_phone:
phone_textfield: telephone
cr_phone:
phone_textfield: telephone
pa_phone:
phone_textfield: telephone
gb_phone:
phone_textfield: telephone
ru_phone:
phone_textfield: telephone
ua_phone:
phone_textfield: telephone
es_phone:
phone_textfield: telephone
au_phone:
phone_textfield: telephone
cs_phone:
phone_textfield: telephone
hu_phone:
phone_textfield: telephone
pl_phone:
phone_textfield: telephone
nl_phone:
phone_textfield: telephone
se_phone:
phone_textfield: telephone
za_phone:
phone_textfield: telephone
il_phone:
phone_textfield: telephone
nz_phone:
phone_textfield: telephone
br_phone:
phone_textfield: telephone
cl_phone:
phone_textfield: telephone
cn_phone:
phone_textfield: telephone
hk_phone:
phone_textfield: telephone
mo_phone:
phone_textfield: telephone
ph_phone:
phone_textfield: telephone
sg_phone:
phone_textfield: telephone
jo_phone:
phone_textfield: telephone
eg_phone:
phone_textfield: telephone
pk_phone:
phone_textfield: telephone
int_phone:
phone_textfield: telephone
cardinality:
plugin: static_map
bypass: true
@ -126,6 +122,5 @@ process:
source:
- '@type'
- global_settings
destination:
plugin: md_entity:field_storage_config

View file

@ -21,8 +21,6 @@ class FieldInstancePerFormDisplay extends DrupalSqlBase {
$rows = array();
$result = $this->prepareQuery()->execute();
while ($field_row = $result->fetchAssoc()) {
$field_row['display_settings'] = unserialize($field_row['display_settings']);
$field_row['widget_settings'] = unserialize($field_row['widget_settings']);
$bundle = $field_row['type_name'];
$field_name = $field_row['field_name'];
@ -34,7 +32,8 @@ class FieldInstancePerFormDisplay extends DrupalSqlBase {
$rows[$index]['module'] = $field_row['module'];
$rows[$index]['weight'] = $field_row['weight'];
$rows[$index]['widget_type'] = $field_row['widget_type'];
$rows[$index]['widget_settings'] = $field_row['widget_settings'];
$rows[$index]['widget_settings'] = unserialize($field_row['widget_settings']);
$rows[$index]['display_settings'] = unserialize($field_row['display_settings']);
}
return new \ArrayIterator($rows);

View file

@ -165,4 +165,30 @@ class NestedFormTest extends FieldTestBase {
$this->assertFieldValues($entity_2, 'field_unlimited', array(13, 14, 15));
}
/**
* Tests entity level validation within subforms.
*/
public function testNestedEntityFormEntityLevelValidation() {
// Create two entities.
$storage = $this->container->get('entity_type.manager')
->getStorage('entity_test_constraints');
$entity_1 = $storage->create();
$entity_1->save();
$entity_2 = $storage->create();
$entity_2->save();
// Display the 'combined form'.
$this->drupalGet("test-entity-constraints/nested/{$entity_1->id()}/{$entity_2->id()}");
$this->assertFieldByName('entity_2[changed]', 0, 'Entity 2: changed value appears correctly in the form.');
// Submit the form and check that the entities are updated accordingly.
$edit = ['entity_2[changed]' => REQUEST_TIME - 86400];
$this->drupalPostForm(NULL, $edit, t('Save'));
$elements = $this->cssSelect('.entity-2.error');
$this->assertEqual(1, count($elements), 'The whole nested entity form has been correctly flagged with an error class.');
}
}

View file

@ -11,3 +11,17 @@ field_test.entity_nested_form:
type: 'entity:entity_test'
requirements:
_permission: 'administer entity_test content'
field_test.entity_constraints_nested_form:
path: '/test-entity-constraints/nested/{entity_1}/{entity_2}'
defaults:
_title: 'Nested entity form'
_form: '\Drupal\field_test\Form\NestedEntityTestForm'
options:
parameters:
entity_1:
type: 'entity:entity_test_constraints'
entity_2:
type: 'entity:entity_test_constraints'
requirements:
_permission: 'administer entity_test content'

View file

@ -2,6 +2,7 @@
namespace Drupal\field_test\Form;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
@ -33,16 +34,26 @@ class NestedEntityTestForm extends FormBase {
$form_state->set('entity_2', $entity_2);
$form_display_2 = EntityFormDisplay::collectRenderDisplay($entity_2, 'default');
$form_state->set('form_display_2', $form_display_2);
$form['entity_2'] = array(
$form['entity_2'] = [
'#type' => 'details',
'#title' => t('Second entity'),
'#tree' => TRUE,
'#parents' => array('entity_2'),
'#parents' => ['entity_2'],
'#weight' => 50,
);
'#attributes' => ['class' => ['entity-2']]
];
$form_display_2->buildForm($entity_2, $form['entity_2'], $form_state);
if ($entity_2 instanceof EntityChangedInterface) {
// Changed must be sent to the client, for later overwrite error checking.
// @see Drupal\field\Tests\NestedFormTest::testNestedEntityFormEntityLevelValidation()
$form['entity_2']['changed'] = [
'#type' => 'hidden',
'#default_value' => $entity_1->getChangedTime(),
];
}
$form['save'] = array(
'#type' => 'submit',
'#value' => t('Save'),
@ -65,7 +76,16 @@ class NestedEntityTestForm extends FormBase {
$entity_2 = $form_state->get('entity_2');
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display_2 */
$form_display_2 = $form_state->get('form_display_2');
$form_display_2->extractFormValues($entity_2, $form['entity_2'], $form_state);
$extracted = $form_display_2->extractFormValues($entity_2, $form['entity_2'], $form_state);
// Extract the values of fields that are not rendered through widgets, by
// simply copying from top-level form values. This leaves the fields that
// are not being edited within this form untouched.
// @see Drupal\field\Tests\NestedFormTest::testNestedEntityFormEntityLevelValidation()
foreach ($form_state->getValues()['entity_2'] as $name => $values) {
if ($entity_2->hasField($name) && !isset($extracted[$name])) {
$entity_2->set($name, $values);
}
}
$form_display_2->validateFormValues($entity_2, $form['entity_2'], $form_state);
}

View file

@ -96,6 +96,19 @@ class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
$this->assertIdentical($expected_entity_type . '.' . $expected_name, $field->getFieldStorageDefinition()->id());
}
/**
* Asserts the settings of a link field config entity.
*
* @param $id
* The entity ID in the form ENTITY_TYPE.BUNDLE.FIELD_NAME.
* @param $title_setting
* The expected title setting.
*/
protected function assertLinkFields($id, $title_setting) {
$field = FieldConfig::load($id);
$this->assertSame($title_setting, $field->getSetting('title'));
}
/**
* Tests migrating D7 field instances to field_config entities.
*/
@ -131,6 +144,10 @@ class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
$this->assertEntity('node.test_content_type.field_text', 'Text', 'text', FALSE);
$this->assertEntity('comment.comment_node_test_content_type.field_integer', 'Integer', 'integer', FALSE);
$this->assertEntity('user.user.field_file', 'File', 'file', FALSE);
$this->assertLinkFields('node.test_content_type.field_link', DRUPAL_OPTIONAL);
$this->assertLinkFields('node.article.field_link', DRUPAL_DISABLED);
$this->assertLinkFields('node.blog.field_link', DRUPAL_REQUIRED);
}
}

View file

@ -0,0 +1,80 @@
<?php
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests d6_field_instance_per_form_display source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstancePerFormDisplay
* @group field
*/
class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'display_settings' => [],
'widget_settings' => [],
'type_name' => 'story',
'widget_active' => TRUE,
'field_name' => 'field_test_filefield',
'type' => 'filefield',
'module' => 'filefield',
'weight' => '8',
'widget_type' => 'filefield_widget',
],
];
// The source data.
$empty_array = serialize([]);
$tests[0]['source_data']['content_node_field'] = [
[
'field_name' => 'field_test_filefield',
'type' => 'filefield',
'global_settings' => $empty_array,
'required' => '0',
'multiple' => '0',
'db_storage' => '1',
'module' => 'filefield',
'db_columns' => $empty_array,
'active' => '1',
'locked' => '0',
]
];
$tests[0]['source_data']['content_node_field_instance'] = [
[
'field_name' => 'field_test_filefield',
'type_name' => 'story',
'weight' => '8',
'label' => 'File Field',
'widget_type' => 'filefield_widget',
'widget_settings' => $empty_array,
'display_settings' => $empty_array,
'description' => 'An example image field.',
'widget_module' => 'filefield',
'widget_active' => '1',
],
];
return $tests;
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 fields per view mode source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstancePerViewMode
* @group field
*/
class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'migrate_drupal', 'node', 'user'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'entity_type' => 'node',
'view_mode' => 4,
'type_name' => 'article',
'field_name' => 'field_test',
'type' => 'text',
'module' => 'text',
'weight' => 1,
'label' => 'above',
'display_settings' => [
'weight' => 1,
'parent' => '',
'label' => [
'format' => 'above',
],
4 => [
'format' => 'trimmed',
'exclude' => 0,
],
],
'widget_settings' => [],
],
[
'entity_type' => 'node',
'view_mode' => 'teaser',
'type_name' => 'story',
'field_name' => 'field_test',
'type' => 'text',
'module' => 'text',
'weight' => 2,
'label' => 'above',
'display_settings' => [
'weight' => 1,
'parent' => '',
'label' => [
'format' => 'above',
],
'teaser' => [
'format' => 'trimmed',
'exclude' => 0,
],
],
'widget_settings' => [],
],
];
// The source data.
foreach ($tests[0]['expected_data'] as $k => $field_view_mode) {
// These are stored as serialized strings.
$field_view_mode['display_settings'] = serialize($field_view_mode['display_settings']);
$field_view_mode['widget_settings'] = serialize($field_view_mode['widget_settings']);
$tests[0]['source_data']['content_node_field'][] = [
'field_name' => $field_view_mode['field_name'],
'type' => $field_view_mode['type'],
'module' => $field_view_mode['module'],
];
unset($field_view_mode['type'], $field_view_mode['module']);
$tests[0]['source_data']['content_node_field_instance'][] = $field_view_mode;
// Update the expected display settings.
$tests[0]['expected_data'][$k]['display_settings'] = $tests[0]['expected_data'][$k]['display_settings'][$field_view_mode['view_mode']];
}
return $tests;
}
}

View file

@ -0,0 +1,96 @@
<?php
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 field instance source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldInstance
* @group field
*/
class FieldInstanceTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'field_name' => 'field_body',
'type_name' => 'page',
'weight' => 1,
'label' => 'body',
'widget_type' => 'text_textarea',
'description' => '',
'widget_module' => 'text',
'widget_active' => 1,
'required' => 1,
'active' => 1,
'global_settings' => [],
'widget_settings' => [
'rows' => 5,
'size' => 60,
'default_value' => [
[
'value' => '',
'_error_element' => 'default_value_widget][field_body][0][value',
'default_value_php' => '',
],
],
],
'display_settings' => [
'label' => [
'format' => 'above',
'exclude' => 0,
],
'teaser' => [
'format' => 'default',
'exclude' => 0,
],
'full' => [
'format' => 'default',
'exclude' => 0,
],
],
],
];
// The source data.
$tests[0]['source_data']['content_node_field_instance'] = array_map(
function (array $row) {
$row['widget_settings'] = serialize($row['widget_settings']);
$row['display_settings'] = serialize($row['display_settings']);
$row['global_settings'] = serialize($row['global_settings']);
return $row;
},
$tests[0]['expected_data']
);
$tests[0]['source_data']['content_node_field'] = [
[
'field_name' => 'field_body',
'required' => 1,
'type' => 'text',
'active' => 1,
'global_settings' => serialize([]),
],
];
return $tests;
}
}

View file

@ -0,0 +1,79 @@
<?php
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 field source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d6\Field
* @group field
*/
class FieldTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'field_name' => 'field_body',
'type' => 'text',
'global_settings' => [
'text_processing' => 0,
'max_length' => '',
'allowed_values' => '',
'allowed_values_php' => '',
],
'required' => 0,
'multiple' => 0,
'db_storage' => 1,
'module' => 'text',
'db_columns' => [
'value' => [
'type' => 'text',
'size' => 'big',
'not null' => '',
'sortable' => 1,
'views' => 1,
],
],
'active' => 1,
'locked' => 0,
],
];
// The source data.
$tests[0]['source_data']['content_node_field'] = array_map(
function (array $row) {
$row['global_settings'] = serialize($row['global_settings']);
$row['db_columns'] = serialize($row['db_columns']);
return $row;
},
$tests[0]['expected_data']
);
$tests[0]['source_data']['content_node_field_instance'] = [
[
'widget_type' => 'text_textarea',
'field_name' => 'field_body',
],
];
return $tests;
}
}

View file

@ -1,84 +1,36 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 field instance per form display source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d7\FieldInstancePerFormDisplay
* @group field
*/
class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\FieldInstancePerFormDisplay';
protected $migrationConfiguration = array(
'id' => 'test_fieldinstance',
'source' => array(
'plugin' => 'd7_field_instance_per_form_display',
),
);
// We need to set up the database contents; it's easier to do that below.
// These are sample result queries.
protected $expectedResults = array(
array(
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => 'page',
'widget_settings' => array(
),
'display_settings' => array(
),
'description' => '',
'required' => FALSE,
'global_settings' => array(),
),
array(
'field_name' => 'field_file',
'entity_type' => 'user',
'bundle' => 'user',
'widget_settings' => array(
),
'display_settings' => array(
),
'description' => '',
'required' => FALSE,
'global_settings' => array(),
),
array(
'field_name' => 'field_integer',
'entity_type' => 'comment',
'bundle' => 'comment_node_test_content_type',
'widget_settings' => array(
),
'display_settings' => array(
),
'description' => '',
'required' => FALSE,
'global_settings' => array(),
),
array(
'field_name' => 'field_link',
'entity_type' => 'taxonomy_term',
'bundle' => 'test_vocabulary',
'widget_settings' => array(
),
'display_settings' => array(
),
'description' => '',
'required' => FALSE,
'global_settings' => array(),
),
);
class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestBase {
/**
* Prepopulate contents with results.
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['field_config_instance'] = array(
array(
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The source data.
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => '2',
'field_id' => '2',
'field_name' => 'body',
@ -86,8 +38,8 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'bundle' => 'page',
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
array(
],
[
'id' => '33',
'field_id' => '11',
'field_name' => 'field_file',
@ -95,8 +47,8 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'bundle' => 'user',
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
array(
],
[
'id' => '32',
'field_id' => '14',
'field_name' => 'field_integer',
@ -104,8 +56,8 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'bundle' => 'comment_node_test_content_type',
'data' => 'a:7:{s:5:"label";s:7:"Integer";s:6:"widget";a:5:{s:6:"weight";s:1:"2";s:4:"type";s:6:"number";s:6:"module";s:6:"number";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:5:{s:3:"min";s:0:"";s:3:"max";s:0:"";s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:14:"number_integer";s:8:"settings";a:4:{s:18:"thousand_separator";s:1:" ";s:17:"decimal_separator";s:1:".";s:5:"scale";i:0;s:13:"prefix_suffix";b:1;}s:6:"module";s:6:"number";s:6:"weight";i:1;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
'deleted' => '0',
),
array(
],
[
'id' => '25',
'field_id' => '15',
'field_name' => 'field_link',
@ -113,10 +65,10 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'bundle' => 'test_vocabulary',
'data' => 'a:7:{s:5:"label";s:4:"Link";s:6:"widget";a:5:{s:6:"weight";s:2:"10";s:4:"type";s:10:"link_field";s:6:"module";s:4:"link";s:6:"active";i:0;s:8:"settings";a:0:{}}s:8:"settings";a:12:{s:12:"absolute_url";i:1;s:12:"validate_url";i:1;s:3:"url";i:0;s:5:"title";s:8:"optional";s:11:"title_value";s:19:"Unused Static Title";s:27:"title_label_use_field_label";i:0;s:15:"title_maxlength";s:3:"128";s:7:"display";a:1:{s:10:"url_cutoff";s:2:"81";}s:10:"attributes";a:6:{s:6:"target";s:6:"_blank";s:3:"rel";s:8:"nofollow";s:18:"configurable_class";i:0;s:5:"class";s:7:"classes";s:18:"configurable_title";i:1;s:5:"title";s:0:"";}s:10:"rel_remove";s:19:"rel_remove_external";s:13:"enable_tokens";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"link_default";s:6:"weight";s:1:"9";s:8:"settings";a:0:{}s:6:"module";s:4:"link";}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}',
'deleted' => '0',
),
);
$this->databaseContents['field_config'] = array(
array(
],
];
$tests[0]['source_data']['field_config'] = [
[
'id' => '2',
'field_name' => 'body',
'type' => 'text_with_summary',
@ -130,8 +82,8 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'cardinality' => '1',
'translatable' => '0',
'deleted' => '0',
),
array(
],
[
'id' => '11',
'field_name' => 'field_file',
'type' => 'file',
@ -145,8 +97,8 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'cardinality' => '1',
'translatable' => '0',
'deleted' => '0',
),
array(
],
[
'id' => '14',
'field_name' => 'field_integer',
'type' => 'number_integer',
@ -160,8 +112,8 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'cardinality' => '1',
'translatable' => '0',
'deleted' => '0',
),
array(
],
[
'id' => '15',
'field_name' => 'field_link',
'type' => 'link_field',
@ -175,10 +127,43 @@ class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
'cardinality' => '1',
'translatable' => '0',
'deleted' => '0',
),
);
],
];
parent::setUp();
// The expected results.
$tests[0]['expected_data'] = [
[
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => 'page',
'widget_settings' => [
'rows' => 20,
'summary_rows' => 5,
],
],
[
'field_name' => 'field_file',
'entity_type' => 'user',
'bundle' => 'user',
'widget_settings' => [
'progress_indicator' => 'throbber',
],
],
[
'field_name' => 'field_integer',
'entity_type' => 'comment',
'bundle' => 'comment_node_test_content_type',
'widget_settings' => [],
],
[
'field_name' => 'field_link',
'entity_type' => 'taxonomy_term',
'bundle' => 'test_vocabulary',
'widget_settings' => [],
],
];
return $tests;
}
}

View file

@ -0,0 +1,75 @@
<?php
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 field instance per view mode source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d7\FieldInstancePerViewMode
* @group field
*/
class FieldInstancePerViewModeTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The source data.
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => '2',
'field_id' => '2',
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => 'page',
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
'deleted' => '0',
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'entity_type' => 'node',
'bundle' => 'page',
'field_name' => 'body',
'label' => 'hidden',
'type' => 'text_default',
'settings' => [],
'module' => 'text',
'weight' => 0,
'view_mode' => 'default',
],
[
'entity_type' => 'node',
'bundle' => 'page',
'field_name' => 'body',
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
'settings' => [
'trim_length' => 600,
],
'module' => 'text',
'weight' => 0,
'view_mode' => 'teaser',
],
];
return $tests;
}
}

View file

@ -1,54 +1,36 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 field instance source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d7\FieldInstance
* @group field
*/
class FieldInstanceTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\FieldInstance';
protected $migrationConfiguration = array(
'id' => 'test_fieldinstance',
'source' => array(
'plugin' => 'd7_field_instance',
),
);
protected $expectedResults = array(
array(
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => 'page',
'label' => 'Body',
'widget_settings' => array(
'module' => 'text',
'settings' => array(
'rows' => 20,
'summary_rows' => 5,
),
'type' => 'text_textarea_with_summary',
'weight' => -4,
),
'display_settings' => array(
),
'description' => '',
'required' => FALSE,
'global_settings' => array(),
),
);
class FieldInstanceTest extends MigrateSqlSourceTestBase {
/**
* Prepopulate contents with results.
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['field_config_instance'] = array(
array(
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The source data.
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => '2',
'field_id' => '2',
'field_name' => 'body',
@ -56,10 +38,10 @@ class FieldInstanceTest extends MigrateSqlSourceTestCase {
'bundle' => 'page',
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
);
$this->databaseContents['field_config'] = array(
array(
],
];
$tests[0]['source_data']['field_config'] = [
[
'id' => '2',
'field_name' => 'body',
'type' => 'text_with_summary',
@ -73,10 +55,49 @@ class FieldInstanceTest extends MigrateSqlSourceTestCase {
'cardinality' => '1',
'translatable' => '0',
'deleted' => '0',
),
);
],
];
parent::setUp();
// The expected results.
$tests[0]['expected_data'] = [
[
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => 'page',
'label' => 'Body',
'widget_settings' => [
'module' => 'text',
'settings' => [
'rows' => 20,
'summary_rows' => 5,
],
'type' => 'text_textarea_with_summary',
'weight' => -4,
],
'display_settings' => [
'default' => [
'label' => 'hidden',
'type' => 'text_default',
'settings' => [],
'module' => 'text',
'weight' => 0,
],
'teaser' => [
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
'settings' => [
'trim_length' => 600,
],
'module' => 'text',
'weight' => 0,
],
],
'description' => '',
'required' => FALSE,
],
];
return $tests;
}
}

View file

@ -1,100 +1,36 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 field source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d7\Field
* @group field
*/
class FieldTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\Field';
protected $migrationConfiguration = array(
'id' => 'test_field',
'source' => array(
'plugin' => 'd7_field',
),
);
protected $expectedResults = array(
array(
'field_name' => 'field_file',
'type' => 'file',
'global_settings' => '',
'storage' => array(
'active' => 1,
'details' => array(
'sql' => array(
'FIELD_LOAD_CURRENT' => array(
'field_data_field_file' => array(
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
),
),
'FIELD_LOAD_REVISION' => array(
'field_revision_field_file' => array(
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
),
),
),
),
'module' => 'field_sql_storage',
'settings' => array(),
'type' => 'field_sql_storage',
),
'module' => 'file',
'db_columns' => '',
'locked' => 0,
'entity_type' => 'node',
),
array(
'field_name' => 'field_file',
'type' => 'file',
'global_settings' => '',
'storage' => array(
'active' => 1,
'details' => array(
'sql' => array(
'FIELD_LOAD_CURRENT' => array(
'field_data_field_file' => array(
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
),
),
'FIELD_LOAD_REVISION' => array(
'field_revision_field_file' => array(
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
),
),
),
),
'module' => 'field_sql_storage',
'settings' => array(),
'type' => 'field_sql_storage',
),
'module' => 'file',
'db_columns' => '',
'locked' => 0,
'entity_type' => 'user',
),
);
class FieldTest extends MigrateSqlSourceTestBase {
/**
* Prepopulate contents with results.
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['field_config'] = array(
array(
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The source data.
$tests[0]['source_data']['field_config'] = [
[
'id' => '11',
'field_name' => 'field_file',
'type' => 'file',
@ -108,10 +44,10 @@ class FieldTest extends MigrateSqlSourceTestCase {
'cardinality' => '1',
'translatable' => '0',
'deleted' => '0',
),
);
$this->databaseContents['field_config_instance'] = array(
array(
],
];
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => '33',
'field_id' => '11',
'field_name' => 'field_file',
@ -119,8 +55,8 @@ class FieldTest extends MigrateSqlSourceTestCase {
'bundle' => 'user',
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
array(
],
[
'id' => '21',
'field_id' => '11',
'field_name' => 'field_file',
@ -128,9 +64,76 @@ class FieldTest extends MigrateSqlSourceTestCase {
'bundle' => 'test_content_type',
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"5";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:15:"txt pdf ods odf";s:12:"max_filesize";s:5:"10 MB";s:17:"description_field";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:6:"weight";s:1:"5";s:8:"settings";a:0:{}s:6:"module";s:4:"file";}}s:8:"required";i:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
);
parent::setUp();
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'field_name' => 'field_file',
'type' => 'file',
'storage' => [
'active' => 1,
'details' => [
'sql' => [
'FIELD_LOAD_CURRENT' => [
'field_data_field_file' => [
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
],
],
'FIELD_LOAD_REVISION' => [
'field_revision_field_file' => [
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
],
],
],
],
'module' => 'field_sql_storage',
'settings' => [],
'type' => 'field_sql_storage',
],
'module' => 'file',
'locked' => 0,
'entity_type' => 'node',
],
[
'field_name' => 'field_file',
'type' => 'file',
'storage' => [
'active' => 1,
'details' => [
'sql' => [
'FIELD_LOAD_CURRENT' => [
'field_data_field_file' => [
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
],
],
'FIELD_LOAD_REVISION' => [
'field_revision_field_file' => [
'description' => 'field_file_description',
'display' => 'field_file_display',
'fid' => 'field_file_fid',
],
],
],
],
'module' => 'field_sql_storage',
'settings' => [],
'type' => 'field_sql_storage',
],
'module' => 'file',
'locked' => 0,
'entity_type' => 'user',
],
];
return $tests;
}
}

View file

@ -1,54 +1,36 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 view mode source plugin.
*
* @covers \Drupal\field\Plugin\migrate\source\d7\ViewMode
* @group field
*/
class ViewModeTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\ViewMode';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_view_mode',
),
);
protected $expectedResults = array(
array(
'entity_type' => 'node',
'view_mode' => 'default',
),
array(
'entity_type' => 'node',
'view_mode' => 'teaser',
),
array(
'entity_type' => 'node',
'view_mode' => 'custom',
),
array(
'entity_type' => 'user',
'view_mode' => 'default',
),
array(
'entity_type' => 'comment',
'view_mode' => 'default',
),
);
class ViewModeTest extends MigrateSqlSourceTestBase {
/**
* Prepopulate contents with results.
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['field_config_instance'] = array(
array(
public static $modules = ['field', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [
[
'source_data' => [],
'expected_data' => [],
],
];
// The source data.
$tests[0]['source_data']['field_config_instance'] = [
[
'id' => '13',
'field_id' => '2',
'field_name' => 'body',
@ -56,8 +38,8 @@ class ViewModeTest extends MigrateSqlSourceTestCase {
'bundle' => 'forum',
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:1;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:3:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:11;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:11;}s:6:"custom";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:11;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
array(
],
[
'id' => '33',
'field_id' => '11',
'field_name' => 'field_file',
@ -65,8 +47,8 @@ class ViewModeTest extends MigrateSqlSourceTestCase {
'bundle' => 'user',
'data' => 'a:6:{s:5:"label";s:4:"File";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";i:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:0;}}s:8:"required";i:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
array(
],
[
'id' => '12',
'field_id' => '1',
'field_name' => 'comment_body',
@ -74,9 +56,34 @@ class ViewModeTest extends MigrateSqlSourceTestCase {
'bundle' => 'comment_node_forum',
'data' => 'a:6:{s:5:"label";s:7:"Comment";s:8:"settings";a:2:{s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:8:"required";b:1;s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:6:"weight";i:0;s:8:"settings";a:0:{}s:6:"module";s:4:"text";}}s:6:"widget";a:4:{s:4:"type";s:13:"text_textarea";s:8:"settings";a:1:{s:4:"rows";i:5;}s:6:"weight";i:0;s:6:"module";s:4:"text";}s:11:"description";s:0:"";}',
'deleted' => '0',
),
);
parent::setUp();
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'entity_type' => 'node',
'view_mode' => 'default',
],
[
'entity_type' => 'node',
'view_mode' => 'teaser',
],
[
'entity_type' => 'node',
'view_mode' => 'custom',
],
[
'entity_type' => 'user',
'view_mode' => 'default',
],
[
'entity_type' => 'comment',
'view_mode' => 'default',
],
];
return $tests;
}
}

View file

@ -1,75 +0,0 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d6;
use Drupal\field\Plugin\migrate\source\d6\FieldInstancePerFormDisplay;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests d6_field_instance_per_form_display source plugin.
*
* @group field
*/
class FieldInstancePerFormDisplayTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = FieldInstancePerFormDisplay::class;
protected $migrationConfiguration = array(
'id' => 'view_mode_test',
'source' => array(
'plugin' => 'd6_field_instance_per_form_display',
),
);
protected $expectedResults = array(
array(
'display_settings' => array(),
'widget_settings' => array(),
'type_name' => 'story',
'widget_active' => TRUE,
'field_name' => 'field_test_filefield',
'type' => 'filefield',
'module' => 'filefield',
'weight' => '8',
'widget_type' => 'filefield_widget',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$empty_array = serialize([]);
$this->databaseContents['content_node_field'] = array(
array(
'field_name' => 'field_test_filefield',
'type' => 'filefield',
'global_settings' => $empty_array,
'required' => '0',
'multiple' => '0',
'db_storage' => '1',
'module' => 'filefield',
'db_columns' => $empty_array,
'active' => '1',
'locked' => '0',
)
);
$this->databaseContents['content_node_field_instance'] = array(
array(
'field_name' => 'field_test_filefield',
'type_name' => 'story',
'weight' => '8',
'label' => 'File Field',
'widget_type' => 'filefield_widget',
'widget_settings' => $empty_array,
'display_settings' => $empty_array,
'description' => 'An example image field.',
'widget_module' => 'filefield',
'widget_active' => '1',
),
);
parent::setUp();
}
}

View file

@ -1,96 +0,0 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 fields per view mode source plugin.
*
* @group field
*/
class FieldInstancePerViewModeTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d6\FieldInstancePerViewMode';
protected $migrationConfiguration = array(
'id' => 'view_mode_test',
'source' => array(
'plugin' => 'd6_field_instance_per_view_mode',
),
);
protected $expectedResults = array(
array(
'entity_type' => 'node',
'view_mode' => 4,
'type_name' => 'article',
'field_name' => 'field_test',
'type' => 'text',
'module' => 'text',
'weight' => 1,
'label' => 'above',
'display_settings' => array(
'weight' => 1,
'parent' => '',
'label' => array(
'format' => 'above',
),
4 => array(
'format' => 'trimmed',
'exclude' => 0,
),
),
'widget_settings' => array(),
),
array(
'entity_type' => 'node',
'view_mode' => 'teaser',
'type_name' => 'story',
'field_name' => 'field_test',
'type' => 'text',
'module' => 'text',
'weight' => 2,
'label' => 'above',
'display_settings' => array(
'weight' => 1,
'parent' => '',
'label' => array(
'format' => 'above',
),
'teaser' => array(
'format' => 'trimmed',
'exclude' => 0,
),
),
'widget_settings' => array(),
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $k => $field_view_mode) {
// These are stored as serialized strings.
$field_view_mode['display_settings'] = serialize($field_view_mode['display_settings']);
$field_view_mode['widget_settings'] = serialize($field_view_mode['widget_settings']);
$this->databaseContents['content_node_field'][] = array(
'field_name' => $field_view_mode['field_name'],
'type' => $field_view_mode['type'],
'module' => $field_view_mode['module'],
);
unset($field_view_mode['type']);
unset($field_view_mode['module']);
$this->databaseContents['content_node_field_instance'][] = $field_view_mode;
// Update the expected display settings.
$this->expectedResults[$k]['display_settings'] = $this->expectedResults[$k]['display_settings'][$field_view_mode['view_mode']];
}
parent::setUp();
}
}

View file

@ -1,91 +0,0 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 field instance source plugin.
*
* @group field
*/
class FieldInstanceTest extends MigrateSqlSourceTestCase {
// The plugin system is not working during unit testing so the source plugin
// class needs to be manually specified.
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d6\FieldInstance';
// The fake Migration configuration entity.
protected $migrationConfiguration = [
// The id of the entity, can be any string.
'id' => 'test_fieldinstance',
'source' => [
'plugin' => 'd6_field_instance',
],
];
// We need to set up the database contents; it's easier to do that below.
// These are sample result queries.
protected $expectedResults = [
[
'field_name' => 'field_body',
'type_name' => 'page',
'weight' => 1,
'label' => 'body',
'widget_type' => 'text_textarea',
'widget_settings' => '',
'display_settings' => '',
'description' => '',
'widget_module' => 'text',
'widget_active' => 1,
'required' => 1,
'active' => 1,
'global_settings' => [],
],
];
/**
* Prepopulate contents with results.
*/
protected function setUp() {
$this->expectedResults[0]['widget_settings'] = [
'rows' => 5,
'size' => 60,
'default_value' => [
[
'value' => '',
'_error_element' => 'default_value_widget][field_body][0][value',
'default_value_php' => '',
],
],
];
$this->expectedResults[0]['display_settings'] = [
'label' => [
'format' => 'above',
'exclude' => 0,
],
'teaser' => [
'format' => 'default',
'exclude' => 0,
],
'full' => [
'format' => 'default',
'exclude' => 0,
],
];
$this->databaseContents['content_node_field_instance'] = $this->expectedResults;
$this->databaseContents['content_node_field_instance'][0]['widget_settings'] = serialize($this->expectedResults[0]['widget_settings']);
$this->databaseContents['content_node_field_instance'][0]['display_settings'] = serialize($this->expectedResults[0]['display_settings']);
$this->databaseContents['content_node_field_instance'][0]['global_settings'] = 'a:0:{}';
$this->databaseContents['content_node_field'][0] = [
'field_name' => 'field_body',
'required' => 1,
'type' => 'text',
'active' => 1,
'global_settings' => serialize([]),
];
parent::setUp();
}
}

View file

@ -1,72 +0,0 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 field source plugin.
*
* @group field
*/
class FieldTest extends MigrateSqlSourceTestCase {
// The plugin system is not working during unit testing so the source plugin
// class needs to be manually specified.
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d6\Field';
// The fake Migration configuration entity.
protected $migrationConfiguration = array(
// The id of the entity, can be any string.
'id' => 'test_field',
'source' => array(
'plugin' => 'd6_field',
),
);
// We need to set up the database contents; it's easier to do that below.
// These are sample result queries.
protected $expectedResults = array(
array(
'field_name' => 'field_body',
'type' => 'text',
'global_settings' => '',
'required' => 0,
'multiple' => 0,
'db_storage' => 1,
'module' => 'text',
'db_columns' => '',
'active' => 1,
'locked' => 0,
),
);
/**
* Prepopulate contents with results.
*/
protected function setUp() {
$this->expectedResults[0]['global_settings'] = array(
'text_processing' => 0,
'max_length' => '',
'allowed_values' => '',
'allowed_values_php' => '',
);
$this->expectedResults[0]['db_columns'] = array(
'value' => array(
'type' => 'text',
'size' => 'big',
'not null' => '',
'sortable' => 1,
'views' => 1,
),
);
$this->databaseContents['content_node_field'] = $this->expectedResults;
$this->databaseContents['content_node_field'][0]['global_settings'] = serialize($this->databaseContents['content_node_field'][0]['global_settings']);
$this->databaseContents['content_node_field'][0]['db_columns'] = serialize($this->databaseContents['content_node_field'][0]['db_columns']);
$this->databaseContents['content_node_field_instance'][0]['widget_type'] = 'text_textarea';
$this->databaseContents['content_node_field_instance'][0]['field_name'] = 'field_body';
parent::setUp();
}
}

View file

@ -1,68 +0,0 @@
<?php
namespace Drupal\Tests\field\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 field instance per view mode source plugin.
*
* @group field
*/
class FieldInstancePerViewModeTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\field\Plugin\migrate\source\d7\FieldInstancePerViewMode';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_field_instance_per_view_mode',
),
);
protected $expectedResults = array(
array(
'entity_type' => 'node',
'bundle' => 'page',
'field_name' => 'body',
'label' => 'hidden',
'type' => 'text_default',
'settings' => array(),
'module' => 'text',
'weight' => 0,
'view_mode' => 'default',
),
array(
'entity_type' => 'node',
'bundle' => 'page',
'field_name' => 'body',
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
'settings' => array(
'trim_length' => 600,
),
'module' => 'text',
'weight' => 0,
'view_mode' => 'teaser',
),
);
/**
* Prepopulate contents with results.
*/
protected function setUp() {
$this->databaseContents['field_config_instance'] = array(
array(
'id' => '2',
'field_id' => '2',
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => 'page',
'data' => 'a:6:{s:5:"label";s:4:"Body";s:6:"widget";a:4:{s:4:"type";s:26:"text_textarea_with_summary";s:8:"settings";a:2:{s:4:"rows";i:20;s:12:"summary_rows";i:5;}s:6:"weight";i:-4;s:6:"module";s:4:"text";}s:8:"settings";a:3:{s:15:"display_summary";b:1;s:15:"text_processing";i:1;s:18:"user_register_form";b:0;}s:7:"display";a:2:{s:7:"default";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:0;}s:6:"teaser";a:5:{s:5:"label";s:6:"hidden";s:4:"type";s:23:"text_summary_or_trimmed";s:8:"settings";a:1:{s:11:"trim_length";i:600;}s:6:"module";s:4:"text";s:6:"weight";i:0;}}s:8:"required";b:0;s:11:"description";s:0:"";}',
'deleted' => '0',
),
);
parent::setUp();
}
}

View file

@ -876,8 +876,12 @@ abstract class EntityDisplayFormBase extends EntityForm {
protected function saveDisplayStatuses($display_statuses) {
$displays = $this->getDisplays();
foreach ($displays as $display) {
$display->set('status', $display_statuses[$display->get('mode')]);
$display->save();
// Only update the display if the status is changing.
$new_status = $display_statuses[$display->get('mode')];
if ($new_status !== $display->status()) {
$display->set('status', $new_status);
$display->save();
}
}
}

View file

@ -50,10 +50,10 @@ class CckFile extends ProcessPluginBase implements ContainerFactoryPluginInterfa
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
// Configure the migration process plugin to look up migrated IDs from
// the d6_file migration.
$migration_plugin_configuration = [
'source' => ['fid'],
// a d6 file migration.
$migration_plugin_configuration = $configuration + [
'migration' => 'd6_file',
'source' => ['fid'],
];
return new static(

View file

@ -0,0 +1,32 @@
<?php
namespace Drupal\Tests\file\Kernel\Migrate\process\d6;
use Drupal\file\Plugin\migrate\process\d6\CckFile;
use Drupal\migrate\Plugin\Migration;
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
/**
* Cck file field migration.
*
* @coversDefaultClass \Drupal\file\Plugin\migrate\process\d6\CckFile
*
* @group file
*/
class CckFileTest extends MigrateDrupalTestBase {
/**
* Tests configurability of file migration name.
*
* @covers ::__construct
*/
public function testConfigurableFileMigration() {
$migration = Migration::create($this->container, [], 'custom_migration', []);
$cck_file_migration = CckFile::create($this->container, ['migration' => 'custom_file'], 'custom_file', [], $migration);
$migration_plugin = $this->readAttribute($cck_file_migration, 'migrationPlugin');
$config = $this->readAttribute($migration_plugin, 'configuration');
$this->assertEquals($config['migration'], 'custom_file');
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace Drupal\Tests\file\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 file source plugin.
*
* @covers \Drupal\file\Plugin\migrate\source\d6\File
*
* @group file
*/
class FileTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['file', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['files'] = [
[
'fid' => 1,
'uid' => 1,
'filename' => 'migrate-test-file-1.pdf',
'filepath' => 'sites/default/files/migrate-test-file-1.pdf',
'filemime' => 'application/pdf',
'filesize' => 890404,
'status' => 1,
'timestamp' => 1382255613,
],
[
'fid' => 2,
'uid' => 1,
'filename' => 'migrate-test-file-2.pdf',
'filepath' => 'sites/default/files/migrate-test-file-2.pdf',
'filemime' => 'application/pdf',
'filesize' => 204124,
'status' => 1,
'timestamp' => 1382255662,
],
];
// The expected results are identical to the source data.
$tests[0]['expected_data'] = $tests[0]['source_data']['files'];
return $tests;
}
}

View file

@ -0,0 +1,68 @@
<?php
namespace Drupal\Tests\file\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 d6_upload_instance source plugin.
*
* @covers \Drupal\file\Plugin\migrate\source\d6\UploadInstance
*
* @group file
*/
class UploadInstanceTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['file', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['node_type'] = [
[
'type' => 'article',
],
[
'type' => 'company',
],
];
$tests[0]['source_data']['variable'] = [
[
'name' => 'upload_article',
'value' => serialize(TRUE),
],
[
'name' => 'upload_company',
'value' => serialize(FALSE),
],
[
'name' => 'upload_uploadsize_default',
'value' => serialize(16),
],
[
'name' => 'upload_extensions_default',
'value' => serialize('txt pdf'),
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'node_type' => 'article',
'max_filesize' => '16MB',
'file_extensions' => 'txt pdf',
],
];
return $tests;
}
}

View file

@ -0,0 +1,78 @@
<?php
namespace Drupal\Tests\file\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 d6_upload source plugin.
*
* @covers \Drupal\file\Plugin\migrate\source\d6\Upload
*
* @group file
*/
class UploadTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['file', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['upload'] = [
[
'fid' => '1',
'nid' => '1',
'vid' => '1',
'description' => 'file 1-1-1',
'list' => '0',
'weight' => '-1',
],
];
$tests[0]['source_data']['node'] = [
[
'nid' => '1',
'vid' => '1',
'type' => 'story',
'language' => '',
'title' => 'Test title',
'uid' => '1',
'status' => '1',
'created' => '1388271197',
'changed' => '1420861423',
'comment' => '0',
'promote' => '0',
'moderate' => '0',
'sticky' => '0',
'tnid' => '0',
'translate' => '0',
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'upload' => [
[
'fid' => '1',
'description' => 'file 1-1-1',
'list' => '0',
],
],
'nid' => '1',
'vid' => '1',
'type' => 'story',
],
];
return $tests;
}
}

View file

@ -0,0 +1,112 @@
<?php
namespace Drupal\Tests\file\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 file source plugin.
*
* @covers \Drupal\file\Plugin\migrate\source\d7\File
* @group file
*/
class FileTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['file', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['file_managed'] = [
// A public file.
[
'fid' => '1',
'uid' => '1',
'filename' => 'cube.jpeg',
'uri' => 'public://cube.jpeg',
'filemime' => 'image/jpeg',
'filesize' => '3620',
'status' => '1',
'timestamp' => '1421727515',
],
// A private file.
[
'fid' => '1',
'uid' => '1',
'filename' => 'cube.jpeg',
'uri' => 'private://cube.jpeg',
'filemime' => 'image/jpeg',
'filesize' => '3620',
'status' => '1',
'timestamp' => '1421727515',
],
// A temporary file.
[
'fid' => '1',
'uid' => '1',
'filename' => 'cube.jpeg',
'uri' => 'temporary://cube.jpeg',
'filemime' => 'image/jpeg',
'filesize' => '3620',
'status' => '1',
'timestamp' => '1421727515',
],
// A file with a URI scheme that will be filtered out.
[
'fid' => '1',
'uid' => '1',
'filename' => 'cube.jpeg',
'uri' => 'null://cube.jpeg',
'filemime' => 'image/jpeg',
'filesize' => '3620',
'status' => '1',
'timestamp' => '1421727515',
],
];
$tests[0]['source_data']['variable'] = [
[
'name' => 'file_public_path',
'value' => serialize('sites/default/files'),
],
[
'name' => 'file_private_path',
'value' => serialize('/path/to/private/files'),
],
[
'name' => 'file_temporary_path',
'value' => serialize('/tmp'),
],
];
// The expected results will include only the first three files, since we
// are configuring the plugin to filter out the file with the null URI
// scheme.
$tests[0]['expected_data'] = array_slice($tests[0]['source_data']['file_managed'], 0, 3);
// The filepath property will vary by URI scheme.
$tests[0]['expected_data'][0]['filepath'] = 'sites/default/files/cube.jpeg';
$tests[0]['expected_data'][1]['filepath'] = '/path/to/private/files/cube.jpeg';
$tests[0]['expected_data'][2]['filepath'] = '/tmp/cube.jpeg';
// Do an automatic count.
$tests[0]['expected_count'] = NULL;
// Set up plugin configuration.
$tests[0]['configuration'] = [
'constants' => [
'source_base_path' => '/path/to/files',
],
// Only return files which use one of these URI schemes.
'scheme' => ['public', 'private', 'temporary'],
];
return $tests;
}
}

View file

@ -70,7 +70,7 @@ class FileUriTest extends MigrateTestCase {
protected function doTransform(array $value) {
$executable = new MigrateExecutable($this->getMigration(), new MigrateMessage());
$row = new Row([], []);
$row = new Row();
return (new FileUri([], 'file_uri', []))
->transform($value, $executable, $row, 'foobaz');

View file

@ -1,54 +0,0 @@
<?php
namespace Drupal\Tests\file\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D6 file source plugin.
*
* @group file
*/
class FileTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\file\Plugin\migrate\source\d6\File';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_file',
),
);
protected $expectedResults = array(
array(
'fid' => 1,
'uid' => 1,
'filename' => 'migrate-test-file-1.pdf',
'filepath' => 'sites/default/files/migrate-test-file-1.pdf',
'filemime' => 'application/pdf',
'filesize' => 890404,
'status' => 1,
'timestamp' => 1382255613,
),
array(
'fid' => 2,
'uid' => 1,
'filename' => 'migrate-test-file-2.pdf',
'filepath' => 'sites/default/files/migrate-test-file-2.pdf',
'filemime' => 'application/pdf',
'filesize' => 204124,
'status' => 1,
'timestamp' => 1382255662,
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['files'] = $this->expectedResults;
parent::setUp();
}
}

View file

@ -1,65 +0,0 @@
<?php
namespace Drupal\Tests\file\Unit\Plugin\migrate\source\d6;
use Drupal\file\Plugin\migrate\source\d6\UploadInstance;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests d6_upload_instance source plugin.
*
* @group file
*/
class UploadInstanceTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = UploadInstance::class;
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_upload_instance',
),
);
protected $expectedResults = array(
array(
'node_type' => 'article',
'max_filesize' => '16MB',
'file_extensions' => 'txt pdf',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['node_type'] = array(
array(
'type' => 'article',
),
array(
'type' => 'company',
),
);
$this->databaseContents['variable'] = array(
array(
'name' => 'upload_article',
'value' => serialize(TRUE),
),
array(
'name' => 'upload_company',
'value' => serialize(FALSE),
),
array(
'name' => 'upload_uploadsize_default',
'value' => serialize(16),
),
array(
'name' => 'upload_extensions_default',
'value' => serialize('txt pdf'),
),
);
parent::setUp();
}
}

View file

@ -1,75 +0,0 @@
<?php
namespace Drupal\Tests\file\Unit\Plugin\migrate\source\d6;
use Drupal\file\Plugin\migrate\source\d6\Upload;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests d6_upload source plugin.
*
* @group file
*/
class UploadTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = Upload::class;
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_upload',
),
);
protected $expectedResults = array(
array(
'upload' => array(
array(
'fid' => '1',
'description' => 'file 1-1-1',
'list' => '0',
),
),
'nid' => '1',
'vid' => '1',
'type' => 'story',
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['upload'] = array(
array(
'fid' => '1',
'nid' => '1',
'vid' => '1',
'description' => 'file 1-1-1',
'list' => '0',
'weight' => '-1',
),
);
$this->databaseContents['node'] = array(
array(
'nid' => '1',
'vid' => '1',
'type' => 'story',
'language' => '',
'title' => 'Test title',
'uid' => '1',
'status' => '1',
'created' => '1388271197',
'changed' => '1420861423',
'comment' => '0',
'promote' => '0',
'moderate' => '0',
'sticky' => '0',
'tnid' => '0',
'translate' => '0',
),
);
parent::setUp();
}
}

View file

@ -1,146 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Tests\file\Unit\Plugin\migrate\source\d7\FileTest.
*/
namespace Drupal\Tests\file\Unit\Plugin\migrate\source\d7;
use Drupal\Core\Database\Query\ConditionInterface;
use Drupal\file\Plugin\migrate\source\d7\File;
use Drupal\migrate\Row;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests D7 file source plugin.
*
* @group file
*/
class FileTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\Tests\file\Unit\Plugin\migrate\source\d7\TestFile';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd7_file',
'constants' => array(
'source_base_path' => '/path/to/files',
),
// Used by testFilteringByScheme().
'scheme' => array(
'public',
'private',
),
),
'destination' => array(
'plugin' => 'entity:file',
),
);
protected $expectedResults = [
[
'fid' => '1',
'uid' => '1',
'filename' => 'cube.jpeg',
'uri' => 'public://cube.jpeg',
'filemime' => 'image/jpeg',
'filesize' => '3620',
'status' => '1',
'timestamp' => '1421727515',
],
];
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->databaseContents['file_managed'] = $this->expectedResults;
parent::setUp();
}
/**
* Tests that public file URIs are properly transformed by prepareRow().
*/
public function testPublicUri() {
$this->source->publicPath = 'sites/default/files';
$row = new Row(['uri' => 'public://foo.png'], ['uri' => []]);
$this->source->prepareRow($row);
$this->assertEquals('sites/default/files/foo.png',
$row->getSourceProperty('filepath'));
}
/**
* Tests that private file URIs are properly transformed by prepareRow().
*/
public function testPrivateUri() {
$this->source->privatePath = '/path/to/private/files';
$row = new Row(['uri' => 'private://baz.jpeg'], ['uri' => []]);
$this->source->prepareRow($row);
$this->assertEquals('/path/to/private/files/baz.jpeg',
$row->getSourceProperty('filepath'));
}
/**
* Tests that temporary file URIs are property transformed by prepareRow().
*/
public function testTemporaryUri() {
$this->source->temporaryPath = '/tmp';
$row = new Row(['uri' => 'temporary://camelot/lancelot.gif'],
['uri' => []]);
$this->source->prepareRow($row);
$this->assertEquals('/tmp/camelot/lancelot.gif',
$row->getSourceProperty('filepath'));
}
/**
* Tests that it's possible to filter files by scheme.
*/
public function testFilteringByScheme() {
$query_conditions = $this->source->query()->conditions();
$scheme_condition = end($query_conditions);
$this->assertInstanceOf(ConditionInterface::class, $scheme_condition['field']);
$conditions = $scheme_condition['field']->conditions();
$this->assertSame('uri', $conditions[0]['field']);
$this->assertSame('LIKE', $conditions[0]['operator']);
$this->assertSame('public://%', $conditions[0]['value']);
$this->assertSame('uri', $conditions[1]['field']);
$this->assertSame('LIKE', $conditions[1]['operator']);
$this->assertSame('private://%', $conditions[1]['value']);
}
}
/**
* Testing version of \Drupal\file\Plugin\migrate\source\d7\File.
*
* Exposes inaccessible properties.
*/
class TestFile extends File {
/**
* The public file directory path.
*
* @var string
*/
public $publicPath;
/**
* The private file directory path, if any.
*
* @var string
*/
public $privatePath;
/**
* The temporary file directory path.
*
* @var string
*/
public $temporaryPath;
}

View file

@ -71,7 +71,7 @@ class FilterIdTest extends KernelTestBase {
);
}
$row = new Row([], []);
$row = new Row();
$output_value = $plugin->transform($value, $this->executable, $row, 'foo');
$this->assertSame($expected_value, $output_value);

View file

@ -0,0 +1,174 @@
<?php
namespace Drupal\Tests\filter\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 filter format source plugin.
*
* @covers \Drupal\filter\Plugin\migrate\source\d6\FilterFormat
*
* @group filter
*/
class FilterFormatTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['filter', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['filter_formats'] = [
[
'format' => 1,
'name' => 'Filtered HTML',
'roles' => ',1,2,',
'cache' => 1,
],
[
'format' => 2,
'name' => 'Full HTML',
'roles' => '',
'cache' => 1,
],
[
'format' => 4,
'name' => 'Example Custom Format',
'roles' => '4',
'cache' => 1,
],
];
$tests[0]['source_data']['filters'] = [
[
'fid' => 1,
'format' => 1,
'module' => 'filter',
'delta' => 2,
'weight' => 0,
],
[
'fid' => 2,
'format' => 1,
'module' => 'filter',
'delta' => 0,
'weight' => 1,
],
[
'fid' => 3,
'format' => 1,
'module' => 'filter',
'delta' => 1,
'weight' => 2,
],
[
'fid' => 4,
'format' => 2,
'module' => 'filter',
'delta' => 2,
'weight' => 0,
],
[
'fid' => 5,
'format' => 2,
'module' => 'filter',
'delta' => 1,
'weight' => 1,
],
[
'fid' => 6,
'format' => 2,
'module' => 'filter',
'delta' => 3,
'weight' => 10,
],
[
'fid' => 7,
'format' => 4,
'module' => 'markdown',
'delta' => 1,
'weight' => 10,
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'format' => 1,
'name' => 'Filtered HTML',
'roles' => [1, 2],
'cache' => 1,
'filters' => [
[
'module' => 'filter',
'delta' => 2,
'weight' => 0,
'settings' => [],
],
[
'module' => 'filter',
'delta' => 0,
'weight' => 1,
'settings' => [],
],
[
'module' => 'filter',
'delta' => 1,
'weight' => 2,
'settings' => [],
],
],
],
[
'format' => 2,
'name' => 'Full HTML',
'roles' => [],
'cache' => 1,
'filters' => [
[
'module' => 'filter',
'delta' => 2,
'weight' => 0,
'settings' => [],
],
[
'module' => 'filter',
'delta' => 1,
'weight' => 1,
'settings' => [],
],
[
'module' => 'filter',
'delta' => 3,
'weight' => 10,
'settings' => [],
],
],
],
[
'format' => 4,
'name' => 'Example Custom Format',
'roles' => [4],
'cache' => 1,
'filters' => [
// This custom format uses a filter defined by a contrib module.
[
'module' => 'markdown',
'delta' => 1,
'weight' => 10,
'settings' => [],
],
],
],
];
return $tests;
}
}

View file

@ -0,0 +1,120 @@
<?php
namespace Drupal\Tests\filter\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D7 filter format source plugin.
*
* @covers \Drupal\filter\Plugin\migrate\source\d7\FilterFormat
*
* @group filter
*/
class FilterFormatTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['filter', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['filter_format'] = [
[
'format' => 'custom_text_format',
'name' => 'Custom Text format',
'cache' => 1,
'status' => 1,
'weight' => 0,
],
[
'format' => 'full_html',
'name' => 'Full HTML',
'cache' => 1,
'status' => 1,
'weight' => 1,
],
];
$tests[0]['source_data']['filter'] = [
[
'format' => 'custom_text_format',
'module' => 'filter',
'name' => 'filter_autop',
'weight' => 0,
'status' => 1,
'settings' => serialize(array()),
],
[
'format' => 'custom_text_format',
'module' => 'filter',
'name' => 'filter_html',
'weight' => 1,
'status' => 1,
'settings' => serialize(array()),
],
[
'format' => 'full_html',
'module' => 'filter',
'name' => 'filter_url',
'weight' => 0,
'status' => 1,
'settings' => serialize(array()),
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'format' => 'custom_text_format',
'name' => 'Custom Text format',
'cache' => 1,
'status' => 1,
'weight' => 0,
'filters' => [
'filter_autop' => [
'format' => 'custom_text_format',
'module' => 'filter',
'name' => 'filter_autop',
'weight' => 0,
'status' => 1,
'settings' => [],
],
'filter_html' => [
'format' => 'custom_text_format',
'module' => 'filter',
'name' => 'filter_html',
'weight' => 1,
'status' => 1,
'settings' => [],
],
],
],
[
'format' => 'full_html',
'name' => 'Full HTML',
'cache' => 1,
'status' => 1,
'weight' => 1,
'filters' => [
'filter_url' => [
'format' => 'full_html',
'module' => 'filter',
'name' => 'filter_url',
'weight' => 0,
'status' => 1,
'settings' => [],
],
],
],
];
return $tests;
}
}

View file

@ -1,114 +0,0 @@
<?php
namespace Drupal\Tests\filter\Unit\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests d6_filter_format source plugin.
*
* @group filter
*/
class FilterFormatTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\filter\Plugin\migrate\source\d6\FilterFormat';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_filter_formats',
),
);
protected $expectedResults = array(
array(
'format' => 1,
'name' => 'Filtered HTML',
'roles' => array(1, 2),
'cache' => 1,
'filters' => array(
array(
'module' => 'filter',
'delta' => 2,
'weight' => 0,
'settings' => array(),
),
array(
'module' => 'filter',
'delta' => 0,
'weight' => 1,
'settings' => array(),
),
array(
'module' => 'filter',
'delta' => 1,
'weight' => 2,
'settings' => array(),
),
),
),
array(
'format' => 2,
'name' => 'Full HTML',
'roles' => array(),
'cache' => 1,
'filters' => array(
array(
'module' => 'filter',
'delta' => 2,
'weight' => 0,
'settings' => array(),
),
array(
'module' => 'filter',
'delta' => 1,
'weight' => 1,
'settings' => array(),
),
array(
'module' => 'filter',
'delta' => 3,
'weight' => 10,
'settings' => array(),
),
),
),
array(
'format' => 4,
'name' => 'Example Custom Format',
'roles' => array(4),
'cache' => 1,
'filters' => array(
// This custom format uses a filter defined by a contrib module.
array(
'module' => 'markdown',
'delta' => 1,
'weight' => 10,
'settings' => array(),
),
),
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
$fid = 1;
$empty_array = serialize(array());
foreach ($this->expectedResults as $k => $row) {
$row['roles'] = ',' . implode(',', $row['roles']) . ',';
foreach ($row['filters'] as $filter) {
$filter['settings'] = $empty_array;
$this->databaseContents['filters'][$fid] = $filter;
$this->databaseContents['filters'][$fid]['format'] = $row['format'];
$this->databaseContents['filters'][$fid]['fid'] = $fid;
$fid++;
}
unset($row['filters']);
$this->databaseContents['filter_formats'][$k] = $row;
}
parent::setUp();
}
}

View file

@ -1,84 +0,0 @@
<?php
namespace Drupal\Tests\filter\Unit\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
/**
* Tests d7_filter_format source plugin.
*
* @group filter
*/
class FilterFormatTest extends MigrateSqlSourceTestCase {
const PLUGIN_CLASS = 'Drupal\filter\Plugin\migrate\source\d7\FilterFormat';
protected $migrationConfiguration = array(
'id' => 'test',
'source' => array(
'plugin' => 'd6_filter_formats',
),
);
protected $expectedResults = array(
array(
'format' => 'custom_text_format',
'name' => 'Custom Text format',
'cache' => 1,
'status' => 1,
'weight' => 0,
'filters' => array(
'filter_autop' => array(
'format' => 'custom_text_format',
'module' => 'filter',
'name' => 'filter_autop',
'weight' => 0,
'status' => 1,
'settings' => array(),
),
'filter_html' => array(
'format' => 'custom_text_format',
'module' => 'filter',
'name' => 'filter_html',
'weight' => 1,
'status' => 1,
'settings' => array(),
),
),
),
array(
'format' => 'full_html',
'name' => 'Full HTML',
'cache' => 1,
'status' => 1,
'weight' => 1,
'filters' => array(
'filter_url' => array(
'format' => 'full_html',
'module' => 'filter',
'name' => 'filter_url',
'weight' => 0,
'status' => 1,
'settings' => array(),
),
),
),
);
/**
* {@inheritdoc}
*/
protected function setUp() {
foreach ($this->expectedResults as $row) {
foreach ($row['filters'] as $filter) {
$filter['format'] = $row['format'];
$filter['settings'] = serialize($filter['settings']);
$this->databaseContents['filter'][] = $filter;
}
unset($row['filters']);
$this->databaseContents['filter_format'][] = $row;
}
parent::setUp();
}
}

View file

@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\taxonomy\VocabularyInterface;
use Drupal\user\Entity\User;
/**
@ -295,7 +296,7 @@ function forum_form_taxonomy_vocabulary_form_alter(&$form, FormStateInterface $f
// Forum's vocabulary always has single hierarchy. Forums and containers
// have only one parent or no parent for root items. By default this value
// is 0.
$form['hierarchy']['#value'] = TAXONOMY_HIERARCHY_SINGLE;
$form['hierarchy']['#value'] = VocabularyInterface::HIERARCHY_SINGLE;
// Do not allow to delete forum's vocabulary.
$form['actions']['delete']['#access'] = FALSE;
// Do not allow to change a vid of forum's vocabulary.

View file

@ -129,14 +129,22 @@ class ContentEntityNormalizer extends NormalizerBase {
// Create the entity.
$typed_data_ids = $this->getTypedDataIds($data['_links']['type'], $context);
$entity_type = $this->entityManager->getDefinition($typed_data_ids['entity_type']);
$default_langcode_key = $entity_type->getKey('default_langcode');
$langcode_key = $entity_type->getKey('langcode');
$values = array();
// Figure out the language to use.
if (isset($data[$langcode_key])) {
$values[$langcode_key] = $data[$langcode_key][0]['value'];
// Remove the langcode so it does not get iterated over below.
unset($data[$langcode_key]);
if (isset($data[$default_langcode_key])) {
// Find the field item for which the default_lancode value is set to 1 and
// set the langcode the right default language.
foreach ($data[$default_langcode_key] as $item) {
if (!empty($item['value']) && isset($item['lang'])) {
$values[$langcode_key] = $item['lang'];
break;
}
}
// Remove the default langcode so it does not get iterated over below.
unset($data[$default_langcode_key]);
}
if ($entity_type->hasKey('bundle')) {

View file

@ -0,0 +1,89 @@
<?php
namespace Drupal\Tests\hal\Kernel;
use Drupal\node\Entity\Node;
use Drupal\user\Entity\User;
use Drupal\node\Entity\NodeType;
/**
* Tests that translated nodes are correctly (de-)normalized.
*
* @group hal
*/
class EntityTranslationNormalizeTest extends NormalizerTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('node', 'content_translation');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', array('sequences'));
$this->installConfig(['node', 'content_translation']);
}
/**
* Tests the normalization of node translations.
*/
public function testNodeTranslation() {
$node_type = NodeType::create(['type' => 'example_type']);
$node_type->save();
$this->container->get('content_translation.manager')->setEnabled('node', 'example_type', TRUE);
$user = User::create(['name' => $this->randomMachineName()]);
$user->save();
$node = Node::create([
'title' => $this->randomMachineName(),
'uid' => $user->id(),
'type' => $node_type->id(),
'status' => NODE_PUBLISHED,
'langcode' => 'en',
'promote' => 1,
'sticky' => 0,
'body' => [
'value' => $this->randomMachineName(),
'format' => $this->randomMachineName()
],
'revision_log' => $this->randomString(),
]);
$node->addTranslation('de', [
'title' => 'German title',
'body' => [
'value' => $this->randomMachineName(),
'format' => $this->randomMachineName()
],
]);
$node->save();
$original_values = $node->toArray();
$translation = $node->getTranslation('de');
$original_translation_values = $node->getTranslation('en')->toArray();
$normalized = $this->serializer->normalize($node, $this->format);
$this->assertContains(['lang' => 'en', 'value' => $node->getTitle()], $normalized['title'], 'Original language title has been normalized.');
$this->assertContains(['lang' => 'de', 'value' => $translation->getTitle()], $normalized['title'], 'Translation language title has been normalized.');
/** @var \Drupal\node\NodeInterface $denormalized_node */
$denormalized_node = $this->serializer->denormalize($normalized, 'Drupal\node\Entity\Node', $this->format);
$this->assertSame($denormalized_node->language()->getId(), $denormalized_node->getUntranslated()->language()->getId(), 'Untranslated object is returned from serializer.');
$this->assertSame('en', $denormalized_node->language()->getId());
$this->assertTrue($denormalized_node->hasTranslation('de'));
$this->assertSame($node->getTitle(), $denormalized_node->getTitle());
$this->assertSame($translation->getTitle(), $denormalized_node->getTranslation('de')->getTitle());
$this->assertEquals($original_values, $denormalized_node->toArray(), 'Node values are restored after normalizing and denormalizing.');
$this->assertEquals($original_translation_values, $denormalized_node->getTranslation('en')->toArray(), 'Node values are restored after normalizing and denormalizing.');
}
}

View file

@ -18,15 +18,15 @@
*/
#}
{% if data.width and data.height -%}
{{ data.width|e }}×{{ data.height|e }}
{{ data.width }}×{{ data.height }}
{%- else -%}
{% if data.width %}
{% trans %}
width {{ data.width|e }}
width {{ data.width }}
{% endtrans %}
{% elseif data.height %}
{% trans %}
height {{ data.height|e }}
height {{ data.height }}
{% endtrans %}
{% endif %}
{%- endif %}

View file

@ -16,15 +16,15 @@
*/
#}
{% if data.width and data.height -%}
{{ data.width|e }}×{{ data.height|e }}
{{ data.width }}×{{ data.height }}
{%- else -%}
{% if data.width %}
{% trans %}
width {{ data.width|e }}
width {{ data.width }}
{% endtrans %}
{% elseif data.height %}
{% trans %}
height {{ data.height|e }}
height {{ data.height }}
{% endtrans %}
{% endif %}
{%- endif %}

View file

@ -19,8 +19,9 @@
*/
#}
{% if data.random %}
{% set degrees = data.degrees|abs %}
{% trans %}
random between -{{ data.degrees|abs }}° and {{ data.degrees|abs }}°
random between -{{ degrees }}° and {{ degrees }}°
{% endtrans %}
{% else %}
{{ data.degrees }}°

Some files were not shown because too many files have changed in this diff Show more