You are here

FeedsParaMapperWebTestCase.test in Feeds Paragraphs 7

Common functionality for all Paragraphs Mapper tests.

File

tests/FeedsParaMapperWebTestCase.test
View source
<?php

/**
 * @file
 * Common functionality for all Paragraphs Mapper tests.
 */

/**
 * Test basic functionality via DrupalWebTestCase.
 */
class FeedsParaMapperWebTestCase extends DrupalWebTestCase {
  protected $webUser;
  protected $profile = 'testing';
  protected $bundles;
  protected $contentType;
  protected $paragraphField;
  protected $importer;
  protected $multiValued = FALSE;
  protected $multiValuedParagraph = FALSE;
  protected $createdPlugins;
  protected $nested = FALSE;

  /**
   * Prepares the test environment.
   */
  public function setUp() {
    $args = func_get_args();
    if (isset($args[0])) {
      $this->multiValued = $args[0];
    }
    if (isset($args[1])) {
      $this->multiValuedParagraph = $args[1];
    }
    if (isset($args[2])) {
      $this->nested = $args[2];
    }
    $modules = array(
      'field',
      'field_ui',
      'image',
      'paragraphs',
      'feeds',
      'feeds_ui',
      'feeds_para_mapper',
    );
    $permissions = array(
      'bypass node access',
      'administer nodes',
      'administer feeds',
      'administer content types',
      'administer fields',
      'administer paragraphs bundles',
    );

    // If we are testing multi valued fields, load Feeds Tamper module:
    if ($this->multiValued || $this->multiValuedParagraph) {
      $modules[] = "feeds_tamper";
      $modules[] = "feeds_tamper_ui";
      $permissions[] = "administer feeds_tamper";
    }
    parent::setUp($modules);
    $this->webUser = $this
      ->drupalCreateUser($permissions);
    $this
      ->drupalLogin($this->webUser);

    // Create paragraphs bundles:
    $this
      ->createBundles();

    // Create a content type with a paragraph field:
    $this->contentType = "product";
    $this->paragraphField = "details";
    $last_key = count($this->bundles) - 1;
    $last_bundle = array(
      $this->bundles[$last_key]['name'],
    );
    $this
      ->createContentType($this->contentType, $this->paragraphField, $last_bundle);

    // Create importer for the content type:
    $this->importer = "product";
    $this
      ->addImporter($this->importer, $this->contentType);
    if ($this->nested) {
      $this
        ->isNestedCorrectly();
    }

    // Make sure that all assets files exist:
    $this
      ->assetsFilesExist();

    // Copy the image to the public path:
    $this
      ->copyFile('/tests/assets/image.png', 'public://image.png');
  }

  /**
   * Creates the needed Paragraphs bundles in a loop.
   *
   * 1- Create a bundle with a text field.
   * 2- Create another bundle with a paragraph field,
   * with the previous bundle as allowed.
   */
  protected function createBundles() {
    $counter = $this->nested ? 2 : 1;
    for ($i = 0; $i < $counter; $i++) {
      if ($i === 0) {
        $cardinality = $this->multiValued ? -1 : 1;
        $bundle = array(
          'name' => 'image_details_bundle',
          'fields' => array(
            array(
              'name' => 'description',
              'type' => "text",
              'widget' => 'text_textfield',
              'cardinality' => $cardinality,
              'mapping' => array(
                'text' => 'field_description',
              ),
              'mapping_multiple' => array(
                'text_multiple' => 'field_description',
              ),
            ),
            array(
              'name' => 'image',
              'type' => "image",
              'widget' => 'image_image',
              'cardinality' => $cardinality,
              'mapping' => array(
                'image_alt' => 'field_image:alt',
                'image_title' => 'field_image:title',
                'image_uri' => 'field_image:uri',
              ),
              'mapping_multiple' => array(
                'image_multi_alt' => 'field_image:alt',
                'image_multi_title' => 'field_image:title',
                'image_multi_uri' => 'field_image:uri',
              ),
            ),
          ),
        );
      }
      else {
        $isLast = $i + 1 === $counter;
        $cardinality = $this->multiValuedParagraph && $isLast ? -1 : 1;
        $bundle = array(
          'name' => 'image_bundle',
          'fields' => array(
            array(
              'name' => 'images',
              'type' => "paragraphs",
              'widget' => 'paragraphs_embed',
              'cardinality' => $cardinality,
              'allowed_bundles' => array(
                end($this->bundles)['name'],
              ),
            ),
          ),
        );
      }
      $this->bundles[] = $bundle;
      $this
        ->createBundle($bundle);
    }
  }

  /**
   * Creates a paragraph bundle.
   *
   * @param array $bundle
   *   Includes the bundle name and the field details.
   */
  protected function createBundle(array $bundle) {
    $this
      ->drupalGet('admin/structure/paragraphs/add');
    $edit = array(
      'name' => $bundle['name'],
      'bundle' => $bundle['name'],
    );
    $this
      ->drupalPost(NULL, $edit, t('Save Paragraph bundle'));
    $message = format_string("Created the paragraph bundle @name.", array(
      '@name' => $bundle['name'],
    ));
    $text = t("The paragraph bundle @name has been added.", array(
      '@name' => $bundle['name'],
    ));
    $this
      ->assertText($text, $message, 'Setup');

    // Add A field to the bundle:
    $bundle_name = $bundle['name'];
    $this
      ->drupalGet("admin/structure/paragraphs/{$bundle_name}/fields");
    $fields = $bundle['fields'];
    foreach ($fields as $field) {
      $allowed_bundles = array();
      if (isset($field['allowed_bundles'])) {
        $allowed_bundles = $field['allowed_bundles'];
      }
      $this
        ->createField($field['name'], $field['cardinality'], $field['type'], $field['widget'], $allowed_bundles);
    }
  }

  /**
   * Utility function to create a content type.
   *
   * @param string $name
   *   The content type name.
   * @param string $paragraph_field
   *   The paragraph field name to add to the content type.
   * @param array $allowed_bundles
   *   The allowed bundles for the paragraph field.
   */
  protected function createContentType($name, $paragraph_field, array $allowed_bundles) {
    $this
      ->drupalGet('admin/structure/types/add');
    $edit = array(
      'name' => $name,
      'type' => $name,
    );
    $this
      ->drupalPost(NULL, $edit, t('Save and add fields'));
    $text = t('The content type @name has been added.', array(
      '@name' => $name,
    ));
    $this
      ->assertText($text, NULL, "Setup");
    $fields = array();
    $cardinality = $this->multiValuedParagraph ? -1 : 1;
    $fields[$paragraph_field] = array(
      'type' => "paragraphs",
      'widget' => 'paragraphs_embed',
      'cardinality' => $cardinality,
      'bundles' => $allowed_bundles,
    );
    foreach ($fields as $field_name => $details) {
      $this
        ->createField($field_name, $details['cardinality'], $details['type'], $details['widget'], $details['bundles']);
    }

    // Somehow clicking "save" isn't enough, and we have to do a
    // node_types_rebuild().
    node_types_rebuild();
    menu_rebuild();
    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(
      ':type' => $name,
    ))
      ->fetchField();
    $this
      ->assertTrue($type_exists, "The new content type has been created in the database", "Setup");
  }

  /**
   * Utility function to create fields on a content type/paragraph bundle.
   *
   * @param string $field_name
   *   Name of the field, like field_something.
   * @param int $cardinality
   *   Cardinality.
   * @param string $type
   *   Field type.
   * @param string $widget
   *   Field widget.
   * @param array $bundles
   *   The allowed bundles if it's a paragraph field.
   */
  protected function createField($field_name, $cardinality, $type, $widget, array $bundles = array()) {

    // Add a singleton field_example_text field.
    $edit = array(
      'fields[_add_new_field][label]' => $field_name,
      'fields[_add_new_field][field_name]' => $field_name,
      'fields[_add_new_field][type]' => $type,
      'fields[_add_new_field][widget_type]' => $widget,
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));

    // There are no settings for this, so just press the button.
    $this
      ->drupalPost(NULL, array(), t('Save field settings'));
    $edit = array(
      'field[cardinality]' => (string) $cardinality,
    );
    if (isset($bundles) && count($bundles)) {
      foreach ($bundles as $bundle) {
        $edit['instance[settings][allowed_bundles_table][' . $bundle . '][enabled]'] = "1";
      }
    }

    // Using all the default settings, so press the button.
    $this
      ->drupalPost(NULL, $edit, t('Save settings'));
    $message = format_string("Field @field added successfully", array(
      "@field" => $field_name,
    ));
    $this
      ->assertText(t('Saved @name configuration.', array(
      '@name' => $field_name,
    )), $message, "Setup");
  }

  /**
   * Creates a feed importer.
   *
   * @param string $name
   *   The importer name.
   * @param string $content_type
   *   The content type to attach to the importer.
   */
  protected function addImporter($name, $content_type) {
    $this
      ->drupalGet('admin/structure/feeds/create');
    $edit = array(
      'name' => $name,
      'id' => $name,
    );
    $this
      ->drupalPost(NULL, $edit, t('Create'));
    $message = format_string("Created importer with the name @name", array(
      '@name' => $name,
    ));
    $text = t("Your configuration has been created with default settings.");
    $this
      ->assertText($text, $message, "Setup");

    // Change the fetcher to the File upload fetcher (FeedsFileFetcher).
    $this
      ->drupalGet('admin/structure/feeds/' . $name . '/fetcher');
    $edit = array(
      'plugin_key' => 'FeedsFileFetcher',
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));
    $message = "Changed the fetcher to the file fetcher";
    $text = t("Changed fetcher plugin.");
    $this
      ->assertText($text, $message, "Setup");

    // Change the parser to CSV parser (FeedsCSVParser).
    $this
      ->drupalGet('admin/structure/feeds/' . $name . '/parser');
    $edit = array(
      'plugin_key' => 'FeedsCSVParser',
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));
    $message = "Changed the parser to the CSV Parser";
    $text = t("Changed parser plugin.");
    $this
      ->assertText($text, $message, "Setup");

    // Make sure the node processor is selected.
    $this
      ->drupalGet('admin/structure/feeds/' . $name . '/processor');
    $edit = array(
      'plugin_key' => 'FeedsNodeProcessor',
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));
    $message = "Changed the processor to Node Processor";
    $text = t("Changed processor plugin.");
    $this
      ->assertText($text, $message, "Setup");

    // Change the bundle to the $content_type.
    $this
      ->drupalGet('admin/structure/feeds/' . $name . '/settings/FeedsNodeProcessor');
    $edit = array(
      'bundle' => $content_type,
      'update_existing' => '2',
      'skip_hash_check' => '1',
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));
    $message = format_string("Selected @type content type as bundle for this importer", array(
      '@type' => $content_type,
    ));
    $text = t("Your changes have been saved.");
    $this
      ->assertText($text, $message, "Setup");
  }

  /**
   * Maps source fields to target fields.
   *
   * @param array $targets
   *   Contains the source and the target string names.
   */
  protected function map(array $targets) {
    $this
      ->drupalGet('admin/structure/feeds/' . $this->importer . '/mapping');
    $targets = array_unique($targets);
    $targets['id'] = "nid";
    $config_key = 0;
    $hasSettings = $this->multiValued && $this->multiValuedParagraph;
    foreach ($targets as $source => $target) {
      $edit = array(
        'source' => $source,
        'target' => $target,
      );
      $this
        ->drupalPost(NULL, $edit, t('Save'));
      $this
        ->assertText(t("Your changes have been saved."));
      $args = array(
        '@source' => $source,
        '@target' => $target,
      );
      $message = format_string("Mapped @source source to @target field", $args);
      $this
        ->assertText(t("Mapping has been added."), $message, 'Mapping');
      if ($target === 'nid') {

        // Set the target as unique:
        $edit = array(
          "config[{$config_key}][settings][unique]" => "1",
        );
      }
      elseif ($hasSettings) {
        $edit = array(
          "config[{$config_key}][settings][max_values]" => "2",
        );
      }
      if ($target === 'nid' || $hasSettings) {

        // Click the gear button so it shows the configuration form:
        $button_name = "mapping_settings_edit_" . $config_key;
        $this
          ->drupalPostAJAX(NULL, array(), $button_name);

        // Click update button.
        $button_name = "mapping_settings_update_" . $config_key;
        $this
          ->drupalPostAJAX(NULL, $edit, $button_name);

        // Save.
        $this
          ->drupalPost(NULL, array(), t('Save'));
      }
      $config_key++;
    }
  }

  /**
   * Starts importing.
   *
   * - Maps a paragraph field to a source.
   * - Imports node to a Paragraphs field.
   *
   * @param string $path
   *   The csv file path relative to the project root directory.
   * @param bool $updating
   *   Whether we are updating nodes or creating new ones.
   * @param bool $map
   *   Whether we should also map or just import.
   */
  protected function import($path = NULL, $updating = FALSE, $map = TRUE) {
    if ($map) {

      // Map the id field:
      $targets = array();
      $multi = $this->multiValued || $this->multiValuedParagraph;
      foreach ($this->bundles[0]['fields'] as $field) {
        if ($multi) {
          $targets = array_merge($targets, $field['mapping_multiple']);
        }
        else {
          $targets = array_merge($targets, $field['mapping']);
        }
      }
      $this
        ->map($targets);
      if ($multi) {
        foreach ($targets as $source => $target) {
          $this
            ->addTamperPlugins($source);
        }
      }
    }

    // Import content:
    $this
      ->drupalGet('import/' . $this->importer);
    if (!isset($path)) {
      $path = '/tests/assets/content.csv';
    }
    $file = $this
      ->getProjectPath() . $path;
    $edit = array(
      'files[feeds]' => $file,
    );
    $this
      ->drupalPost(NULL, $edit, "Import");
    $text = $updating ? 'Updated 1 node.' : 'Created 1 node.';
    $this
      ->assertText($text);
  }

  /**
   * Check that the top host field exists on the created node.
   */
  protected function topHostParagraphsFieldExists() {
    $node = node_load(1, NULL, TRUE);
    $host_field = "field_" . $this->paragraphField;
    $host_field_exists = isset($node->{$host_field});
    $message = "The host Paragraphs field exists on the node";
    $this
      ->assertTrue($host_field_exists, $message, "Importing");

    /*
        Check if the host Paragraphs field has the id
        of the created ParagraphsItemEntity.
    */
    $lang = $node->language;
    $id_exists = isset($node->{$host_field}[$lang][0]['value']);
    $message = "The host Paragraphs field has the id of the created ParagraphsItemEntity";
    $this
      ->assertTrue($id_exists, $message);
  }

  /**
   * Check whether the top host (node) has Paragraphs entity.
   */
  protected function topHostParagraphsEntityExists() {
    $item = $this
      ->getTopHostParagraphsEntities();
    $message = "The created paragraphs item entity found";
    $this
      ->assertTrue(count($item) > 0, $message, 'Importing');
  }

  /**
   * Gets the paragraphs items attached to the created node.
   *
   * @return array
   *   The attached items array.
   */
  protected function getTopHostParagraphsEntities() {
    $node = node_load(1);
    $lang = $node->language;
    $host_field = 'field_' . $this->paragraphField;
    $items = array();
    foreach ($node->{$host_field}[$lang] as $val) {
      $id = array(
        $val['value'],
      );
      $item = entity_load('paragraphs_item', $id, array(), TRUE);
      $item = reset($item);
      $items[] = $item;
    }
    return $items;
  }

  /**
   * Checks if the Paragraphs fields are nested as expected.
   */
  protected function isNestedCorrectly() {
    krsort($this->bundles);
    $this->bundles = array_values($this->bundles);
    foreach ($this->bundles as $key => $bundle) {
      foreach ($bundle['fields'] as $field) {
        $field = 'field_' . $field['name'];
        $instance = field_info_instance('paragraphs_item', $field, $bundle['name']);

        // If we have another bundle, it should have a Paragraphs field,
        // otherwise it should contain a text field:
        if (isset($this->bundles[$key + 1])) {
          $is_paragraph = $instance['widget']['module'] === "paragraphs";
          $message = format_string("The nested field @field is paragraph", array(
            "@field" => $field,
          ));
          $this
            ->assertTrue($is_paragraph, $message, 'Setup');
          if (isset($instance['settings']['allowed_bundles'])) {
            $allowed = $instance['settings']['allowed_bundles'];
            $next = $this->bundles[$key + 1];
            $has_next_bundle = $allowed[$next['name']] === $next['name'];
            $message = format_string("the @field has the next nested bundle as allowed", array(
              "@field" => $field,
            ));
            $this
              ->assertTrue($has_next_bundle, $message, "Setup");
          }
        }
        else {
          $expected = array(
            'text',
            'image',
          );
          $field_type = $instance['widget']['module'];
          $is_expected = in_array($field_type, $expected);
          $message = format_string("the field type @type is expected", array(
            "@type" => $field_type,
          ));
          $this
            ->assertTrue($is_expected, $message, "Setup");
        }
      }
    }
    krsort($this->bundles);
    $this->bundles = array_values($this->bundles);
  }

  /**
   * Get the paragraph field values.
   *
   * @param \ParagraphsItemEntity $paragraph
   *   The paragraph entity.
   * @param string $target
   *   The target field inside the paragraph entity.
   * @param array $values
   *   The previously collected values to append to.
   *
   * @return array
   *   array of the values.
   */
  protected function getValues(\ParagraphsItemEntity $paragraph, $target, array $values = array()) {
    $target_info = field_info_field($target);
    $node = node_load(1, NULL, TRUE);
    $lang = $node->language;
    if (isset($paragraph->{$target})) {
      if ($target_info['type'] === 'paragraphs' && isset($paragraph->{$target}[$lang])) {
        foreach ($paragraph->{$target}[$lang] as $item) {
          if (isset($item['value'])) {
            $id = array(
              $item['value'],
            );
            $entity = entity_load('paragraphs_item', $id, array(), TRUE);
            $values[] = reset($entity);
          }
        }
      }
      else {
        if (isset($paragraph->{$target}[$lang])) {
          foreach ($paragraph->{$target}[$lang] as $item) {
            if ($target_info['type'] === 'text') {
              $values[] = $item['value'];
            }
            else {
              $values[] = $item;
            }
          }
        }
      }
    }
    else {
      $keys = get_object_vars($paragraph);
      foreach ($keys as $key) {
        if (is_array($key) && isset($key[$lang]) && is_array($key[$lang])) {
          foreach ($key[$lang] as $item) {
            $item_id = (int) $item['value'];
            if ($item_id) {
              $en = entity_load('paragraphs_item', array(
                $item_id,
              ), array(), TRUE);
              $en = reset($en);
              if ($en) {
                $values = $this
                  ->getValues($en, $target, $values);
              }
            }
          }
        }
      }
    }
    return $values;
  }

  /**
   * Tests Multi-valued fields importing.
   *
   * @param array $expected_values
   *   The values that the entities should have.
   * @param bool $update
   *   Whether we are updating or creating new node.
   */
  protected function multiImport(array $expected_values, $update = FALSE) {
    $this
      ->import();
    $this
      ->topHostParagraphsFieldExists();
    $this
      ->topHostParagraphsEntityExists();
    $entities_count = 2;
    if ($update) {
      $entities_count = 3;
      $path = '/tests/assets/updated_content.csv';
      $this
        ->import($path, TRUE, FALSE);
    }
    $items = $this
      ->getTopHostParagraphsEntities();
    krsort($this->bundles);
    $this->bundles = array_values($this->bundles);

    // Check to see if the total of the created entities is correct:
    $paragraphs = NULL;
    if (count($this->bundles) > 1) {
      $parent = 'field_' . $this->bundles[0]['fields'][0]['name'];
      $paragraphs = $this
        ->getValues($items[0], $parent);
    }
    else {
      $paragraphs = $items;
    }
    $message = "The created Paragraphs entities are 2";
    $this
      ->assertEqual(count($paragraphs), $entities_count, $message, "Multi-valued Importing");

    // Test the entities values:
    $lastKey = count($this->bundles) - 1;
    foreach ($this->bundles[$lastKey]['fields'] as $field) {
      $machine_name = "field_" . $field['name'];
      $values = array();
      $values_count = array();
      $total_count = 0;
      foreach ($paragraphs as $paragraph) {
        $p_values = $this
          ->getValues($paragraph, $machine_name);
        $values_count[] = count($p_values);
        $total_count += count($p_values);
        $values = array_merge($values, $p_values);
      }

      // Test if each entity has total field values of 2:
      if ($total_count !== count($expected_values[$machine_name])) {
        for ($i = 0; $i < count($values_count); $i++) {
          $item_num = $i + 1;
          $message = format_string("Paragraph entity #@num has 2 values", array(
            "@num" => $item_num,
          ));
          $this
            ->assertEqual($values_count[$i], 2, $message, "Multi-valued Importing");
        }
      }
      $found_values = array();
      $expected_field_values = NULL;
      foreach ($expected_values as $values_field => $valuesArr) {
        if ($values_field === $machine_name) {
          $expected_field_values = $valuesArr;
          foreach ($valuesArr as $expected_value) {
            foreach ($values as $value) {
              if (is_array($expected_value)) {
                $total_found = 0;
                foreach ($expected_value as $subVal) {
                  if (in_array($subVal, $value)) {
                    $total_found++;
                  }
                }
                if (count($expected_value) === $total_found) {
                  $found_values[] = $expected_value;
                }
              }
              elseif ($value === $expected_value) {
                $found_values[] = $expected_value;
              }
            }
          }
        }
      }
      $message = "All field values are found";
      $this
        ->assertEqual(count($found_values), count($expected_field_values), $message);
    }
  }

  /**
   * Add the needed Tamper plugins (explode) in a loop.
   *
   * In order to import multiple values to a field, we need to use Tamper.
   *
   * @param string $source
   *   The source name.
   */
  protected function addTamperPlugins($source) {
    if (!isset($this->createdPlugins)) {
      $this->createdPlugins = array();
    }
    if ($this->multiValuedParagraph) {
      $settings = array(
        'settings[separator]' => '|',
      );
      $des = "Separate paragraphs";
      $plugin = $this
        ->addTamperPlugin($this->importer, $source, 'explode', $des, $settings);
      $this->createdPlugins[] = array(
        'source' => $source,
        'plugin' => $plugin,
      );
    }
    if ($this->multiValued) {
      $settings = array(
        'settings[separator]' => ',',
      );
      $des = "Separate values";
      $plugin = $this
        ->addTamperPlugin($this->importer, $source, 'explode', $des, $settings);
      $this->createdPlugins[] = array(
        'source' => $source,
        'plugin' => $plugin,
      );
    }
  }

  /**
   * Creates a Tamper plugin.
   *
   * @param string $importer
   *   The importer name.
   * @param string $source
   *   The source name.
   * @param string $plugin_id
   *   The plugin to add.
   * @param string $description
   *   The plugin description.
   * @param array $settings
   *   Configuration for the plugin (e.g The separator field value).
   *
   * @return string
   *   The plugin id.
   */
  protected function addTamperPlugin($importer, $source, $plugin_id, $description, array $settings = array()) {
    $url = "admin/structure/feeds/{$importer}/tamper/add/" . bin2hex($source);
    $edit = array(
      'plugin_id' => $plugin_id,
    );
    $this
      ->drupalPost($url, $edit, t('Choose'));
    $id = str_replace(' ', '_', $description);
    $id = strtolower($id);
    $edit = array(
      'plugin_id' => $plugin_id,
      'description' => $description,
      'id' => $id,
    );
    $edit = array_merge($edit, $settings);
    $this
      ->drupalPost(NULL, $edit, t("Add"));
    return $id;
  }

  /**
   * Checks if all assets files exist.
   */
  protected function assetsFilesExist() {
    $root = $this
      ->getProjectPath();
    $assets = array(
      'content.csv' => $root . '/tests/assets/content.csv',
      'updated_content.csv' => $root . '/tests/assets/updated_content.csv',
      'image.png' => $root . '/tests/assets/image.png',
    );
    foreach ($assets as $name => $path) {
      $exists = file_exists($path);
      $message = format_string("Asset file @name exists", array(
        "@name" => $name,
      ));
      $this
        ->assertTrue($exists, $message, "Setup");
    }
  }

  /**
   * Copies a file.
   *
   * @param string $source
   *   The path of the source file.
   * @param string $dest
   *   The path of the destination directory along with the file name.
   */
  public function copyFile($source, $dest) {
    $full_path = $this
      ->getProjectPath() . $source;
    $file = file_unmanaged_copy($full_path, $dest);
    $message = format_string("The file @source copied successfully", array(
      '@source' => $source,
    ));
    $this
      ->assertTrue(is_string($file), $message);
  }

  /**
   * Gets the project path.
   *
   * @return string
   *   The path.
   */
  public function getProjectPath() {
    $root = realpath(getcwd()) . '/';
    $path = $root . drupal_get_path('module', 'feeds_para_mapper');
    return $path;
  }

}

Classes

Namesort descending Description
FeedsParaMapperWebTestCase Test basic functionality via DrupalWebTestCase.