示例#1
0
 /**
  * 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 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.');
 }
 /**
  * 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());
 }
 /**
  * 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'));
 }
 protected function setUp()
 {
     parent::setUp();
     node_access_test_add_field(NodeType::load('article'));
     node_access_rebuild();
     \Drupal::state()->set('node_access_test.private', TRUE);
 }
示例#7
0
 /**
  * Tests if forum module uninstallation properly deletes the field.
  */
 public function testForumUninstallWithField()
 {
     $this->drupalLogin($this->drupalCreateUser(['administer taxonomy', 'administer nodes', 'administer modules', 'delete any forum content', 'administer content types']));
     // Ensure that the field exists before uninstallation.
     $field_storage = FieldStorageConfig::loadByName('node', 'taxonomy_forums');
     $this->assertNotNull($field_storage, 'The taxonomy_forums field storage exists.');
     // Create a taxonomy term.
     $term = Term::create(['name' => t('A term'), 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(), 'description' => '', 'parent' => array(0), 'vid' => 'forums', 'forum_container' => 0]);
     $term->save();
     // Create a forum node.
     $node = $this->drupalCreateNode(array('title' => 'A forum post', 'type' => 'forum', 'taxonomy_forums' => array(array('target_id' => $term->id()))));
     // Create at least one comment against the forum node.
     $comment = Comment::create(array('entity_id' => $node->nid->value, 'entity_type' => 'node', 'field_name' => 'comment_forum', 'pid' => 0, 'uid' => 0, 'status' => CommentInterface::PUBLISHED, 'subject' => $this->randomMachineName(), 'hostname' => '127.0.0.1'));
     $comment->save();
     // Attempt to uninstall forum.
     $this->drupalGet('admin/modules/uninstall');
     // Assert forum is required.
     $this->assertNoFieldByName('uninstall[forum]');
     $this->assertText('To uninstall Forum, first delete all Forum content');
     // Delete the node.
     $this->drupalPostForm('node/' . $node->id() . '/delete', array(), t('Delete'));
     // Attempt to uninstall forum.
     $this->drupalGet('admin/modules/uninstall');
     // Assert forum is still required.
     $this->assertNoFieldByName('uninstall[forum]');
     $this->assertText('To uninstall Forum, first delete all Forums terms');
     // Delete any forum terms.
     $vid = $this->config('forum.settings')->get('vocabulary');
     $terms = entity_load_multiple_by_properties('taxonomy_term', ['vid' => $vid]);
     foreach ($terms as $term) {
         $term->delete();
     }
     // Ensure that the forum node type can not be deleted.
     $this->drupalGet('admin/structure/types/manage/forum');
     $this->assertNoLink(t('Delete'));
     // Now attempt to uninstall forum.
     $this->drupalGet('admin/modules/uninstall');
     // Assert forum is no longer required.
     $this->assertFieldByName('uninstall[forum]');
     $this->drupalPostForm('admin/modules/uninstall', array('uninstall[forum]' => 1), t('Uninstall'));
     $this->drupalPostForm(NULL, [], t('Uninstall'));
     // Check that the field is now deleted.
     $field_storage = FieldStorageConfig::loadByName('node', 'taxonomy_forums');
     $this->assertNull($field_storage, 'The taxonomy_forums field storage has been deleted.');
     // Check that a node type with a machine name of forum can be created after
     // uninstalling the forum module and the node type is not locked.
     $edit = array('name' => 'Forum', 'title_label' => 'title for forum', 'type' => 'forum');
     $this->drupalPostForm('admin/structure/types/add', $edit, t('Save content type'));
     $this->assertTrue((bool) NodeType::load('forum'), 'Node type with machine forum created.');
     $this->drupalGet('admin/structure/types/manage/forum');
     $this->clickLink(t('Delete'));
     $this->drupalPostForm(NULL, array(), t('Delete'));
     $this->assertResponse(200);
     $this->assertFalse((bool) NodeType::load('forum'), 'Node type with machine forum deleted.');
     // Double check everything by reinstalling the forum module again.
     $this->drupalPostForm('admin/modules', ['modules[Core][forum][enable]' => 1], 'Install');
     $this->assertText('Module Forum has been enabled.');
 }
示例#8
0
 protected function setUp()
 {
     parent::setUp();
     node_access_rebuild();
     $this->drupalCreateContentType(array('type' => 'page'));
     node_access_test_add_field(NodeType::load('page'));
     $this->addDefaultCommentField('node', 'page', 'comment', CommentItemInterface::OPEN);
     \Drupal::state()->set('node_access_test.private', TRUE);
 }
 /**
  * Tests creating and editing nodes with required scheduling enabled.
  */
 public function testRequiredScheduling()
 {
     $this->drupalLogin($this->adminUser);
     // Define test scenarios with expected results.
     $test_cases = [['id' => 0, 'required' => '', 'operation' => 'add', 'status' => 1, 'expected' => 'not required', 'message' => 'By default when a new node is created, the publish on and unpublish on dates are not required.'], ['id' => 1, 'required' => 'publish', 'operation' => 'add', 'status' => 0, 'expected' => 'required', 'message' => 'When scheduled publishing is required and a new unpublished node is created, entering a date in the publish on field is required.'], ['id' => 2, 'required' => 'publish', 'operation' => 'add', 'status' => 1, 'expected' => 'required', 'message' => 'When scheduled publishing is required and a new published node is created, entering a date in the publish on field is required.'], ['id' => 3, 'required' => 'publish', 'operation' => 'edit', 'scheduled' => 0, 'status' => 1, 'expected' => 'not required', 'message' => 'When scheduled publishing is required and an existing published, unscheduled node is edited, entering a date in the publish on field is not required.'], ['id' => 4, 'required' => 'publish', 'operation' => 'edit', 'scheduled' => 1, 'status' => 0, 'expected' => 'required', 'message' => 'When scheduled publishing is required and an existing unpublished, scheduled node is edited, entering a date in the publish on field is required.'], ['id' => 5, 'required' => 'publish', 'operation' => 'edit', 'scheduled' => 0, 'status' => 0, 'expected' => 'not required', 'message' => 'When scheduled publishing is required and an existing unpublished, unscheduled node is edited, entering a date in the publish on field is not required.'], ['id' => 6, 'required' => 'unpublish', 'operation' => 'add', 'status' => 0, 'expected' => 'required', 'message' => 'When scheduled unpublishing is required and a new unpublished node is created, entering a date in the unpublish on field is required.'], ['id' => 7, 'required' => 'unpublish', 'operation' => 'add', 'status' => 1, 'expected' => 'required', 'message' => 'When scheduled unpublishing is required and a new published node is created, entering a date in the unpublish on field is required.'], ['id' => 8, 'required' => 'unpublish', 'operation' => 'edit', 'scheduled' => 0, 'status' => 1, 'expected' => 'required', 'message' => 'When scheduled unpublishing is required and an existing published, unscheduled node is edited, entering a date in the unpublish on field is required.'], ['id' => 9, 'required' => 'unpublish', 'operation' => 'edit', 'scheduled' => 1, 'status' => 0, 'expected' => 'required', 'message' => 'When scheduled unpublishing is required and an existing unpublished, scheduled node is edited, entering a date in the unpublish on field is required.'], ['id' => 10, 'required' => 'unpublish', 'operation' => 'edit', 'scheduled' => 0, 'status' => 0, 'expected' => 'not required', 'message' => 'When scheduled unpublishing is required and an existing unpublished, unscheduled node is edited, entering a date in the unpublish on field is not required.']];
     $node_type = NodeType::load('page');
     $fields = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
     foreach ($test_cases as $test_case) {
         // Set required (un)publishing as stipulated by the test case.
         if (!empty($test_case['required'])) {
             $node_type->setThirdPartySetting('scheduler', 'publish_required', $test_case['required'] == 'publish')->setThirdPartySetting('scheduler', 'unpublish_required', $test_case['required'] == 'unpublish')->save();
         }
         // To assist viewing and analysing the generated test result pages create
         // a text string showing all the test case parameters.
         $title_data = [];
         foreach ($test_case as $key => $value) {
             if ($key != 'message') {
                 $title_data[] = $key . ' = ' . $value;
             }
         }
         $title = implode(', ', $title_data);
         // If the test case requires editing a node, we need to create one first.
         if ($test_case['operation'] == 'edit') {
             // Note: The key names in the $options parameter for drupalCreateNode()
             // are the plain field names i.e. 'title' not title[0][value]
             $options = ['title' => $title, 'type' => 'page', 'status' => $test_case['status'], 'publish_on' => !empty($test_case['scheduled']) ? strtotime('+1 day') : NULL];
             $node = $this->drupalCreateNode($options);
             // Define the path and button to use for editing the node.
             $path = 'node/' . $node->id() . '/edit';
             $button_text = $node->status->value ? t('Save and keep published') : t('Save and keep unpublished');
         } else {
             // Set the default status, used when testing creation of the new node.
             $fields['status']->getConfig('page')->setDefaultValue($test_case['status'])->save();
             // Define the path and button to use for creating the node.
             $path = 'node/add/page';
             $button_text = t('Save and publish');
         }
         // Make sure that both date fields are empty so we can check if they throw
         // validation errors when the fields are required.
         $edit = ['title[0][value]' => $title, 'publish_on[0][value][date]' => '', 'publish_on[0][value][time]' => '', 'unpublish_on[0][value][date]' => '', 'unpublish_on[0][value][time]' => ''];
         $this->drupalPostForm($path, $edit, $button_text);
         // Check for the expected result.
         switch ($test_case['expected']) {
             case 'required':
                 $string = t('The %name date is required.', ['%name' => ucfirst($test_case['required']) . ' on']);
                 $this->assertRaw($string, $test_case['id'] . '. ' . $test_case['message']);
                 break;
             case 'not required':
                 $string = '@type %title has been ' . ($test_case['operation'] == 'add' ? 'created' : 'updated') . '.';
                 $args = ['@type' => 'Basic page', '%title' => $title];
                 // @codingStandardsIgnoreStart
                 $this->assertRaw(t($string, $args), $test_case['id'] . '. ' . $test_case['message']);
                 // @codingStandardsIgnoreEnd
                 break;
         }
     }
 }
示例#10
0
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     parent::setUp();
     // Create Article node type.
     $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
     $this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('node');
     node_access_test_add_field(NodeType::load('article'));
     // 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);
 }
 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();
 }
示例#12
0
 /**
  * Test event types in UI.
  */
 function testEventType()
 {
     $web_user = $this->drupalCreateUser(['administer event types', 'access administration pages']);
     $this->drupalLogin($web_user);
     // Create and delete the testing event type.
     $event_bundle = $this->drupalCreateContentType();
     $event_type = $this->createEventType($event_bundle);
     $this->drupalGet('admin/structure/rng/event_types/manage/' . $event_type->id() . '/edit');
     $event_type->delete();
     $event_bundle->delete();
     // Event types button on admin.
     $this->drupalGet('admin/structure');
     $this->assertLinkByHref(Url::fromRoute('rng.event_type.overview')->toString());
     $this->assertRaw('Manage which entity bundles are designated as events.', 'Button shows in administration.');
     // No events.
     $this->assertEqual(0, count(EventType::loadMultiple()), 'There are no event type entities.');
     $this->drupalGet('admin/structure/rng/event_types');
     $this->assertRaw('No event types found.', 'Event Type list is empty');
     // There are no courier contexts.
     $this->assertEqual(0, count(CourierContext::loadMultiple()), 'There are no courier context entities.');
     // Local action.
     $this->assertLinkByHref(Url::fromRoute('entity.event_type.add')->toString());
     // Add.
     $t_args = ['%label' => 'node.event'];
     $edit = [];
     $this->drupalPostForm('admin/structure/rng/event_types/add', $edit, t('Save'));
     /** @var \Drupal\node\NodeTypeInterface $node_type */
     $node_type = NodeType::load('event');
     $this->assertEqual(1, count(EventType::loadMultiple()), 'Event type exists in database.');
     $this->assertRaw(t('The content type <a href=":url">%label</a> has been added.', ['%label' => $node_type->label(), ':url' => $node_type->toUrl()->toString()]), 'Node was created for Event Type');
     $this->assertRaw(t('%label event type added.', $t_args), 'Event Type created');
     // Courier context created?
     $this->assertTrue(CourierContext::load('rng_registration_node'), 'Courier context entity created for this event type\' entity type.');
     // Event type list.
     $this->assertUrl('admin/structure/rng/event_types', [], 'Browser was redirected to event type list.');
     $this->assertRaw('<td>Content: event</td>', 'Event Type shows in list');
     $options = ['node_type' => 'event'];
     $this->assertLinkByHref(Url::fromRoute("entity.node.field_ui_fields", $options)->toString());
     // Edit form.
     $edit = [];
     $this->drupalPostForm('admin/structure/rng/event_types/manage/node.event/edit', $edit, t('Save'));
     $this->assertRaw(t('%label event type updated.', $t_args), 'Event Type edit form saved');
     // Delete form.
     $this->drupalGet('admin/structure/rng/event_types/manage/node.event/delete');
     $this->assertRaw('Are you sure you want to delete event type node.event?', 'Event Type delete form rendered.');
     $this->drupalPostForm('admin/structure/rng/event_types/manage/node.event/delete', [], t('Delete'));
     $this->assertRaw(t('Event type %label was deleted.', $t_args), 'Event Type delete form saved');
     $this->assertEqual(0, count(EventType::loadMultiple()), 'Event type deleted from database.');
     // @todo: ensure conditional on form omits node/existing radios
     // @todo create event type with custom entity
 }
 /**
  * {@inheritdoc}
  */
 public function getDerivativeDefinitions($base_plugin_definition)
 {
     $node_types = simplenews_get_content_types();
     $node_type = reset($node_types);
     if (count($node_types) == 1) {
         $label = NodeType::load($node_type)->label();
         $this->derivatives[$node_type] = $base_plugin_definition;
         $this->derivatives[$node_type]['title'] = new TranslationWrapper('Add @label', array('@label' => $label));
         $this->derivatives[$node_type]['route_parameters'] = array('node_type' => $node_type);
     } elseif (count($node_types) > 1) {
         $base_plugin_definition['route_name'] = 'node.add_page';
         $base_plugin_definition['title'] = new TranslationWrapper('Add content');
         $this->derivatives[] = $base_plugin_definition;
     }
     return parent::getDerivativeDefinitions($base_plugin_definition);
 }
 /**
  * Tests a single node type.
  *
  * @dataProvider testNodeTypeDataProvider
  *
  * @param string $id
  *   The node type ID.
  * @param string $label
  *   The expected label.
  * @param string $description
  *   The expected node type description.
  * @param string $help
  *   The expected help text.
  */
 protected function assertEntity($id, $label, $description, $help, $display_submitted, $new_revision, $body_label = NULL)
 {
     /** @var \Drupal\node\NodeTypeInterface $entity */
     $entity = NodeType::load($id);
     $this->assertTrue($entity instanceof NodeTypeInterface);
     $this->assertIdentical($label, $entity->label());
     $this->assertIdentical($description, $entity->getDescription());
     $this->assertIdentical($help, $entity->getHelp());
     $this->assertIdentical($display_submitted, $entity->displaySubmitted(), 'Submission info is displayed');
     $this->assertIdentical($new_revision, $entity->isNewRevision(), 'Is a new revision');
     if ($body_label) {
         /** @var \Drupal\field\FieldConfigInterface $body */
         $body = FieldConfig::load('node.' . $id . '.body');
         $this->assertTrue($body instanceof FieldConfigInterface);
         $this->assertIdentical($body_label, $body->label());
     }
 }
 /**
  * Verifies that content without prior moderation information can be moderated.
  */
 public function testLegacyContent()
 {
     $node_type = NodeType::create(['type' => 'example']);
     $node_type->save();
     $node = Node::create(['type' => 'example', 'title' => 'Test title']);
     $node->save();
     // Enable moderation for Articles.
     /** @var NodeType $node_type */
     $node_type = NodeType::load('example');
     $node_type->setThirdPartySetting('workbench_moderation', 'enabled', TRUE);
     $node_type->setThirdPartySetting('workbench_moderation', 'allowed_moderation_states', ['draft', 'needs_review', 'published']);
     $node_type->setThirdPartySetting('workbench_moderation', 'default_moderation_state', 'draft');
     $node_type->save();
     // Having no previous state should not break validation.
     $violations = $node->validate();
     $this->assertCount(0, $violations);
 }
示例#16
0
 /**
  * Tests the book_system_info_alter() method.
  */
 public function testBookUninstall()
 {
     // No nodes exist.
     $module_data = _system_rebuild_module_data();
     $this->assertFalse(isset($module_data['book']->info['required']), 'The book module is not required.');
     $content_type = NodeType::create(array('type' => $this->randomMachineName(), 'name' => $this->randomString()));
     $content_type->save();
     $book_config = $this->config('book.settings');
     $allowed_types = $book_config->get('allowed_types');
     $allowed_types[] = $content_type->id();
     $book_config->set('allowed_types', $allowed_types)->save();
     $node = Node::create(array('type' => $content_type->id()));
     $node->book['bid'] = 'new';
     $node->save();
     // One node in a book but not of type book.
     $module_data = _system_rebuild_module_data();
     $this->assertTrue($module_data['book']->info['required'], 'The book module is required.');
     $this->assertEqual($module_data['book']->info['explanation'], t('To uninstall Book, delete all content that is part of a book.'));
     $book_node = Node::create(array('type' => 'book'));
     $book_node->book['bid'] = FALSE;
     $book_node->save();
     // Two nodes, one in a book but not of type book and one book node (which is
     // not in a book).
     $module_data = _system_rebuild_module_data();
     $this->assertTrue($module_data['book']->info['required'], 'The book module is required.');
     $this->assertEqual($module_data['book']->info['explanation'], t('To uninstall Book, delete all content that is part of a book.'));
     $node->delete();
     // One node of type book but not actually part of a book.
     $module_data = _system_rebuild_module_data();
     $this->assertTrue($module_data['book']->info['required'], 'The book module is required.');
     $this->assertEqual($module_data['book']->info['explanation'], t('To uninstall Book, delete all content that has the Book content type.'));
     $book_node->delete();
     // No nodes exist therefore the book module is not required.
     $module_data = _system_rebuild_module_data();
     $this->assertFalse(isset($module_data['book']->info['required']), 'The book module is not required.');
     $node = Node::create(array('type' => $content_type->id()));
     $node->save();
     // One node exists but is not part of a book therefore the book module is
     // not required.
     $module_data = _system_rebuild_module_data();
     $this->assertFalse(isset($module_data['book']->info['required']), 'The book module is not required.');
     // Uninstall the Book module and check the node type is deleted.
     \Drupal::service('module_installer')->uninstall(array('book'));
     $this->assertNull(NodeType::load('book'), "The book node type does not exist.");
 }
 /**
  * Tests rebuilding the node access permissions table with content.
  */
 public function testNodeAccessRebuildNodeGrants()
 {
     \Drupal::service('module_installer')->install(['node_access_test']);
     \Drupal::state()->set('node_access_test.private', TRUE);
     node_access_test_add_field(NodeType::load('page'));
     $this->resetAll();
     // Create 30 nodes so that _node_access_rebuild_batch_operation() has to run
     // more than once.
     for ($i = 0; $i < 30; $i++) {
         $nodes[] = $this->drupalCreateNode(array('uid' => $this->webUser->id(), 'private' => [['value' => 1]]));
     }
     /** @var \Drupal\node\NodeGrantDatabaseStorageInterface $grant_storage */
     $grant_storage = \Drupal::service('node.grant_storage');
     // Default realm access and node records are present.
     foreach ($nodes as $node) {
         $this->assertTrue($node->private->value);
         $this->assertTrue($grant_storage->access($node, 'view', $this->webUser)->isAllowed(), 'Prior to rebuilding node access the grant storage returns allowed for the node author.');
         $this->assertTrue($grant_storage->access($node, 'view', $this->adminUser)->isAllowed(), 'Prior to rebuilding node access the grant storage returns allowed for the admin user.');
     }
     $this->assertEqual(1, \Drupal::service('node.grant_storage')->checkAll($this->webUser), 'There is an all realm access record');
     $this->assertTrue(\Drupal::state()->get('node.node_access_needs_rebuild'), 'Node access permissions need to be rebuilt');
     // Rebuild permissions.
     $this->drupalGet('admin/reports/status');
     $this->clickLink(t('Rebuild permissions'));
     $this->drupalPostForm(NULL, array(), t('Rebuild permissions'));
     $this->assertText(t('The content access permissions have been rebuilt.'));
     // Test if the rebuild by user that cannot bypass node access and does not
     // have access to the nodes has been successful.
     $this->assertFalse($this->adminUser->hasPermission('bypass node access'));
     $this->assertNull(\Drupal::state()->get('node.node_access_needs_rebuild'), 'Node access permissions have been rebuilt');
     foreach ($nodes as $node) {
         $this->assertTrue($grant_storage->access($node, 'view', $this->webUser)->isAllowed(), 'After rebuilding node access the grant storage returns allowed for the node author.');
         $this->assertFalse($grant_storage->access($node, 'view', $this->adminUser)->isForbidden(), 'After rebuilding node access the grant storage returns forbidden for the admin user.');
     }
     $this->assertFalse(\Drupal::service('node.grant_storage')->checkAll($this->webUser), 'There is no all realm access record');
     // Test an anonymous node access rebuild from code.
     $this->drupalLogout();
     node_access_rebuild();
     foreach ($nodes as $node) {
         $this->assertTrue($grant_storage->access($node, 'view', $this->webUser)->isAllowed(), 'After rebuilding node access the grant storage returns allowed for the node author.');
         $this->assertFalse($grant_storage->access($node, 'view', $this->adminUser)->isForbidden(), 'After rebuilding node access the grant storage returns forbidden for the admin user.');
     }
     $this->assertFalse(\Drupal::service('node.grant_storage')->checkAll($this->webUser), 'There is no all realm access record');
 }
 /**
  * Tests creating a content type during config import.
  */
 public function testImportCreate()
 {
     $node_type_id = 'import';
     $node_type_config_name = "node.type.{$node_type_id}";
     // Simulate config data to import.
     $active = $this->container->get('config.storage');
     $staging = $this->container->get('config.storage.staging');
     $this->copyConfig($active, $staging);
     // Manually add new node type.
     $src_dir = drupal_get_path('module', 'node_test_config') . '/staging';
     $target_dir = $this->configDirectories[CONFIG_STAGING_DIRECTORY];
     $this->assertTrue(file_unmanaged_copy("{$src_dir}/{$node_type_config_name}.yml", "{$target_dir}/{$node_type_config_name}.yml"));
     // Import the content of the staging directory.
     $this->configImporter()->import();
     // Check that the content type was created.
     $node_type = NodeType::load($node_type_id);
     $this->assertTrue($node_type, 'Import node type from staging was created.');
     $this->assertFalse(FieldConfig::loadByName('node', $node_type_id, 'body'));
 }
 /**
  * {@inheritdoc}
  */
 public function setUp()
 {
     parent::setUp();
     // Load the custom node type and check it .
     $this->custom_type = 'scheduler_api_test';
     $this->nodetype = NodeType::load($this->custom_type);
     if ($this->nodetype) {
         $this->pass('Custom node type ' . $this->custom_type . ' "' . $this->nodetype->get('name') . '"  created during install');
         // Do not need to enable this node type for scheduler as that is already
         // pre-configured in node.type.scheduler_api_test.yml
     } else {
         $this->fail('*** Custom node type ' . $this->custom_type . ' does not exist. Testing abandoned ***');
         return;
     }
     // Create a web user for this content type.
     $this->webUser = $this->drupalCreateUser(['create ' . $this->custom_type . ' content', 'edit any ' . $this->custom_type . ' content', 'schedule publishing of nodes']);
     // Create node_storage property.
     $this->node_storage = $this->container->get('entity.manager')->getStorage('node');
 }
示例#20
0
 /**
  * Tests that field overrides work as expected.
  */
 public function testFieldOverrides()
 {
     if (!NodeType::load('ponies')) {
         NodeType::create(['name' => 'Ponies', 'type' => 'ponies'])->save();
     }
     $override = BaseFieldOverride::loadByName('node', 'ponies', 'uid');
     if ($override) {
         $override->delete();
     }
     $uid_field = \Drupal::entityManager()->getBaseFieldDefinitions('node')['uid'];
     $config = $uid_field->getConfig('ponies');
     $config->save();
     $this->assertEqual($config->get('default_value_callback'), 'Drupal\\node\\Entity\\Node::getCurrentUserId');
     /** @var \Drupal\node\NodeInterface $node */
     $node = Node::create(['type' => 'ponies']);
     $owner = $node->getOwner();
     $this->assertTrue($owner instanceof UserInterface);
     $this->assertEqual($owner->id(), $this->user->id());
 }
示例#21
0
 /**
  * Tests creating a content type during config import.
  */
 public function testImportCreate()
 {
     $node_type_id = 'import';
     $node_type_config_name = "node.type.{$node_type_id}";
     // Simulate config data to import.
     $active = $this->container->get('config.storage');
     $sync = $this->container->get('config.storage.sync');
     $this->copyConfig($active, $sync);
     // Manually add new node type.
     $src_dir = __DIR__ . '/../../../modules/node_test_config/sync';
     $target_dir = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
     $this->assertTrue(file_unmanaged_copy("{$src_dir}/{$node_type_config_name}.yml", "{$target_dir}/{$node_type_config_name}.yml"));
     // Import the content of the sync directory.
     $this->configImporter()->import();
     // Check that the content type was created.
     $node_type = NodeType::load($node_type_id);
     $this->assertTrue($node_type, 'Import node type from sync was created.');
     $this->assertFalse(FieldConfig::loadByName('node', $node_type_id, 'body'));
 }
示例#22
0
 /**
  * Tests importing an updated content type.
  */
 public function testImportChange()
 {
     $node_type_id = 'default';
     $node_type_config_name = "node.type.{$node_type_id}";
     // Simulate config data to import:
     // - a modified version (modified label) of the node type config.
     $active = $this->container->get('config.storage');
     $sync = $this->container->get('config.storage.sync');
     $this->copyConfig($active, $sync);
     $node_type = $active->read($node_type_config_name);
     $new_label = 'Test update import field';
     $node_type['name'] = $new_label;
     // Save as files in the sync directory.
     $sync->write($node_type_config_name, $node_type);
     // Import the content of the sync directory.
     $this->configImporter()->import();
     // Check that the updated config was correctly imported.
     $node_type = NodeType::load($node_type_id);
     $this->assertEqual($node_type->label(), $new_label, 'Node type name has been updated.');
 }
 /**
  * Creates a custom content type based on default settings.
  *
  * @param array $values
  *   An array of settings to change from the defaults.
  *   Example: 'type' => 'foo'.
  *
  * @return \Drupal\node\Entity\NodeType
  *   Created content type.
  */
 protected function createContentType(array $values = array())
 {
     // Find a non-existent random type name.
     if (!isset($values['type'])) {
         do {
             $id = strtolower($this->randomMachineName(8));
         } while (NodeType::load($id));
     } else {
         $id = $values['type'];
     }
     $values += array('type' => $id, 'name' => $id);
     $type = NodeType::create($values);
     $status = $type->save();
     node_add_body_field($type);
     if ($this instanceof \PHPUnit_Framework_TestCase) {
         $this->assertSame($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', array('%type' => $type->id())))->__toString());
     } else {
         $this->assertEqual($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', array('%type' => $type->id())))->__toString());
     }
     return $type;
 }
 /**
  * Tests date input is displayed as vertical tab or an expandable fieldset.
  */
 public function testFieldsDisplay()
 {
     /** @var NodeTypeInterface $node_type */
     $node_type = NodeType::load('page');
     $this->drupalLogin($this->adminUser);
     // Check that the dates are shown in a vertical tab by default.
     $this->drupalGet('node/add/page');
     $this->assertTrue($this->xpath('//div[contains(@class, "form-type-vertical-tabs")]//details[@id = "edit-scheduler-settings"]'), 'By default the scheduler dates are shown in a vertical tab.');
     // Check that the dates are shown as a fieldset when configured to do so.
     $node_type->setThirdPartySetting('scheduler', 'fields_display_mode', 'fieldset')->save();
     $this->drupalGet('node/add/page');
     $this->assertFalse($this->xpath('//div[contains(@class, "form-type-vertical-tabs")]//details[@id = "edit-scheduler-settings"]'), 'The scheduler dates are not shown in a vertical tab when they are configured to show as a fieldset.');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings"]'), 'The scheduler dates are shown in a fieldset when they are configured to show as a fieldset.');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings" and not(@open = "open")]'), 'The scheduler dates fieldset is collapsed by default.');
     // Check that the fieldset is expanded if either of the scheduling dates
     // are required.
     $node_type->setThirdPartySetting('scheduler', 'publish_required', TRUE)->save();
     $this->drupalGet('node/add/page');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings" and @open = "open"]'), 'The scheduler dates are shown in an expanded fieldset when the publish-on date is required.');
     $node_type->setThirdPartySetting('scheduler', 'publish_required', FALSE)->setThirdPartySetting('scheduler', 'unpublish_required', TRUE)->save();
     $this->drupalGet('node/add/page');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings" and @open = "open"]'), 'The scheduler dates are shown in an expanded fieldset when the unpublish-on date is required.');
     // Check that the fieldset is expanded if the 'always' option is set.
     $node_type->setThirdPartySetting('scheduler', 'publish_required', FALSE)->setThirdPartySetting('scheduler', 'unpublish_required', FALSE)->setThirdPartySetting('scheduler', 'expand_fieldset', 'always')->save();
     $this->drupalGet('node/add/page');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings" and @open = "open"]'), 'The scheduler dates are shown in an expanded fieldset when the option to always expand is turned on.');
     // Check that the fieldset is expanded if the node already has a publish-on
     // date. This requires editing an existing scheduled node.
     $node_type->setThirdPartySetting('scheduler', 'expand_fieldset', 'when_required')->save();
     $options = ['title' => 'Contains Publish-on date ' . $this->randomMachineName(10), 'type' => 'page', 'publish_on' => strtotime('+1 day')];
     $node = $this->drupalCreateNode($options);
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings" and @open = "open"]'), 'The scheduler dates are shown in an expanded fieldset when a publish-on date already exists.');
     // Check that the fieldset is expanded if the node has an unpublish-on date.
     $options = ['title' => 'Contains Unpublish-on date ' . $this->randomMachineName(10), 'type' => 'page', 'unpublish_on' => strtotime('+1 day')];
     $node = $this->drupalCreateNode($options);
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->assertTrue($this->xpath('//details[@id = "edit-scheduler-settings" and @open = "open"]'), 'The scheduler dates are shown in an expanded fieldset when an unpublish-on date already exists.');
 }
示例#25
0
 /**
  * Checks whether emails get sent when a user creates a new article node.
  */
 function testMandrillEmail()
 {
     $this->installEntitySchema('node');
     $this->installEntitySchema('user');
     \Drupal::service('module_installer')->install(array('dblog', 'field'));
     // Use the state system collector mail backend.
     $config = \Drupal::configFactory()->getEditable('system.mail');
     $mail_plugins = array('default' => 'test_mail_collector');
     $config->set('interface', $mail_plugins)->save();
     // Reset the state variable that holds sent messages.
     \Drupal::state()->set('system.test_mail_collector', array());
     // Create a user account and set it as the current user.
     $user = entity_create('user', array('uid' => 1, 'mail' => '*****@*****.**'));
     $user->save();
     \Drupal::currentUser()->setAccount($user);
     // Set the site email address.
     \Drupal::configFactory()->getEditable('system.site')->set('mail', '*****@*****.**')->save();
     // Create the article content type and add the body field to it.
     $type = array('type' => 'article', 'name' => 'Article');
     $type = entity_create('node_type', $type);
     $type->save();
     $article = NodeType::load('article');
     node_add_body_field($article);
     // Create a random article node.
     $title = $this->randomMachineName();
     $values = array('uid' => $user->id(), 'title' => $title, 'body' => [['value' => 'test_body']], 'type' => 'article');
     $node = entity_create('node', $values);
     $node->save();
     // Check the latest captured emails.
     $captured_emails = \Drupal::state()->get('system.test_mail_collector');
     $sent_message = end($captured_emails);
     $this->assertTrue(!empty($sent_message));
     $this->assertEqual($sent_message['id'], 'd8mail_node_insert', 'Correct mail id.');
     $this->assertEqual($sent_message['to'], '*****@*****.**', 'Correct mail to.');
     $this->assertEqual($sent_message['from'], '*****@*****.**', 'Correct mail from.');
     $this->assertEqual($sent_message['subject'], sprintf("Node created: %s", $title), 'Correct mail subject.');
     $this->assertEqual($sent_message['body'], 'test_body' . PHP_EOL, 'Correct mail body.');
 }
示例#26
0
 /**
  * Tests breadcrumbs on node and administrative paths.
  */
 function testBreadCrumbs()
 {
     // Prepare common base breadcrumb elements.
     $home = array('' => 'Home');
     $admin = $home + array('admin' => t('Administration'));
     $config = $admin + array('admin/config' => t('Configuration'));
     $type = 'article';
     // Verify Taxonomy administration breadcrumbs.
     $trail = $admin + array('admin/structure' => t('Structure'));
     $this->assertBreadcrumb('admin/structure/taxonomy', $trail);
     $trail += array('admin/structure/taxonomy' => t('Taxonomy'));
     $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags', $trail);
     $trail += array('admin/structure/taxonomy/manage/tags' => t('Tags'));
     $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/overview', $trail);
     $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/add', $trail);
     // Verify Menu administration breadcrumbs.
     $trail = $admin + array('admin/structure' => t('Structure'));
     $this->assertBreadcrumb('admin/structure/menu', $trail);
     $trail += array('admin/structure/menu' => t('Menus'));
     $this->assertBreadcrumb('admin/structure/menu/manage/tools', $trail);
     $trail += array('admin/structure/menu/manage/tools' => t('Tools'));
     $this->assertBreadcrumb("admin/structure/menu/link/node.add_page/edit", $trail);
     $this->assertBreadcrumb('admin/structure/menu/manage/tools/add', $trail);
     // Verify Node administration breadcrumbs.
     $trail = $admin + array('admin/structure' => t('Structure'), 'admin/structure/types' => t('Content types'));
     $this->assertBreadcrumb('admin/structure/types/add', $trail);
     $this->assertBreadcrumb("admin/structure/types/manage/{$type}", $trail);
     $trail += array("admin/structure/types/manage/{$type}" => t('Article'));
     $this->assertBreadcrumb("admin/structure/types/manage/{$type}/fields", $trail);
     $this->assertBreadcrumb("admin/structure/types/manage/{$type}/display", $trail);
     $trail_teaser = $trail + array("admin/structure/types/manage/{$type}/display" => t('Manage display'));
     $this->assertBreadcrumb("admin/structure/types/manage/{$type}/display/teaser", $trail_teaser);
     $this->assertBreadcrumb("admin/structure/types/manage/{$type}/delete", $trail);
     $trail += array("admin/structure/types/manage/{$type}/fields" => t('Manage fields'));
     $this->assertBreadcrumb("admin/structure/types/manage/{$type}/fields/node.{$type}.body", $trail);
     // Verify Filter text format administration breadcrumbs.
     $filter_formats = filter_formats();
     $format = reset($filter_formats);
     $format_id = $format->id();
     $trail = $config + array('admin/config/content' => t('Content authoring'));
     $this->assertBreadcrumb('admin/config/content/formats', $trail);
     $trail += array('admin/config/content/formats' => t('Text formats and editors'));
     $this->assertBreadcrumb('admin/config/content/formats/add', $trail);
     $this->assertBreadcrumb("admin/config/content/formats/manage/{$format_id}", $trail);
     // @todo Remove this part once we have a _title_callback, see
     //   https://www.drupal.org/node/2076085.
     $trail += array("admin/config/content/formats/manage/{$format_id}" => $format->label());
     $this->assertBreadcrumb("admin/config/content/formats/manage/{$format_id}/disable", $trail);
     // Verify node breadcrumbs (without menu link).
     $node1 = $this->drupalCreateNode();
     $nid1 = $node1->id();
     $trail = $home;
     $this->assertBreadcrumb("node/{$nid1}", $trail);
     // Also verify that the node does not appear elsewhere (e.g., menu trees).
     $this->assertNoLink($node1->getTitle());
     // Also verify that the node does not appear elsewhere (e.g., menu trees).
     $this->assertNoLink($node1->getTitle());
     $trail += array("node/{$nid1}" => $node1->getTitle());
     $this->assertBreadcrumb("node/{$nid1}/edit", $trail);
     // Verify that breadcrumb on node listing page contains "Home" only.
     $trail = array();
     $this->assertBreadcrumb('node', $trail);
     // Verify node breadcrumbs (in menu).
     // Do this separately for Main menu and Tools menu, since only the
     // latter is a preferred menu by default.
     // @todo Also test all themes? Manually testing led to the suspicion that
     //   breadcrumbs may differ, possibly due to theme overrides.
     $menus = array('main', 'tools');
     // Alter node type menu settings.
     $node_type = NodeType::load($type);
     $node_type->setThirdPartySetting('menu_ui', 'available_menus', $menus);
     $node_type->setThirdPartySetting('menu_ui', 'parent', 'tools:');
     $node_type->save();
     foreach ($menus as $menu) {
         // Create a parent node in the current menu.
         $title = $this->randomMachineName();
         $node2 = $this->drupalCreateNode(array('type' => $type, 'title' => $title, 'menu' => array('enabled' => 1, 'title' => 'Parent ' . $title, 'description' => '', 'menu_name' => $menu, 'parent' => '')));
         if ($menu == 'tools') {
             $parent = $node2;
         }
     }
     // Create a Tools menu link for 'node', move the last parent node menu
     // link below it, and verify a full breadcrumb for the last child node.
     $menu = 'tools';
     $edit = array('title[0][value]' => 'Root', 'link[0][uri]' => '/node');
     $this->drupalPostForm("admin/structure/menu/manage/{$menu}/add", $edit, t('Save'));
     $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => 'Root'));
     $link = reset($menu_links);
     $edit = array('menu[menu_parent]' => $link->getMenuName() . ':' . $link->getPluginId());
     $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published'));
     $expected = array("node" => $link->getTitle());
     $trail = $home + $expected;
     $tree = $expected + array('node/' . $parent->id() => $parent->menu['title']);
     $trail += array('node/' . $parent->id() => $parent->menu['title']);
     // Add a taxonomy term/tag to last node, and add a link for that term to the
     // Tools menu.
     $tags = array('Drupal' => array(), 'Breadcrumbs' => array());
     $edit = array('field_tags[target_id]' => implode(',', array_keys($tags)));
     $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published'));
     // Put both terms into a hierarchy Drupal » Breadcrumbs. Required for both
     // the menu links and the terms itself, since taxonomy_term_page() resets
     // the breadcrumb based on taxonomy term hierarchy.
     $parent_tid = 0;
     foreach ($tags as $name => $null) {
         $terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => $name));
         $term = reset($terms);
         $tags[$name]['term'] = $term;
         if ($parent_tid) {
             $edit = array('parent[]' => array($parent_tid));
             $this->drupalPostForm("taxonomy/term/{$term->id()}/edit", $edit, t('Save'));
         }
         $parent_tid = $term->id();
     }
     $parent_mlid = '';
     foreach ($tags as $name => $data) {
         $term = $data['term'];
         $edit = array('title[0][value]' => "{$name} link", 'link[0][uri]' => "/taxonomy/term/{$term->id()}", 'menu_parent' => "{$menu}:{$parent_mlid}", 'enabled[value]' => 1);
         $this->drupalPostForm("admin/structure/menu/manage/{$menu}/add", $edit, t('Save'));
         $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $edit['title[0][value]'], 'link.uri' => 'internal:/taxonomy/term/' . $term->id()));
         $tags[$name]['link'] = reset($menu_links);
         $parent_mlid = $tags[$name]['link']->getPluginId();
     }
     // Verify expected breadcrumbs for menu links.
     $trail = $home;
     $tree = array();
     // Logout the user because we want to check the active class as well, which
     // is just rendered as anonymous user.
     $this->drupalLogout();
     foreach ($tags as $name => $data) {
         $term = $data['term'];
         /** @var \Drupal\menu_link_content\MenuLinkContentInterface $link */
         $link = $data['link'];
         $link_path = $link->getUrlObject()->getInternalPath();
         $tree += array($link_path => $link->getTitle());
         $this->assertBreadcrumb($link_path, $trail, $term->getName(), $tree);
         $this->assertEscaped($parent->getTitle(), 'Tagged node found.');
         // Additionally make sure that this link appears only once; i.e., the
         // untranslated menu links automatically generated from menu router items
         // ('taxonomy/term/%') should never be translated and appear in any menu
         // other than the breadcrumb trail.
         $elements = $this->xpath('//nav[@id=:menu]/descendant::a[@href=:href]', array(':menu' => 'block-bartik-tools', ':href' => Url::fromUri('base:' . $link_path)->toString()));
         $this->assertTrue(count($elements) == 1, "Link to {$link_path} appears only once.");
         // Next iteration should expect this tag as parent link.
         // Note: Term name, not link name, due to taxonomy_term_page().
         $trail += array($link_path => $term->getName());
     }
     // Verify breadcrumbs on user and user/%.
     // We need to log back in and out below, and cannot simply grant the
     // 'administer users' permission, since user_page() makes your head explode.
     user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access user profiles'));
     // Verify breadcrumb on front page.
     $this->assertBreadcrumb('<front>', array());
     // Verify breadcrumb on user pages (without menu link) for anonymous user.
     $trail = $home;
     $this->assertBreadcrumb('user', $trail, t('Log in'));
     $this->assertBreadcrumb('user/' . $this->adminUser->id(), $trail, $this->adminUser->getUsername());
     // Verify breadcrumb on user pages (without menu link) for registered users.
     $this->drupalLogin($this->adminUser);
     $trail = $home;
     $this->assertBreadcrumb('user', $trail, $this->adminUser->getUsername());
     $this->assertBreadcrumb('user/' . $this->adminUser->id(), $trail, $this->adminUser->getUsername());
     $trail += array('user/' . $this->adminUser->id() => $this->adminUser->getUsername());
     $this->assertBreadcrumb('user/' . $this->adminUser->id() . '/edit', $trail, $this->adminUser->getUsername());
     // Create a second user to verify breadcrumb on user pages again.
     $this->webUser = $this->drupalCreateUser(array('administer users', 'access user profiles'));
     $this->drupalLogin($this->webUser);
     // Verify correct breadcrumb and page title on another user's account pages.
     $trail = $home;
     $this->assertBreadcrumb('user/' . $this->adminUser->id(), $trail, $this->adminUser->getUsername());
     $trail += array('user/' . $this->adminUser->id() => $this->adminUser->getUsername());
     $this->assertBreadcrumb('user/' . $this->adminUser->id() . '/edit', $trail, $this->adminUser->getUsername());
     // Verify correct breadcrumb and page title when viewing own user account.
     $trail = $home;
     $this->assertBreadcrumb('user/' . $this->webUser->id(), $trail, $this->webUser->getUsername());
     $trail += array('user/' . $this->webUser->id() => $this->webUser->getUsername());
     $this->assertBreadcrumb('user/' . $this->webUser->id() . '/edit', $trail, $this->webUser->getUsername());
     // Create an only slightly privileged user being able to access site reports
     // but not administration pages.
     $this->webUser = $this->drupalCreateUser(array('access site reports'));
     $this->drupalLogin($this->webUser);
     // Verify that we can access recent log entries, there is a corresponding
     // page title, and that the breadcrumb is just the Home link (because the
     // user is not able to access "Administer".
     $trail = $home;
     $this->assertBreadcrumb('admin', $trail, t('Access denied'));
     $this->assertResponse(403);
     // Since the 'admin' path is not accessible, we still expect only the Home
     // link.
     $this->assertBreadcrumb('admin/reports', $trail, t('Reports'));
     $this->assertNoResponse(403);
     // Since the Reports page is accessible, that will show.
     $trail += array('admin/reports' => t('Reports'));
     $this->assertBreadcrumb('admin/reports/dblog', $trail, t('Recent log messages'));
     $this->assertNoResponse(403);
     // Ensure that the breadcrumb is safe against XSS.
     $this->drupalGet('menu-test/breadcrumb1/breadcrumb2/breadcrumb3');
     $this->assertRaw('<script>alert(12);</script>');
     $this->assertEscaped('<script>alert(123);</script>');
 }
示例#27
0
 /**
  * Creates a content type.
  *
  * Attempts to create a content type with ID $prefix, $prefix_1, $prefix_2...
  *
  * @param string $prefix
  *   A string prefix for the node type ID.
  *
  * @return \Drupal\node\NodeTypeInterface
  *   A node type entity.
  */
 private function createContentType($prefix)
 {
     // Generate a unique ID.
     $i = 0;
     $separator = '_';
     $id = $prefix;
     while (NodeType::load($id)) {
         $i++;
         $id = $prefix . $separator . $i;
     }
     $node_type = NodeType::create(['type' => $id, 'name' => $id]);
     $node_type->save();
     return $node_type;
 }
 /**
  * Tests the loading of Quick Edit when a user does have access to it.
  *
  * Also ensures lazy loading of in-place editors works.
  */
 public function testUserWithPermission()
 {
     $this->drupalLogin($this->editorUser);
     $this->drupalGet('node/1');
     // Library and in-place editors.
     $settings = $this->getDrupalSettings();
     $libraries = explode(',', $settings['ajaxPageState']['libraries']);
     $this->assertTrue(in_array('quickedit/quickedit', $libraries), 'Quick Edit library loaded.');
     $this->assertFalse(in_array('quickedit/quickedit.inPlaceEditor.form', $libraries), "'form' in-place editor not loaded.");
     // HTML annotation must always exist (to not break the render cache).
     $this->assertRaw('data-quickedit-entity-id="node/1"');
     $this->assertRaw('data-quickedit-field-id="node/1/body/en/full"');
     // There should be only one revision so far.
     $node = Node::load(1);
     $vids = \Drupal::entityManager()->getStorage('node')->revisionIds($node);
     $this->assertIdentical(1, count($vids), 'The node has only one revision.');
     $original_log = $node->revision_log->value;
     // Retrieving the metadata should result in a 200 JSON response.
     $htmlPageDrupalSettings = $this->drupalSettings;
     $post = array('fields[0]' => 'node/1/body/en/full');
     $response = $this->drupalPostWithFormat('quickedit/metadata', 'json', $post);
     $this->assertResponse(200);
     $expected = array('node/1/body/en/full' => array('label' => 'Body', 'access' => TRUE, 'editor' => 'form'));
     $this->assertIdentical(Json::decode($response), $expected, 'The metadata HTTP request answers with the correct JSON response.');
     // Restore drupalSettings to build the next requests; simpletest wipes them
     // after a JSON response.
     $this->drupalSettings = $htmlPageDrupalSettings;
     // Retrieving the attachments should result in a 200 response, containing:
     //  1. a settings command with useless metadata: AjaxController is dumb
     //  2. an insert command that loads the required in-place editors
     $post = array('editors[0]' => 'form') + $this->getAjaxPageStatePostData();
     $response = $this->drupalPost('quickedit/attachments', 'application/vnd.drupal-ajax', $post);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(2, count($ajax_commands), 'The attachments HTTP request results in two AJAX commands.');
     // First command: settings.
     $this->assertIdentical('settings', $ajax_commands[0]['command'], 'The first AJAX command is a settings command.');
     // Second command: insert libraries into DOM.
     $this->assertIdentical('insert', $ajax_commands[1]['command'], 'The second AJAX command is an append command.');
     $this->assertTrue(in_array('quickedit/quickedit.inPlaceEditor.form', explode(',', $ajax_commands[0]['settings']['ajaxPageState']['libraries'])), 'The quickedit.inPlaceEditor.form library is loaded.');
     // Retrieving the form for this field should result in a 200 response,
     // containing only a quickeditFieldForm command.
     $post = array('nocssjs' => 'true', 'reset' => 'true') + $this->getAjaxPageStatePostData();
     $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
     $this->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
     $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
     // Prepare form values for submission. drupalPostAjaxForm() is not suitable
     // for handling pages with JSON responses, so we need our own solution here.
     $form_tokens_found = preg_match('/\\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match) && preg_match('/\\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match);
     $this->assertTrue($form_tokens_found, 'Form tokens found in output.');
     if ($form_tokens_found) {
         $edit = array('body[0][summary]' => '', 'body[0][value]' => '<p>Fine thanks.</p>', 'body[0][format]' => 'filtered_html', 'op' => t('Save'));
         $post = array('form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1]);
         $post += $edit + $this->getAjaxPageStatePostData();
         // Submit field form and check response. This should store the updated
         // entity in PrivateTempStore on the server.
         $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
         $this->assertResponse(200);
         $ajax_commands = Json::decode($response);
         $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
         $this->assertIdentical('quickeditFieldFormSaved', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldFormSaved command.');
         $this->assertTrue(strpos($ajax_commands[0]['data'], 'Fine thanks.'), 'Form value saved and printed back.');
         $this->assertIdentical($ajax_commands[0]['other_view_modes'], array(), 'Field was not rendered in any other view mode.');
         // Ensure the text on the original node did not change yet.
         $this->drupalGet('node/1');
         $this->assertText('How are you?');
         // Save the entity by moving the PrivateTempStore values to entity storage.
         $post = array('nocssjs' => 'true');
         $response = $this->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post);
         $this->assertResponse(200);
         $ajax_commands = Json::decode($response);
         $this->assertIdentical(1, count($ajax_commands), 'The entity submission HTTP request results in one AJAX command.');
         $this->assertIdentical('quickeditEntitySaved', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditEntitySaved command.');
         $this->assertIdentical($ajax_commands[0]['data']['entity_type'], 'node', 'Saved entity is of type node.');
         $this->assertIdentical($ajax_commands[0]['data']['entity_id'], '1', 'Entity id is 1.');
         // Ensure the text on the original node did change.
         $this->drupalGet('node/1');
         $this->assertText('Fine thanks.');
         // Ensure no new revision was created and the log message is unchanged.
         $node = Node::load(1);
         $vids = \Drupal::entityManager()->getStorage('node')->revisionIds($node);
         $this->assertIdentical(1, count($vids), 'The node has only one revision.');
         $this->assertIdentical($original_log, $node->revision_log->value, 'The revision log message is unchanged.');
         // Now configure this node type to create new revisions automatically,
         // then again retrieve the field form, fill it, submit it (so it ends up
         // in PrivateTempStore) and then save the entity. Now there should be two
         // revisions.
         $node_type = NodeType::load('article');
         $node_type->setNewRevision(TRUE);
         $node_type->save();
         // Retrieve field form.
         $post = array('nocssjs' => 'true', 'reset' => 'true');
         $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
         $this->assertResponse(200);
         $ajax_commands = Json::decode($response);
         $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
         $this->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
         $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
         // Submit field form.
         preg_match('/\\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match);
         preg_match('/\\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match);
         $edit['body[0][value]'] = '<p>kthxbye</p>';
         $post = array('form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1]);
         $post += $edit + $this->getAjaxPageStatePostData();
         $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
         $this->assertResponse(200);
         $ajax_commands = Json::decode($response);
         $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
         $this->assertIdentical('quickeditFieldFormSaved', $ajax_commands[0]['command'], 'The first AJAX command is an quickeditFieldFormSaved command.');
         $this->assertTrue(strpos($ajax_commands[0]['data'], 'kthxbye'), 'Form value saved and printed back.');
         // Save the entity.
         $post = array('nocssjs' => 'true');
         $response = $this->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post);
         $this->assertResponse(200);
         $ajax_commands = Json::decode($response);
         $this->assertIdentical(1, count($ajax_commands));
         $this->assertIdentical('quickeditEntitySaved', $ajax_commands[0]['command'], 'The first AJAX command is an quickeditEntitySaved command.');
         $this->assertEqual($ajax_commands[0]['data'], ['entity_type' => 'node', 'entity_id' => 1], 'Updated entity type and ID returned');
         // Test that a revision was created with the correct log message.
         $vids = \Drupal::entityManager()->getStorage('node')->revisionIds(Node::load(1));
         $this->assertIdentical(2, count($vids), 'The node has two revisions.');
         $revision = node_revision_load($vids[0]);
         $this->assertIdentical($original_log, $revision->revision_log->value, 'The first revision log message is unchanged.');
         $revision = node_revision_load($vids[1]);
         $this->assertIdentical('Updated the <em class="placeholder">Body</em> field through in-place editing.', $revision->revision_log->value, 'The second revision log message was correctly generated by Quick Edit module.');
     }
 }
示例#29
0
 /**
  * Creates a custom content type based on default settings.
  *
  * @param array $values
  *   An array of settings to change from the defaults.
  *   Example: 'type' => 'foo'.
  *
  * @return \Drupal\node\Entity\NodeType
  *   Created content type.
  */
 protected function drupalCreateContentType(array $values = array())
 {
     // Find a non-existent random type name.
     if (!isset($values['type'])) {
         do {
             $id = strtolower($this->randomMachineName(8));
         } while (NodeType::load($id));
     } else {
         $id = $values['type'];
     }
     $values += array('type' => $id, 'name' => $id);
     $type = entity_create('node_type', $values);
     $status = $type->save();
     node_add_body_field($type);
     \Drupal::service('router.builder')->rebuild();
     $this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created content type %type.', array('%type' => $type->id())));
     return $type;
 }
示例#30
0
 /**
  * Checks the node preview functionality, when using revisions.
  */
 function testPagePreviewWithRevisions()
 {
     $title_key = 'title[0][value]';
     $body_key = 'body[0][value]';
     $term_key = $this->fieldName . '[target_id]';
     // Force revision on "Basic page" content.
     $node_type = NodeType::load('page');
     $node_type->setNewRevision(TRUE);
     $node_type->save();
     // Fill in node creation form and preview node.
     $edit = array();
     $edit[$title_key] = $this->randomMachineName(8);
     $edit[$body_key] = $this->randomMachineName(16);
     $edit[$term_key] = $this->term->id();
     $edit['revision_log[0][value]'] = $this->randomString(32);
     $this->drupalPostForm('node/add/page', $edit, t('Preview'));
     // Check that the preview is displaying the title, body and term.
     $this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.');
     $this->assertText($edit[$title_key], 'Title displayed.');
     $this->assertText($edit[$body_key], 'Body displayed.');
     $this->assertText($edit[$term_key], 'Term displayed.');
     // Check that the title and body fields are displayed with the correct
     // values after going back to the content edit page.
     $this->clickLink(t('Back to content editing'));
     $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.');
     $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.');
     $this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.');
     // Check that the revision log field has the correct value.
     $this->assertFieldByName('revision_log[0][value]', $edit['revision_log[0][value]'], 'Revision log field displayed.');
 }