diff --git a/feeds.info b/feeds.info index 0f32cdc..6e32601 100644 --- a/feeds.info +++ b/feeds.info @@ -36,7 +36,6 @@ files[] = tests/feeds_mapper_date.test files[] = tests/feeds_mapper_date_multiple.test files[] = tests/feeds_mapper_field.test files[] = tests/feeds_mapper_file.test -files[] = tests/feeds_mapper_link.test files[] = tests/feeds_mapper_path.test files[] = tests/feeds_mapper_profile.test files[] = tests/feeds_mapper_unique.test diff --git a/mappers/link.inc b/mappers/link.inc index 90b5268..2d3331e 100644 --- a/mappers/link.inc +++ b/mappers/link.inc @@ -58,5 +58,9 @@ function link_feeds_set_target($source, $entity, $target, array $values) { $delta++; } + // Filter out empty values. + $info = field_info_field($field_name); + $field['und'] = _field_filter_items($info, $field['und']); + $entity->$field_name = $field; } diff --git a/tests/feeds/feeds-tests-files-empty.tpl.php b/tests/feeds/feeds-tests-files-empty.tpl.php new file mode 100644 index 0000000..b36606d --- /dev/null +++ b/tests/feeds/feeds-tests-files-empty.tpl.php @@ -0,0 +1,6 @@ +Title,published,file,GUID,alt,title2 +"Tubing is awesome",205200720,,0,, +"Jeff vs Tom",428112720,,1,, +"Attersee",1151766000,,2,, +"H Street NE",1256326995,,3,, +"La Fayette Park",1256326995,,4,, diff --git a/tests/feeds_mapper_file.test b/tests/feeds_mapper_file.test index dcf5d98..9adfc4b 100644 --- a/tests/feeds_mapper_file.test +++ b/tests/feeds_mapper_file.test @@ -216,6 +216,130 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase { } /** + * Tests if values are cleared out when an empty value or no value + * is provided. + */ + public function testClearOutValues() { + variable_set('feeds_never_use_curl', TRUE); + + $this->createContentType(array(), array('files' => 'file')); + $typename = $this->createContentType(array(), array( + 'images' => 'image', + )); + + // Enable title and alt mapping. + $edit = array( + 'instance[settings][alt_field]' => 1, + 'instance[settings][title_field]' => 1, + ); + $this->drupalPost("admin/structure/types/manage/$typename/fields/field_images", $edit, t('Save settings')); + + // Create and configure importer. + $this->createImporterConfiguration('Content CSV', 'csv'); + $this->setSettings('csv', NULL, array( + 'content_type' => '', + 'import_period' => FEEDS_SCHEDULE_NEVER, + )); + $this->setPlugin('csv', 'FeedsCSVParser'); + $this->setSettings('csv', 'FeedsNodeProcessor', array( + 'bundle' => $typename, + 'update_existing' => 1, + )); + $this->addMappings('csv', array( + 0 => array( + 'source' => 'guid', + 'target' => 'guid', + 'unique' => TRUE, + ), + 1 => array( + 'source' => 'title', + 'target' => 'title', + ), + 2 => array( + 'source' => 'file', + 'target' => 'field_images:uri', + ), + 3 => array( + 'source' => 'title2', + 'target' => 'field_images:title', + ), + 4 => array( + 'source' => 'alt', + 'target' => 'field_images:alt', + ), + )); + + // Import. + $edit = array( + 'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-remote.csv', array('absolute' => TRUE)), + ); + $this->drupalPost('import/csv', $edit, 'Import'); + $this->assertText('Created 5 nodes'); + + // Assert files exist. + $files = $this->listTestFiles(); + foreach ($files as $file) { + $file_uri = 'public://' . rawurlencode($file); + $this->assertTrue(file_exists($file_uri), format_string('The file %file exists.', array( + '%file' => $file_uri, + ))); + } + + // Assert files exists with the expected alt/title on node edit form. + $entities = db_select('feeds_item') + ->fields('feeds_item', array('entity_id')) + ->condition('id', 'csv') + ->execute() + ->fetchAll(); + + foreach ($entities as $i => $entity) { + $this->drupalGet('node/' . $entity->entity_id . '/edit'); + $f = new FeedsEnclosure(array_shift($files), NULL); + $this->assertRaw($f->getUrlEncodedValue()); + $this->assertRaw("Alt text $i"); + $this->assertRaw("Title text $i"); + } + + // Import CSV with empty alt/title fields and check if these are removed. + $edit = array( + 'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-empty-alt-title.csv', array('absolute' => TRUE)), + ); + $this->drupalPost('import/csv', $edit, 'Import'); + $this->assertText('Updated 5 nodes'); + + $files = $this->listTestFiles(); + foreach ($entities as $i => $entity) { + $this->drupalGet('node/' . $entity->entity_id . '/edit'); + $f = new FeedsEnclosure(array_shift($files), NULL); + $this->assertRaw($f->getUrlEncodedValue()); + $this->assertNoRaw("Alt text $i"); + $this->assertNoRaw("Title text $i"); + } + + // Import CSV with empty file fields and check if all files are removed. + $edit = array( + 'feeds[FeedsHTTPFetcher][source]' => url('testing/feeds/files-empty.csv', array('absolute' => TRUE)), + ); + $this->drupalPost('import/csv', $edit, 'Import'); + $this->assertText('Updated 5 nodes'); + + // Assert files are removed. + $files = $this->listTestFiles(); + foreach ($files as $file) { + $file_uri = 'public://' . rawurlencode($file); + $this->assertFalse(file_exists($file_uri), format_string('The file %file no longer exists.', array( + '%file' => $file_uri, + ))); + } + // Check if the files are removed from the node edit form as well. + foreach ($entities as $i => $entity) { + $this->drupalGet('node/' . $entity->entity_id . '/edit'); + $f = new FeedsEnclosure(array_shift($files), NULL); + $this->assertNoRaw($f->getUrlEncodedValue()); + } + } + + /** * Lists test files. */ protected function listTestFiles() { diff --git a/tests/feeds_tests.module b/tests/feeds_tests.module index fe25704..2afacb9 100644 --- a/tests/feeds_tests.module +++ b/tests/feeds_tests.module @@ -24,6 +24,16 @@ function feeds_tests_menu() { 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); + $items['testing/feeds/files-empty-alt-title.csv'] = array( + 'page callback' => 'feeds_tests_files_empty_alt_title', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); + $items['testing/feeds/files-empty.csv'] = array( + 'page callback' => 'feeds_tests_files_empty', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); return $items; } @@ -42,6 +52,11 @@ function feeds_tests_theme() { 'path' => drupal_get_path('module', 'feeds_tests') . '/feeds', 'template' => 'feeds-tests-files', ), + 'feeds_tests_files_empty' => array( + 'variables' => array('files' => array()), + 'path' => drupal_get_path('module', 'feeds_tests') . '/feeds', + 'template' => 'feeds-tests-files-empty', + ), ); } @@ -102,6 +117,44 @@ function feeds_tests_files_remote() { } /** + * Outputs a CSV file pointing to files without alt/title. + * + * This is used to test if alt/title attributes are removed on a second import. + */ +function feeds_tests_files_empty_alt_title() { + $images = array( + 0 => 'tubing.jpeg', + 1 => 'foosball.jpeg', + 2 => 'attersee.jpeg', + 3 => 'hstreet.jpeg', + 4 => 'la fayette.jpeg', + ); + $path = drupal_get_path('module', 'feeds_tests') . '/feeds/assets'; + foreach ($images as &$image) { + $image = file_create_url("$path/$image"); + } + drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8'); + print theme('feeds_tests_files_empty', array('files' => $images)); +} + +/** + * Outputs a CSV file pointing to no files. + * + * This is used to test if files are removed on a second import. + */ +function feeds_tests_files_empty() { + $images = array( + 0 => '', + 1 => '', + 2 => '', + 3 => '', + 4 => '', + ); + drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8'); + print theme('feeds_tests_files_empty', array('files' => $images)); +} + +/** * Implements hook_feeds_processor_targets_alter(). */ function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bundle) {