'Mapper: Taxonomy', 'description' => 'Test Feeds Mapper support for Taxonomy.', 'group' => 'Feeds', ); } public function setUp() { parent::setUp(); // Add Tags vocabulary $edit = array( 'name' => 'Tags', 'machine_name' => 'tags', ); $this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save'); $edit = array( 'name' => 'term1', ); $this->drupalPost('admin/structure/taxonomy/tags/add', $edit, t('Save')); $this->assertText('Created new term term1.'); // Create term reference field. $field = array( 'field_name' => 'field_tags', 'type' => 'taxonomy_term_reference', 'cardinality' => FIELD_CARDINALITY_UNLIMITED, 'settings' => array( 'allowed_values' => array( array( 'vocabulary' => 'tags', 'parent' => 0, ), ), ), ); field_create_field($field); // Add term reference field to feed item bundle. $this->instance = array( 'field_name' => 'field_tags', 'bundle' => 'article', 'entity_type' => 'node', 'widget' => array( 'type' => 'options_select', ), 'display' => array( 'default' => array( 'type' => 'taxonomy_term_reference_link', ), ), ); field_create_instance($this->instance); // Add term reference field to feed node bundle. $this->instance = array( 'field_name' => 'field_tags', 'bundle' => 'page', 'entity_type' => 'node', 'widget' => array( 'type' => 'options_select', ), 'display' => array( 'default' => array( 'type' => 'taxonomy_term_reference_link', ), ), ); field_create_instance($this->instance); // Create an importer configuration with basic mapping. $this->createImporterConfiguration('Syndication', 'syndication'); $this->addMappings('syndication', array( 0 => array( 'source' => 'title', 'target' => 'title', ), 1 => array( 'source' => 'description', 'target' => 'body', ), 2 => array( 'source' => 'timestamp', 'target' => 'created', ), 3 => array( 'source' => 'url', 'target' => 'url', 'unique' => TRUE, ), 4 => array( 'source' => 'guid', 'target' => 'guid', 'unique' => TRUE, ), ) ); } /** * Tests inheriting taxonomy from the feed node. */ public function testInheritTaxonomy() { // Adjust importer settings $this->setSettings('syndication', NULL, array('import_period' => FEEDS_SCHEDULE_NEVER)); $this->setSettings('syndication', NULL, array('import_on_create' => FALSE)); $this->assertText('Do not import on submission'); // Map feed node's taxonomy to feed item node's taxonomy. $mappings = array( 5 => array( 'source' => 'parent:taxonomy:tags', 'target' => 'field_tags', ), ); $this->addMappings('syndication', $mappings); // Create feed node and add term term1. $langcode = LANGUAGE_NONE; $nid = $this->createFeedNode('syndication', NULL, 'Syndication'); $term = taxonomy_get_term_by_name('term1'); $term = reset($term); $edit = array( 'field_tags' . '[' . $langcode . '][]' => $term->tid, ); $this->drupalPost("node/$nid/edit", $edit, t('Save')); $this->assertTaxonomyTerm($term->name); // Import nodes. $this->drupalPost("node/$nid/import", array(), 'Import'); $this->assertText('Created 10 nodes.'); $count = db_query("SELECT COUNT(*) FROM {taxonomy_index}")->fetchField(); // There should be one term for each node imported plus the term on the feed node. $this->assertEqual(11, $count, 'Found correct number of tags for all feed nodes and feed items.'); } /** * Tests searching taxonomy terms by name. */ public function testSearchByName() { $terms = array( 'Drupal', 'localization', 'localization client', 'localization server', 'open atrium', 'translation', 'translation server', 'Drupal planet', ); $this->setSettings('syndication', 'FeedsNodeProcessor', array( 'skip_hash_check' => TRUE, 'update_existing' => 2, )); $mappings = array( 5 => array( 'source' => 'tags', 'target' => 'field_tags', 'term_search' => 0, ), ); $this->addMappings('syndication', $mappings); $nid = $this->createFeedNode('syndication', NULL, 'Syndication'); $this->assertText('Created 10 nodes.'); // Check that terms we not auto-created. $this->drupalGet('node/2'); foreach ($terms as $term) { $this->assertNoTaxonomyTerm($term); } $this->drupalGet('node/3'); $this->assertNoTaxonomyTerm('Washington DC'); // Change the mapping configuration. $this->removeMappings('syndication', $mappings); // Turn on autocreate. $mappings[5]['autocreate'] = TRUE; $this->addMappings('syndication', $mappings); $this->drupalPost('node/' . $nid . '/import', array(), t('Import')); $this->assertText('Updated 10 nodes.'); $this->drupalGet('node/2'); foreach ($terms as $term) { $this->assertTaxonomyTerm($term); } $this->drupalGet('node/3'); $this->assertTaxonomyTerm('Washington DC'); $names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol(); $this->assertEqual(count($names), 31, 'Found correct number of terms in the database.'); // Run import again. This verifys that the terms we found by name. $this->drupalPost('node/' . $nid . '/import', array(), t('Import')); $this->assertText('Updated 10 nodes.'); $names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol(); $this->assertEqual(count($names), 31, 'Found correct number of terms in the database.'); } /** * Tests mapping to taxonomy terms by tid. */ public function testSearchByID() { // Create 10 terms. The first one was created in setup. $terms = array(1); foreach (range(2, 10) as $i) { $term = (object) array( 'name' => 'term' . $i, 'vid' => 1, ); taxonomy_term_save($term); $terms[] = $term->tid; } FeedsPlugin::loadMappers(); $entity = new stdClass(); $target = 'field_tags'; $mapping = array( 'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_ID, 'language' => LANGUAGE_NONE, ); $source = FeedsSource::instance('tmp', 0); taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping); $this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10); // Test a second mapping with a bogus term id. taxonomy_feeds_set_target($source, $entity, $target, array(1234), $mapping); $this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10); } /** * Tests mapping to a taxonomy term's guid. */ public function testSearchByGUID() { // Create 10 terms. The first one was created in setup. $tids = array(1); foreach (range(2, 10) as $i) { $term = (object) array( 'name' => 'term' . $i, 'vid' => 1, ); taxonomy_term_save($term); $tids[] = $term->tid; } // Create a bunch of bogus imported terms. $guids = array(); foreach ($tids as $tid) { $guid = 100 * $tid; $guids[] = $guid; $record = array( 'entity_type' => 'taxonomy_term', 'entity_id' => $tid, 'id' => 'does_not_exist', 'feed_nid' => 0, 'imported' => REQUEST_TIME, 'url' => '', 'guid' => $guid, ); drupal_write_record('feeds_item', $record); } FeedsPlugin::loadMappers(); $entity = new stdClass(); $target = 'field_tags'; $mapping = array( 'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_GUID, 'language' => LANGUAGE_NONE, ); $source = FeedsSource::instance('tmp', 0); taxonomy_feeds_set_target($source, $entity, $target, $guids, $mapping); $this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10); foreach ($entity->field_tags[LANGUAGE_NONE] as $delta => $values) { $this->assertEqual($tids[$delta], $values['tid'], 'Correct term id foud.'); } // Test a second mapping with a bogus term id. taxonomy_feeds_set_target($source, $entity, $target, array(1234), $mapping); $this->assertEqual(count($entity->field_tags[LANGUAGE_NONE]), 10); foreach ($entity->field_tags[LANGUAGE_NONE] as $delta => $values) { $this->assertEqual($tids[$delta], $values['tid'], 'Correct term id foud.'); } } /** * Tests importing empty values */ public function testBlankSourceValues() { // Create a CSV importer configuration. $this->createImporterConfiguration('Node import from CSV', 'node'); $this->setPlugin('node', 'FeedsFileFetcher'); $this->setPlugin('node', 'FeedsCSVParser'); $this->setSettings('node', 'FeedsNodeProcessor', array('bundle' => 'article')); $this->setSettings('node', NULL, array('content_type' => '')); $this->addMappings('node', array( 0 => array( 'source' => 'title', 'target' => 'title', ), 1 => array( 'source' => 'tags', 'target' => 'field_tags', 'term_search' => 0, 'autocreate' => 1, ), 2 => array( 'source' => 'guid', 'target' => 'guid', 'unique' => TRUE, ), )); // Verify that there are 5 nodes total. $this->importFile('node', $this->absolutePath() . '/tests/feeds/taxonomy_empty_terms.csv'); $this->assertText('Created 5 nodes'); // Make sure only two terms were added $names = db_query('SELECT name FROM {taxonomy_term_data}')->fetchCol(); $this->assertEqual(count($names), 2, 'Found correct number of terms in the database.'); // Make sure the correct terms were created $terms = array( 'term1', '0', ); foreach ($terms as $term_name) { $this->assertTrue(in_array($term_name, $names), 'Correct term created'); } } /** * Tests that there are no errors when trying to map to an invalid vocabulary. */ public function testMissingVocabulary() { $this->addMappings('syndication', array( 5 => array( 'source' => 'tags', 'target' => 'field_tags', 'term_search' => 0, 'autocreate' => TRUE, ), )); // Create an invalid configuration. db_delete('taxonomy_vocabulary')->execute(); $this->createFeedNode('syndication', NULL, 'Syndication'); $this->assertText('Created 10 nodes.'); } /** * Tests if values are cleared out when an empty value or no value * is provided. */ public function testClearOutValues() { // Create a CSV importer configuration. $this->createImporterConfiguration('Node import from CSV', 'node'); $this->setSettings('node', NULL, array( 'content_type' => '', )); $this->setPlugin('node', 'FeedsFileFetcher'); $this->setPlugin('node', 'FeedsCSVParser'); $this->setSettings('node', 'FeedsNodeProcessor', array( 'bundle' => 'article', 'update_existing' => 1, )); $this->addMappings('node', array( 0 => array( 'source' => 'title', 'target' => 'title', ), 1 => array( 'source' => 'alpha', 'target' => 'field_tags', 'term_search' => 0, 'autocreate' => 1, ), 2 => array( 'source' => 'guid', 'target' => 'guid', 'unique' => TRUE, ), )); $this->importFile('node', $this->absolutePath() . '/tests/feeds/content.csv'); $this->assertText('Created 2 nodes'); // Check the imported nodes. $terms1 = taxonomy_get_term_by_name('Lorem'); $term1 = reset($terms1); $terms2 = taxonomy_get_term_by_name('Ut wisi'); $term2 = reset($terms2); $taxonomy_values = array( 1 => $term1->tid, 2 => $term2->tid, ); for ($i = 1; $i <= 2; $i++) { $this->drupalGet("node/$i/edit"); $this->assertFieldByName('field_tags[und][]', $taxonomy_values[$i]); } // Import CSV file with empty values. $this->importFile('node', $this->absolutePath() . '/tests/feeds/content_empty.csv'); $this->assertText('Updated 2 nodes'); // Check if the taxonomy reference field was cleared out for node 1. $this->drupalGet('node/1/edit'); $this->assertFieldByName('field_tags[und][]', '_none'); $this->drupalGet('node/1'); $this->assertNoText('field_tags'); // Check if zero's didn't cleared out the taxonomy reference field for // node 2. $terms0 = taxonomy_get_term_by_name('0'); $term0 = reset($terms0); $this->drupalGet('node/2/edit'); $this->assertFieldByName('field_tags[und][]', $term0->tid); $this->drupalGet('node/2'); $this->assertText('field_tags'); // Re-import the first file again and check if the values returned. $this->importFile('node', $this->absolutePath() . '/tests/feeds/content.csv'); $this->assertText('Updated 2 nodes'); for ($i = 1; $i <= 2; $i++) { $this->drupalGet("node/$i/edit"); $this->assertFieldByName('field_tags[und][]', $taxonomy_values[$i]); } // Import CSV file with non-existent values. $this->importFile('node', $this->absolutePath() . '/tests/feeds/content_non_existent.csv'); $this->assertText('Updated 2 nodes'); // Check if the taxonomy reference field was cleared out for node 1. $this->drupalGet('node/1/edit'); $this->assertFieldByName('field_tags[und][]', '_none'); $this->drupalGet('node/1'); $this->assertNoText('field_tags'); } /** * Finds node style taxonomy term markup in DOM. */ public function assertTaxonomyTerm($term) { $term = check_plain($term); $this->assertPattern('/' . $term . '<\/a>/', 'Found ' . $term); } /** * Asserts that the term does not exist on a node page. */ public function assertNoTaxonomyTerm($term) { $term = check_plain($term); $this->assertNoPattern('/' . $term . '<\/a>/', 'Did not find ' . $term); } }