/**
* Checks that the Revision tab is displayed correctly.
*/
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 = array('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 = array();
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
$this->assertUrl($node->toUrl());
$this->assertLink(t('Revisions'));
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->installEntitySchema('node');
// Need at least one node type present.
NodeType::create(['type' => 'testnodetype', 'name' => 'Test node type'])->save();
}
/**
* Adds a content type with a Paragraphs field.
*
* @param string $content_type_name
* Content type name to be used.
* @param string $paragraphs_field_name
* Paragraphs field name to be used.
*/
protected function addParagraphedContentType($content_type_name, $paragraphs_field_name)
{
// Create the content type.
$node_type = NodeType::create(['type' => $content_type_name, 'name' => $content_type_name]);
$node_type->save();
$this->addParagraphsField($content_type_name, $paragraphs_field_name, 'node');
}
/**
* Tests configuration renaming validation.
*/
public function testRenameValidation()
{
// Create a test entity.
$test_entity_id = $this->randomMachineName();
$test_entity = entity_create('config_test', array('id' => $test_entity_id, 'label' => $this->randomMachineName()));
$test_entity->save();
$uuid = $test_entity->uuid();
// Stage the test entity and then delete it from the active storage.
$active = $this->container->get('config.storage');
$sync = $this->container->get('config.storage.sync');
$this->copyConfig($active, $sync);
$test_entity->delete();
// Create a content type with a matching UUID in the active storage.
$content_type = NodeType::create(['type' => Unicode::strtolower($this->randomMachineName(16)), 'name' => $this->randomMachineName(), 'uuid' => $uuid]);
$content_type->save();
// Confirm that the staged configuration is detected as a rename since the
// UUIDs match.
$this->configImporter->reset();
$expected = array('node.type.' . $content_type->id() . '::config_test.dynamic.' . $test_entity_id);
$renames = $this->configImporter->getUnprocessedConfiguration('rename');
$this->assertIdentical($expected, $renames);
// Try to import the configuration. We expect an exception to be thrown
// because the staged entity is of a different type.
try {
$this->configImporter->import();
$this->fail('Expected ConfigImporterException thrown when a renamed configuration entity does not match the existing entity type.');
} catch (ConfigImporterException $e) {
$this->pass('Expected ConfigImporterException thrown when a renamed configuration entity does not match the existing entity type.');
$expected = array(SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', array('@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id)));
$this->assertEqual($expected, $this->configImporter->getErrors());
}
}
/**
* Tests the deletion of a scheduled node.
*
* This tests if it is possible to delete a node that does not have a
* publication date set, when scheduled publishing is required.
*
* @see https://drupal.org/node/1614880
*/
public function testScheduledNodeDelete()
{
// Log in.
$this->drupalLogin($this->adminUser);
// Create a published and an unpublished node, both without scheduling.
$published_node = $this->drupalCreateNode(['type' => 'page', 'status' => 1]);
$unpublished_node = $this->drupalCreateNode(['type' => 'page', 'status' => 0]);
// Make scheduled publishing and unpublishing required.
$node_type = NodeType::load('page');
$node_type->setThirdPartySetting('scheduler', 'publish_required', TRUE);
$node_type->setThirdPartySetting('scheduler', 'unpublish_required', TRUE);
$node_type->save();
// Check that deleting the nodes does not throw form validation errors.
### @TODO Delete was a button in 7.x but a separate link node/<nid>/delete in 8.x
### Is the previous validation (that we had to avoid on delete) still done now in D8, given that there is no form?
### Maybe this test is not actually checking anything useful? Can it be altered to do something testable?
$this->drupalGet('node/' . $published_node->id() . '/delete');
// Note that the text 'error message' is used in a header h2 html tag which
// is normally made hidden from browsers but will be in the page source.
// It is also good when testing for the absense of somthing to also test
// for the presence of text, hence the second assertion for each check.
$this->assertNoRaw(t('Error message'), 'No error messages are shown when trying to delete a published node with no scheduling information.');
$this->assertRaw(t('Are you sure you want to delete the content'), 'The deletion warning message is shown immediately when trying to delete a published node with no scheduling information.');
$this->drupalGet('node/' . $unpublished_node->id() . '/delete');
$this->assertNoRaw(t('Error message'), 'No error messages are shown when trying to delete an unpublished node with no scheduling information.');
$this->assertRaw(t('Are you sure you want to delete the content'), 'The deletion warning message is shown immediately when trying to delete an unpublished node with no scheduling information.');
}
/**
* Checks that unchecking 'Create new revision' works when editing a node.
*/
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 = array('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(array($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 = array();
$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(array($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.");
}
/**
* Tests Drupal 6 node type to Drupal 8 migration.
*/
public function testNodeType()
{
$migration = entity_load('migration', 'd6_node_type');
// Test the test_page content type.
$node_type_page = NodeType::load('test_page');
$this->assertIdentical('test_page', $node_type_page->id(), 'Node type test_page loaded');
$this->assertIdentical(TRUE, $node_type_page->displaySubmitted());
$this->assertIdentical(FALSE, $node_type_page->isNewRevision());
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_page->getPreviewMode());
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array('test_page')), array('test_page'));
// Test we have a body field.
$field = FieldConfig::loadByName('node', 'test_page', 'body');
$this->assertIdentical('This is the body field label', $field->getLabel(), 'Body field was found.');
// Test the test_story content type.
$node_type_story = NodeType::load('test_story');
$this->assertIdentical('test_story', $node_type_story->id(), 'Node type test_story loaded');
$this->assertIdentical(TRUE, $node_type_story->displaySubmitted());
$this->assertIdentical(FALSE, $node_type_story->isNewRevision());
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_story->getPreviewMode());
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array('test_story')), array('test_story'));
// Test we don't have a body field.
$field = FieldConfig::loadByName('node', 'test_story', 'body');
$this->assertIdentical(NULL, $field, 'No body field found');
// Test the test_event content type.
$node_type_event = NodeType::load('test_event');
$this->assertIdentical('test_event', $node_type_event->id(), 'Node type test_event loaded');
$this->assertIdentical(TRUE, $node_type_event->displaySubmitted());
$this->assertIdentical(TRUE, $node_type_event->isNewRevision());
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_event->getPreviewMode());
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array('test_event')), array('test_event'));
// Test we have a body field.
$field = FieldConfig::loadByName('node', 'test_event', 'body');
$this->assertIdentical('Body', $field->getLabel(), 'Body field was found.');
}
public function testRecreateEntity()
{
$type_name = Unicode::strtolower($this->randomMachineName(16));
$content_type = entity_create('node_type', array('type' => $type_name, 'name' => 'Node type one'));
$content_type->save();
node_add_body_field($content_type);
/** @var \Drupal\Core\Config\StorageInterface $active */
$active = $this->container->get('config.storage');
/** @var \Drupal\Core\Config\StorageInterface $sync */
$sync = $this->container->get('config.storage.sync');
$config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
$this->copyConfig($active, $sync);
// Delete the content type. This will also delete a field storage, a field,
// an entity view display and an entity form display.
$content_type->delete();
$this->assertFalse($active->exists($config_name), 'Content type\'s old name does not exist active store.');
// Recreate with the same type - this will have a different UUID.
$content_type = entity_create('node_type', array('type' => $type_name, 'name' => 'Node type two'));
$content_type->save();
node_add_body_field($content_type);
$this->configImporter->reset();
// A node type, a field, an entity view display and an entity form display
// will be recreated.
$creates = $this->configImporter->getUnprocessedConfiguration('create');
$deletes = $this->configImporter->getUnprocessedConfiguration('delete');
$this->assertEqual(5, count($creates), 'There are 5 configuration items to create.');
$this->assertEqual(5, count($deletes), 'There are 5 configuration items to delete.');
$this->assertEqual(0, count($this->configImporter->getUnprocessedConfiguration('update')), 'There are no configuration items to update.');
$this->assertIdentical($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.');
$this->configImporter->import();
// Verify that there is nothing more to import.
$this->assertFalse($this->configImporter->reset()->hasUnprocessedConfigurationChanges());
$content_type = NodeType::load($type_name);
$this->assertEqual('Node type one', $content_type->label());
}
/**
* Creates a new node type.
*
* @param string $label
* The human-readable label of the type to create.
* @param string $machine_name
* The machine name of the type to create.
*
* @return NodeType
* The node type just created.
*/
protected function createNodeType($label, $machine_name)
{
/** @var NodeType $node_type */
$node_type = NodeType::create(['type' => $machine_name, 'label' => $label]);
$node_type->save();
return $node_type;
}
请发表评论