You are here

entity_embed.test in Entity Embed 7.2

Same filename and directory in other branches
  1. 7.3 entity_embed.test
  2. 7 entity_embed.test

Test integration for the entity_embed module.

File

entity_embed.test
View source
<?php

/**
 * @file
 * Test integration for the entity_embed module.
 */
class EntityEmbedTestBase extends DrupalWebTestCase {
  protected $profile = 'testing';

  /**
   * The test user.
   */
  protected $webUser;

  /**
   * A test node to be used for embedding.
   */
  protected $node;
  function setUp() {
    $modules = func_get_args();
    if (isset($modules[0]) && is_array($modules[0])) {
      $modules = $modules[0];
    }
    $modules[] = 'entity_embed';
    $modules[] = 'node';
    parent::setUp($modules);

    // Create a page content type.
    $this
      ->drupalCreateContentType(array(
      'type' => 'page',
      'name' => 'Basic page',
    ));

    // Create Filtered HTML text format and enable entity_embed filter.
    $format = new stdClass();
    $format->format = 'custom_format';
    $format->name = 'Custom format';
    $format->filters = array(
      'entity_embed' => array(
        'status' => 1,
      ),
    );
    filter_format_save($format);

    // Reset permissions so that permissions for the filter are available.
    $this
      ->checkPermissions(array(), TRUE);

    // Create a user with required permissions.
    $this->webUser = $this
      ->drupalCreateUser(array(
      'access content',
      'create page content',
      'use text format custom_format',
    ));
    $this
      ->drupalLogin($this->webUser);

    // Create a sample node to be embedded.
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Embed Test Node';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => 'This node is to be used for embedding in other nodes.',
          'format' => 'custom_format',
        ),
      ),
    );
    $this->node = $this
      ->drupalCreateNode($settings);
  }

}

/**
 * Tests the entity_embed filter.
 */
class EntityEmbedFilterTest extends EntityEmbedTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Entity Embed filter test',
      'description' => 'Tests the Entity Embed filter.',
      'group' => 'Entity Embed',
    );
  }
  public function setUp() {
    parent::setUp('uuid');
  }

  /**
   * Tests the entity_embed filter.
   *
   * Ensures that entities are getting rendered when correct data attributes
   * are passed. Also tests situations when embed fails.
   */
  function testFilter() {

    // Tests entity embed using entity ID and view mode.
    $content = '<drupal-entity data-entity-type="node" data-entity-id="' . $this->node->nid . '" data-view-mode="teaser">This placeholder should not be rendered.</drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Test entity embed with entity-id and view-mode';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertNoRaw('<drupal-entity data-entity-type="node" data-entity');
    $this
      ->assertText($this->node->body[LANGUAGE_NONE][0]['value'], 'Embedded node exists in page');
    $this
      ->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is successful.');

    // Tests entity embed using entity UUID and view mode.
    $content = '<drupal-entity data-entity-type="node" data-entity-uuid="' . $this->node->uuid . '" data-view-mode="teaser">This placeholder should not be rendered.</drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Test entity embed with entity-uuid and view-mode';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertNoRaw('<drupal-entity data-entity-type="node" data-entity');
    $this
      ->assertText($this->node->body[LANGUAGE_NONE][0]['value'], 'Embedded node exists in page');
    $this
      ->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is successful.');

    // Ensure that placeholder is not replaced when embed is unsuccessful.
    $content = '<drupal-entity data-entity-type="node" data-entity-id="InvalidID" data-view-mode="teaser">This placeholder should be rendered since specified entity does not exist.</drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Test that placeholder is retained when specified entity does not exist';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertNoRaw('<drupal-entity data-entity-type="node" data-entity');
    $this
      ->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is unsuccessful.');

    // Ensure that UUID is preferred over ID when both attributes are present.
    $sample_node = $this
      ->drupalCreateNode();
    $content = '<drupal-entity data-entity-type="node" data-entity-id="' . $sample_node->nid . '" data-entity-uuid="' . $this->node->uuid . '" data-view-mode="teaser">This placeholder should not be rendered.</drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Test that entity-uuid is preferred over entity-id when both attributes are present';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertNoRaw('<drupal-entity data-entity-type="node" data-entity');
    $this
      ->assertText($this->node->body[LANGUAGE_NONE][0]['value'], 'Entity specified with UUID exists in the page.');
    $this
      ->assertNoText($sample_node->body[LANGUAGE_NONE][0]['value'], 'Entity specified with ID does not exists in the page.');
    $this
      ->assertNoText(strip_tags($content), 'Placeholder not appears in the output when embed is successful.');

    //    // Test deprecated 'default' Entity Embed Display plugin.
    //    $content = '<drupal-entity data-entity-type="node" data-entity-uuid="' . $this->node->uuid . '" data-entity-embed-display="default" data-entity-embed-settings=\'{"view_mode":"teaser"}\'>This placeholder should not be rendered.</drupal-entity>';
    //    $settings = array();
    //    $settings['type'] = 'page';
    //    $settings['title'] = 'Test entity embed with entity-embed-display and data-entity-embed-settings';
    //    $settings['body'] = array(LANGUAGE_NONE => array(array('value' => $content, 'format' => 'custom_format')));
    //    $node = $this->drupalCreateNode($settings);
    //    $this->drupalGet('node/' . $node->nid);
    //    $this->assertText($this->node->body[LANGUAGE_NONE][0]['value'], 'Embedded node exists in page');
    //    $this->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is successful.');
    //
    //    // Ensure that Entity Embed Display plugin is preferred over view mode when
    //    // both attributes are present.
    //    $content = '<drupal-entity data-entity-type="node" data-entity-uuid="' . $this->node->uuid . '" data-entity-embed-display="default" data-entity-embed-settings=\'{"view_mode":"teaser"}\' data-view-mode="some-invalid-view-mode">This placeholder should not be rendered.</drupal-entity>';
    //    $settings = array();
    //    $settings['type'] = 'page';
    //    $settings['title'] = 'Test entity embed with entity-embed-display and data-entity-embed-settings';
    //    $settings['body'] = array(LANGUAGE_NONE => array(array('value' => $content, 'format' => 'custom_format')));
    //    $node = $this->drupalCreateNode($settings);
    //    $this->drupalGet('node/' . $node->nid);
    //    $this->assertText($this->node->body[LANGUAGE_NONE][0]['value'], 'Embedded node exists in page with the view mode specified by entity-embed-settings.');
    //    $this->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is successful.');
    // Test that tag of container element is not replaced when it's not
    // <drupal-entity>.
    $content = '<not-drupal-entity data-entity-type="node" data-entity-id="' . $this->node->nid . '" data-view-mode="teaser">this placeholder should not be rendered.</not-drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'test entity embed with entity-id and view-mode';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalget('node/' . $node->nid);
    $this
      ->assertNoText($this->node->body[LANGUAGE_NONE][0]['value'], 'embedded node exists in page');
    $this
      ->assertRaw('</not-drupal-entity>');
    $content = '<div data-entity-type="node" data-entity-id="' . $this->node->nid . '" data-view-mode="teaser">this placeholder should not be rendered.</div>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'test entity embed with entity-id and view-mode';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalget('node/' . $node->nid);
    $this
      ->assertNoText($this->node->body[LANGUAGE_NONE][0]['value'], 'embedded node exists in page');
    $this
      ->assertRaw('<div data-entity-type="node" data-entity-id');
  }

}

/**
 * Tests the administrative UI.
 */
class EmbedButtonAdminTest extends EntityEmbedTestBase {

  /**
   * A user with permission to administer embed buttons.
   */
  protected $adminUser;
  public static function getInfo() {
    return array(
      'name' => 'Entity Embed button administration test',
      'description' => 'Tests the administrative UI for managing buttons.',
      'group' => 'Entity Embed',
    );
  }
  public function setUp() {
    parent::setUp();

    // Create a user with admin permissions.
    $this->adminUser = $this
      ->drupalCreateUser(array(
      'access content',
      'create page content',
      'use text format custom_format',
      'administer embed buttons',
    ));
  }

  /**
   * Tests the embed_button administration functionality.
   */
  function testEmbedButtonAdmin() {
    $this
      ->drupalGet('admin/config/content/embed-button');
    $this
      ->assertResponse(403, 'User without admin permissions are not able to visit the configuration page.');

    // Swtich to admin user.
    $this
      ->drupalLogin($this->adminUser);
    $this
      ->drupalGet('admin/config/content/embed-button');
    $this
      ->assertResponse(200, 'User without admin permissions is able to visit the configuration page.');
    $this
      ->assertText('Node', 'Node embed_button entity exists by default.');
    $this
      ->assertText('node', 'Node embed_button entity exists by default.');

    // Add embed button.
    $this
      ->clickLink('Add');
    $button_id = drupal_strtolower($this
      ->randomName());
    $name = $this
      ->randomName();
    $edit = array(
      'admin_title' => $name,
      'name' => $button_id,
      'entity_type' => 'node',
      'button_label' => $name,
    );
    $this
      ->drupalPost(NULL, $edit, t('Choose'));
    $this
      ->drupalPost(NULL, $edit, t('Save'));

    // Ensure that the newly created button exists.
    $this
      ->drupalGet('admin/config/content/embed-button/list/' . $button_id);
    $this
      ->assertResponse(200, 'Added embed button exists.');

    // Ensure that the newly created button is listed.
    $this
      ->drupalGet('admin/config/content/embed-button');
    $this
      ->assertText($name, 'Test embed_button appears on the list page');

    // Edit embed button.
    $this
      ->drupalGet('admin/config/content/embed-button/list/' . $button_id . '/edit');
    $new_name = drupal_strtolower($this
      ->randomName());
    $edit = array(
      'admin_title' => $new_name,
      'button_label' => $new_name,
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));

    // Ensure that name and button_label has been changed.
    $this
      ->drupalGet('admin/config/content/embed-button');
    $this
      ->assertText($new_name, 'New label appears on the list page');
    $this
      ->assertNoText($name, 'Old label does not appears on the list page');

    // Delete embed button.
    $this
      ->drupalGet('admin/config/content/embed-button/list/' . $button_id . '/delete');
    $this
      ->drupalPost(NULL, array(), t('Delete'));

    // Ensure that the deleted embed button no longer exists.
    $this
      ->drupalGet('admin/config/content/embed-button/list/' . $button_id);
    $this
      ->assertResponse(404, 'Deleted embed button no longer exists.');

    // Ensure that the deleted button is no longer listed.
    $this
      ->drupalGet('admin/config/content/embed-button');
    $this
      ->assertNoText($name, 'Test embed_button does not appears on the list page');
  }

}

/**
 * Tests the hooks provided by entity_embed.
 */
class EntityEmbedHooksTest extends EntityEmbedTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Entity Embed hooks test',
      'description' => 'Tests the hooks provided by Entity Embed.',
      'group' => 'Entity Embed',
    );
  }
  public function setUp() {
    parent::setUp('entity_embed_test', 'uuid');
  }

  /**
   * Tests the hooks provided by entity_embed module.
   *
   * This method tests all the hooks provided by entity_embed.
   */
  function testEntityEmbedHooks() {

    // Enable entity_embed_test.module's hook_entity_embed_alter()
    // implementation and ensure it is working as designed.
    variable_set('entity_embed_test_entity_embed_alter', TRUE);
    $content = '<drupal-entity data-entity-type="node" data-entity-uuid="' . $this->node->uuid . '" data-entity-embed-display="default" data-entity-embed-settings=\'{"view_mode":"full"}\'>This placeholder should not be rendered.</drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Test hook_entity_embed_alter()';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertText($this->node->body[LANGUAGE_NONE][0]['value'], 'Embedded node exists in page');
    $this
      ->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is successful.');

    // Ensure that embedded node's title has been replaced.
    $this
      ->assertText('Title set by hook_entity_embed_alter', 'Title of the embedded node is replaced by hook_entity_embed_alter()');
    $this
      ->assertNoText($this->node->title, 'Original title of the embedded node is not visible.');
    variable_set('entity_embed_test_entity_embed_alter', FALSE);

    // Enable entity_embed_test.module's hook_entity_embed_context_alter()
    // implementation and ensure it is working as designed.
    variable_set('entity_embed_test_entity_embed_context_alter', TRUE);
    $content = '<drupal-entity data-entity-type="node" data-entity-uuid="' . $this->node->uuid . '" data-entity-embed-display="default" data-entity-embed-settings=\'{"view_mode":"teaser"}\'>This placeholder should not be rendered.</drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'Test hook_entity_embed_context_alter()';
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertNoText(strip_tags($content), 'Placeholder does not appear in the output when embed is successful.');

    // To ensure that 'label' plugin is used, verify that the body of the
    // embedded node is not visible and the title links to the embedded node.
    //    $this->assertNoText($this->node->body[LANGUAGE_NONE][0]['value'], 'Body of the embedded node does not exist in page.');
    //    $this->assertText('Title set by hook_entity_embed_context_alter', 'Title of the embedded node is replaced by hook_entity_embed_context_alter()');
    //    $this->assertNoText($this->node->title, 'Original title of the embedded node is not visible.');
    $this
      ->assertLinkByHref('node/' . $this->node->nid, 0, 'Link to the embedded node exists.');
    variable_set('entity_embed_test_entity_embed_context_alter', FALSE);
  }

}

/**
 * Tests the align filter.
 */
class AlignFilterTest extends DrupalUnitTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Align filter test',
      'description' => 'Tests the alignment filter.',
      'group' => 'Entity Embed',
    );
  }
  function setUp() {
    drupal_load('module', 'entity_embed');
    parent::setUp();
  }

  /**
   * Tests the embed_button administration functionality.
   */
  function testAlignFilter() {

    // Setup dummy filter object.
    $filter = new stdClass();
    $filter->callback = '_entity_embed_filter_align';

    // No data-align attribute.
    $tests = array(
      '<img src="llama.jpg" />' => array(
        '<img src="llama.jpg" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);

    // Data-align attribute: all 3 allowed values.
    $tests = array(
      '<img src="llama.jpg" data-align="left" />' => array(
        '<img src="llama.jpg" class="align-left" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);
    $tests = array(
      '<img src="llama.jpg" data-align="center" />' => array(
        '<img src="llama.jpg" class="align-center" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);
    $tests = array(
      '<img src="llama.jpg" data-align="right" />' => array(
        '<img src="llama.jpg" class="align-right" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);

    // Data-align attribute: a disallowed value.
    $tests = array(
      '<img src="llama.jpg" data-align="left foobar" />' => array(
        '<img src="llama.jpg" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);

    // Empty data-align attribute.
    $tests = array(
      '<img src="llama.jpg" data-align="" />' => array(
        '<img src="llama.jpg" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);

    // Ensure the filter also works with uncommon yet valid attribute quoting.
    $tests = array(
      '<img src=llama.jpg data-align=right />' => array(
        '<img src="llama.jpg" class="align-right" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);

    // Security test: attempt to inject an additional class.
    $tests = array(
      '<img src="llama.jpg" data-align="center another-class-here" />' => array(
        '<img src="llama.jpg" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);

    // Security test: attempt an XSS.
    $tests = array(
      '<img src="llama.jpg" data-align="center \'onclick=\'alert(foo);" />' => array(
        '<img src="llama.jpg" />' => TRUE,
      ),
    );
    $this
      ->assertFilteredString($filter, $tests);
  }

  /**
   * Asserts multiple filter output expectations for multiple input strings.
   *
   * @param $filter
   *   A input filter object.
   * @param $tests
   *   An associative array, whereas each key is an arbitrary input string and
   *   each value is again an associative array whose keys are filter output
   *   strings and whose values are Booleans indicating whether the output is
   *   expected or not.
   *
   * For example:
   * @code
   * $tests = array(
   *   'Input string' => array(
   *     '<p>Input string</p>' => TRUE,
   *     'Input string<br' => FALSE,
   *   ),
   * );
   * @endcode
   */
  function assertFilteredString($filter, $tests) {
    foreach ($tests as $source => $tasks) {
      $function = $filter->callback;
      $result = $function($source, $filter);
      foreach ($tasks as $value => $is_expected) {

        // Not using assertIdentical, since combination with strpos() is hard to grok.
        if ($is_expected) {
          $success = $this
            ->assertTrue(strpos($result, $value) !== FALSE, format_string('@source: @value found.', array(
            '@source' => var_export($source, TRUE),
            '@value' => var_export($value, TRUE),
          )));
        }
        else {
          $success = $this
            ->assertTrue(strpos($result, $value) === FALSE, format_string('@source: @value not found.', array(
            '@source' => var_export($source, TRUE),
            '@value' => var_export($value, TRUE),
          )));
        }
        if (!$success) {
          $this
            ->verbose('Source:<pre>' . check_plain(var_export($source, TRUE)) . '</pre>' . '<hr />' . 'Result:<pre>' . check_plain(var_export($result, TRUE)) . '</pre>' . '<hr />' . ($is_expected ? 'Expected:' : 'Not expected:') . '<pre>' . check_plain(var_export($value, TRUE)) . '</pre>');
        }
      }
    }
  }

}

/**
 * Tests embed button icon file usage.
 */
class IconFileUsageTest extends EntityEmbedTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Entity Embed button icon file usage test',
      'description' => 'Tests the embed button and file usage integration.',
      'group' => 'Entity Embed',
    );
  }
  public function setUp() {
    parent::setUp('entity_embed_test');
  }

  /**
   * Tests the embed_button and file usage integration.
   */
  public function testEmbedButtonIcon() {
    $file1 = file_save_data(file_get_contents('misc/druplicon.png'));
    $file1->status = 0;
    file_save($file1);
    $file2 = file_save_data(file_get_contents('misc/druplicon.png'));
    $file1->status = 0;
    file_save($file2);
    $button = entity_embed_embed_button_new();
    $button->admin_title = 'Testing embed button instance';
    $button->name = 'test_button';
    $button->entity_type = 'node';
    $button->entity_type_bundles = array(
      'page',
    );
    $button->button_icon_fid = $file1->fid;
    $button->display_plugins = array(
      'default',
    );

    // Verify that saving a new button makes the icon file permanent.
    entity_embed_embed_button_save($button);
    $this
      ->assertTrue(file_load($file1->fid)->status == FILE_STATUS_PERMANENT);

    // Verify that updating an existing button makes the icon file permanent.
    $button->button_icon_fid = $file2->fid;
    entity_embed_embed_button_save($button);

    // Verify that replacing an existing button makes the new icon file
    // permanent and the old icon file temporary.
    $this
      ->assertTrue(file_load($file1->fid)->status == 0);
    $this
      ->assertTrue(file_load($file2->fid)->status == FILE_STATUS_PERMANENT);

    // Verify that deleting a button makes the icon file temporary.
    entity_embed_embed_button_delete($button);
    $this
      ->assertTrue(file_load($file2->fid)->status == 0);
  }

}

/**
 * Tests file usage.
 */
class EntityEmbedFileUsageTest extends EntityEmbedTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Entity Embed file usage test',
      'description' => 'Tests usage tracking of embedded file entities.',
      'group' => 'Entity Embed',
    );
  }
  public function setUp() {
    parent::setUp();
  }

  /**
   * Tests usage tracking of embedded files.
   */
  function testFileUsage() {

    // Create a file.
    $files = $this
      ->drupalGetTestFiles('image');
    $file = file_save($files[0]);
    $fid = $file->fid;

    // The file should start without any usage.
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual(empty($file_uses), TRUE, t('Created a new file without any usage.'));

    // Create a node with an embedded file.
    $content = '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $settings = array();
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $nid = $node->nid;

    // Verify that file usage increased.
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 1, t('File usage increases after embedding a file in a new node.'));

    // Create a new revision of the node that has the file on it.
    $node = node_load($nid);
    $node->revision = TRUE;
    node_save($node);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);
    $revisions = count(node_revision_list($node));

    // Keep track of this VID to test deletion later on.
    $delete_one = $node->vid;

    // Verify that there are two revisions of the node.
    // File should now be used twice.
    $this
      ->assertEqual($revisions, 2, t('Node save created a second revision'));
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 2, t('File usage incremented with a new node revision.'));

    // Create a new revision of the node that has the file on it.
    // Embed two instances of the file.
    $node = node_load($nid);
    $content = '';
    $content .= '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $content .= '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $node->body[LANGUAGE_NONE][0]['value'] = $content;
    $node->revision = TRUE;
    node_save($node);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);
    $revisions = count(node_revision_list($node));

    // Keep track of this VID to test deletion later on.
    $delete_two = $node->vid;

    // Verify that there are three revisions of the node.
    // File should now be used four times.
    $this
      ->assertEqual($revisions, 3, t('Node save created a third revision.'));
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 4, t('File usage incremented with multiple files and a new node revision.'));

    // Create a new revision of the node that has the file on it.
    // Remove all embedded files.
    $node = node_load($nid);
    $node->body[LANGUAGE_NONE][0]['value'] = '';
    $node->revision = TRUE;
    node_save($node);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);
    $revisions = count(node_revision_list($node));

    // Keep track of this VID to test deletion later on.
    $delete_zero = $node->vid;

    // Verify that there are four revisions of the node.
    // File should continue to be used four times.
    $this
      ->assertEqual($revisions, 4, t('Node save created a fourth revision.'));
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 4, t('File usage is unchanged with a new revision of the node that does not contain any embedded files.'));

    // Create a new revision of the node that has the file on it.
    // Embed one instance of the file.
    $node = node_load($nid);
    $node->body[LANGUAGE_NONE][0]['value'] = '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $node->revision = TRUE;
    node_save($node);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);
    $revisions = count(node_revision_list($node));

    // Verify that there are five revisions of the node.
    // File should now be used five times.
    $this
      ->assertEqual($revisions, 5, t('Node save created a new revision.'));
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 5, t('File usage incremented with a single file on a new node revision.'));

    // Delete a revision that has one embedded file. File usage will be 4.
    node_revision_delete($delete_one);
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 4, t('Deleting revision with file decreases file usage.'));

    // Delete a revision that has no embedded files. File usage will continue to
    // be 4.
    node_revision_delete($delete_zero);
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 4, t('Deleting revision without a file does not change file usage.'));

    // Delete a revision that has two embedded files. File usage will be 2.
    node_revision_delete($delete_two);
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 2, t('Deleting revision with file decreases file usage'));

    // Create a new revision of the node that has the file on it.
    // Embed two instances of the file.
    $node = node_load($nid);
    $content = '';
    $content .= '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $content .= '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $node->body[LANGUAGE_NONE][0]['value'] = $content;
    $node->revision = TRUE;
    node_save($node);
    $file_uses = file_usage_list($file);

    // File should now be used four times.
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 4, t('File usage incremented with files on a new node revision.'));

    // Remove one instance of the embedded file and re-save the current revision
    // of the node.
    $node = node_load($nid);
    $node->body[LANGUAGE_NONE][0]['value'] = '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $saved_vid = $node->vid;
    node_save($node);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);

    // Verify that the current revision was used.
    // File should now be used three times.
    $this
      ->assertEqual($node->vid, $saved_vid, t('Resaved node revision does not create new revision.'));
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 3, t('Resaved node revision with fewer files reduces file usage.'));

    // Delete the node.
    // The file should now be unused.
    node_delete($nid);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);

    // Verify that the node was deleted and the file is now unused.
    $this
      ->assertEqual(empty($node), TRUE, t('Node has been deleted.'));
    $this
      ->assertEqual(empty($file_uses), TRUE, t('Deleting the node removes all file uses.'));
  }

  /**
   * Tests usage tracking when deleting content or files.
   */
  function testFileUsageDeleted() {

    // Create a file.
    $files = $this
      ->drupalGetTestFiles('image');
    $file = file_save($files[1]);
    $fid = $file->fid;

    // The file should start without any usage.
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual(empty($file_uses), TRUE, t('Created a new file without any usage.'));

    // Create a node with an embedded file.
    $content = '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $settings = array();
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $nid = $node->nid;

    // Verify that file usage increased.
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 1, t('File usage increases after embedding a file in a new node.'));

    // Try to delete the file. file_delete() should return file_usage().
    $deleted = file_delete($file);
    $this
      ->assertTrue(is_array($deleted), t('File cannot be deleted while in use by a node.'));

    // Delete the node.
    node_delete($nid);
    $node = node_load($nid);
    $file_uses = file_usage_list($file);

    // Verify that the node was deleted and the file is now unused.
    $this
      ->assertEqual(empty($node), TRUE, t('Node has been deleted.'));
    $this
      ->assertEqual(empty($file_uses), TRUE, t('File has zero usage after node is deleted.'));

    // Delete the file.
    // Verify that the file can be deleted when it is unused.
    $deleted = file_delete($file);
    $this
      ->assertTrue($deleted, t('File can be deleted with no usage.'));

    // Verify that the file was deleted.
    $file = file_load($fid);
    $this
      ->assertTrue(empty($file), t('File no longer exists after delete.'));
  }

  /**
   * Tests usage tracking after forcefully deleting content or files.
   */
  function testFileUsageForcefullyDeleted() {

    // Create a file.
    $files = $this
      ->drupalGetTestFiles('image');
    $file = file_save($files[1]);
    $fid = $file->fid;

    // The file should start without any usage.
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual(empty($file_uses), TRUE, t('Created a new file without any usage.'));

    // Create a node with an embedded file.
    $content = '<drupal-entity data-entity-type="file" data-entity-id="' . $fid . '" data-view-mode="full"></drupal-entity>';
    $settings = array();
    $settings['body'] = array(
      LANGUAGE_NONE => array(
        array(
          'value' => $content,
          'format' => 'custom_format',
        ),
      ),
    );
    $node = $this
      ->drupalCreateNode($settings);
    $nid = $node->nid;

    // Verify that file usage increased.
    $file_uses = file_usage_list($file);
    $this
      ->assertEqual($file_uses['entity_embed']['node'][$nid], 1, t('File usage increases after embedding a file in a new node.'));

    // Forcefully delete the file.
    $deleted = file_delete($file, TRUE);
    $this
      ->assertTrue($deleted, t('File was deleted despite having usage.'));

    // Try to update the node that references a non-existent file.
    $account = $this
      ->drupalCreateUser(array(
      'edit any page content',
      'use text format custom_format',
    ));
    $node = node_load($nid);
    $this
      ->drupalLogin($account);
    $this
      ->drupalGet('node/' . $nid . '/edit');
    $this
      ->assertRaw(check_plain($node->body['und'][0]['value']), t('Reference to deleted file found in node body.'));
    $edit = array(
      'body[und][0][value]' => '',
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));

    // Verify that the node was save successfully.
    $type = node_type_load($node->type);
    $this
      ->assertRaw(t('@type %title has been updated.', array(
      '@type' => $type->name,
      '%title' => $node->title,
    )), t('Node without reference to deleted file saved successfully.'));
  }

}

Classes

Namesort descending Description
AlignFilterTest Tests the align filter.
EmbedButtonAdminTest Tests the administrative UI.
EntityEmbedFileUsageTest Tests file usage.
EntityEmbedFilterTest Tests the entity_embed filter.
EntityEmbedHooksTest Tests the hooks provided by entity_embed.
EntityEmbedTestBase @file Test integration for the entity_embed module.
IconFileUsageTest Tests embed button icon file usage.