You are here

public function BaseFieldTest::testEncryptFieldNormal in Field Encryption 3.0.x

Test encrypting base fields.

This test also covers changing field encryption settings when existing data already exists, as well as making fields unencrypted again with data decryption support.

File

tests/src/Functional/BaseFieldTest.php, line 94

Class

BaseFieldTest
Tests base field encryption.

Namespace

Drupal\Tests\field_encrypt\Functional

Code

public function testEncryptFieldNormal() {
  $this
    ->setFieldStorageSettings(TRUE);

  // Save test entity.
  $test_node = $this
    ->createNode([
    'title' => 'Test title',
  ]);
  $fields = $test_node
    ->getFields();

  // Check title base field settings.
  $definition = $fields['title']
    ->getFieldDefinition();
  $this
    ->assertTrue($definition instanceof FieldDefinitionInterface);

  /** @var \Drupal\Core\Field\FieldConfigInterface $storage */
  $storage = $definition
    ->getFieldStorageDefinition();
  $this
    ->assertEquals(TRUE, $storage
    ->getSetting('field_encrypt.encrypt'));
  $this
    ->assertEquals([
    'value',
  ], array_filter($storage
    ->getSetting('field_encrypt.properties')));

  // Check if text is displayed unencrypted.
  $this
    ->drupalGet('node/' . $test_node
    ->id());
  $this
    ->assertSession()
    ->pageTextContains("Test title");
  $result = \Drupal::database()
    ->query("SELECT title FROM {node_field_data} WHERE nid = :entity_id", [
    ':entity_id' => $test_node
      ->id(),
  ])
    ->fetchField();
  $this
    ->assertEquals(ProcessEntities::ENCRYPTED_VALUE, $result);

  // Change default encryption profile and ensure the entity can still be
  // decrypted.
  $this
    ->config('field_encrypt.settings')
    ->set('encryption_profile', 'encryption_profile_2')
    ->save();
  $this
    ->resetAll();

  // Check if text is displayed unencrypted.
  $this
    ->drupalGet('node/' . $test_node
    ->id());
  $this
    ->assertSession()
    ->pageTextContains("Test title");

  // Ensure that base fields used in post save messages are decrypted on
  // insert, update and delete.
  $this
    ->drupalGet('node/add/page');
  $this
    ->assertSession()
    ->fieldExists('title[0][value]')
    ->setValue('Test title encrypted');
  $this
    ->assertSession()
    ->buttonExists('Save')
    ->press();
  $this
    ->assertSession()
    ->pageTextContains('Test title encrypted has been created.');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_ENTITY_TYPE_insert: Test title encrypted');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_entity_insert: Test title encrypted');
  $this
    ->drupalGet('node/2/edit');
  $this
    ->assertSession()
    ->fieldExists('title[0][value]')
    ->setValue('Test new title encrypted');
  $this
    ->assertSession()
    ->buttonExists('Save')
    ->press();
  $this
    ->assertSession()
    ->pageTextContains('Test new title encrypted has been updated.');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_ENTITY_TYPE_update: Test new title encrypted');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_entity_update: Test new title encrypted');
  $this
    ->drupalGet('node/2/delete');
  $this
    ->assertSession()
    ->buttonExists('Delete')
    ->press();
  $this
    ->assertSession()
    ->pageTextContains('Test new title encrypted has been deleted.');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_ENTITY_TYPE_delete: Test new title encrypted');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_entity_delete: Test new title encrypted');

  // Create another node to delete after the queue is set up.
  $this
    ->drupalGet('node/add/page');
  $this
    ->assertSession()
    ->fieldExists('title[0][value]')
    ->setValue('Test title encrypted 3');
  $this
    ->assertSession()
    ->buttonExists('Save')
    ->press();
  $this
    ->assertSession()
    ->pageTextContains('Test title encrypted 3 has been created.');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_ENTITY_TYPE_insert: Test title encrypted 3');
  $this
    ->assertSession()
    ->pageTextContains('Field encrypt test hook_entity_insert: Test title encrypted 3');

  // Test updating entities to remove field encryption.
  $this
    ->setFieldStorageSettings(FALSE);

  // Update existing data with new field encryption settings.
  $this
    ->assertSession()
    ->linkByHrefExists('admin/config/system/field-encrypt/process-queues');
  $this
    ->drupalGet('admin/config/system/field-encrypt/process-queues');
  $this
    ->assertSession()
    ->pageTextContains('There are 2 entities queued for updating to use the latest field encryption settings.');
  $this
    ->assertTrue(\Drupal::database()
    ->schema()
    ->fieldExists('node_field_data', ProcessEntities::ENCRYPTED_FIELD_STORAGE_NAME . '__value'));

  // Delete the node before running cron.
  $this
    ->drupalGet('node/3/delete');
  $this
    ->assertSession()
    ->buttonExists('Delete')
    ->press();
  $this
    ->assertSession()
    ->pageTextContains('Test title encrypted 3 has been deleted.');
  $this
    ->cronRun();
  $this
    ->drupalGet('admin/config/system/field-encrypt/process-queues');
  $this
    ->assertSession()
    ->pageTextContains('There are 0 entities queued for updating to use the latest field encryption settings.');

  // Check if text is displayed unencrypted.
  $this
    ->drupalGet('node/' . $test_node
    ->id());
  $this
    ->assertSession()
    ->pageTextContains("Test title");
  $result = \Drupal::database()
    ->query("SELECT title FROM {node_field_data} WHERE nid = :entity_id", [
    ':entity_id' => $test_node
      ->id(),
  ])
    ->fetchField();
  $this
    ->assertEquals('Test title', $result);
  $this
    ->assertTrue(\Drupal::database()
    ->schema()
    ->fieldExists('node_field_data', ProcessEntities::ENCRYPTED_FIELD_STORAGE_NAME . '__value'));

  // This will call field_encrypt_cron() which will now remove the storage
  // field. Cron hooks are always processed before queue workers so this takes
  // an additional call.
  $this
    ->cronRun();
  $this
    ->assertFalse(\Drupal::database()
    ->schema()
    ->fieldExists('node_field_data', ProcessEntities::ENCRYPTED_FIELD_STORAGE_NAME . '__value'));

  // Create a node once the encryption has been remvoed.
  $this
    ->drupalGet('node/add/page');
  $this
    ->assertSession()
    ->fieldExists('title[0][value]')
    ->setValue('Test title no encryption');
  $this
    ->assertSession()
    ->buttonExists('Save')
    ->press();
  $this
    ->assertSession()
    ->pageTextContains('Test title no encryption has been created.');
}