function EntityFieldTest::doTestReadWrite

Same name and namespace in other branches
  1. 9 core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php \Drupal\KernelTests\Core\Entity\EntityFieldTest::doTestReadWrite()
  2. 8.9.x core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php \Drupal\KernelTests\Core\Entity\EntityFieldTest::doTestReadWrite()
  3. 11.x core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php \Drupal\KernelTests\Core\Entity\EntityFieldTest::doTestReadWrite()

Executes the read write test set for a defined entity type.

Parameters

string $entity_type: The entity type to run the tests with.

1 call to EntityFieldTest::doTestReadWrite()
EntityFieldTest::testReadWrite in core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
Tests reading and writing properties and field items.

File

core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php, line 150

Class

EntityFieldTest
Tests the Entity Field API.

Namespace

Drupal\KernelTests\Core\Entity

Code

protected function doTestReadWrite($entity_type) {
  $entity = $this->createTestEntity($entity_type);
  $langcode = 'en';
  // Access the name field.
  $this->assertInstanceOf(FieldItemListInterface::class, $entity->name);
  $this->assertInstanceOf(FieldItemInterface::class, $entity->name[0]);
  $this->assertEquals($this->entityName, $entity->name->value, "{$entity_type}: Name value can be read.");
  $this->assertEquals($this->entityName, $entity->name[0]->value, "{$entity_type}: Name value can be read through list access.");
  $this->assertEquals([
    0 => [
      'value' => $this->entityName,
    ],
  ], $entity->name
    ->getValue(), "{$entity_type}: Plain field value returned.");
  // Change the name.
  $new_name = $this->randomMachineName();
  $entity->name->value = $new_name;
  $this->assertEquals($new_name, $entity->name->value, "{$entity_type}: Name can be updated and read.");
  $this->assertEquals([
    0 => [
      'value' => $new_name,
    ],
  ], $entity->name
    ->getValue(), "{$entity_type}: Plain field value reflects the update.");
  $new_name = $this->randomMachineName();
  $entity->name[0]->value = $new_name;
  $this->assertEquals($new_name, $entity->name->value, "{$entity_type}: Name can be updated and read through list access.");
  // Access the user field.
  $this->assertInstanceOf(FieldItemListInterface::class, $entity->user_id);
  $this->assertInstanceOf(FieldItemInterface::class, $entity->user_id[0]);
  $this->assertEquals($this->entityUser
    ->id(), $entity->user_id->target_id, "{$entity_type}: User id can be read.");
  $this->assertEquals($this->entityUser
    ->getAccountName(), $entity->user_id->entity->name->value, "{$entity_type}: User name can be read.");
  // Change the assigned user by entity.
  $new_user1 = $this->createUser();
  $entity->user_id->entity = $new_user1;
  $this->assertEquals($new_user1->id(), $entity->user_id->target_id, "{$entity_type}: Updated user id can be read.");
  $this->assertEquals($new_user1->getAccountName(), $entity->user_id->entity->name->value, "{$entity_type}: Updated username value can be read.");
  // Change the assigned user by id.
  $new_user2 = $this->createUser();
  $entity->user_id->target_id = $new_user2->id();
  $this->assertEquals($new_user2->id(), $entity->user_id->target_id, "{$entity_type}: Updated user id can be read.");
  $this->assertEquals($new_user2->getAccountName(), $entity->user_id->entity->name->value, "{$entity_type}: Updated username value can be read.");
  // Try unsetting a field property.
  $entity->name->value = NULL;
  $entity->user_id->target_id = NULL;
  $this->assertNull($entity->name->value, "{$entity_type}: Name field is not set.");
  $this->assertNull($entity->user_id->target_id, "{$entity_type}: User ID field is not set.");
  $this->assertNull($entity->user_id->entity, "{$entity_type}: User entity field is not set.");
  // Test setting the values via the typed data API works as well.
  // Change the assigned user by entity.
  $entity->user_id
    ->first()
    ->get('entity')
    ->setValue($new_user2);
  $this->assertEquals($new_user2->id(), $entity->user_id->target_id, "{$entity_type}: Updated user id can be read.");
  $this->assertEquals($new_user2->getAccountName(), $entity->user_id->entity->name->value, "{$entity_type}: Updated user name value can be read.");
  // Change the assigned user by id.
  $entity->user_id
    ->first()
    ->get('target_id')
    ->setValue($new_user2->id());
  $this->assertEquals($new_user2->id(), $entity->user_id->target_id, "{$entity_type}: Updated user id can be read.");
  $this->assertEquals($new_user2->getAccountName(), $entity->user_id->entity->name->value, "{$entity_type}: Updated user name value can be read.");
  // Try unsetting a field.
  $entity->name
    ->first()
    ->get('value')
    ->setValue(NULL);
  $entity->user_id
    ->first()
    ->get('target_id')
    ->setValue(NULL);
  $this->assertNull($entity->name->value, "{$entity_type}: Name field is not set.");
  $this->assertNull($entity->user_id->target_id, "{$entity_type}: User ID field is not set.");
  $this->assertNull($entity->user_id->entity, "{$entity_type}: User entity field is not set.");
  // Create a fresh entity so target_id does not get its property object
  // instantiated, then verify setting a new value via typed data API works.
  $entity2 = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type)
    ->create([
    'user_id' => [
      'target_id' => $new_user1->id(),
    ],
  ]);
  // Access the property object, and set a value.
  $entity2->user_id
    ->first()
    ->get('target_id')
    ->setValue($new_user2->id());
  $this->assertEquals($new_user2->id(), $entity2->user_id->target_id, "{$entity_type}: Updated user id can be read.");
  $this->assertEquals($new_user2->name->value, $entity2->user_id->entity->name->value, "{$entity_type}: Updated user name value can be read.");
  // Test using isset(), empty() and unset().
  $entity->name->value = 'test unset';
  unset($entity->name->value);
  $this->assertFalse(isset($entity->name->value), "{$entity_type}: Name is not set.");
  $this->assertFalse(isset($entity->name[0]->value), "{$entity_type}: Name is not set.");
  $this->assertEmpty($entity->name->value, "{$entity_type}: Name is empty.");
  $this->assertEmpty($entity->name[0]->value, "{$entity_type}: Name is empty.");
  $entity->name->value = 'a value';
  $this->assertTrue(isset($entity->name->value), "{$entity_type}: Name is set.");
  $this->assertTrue(isset($entity->name[0]->value), "{$entity_type}: Name is set.");
  $this->assertNotEmpty($entity->name->value, "{$entity_type}: Name is not empty.");
  $this->assertNotEmpty($entity->name[0]->value, "{$entity_type}: Name is not empty.");
  $this->assertTrue(isset($entity->name[0]), "{$entity_type}: Name string item is set.");
  $this->assertFalse(isset($entity->name[1]), "{$entity_type}: Second name string item is not set as it does not exist");
  $this->assertTrue(isset($entity->name), "{$entity_type}: Name field is set.");
  $this->assertFalse(isset($entity->nameInvalid), "{$entity_type}: Non-existent field is not set.");
  unset($entity->name[0]);
  $this->assertFalse(isset($entity->name[0]), "{$entity_type}: Name field item is not set.");
  $this->assertFalse(isset($entity->name[0]->value), "{$entity_type}: Name is not set.");
  $this->assertFalse(isset($entity->name->value), "{$entity_type}: Name is not set.");
  // Test emptying a field by assigning an empty value. NULL and array()
  // behave the same.
  foreach ([
    NULL,
    [],
    'unset',
  ] as $empty) {
    // Make sure a value is present
    $entity->name->value = 'a value';
    $this->assertTrue(isset($entity->name->value), "{$entity_type}: Name is set.");
    // Now, empty the field.
    if ($empty === 'unset') {
      unset($entity->name);
    }
    else {
      $entity->name = $empty;
    }
    $this->assertTrue(isset($entity->name), "{$entity_type}: Name field is set.");
    $this->assertTrue($entity->name
      ->isEmpty(), "{$entity_type}: Name field is set.");
    $this->assertCount(0, $entity->name, "{$entity_type}: Name field contains no items.");
    $this->assertSame([], $entity->name
      ->getValue(), "{$entity_type}: Name field value is an empty array.");
    $this->assertFalse(isset($entity->name[0]), "{$entity_type}: Name field item is not set.");
    $this->assertFalse(isset($entity->name[0]->value), "{$entity_type}: First name item value is not set.");
    $this->assertFalse(isset($entity->name->value), "{$entity_type}: Name value is not set.");
  }
  // Access the language field.
  $langcode_key = $this->entityTypeManager
    ->getDefinition($entity_type)
    ->getKey('langcode');
  $this->assertEquals($langcode, $entity->{$langcode_key}->value, "{$entity_type}: Language code can be read.");
  $this->assertEquals(\Drupal::languageManager()->getLanguage($langcode), $entity->{$langcode_key}->language, "{$entity_type}: Language object can be read.");
  // Change the language by code.
  $entity->{$langcode_key}->value = \Drupal::languageManager()->getDefaultLanguage()
    ->getId();
  $this->assertEquals(\Drupal::languageManager()->getDefaultLanguage()
    ->getId(), $entity->{$langcode_key}->value, "{$entity_type}: Language code can be read.");
  $this->assertEquals(\Drupal::languageManager()->getDefaultLanguage(), $entity->{$langcode_key}->language, "{$entity_type}: Language object can be read.");
  // Revert language by code then try setting it by language object.
  $entity->{$langcode_key}->value = $langcode;
  $entity->{$langcode_key}->language = \Drupal::languageManager()->getDefaultLanguage();
  $this->assertEquals(\Drupal::languageManager()->getDefaultLanguage()
    ->getId(), $entity->{$langcode_key}->value, "{$entity_type}: Language code can be read.");
  $this->assertEquals(\Drupal::languageManager()->getDefaultLanguage(), $entity->{$langcode_key}->language, "{$entity_type}: Language object can be read.");
  // Access the text field and test updating.
  $this->assertEquals($this->entityFieldText, $entity->field_test_text->value, "{$entity_type}: Text field can be read.");
  $new_text = $this->randomMachineName();
  $entity->field_test_text->value = $new_text;
  $this->assertEquals($new_text, $entity->field_test_text->value, "{$entity_type}: Updated text field can be read.");
  // Test creating the entity by passing in plain values.
  $this->entityName = $this->randomMachineName();
  $name_item[0]['value'] = $this->entityName;
  $this->entityUser = $this->createUser();
  $user_item[0]['target_id'] = $this->entityUser
    ->id();
  $this->entityFieldText = $this->randomMachineName();
  $text_item[0]['value'] = $this->entityFieldText;
  $entity = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type)
    ->create([
    'name' => $name_item,
    'user_id' => $user_item,
    'field_test_text' => $text_item,
  ]);
  $this->assertEquals($this->entityName, $entity->name->value, "{$entity_type}: Name value can be read.");
  $this->assertEquals($this->entityUser
    ->id(), $entity->user_id->target_id, "{$entity_type}: User id can be read.");
  $this->assertEquals($this->entityUser
    ->getAccountName(), $entity->user_id->entity->name->value, "{$entity_type}: User name can be read.");
  $this->assertEquals($this->entityFieldText, $entity->field_test_text->value, "{$entity_type}: Text field can be read.");
  // Tests copying field values by assigning the TypedData objects.
  $entity2 = $this->createTestEntity($entity_type);
  $entity2->name = $entity->name;
  $entity2->user_id = $entity->user_id;
  $entity2->field_test_text = $entity->field_test_text;
  $this->assertNotSame($entity->name, $entity2->name, "{$entity_type}: Copying properties results in a different field object.");
  $this->assertEquals($entity->name->value, $entity2->name->value, "{$entity_type}: Name field copied.");
  $this->assertEquals($entity->user_id->target_id, $entity2->user_id->target_id, "{$entity_type}: User id field copied.");
  $this->assertEquals($entity->field_test_text->value, $entity2->field_test_text->value, "{$entity_type}: Text field copied.");
  // Tests that assigning TypedData objects to non-field properties keeps the
  // assigned value as is.
  $entity2 = $this->createTestEntity($entity_type);
  $entity2->_not_a_field = $entity->name;
  $this->assertSame($entity->name, $entity2->_not_a_field, "{$entity_type}: Typed data objects can be copied to non-field properties as is.");
  // Tests adding a value to a field item list.
  $entity->name[] = 'Another name';
  $this->assertEquals('Another name', $entity->name[1]->value, "{$entity_type}: List item added via [] and the first property.");
  $entity->name[] = [
    'value' => 'Third name',
  ];
  $this->assertEquals('Third name', $entity->name[2]->value, "{$entity_type}: List item added via [] and an array of properties.");
  $entity->name[3] = [
    'value' => 'Fourth name',
  ];
  $this->assertEquals('Fourth name', $entity->name[3]->value, "{$entity_type}: List item added via offset and an array of properties.");
  unset($entity->name[3]);
  // Test removing and empty-ing list items.
  $this->assertCount(3, $entity->name, "{$entity_type}: List has 3 items.");
  unset($entity->name[1]);
  $this->assertCount(2, $entity->name, "{$entity_type}: Second list item has been removed.");
  $this->assertEquals('Third name', $entity->name[1]->value, "{$entity_type}: The subsequent items have been shifted up.");
  $this->assertEquals(1, $entity->name[1]
    ->getName(), "{$entity_type}: The items names have been updated to their new delta.");
  $entity->name[1] = NULL;
  $this->assertCount(2, $entity->name, "{$entity_type}: Assigning NULL does not reduce array count.");
  $this->assertTrue($entity->name[1]
    ->isEmpty(), "{$entity_type}: Assigning NULL empties the item.");
  // Test using isEmpty().
  unset($entity->name[1]);
  $this->assertFalse($entity->name[0]
    ->isEmpty(), "{$entity_type}: Name item is not empty.");
  $entity->name->value = NULL;
  $this->assertTrue($entity->name[0]
    ->isEmpty(), "{$entity_type}: Name item is empty.");
  $this->assertTrue($entity->name
    ->isEmpty(), "{$entity_type}: Name field is empty.");
  $this->assertCount(1, $entity->name, "{$entity_type}: Empty item is considered when counting.");
  $this->assertCount(1, iterator_to_array($entity->name
    ->getIterator()), "{$entity_type}: Count matches iterator count.");
  $this->assertSame([
    0 => [
      'value' => NULL,
    ],
  ], $entity->name
    ->getValue(), "{$entity_type}: Name field value contains a NULL value.");
  // Test using filterEmptyItems().
  $entity->name = [
    NULL,
    'foo',
  ];
  $this->assertCount(2, $entity->name, "{$entity_type}: List has 2 items.");
  $entity->name
    ->filterEmptyItems();
  $this->assertCount(1, $entity->name, "{$entity_type}: The empty item was removed.");
  $this->assertEquals('foo', $entity->name[0]->value, "{$entity_type}: The items were renumbered.");
  $this->assertEquals(0, $entity->name[0]
    ->getName(), "{$entity_type}: The deltas were updated in the items.");
  // Test get and set field values.
  $entity->name = 'foo';
  $this->assertEquals([
    'value' => 'foo',
  ], $entity->name[0]
    ->toArray(), "{$entity_type}: Field value has been retrieved via toArray()");
  $values = $entity->toArray();
  $this->assertEquals([
    0 => [
      'value' => 'foo',
    ],
  ], $values['name'], "{$entity_type}: Field value has been retrieved via toArray() from an entity.");
  // Make sure the user id can be set to zero.
  $user_item[0]['target_id'] = 0;
  $entity = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type)
    ->create([
    'name' => $name_item,
    'user_id' => $user_item,
    'field_test_text' => $text_item,
  ]);
  $this->assertNotNull($entity->user_id->target_id, "{$entity_type}: User id is not NULL");
  $this->assertSame(0, $entity->user_id->target_id, "{$entity_type}: User id has been set to 0");
  // Test setting the ID with the value only.
  $entity = $this->container
    ->get('entity_type.manager')
    ->getStorage($entity_type)
    ->create([
    'name' => $name_item,
    'user_id' => 0,
    'field_test_text' => $text_item,
  ]);
  $this->assertNotNull($entity->user_id->target_id, "{$entity_type}: User id is not NULL");
  $this->assertSame(0, $entity->user_id->target_id, "{$entity_type}: User id has been set to 0");
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.