Update core 8.3.0
This commit is contained in:
parent
da7a7918f8
commit
cd7a898e66
6144 changed files with 132297 additions and 87747 deletions
|
@ -50,15 +50,15 @@ use Drupal\node\NodeInterface;
|
|||
* @see node_access_test_node_access_records()
|
||||
*/
|
||||
function node_access_test_node_grants($account, $op) {
|
||||
$grants = array();
|
||||
$grants['node_access_test_author'] = array($account->id());
|
||||
$grants = [];
|
||||
$grants['node_access_test_author'] = [$account->id()];
|
||||
if ($op == 'view' && $account->hasPermission('node test view', $account)) {
|
||||
$grants['node_access_test'] = array(8888, 8889);
|
||||
$grants['node_access_test'] = [8888, 8889];
|
||||
}
|
||||
|
||||
$no_access_uid = \Drupal::state()->get('node_access_test.no_access_uid') ?: 0;
|
||||
if ($op == 'view' && $account->id() == $no_access_uid) {
|
||||
$grants['node_access_all'] = array(0);
|
||||
$grants['node_access_all'] = [0];
|
||||
}
|
||||
return $grants;
|
||||
}
|
||||
|
@ -77,37 +77,37 @@ function node_access_test_node_grants($account, $op) {
|
|||
* @see node_access_test.permissions.yml
|
||||
*/
|
||||
function node_access_test_node_access_records(NodeInterface $node) {
|
||||
$grants = array();
|
||||
$grants = [];
|
||||
// For NodeAccessBaseTableTestCase, only set records for private nodes.
|
||||
if (!\Drupal::state()->get('node_access_test.private') || $node->private->value) {
|
||||
// Groups 8888 and 8889 for the node_access_test realm both receive a view
|
||||
// grant for all controlled nodes. See node_access_test_node_grants().
|
||||
$grants[] = array(
|
||||
$grants[] = [
|
||||
'realm' => 'node_access_test',
|
||||
'gid' => 8888,
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 0,
|
||||
'grant_delete' => 0,
|
||||
'priority' => 0,
|
||||
);
|
||||
$grants[] = array(
|
||||
];
|
||||
$grants[] = [
|
||||
'realm' => 'node_access_test',
|
||||
'gid' => 8889,
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 0,
|
||||
'grant_delete' => 0,
|
||||
'priority' => 0,
|
||||
);
|
||||
];
|
||||
// For the author realm, the group ID is equivalent to a user ID, which
|
||||
// means there are many many groups of just 1 user.
|
||||
$grants[] = array(
|
||||
$grants[] = [
|
||||
'realm' => 'node_access_test_author',
|
||||
'gid' => $node->getOwnerId(),
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 1,
|
||||
'grant_delete' => 1,
|
||||
'priority' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return $grants;
|
||||
|
@ -120,25 +120,25 @@ function node_access_test_node_access_records(NodeInterface $node) {
|
|||
* A node type entity.
|
||||
*/
|
||||
function node_access_test_add_field(NodeTypeInterface $type) {
|
||||
$field_storage = FieldStorageConfig::create(array(
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'private',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'integer',
|
||||
));
|
||||
]);
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::create(array(
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => 'private',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $type->id(),
|
||||
'label' => 'Private',
|
||||
));
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
// Assign widget settings for the 'default' form mode.
|
||||
entity_get_form_display('node', $type->id(), 'default')
|
||||
->setComponent('private', array(
|
||||
->setComponent('private', [
|
||||
'type' => 'number',
|
||||
))
|
||||
])
|
||||
->save();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ use Drupal\node\NodeInterface;
|
|||
* Implements hook_node_grants().
|
||||
*/
|
||||
function node_access_test_empty_node_grants($account, $op) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_access_records().
|
||||
*/
|
||||
function node_access_test_empty_node_access_records(NodeInterface $node) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use Drupal\node\NodeInterface;
|
|||
* This module defines a single grant realm. All users belong to this group.
|
||||
*/
|
||||
function node_access_test_language_node_grants($account, $op) {
|
||||
$grants['node_access_language_test'] = array(7888);
|
||||
$grants['node_access_language_test'] = [7888];
|
||||
return $grants;
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,13 @@ function node_access_test_language_node_grants($account, $op) {
|
|||
* Implements hook_node_access_records().
|
||||
*/
|
||||
function node_access_test_language_node_access_records(NodeInterface $node) {
|
||||
$grants = array();
|
||||
$grants = [];
|
||||
|
||||
// Create grants for each translation of the node.
|
||||
foreach ($node->getTranslationLanguages() as $langcode => $language) {
|
||||
// If the translation is not marked as private, grant access.
|
||||
$translation = $node->getTranslation($langcode);
|
||||
$grants[] = array(
|
||||
$grants[] = [
|
||||
'realm' => 'node_access_language_test',
|
||||
'gid' => 7888,
|
||||
'grant_view' => empty($translation->field_private->value) ? 1 : 0,
|
||||
|
@ -38,7 +38,7 @@ function node_access_test_language_node_access_records(NodeInterface $node) {
|
|||
'grant_delete' => 0,
|
||||
'priority' => 0,
|
||||
'langcode' => $langcode,
|
||||
);
|
||||
];
|
||||
}
|
||||
return $grants;
|
||||
}
|
||||
|
|
|
@ -21,23 +21,23 @@ use Drupal\node\NodeInterface;
|
|||
function node_test_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
|
||||
if ($view_mode == 'rss') {
|
||||
// Add RSS elements and namespaces when building the RSS feed.
|
||||
$node->rss_elements[] = array(
|
||||
$node->rss_elements[] = [
|
||||
'key' => 'testElement',
|
||||
'value' => t('Value of testElement RSS element for node @nid.', array('@nid' => $node->id())),
|
||||
);
|
||||
'value' => t('Value of testElement RSS element for node @nid.', ['@nid' => $node->id()]),
|
||||
];
|
||||
|
||||
// Add content that should be displayed only in the RSS feed.
|
||||
$build['extra_feed_content'] = array(
|
||||
'#markup' => '<p>' . t('Extra data that should appear only in the RSS feed for node @nid.', array('@nid' => $node->id())) . '</p>',
|
||||
$build['extra_feed_content'] = [
|
||||
'#markup' => '<p>' . t('Extra data that should appear only in the RSS feed for node @nid.', ['@nid' => $node->id()]) . '</p>',
|
||||
'#weight' => 10,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
if ($view_mode != 'rss') {
|
||||
// Add content that should NOT be displayed in the RSS feed.
|
||||
$build['extra_non_feed_content'] = array(
|
||||
'#markup' => '<p>' . t('Extra data that should appear everywhere except the RSS feed for node @nid.', array('@nid' => $node->id())) . '</p>',
|
||||
);
|
||||
$build['extra_non_feed_content'] = [
|
||||
'#markup' => '<p>' . t('Extra data that should appear everywhere except the RSS feed for node @nid.', ['@nid' => $node->id()]) . '</p>',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +57,11 @@ function node_test_node_grants(AccountInterface $account, $op) {
|
|||
// Give everyone full grants so we don't break other node tests.
|
||||
// Our node access tests asserts three realms of access.
|
||||
// See testGrantAlter().
|
||||
return array(
|
||||
'test_article_realm' => array(1),
|
||||
'test_page_realm' => array(1),
|
||||
'test_alter_realm' => array(2),
|
||||
);
|
||||
return [
|
||||
'test_article_realm' => [1],
|
||||
'test_page_realm' => [1],
|
||||
'test_alter_realm' => [2],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,28 +72,28 @@ function node_test_node_access_records(NodeInterface $node) {
|
|||
if (!empty($node->disable_node_access)) {
|
||||
return;
|
||||
}
|
||||
$grants = array();
|
||||
$grants = [];
|
||||
if ($node->getType() == 'article') {
|
||||
// Create grant in arbitrary article_realm for article nodes.
|
||||
$grants[] = array(
|
||||
$grants[] = [
|
||||
'realm' => 'test_article_realm',
|
||||
'gid' => 1,
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 0,
|
||||
'grant_delete' => 0,
|
||||
'priority' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
elseif ($node->getType() == 'page') {
|
||||
// Create grant in arbitrary page_realm for page nodes.
|
||||
$grants[] = array(
|
||||
$grants[] = [
|
||||
'realm' => 'test_page_realm',
|
||||
'gid' => 1,
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 0,
|
||||
'grant_delete' => 0,
|
||||
'priority' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
return $grants;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ function node_test_node_access_records_alter(&$grants, NodeInterface $node) {
|
|||
*/
|
||||
function node_test_node_grants_alter(&$grants, AccountInterface $account, $op) {
|
||||
// Return an empty array of grants to prove that we can alter by reference.
|
||||
$grants = array();
|
||||
$grants = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,40 +4,13 @@ namespace Drupal\node_access_test_auto_bubbling\Controller;
|
|||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\Query\QueryFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Returns a node ID listing.
|
||||
*/
|
||||
class NodeAccessTestAutoBubblingController extends ControllerBase implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* The entity query factory service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Query\QueryFactory
|
||||
*/
|
||||
protected $entityQuery;
|
||||
|
||||
/**
|
||||
* Constructs a new NodeAccessTestAutoBubblingController.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
|
||||
* The entity query factory.
|
||||
*/
|
||||
public function __construct(QueryFactory $entity_query) {
|
||||
$this->entityQuery = $entity_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.query')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the three latest published node IDs.
|
||||
*
|
||||
|
@ -45,8 +18,8 @@ class NodeAccessTestAutoBubblingController extends ControllerBase implements Con
|
|||
* A render array.
|
||||
*/
|
||||
public function latest() {
|
||||
$nids = $this->entityQuery->get('node')
|
||||
->condition('status', NODE_PUBLISHED)
|
||||
$nids = $this->entityTypeManager()->getStorage('node')->getQuery()
|
||||
->condition('status', NodeInterface::PUBLISHED)
|
||||
->sort('created', 'DESC')
|
||||
->range(0, 3)
|
||||
->execute();
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Migrate\d6;
|
||||
use Drupal\Tests\node\Kernel\Migrate\d6\MigrateNodeTestBase;
|
||||
|
||||
/**
|
||||
* Node content revisions migration.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateNodeRevisionTest extends MigrateNodeTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['language', 'content_translation'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigrations(['d6_node', 'd6_node_revision']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test node revisions migration from Drupal 6 to 8.
|
||||
*/
|
||||
public function testNodeRevision() {
|
||||
$node = \Drupal::entityManager()->getStorage('node')->loadRevision(2);
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$this->assertIdentical('1', $node->id());
|
||||
$this->assertIdentical('2', $node->getRevisionId());
|
||||
$this->assertIdentical('und', $node->langcode->value);
|
||||
$this->assertIdentical('Test title rev 2', $node->getTitle());
|
||||
$this->assertIdentical('body test rev 2', $node->body->value);
|
||||
$this->assertIdentical('teaser test rev 2', $node->body->summary);
|
||||
$this->assertIdentical('2', $node->getRevisionUser()->id());
|
||||
$this->assertIdentical('modified rev 2', $node->revision_log->value);
|
||||
$this->assertIdentical('1390095702', $node->getRevisionCreationTime());
|
||||
|
||||
$node = \Drupal::entityManager()->getStorage('node')->loadRevision(5);
|
||||
$this->assertIdentical('1', $node->id());
|
||||
$this->assertIdentical('body test rev 3', $node->body->value);
|
||||
$this->assertIdentical('1', $node->getRevisionUser()->id());
|
||||
$this->assertIdentical('modified rev 3', $node->revision_log->value);
|
||||
$this->assertIdentical('1390095703', $node->getRevisionCreationTime());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Tests the d7_node node deriver.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeMigrateDeriverTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = ['node'];
|
||||
|
||||
public function testBuilder() {
|
||||
$process = $this->getMigration('d7_node:test_content_type')->getProcess();
|
||||
$this->assertIdentical('field_boolean', $process['field_boolean'][0]['source']);
|
||||
$this->assertIdentical('field_email', $process['field_email'][0]['source']);
|
||||
$this->assertIdentical('field_phone', $process['field_phone'][0]['source']);
|
||||
$this->assertIdentical('field_date', $process['field_date'][0]['source']);
|
||||
$this->assertIdentical('field_date_with_end_time', $process['field_date_with_end_time'][0]['source']);
|
||||
$this->assertIdentical('field_file', $process['field_file'][0]['source']);
|
||||
$this->assertIdentical('field_float', $process['field_float'][0]['source']);
|
||||
$this->assertIdentical('field_images', $process['field_images'][0]['source']);
|
||||
$this->assertIdentical('field_integer', $process['field_integer'][0]['source']);
|
||||
$this->assertIdentical('field_link', $process['field_link'][0]['source']);
|
||||
$this->assertIdentical('field_text_list', $process['field_text_list'][0]['source']);
|
||||
$this->assertIdentical('field_integer_list', $process['field_integer_list'][0]['source']);
|
||||
$this->assertIdentical('field_long_text', $process['field_long_text'][0]['source']);
|
||||
$this->assertIdentical('field_term_reference', $process['field_term_reference'][0]['source']);
|
||||
$this->assertIdentical('field_text', $process['field_text'][0]['source']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the persistence of basic options through multiple steps.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class MultiStepNodeFormBasicOptionsTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* The field name to create.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* Tests changing the default values of basic options to ensure they persist.
|
||||
*/
|
||||
public function testMultiStepNodeFormBasicOptions() {
|
||||
// Prepare a user to create the node.
|
||||
$web_user = $this->drupalCreateUser(['administer nodes', 'create page content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create an unlimited cardinality field.
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text',
|
||||
'cardinality' => -1,
|
||||
])->save();
|
||||
|
||||
// Attach an instance of the field to the page content type.
|
||||
FieldConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
])->save();
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => 'text_textfield',
|
||||
])
|
||||
->save();
|
||||
|
||||
$edit = [
|
||||
'title[0][value]' => 'a',
|
||||
'promote[value]' => FALSE,
|
||||
'sticky[value]' => 1,
|
||||
"{$this->fieldName}[0][value]" => $this->randomString(32),
|
||||
];
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Add another item'));
|
||||
$this->assertNoFieldChecked('edit-promote-value', 'Promote stayed unchecked');
|
||||
$this->assertFieldChecked('edit-sticky-value', 'Sticky stayed checked');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the interaction of the node access system with fields.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeAccessFieldTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_access_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* A user with permission to bypass access content.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* A user with permission to manage content types and fields.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $contentAdminUser;
|
||||
|
||||
/**
|
||||
* The name of the created field.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
node_access_rebuild();
|
||||
|
||||
// Create some users.
|
||||
$this->adminUser = $this->drupalCreateUser(['access content', 'bypass node access']);
|
||||
$this->contentAdminUser = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields']);
|
||||
|
||||
// Add a custom field to the page content type.
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text'
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
])->save();
|
||||
entity_get_display('node', 'page', 'default')
|
||||
->setComponent($this->fieldName)
|
||||
->save();
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->setComponent($this->fieldName)
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests administering fields when node access is restricted.
|
||||
*/
|
||||
public function testNodeAccessAdministerField() {
|
||||
// Create a page node.
|
||||
$fieldData = [];
|
||||
$value = $fieldData[0]['value'] = $this->randomMachineName();
|
||||
$node = $this->drupalCreateNode([$this->fieldName => $fieldData]);
|
||||
|
||||
// Log in as the administrator and confirm that the field value is present.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertText($value, 'The saved field value is visible to an administrator.');
|
||||
|
||||
// Log in as the content admin and try to view the node.
|
||||
$this->drupalLogin($this->contentAdminUser);
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertText('Access denied', 'Access is denied for the content admin.');
|
||||
|
||||
// Modify the field default as the content admin.
|
||||
$edit = [];
|
||||
$default = 'Sometimes words have two meanings';
|
||||
$edit["default_value_input[{$this->fieldName}][0][value]"] = $default;
|
||||
$this->drupalPostForm(
|
||||
"admin/structure/types/manage/page/fields/node.page.{$this->fieldName}",
|
||||
$edit,
|
||||
t('Save settings')
|
||||
);
|
||||
|
||||
// Log in as the administrator.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Confirm that the existing node still has the correct field value.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertText($value, 'The original field value is visible to an administrator.');
|
||||
|
||||
// Confirm that the new default value appears when creating a new node.
|
||||
$this->drupalGet('node/add/page');
|
||||
$this->assertRaw($default, 'The updated default value is displayed when creating a new node.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
/**
|
||||
* Tests the node access grants cache context service.
|
||||
*
|
||||
* @group node
|
||||
* @group Cache
|
||||
*/
|
||||
class NodeAccessGrantsCacheContextTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_access_test'];
|
||||
|
||||
/**
|
||||
* User with permission to view content.
|
||||
*/
|
||||
protected $accessUser;
|
||||
|
||||
/**
|
||||
* User without permission to view content.
|
||||
*/
|
||||
protected $noAccessUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
node_access_rebuild();
|
||||
|
||||
// Create some content.
|
||||
$this->drupalCreateNode();
|
||||
$this->drupalCreateNode();
|
||||
$this->drupalCreateNode();
|
||||
$this->drupalCreateNode();
|
||||
|
||||
// Create user with simple node access permission. The 'node test view'
|
||||
// permission is implemented and granted by the node_access_test module.
|
||||
$this->accessUser = $this->drupalCreateUser(['access content overview', 'access content', 'node test view']);
|
||||
$this->noAccessUser = $this->drupalCreateUser(['access content overview', 'access content']);
|
||||
$this->noAccessUser2 = $this->drupalCreateUser(['access content overview', 'access content']);
|
||||
|
||||
$this->userMapping = [
|
||||
1 => $this->rootUser,
|
||||
2 => $this->accessUser,
|
||||
3 => $this->noAccessUser,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that for each given user, the expected cache context is returned.
|
||||
*
|
||||
* @param array $expected
|
||||
* Expected values, keyed by user ID, expected cache contexts as values.
|
||||
*/
|
||||
protected function assertUserCacheContext(array $expected) {
|
||||
foreach ($expected as $uid => $context) {
|
||||
if ($uid > 0) {
|
||||
$this->drupalLogin($this->userMapping[$uid]);
|
||||
}
|
||||
$this->pass('Asserting cache context for user ' . $uid . '.');
|
||||
$this->assertIdentical($context, $this->container->get('cache_context.user.node_grants')->getContext('view'));
|
||||
}
|
||||
$this->drupalLogout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests NodeAccessGrantsCacheContext::getContext().
|
||||
*/
|
||||
public function testCacheContext() {
|
||||
$this->assertUserCacheContext([
|
||||
0 => 'view.all:0;node_access_test_author:0;node_access_all:0',
|
||||
1 => 'all',
|
||||
2 => 'view.all:0;node_access_test_author:2;node_access_test:8888,8889',
|
||||
3 => 'view.all:0;node_access_test_author:3',
|
||||
]);
|
||||
|
||||
// Grant view to all nodes (because nid = 0) for users in the
|
||||
// 'node_access_all' realm.
|
||||
$record = [
|
||||
'nid' => 0,
|
||||
'gid' => 0,
|
||||
'realm' => 'node_access_all',
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 0,
|
||||
'grant_delete' => 0,
|
||||
];
|
||||
db_insert('node_access')->fields($record)->execute();
|
||||
|
||||
// Put user accessUser (uid 0) in the realm.
|
||||
\Drupal::state()->set('node_access_test.no_access_uid', 0);
|
||||
drupal_static_reset('node_access_view_all_nodes');
|
||||
$this->assertUserCacheContext([
|
||||
0 => 'view.all',
|
||||
1 => 'all',
|
||||
2 => 'view.all:0;node_access_test_author:2;node_access_test:8888,8889',
|
||||
3 => 'view.all:0;node_access_test_author:3',
|
||||
]);
|
||||
|
||||
// Put user accessUser (uid 2) in the realm.
|
||||
\Drupal::state()->set('node_access_test.no_access_uid', $this->accessUser->id());
|
||||
drupal_static_reset('node_access_view_all_nodes');
|
||||
$this->assertUserCacheContext([
|
||||
0 => 'view.all:0;node_access_test_author:0',
|
||||
1 => 'all',
|
||||
2 => 'view.all',
|
||||
3 => 'view.all:0;node_access_test_author:3',
|
||||
]);
|
||||
|
||||
// Put user noAccessUser (uid 3) in the realm.
|
||||
\Drupal::state()->set('node_access_test.no_access_uid', $this->noAccessUser->id());
|
||||
drupal_static_reset('node_access_view_all_nodes');
|
||||
$this->assertUserCacheContext([
|
||||
0 => 'view.all:0;node_access_test_author:0',
|
||||
1 => 'all',
|
||||
2 => 'view.all:0;node_access_test_author:2;node_access_test:8888,8889',
|
||||
3 => 'view.all',
|
||||
]);
|
||||
|
||||
// Uninstall the node_access_test module
|
||||
$this->container->get('module_installer')->uninstall(['node_access_test']);
|
||||
drupal_static_reset('node_access_view_all_nodes');
|
||||
$this->assertUserCacheContext([
|
||||
0 => 'view.all',
|
||||
1 => 'all',
|
||||
2 => 'view.all',
|
||||
3 => 'view.all',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,334 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests node access functionality with multiple languages and two node access
|
||||
* modules.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Enable language and two node access modules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['language', 'node_access_test_language', 'node_access_test'];
|
||||
|
||||
/**
|
||||
* A set of nodes to use in testing.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $nodes = [];
|
||||
|
||||
/**
|
||||
* A normal authenticated user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface.
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* User 1.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface.
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
node_access_test_add_field(NodeType::load('page'));
|
||||
|
||||
// Create the 'private' field, which allows the node to be marked as private
|
||||
// (restricted access) in a given translation.
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_private',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'boolean',
|
||||
'cardinality' => 1,
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'page',
|
||||
'widget' => [
|
||||
'type' => 'options_buttons',
|
||||
],
|
||||
'settings' => [
|
||||
'on_label' => 'Private',
|
||||
'off_label' => 'Not private',
|
||||
],
|
||||
])->save();
|
||||
|
||||
// After enabling a node access module, the access table has to be rebuild.
|
||||
node_access_rebuild();
|
||||
|
||||
// Add Hungarian and Catalan.
|
||||
ConfigurableLanguage::createFromLangcode('hu')->save();
|
||||
ConfigurableLanguage::createFromLangcode('ca')->save();
|
||||
|
||||
// Create a normal authenticated user.
|
||||
$this->webUser = $this->drupalCreateUser(['access content']);
|
||||
|
||||
// Load the user 1 user for later use as an admin user with permission to
|
||||
// see everything.
|
||||
$this->adminUser = User::load(1);
|
||||
|
||||
// The node_access_test_language module allows individual translations of a
|
||||
// node to be marked private (not viewable by normal users), and the
|
||||
// node_access_test module allows whole nodes to be marked private. (In a
|
||||
// real-world implementation, hook_node_access_records_alter() might be
|
||||
// implemented by one or both modules to enforce that private nodes or
|
||||
// translations are always private, but we want to test the default,
|
||||
// additive behavior of node access).
|
||||
|
||||
// Create six Hungarian nodes with Catalan translations:
|
||||
// 1. One public with neither language marked as private.
|
||||
// 2. One private with neither language marked as private.
|
||||
// 3. One public with only the Hungarian translation private.
|
||||
// 4. One public with only the Catalan translation private.
|
||||
// 5. One public with both the Hungarian and Catalan translations private.
|
||||
// 6. One private with both the Hungarian and Catalan translations private.
|
||||
$this->nodes['public_both_public'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 0]],
|
||||
'private' => FALSE,
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['private_both_public'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 0]],
|
||||
'private' => TRUE,
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['public_hu_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 1]],
|
||||
'private' => FALSE,
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['public_ca_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 0]],
|
||||
'private' => FALSE,
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['public_both_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 1]],
|
||||
'private' => FALSE,
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['private_both_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 1]],
|
||||
'private' => TRUE,
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['public_no_language_private'] = $this->drupalCreateNode([
|
||||
'field_private' => [['value' => 1]],
|
||||
'private' => FALSE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->nodes['public_no_language_public'] = $this->drupalCreateNode([
|
||||
'field_private' => [['value' => 0]],
|
||||
'private' => FALSE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->nodes['private_no_language_private'] = $this->drupalCreateNode([
|
||||
'field_private' => [['value' => 1]],
|
||||
'private' => TRUE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->nodes['private_no_language_public'] = $this->drupalCreateNode([
|
||||
'field_private' => [['value' => 1]],
|
||||
'private' => TRUE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node access and node access queries with multiple node languages.
|
||||
*/
|
||||
public function testNodeAccessLanguageAwareCombination() {
|
||||
|
||||
$expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
|
||||
$expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
|
||||
|
||||
// When the node and both translations are public, access should always be
|
||||
// granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// If the node is marked private but both existing translations are not,
|
||||
// access should still be granted, because the grants are additive.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// If the node is marked private, but a existing translation is public,
|
||||
// access should only be granted for the public translation. With the
|
||||
// Hungarian translation marked as private, but the Catalan translation
|
||||
// public, the access is granted.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_hu_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// With the Catalan translation marked as private, but the node public,
|
||||
// access is granted for the existing Hungarian translation, but not for the
|
||||
// Catalan.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// With both translations marked as private, but the node public, access
|
||||
// should be denied in all cases.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// If the node and both its existing translations are private, access should
|
||||
// be denied in all cases.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// No access for all languages as the language aware node access module
|
||||
// denies access.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser);
|
||||
|
||||
// Access only for request with no language defined.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_no_language_public'], $this->webUser);
|
||||
|
||||
// No access for all languages as both node access modules deny access.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser);
|
||||
|
||||
// No access for all languages as the non language aware node access module
|
||||
// denies access.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser);
|
||||
|
||||
// Query the node table with the node access tag in several languages.
|
||||
|
||||
// Query with no language specified. The fallback (hu or und) will be used.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Four nodes should be returned with public Hungarian translations or the
|
||||
// no language public node.
|
||||
$this->assertEqual(count($nids), 4, 'db_select() returns 4 nodes when no langcode is specified.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_both_public']->id(), $nids), 'Returned node ID is full public node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_ca_private']->id(), $nids), 'Returned node ID is Hungarian public only node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['private_both_public']->id(), $nids), 'Returned node ID is both public non-language-aware private only node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_no_language_public']->id(), $nids), 'Returned node ID is no language public node.');
|
||||
|
||||
// Query with Hungarian (hu) specified.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addMetaData('langcode', 'hu')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Three nodes should be returned (with public Hungarian translations).
|
||||
$this->assertEqual(count($nids), 3, 'db_select() returns 3 nodes.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_both_public']->id(), $nids), 'Returned node ID is both public node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_ca_private']->id(), $nids), 'Returned node ID is Hungarian public only node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['private_both_public']->id(), $nids), 'Returned node ID is both public non-language-aware private only node.');
|
||||
|
||||
// Query with Catalan (ca) specified.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addMetaData('langcode', 'ca')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Three nodes should be returned (with public Catalan translations).
|
||||
$this->assertEqual(count($nids), 3, 'db_select() returns 3 nodes.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_both_public']->id(), $nids), 'Returned node ID is both public node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['public_hu_private']->id(), $nids), 'Returned node ID is Catalan public only node.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['private_both_public']->id(), $nids), 'Returned node ID is both public non-language-aware private only node.');
|
||||
|
||||
// Query with German (de) specified.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addMetaData('langcode', 'de')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// There are no nodes with German translations, so no results are returned.
|
||||
$this->assertTrue(empty($nids), 'db_select() returns an empty result.');
|
||||
|
||||
// Query the nodes table as admin user (full access) with the node access
|
||||
// tag and no specific langcode.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->adminUser)
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// All nodes are returned.
|
||||
$this->assertEqual(count($nids), 10, 'db_select() returns all nodes.');
|
||||
|
||||
// Query the nodes table as admin user (full access) with the node access
|
||||
// tag and langcode de.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->adminUser)
|
||||
->addMetaData('langcode', 'de')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Even though there is no German translation, all nodes are returned
|
||||
// because node access filtering does not occur when the user is user 1.
|
||||
$this->assertEqual(count($nids), 10, 'db_select() returns all nodes.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests node_access and db_select() with node_access tag functionality with
|
||||
* multiple languages with node_access_test_language which is language-aware.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeAccessLanguageAwareTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Enable language and a language-aware node access module.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['language', 'node_access_test_language'];
|
||||
|
||||
/**
|
||||
* A set of nodes to use in testing.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $nodes = [];
|
||||
|
||||
/**
|
||||
* A user with permission to bypass access content.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* A normal authenticated user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create the 'private' field, which allows the node to be marked as private
|
||||
// (restricted access) in a given translation.
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_private',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'boolean',
|
||||
'cardinality' => 1,
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'page',
|
||||
'widget' => [
|
||||
'type' => 'options_buttons',
|
||||
],
|
||||
'settings' => [
|
||||
'on_label' => 'Private',
|
||||
'off_label' => 'Not private',
|
||||
],
|
||||
])->save();
|
||||
|
||||
// After enabling a node access module, the access table has to be rebuild.
|
||||
node_access_rebuild();
|
||||
|
||||
// Create a normal authenticated user.
|
||||
$this->webUser = $this->drupalCreateUser(['access content']);
|
||||
|
||||
// Load the user 1 user for later use as an admin user with permission to
|
||||
// see everything.
|
||||
$this->adminUser = User::load(1);
|
||||
|
||||
// Add Hungarian and Catalan.
|
||||
ConfigurableLanguage::createFromLangcode('hu')->save();
|
||||
ConfigurableLanguage::createFromLangcode('ca')->save();
|
||||
|
||||
// The node_access_test_language module allows individual translations of a
|
||||
// node to be marked private (not viewable by normal users).
|
||||
|
||||
// Create six nodes:
|
||||
// 1. Four Hungarian nodes with Catalan translations
|
||||
// - One with neither language marked as private.
|
||||
// - One with only the Hungarian translation private.
|
||||
// - One with only the Catalan translation private.
|
||||
// - One with both the Hungarian and Catalan translations private.
|
||||
// 2. Two nodes with no language specified.
|
||||
// - One public.
|
||||
// - One private.
|
||||
$this->nodes['both_public'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 0]],
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['ca_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 0]],
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['hu_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 1]],
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['both_private'] = $node = $this->drupalCreateNode([
|
||||
'body' => [[]],
|
||||
'langcode' => 'hu',
|
||||
'field_private' => [['value' => 1]],
|
||||
]);
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
||||
$this->nodes['no_language_public'] = $this->drupalCreateNode([
|
||||
'field_private' => [['value' => 0]],
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->nodes['no_language_private'] = $this->drupalCreateNode([
|
||||
'field_private' => [['value' => 1]],
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node access and node access queries with multiple node languages.
|
||||
*/
|
||||
public function testNodeAccessLanguageAware() {
|
||||
// The node_access_test_language module only grants view access.
|
||||
$expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
|
||||
$expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
|
||||
|
||||
// When both Hungarian and Catalan are marked as public, access to the
|
||||
// Hungarian translation should be granted with the default entity object or
|
||||
// when the Hungarian translation is specified explicitly.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public']->getTranslation('hu'), $this->webUser);
|
||||
// Access to the Catalan translation should also be granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When Hungarian is marked as private, access to the Hungarian translation
|
||||
// should be denied with the default entity object or when the Hungarian
|
||||
// translation is specified explicitly.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['hu_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['hu_private']->getTranslation('hu'), $this->webUser);
|
||||
// Access to the Catalan translation should be granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['hu_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When Catalan is marked as private, access to the Hungarian translation
|
||||
// should be granted with the default entity object or when the Hungarian
|
||||
// translation is specified explicitly.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['ca_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['ca_private']->getTranslation('hu'), $this->webUser);
|
||||
// Access to the Catalan translation should be granted.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['ca_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When both translations are marked as private, access should be denied
|
||||
// regardless of the entity object specified.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When no language is specified for a private node, access to every node
|
||||
// translation is denied.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_private'], $this->webUser);
|
||||
|
||||
// When no language is specified for a public node, access should be
|
||||
// granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['no_language_public'], $this->webUser);
|
||||
|
||||
// Query the node table with the node access tag in several languages.
|
||||
|
||||
// Query with no language specified. The fallback (hu) will be used.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Three nodes should be returned:
|
||||
// - Node with both translations public.
|
||||
// - Node with only the Catalan translation marked as private.
|
||||
// - No language node marked as public.
|
||||
$this->assertEqual(count($nids), 3, 'db_select() returns 3 nodes when no langcode is specified.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['both_public']->id(), $nids), 'The node with both translations public is returned.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['ca_private']->id(), $nids), 'The node with only the Catalan translation private is returned.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['no_language_public']->id(), $nids), 'The node with no language is returned.');
|
||||
|
||||
// Query with Hungarian (hu) specified.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addMetaData('langcode', 'hu')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Two nodes should be returned: the node with both translations public, and
|
||||
// the node with only the Catalan translation marked as private.
|
||||
$this->assertEqual(count($nids), 2, 'db_select() returns 2 nodes when the hu langcode is specified.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['both_public']->id(), $nids), 'The node with both translations public is returned.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['ca_private']->id(), $nids), 'The node with only the Catalan translation private is returned.');
|
||||
|
||||
// Query with Catalan (ca) specified.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addMetaData('langcode', 'ca')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Two nodes should be returned: the node with both translations public, and
|
||||
// the node with only the Hungarian translation marked as private.
|
||||
$this->assertEqual(count($nids), 2, 'db_select() returns 2 nodes when the hu langcode is specified.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['both_public']->id(), $nids), 'The node with both translations public is returned.');
|
||||
$this->assertTrue(array_key_exists($this->nodes['hu_private']->id(), $nids), 'The node with only the Hungarian translation private is returned.');
|
||||
|
||||
// Query with German (de) specified.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->webUser)
|
||||
->addMetaData('langcode', 'de')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// There are no nodes with German translations, so no results are returned.
|
||||
$this->assertTrue(empty($nids), 'db_select() returns an empty result when the de langcode is specified.');
|
||||
|
||||
// Query the nodes table as admin user (full access) with the node access
|
||||
// tag and no specific langcode.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->adminUser)
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// All nodes are returned.
|
||||
$this->assertEqual(count($nids), 6, 'db_select() returns all nodes.');
|
||||
|
||||
// Query the nodes table as admin user (full access) with the node access
|
||||
// tag and langcode de.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $this->adminUser)
|
||||
->addMetaData('langcode', 'de')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Even though there is no German translation, all nodes are returned
|
||||
// because node access filtering does not occur when the user is user 1.
|
||||
$this->assertEqual(count($nids), 6, 'db_select() returns all nodes.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Tests node_access and db_select() with node_access tag functionality with
|
||||
* multiple languages with a test node access module that is not language-aware.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeAccessLanguageTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['language', 'node_access_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
node_access_test_add_field(NodeType::load('page'));
|
||||
|
||||
// After enabling a node access module, the access table has to be rebuild.
|
||||
node_access_rebuild();
|
||||
|
||||
// Enable the private node feature of the node_access_test module.
|
||||
\Drupal::state()->set('node_access_test.private', TRUE);
|
||||
|
||||
// Add Hungarian, Catalan and Croatian.
|
||||
ConfigurableLanguage::createFromLangcode('hu')->save();
|
||||
ConfigurableLanguage::createFromLangcode('ca')->save();
|
||||
ConfigurableLanguage::createFromLangcode('hr')->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node access with multiple node languages and no private nodes.
|
||||
*/
|
||||
public function testNodeAccess() {
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
|
||||
$expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
|
||||
$expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
|
||||
|
||||
// Creating a public node with langcode Hungarian, will be saved as the
|
||||
// fallback in node access table.
|
||||
$node_public_hu = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => FALSE]);
|
||||
$this->assertTrue($node_public_hu->language()->getId() == 'hu', 'Node created as Hungarian.');
|
||||
|
||||
// Tests the default access is provided for the public Hungarian node.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
|
||||
|
||||
// Tests that Hungarian provided specifically results in the same.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Creating a public node with no special langcode, like when no language
|
||||
// module enabled.
|
||||
$node_public_no_language = $this->drupalCreateNode([
|
||||
'private' => FALSE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->assertTrue($node_public_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
|
||||
|
||||
// Tests that access is granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
|
||||
|
||||
// Reset the node access cache and turn on our test node access code.
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 1);
|
||||
$node_public_ca = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'ca', 'private' => FALSE]);
|
||||
$this->assertTrue($node_public_ca->language()->getId() == 'ca', 'Node created as Catalan.');
|
||||
|
||||
// Tests that access is granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user);
|
||||
|
||||
// Tests that Hungarian node is still accessible.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Tests that Catalan is still not accessible.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
|
||||
|
||||
// Make Catalan accessible.
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 0);
|
||||
|
||||
// Tests that Catalan is accessible on a node with a Catalan version as the
|
||||
// static cache has not been reset.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
|
||||
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
|
||||
// Tests that access is granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_ca, $web_user);
|
||||
|
||||
// Tests that Hungarian node is still accessible.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Tests that Catalan is accessible on a node with a Catalan version.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_ca->getTranslation('ca'), $web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node access with multiple node languages and private nodes.
|
||||
*/
|
||||
public function testNodeAccessPrivate() {
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
$expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
|
||||
$expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
|
||||
|
||||
// Creating a private node with langcode Hungarian, will be saved as the
|
||||
// fallback in node access table.
|
||||
$node_private_hu = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => TRUE]);
|
||||
$this->assertTrue($node_private_hu->language()->getId() == 'hu', 'Node created as Hungarian.');
|
||||
|
||||
// Tests the default access is not provided for the private Hungarian node.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu, $web_user);
|
||||
|
||||
// Tests that Hungarian provided specifically results in the same.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Creating a private node with no special langcode, like when no language
|
||||
// module enabled.
|
||||
$node_private_no_language = $this->drupalCreateNode([
|
||||
'private' => TRUE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->assertTrue($node_private_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
|
||||
|
||||
// Tests that access is not granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
|
||||
|
||||
// Reset the node access cache and turn on our test node access code.
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 1);
|
||||
|
||||
// Tests that access is not granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
|
||||
|
||||
// Creating a private node with langcode Catalan to test that the
|
||||
// node_access_test_secret_catalan flag works.
|
||||
$private_ca_user = $this->drupalCreateUser(['access content', 'node test view']);
|
||||
$node_private_ca = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'ca', 'private' => TRUE]);
|
||||
$this->assertTrue($node_private_ca->language()->getId() == 'ca', 'Node created as Catalan.');
|
||||
|
||||
// Tests that Catalan is still not accessible to either user.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $private_ca_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $private_ca_user);
|
||||
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 0);
|
||||
|
||||
// Tests that Catalan is still not accessible for a user with no access to
|
||||
// private nodes.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $web_user);
|
||||
|
||||
// Tests that Catalan is accessible by a user with the permission to see
|
||||
// private nodes.
|
||||
$this->assertNodeAccess($expected_node_access, $node_private_ca, $private_ca_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_private_ca->getTranslation('ca'), $private_ca_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests db_select() with a 'node_access' tag and langcode metadata.
|
||||
*/
|
||||
public function testNodeAccessQueryTag() {
|
||||
// Create a normal authenticated user.
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
|
||||
// Load the user 1 user for later use as an admin user with permission to
|
||||
// see everything.
|
||||
$admin_user = User::load(1);
|
||||
|
||||
// Creating a private node with langcode Hungarian, will be saved as
|
||||
// the fallback in node access table.
|
||||
$node_private = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => TRUE]);
|
||||
$this->assertTrue($node_private->language()->getId() == 'hu', 'Node created as Hungarian.');
|
||||
|
||||
// Creating a public node with langcode Hungarian, will be saved as
|
||||
// the fallback in node access table.
|
||||
$node_public = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => FALSE]);
|
||||
$this->assertTrue($node_public->language()->getId() == 'hu', 'Node created as Hungarian.');
|
||||
|
||||
// Creating a public node with no special langcode, like when no language
|
||||
// module enabled.
|
||||
$node_no_language = $this->drupalCreateNode([
|
||||
'private' => FALSE,
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->assertTrue($node_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
|
||||
|
||||
// Query the nodes table as the web user with the node access tag and no
|
||||
// specific langcode.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $web_user)
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// The public node and no language node should be returned. Because no
|
||||
// langcode is given it will use the fallback node.
|
||||
$this->assertEqual(count($nids), 2, 'db_select() returns 2 node');
|
||||
$this->assertTrue(array_key_exists($node_public->id(), $nids), 'Returned node ID is public node.');
|
||||
$this->assertTrue(array_key_exists($node_no_language->id(), $nids), 'Returned node ID is no language node.');
|
||||
|
||||
// Query the nodes table as the web user with the node access tag and
|
||||
// langcode de.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $web_user)
|
||||
->addMetaData('langcode', 'de')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// Because no nodes are created in German, no nodes are returned.
|
||||
$this->assertTrue(empty($nids), 'db_select() returns an empty result.');
|
||||
|
||||
// Query the nodes table as admin user (full access) with the node access
|
||||
// tag and no specific langcode.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $admin_user)
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// All nodes are returned.
|
||||
$this->assertEqual(count($nids), 3, 'db_select() returns all three nodes.');
|
||||
|
||||
// Query the nodes table as admin user (full access) with the node access
|
||||
// tag and langcode de.
|
||||
$select = db_select('node', 'n')
|
||||
->fields('n', ['nid'])
|
||||
->addMetaData('account', $admin_user)
|
||||
->addMetaData('langcode', 'de')
|
||||
->addTag('node_access');
|
||||
$nids = $select->execute()->fetchAllAssoc('nid');
|
||||
|
||||
// All nodes are returned because node access tag is not invoked when the
|
||||
// user is user 1.
|
||||
$this->assertEqual(count($nids), 3, 'db_select() returns all three nodes.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Tests the interaction of the node access system with menu links.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeAccessMenuLinkTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['menu_ui', 'block'];
|
||||
|
||||
/**
|
||||
* A user with permission to manage menu links and create nodes.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $contentAdminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalPlaceBlock('system_menu_block:main');
|
||||
|
||||
$this->contentAdminUser = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'administer content types',
|
||||
'administer menu'
|
||||
]);
|
||||
|
||||
$this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', [])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* SA-CORE-2015-003: Tests menu links to nodes when node access is restricted.
|
||||
*/
|
||||
public function testNodeAccessMenuLink() {
|
||||
|
||||
$menu_link_title = $this->randomString();
|
||||
|
||||
$this->drupalLogin($this->contentAdminUser);
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomString(),
|
||||
'body[0][value]' => $this->randomString(),
|
||||
'menu[enabled]' => 1,
|
||||
'menu[title]' => $menu_link_title,
|
||||
];
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
$this->assertLink($menu_link_title);
|
||||
|
||||
// Ensure anonymous users without "access content" permission do not see
|
||||
// this menu link.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('');
|
||||
$this->assertNoLink($menu_link_title);
|
||||
|
||||
// Ensure anonymous users with "access content" permission see this menu
|
||||
// link.
|
||||
$this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', ['access content'])->save();
|
||||
$this->drupalGet('');
|
||||
$this->assertLink($menu_link_title);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Tests hook_node_access_records when acquiring grants.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeAccessRecordsTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Enable a module that implements node access API hooks and alter hook.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_test'];
|
||||
|
||||
/**
|
||||
* Creates a node and tests the creation of node access rules.
|
||||
*/
|
||||
public function testNodeAccessRecords() {
|
||||
// Create an article node.
|
||||
$node1 = $this->drupalCreateNode(['type' => 'article']);
|
||||
$this->assertTrue(Node::load($node1->id()), 'Article node created.');
|
||||
|
||||
// Check to see if grants added by node_test_node_access_records made it in.
|
||||
$records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node1->id()])->fetchAll();
|
||||
$this->assertEqual(count($records), 1, 'Returned the correct number of rows.');
|
||||
$this->assertEqual($records[0]->realm, 'test_article_realm', 'Grant with article_realm acquired for node without alteration.');
|
||||
$this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
|
||||
|
||||
// Create an unpromoted "Basic page" node.
|
||||
$node2 = $this->drupalCreateNode(['type' => 'page', 'promote' => 0]);
|
||||
$this->assertTrue(Node::load($node2->id()), 'Unpromoted basic page node created.');
|
||||
|
||||
// Check to see if grants added by node_test_node_access_records made it in.
|
||||
$records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node2->id()])->fetchAll();
|
||||
$this->assertEqual(count($records), 1, 'Returned the correct number of rows.');
|
||||
$this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.');
|
||||
$this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
|
||||
|
||||
// Create an unpromoted, unpublished "Basic page" node.
|
||||
$node3 = $this->drupalCreateNode(['type' => 'page', 'promote' => 0, 'status' => 0]);
|
||||
$this->assertTrue(Node::load($node3->id()), 'Unpromoted, unpublished basic page node created.');
|
||||
|
||||
// Check to see if grants added by node_test_node_access_records made it in.
|
||||
$records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node3->id()])->fetchAll();
|
||||
$this->assertEqual(count($records), 1, 'Returned the correct number of rows.');
|
||||
$this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.');
|
||||
$this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
|
||||
|
||||
// Create a promoted "Basic page" node.
|
||||
$node4 = $this->drupalCreateNode(['type' => 'page', 'promote' => 1]);
|
||||
$this->assertTrue(Node::load($node4->id()), 'Promoted basic page node created.');
|
||||
|
||||
// Check to see if grant added by node_test_node_access_records was altered
|
||||
// by node_test_node_access_records_alter.
|
||||
$records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node4->id()])->fetchAll();
|
||||
$this->assertEqual(count($records), 1, 'Returned the correct number of rows.');
|
||||
$this->assertEqual($records[0]->realm, 'test_alter_realm', 'Altered grant with alter_realm acquired for node.');
|
||||
$this->assertEqual($records[0]->gid, 2, 'Altered grant with gid = 2 acquired for node.');
|
||||
|
||||
// Check to see if we can alter grants with hook_node_grants_alter().
|
||||
$operations = ['view', 'update', 'delete'];
|
||||
// Create a user that is allowed to access content.
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
foreach ($operations as $op) {
|
||||
$grants = node_test_node_grants($web_user, $op);
|
||||
$altered_grants = $grants;
|
||||
\Drupal::moduleHandler()->alter('node_grants', $altered_grants, $web_user, $op);
|
||||
$this->assertNotEqual($grants, $altered_grants, format_string('Altered the %op grant for a user.', ['%op' => $op]));
|
||||
}
|
||||
|
||||
// Check that core does not grant access to an unpublished node when an
|
||||
// empty $grants array is returned.
|
||||
$node6 = $this->drupalCreateNode(['status' => 0, 'disable_node_access' => TRUE]);
|
||||
$records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node6->id()])->fetchAll();
|
||||
$this->assertEqual(count($records), 0, 'Returned no records for unpublished node.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\system\Entity\Action;
|
||||
|
||||
/**
|
||||
* Tests configuration of actions provided by the Node module.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeActionsConfigurationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['action', 'node'];
|
||||
|
||||
/**
|
||||
* Tests configuration of the node_assign_owner_action action.
|
||||
*/
|
||||
public function testAssignOwnerNodeActionConfiguration() {
|
||||
// Create a user with permission to view the actions administration pages.
|
||||
$user = $this->drupalCreateUser(['administer actions']);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
// Make a POST request to admin/config/system/actions.
|
||||
$edit = [];
|
||||
$edit['action'] = Crypt::hashBase64('node_assign_owner_action');
|
||||
$this->drupalPostForm('admin/config/system/actions', $edit, t('Create'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make a POST request to the individual action configuration page.
|
||||
$edit = [];
|
||||
$action_label = $this->randomMachineName();
|
||||
$edit['label'] = $action_label;
|
||||
$edit['id'] = strtolower($action_label);
|
||||
$edit['owner_uid'] = $user->id();
|
||||
$this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('node_assign_owner_action'), $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make sure that the new action was saved properly.
|
||||
$this->assertText(t('The action has been successfully saved.'), 'The node_assign_owner_action action has been successfully saved.');
|
||||
$this->assertText($action_label, 'The label of the node_assign_owner_action action appears on the actions administration page after saving.');
|
||||
|
||||
// Make another POST request to the action edit page.
|
||||
$this->clickLink(t('Configure'));
|
||||
preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
|
||||
$aid = $matches[1];
|
||||
$edit = [];
|
||||
$new_action_label = $this->randomMachineName();
|
||||
$edit['label'] = $new_action_label;
|
||||
$edit['owner_uid'] = $user->id();
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make sure that the action updated properly.
|
||||
$this->assertText(t('The action has been successfully saved.'), 'The node_assign_owner_action action has been successfully updated.');
|
||||
$this->assertNoText($action_label, 'The old label for the node_assign_owner_action action does not appear on the actions administration page after updating.');
|
||||
$this->assertText($new_action_label, 'The new label for the node_assign_owner_action action appears on the actions administration page after updating.');
|
||||
|
||||
// Make sure that deletions work properly.
|
||||
$this->drupalGet('admin/config/system/actions');
|
||||
$this->clickLink(t('Delete'));
|
||||
$this->assertResponse(200);
|
||||
$edit = [];
|
||||
$this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make sure that the action was actually deleted.
|
||||
$this->assertRaw(t('The action %action has been deleted.', ['%action' => $new_action_label]), 'The delete confirmation message appears after deleting the node_assign_owner_action action.');
|
||||
$this->drupalGet('admin/config/system/actions');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoText($new_action_label, 'The label for the node_assign_owner_action action does not appear on the actions administration page after deleting.');
|
||||
|
||||
$action = Action::load($aid);
|
||||
$this->assertFalse($action, 'The node_assign_owner_action action is not available after being deleted.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\system\Tests\Entity\EntityWithUriCacheTagsTestBase;
|
||||
|
||||
/**
|
||||
* Tests the Node entity's cache tags.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeCacheTagsTest extends EntityWithUriCacheTagsTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
// Create a "Camelids" node type.
|
||||
NodeType::create([
|
||||
'name' => 'Camelids',
|
||||
'type' => 'camelids',
|
||||
])->save();
|
||||
|
||||
// Create a "Llama" node.
|
||||
$node = Node::create(['type' => 'camelids']);
|
||||
$node->setTitle('Llama')
|
||||
->setPublished(TRUE)
|
||||
->save();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getDefaultCacheContexts() {
|
||||
$defaults = parent::getDefaultCacheContexts();
|
||||
// @see \Drupal\node\Controller\NodeViewController::view()
|
||||
$defaults[] = 'user.roles:anonymous';
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) {
|
||||
return ['timezone'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Each node must have an author.
|
||||
*/
|
||||
protected function getAdditionalCacheTagsForEntity(EntityInterface $node) {
|
||||
return ['user:' . $node->getOwnerId(), 'user_view'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getAdditionalCacheContextsForEntityListing() {
|
||||
return ['user.node_grants:view'];
|
||||
}
|
||||
|
||||
}
|
234
web/core/modules/node/tests/src/Functional/NodeCreationTest.php
Normal file
234
web/core/modules/node/tests/src/Functional/NodeCreationTest.php
Normal file
|
@ -0,0 +1,234 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Create a node and test saving it.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeCreationTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* Enable dummy module that implements hook_ENTITY_TYPE_insert() for
|
||||
* exceptions (function node_test_exception_node_insert() ).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_test_exception', 'dblog', 'test_page_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser(['create page content', 'edit own page content']);
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a "Basic page" node and verifies its consistency in the database.
|
||||
*/
|
||||
public function testNodeCreation() {
|
||||
$node_type_storage = \Drupal::entityManager()->getStorage('node_type');
|
||||
|
||||
// Test /node/add page with only one content type.
|
||||
$node_type_storage->load('article')->delete();
|
||||
$this->drupalGet('node/add');
|
||||
$this->assertResponse(200);
|
||||
$this->assertUrl('node/add/page');
|
||||
// Create a node.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit['body[0][value]'] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
|
||||
// Check that the Basic page has been created.
|
||||
$this->assertText(t('@post @title has been created.', ['@post' => 'Basic page', '@title' => $edit['title[0][value]']]), 'Basic page created.');
|
||||
|
||||
// Verify that the creation message contains a link to a node.
|
||||
$view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']);
|
||||
$this->assert(isset($view_link), 'The message area contains a link to a node');
|
||||
|
||||
// Check that the node exists in the database.
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->assertTrue($node, 'Node found in database.');
|
||||
|
||||
// Verify that pages do not show submitted information by default.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertNoText($node->getOwner()->getUsername());
|
||||
$this->assertNoText(format_date($node->getCreatedTime()));
|
||||
|
||||
// Change the node type setting to show submitted by information.
|
||||
/** @var \Drupal\node\NodeTypeInterface $node_type */
|
||||
$node_type = $node_type_storage->load('page');
|
||||
$node_type->setDisplaySubmitted(TRUE);
|
||||
$node_type->save();
|
||||
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertText($node->getOwner()->getUsername());
|
||||
$this->assertText(format_date($node->getCreatedTime()));
|
||||
|
||||
// Check if the node revision checkbox is not rendered on node creation form.
|
||||
$admin_user = $this->drupalCreateUser(['administer nodes', 'create page content']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalGet('node/add/page');
|
||||
$this->assertNoFieldById('edit-revision', NULL, 'The revision checkbox is not present.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that a transaction rolls back the failed creation.
|
||||
*/
|
||||
public function testFailedPageCreation() {
|
||||
// Create a node.
|
||||
$edit = [
|
||||
'uid' => $this->loggedInUser->id(),
|
||||
'name' => $this->loggedInUser->name,
|
||||
'type' => 'page',
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
'title' => 'testing_transaction_exception',
|
||||
];
|
||||
|
||||
try {
|
||||
// An exception is generated by node_test_exception_node_insert() if the
|
||||
// title is 'testing_transaction_exception'.
|
||||
Node::create($edit)->save();
|
||||
$this->fail(t('Expected exception has not been thrown.'));
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$this->pass(t('Expected exception has been thrown.'));
|
||||
}
|
||||
|
||||
if (Database::getConnection()->supportsTransactions()) {
|
||||
// Check that the node does not exist in the database.
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
$this->assertFalse($node, 'Transactions supported, and node not found in database.');
|
||||
}
|
||||
else {
|
||||
// Check that the node exists in the database.
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
$this->assertTrue($node, 'Transactions not supported, and node found in database.');
|
||||
|
||||
// Check that the failed rollback was logged.
|
||||
$records = static::getWatchdogIdsForFailedExplicitRollback();
|
||||
$this->assertTrue(count($records) > 0, 'Transactions not supported, and rollback error logged to watchdog.');
|
||||
}
|
||||
|
||||
// Check that the rollback error was logged.
|
||||
$records = static::getWatchdogIdsForTestExceptionRollback();
|
||||
$this->assertTrue(count($records) > 0, 'Rollback explanatory error logged to watchdog.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unpublished node and confirms correct redirect behavior.
|
||||
*/
|
||||
public function testUnpublishedNodeCreation() {
|
||||
// Set the front page to the test page.
|
||||
$this->config('system.site')->set('page.front', '/test-page')->save();
|
||||
|
||||
// Set "Basic page" content type to be unpublished by default.
|
||||
$fields = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
|
||||
$fields['status']->getConfig('page')
|
||||
->setDefaultValue(FALSE)
|
||||
->save();
|
||||
|
||||
// Create a node.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit['body[0][value]'] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
|
||||
// Check that the user was redirected to the home page.
|
||||
$this->assertUrl('');
|
||||
$this->assertText(t('Test page text'));
|
||||
|
||||
// Confirm that the node was created.
|
||||
$this->assertText(t('@post @title has been created.', ['@post' => 'Basic page', '@title' => $edit['title[0][value]']]));
|
||||
|
||||
// Verify that the creation message contains a link to a node.
|
||||
$view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']);
|
||||
$this->assert(isset($view_link), 'The message area contains a link to a node');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the author autocompletion textfield.
|
||||
*/
|
||||
public function testAuthorAutocomplete() {
|
||||
$admin_user = $this->drupalCreateUser(['administer nodes', 'create page content']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalGet('node/add/page');
|
||||
|
||||
$result = $this->xpath('//input[@id="edit-uid-0-value" and contains(@data-autocomplete-path, "user/autocomplete")]');
|
||||
$this->assertEqual(count($result), 0, 'No autocompletion without access user profiles.');
|
||||
|
||||
$admin_user = $this->drupalCreateUser(['administer nodes', 'create page content', 'access user profiles']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalGet('node/add/page');
|
||||
|
||||
$result = $this->xpath('//input[@id="edit-uid-0-target-id" and contains(@data-autocomplete-path, "/entity_reference_autocomplete/user/default")]');
|
||||
$this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check node/add when no node types exist.
|
||||
*/
|
||||
public function testNodeAddWithoutContentTypes() {
|
||||
$this->drupalGet('node/add');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoLinkByHref('/admin/structure/types/add');
|
||||
|
||||
// Test /node/add page without content types.
|
||||
foreach (\Drupal::entityManager()->getStorage('node_type')->loadMultiple() as $entity ) {
|
||||
$entity->delete();
|
||||
}
|
||||
|
||||
$this->drupalGet('node/add');
|
||||
$this->assertResponse(403);
|
||||
|
||||
$admin_content_types = $this->drupalCreateUser(['administer content types']);
|
||||
$this->drupalLogin($admin_content_types);
|
||||
|
||||
$this->drupalGet('node/add');
|
||||
|
||||
$this->assertLinkByHref('/admin/structure/types/add');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the watchdog IDs of the records with the rollback exception message.
|
||||
*
|
||||
* @return int[]
|
||||
* Array containing the IDs of the log records with the rollback exception
|
||||
* message.
|
||||
*/
|
||||
protected static function getWatchdogIdsForTestExceptionRollback() {
|
||||
// PostgreSQL doesn't support bytea LIKE queries, so we need to unserialize
|
||||
// first to check for the rollback exception message.
|
||||
$matches = [];
|
||||
$query = db_query("SELECT wid, variables FROM {watchdog}");
|
||||
foreach ($query as $row) {
|
||||
$variables = (array) unserialize($row->variables);
|
||||
if (isset($variables['@message']) && $variables['@message'] === 'Test exception for rollback.') {
|
||||
$matches[] = $row->wid;
|
||||
}
|
||||
}
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log records with the explicit rollback failed exception message.
|
||||
*
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* A prepared statement object (already executed), which contains the log
|
||||
* records with the explicit rollback failed exception message.
|
||||
*/
|
||||
protected static function getWatchdogIdsForFailedExplicitRollback() {
|
||||
return db_query("SELECT wid FROM {watchdog} WHERE message LIKE 'Explicit rollback failed%'")->fetchAll();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests updating the changed time after API and FORM entity save.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeFormSaveChangedTimeTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = [
|
||||
'node',
|
||||
];
|
||||
|
||||
/**
|
||||
* An user with permissions to create and edit articles.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $authorUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a node type.
|
||||
$this->drupalCreateContentType([
|
||||
'type' => 'article',
|
||||
'name' => 'Article',
|
||||
]);
|
||||
|
||||
$this->authorUser = $this->drupalCreateUser(['access content', 'create article content', 'edit any article content'], 'author');
|
||||
$this->drupalLogin($this->authorUser);
|
||||
|
||||
// Create one node of the above node type .
|
||||
$this->drupalCreateNode([
|
||||
'type' => 'article',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the changed time after API and FORM save without changes.
|
||||
*/
|
||||
public function testChangedTimeAfterSaveWithoutChanges() {
|
||||
$storage = $this->container->get('entity_type.manager')->getStorage('node');
|
||||
$storage->resetCache([1]);
|
||||
$node = $storage->load(1);
|
||||
$changed_timestamp = $node->getChangedTime();
|
||||
$node->save();
|
||||
$storage->resetCache([1]);
|
||||
$node = $storage->load(1);
|
||||
$this->assertEqual($changed_timestamp, $node->getChangedTime(), "The entity's changed time wasn't updated after API save without changes.");
|
||||
|
||||
// Ensure different save timestamps.
|
||||
sleep(1);
|
||||
|
||||
// Save the node on the regular node edit form.
|
||||
$this->drupalPostForm('node/1/edit', [], t('Save'));
|
||||
|
||||
$storage->resetCache([1]);
|
||||
$node = $storage->load(1);
|
||||
$this->assertNotEqual($changed_timestamp, $node->getChangedTime(), "The entity's changed time was updated after form save without changes.");
|
||||
}
|
||||
|
||||
}
|
77
web/core/modules/node/tests/src/Functional/NodeHelpTest.php
Normal file
77
web/core/modules/node/tests/src/Functional/NodeHelpTest.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests help functionality for nodes.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeHelpTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array.
|
||||
*/
|
||||
public static $modules = ['block', 'node', 'help'];
|
||||
|
||||
/**
|
||||
* The name of the test node type to create.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $testType;
|
||||
|
||||
/**
|
||||
* The test 'node help' text to be checked.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $testText;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create user.
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer content types',
|
||||
'administer nodes',
|
||||
'bypass node access',
|
||||
]);
|
||||
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalPlaceBlock('help_block');
|
||||
|
||||
$this->testType = 'type';
|
||||
$this->testText = t('Help text to find on node forms.');
|
||||
|
||||
// Create content type.
|
||||
$this->drupalCreateContentType([
|
||||
'type' => $this->testType,
|
||||
'help' => $this->testText,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that help text appears on node add/edit forms.
|
||||
*/
|
||||
public function testNodeShowHelpText() {
|
||||
// Check the node add form.
|
||||
$this->drupalGet('node/add/' . $this->testType);
|
||||
$this->assertResponse(200);
|
||||
$this->assertText($this->testText);
|
||||
|
||||
// Create node and check the node edit form.
|
||||
$node = $this->drupalCreateNode(['type' => $this->testType]);
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertResponse(200);
|
||||
$this->assertText($this->testText);
|
||||
}
|
||||
|
||||
}
|
45
web/core/modules/node/tests/src/Functional/NodeLinksTest.php
Normal file
45
web/core/modules/node/tests/src/Functional/NodeLinksTest.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Tests the output of node links (read more, add new comment, etc).
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeLinksTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views'];
|
||||
|
||||
/**
|
||||
* Tests that the links can be hidden in the view display settings.
|
||||
*/
|
||||
public function testHideLinks() {
|
||||
$node = $this->drupalCreateNode([
|
||||
'type' => 'article',
|
||||
'promote' => NodeInterface::PROMOTED,
|
||||
]);
|
||||
|
||||
// Links are displayed by default.
|
||||
$this->drupalGet('node');
|
||||
$this->assertText($node->getTitle());
|
||||
$this->assertLink('Read more');
|
||||
|
||||
// Hide links.
|
||||
entity_get_display('node', 'article', 'teaser')
|
||||
->removeComponent('links')
|
||||
->save();
|
||||
|
||||
$this->drupalGet('node');
|
||||
$this->assertText($node->getTitle());
|
||||
$this->assertNoLink('Read more');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Tests the loading of multiple nodes.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeLoadMultipleTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Enable Views to test the frontpage against Node::loadMultiple() results.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$web_user = $this->drupalCreateUser(['create article content', 'create page content']);
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates four nodes and ensures that they are loaded correctly.
|
||||
*/
|
||||
public function testNodeMultipleLoad() {
|
||||
$node1 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]);
|
||||
$node2 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]);
|
||||
$node3 = $this->drupalCreateNode(['type' => 'article', 'promote' => 0]);
|
||||
$node4 = $this->drupalCreateNode(['type' => 'page', 'promote' => 0]);
|
||||
|
||||
// Confirm that promoted nodes appear in the default node listing.
|
||||
$this->drupalGet('node');
|
||||
$this->assertText($node1->label(), 'Node title appears on the default listing.');
|
||||
$this->assertText($node2->label(), 'Node title appears on the default listing.');
|
||||
$this->assertNoText($node3->label(), 'Node title does not appear in the default listing.');
|
||||
$this->assertNoText($node4->label(), 'Node title does not appear in the default listing.');
|
||||
// Load nodes with only a condition. Nodes 3 and 4 will be loaded.
|
||||
$nodes = $this->container->get('entity_type.manager')->getStorage('node')
|
||||
->loadByProperties(['promote' => 0]);
|
||||
$this->assertEqual($node3->label(), $nodes[$node3->id()]->label(), 'Node was loaded.');
|
||||
$this->assertEqual($node4->label(), $nodes[$node4->id()]->label(), 'Node was loaded.');
|
||||
$count = count($nodes);
|
||||
$this->assertTrue($count == 2, format_string('@count nodes loaded.', ['@count' => $count]));
|
||||
|
||||
// Load nodes by nid. Nodes 1, 2 and 4 will be loaded.
|
||||
$nodes = Node::loadMultiple([1, 2, 4]);
|
||||
$count = count($nodes);
|
||||
$this->assertTrue(count($nodes) == 3, format_string('@count nodes loaded', ['@count' => $count]));
|
||||
$this->assertTrue(isset($nodes[$node1->id()]), 'Node is correctly keyed in the array');
|
||||
$this->assertTrue(isset($nodes[$node2->id()]), 'Node is correctly keyed in the array');
|
||||
$this->assertTrue(isset($nodes[$node4->id()]), 'Node is correctly keyed in the array');
|
||||
foreach ($nodes as $node) {
|
||||
$this->assertTrue(is_object($node), 'Node is an object');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
/**
|
||||
* Tests that the post information (submitted by Username on date) text displays
|
||||
* appropriately.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodePostSettingsTest extends NodeTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser(['create page content', 'administer content types', 'access user profiles']);
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms "Basic page" content type and post information is on a new node.
|
||||
*/
|
||||
public function testPagePostInfo() {
|
||||
|
||||
// Set "Basic page" content type to display post information.
|
||||
$edit = [];
|
||||
$edit['display_submitted'] = TRUE;
|
||||
$this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
|
||||
|
||||
// Create a node.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit['body[0][value]'] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
|
||||
// Check that the post information is displayed.
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$elements = $this->xpath('//div[contains(@class, :class)]', [':class' => 'node__submitted']);
|
||||
$this->assertEqual(count($elements), 1, 'Post information is displayed.');
|
||||
$node->delete();
|
||||
|
||||
// Set "Basic page" content type to display post information.
|
||||
$edit = [];
|
||||
$edit['display_submitted'] = FALSE;
|
||||
$this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
|
||||
|
||||
// Create a node.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit['body[0][value]'] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
|
||||
// Check that the post information is displayed.
|
||||
$elements = $this->xpath('//div[contains(@class, :class)]', [':class' => 'node__submitted']);
|
||||
$this->assertEqual(count($elements), 0, 'Post information is not displayed.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
|
||||
/**
|
||||
* Ensures that data added to nodes by other modules appears in RSS feeds.
|
||||
*
|
||||
* Create a node, enable the node_test module to ensure that extra data is
|
||||
* added to the node's renderable array, then verify that the data appears on
|
||||
* the site-wide RSS feed at rss.xml.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeRSSContentTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Enable a module that implements hook_node_view().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_test', 'views'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Use bypass node access permission here, because the test class uses
|
||||
// hook_grants_alter() to deny access to everyone on node_access
|
||||
// queries.
|
||||
$user = $this->drupalCreateUser(['bypass node access', 'access content', 'create article content']);
|
||||
$this->drupalLogin($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a new node includes the custom data when added to an RSS feed.
|
||||
*/
|
||||
public function testNodeRSSContent() {
|
||||
// Create a node.
|
||||
$node = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]);
|
||||
|
||||
$this->drupalGet('rss.xml');
|
||||
|
||||
// Check that content added in 'rss' view mode appear in RSS feed.
|
||||
$rss_only_content = t('Extra data that should appear only in the RSS feed for node @nid.', ['@nid' => $node->id()]);
|
||||
$this->assertText($rss_only_content, 'Node content designated for RSS appear in RSS feed.');
|
||||
|
||||
// Check that content added in view modes other than 'rss' doesn't
|
||||
// appear in RSS feed.
|
||||
$non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node @nid.', ['@nid' => $node->id()]);
|
||||
$this->assertNoText($non_rss_content, 'Node content not designed for RSS does not appear in RSS feed.');
|
||||
|
||||
// Check that extra RSS elements and namespaces are added to RSS feed.
|
||||
$test_element = '<testElement>' . t('Value of testElement RSS element for node @nid.', ['@nid' => $node->id()]) . '</testElement>';
|
||||
$test_ns = 'xmlns:drupaltest="http://example.com/test-namespace"';
|
||||
$this->assertRaw($test_element, 'Extra RSS elements appear in RSS feed.');
|
||||
$this->assertRaw($test_ns, 'Extra namespaces appear in RSS feed.');
|
||||
|
||||
// Check that content added in 'rss' view mode doesn't appear when
|
||||
// viewing node.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$this->assertNoText($rss_only_content, 'Node content designed for RSS does not appear when viewing node.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests relative, root-relative, protocol-relative and absolute URLs.
|
||||
*/
|
||||
public function testUrlHandling() {
|
||||
// Only the plain_text text format is available by default, which escapes
|
||||
// all HTML.
|
||||
FilterFormat::create([
|
||||
'format' => 'full_html',
|
||||
'name' => 'Full HTML',
|
||||
'filters' => [],
|
||||
])->save();
|
||||
|
||||
$defaults = [
|
||||
'type' => 'article',
|
||||
'promote' => 1,
|
||||
];
|
||||
$this->drupalCreateNode($defaults + [
|
||||
'body' => [
|
||||
'value' => '<p><a href="' . file_url_transform_relative(file_create_url('public://root-relative')) . '">Root-relative URL</a></p>',
|
||||
'format' => 'full_html',
|
||||
],
|
||||
]);
|
||||
$protocol_relative_url = substr(file_create_url('public://protocol-relative'), strlen(\Drupal::request()->getScheme() . ':'));
|
||||
$this->drupalCreateNode($defaults + [
|
||||
'body' => [
|
||||
'value' => '<p><a href="' . $protocol_relative_url . '">Protocol-relative URL</a></p>',
|
||||
'format' => 'full_html',
|
||||
],
|
||||
]);
|
||||
$absolute_url = file_create_url('public://absolute');
|
||||
$this->drupalCreateNode($defaults + [
|
||||
'body' => [
|
||||
'value' => '<p><a href="' . $absolute_url . '">Absolute URL</a></p>',
|
||||
'format' => 'full_html',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->drupalGet('rss.xml');
|
||||
$this->assertRaw(file_create_url('public://root-relative'), 'Root-relative URL is transformed to absolute.');
|
||||
$this->assertRaw($protocol_relative_url, 'Protocol-relative URL is left untouched.');
|
||||
$this->assertRaw($absolute_url, 'Absolute URL is left untouched.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Create a node with revisions and test viewing, saving, reverting, and
|
||||
* deleting revisions for user with access to all.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeRevisionsAllTest extends NodeTestBase {
|
||||
protected $nodes;
|
||||
protected $revisionLogs;
|
||||
protected $profile = "standard";
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create and log in user.
|
||||
$web_user = $this->drupalCreateUser(
|
||||
[
|
||||
'view page revisions',
|
||||
'revert page revisions',
|
||||
'delete page revisions',
|
||||
'edit any page content',
|
||||
'delete any page content'
|
||||
]
|
||||
);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create an initial node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
$settings = get_object_vars($node);
|
||||
$settings['revision'] = 1;
|
||||
|
||||
$nodes = [];
|
||||
$logs = [];
|
||||
|
||||
// Get the original node.
|
||||
$nodes[] = clone $node;
|
||||
|
||||
// Create three revisions.
|
||||
$revision_count = 3;
|
||||
for ($i = 0; $i < $revision_count; $i++) {
|
||||
$logs[] = $node->revision_log = $this->randomMachineName(32);
|
||||
|
||||
$node = $this->createNodeRevision($node);
|
||||
$nodes[] = clone $node;
|
||||
}
|
||||
|
||||
$this->nodes = $nodes;
|
||||
$this->revisionLogs = $logs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new revision for a given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* A node object.
|
||||
*
|
||||
* @return \Drupal\node\NodeInterface
|
||||
* A node object with up to date revision information.
|
||||
*/
|
||||
protected function createNodeRevision(NodeInterface $node) {
|
||||
// Create revision with a random title and body and update variables.
|
||||
$node->title = $this->randomMachineName();
|
||||
$node->body = [
|
||||
'value' => $this->randomMachineName(32),
|
||||
'format' => filter_default_format(),
|
||||
];
|
||||
$node->setNewRevision();
|
||||
$node->save();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks node revision operations.
|
||||
*/
|
||||
public function testRevisions() {
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
$nodes = $this->nodes;
|
||||
$logs = $this->revisionLogs;
|
||||
|
||||
// Get last node for simple checks.
|
||||
$node = $nodes[3];
|
||||
|
||||
// Create and log in user.
|
||||
$content_admin = $this->drupalCreateUser(
|
||||
[
|
||||
'view all revisions',
|
||||
'revert all revisions',
|
||||
'delete all revisions',
|
||||
'edit any page content',
|
||||
'delete any page content'
|
||||
]
|
||||
);
|
||||
$this->drupalLogin($content_admin);
|
||||
|
||||
// Confirm the correct revision text appears on "view revisions" page.
|
||||
$this->drupalGet("node/" . $node->id() . "/revisions/" . $node->getRevisionId() . "/view");
|
||||
$this->assertText($node->body->value, 'Correct text displays for version.');
|
||||
|
||||
// Confirm the correct revision log message appears on the "revisions
|
||||
// overview" page.
|
||||
$this->drupalGet("node/" . $node->id() . "/revisions");
|
||||
foreach ($logs as $revision_log) {
|
||||
$this->assertText($revision_log, 'Revision log message found.');
|
||||
}
|
||||
|
||||
// Confirm that this is the current revision.
|
||||
$this->assertTrue($node->isDefaultRevision(), 'Third node revision is the current one.');
|
||||
|
||||
// Confirm that revisions revert properly.
|
||||
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/revert", [], t('Revert'));
|
||||
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.',
|
||||
[
|
||||
'@type' => 'Basic page',
|
||||
'%title' => $nodes[1]->getTitle(),
|
||||
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime())
|
||||
]),
|
||||
'Revision reverted.');
|
||||
$node_storage->resetCache([$node->id()]);
|
||||
$reverted_node = $node_storage->load($node->id());
|
||||
$this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.');
|
||||
|
||||
// Confirm that this is not the current version.
|
||||
$node = node_revision_load($node->getRevisionId());
|
||||
$this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the current one.');
|
||||
|
||||
// Confirm revisions delete properly.
|
||||
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", [], t('Delete'));
|
||||
$this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
|
||||
[
|
||||
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
|
||||
'@type' => 'Basic page',
|
||||
'%title' => $nodes[1]->getTitle(),
|
||||
]),
|
||||
'Revision deleted.');
|
||||
$this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid',
|
||||
[':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0,
|
||||
'Revision not found.');
|
||||
|
||||
// Set the revision timestamp to an older date to make sure that the
|
||||
// confirmation message correctly displays the stored revision date.
|
||||
$old_revision_date = REQUEST_TIME - 86400;
|
||||
db_update('node_revision')
|
||||
->condition('vid', $nodes[2]->getRevisionId())
|
||||
->fields([
|
||||
'revision_timestamp' => $old_revision_date,
|
||||
])
|
||||
->execute();
|
||||
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", [], t('Revert'));
|
||||
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [
|
||||
'@type' => 'Basic page',
|
||||
'%title' => $nodes[2]->getTitle(),
|
||||
'%revision-date' => format_date($old_revision_date),
|
||||
]));
|
||||
|
||||
// Create 50 more revisions in order to trigger paging on the revisions
|
||||
// overview screen.
|
||||
$node = $nodes[0];
|
||||
for ($i = 0; $i < 50; $i++) {
|
||||
$logs[] = $node->revision_log = $this->randomMachineName(32);
|
||||
|
||||
$node = $this->createNodeRevision($node);
|
||||
$nodes[] = clone $node;
|
||||
}
|
||||
|
||||
$this->drupalGet('node/' . $node->id() . '/revisions');
|
||||
|
||||
// Check that the pager exists.
|
||||
$this->assertRaw('page=1');
|
||||
|
||||
// Check that the last revision is displayed on the first page.
|
||||
$this->assertText(end($logs));
|
||||
|
||||
// Go to the second page and check that one of the initial three revisions
|
||||
// is displayed.
|
||||
$this->clickLink(t('Page 2'));
|
||||
$this->assertText($logs[2]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Tests the revision tab display.
|
||||
*
|
||||
* This test is similar to NodeRevisionsUITest except that it uses a user with
|
||||
* the bypass node access permission to make sure that the revision access
|
||||
* check adds correct cacheability metadata.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeRevisionsUiBypassAccessTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* User with bypass node access permission.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $editor;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a user.
|
||||
$this->editor = $this->drupalCreateUser([
|
||||
'administer nodes',
|
||||
'edit any page content',
|
||||
'view page revisions',
|
||||
'bypass node access',
|
||||
'access user profiles',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the Revision tab is displayed correctly.
|
||||
*/
|
||||
public function testDisplayRevisionTab() {
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
|
||||
$this->drupalLogin($this->editor);
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
|
||||
// Set page revision setting 'create new revision'. This will mean new
|
||||
// revisions are created by default when the node is edited.
|
||||
$type = NodeType::load('page');
|
||||
$type->setNewRevision(TRUE);
|
||||
$type->save();
|
||||
|
||||
// Create the node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
// Verify the checkbox is checked on the node edit form.
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked");
|
||||
|
||||
// Uncheck the create new revision checkbox and save the node.
|
||||
$edit = ['revision' => FALSE];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
|
||||
|
||||
$this->assertUrl($node->toUrl());
|
||||
$this->assertNoLink(t('Revisions'));
|
||||
|
||||
// Verify the checkbox is checked on the node edit form.
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked");
|
||||
|
||||
// Submit the form without changing the checkbox.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
|
||||
|
||||
$this->assertUrl($node->toUrl());
|
||||
$this->assertLink(t('Revisions'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Tests the UI for controlling node revision behavior.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeRevisionsUiTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $editor;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create users.
|
||||
$this->editor = $this->drupalCreateUser([
|
||||
'administer nodes',
|
||||
'edit any page content',
|
||||
'view page revisions',
|
||||
'access user profiles',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that unchecking 'Create new revision' works when editing a node.
|
||||
*/
|
||||
public function testNodeFormSaveWithoutRevision() {
|
||||
$this->drupalLogin($this->editor);
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
|
||||
// Set page revision setting 'create new revision'. This will mean new
|
||||
// revisions are created by default when the node is edited.
|
||||
$type = NodeType::load('page');
|
||||
$type->setNewRevision(TRUE);
|
||||
$type->save();
|
||||
|
||||
// Create the node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
// Verify the checkbox is checked on the node edit form.
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked");
|
||||
|
||||
// Uncheck the create new revision checkbox and save the node.
|
||||
$edit = ['revision' => FALSE];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
|
||||
// Load the node again and check the revision is the same as before.
|
||||
$node_storage->resetCache([$node->id()]);
|
||||
$node_revision = $node_storage->load($node->id(), TRUE);
|
||||
$this->assertEqual($node_revision->getRevisionId(), $node->getRevisionId(), "After an existing node is saved with 'Create new revision' unchecked, a new revision is not created.");
|
||||
|
||||
// Verify the checkbox is checked on the node edit form.
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked");
|
||||
|
||||
// Submit the form without changing the checkbox.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
|
||||
// Load the node again and check the revision is different from before.
|
||||
$node_storage->resetCache([$node->id()]);
|
||||
$node_revision = $node_storage->load($node->id());
|
||||
$this->assertNotEqual($node_revision->getRevisionId(), $node->getRevisionId(), "After an existing node is saved with 'Create new revision' checked, a new revision is created.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks HTML double escaping of revision logs.
|
||||
*/
|
||||
public function testNodeRevisionDoubleEscapeFix() {
|
||||
$this->drupalLogin($this->editor);
|
||||
$nodes = [];
|
||||
|
||||
// Create the node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
$username = [
|
||||
'#theme' => 'username',
|
||||
'#account' => $this->editor,
|
||||
];
|
||||
$editor = \Drupal::service('renderer')->renderPlain($username);
|
||||
|
||||
// Get original node.
|
||||
$nodes[] = clone $node;
|
||||
|
||||
// Create revision with a random title and body and update variables.
|
||||
$node->title = $this->randomMachineName();
|
||||
$node->body = [
|
||||
'value' => $this->randomMachineName(32),
|
||||
'format' => filter_default_format(),
|
||||
];
|
||||
$node->setNewRevision();
|
||||
$revision_log = 'Revision <em>message</em> with markup.';
|
||||
$node->revision_log->value = $revision_log;
|
||||
$node->save();
|
||||
// Make sure we get revision information.
|
||||
$node = Node::load($node->id());
|
||||
$nodes[] = clone $node;
|
||||
|
||||
$this->drupalGet('node/' . $node->id() . '/revisions');
|
||||
|
||||
// Assert the old revision message.
|
||||
$date = format_date($nodes[0]->revision_timestamp->value, 'short');
|
||||
$url = new Url('entity.node.revision', ['node' => $nodes[0]->id(), 'node_revision' => $nodes[0]->getRevisionId()]);
|
||||
$this->assertRaw(\Drupal::l($date, $url) . ' by ' . $editor);
|
||||
|
||||
// Assert the current revision message.
|
||||
$date = format_date($nodes[1]->revision_timestamp->value, 'short');
|
||||
$this->assertRaw($nodes[1]->link($date) . ' by ' . $editor . '<p class="revision-log">' . $revision_log . '</p>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the Revisions tab.
|
||||
*/
|
||||
public function testNodeRevisionsTabWithDefaultRevision() {
|
||||
$this->drupalLogin($this->editor);
|
||||
|
||||
// Create the node.
|
||||
$node = $this->drupalCreateNode();
|
||||
$storage = \Drupal::entityTypeManager()->getStorage($node->getEntityTypeId());
|
||||
|
||||
// Create a new revision based on the default revision.
|
||||
// Revision 2.
|
||||
$node = $storage->load($node->id());
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->save();
|
||||
|
||||
// Revision 3.
|
||||
$node = $storage->load($node->id());
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->save();
|
||||
|
||||
// Revision 4.
|
||||
// Trigger translation changes in order to show the revision.
|
||||
$node = $storage->load($node->id());
|
||||
$node->setTitle($this->randomString());
|
||||
$node->isDefaultRevision(FALSE);
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->save();
|
||||
|
||||
// Revision 5.
|
||||
$node = $storage->load($node->id());
|
||||
$node->isDefaultRevision(FALSE);
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->save();
|
||||
|
||||
$node_id = $node->id();
|
||||
|
||||
$this->drupalGet('node/' . $node_id . '/revisions');
|
||||
|
||||
// Verify that the default revision can be an older revision than the latest
|
||||
// one.
|
||||
// Assert that the revisions with translations changes are shown: 1 and 4.
|
||||
$this->assertLinkByHref('/node/' . $node_id . '/revisions/1/revert');
|
||||
$this->assertLinkByHref('/node/' . $node_id . '/revisions/4/revert');
|
||||
|
||||
// Assert that the revisions without translations changes are filtered out:
|
||||
// 2, 3 and 5.
|
||||
$this->assertNoLinkByHref('/node/' . $node_id . '/revisions/2/revert');
|
||||
$this->assertNoLinkByHref('/node/' . $node_id . '/revisions/3/revert');
|
||||
$this->assertNoLinkByHref('/node/' . $node_id . '/revisions/5/revert');
|
||||
}
|
||||
|
||||
}
|
182
web/core/modules/node/tests/src/Functional/NodeSaveTest.php
Normal file
182
web/core/modules/node/tests/src/Functional/NodeSaveTest.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Tests $node->save() for saving content.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeSaveTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* A normal logged in user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a user that is allowed to post; we'll use this to test the submission.
|
||||
$web_user = $this->drupalCreateUser(['create article content']);
|
||||
$this->drupalLogin($web_user);
|
||||
$this->webUser = $web_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether custom node IDs are saved properly during an import operation.
|
||||
*
|
||||
* Workflow:
|
||||
* - first create a piece of content
|
||||
* - save the content
|
||||
* - check if node exists
|
||||
*/
|
||||
public function testImport() {
|
||||
// Node ID must be a number that is not in the database.
|
||||
$nids = \Drupal::entityManager()->getStorage('node')->getQuery()
|
||||
->sort('nid', 'DESC')
|
||||
->range(0, 1)
|
||||
->execute();
|
||||
$max_nid = reset($nids);
|
||||
$test_nid = $max_nid + mt_rand(1000, 1000000);
|
||||
$title = $this->randomMachineName(8);
|
||||
$node = [
|
||||
'title' => $title,
|
||||
'body' => [['value' => $this->randomMachineName(32)]],
|
||||
'uid' => $this->webUser->id(),
|
||||
'type' => 'article',
|
||||
'nid' => $test_nid,
|
||||
];
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = Node::create($node);
|
||||
$node->enforceIsNew();
|
||||
|
||||
$this->assertEqual($node->getOwnerId(), $this->webUser->id());
|
||||
|
||||
$node->save();
|
||||
// Test the import.
|
||||
$node_by_nid = Node::load($test_nid);
|
||||
$this->assertTrue($node_by_nid, 'Node load by node ID.');
|
||||
|
||||
$node_by_title = $this->drupalGetNodeByTitle($title);
|
||||
$this->assertTrue($node_by_title, 'Node load by node title.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies accuracy of the "created" and "changed" timestamp functionality.
|
||||
*/
|
||||
public function testTimestamps() {
|
||||
// Use the default timestamps.
|
||||
$edit = [
|
||||
'uid' => $this->webUser->id(),
|
||||
'type' => 'article',
|
||||
'title' => $this->randomMachineName(8),
|
||||
];
|
||||
|
||||
Node::create($edit)->save();
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
$this->assertEqual($node->getCreatedTime(), REQUEST_TIME, 'Creating a node sets default "created" timestamp.');
|
||||
$this->assertEqual($node->getChangedTime(), REQUEST_TIME, 'Creating a node sets default "changed" timestamp.');
|
||||
|
||||
// Store the timestamps.
|
||||
$created = $node->getCreatedTime();
|
||||
|
||||
$node->save();
|
||||
$node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
|
||||
$this->assertEqual($node->getCreatedTime(), $created, 'Updating a node preserves "created" timestamp.');
|
||||
|
||||
// Programmatically set the timestamps using hook_ENTITY_TYPE_presave().
|
||||
$node->title = 'testing_node_presave';
|
||||
|
||||
$node->save();
|
||||
$node = $this->drupalGetNodeByTitle('testing_node_presave', TRUE);
|
||||
$this->assertEqual($node->getCreatedTime(), 280299600, 'Saving a node uses "created" timestamp set in presave hook.');
|
||||
$this->assertEqual($node->getChangedTime(), 979534800, 'Saving a node uses "changed" timestamp set in presave hook.');
|
||||
|
||||
// Programmatically set the timestamps on the node.
|
||||
$edit = [
|
||||
'uid' => $this->webUser->id(),
|
||||
'type' => 'article',
|
||||
'title' => $this->randomMachineName(8),
|
||||
'created' => 280299600, // Sun, 19 Nov 1978 05:00:00 GMT
|
||||
'changed' => 979534800, // Drupal 1.0 release.
|
||||
];
|
||||
|
||||
Node::create($edit)->save();
|
||||
$node = $this->drupalGetNodeByTitle($edit['title']);
|
||||
$this->assertEqual($node->getCreatedTime(), 280299600, 'Creating a node programmatically uses programmatically set "created" timestamp.');
|
||||
$this->assertEqual($node->getChangedTime(), 979534800, 'Creating a node programmatically uses programmatically set "changed" timestamp.');
|
||||
|
||||
// Update the timestamps.
|
||||
$node->setCreatedTime(979534800);
|
||||
$node->changed = 280299600;
|
||||
|
||||
$node->save();
|
||||
$node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
|
||||
$this->assertEqual($node->getCreatedTime(), 979534800, 'Updating a node uses user-set "created" timestamp.');
|
||||
// Allowing setting changed timestamps is required, see
|
||||
// Drupal\content_translation\ContentTranslationMetadataWrapper::setChangedTime($timestamp)
|
||||
// for example.
|
||||
$this->assertEqual($node->getChangedTime(), 280299600, 'Updating a node uses user-set "changed" timestamp.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node presave and static node load cache.
|
||||
*
|
||||
* This test determines changes in hook_ENTITY_TYPE_presave() and verifies
|
||||
* that the static node load cache is cleared upon save.
|
||||
*/
|
||||
public function testDeterminingChanges() {
|
||||
// Initial creation.
|
||||
$node = Node::create([
|
||||
'uid' => $this->webUser->id(),
|
||||
'type' => 'article',
|
||||
'title' => 'test_changes',
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
// Update the node without applying changes.
|
||||
$node->save();
|
||||
$this->assertEqual($node->label(), 'test_changes', 'No changes have been determined.');
|
||||
|
||||
// Apply changes.
|
||||
$node->title = 'updated';
|
||||
$node->save();
|
||||
|
||||
// The hook implementations node_test_node_presave() and
|
||||
// node_test_node_update() determine changes and change the title.
|
||||
$this->assertEqual($node->label(), 'updated_presave_update', 'Changes have been determined.');
|
||||
|
||||
// Test the static node load cache to be cleared.
|
||||
$node = Node::load($node->id());
|
||||
$this->assertEqual($node->label(), 'updated_presave', 'Static cache has been cleared.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests saving a node on node insert.
|
||||
*
|
||||
* This test ensures that a node has been fully saved when
|
||||
* hook_ENTITY_TYPE_insert() is invoked, so that the node can be saved again
|
||||
* in a hook implementation without errors.
|
||||
*
|
||||
* @see node_test_node_insert()
|
||||
*/
|
||||
public function testNodeSaveOnInsert() {
|
||||
// node_test_node_insert() triggers a save on insert if the title equals
|
||||
// 'new'.
|
||||
$node = $this->drupalCreateNode(['title' => 'new']);
|
||||
$this->assertEqual($node->getTitle(), 'Node ' . $node->id(), 'Node saved on node insert.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
/**
|
||||
* Tests node template suggestions.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeTemplateSuggestionsTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Tests if template_preprocess_node() generates the correct suggestions.
|
||||
*/
|
||||
public function testNodeThemeHookSuggestions() {
|
||||
// Create node to be rendered.
|
||||
$node = $this->drupalCreateNode();
|
||||
$view_mode = 'full';
|
||||
|
||||
// Simulate theming of the node.
|
||||
$build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode);
|
||||
|
||||
$variables['elements'] = $build;
|
||||
$suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', [$variables]);
|
||||
|
||||
$this->assertEqual($suggestions, ['node__full', 'node__page', 'node__page__full', 'node__' . $node->id(), 'node__' . $node->id() . '__full'], 'Found expected node suggestions.');
|
||||
|
||||
// Change the view mode.
|
||||
$view_mode = 'node.my_custom_view_mode';
|
||||
$build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode);
|
||||
|
||||
$variables['elements'] = $build;
|
||||
$suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', [$variables]);
|
||||
|
||||
$this->assertEqual($suggestions, ['node__node_my_custom_view_mode', 'node__page', 'node__page__node_my_custom_view_mode', 'node__' . $node->id(), 'node__' . $node->id() . '__node_my_custom_view_mode'], 'Found expected node suggestions.');
|
||||
}
|
||||
|
||||
}
|
110
web/core/modules/node/tests/src/Functional/NodeTestBase.php
Normal file
110
web/core/modules/node/tests/src/Functional/NodeTestBase.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Sets up page and article content types.
|
||||
*/
|
||||
abstract class NodeTestBase extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'datetime'];
|
||||
|
||||
/**
|
||||
* The node access control handler.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface
|
||||
*/
|
||||
protected $accessHandler;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create Basic page and Article node types.
|
||||
if ($this->profile != 'standard') {
|
||||
$this->drupalCreateContentType([
|
||||
'type' => 'page',
|
||||
'name' => 'Basic page',
|
||||
'display_submitted' => FALSE,
|
||||
]);
|
||||
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
||||
}
|
||||
$this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('node');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that node access correctly grants or denies access.
|
||||
*
|
||||
* @param array $ops
|
||||
* An associative array of the expected node access grants for the node
|
||||
* and account, with each key as the name of an operation (e.g. 'view',
|
||||
* 'delete') and each value a Boolean indicating whether access to that
|
||||
* operation should be granted.
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node object to check.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user account for which to check access.
|
||||
*/
|
||||
public function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) {
|
||||
foreach ($ops as $op => $result) {
|
||||
$this->assertEqual($result, $this->accessHandler->access($node, $op, $account), $this->nodeAccessAssertMessage($op, $result, $node->language()->getId()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that node create access correctly grants or denies access.
|
||||
*
|
||||
* @param string $bundle
|
||||
* The node bundle to check access to.
|
||||
* @param bool $result
|
||||
* Whether access should be granted or not.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user account for which to check access.
|
||||
* @param string|null $langcode
|
||||
* (optional) The language code indicating which translation of the node
|
||||
* to check. If NULL, the untranslated (fallback) access is checked.
|
||||
*/
|
||||
public function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) {
|
||||
$this->assertEqual($result, $this->accessHandler->createAccess($bundle, $account, [
|
||||
'langcode' => $langcode,
|
||||
]), $this->nodeAccessAssertMessage('create', $result, $langcode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an assert message to display which node access was tested.
|
||||
*
|
||||
* @param string $operation
|
||||
* The operation to check access for.
|
||||
* @param bool $result
|
||||
* Whether access should be granted or not.
|
||||
* @param string|null $langcode
|
||||
* (optional) The language code indicating which translation of the node
|
||||
* to check. If NULL, the untranslated (fallback) access is checked.
|
||||
*
|
||||
* @return string
|
||||
* An assert message string which contains information in plain English
|
||||
* about the node access permission test that was performed.
|
||||
*/
|
||||
public function nodeAccessAssertMessage($operation, $result, $langcode = NULL) {
|
||||
return format_string(
|
||||
'Node access returns @result with operation %op, language code %langcode.',
|
||||
[
|
||||
'@result' => $result ? 'true' : 'false',
|
||||
'%op' => $operation,
|
||||
'%langcode' => !empty($langcode) ? $langcode : 'empty'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
||||
/**
|
||||
* Tests node type initial language settings.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeTypeInitialLanguageTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['language', 'field_ui'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser(['bypass node access', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'administer languages']);
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the node type initial language defaults, and modifies them.
|
||||
*
|
||||
* The default initial language must be the site's default, and the language
|
||||
* locked option must be on.
|
||||
*/
|
||||
public function testNodeTypeInitialLanguageDefaults() {
|
||||
$this->drupalGet('admin/structure/types/manage/article');
|
||||
$this->assertOptionSelected('edit-language-configuration-langcode', LanguageInterface::LANGCODE_SITE_DEFAULT, 'The default initial language is the site default.');
|
||||
$this->assertNoFieldChecked('edit-language-configuration-language-alterable', 'Language selector is hidden by default.');
|
||||
|
||||
// Tests if the language field cannot be rearranged on the manage fields tab.
|
||||
$this->drupalGet('admin/structure/types/manage/article/fields');
|
||||
$language_field = $this->xpath('//*[@id="field-overview"]/*[@id="language"]');
|
||||
$this->assert(empty($language_field), 'Language field is not visible on manage fields tab.');
|
||||
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertNoField('langcode', 'Language is not selectable on node add/edit page by default.');
|
||||
|
||||
// Adds a new language and set it as default.
|
||||
$edit = [
|
||||
'predefined_langcode' => 'hu',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$edit = [
|
||||
'site_default_language' => 'hu',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/regional/language', $edit, t('Save configuration'));
|
||||
|
||||
// Tests the initial language after changing the site default language.
|
||||
// First unhide the language selector.
|
||||
$edit = [
|
||||
'language_configuration[language_alterable]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertField('langcode[0][value]', 'Language is selectable on node add/edit page when language not hidden.');
|
||||
$this->assertOptionSelected('edit-langcode-0-value', 'hu', 'The initial language is the site default on the node add page after the site default language is changed.');
|
||||
|
||||
// Tests if the language field can be rearranged on the manage form display
|
||||
// tab.
|
||||
$this->drupalGet('admin/structure/types/manage/article/form-display');
|
||||
$language_field = $this->xpath('//*[@id="langcode"]');
|
||||
$this->assert(!empty($language_field), 'Language field is visible on manage form display tab.');
|
||||
|
||||
// Tests if the language field can be rearranged on the manage display tab.
|
||||
$this->drupalGet('admin/structure/types/manage/article/display');
|
||||
$language_display = $this->xpath('//*[@id="langcode"]');
|
||||
$this->assert(!empty($language_display), 'Language field is visible on manage display tab.');
|
||||
// Tests if the language field is hidden by default.
|
||||
$this->assertOptionSelected('edit-fields-langcode-region', 'hidden', 'Language is hidden by default on manage display tab.');
|
||||
|
||||
// Changes the initial language settings.
|
||||
$edit = [
|
||||
'language_configuration[langcode]' => 'en',
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertOptionSelected('edit-langcode-0-value', 'en', 'The initial language is the defined language.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests language field visibility features.
|
||||
*/
|
||||
public function testLanguageFieldVisibility() {
|
||||
// Creates a node to test Language field visibility feature.
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomMachineName(8),
|
||||
'body[0][value]' => $this->randomMachineName(16),
|
||||
];
|
||||
$this->drupalPostForm('node/add/article', $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->assertTrue($node, 'Node found in database.');
|
||||
|
||||
// Loads node page and check if Language field is hidden by default.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$language_field = $this->xpath('//div[@id=:id]/div', [
|
||||
':id' => 'field-language-display',
|
||||
]);
|
||||
$this->assertTrue(empty($language_field), 'Language field value is not shown by default on node page.');
|
||||
|
||||
// Configures Language field formatter and check if it is saved.
|
||||
$edit = [
|
||||
'fields[langcode][type]' => 'language',
|
||||
'fields[langcode][region]' => 'content',
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/article/display', $edit, t('Save'));
|
||||
$this->drupalGet('admin/structure/types/manage/article/display');
|
||||
$this->assertOptionSelected('edit-fields-langcode-type', 'language', 'Language field has been set to visible.');
|
||||
|
||||
// Loads node page and check if Language field is shown.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$language_field = $this->xpath('//div[@id=:id]/div', [
|
||||
':id' => 'field-language-display',
|
||||
]);
|
||||
$this->assertFalse(empty($language_field), 'Language field value is shown on node page.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Ensures that node types translation work correctly.
|
||||
*
|
||||
* Note that the child site is installed in French; therefore, when making
|
||||
* assertions on translated text it is important to provide a langcode. This
|
||||
* ensures the asserts pass regardless of the Drupal version.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeTypeTranslationTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = [
|
||||
'block',
|
||||
'config_translation',
|
||||
'field_ui',
|
||||
'node',
|
||||
];
|
||||
|
||||
/**
|
||||
* The default language code to use in this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaultLangcode = 'fr';
|
||||
|
||||
/**
|
||||
* Languages to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $additionalLangcodes = ['es'];
|
||||
|
||||
/**
|
||||
* Administrator user for tests.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$admin_permissions = [
|
||||
'administer content types',
|
||||
'administer node fields',
|
||||
'administer languages',
|
||||
'administer site configuration',
|
||||
'administer themes',
|
||||
'translate configuration',
|
||||
];
|
||||
|
||||
// Create and log in user.
|
||||
$this->adminUser = $this->drupalCreateUser($admin_permissions);
|
||||
|
||||
// Add languages.
|
||||
foreach ($this->additionalLangcodes as $langcode) {
|
||||
ConfigurableLanguage::createFromLangcode($langcode)->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Install Drupal in a language other than English for this test. This is not
|
||||
* needed to test the node type translation itself but acts as a regression
|
||||
* test.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2584603
|
||||
*/
|
||||
protected function installParameters() {
|
||||
$parameters = parent::installParameters();
|
||||
$parameters['parameters']['langcode'] = $this->defaultLangcode;
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the node type translation.
|
||||
*/
|
||||
public function testNodeTypeTranslation() {
|
||||
$type = Unicode::strtolower($this->randomMachineName(16));
|
||||
$name = $this->randomString();
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalCreateContentType(['type' => $type, 'name' => $name]);
|
||||
|
||||
// Translate the node type name.
|
||||
$langcode = $this->additionalLangcodes[0];
|
||||
$translated_name = $langcode . '-' . $name;
|
||||
$edit = [
|
||||
"translation[config_names][node.type.$type][name]" => $translated_name,
|
||||
];
|
||||
|
||||
// Edit the title label to avoid having an exception when we save the translation.
|
||||
$this->drupalPostForm("admin/structure/types/manage/$type/translate/$langcode/add", $edit, t('Save translation'));
|
||||
|
||||
// Check the name is translated without admin theme for editing.
|
||||
$this->drupalPostForm('admin/appearance', ['use_admin_theme' => '0'], t('Save configuration'));
|
||||
$this->drupalGet("$langcode/node/add/$type");
|
||||
// This is a Spanish page, so ensure the text asserted is translated in
|
||||
// Spanish and not French by adding the langcode option.
|
||||
$this->assertRaw(t('Create @name', ['@name' => $translated_name], ['langcode' => $langcode]));
|
||||
|
||||
// Check the name is translated with admin theme for editing.
|
||||
$this->drupalPostForm('admin/appearance', ['use_admin_theme' => '1'], t('Save configuration'));
|
||||
$this->drupalGet("$langcode/node/add/$type");
|
||||
// This is a Spanish page, so ensure the text asserted is translated in
|
||||
// Spanish and not French by adding the langcode option.
|
||||
$this->assertRaw(t('Create @name', ['@name' => $translated_name], ['langcode' => $langcode]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the node type title label translation.
|
||||
*/
|
||||
public function testNodeTypeTitleLabelTranslation() {
|
||||
$type = Unicode::strtolower($this->randomMachineName(16));
|
||||
$name = $this->randomString();
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalCreateContentType(['type' => $type, 'name' => $name]);
|
||||
$langcode = $this->additionalLangcodes[0];
|
||||
|
||||
// Edit the title label for it to be displayed on the translation form.
|
||||
$this->drupalPostForm("admin/structure/types/manage/$type", ['title_label' => 'Edited title'], t('Save content type'));
|
||||
|
||||
// Assert that the title label is displayed on the translation form with the right value.
|
||||
$this->drupalGet("admin/structure/types/manage/$type/translate/$langcode/add");
|
||||
$this->assertText('Edited title');
|
||||
|
||||
// Translate the title label.
|
||||
$this->drupalPostForm(NULL, ["translation[config_names][core.base_field_override.node.$type.title][label]" => 'Translated title'], t('Save translation'));
|
||||
|
||||
// Assert that the right title label is displayed on the node add form. The
|
||||
// translations are created in this test; therefore, the assertions do not
|
||||
// use t(). If t() were used then the correct langcodes would need to be
|
||||
// provided.
|
||||
$this->drupalGet("node/add/$type");
|
||||
$this->assertText('Edited title');
|
||||
$this->drupalGet("$langcode/node/add/$type");
|
||||
$this->assertText('Translated title');
|
||||
|
||||
// Add an e-mail field.
|
||||
$this->drupalPostForm("admin/structure/types/manage/$type/fields/add-field", ['new_storage_type' => 'email', 'label' => 'Email', 'field_name' => 'email'], 'Save and continue');
|
||||
$this->drupalPostForm(NULL, [], 'Save field settings');
|
||||
$this->drupalPostForm(NULL, [], 'Save settings');
|
||||
|
||||
$type = Unicode::strtolower($this->randomMachineName(16));
|
||||
$name = $this->randomString();
|
||||
$this->drupalCreateContentType(['type' => $type, 'name' => $name]);
|
||||
|
||||
// Set tabs.
|
||||
$this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]);
|
||||
|
||||
// Change default language.
|
||||
$this->drupalPostForm('admin/config/regional/language', ['site_default_language' => 'es'], 'Save configuration');
|
||||
|
||||
// Try re-using the email field.
|
||||
$this->drupalGet("es/admin/structure/types/manage/$type/fields/add-field");
|
||||
$this->drupalPostForm(NULL, ['existing_storage_name' => 'field_email', 'existing_storage_label' => 'Email'], 'Save and continue');
|
||||
$this->assertResponse(200);
|
||||
$this->drupalGet("es/admin/structure/types/manage/$type/fields/node.$type.field_email/translate");
|
||||
$this->assertResponse(200);
|
||||
$this->assertText("The configuration objects have different language codes so they cannot be translated");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
|
||||
/**
|
||||
* Tests the node language extra field display.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeViewLanguageTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'datetime', 'language'];
|
||||
|
||||
/**
|
||||
* Tests the language extra field display.
|
||||
*/
|
||||
public function testViewLanguage() {
|
||||
// Add Spanish language.
|
||||
ConfigurableLanguage::createFromLangcode('es')->save();
|
||||
|
||||
// Set language field visible.
|
||||
entity_get_display('node', 'page', 'full')
|
||||
->setComponent('langcode')
|
||||
->save();
|
||||
|
||||
// Create a node in Spanish.
|
||||
$node = $this->drupalCreateNode(['langcode' => 'es']);
|
||||
|
||||
$this->drupalGet($node->urlInfo());
|
||||
$this->assertText('Spanish', 'The language field is displayed properly.');
|
||||
}
|
||||
|
||||
}
|
42
web/core/modules/node/tests/src/Functional/PageViewTest.php
Normal file
42
web/core/modules/node/tests/src/Functional/PageViewTest.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Create a node and test edit permissions.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class PageViewTest extends NodeTestBase {
|
||||
/**
|
||||
* Tests an anonymous and unpermissioned user attempting to edit the node.
|
||||
*/
|
||||
public function testPageView() {
|
||||
// Create a node to view.
|
||||
$node = $this->drupalCreateNode();
|
||||
$this->assertTrue(Node::load($node->id()), 'Node created.');
|
||||
|
||||
// Try to edit with anonymous user.
|
||||
$this->drupalGet("node/" . $node->id() . "/edit");
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Create a user without permission to edit node.
|
||||
$web_user = $this->drupalCreateUser(['access content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Attempt to access edit page.
|
||||
$this->drupalGet("node/" . $node->id() . "/edit");
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Create user with permission to edit node.
|
||||
$web_user = $this->drupalCreateUser(['bypass node access']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Attempt to access edit page.
|
||||
$this->drupalGet("node/" . $node->id() . "/edit");
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,7 +26,7 @@ class NodeImportChangeTest extends KernelTestBase {
|
|||
parent::setUp();
|
||||
|
||||
// Set default storage backend.
|
||||
$this->installConfig(array('field', 'node_test_config'));
|
||||
$this->installConfig(['field', 'node_test_config']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,7 @@ class NodeImportCreateTest extends KernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'field', 'text', 'system', 'user');
|
||||
public static $modules = ['node', 'field', 'text', 'system', 'user'];
|
||||
|
||||
/**
|
||||
* Set the default field storage backend for fields created during tests.
|
||||
|
@ -28,7 +28,7 @@ class NodeImportCreateTest extends KernelTestBase {
|
|||
$this->installEntitySchema('user');
|
||||
|
||||
// Set default storage backend.
|
||||
$this->installConfig(array('field'));
|
||||
$this->installConfig(['field']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +42,7 @@ class NodeImportCreateTest extends KernelTestBase {
|
|||
|
||||
// Enable node_test_config module and check that the content type
|
||||
// shipped in the module's default config is created.
|
||||
$this->container->get('module_installer')->install(array('node_test_config'));
|
||||
$this->container->get('module_installer')->install(['node_test_config']);
|
||||
$node_type = NodeType::load($node_type_id);
|
||||
$this->assertTrue($node_type, 'The default content type was created.');
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\node\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,6 +57,8 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
$node_revision = \Drupal::entityManager()->getStorage('node')->loadRevision(1);
|
||||
$this->assertIdentical('Test title', $node_revision->getTitle());
|
||||
$this->assertIdentical('1', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user');
|
||||
$this->assertSame('1', $node_revision->id(), 'Node 1 loaded.');
|
||||
$this->assertSame('1', $node_revision->getRevisionId(), 'Node 1 revision 1 loaded.');
|
||||
// This is empty on the first revision.
|
||||
$this->assertIdentical(NULL, $node_revision->revision_log->value);
|
||||
$this->assertIdentical('This is a shared text field', $node->field_test->value);
|
||||
|
@ -77,7 +79,7 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
|
||||
// Test the file field meta.
|
||||
$this->assertIdentical('desc', $node->field_test_filefield->description);
|
||||
$this->assertIdentical('5', $node->field_test_filefield->target_id);
|
||||
$this->assertIdentical('4', $node->field_test_filefield->target_id);
|
||||
|
||||
$node = Node::load(2);
|
||||
$this->assertIdentical('Test title rev 3', $node->getTitle());
|
||||
|
@ -89,6 +91,20 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
$this->assertIdentical('Drupal Groups', $node->field_test_link->title);
|
||||
$this->assertIdentical([], $node->field_test_link->options['attributes']);
|
||||
|
||||
$node = Node::load(3);
|
||||
// Test multivalue field.
|
||||
$value_1 = $node->field_multivalue->value;
|
||||
$value_2 = $node->field_multivalue[1]->value;
|
||||
|
||||
// SQLite does not support scales for float data types so we need to convert
|
||||
// the value manually.
|
||||
if ($this->container->get('database')->driver() == 'sqlite') {
|
||||
$value_1 = sprintf('%01.2f', $value_1);
|
||||
$value_2 = sprintf('%01.2f', $value_2);
|
||||
}
|
||||
$this->assertSame('33.00', $value_1);
|
||||
$this->assertSame('44.00', $value_2);
|
||||
|
||||
// Test that a link field with an internal link is migrated.
|
||||
$node = Node::load(9);
|
||||
$this->assertSame('internal:/node/10', $node->field_test_link->uri);
|
||||
|
@ -156,11 +172,11 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
$this->assertIdentical('full_html', $node->body->format);
|
||||
|
||||
// Now insert a row indicating a failure and set to update later.
|
||||
$title = $this->rerunMigration(array(
|
||||
$title = $this->rerunMigration([
|
||||
'sourceid1' => 2,
|
||||
'destid1' => NULL,
|
||||
'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
|
||||
));
|
||||
]);
|
||||
$node = Node::load(2);
|
||||
$this->assertIdentical($title, $node->getTitle());
|
||||
}
|
||||
|
@ -178,10 +194,10 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
$title = $this->randomString();
|
||||
$source_connection = Database::getConnection('default', 'migrate');
|
||||
$source_connection->update('node_revisions')
|
||||
->fields(array(
|
||||
->fields([
|
||||
'title' => $title,
|
||||
'format' => 2,
|
||||
))
|
||||
])
|
||||
->condition('vid', 3)
|
||||
->execute();
|
||||
$migration = $this->getMigration('d6_node:story');
|
||||
|
|
|
@ -33,7 +33,7 @@ class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
|||
$this->assertIdentical(TRUE, $node_type_page->displaySubmitted());
|
||||
$this->assertIdentical(FALSE, $node_type_page->isNewRevision());
|
||||
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_page->getPreviewMode());
|
||||
$this->assertIdentical($id_map->lookupDestinationID(array('test_page')), array('test_page'));
|
||||
$this->assertIdentical($id_map->lookupDestinationID(['test_page']), ['test_page']);
|
||||
|
||||
// Test we have a body field.
|
||||
$field = FieldConfig::loadByName('node', 'test_page', 'body');
|
||||
|
@ -46,7 +46,7 @@ class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
|||
$this->assertIdentical(TRUE, $node_type_story->displaySubmitted());
|
||||
$this->assertIdentical(FALSE, $node_type_story->isNewRevision());
|
||||
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_story->getPreviewMode());
|
||||
$this->assertIdentical($id_map->lookupDestinationID(array('test_story')), array('test_story'));
|
||||
$this->assertIdentical($id_map->lookupDestinationID(['test_story']), ['test_story']);
|
||||
|
||||
// Test we don't have a body field.
|
||||
$field = FieldConfig::loadByName('node', 'test_story', 'body');
|
||||
|
@ -59,7 +59,7 @@ class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
|||
$this->assertIdentical(TRUE, $node_type_event->displaySubmitted());
|
||||
$this->assertIdentical(TRUE, $node_type_event->isNewRevision());
|
||||
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_event->getPreviewMode());
|
||||
$this->assertIdentical($id_map->lookupDestinationID(array('test_event')), array('test_event'));
|
||||
$this->assertIdentical($id_map->lookupDestinationID(['test_event']), ['test_event']);
|
||||
|
||||
// Test we have a body field.
|
||||
$field = FieldConfig::loadByName('node', 'test_event', 'body');
|
||||
|
|
|
@ -29,7 +29,7 @@ class MigrateViewModesTest extends MigrateDrupal6TestBase {
|
|||
$this->assertIdentical(FALSE, is_null($view_mode), 'Preview view mode loaded.');
|
||||
$this->assertIdentical('Preview', $view_mode->label(), 'View mode has correct label.');
|
||||
// Test the ID map.
|
||||
$this->assertIdentical(array('node', 'preview'), $this->getMigration('d6_view_modes')->getIdMap()->lookupDestinationID(array(1)));
|
||||
$this->assertIdentical(['node', 'preview'], $this->getMigration('d6_view_modes')->getIdMap()->lookupDestinationID([1]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Test D7NodeDeriver.
|
||||
*
|
||||
* @group migrate_drupal_7
|
||||
*/
|
||||
class MigrateNodeDeriverTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* The migration plugin manager.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
|
||||
*/
|
||||
protected $pluginManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->pluginManager = $this->container->get('plugin.manager.migration');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test node translation migrations with translation disabled.
|
||||
*/
|
||||
public function testNoTranslations() {
|
||||
// Without content_translation, there should be no translation migrations.
|
||||
$migrations = $this->pluginManager->createInstances('d7_node_translation');
|
||||
$this->assertSame([], $migrations,
|
||||
"No node translation migrations without content_translation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test node translation migrations with translation enabled.
|
||||
*/
|
||||
public function testTranslations() {
|
||||
// With content_translation, there should be translation migrations for
|
||||
// each content type.
|
||||
$this->enableModules(['language', 'content_translation', 'node', 'filter']);
|
||||
$migrations = $this->pluginManager->createInstances('d7_node_translation');
|
||||
$this->assertArrayHasKey('d7_node_translation:article', $migrations,
|
||||
"Node translation migrations exist after content_translation installed");
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\node\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,17 +13,22 @@ use Drupal\node\NodeInterface;
|
|||
*/
|
||||
class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = array(
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'content_translation',
|
||||
'comment',
|
||||
'datetime',
|
||||
'filter',
|
||||
'image',
|
||||
'language',
|
||||
'link',
|
||||
'node',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
'text',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -40,15 +45,17 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
|||
$this->installSchema('system', ['sequences']);
|
||||
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd7_user_role',
|
||||
'd7_user',
|
||||
'd7_node_type',
|
||||
'd7_language_content_settings',
|
||||
'd7_comment_type',
|
||||
'd7_taxonomy_vocabulary',
|
||||
'd7_field',
|
||||
'd7_field_instance',
|
||||
'd7_node',
|
||||
'd7_node:article',
|
||||
'd7_node_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -144,9 +151,31 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
|||
$this->assertIdentical('Click Here', $node->field_link->title);
|
||||
|
||||
$node = Node::load(2);
|
||||
$this->assertSame('en', $node->langcode->value);
|
||||
$this->assertIdentical("...is that it's the absolute best show ever. Trust me, I would know.", $node->body->value);
|
||||
$this->assertSame('The thing about Deep Space 9', $node->label());
|
||||
$this->assertIdentical('internal:/', $node->field_link->uri);
|
||||
$this->assertIdentical('Home', $node->field_link->title);
|
||||
$this->assertTrue($node->hasTranslation('is'), "Node 2 has an Icelandic translation");
|
||||
|
||||
$translation = $node->getTranslation('is');
|
||||
$this->assertSame('is', $translation->langcode->value);
|
||||
$this->assertSame("is - ...is that it's the absolute best show ever. Trust me, I would know.", $translation->body->value);
|
||||
$this->assertSame('is - The thing about Deep Space 9', $translation->label());
|
||||
$this->assertSame('internal:/', $translation->field_link->uri);
|
||||
$this->assertSame('Home', $translation->field_link->title);
|
||||
|
||||
// Test that content_translation_source is set.
|
||||
$manager = $this->container->get('content_translation.manager');
|
||||
$this->assertSame('en', $manager->getTranslationMetadata($node->getTranslation('is'))->getSource());
|
||||
|
||||
// Node 3 is a translation of node 2, and should not be imported separately.
|
||||
$this->assertNull(Node::load(3), "Node 3 doesn't exist in D8, it was a translation");
|
||||
|
||||
// Test that content_translation_source for a source other than English.
|
||||
$node = Node::load(4);
|
||||
$this->assertSame('is', $manager->getTranslationMetadata($node->getTranslation('en'))->getSource());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,14 +20,14 @@ class MigrateNodeTypeTest extends MigrateDrupal7TestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'text', 'filter');
|
||||
public static $modules = ['node', 'text', 'filter'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('node'));
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigration('d7_node_type');
|
||||
}
|
||||
|
||||
|
|
|
@ -73,11 +73,11 @@ class NodeAccessTest extends KernelTestBase {
|
|||
$this->drupalCreateUser();
|
||||
|
||||
// Create a node type.
|
||||
$this->drupalCreateContentType(array(
|
||||
$this->drupalCreateContentType([
|
||||
'type' => 'page',
|
||||
'name' => 'Basic page',
|
||||
'display_submitted' => FALSE,
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@ class NodeBodyFieldStorageTest extends KernelTestBase {
|
|||
$this->installSchema('user', 'users_data');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(array('field', 'node'));
|
||||
$this->installConfig(['field', 'node']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,7 @@ class NodeBodyFieldStorageTest extends KernelTestBase {
|
|||
$field->delete();
|
||||
$field_storage = FieldStorageConfig::loadByName('node', 'body');
|
||||
$this->assertTrue(count($field_storage->getBundles()) == 0, 'Node body field storage exists after deleting the only instance of a field.');
|
||||
\Drupal::service('module_installer')->uninstall(array('node'));
|
||||
\Drupal::service('module_installer')->uninstall(['node']);
|
||||
$field_storage = FieldStorageConfig::loadByName('node', 'body');
|
||||
$this->assertFalse($field_storage, 'Node body field storage does not exist after uninstalling the Node module.');
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use Drupal\node\Entity\NodeType;
|
|||
*/
|
||||
class NodeConditionTest extends EntityKernelTestBase {
|
||||
|
||||
public static $modules = array('node');
|
||||
public static $modules = ['node'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
@ -30,7 +30,7 @@ class NodeConditionTest extends EntityKernelTestBase {
|
|||
/**
|
||||
* Tests conditions.
|
||||
*/
|
||||
function testConditions() {
|
||||
public function testConditions() {
|
||||
$manager = $this->container->get('plugin.manager.condition', $this->container->get('container.namespaces'));
|
||||
$this->createUser();
|
||||
|
||||
|
@ -45,20 +45,20 @@ class NodeConditionTest extends EntityKernelTestBase {
|
|||
// Grab the node type condition and configure it to check against node type
|
||||
// of 'article' and set the context to the page type node.
|
||||
$condition = $manager->createInstance('node_type')
|
||||
->setConfig('bundles', array('article' => 'article'))
|
||||
->setConfig('bundles', ['article' => 'article'])
|
||||
->setContextValue('node', $page);
|
||||
$this->assertFalse($condition->execute(), 'Page type nodes fail node type checks for articles.');
|
||||
// Check for the proper summary.
|
||||
$this->assertEqual('The node bundle is article', $condition->summary());
|
||||
|
||||
// Set the node type check to page.
|
||||
$condition->setConfig('bundles', array('page' => 'page'));
|
||||
$condition->setConfig('bundles', ['page' => 'page']);
|
||||
$this->assertTrue($condition->execute(), 'Page type nodes pass node type checks for pages');
|
||||
// Check for the proper summary.
|
||||
$this->assertEqual('The node bundle is page', $condition->summary());
|
||||
|
||||
// Set the node type check to page or article.
|
||||
$condition->setConfig('bundles', array('page' => 'page', 'article' => 'article'));
|
||||
$condition->setConfig('bundles', ['page' => 'page', 'article' => 'article']);
|
||||
$this->assertTrue($condition->execute(), 'Page type nodes pass node type checks for pages or articles');
|
||||
// Check for the proper summary.
|
||||
$this->assertEqual('The node bundle is page or article', $condition->summary());
|
||||
|
@ -72,11 +72,11 @@ class NodeConditionTest extends EntityKernelTestBase {
|
|||
$this->assertFalse($condition->execute(), 'Test type nodes pass node type checks for pages or articles');
|
||||
|
||||
// Check a greater than 2 bundles summary scenario.
|
||||
$condition->setConfig('bundles', array('page' => 'page', 'article' => 'article', 'test' => 'test'));
|
||||
$condition->setConfig('bundles', ['page' => 'page', 'article' => 'article', 'test' => 'test']);
|
||||
$this->assertEqual('The node bundle is page, article or test', $condition->summary());
|
||||
|
||||
// Test Constructor injection.
|
||||
$condition = $manager->createInstance('node_type', array('bundles' => array('article' => 'article'), 'context' => array('node' => $article)));
|
||||
$condition = $manager->createInstance('node_type', ['bundles' => ['article' => 'article'], 'context' => ['node' => $article]]);
|
||||
$this->assertTrue($condition->execute(), 'Constructor injection of context and configuration working as anticipated.');
|
||||
}
|
||||
|
||||
|
|
|
@ -19,32 +19,32 @@ class NodeFieldAccessTest extends EntityKernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* Fields that only users with administer nodes permissions can change.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $administrativeFields = array(
|
||||
protected $administrativeFields = [
|
||||
'status',
|
||||
'promote',
|
||||
'sticky',
|
||||
'created',
|
||||
'uid',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* These fields are automatically managed and can not be changed by any user.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $readOnlyFields = array('changed', 'revision_uid', 'revision_timestamp');
|
||||
protected $readOnlyFields = ['changed', 'revision_uid', 'revision_timestamp'];
|
||||
|
||||
/**
|
||||
* Test permissions on nodes status field.
|
||||
*/
|
||||
function testAccessToAdministrativeFields() {
|
||||
public function testAccessToAdministrativeFields() {
|
||||
|
||||
// Create the page node type with revisions disabled.
|
||||
$page = NodeType::create([
|
||||
|
@ -62,74 +62,74 @@ class NodeFieldAccessTest extends EntityKernelTestBase {
|
|||
|
||||
// An administrator user. No user exists yet, ensure that the first user
|
||||
// does not have UID 1.
|
||||
$content_admin_user = $this->createUser(array('uid' => 2), array('administer nodes'));
|
||||
$content_admin_user = $this->createUser(['uid' => 2], ['administer nodes']);
|
||||
|
||||
// Two different editor users.
|
||||
$page_creator_user = $this->createUser(array(), array('create page content', 'edit own page content', 'delete own page content'));
|
||||
$page_manager_user = $this->createUser(array(), array('create page content', 'edit any page content', 'delete any page content'));
|
||||
$page_creator_user = $this->createUser([], ['create page content', 'edit own page content', 'delete own page content']);
|
||||
$page_manager_user = $this->createUser([], ['create page content', 'edit any page content', 'delete any page content']);
|
||||
|
||||
// An unprivileged user.
|
||||
$page_unrelated_user = $this->createUser(array(), array('access content'));
|
||||
$page_unrelated_user = $this->createUser([], ['access content']);
|
||||
|
||||
// List of all users
|
||||
$test_users = array(
|
||||
$test_users = [
|
||||
$content_admin_user,
|
||||
$page_creator_user,
|
||||
$page_manager_user,
|
||||
$page_unrelated_user,
|
||||
);
|
||||
];
|
||||
|
||||
// Create three "Basic pages". One is owned by our test-user
|
||||
// "page_creator", one by "page_manager", and one by someone else.
|
||||
$node1 = Node::create(array(
|
||||
$node1 = Node::create([
|
||||
'title' => $this->randomMachineName(8),
|
||||
'uid' => $page_creator_user->id(),
|
||||
'type' => 'page',
|
||||
));
|
||||
$node2 = Node::create(array(
|
||||
]);
|
||||
$node2 = Node::create([
|
||||
'title' => $this->randomMachineName(8),
|
||||
'uid' => $page_manager_user->id(),
|
||||
'type' => 'article',
|
||||
));
|
||||
$node3 = Node::create(array(
|
||||
]);
|
||||
$node3 = Node::create([
|
||||
'title' => $this->randomMachineName(8),
|
||||
'type' => 'page',
|
||||
));
|
||||
]);
|
||||
|
||||
foreach ($this->administrativeFields as $field) {
|
||||
|
||||
// Checks on view operations.
|
||||
foreach ($test_users as $account) {
|
||||
$may_view = $node1->{$field}->access('view', $account);
|
||||
$this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', array('@name' => $field)));
|
||||
$this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', ['@name' => $field]));
|
||||
}
|
||||
|
||||
// Checks on edit operations.
|
||||
$may_update = $node1->{$field}->access('edit', $page_creator_user);
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', array('@name' => $field)));
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', ['@name' => $field]));
|
||||
$may_update = $node2->{$field}->access('edit', $page_creator_user);
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', array('@name' => $field)));
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', ['@name' => $field]));
|
||||
$may_update = $node2->{$field}->access('edit', $page_manager_user);
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', array('@name' => $field)));
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', ['@name' => $field]));
|
||||
$may_update = $node1->{$field}->access('edit', $page_manager_user);
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', array('@name' => $field)));
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', ['@name' => $field]));
|
||||
$may_update = $node2->{$field}->access('edit', $page_unrelated_user);
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users not having permission "edit any page content" is not allowed to the field @name.', array('@name' => $field)));
|
||||
$this->assertFalse($may_update, SafeMarkup::format('Users not having permission "edit any page content" is not allowed to the field @name.', ['@name' => $field]));
|
||||
$may_update = $node1->{$field}->access('edit', $content_admin_user) && $node3->status->access('edit', $content_admin_user);
|
||||
$this->assertTrue($may_update, SafeMarkup::format('Users with permission "administer nodes" may edit @name fields on all nodes.', array('@name' => $field)));
|
||||
$this->assertTrue($may_update, SafeMarkup::format('Users with permission "administer nodes" may edit @name fields on all nodes.', ['@name' => $field]));
|
||||
}
|
||||
|
||||
foreach ($this->readOnlyFields as $field) {
|
||||
// Check view operation.
|
||||
foreach ($test_users as $account) {
|
||||
$may_view = $node1->{$field}->access('view', $account);
|
||||
$this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', array('@name' => $field)));
|
||||
$this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', ['@name' => $field]));
|
||||
}
|
||||
|
||||
// Check edit operation.
|
||||
foreach ($test_users as $account) {
|
||||
$may_view = $node1->{$field}->access('edit', $account);
|
||||
$this->assertFalse($may_view, SafeMarkup::format('No user is not allowed to edit the field @name.', array('@name' => $field)));
|
||||
$this->assertFalse($may_view, SafeMarkup::format('No user is not allowed to edit the field @name.', ['@name' => $field]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,14 @@ class NodeFieldOverridesTest extends EntityKernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('user', 'system', 'field', 'node');
|
||||
public static $modules = ['user', 'system', 'field', 'node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('user'));
|
||||
$this->installConfig(['user']);
|
||||
$this->user = $this->createUser();
|
||||
\Drupal::service('current_user')->setAccount($this->user);
|
||||
}
|
||||
|
|
|
@ -19,16 +19,16 @@ class NodeOwnerTest extends EntityKernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'language');
|
||||
public static $modules = ['node', 'language'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create the node bundles required for testing.
|
||||
$type = NodeType::create(array(
|
||||
$type = NodeType::create([
|
||||
'type' => 'page',
|
||||
'name' => 'page',
|
||||
));
|
||||
]);
|
||||
$type->save();
|
||||
|
||||
// Enable two additional languages.
|
||||
|
@ -48,11 +48,11 @@ class NodeOwnerTest extends EntityKernelTestBase {
|
|||
$container->get('current_user')->setAccount($user);
|
||||
|
||||
// Create a test node.
|
||||
$english = Node::create(array(
|
||||
$english = Node::create([
|
||||
'type' => 'page',
|
||||
'title' => $this->randomMachineName(),
|
||||
'language' => 'en',
|
||||
));
|
||||
]);
|
||||
$english->save();
|
||||
|
||||
$this->assertEqual($user->id(), $english->getOwnerId());
|
||||
|
|
|
@ -22,14 +22,14 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'filter');
|
||||
public static $modules = ['node', 'filter'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('filter', 'node'));
|
||||
$this->installConfig(['filter', 'node']);
|
||||
|
||||
$node_type = NodeType::create(['type' => 'article', 'name' => 'Article']);
|
||||
$node_type->save();
|
||||
|
@ -39,11 +39,11 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase {
|
|||
/**
|
||||
* Creates a node, then tests the tokens generated from it.
|
||||
*/
|
||||
function testNodeTokenReplacement() {
|
||||
$url_options = array(
|
||||
public function testNodeTokenReplacement() {
|
||||
$url_options = [
|
||||
'absolute' => TRUE,
|
||||
'language' => $this->interfaceLanguage,
|
||||
);
|
||||
];
|
||||
|
||||
// Create a user and a node.
|
||||
$account = $this->createUser();
|
||||
|
@ -58,7 +58,7 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase {
|
|||
$node->save();
|
||||
|
||||
// Generate and test tokens.
|
||||
$tests = array();
|
||||
$tests = [];
|
||||
$tests['[node:nid]'] = $node->id();
|
||||
$tests['[node:vid]'] = $node->getRevisionId();
|
||||
$tests['[node:type]'] = 'article';
|
||||
|
@ -72,8 +72,8 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase {
|
|||
$tests['[node:author]'] = $account->getUsername();
|
||||
$tests['[node:author:uid]'] = $node->getOwnerId();
|
||||
$tests['[node:author:name]'] = $account->getUsername();
|
||||
$tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId()));
|
||||
$tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId()));
|
||||
$tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), ['langcode' => $this->interfaceLanguage->getId()]);
|
||||
$tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), ['langcode' => $this->interfaceLanguage->getId()]);
|
||||
|
||||
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($node);
|
||||
|
||||
|
@ -101,7 +101,7 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase {
|
|||
|
||||
foreach ($tests as $input => $expected) {
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$output = $this->tokenService->replace($input, array('node' => $node), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata);
|
||||
$output = $this->tokenService->replace($input, ['node' => $node], ['langcode' => $this->interfaceLanguage->getId()], $bubbleable_metadata);
|
||||
$this->assertEqual($output, $expected, format_string('Node token %token replaced.', ['%token' => $input]));
|
||||
$this->assertEqual($bubbleable_metadata, $metadata_tests[$input]);
|
||||
}
|
||||
|
@ -116,14 +116,14 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase {
|
|||
$node->save();
|
||||
|
||||
// Generate and test token - use full body as expected value.
|
||||
$tests = array();
|
||||
$tests = [];
|
||||
$tests['[node:summary]'] = $node->body->processed;
|
||||
|
||||
// Test to make sure that we generated something for each token.
|
||||
$this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.');
|
||||
|
||||
foreach ($tests as $input => $expected) {
|
||||
$output = $this->tokenService->replace($input, array('node' => $node), array('language' => $this->interfaceLanguage));
|
||||
$output = $this->tokenService->replace($input, ['node' => $node], ['language' => $this->interfaceLanguage]);
|
||||
$this->assertEqual($output, $expected, new FormattableMarkup('Node token %token replaced for node without a summary.', ['%token' => $input]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ class NodeValidationTest extends EntityKernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* Set the default field storage backend for fields created during tests.
|
||||
|
|
|
@ -27,7 +27,6 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
// The source data.
|
||||
$tests[0]['source_data']['node'] = [
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 1,
|
||||
'vid' => 1,
|
||||
'type' => 'page',
|
||||
|
@ -44,7 +43,6 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'translate' => 0,
|
||||
],
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 2,
|
||||
'vid' => 2,
|
||||
'type' => 'page',
|
||||
|
@ -61,7 +59,6 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'translate' => 0,
|
||||
],
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 5,
|
||||
'vid' => 5,
|
||||
'type' => 'article',
|
||||
|
@ -77,11 +74,41 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'tnid' => 0,
|
||||
'translate' => 0,
|
||||
],
|
||||
|
||||
[
|
||||
'nid' => 6,
|
||||
'vid' => 6,
|
||||
'type' => 'article',
|
||||
'language' => 'en',
|
||||
'title' => 'node title 5',
|
||||
'uid' => 1,
|
||||
'status' => 1,
|
||||
'created' => 1279291908,
|
||||
'changed' => 1279309993,
|
||||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 6,
|
||||
'translate' => 0,
|
||||
],
|
||||
[
|
||||
'nid' => 7,
|
||||
'vid' => 7,
|
||||
'type' => 'article',
|
||||
'language' => 'fr',
|
||||
'title' => 'fr - node title 5',
|
||||
'uid' => 1,
|
||||
'status' => 1,
|
||||
'created' => 1279292908,
|
||||
'changed' => 1279310993,
|
||||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 6,
|
||||
'translate' => 0,
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['node_revision'] = [
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 1,
|
||||
'vid' => 1,
|
||||
'uid' => 2,
|
||||
|
@ -94,7 +121,6 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'sticky' => 0,
|
||||
],
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 2,
|
||||
'vid' => 2,
|
||||
'uid' => 2,
|
||||
|
@ -107,7 +133,6 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'sticky' => 0,
|
||||
],
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 5,
|
||||
'vid' => 5,
|
||||
'uid' => 2,
|
||||
|
@ -119,6 +144,31 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
],
|
||||
[
|
||||
'nid' => 6,
|
||||
'vid' => 6,
|
||||
'uid' => 1,
|
||||
'title' => 'node title 5',
|
||||
'log' => '',
|
||||
'timestamp' => 1279309993,
|
||||
'status' => 1,
|
||||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
|
||||
],
|
||||
[
|
||||
'nid' => 7,
|
||||
'vid' => 7,
|
||||
'uid' => 1,
|
||||
'title' => 'fr - node title 5',
|
||||
'log' => '',
|
||||
'timestamp' => 1279310993,
|
||||
'status' => 1,
|
||||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['field_config_instance'] = [
|
||||
[
|
||||
|
@ -131,7 +181,7 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'deleted' => '0',
|
||||
],
|
||||
[
|
||||
'id' => '2',
|
||||
'id' => '3',
|
||||
'field_id' => '2',
|
||||
'field_name' => 'body',
|
||||
'entity_type' => 'node',
|
||||
|
@ -153,12 +203,59 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'body_summary' => '',
|
||||
'body_format' => 'filtered_html',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '2',
|
||||
'revision_id' => '2',
|
||||
'language' => 'en',
|
||||
'delta' => '0',
|
||||
'body_value' => 'body 2',
|
||||
'body_summary' => '',
|
||||
'body_format' => 'filtered_html',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '5',
|
||||
'revision_id' => '5',
|
||||
'language' => 'en',
|
||||
'delta' => '0',
|
||||
'body_value' => 'body 5',
|
||||
'body_summary' => '',
|
||||
'body_format' => 'filtered_html',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '6',
|
||||
'revision_id' => '6',
|
||||
'language' => 'en',
|
||||
'delta' => '0',
|
||||
'body_value' => 'body 6',
|
||||
'body_summary' => '',
|
||||
'body_format' => 'filtered_html',
|
||||
],
|
||||
[
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'deleted' => '0',
|
||||
'entity_id' => '7',
|
||||
'revision_id' => '7',
|
||||
'language' => 'fr',
|
||||
'delta' => '0',
|
||||
'body_value' => 'fr - body 6',
|
||||
'body_summary' => '',
|
||||
'body_format' => 'filtered_html',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 1,
|
||||
'vid' => 1,
|
||||
'type' => 'page',
|
||||
|
@ -172,7 +269,7 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'comment' => 2,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 0,
|
||||
'tnid' => 1,
|
||||
'translate' => 0,
|
||||
'log' => '',
|
||||
'timestamp' => 1279051598,
|
||||
|
@ -185,7 +282,6 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
],
|
||||
],
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 2,
|
||||
'vid' => 2,
|
||||
'type' => 'page',
|
||||
|
@ -199,13 +295,19 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 0,
|
||||
'tnid' => 2,
|
||||
'translate' => 0,
|
||||
'log' => '',
|
||||
'timestamp' => 1279308993,
|
||||
'body' => [
|
||||
[
|
||||
'value' => 'body 2',
|
||||
'summary' => '',
|
||||
'format' => 'filtered_html',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 5,
|
||||
'vid' => 5,
|
||||
'type' => 'article',
|
||||
|
@ -219,10 +321,43 @@ class NodeTest extends MigrateSqlSourceTestBase {
|
|||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 0,
|
||||
'tnid' => 5,
|
||||
'translate' => 0,
|
||||
'log' => '',
|
||||
'timestamp' => 1279308993,
|
||||
'body' => [
|
||||
[
|
||||
'value' => 'body 5',
|
||||
'summary' => '',
|
||||
'format' => 'filtered_html',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'nid' => 6,
|
||||
'vid' => 6,
|
||||
'type' => 'article',
|
||||
'language' => 'en',
|
||||
'title' => 'node title 5',
|
||||
'node_uid' => 1,
|
||||
'revision_uid' => 1,
|
||||
'status' => 1,
|
||||
'created' => 1279291908,
|
||||
'changed' => 1279309993,
|
||||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 6,
|
||||
'translate' => 0,
|
||||
'log' => '',
|
||||
'timestamp' => 1279309993,
|
||||
'body' => [
|
||||
[
|
||||
'value' => 'body 6',
|
||||
'summary' => '',
|
||||
'format' => 'filtered_html',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
/**
|
||||
* Tests D7 node translation source plugin.
|
||||
*
|
||||
* @covers \Drupal\node\Plugin\migrate\source\d7\Node
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeTranslationTest extends NodeTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'user', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
// Get the source data from parent.
|
||||
$tests = parent::providerSource();
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
// Node fields.
|
||||
'nid' => 7,
|
||||
'vid' => 7,
|
||||
'type' => 'article',
|
||||
'language' => 'fr',
|
||||
'title' => 'fr - node title 5',
|
||||
'node_uid' => 1,
|
||||
'revision_uid' => 1,
|
||||
'status' => 1,
|
||||
'created' => 1279292908,
|
||||
'changed' => 1279310993,
|
||||
'comment' => 0,
|
||||
'promote' => 1,
|
||||
'sticky' => 0,
|
||||
'tnid' => 6,
|
||||
'translate' => 0,
|
||||
// Node revision fields.
|
||||
'log' => '',
|
||||
'timestamp' => 1279310993,
|
||||
'body' => [
|
||||
[
|
||||
'value' => 'fr - body 6',
|
||||
'summary' => '',
|
||||
'format' => 'filtered_html',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// Do an automatic count.
|
||||
$tests[0]['expected_count'] = NULL;
|
||||
|
||||
// Set up source plugin configuration.
|
||||
$tests[0]['configuration'] = [
|
||||
'translations' => TRUE,
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -25,7 +25,7 @@ class NodeBulkFormTest extends UnitTestCase {
|
|||
* Tests the constructor assignment of actions.
|
||||
*/
|
||||
public function testConstructor() {
|
||||
$actions = array();
|
||||
$actions = [];
|
||||
|
||||
for ($i = 1; $i <= 2; $i++) {
|
||||
$action = $this->getMock('\Drupal\system\ActionConfigEntityInterface');
|
||||
|
@ -60,7 +60,7 @@ class NodeBulkFormTest extends UnitTestCase {
|
|||
$views_data->expects($this->any())
|
||||
->method('get')
|
||||
->with('node')
|
||||
->will($this->returnValue(array('table' => array('entity type' => 'node'))));
|
||||
->will($this->returnValue(['table' => ['entity type' => 'node']]));
|
||||
$container = new ContainerBuilder();
|
||||
$container->set('views.views_data', $views_data);
|
||||
$container->set('string_translation', $this->getStringTranslationStub());
|
||||
|
@ -82,9 +82,9 @@ class NodeBulkFormTest extends UnitTestCase {
|
|||
->getMock();
|
||||
|
||||
$definition['title'] = '';
|
||||
$options = array();
|
||||
$options = [];
|
||||
|
||||
$node_bulk_form = new NodeBulkForm(array(), 'node_bulk_form', $definition, $entity_manager, $language_manager);
|
||||
$node_bulk_form = new NodeBulkForm([], 'node_bulk_form', $definition, $entity_manager, $language_manager);
|
||||
$node_bulk_form->init($executable, $display, $options);
|
||||
|
||||
$this->assertAttributeEquals(array_slice($actions, 0, -1, TRUE), 'actions', $node_bulk_form);
|
||||
|
|
Reference in a new issue