crm_core-8.x-3.x-dev/modules/crm_core_contact/tests/src/Functional/IndividualEditFormTest.php
modules/crm_core_contact/tests/src/Functional/IndividualEditFormTest.php
<?php namespace Drupal\Tests\crm_core_contact\Functional; use Drupal\crm_core_contact\IndividualInterface; use Drupal\user\Entity\User; /** * Create a individual and test individual edit functionality. * * @group crm_core_contact */ class IndividualEditFormTest extends ContactTestBase { /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * A normal logged in user. * * @var \Drupal\user\UserInterface */ protected $webUser; /** * A user with permission to bypass content access checks. * * @var \Drupal\user\UserInterface */ protected $adminUser; /** * The individual storage. * * @var \Drupal\crm_core_contact\IndividualStorageInterface */ protected $individualStorage; /** * Modules to enable. * * @var string[] */ protected static $modules = ['block', 'crm_core_contact', 'datetime']; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); $this->webUser = $this->drupalCreateUser([ 'view any crm_core_individual entity of bundle person', 'edit any crm_core_individual entity of bundle person', 'create crm_core_individual entities of bundle person', ]); $this->adminUser = $this->drupalCreateUser([ 'administer crm_core_individual entities', ]); $this->drupalPlaceBlock('local_tasks_block'); $this->individualStorage = $this->container ->get('entity_type.manager') ->getStorage('crm_core_individual'); } /** * Checks individual functionality. */ public function testIndividualEdit() { $this->drupalLogin($this->webUser); $name_key = 'name[0][given]'; $last_key = 'name[0][family]'; // Create individual to edit. $edit = []; $edit[$name_key] = $this->randomMachineName(8); $edit[$last_key] = $this->randomMachineName(8); $this->drupalGet('crm-core/individual/add/person'); $this->submitForm($edit, 'Save'); // Check that the individual exists in the database. $individual = $this->drupalGetIndividualByLabel($edit[$name_key] . ' ' . $edit[$last_key]); $this->assertNotEmpty($individual, 'Individual found in database.'); // Check that "edit" link points to correct page. $this->clickLink('Edit'); $this->assertSession()->addressEquals($individual->toUrl('edit-form')); // Check that the title and body fields are displayed with the // correct values. // @todo Ideally assertLink would support HTML, but it doesn't. $this->assertSession()->responseContains('Edit<span class="visually-hidden">(active tab)</span>'); $this->assertSession()->fieldValueEquals($name_key, $edit[$name_key]); $this->assertSession()->fieldValueEquals($last_key, $edit[$last_key]); // Edit the content of the individual. $edit = []; $edit[$name_key] = $this->randomMachineName(8); $edit[$last_key] = $this->randomMachineName(8); // Stay on the current page, without reloading. $this->submitForm($edit, 'Save'); // Check that the title field is displayed with the updated values. $this->assertSession()->pageTextContains($edit[$name_key]); // Log in as a second administrator user. $second_web_user = $this->drupalCreateUser([ 'administer crm_core_individual entities', 'edit any crm_core_individual entity of bundle person', ]); $this->drupalLogin($second_web_user); // Edit the same individual, creating a new revision. $this->drupalGet("crm-core/individual/" . $individual->id() . "/edit"); $edit = []; $edit['name[0][given]'] = $this->randomMachineName(8); $edit['name[0][family]'] = $this->randomMachineName(8); $edit['revision'] = TRUE; $this->submitForm($edit, 'Save'); // Ensure that the individual revision has been created. $revised_individual = $this->drupalGetIndividualByLabel($edit['name[0][given]'] . ' ' . $edit['name[0][family]'], TRUE); $this->assertNotSame($individual->getRevisionId(), $revised_individual->getRevisionId(), 'A new revision has been created.'); // Ensure that the individual owner is preserved when it was not changed in // the edit form. $this->assertSame($individual->getOwnerId(), $revised_individual->getOwnerId(), 'The individual owner has been preserved.'); // Ensure that the revision authors are different since the revisions were // made by different users. $first_individual_version = $this->individualStorage->loadRevision($individual->getRevisionId()); $second_individual_version = $this->individualStorage->loadRevision($revised_individual->getRevisionId()); $this->assertNotSame($first_individual_version->getRevisionUser()->id(), $second_individual_version->getRevisionUser()->id(), 'Each revision has a distinct user.'); // Check if the individual revision checkbox is rendered on // individual edit form. $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $this->assertSession()->fieldExists('edit-revision', NULL); // Check that details form element opens when there are errors on child // elements. $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $edit = []; // This invalid date will trigger an error. $edit['created[0][value][date]'] = $this->randomMachineName(8); // Get the current amount of open details elements. $open_details_elements = count($this->cssSelect('details[open="open"]')); $this->submitForm($edit, 'Save'); // The individual owner details must be open. // Only one extra details element should now be open. $open_details_elements++; $this->assertCount($open_details_elements, $this->cssSelect('details[open="open"]'), 'Exactly one extra open <details> element found.'); // Edit the same individual, save it and verify it's inactive after // unchecking the 'Active' boolean_checkbox and clicking 'Save'. $this->drupalGet("crm-core/individual/" . $individual->id() . "/edit"); $edit = ['status[value]' => FALSE]; $this->submitForm($edit, 'Save'); $this->individualStorage->resetCache([$individual->id()]); $individual = $this->individualStorage->load($individual->id()); $this->assertFalse($individual->isPublished(), 'Individual is inactive'); } /** * Tests changing a individual's "created" field. */ public function testIndividualEditAuthoredBy() { $this->drupalLogin($this->adminUser); // Create individual to edit. $edit = []; $edit['name[0][given]'] = $this->randomMachineName(8); $edit['name[0][family]'] = $this->randomMachineName(8); $this->drupalGet('crm-core/individual/add/person'); $this->submitForm($edit, 'Save'); // Check that the individual was authored by the currently logged in user. $individual = $this->drupalGetIndividualByLabel($edit['name[0][given]'] . ' ' . $edit['name[0][family]']); $this->assertSame($this->adminUser->id(), $individual->getOwnerId(), 'Individual authored by admin user.'); $this->checkVariousAuthoredByValues($individual, 'uid[0][target_id]'); // Check that normal users cannot change the authored by information. $this->drupalLogin($this->webUser); $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $this->assertSession()->fieldNotExists('uid[0][target_id]'); // Now test with the Autocomplete (Tags) field widget. /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */ $form_display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load('crm_core_indidual.person.default'); if (empty($form_display)) { $form_display_values = [ 'targetEntityType' => 'crm_core_individual', 'bundle' => 'person', 'mode' => 'default', 'status' => TRUE, ]; $form_display = \Drupal::entityTypeManager() ->getStorage('entity_form_display') ->create($form_display_values); } $widget = $form_display->getComponent('uid'); $widget['type'] = 'entity_reference_autocomplete_tags'; $widget['settings'] = [ 'match_operator' => 'CONTAINS', 'size' => 60, 'placeholder' => '', ]; $form_display->setComponent('uid', $widget); $form_display->save(); $this->drupalLogin($this->adminUser); // Save the individual without making any changes. $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $this->submitForm([], 'Save'); $this->individualStorage->resetCache([$individual->id()]); $individual = $this->individualStorage->load($individual->id()); $this->assertSame($this->webUser->id(), $individual->getOwner()->id()); $this->checkVariousAuthoredByValues($individual, 'uid[target_id]'); // Hide the 'authored by' field from the form. $form_display->removeComponent('uid')->save(); // Check that saving the individual without making any changes keeps the // proper owner ID. $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $this->submitForm([], 'Save'); $this->individualStorage->resetCache([$individual->id()]); $individual = $this->individualStorage->load($individual->id()); $this->assertSame($this->webUser->id(), $individual->getOwner()->id()); } /** * Tests the individual meta information. */ public function testIindividualMetaInformation() { // Check that regular users (i.e. without the // 'administer individuals' permission) can not see the meta information. $this->drupalLogin($this->webUser); $this->drupalGet('crm-core/individual/add/person'); $this->assertSession()->pageTextNotContains('Not saved yet'); // Create individual to edit. $edit['name[0][given]'] = $this->randomMachineName(8); $edit['name[0][family]'] = $this->randomMachineName(8); $this->submitForm($edit, 'Save'); $individual = $this->drupalGetIndividualByLabel($edit['name[0][given]'] . ' ' . $edit['name[0][family]']); $this->drupalGet("crm-core/individual/" . $individual->id() . "/edit"); $this->assertSession()->pageTextNotContains('Published'); $this->assertSession()->pageTextNotContains($this->container->get('date.formatter')->format($individual->getChangedTime(), 'short')); // Check that users with the 'administer individuals' permission can see the // meta information. $this->drupalLogin($this->adminUser); $this->drupalGet('crm-core/individual/add/person'); $this->assertSession()->pageTextContains('Not saved yet'); // Create individual to edit. $edit['name[0][given]'] = $this->randomMachineName(8); $edit['name[0][family]'] = $this->randomMachineName(8); $this->submitForm($edit, 'Save'); $individual = $this->drupalGetIndividualByLabel($edit['name[0][given]'] . ' ' . $edit['name[0][family]']); $this->drupalGet("crm-core/individual/" . $individual->id() . "/edit"); $this->assertSession()->pageTextContains('Active'); $this->assertSession()->pageTextContains($this->container->get('date.formatter')->format($individual->getChangedTime(), 'short')); } /** * Checks that the "authored by" works correctly with various values. * * @param \Drupal\crm_core_contact\IndividualInterface $individual * An individual object. * @param string $form_element_name * The name of the form element to populate. */ protected function checkVariousAuthoredByValues(IndividualInterface $individual, $form_element_name) { // Try to change the 'authored by' field to an invalid user name. $edit = [ $form_element_name => 'invalid-name', ]; $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $this->submitForm($edit, 'Save'); $this->assertSession()->pageTextContains('There are no users matching "invalid-name".'); // Change the authored by field to an empty string, which should assign // authorship to the anonymous user (uid 0). $edit[$form_element_name] = ''; $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $this->submitForm($edit, 'Save'); $this->individualStorage->resetCache([$individual->id()]); $individual = $this->individualStorage->load($individual->id()); $uid = $individual->getOwnerId(); // Most SQL database drivers stringify fetches but entities are not // necessarily stored in a SQL database. At the same time, NULL/FALSE/"" // won't do. $this->assertTrue($uid === 0 || $uid === '0', 'Individual owned by anonymous user.'); // Go back to the edit form and check that the correct value is displayed // in the author widget. $this->drupalGet('crm-core/individual/' . $individual->id() . '/edit'); $anonymous_user = User::getAnonymousUser(); $expected = $anonymous_user->label() . ' (' . $anonymous_user->id() . ')'; $this->assertSession()->fieldValueEquals($form_element_name, $expected); // Change the authored by field to another user's name (that is not // logged in). $edit[$form_element_name] = $this->webUser->getAccountName(); $this->submitForm($edit, 'Save'); $this->individualStorage->resetCache([$individual->id()]); $individual = $this->individualStorage->load($individual->id()); $this->assertSame($this->webUser->id(), $individual->getOwnerId(), 'Node authored by normal user.'); } }