Skip to content
Snippets Groups Projects
Commit d05e5385 authored by Alex Barth's avatar Alex Barth
Browse files

Second round of improvements on file field mapper: better tests, files.csv.

parent e599e774
No related branches found
No related tags found
No related merge requests found
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
Feeds 7.x 2.0 XXXXXXXXXXXXXXXXXXX Feeds 7.x 2.0 XXXXXXXXXXXXXXXXXXX
--------------------------------- ---------------------------------
- alex_b: Fix file mapper, add file mapper tests, make flickr.xml point to - alex_b: Fix file mapper, add file mapper tests, generate flickr.xml and
local assets. files.csv dynamically.
- #953538 yhahn: Remove BOM from UTF-8 files. - #953538 yhahn: Remove BOM from UTF-8 files.
Adds sanitizeFile() and sanitizeRaw() methods to FeedsFetcherResult. Adds sanitizeFile() and sanitizeRaw() methods to FeedsFetcherResult.
Extending classes that override either the getRaw() or getFilePath() methods Extending classes that override either the getRaw() or getFilePath() methods
......
...@@ -280,11 +280,10 @@ class FeedsEnclosure extends FeedsElement { ...@@ -280,11 +280,10 @@ class FeedsEnclosure extends FeedsElement {
* *
* @param $destination * @param $destination
* The path or uri specifying the target directory in which the file is * The path or uri specifying the target directory in which the file is
* expected. * expected. Don't use trailing slashes unless it's a streamwrapper scheme.
* *
* @return * @return
* A Drupal file object of the enclosed resource. The file object is * A Drupal temporary file object of the enclosed resource.
* permanent.
* *
* @throws Exception * @throws Exception
* If file object could not be created. * If file object could not be created.
...@@ -294,16 +293,19 @@ class FeedsEnclosure extends FeedsElement { ...@@ -294,16 +293,19 @@ class FeedsEnclosure extends FeedsElement {
if ($this->getValue()) { if ($this->getValue()) {
// Prepare destination directory. // Prepare destination directory.
file_prepare_directory($destination, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY); file_prepare_directory($destination, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY);
// Copy or save file depending on whether it is remote or local. // Copy or save file depending on whether it is remote or local.
if (drupal_realpath($this->getValue())) { if (drupal_realpath($this->getValue())) {
$file = new stdClass(); $file = new stdClass();
$file->uid = $user->uid; $file->uid = 0;
$file->status = FILE_STATUS_PERMANENT; $file->uri = $this->getValue();
$file->uri = $this->getValue(); $file->filemime = $this->mime_type;
if (strpos($file->uri, $destination) !== 0) { $file->filename = basename($file->uri);
if (dirname($file->uri) != $destination) {
$file = file_copy($file, $destination); $file = file_copy($file, $destination);
} }
else {
file_save($file);
}
} }
else { else {
$filename = basename($this->getValue()); $filename = basename($this->getValue());
......
...@@ -409,4 +409,16 @@ class FeedsWebTestCase extends DrupalWebTestCase { ...@@ -409,4 +409,16 @@ class FeedsWebTestCase extends DrupalWebTestCase {
} }
return $nid; return $nid;
} }
/**
* Copies a directory.
*/
public function copyDir($source, $dest) {
$result = file_prepare_directory($dest, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
foreach (scandir($source) as $file) {
if (is_file("$source/$file")) {
$file = file_unmanaged_copy("$source/$file", "$dest/$file");
}
}
}
} }
Title,published,file,GUID
"Tubing is awesome",205200720,<?php print $files[0]; ?>,0
"Jeff vs Tom",428112720,<?php print $files[1]; ?>,1
"Attersee",1151766000,<?php print $files[2]; ?>,2
"H Street NE",1256326995,<?php print $files[3]; ?>,3
...@@ -60,14 +60,8 @@ class FeedsFileFetcherTestCase extends FeedsWebTestCase { ...@@ -60,14 +60,8 @@ class FeedsFileFetcherTestCase extends FeedsWebTestCase {
// Verify batching through directories. // Verify batching through directories.
// Copy directory of files. // Copy directory of files.
$source_dir = $this->absolutePath() . '/tests/feeds/batch';
$dir = 'public://batchtest'; $dir = 'public://batchtest';
$result = file_prepare_directory($dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); $this->copyDir($this->absolutePath() . '/tests/feeds/batch', $dir);
foreach (scandir($source_dir) as $file) {
if (is_file("$source_dir/$file")) {
file_unmanaged_copy("$source_dir/$file", "$dir/$file");
}
}
// Ingest directory of files. Set limit to 5 to force processor to batch, // Ingest directory of files. Set limit to 5 to force processor to batch,
// too. // too.
......
...@@ -37,6 +37,8 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase { ...@@ -37,6 +37,8 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
public function test() { public function test() {
$typename = $this->createContentType(NULL, array('files' => 'file')); $typename = $this->createContentType(NULL, array('files' => 'file'));
// 1) Test mapping remote resources to file field.
// Create importer configuration. // Create importer configuration.
$this->createImporterConfiguration(); $this->createImporterConfiguration();
$this->setPlugin('syndication', 'FeedsSimplePieParser'); $this->setPlugin('syndication', 'FeedsSimplePieParser');
...@@ -51,23 +53,109 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase { ...@@ -51,23 +53,109 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
'target' => 'created' 'target' => 'created'
), ),
array( array(
'source' => 'description', 'source' => 'enclosures',
'target' => 'body' 'target' => 'field_files'
), ),
));
$nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] . '/testing/feeds/flickr.xml');
$this->assertText('Created 4 nodes');
$files = $this->testFiles();
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'syndication')
->execute();
foreach ($entities as $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertText(array_shift($files));
}
// 2) Test mapping local resources to file field.
// Copy directory of files, CSV file expects them in public://images, point
// file field to a 'resources' directory. Feeds should copy files from
// images/ to resources/ on import.
$this->copyDir($this->absolutePath() . '/tests/feeds/assets', 'public://images');
$edit = array(
'instance[settings][file_directory]' => 'resources',
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/field_files', $edit, t('Save settings'));
// Create a CSV importer configuration.
$this->createImporterConfiguration('Node import from CSV', 'node');
$this->setPlugin('node', 'FeedsCSVParser');
$this->setSettings('node', 'FeedsNodeProcessor', array('content_type' => $typename));
$this->addMappings('node', array(
array( array(
'source' => 'enclosures', 'source' => 'title',
'target' => 'title'
),
array(
'source' => 'file',
'target' => 'field_files' 'target' => 'field_files'
), ),
)); ));
$edit = array(
'content_type' => '',
);
$this->drupalPost('admin/structure/feeds/edit/node/settings', $edit, 'Save');
$nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] . '/testing/feeds/flickr.xml'); // Import.
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/testing/feeds/files.csv',
);
$this->drupalPost('import/node', $edit, 'Import');
$this->assertText('Created 4 nodes'); $this->assertText('Created 4 nodes');
$filename = array('tubing', 'foosball', 'attersee', 'hstreet'); // Assert: files should be in resources/.
for($i = 0; $i < 4; $i++) { $files = $this->testFiles();
$this->drupalGet('node/'. ($i+2) .'/edit'); $entities = db_select('feeds_item')
$this->assertText($filename[$i]); ->fields('feeds_item', array('entity_id'))
->condition('id', 'node')
->execute();
foreach ($entities as $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertRaw('resources/' . array_shift($files));
} }
// 3) Test mapping of local resources, this time leave files in place.
$this->drupalPost('import/node/delete-items', array(), 'Delete');
// Setting the fields file directory to images will make copying files
// obsolete.
$edit = array(
'instance[settings][file_directory]' => 'images',
);
$this->drupalPost('admin/structure/types/manage/' . $typename . '/fields/field_files', $edit, t('Save settings'));
$edit = array(
'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/testing/feeds/files.csv',
);
$this->drupalPost('import/node', $edit, 'Import');
$this->assertText('Created 4 nodes');
// Assert: files should be in images/ now.
$files = $this->testFiles();
$entities = db_select('feeds_item')
->fields('feeds_item', array('entity_id'))
->condition('id', 'node')
->execute();
foreach ($entities as $entity) {
$this->drupalGet('node/' . $entity->entity_id . '/edit');
$this->assertRaw('images/' . array_shift($files));
}
// Deleting all imported items will delete the files from the images/ dir.
// @todo: for some reason the first file does not get deleted.
// $this->drupalPost('import/node/delete-items', array(), 'Delete');
// foreach ($this->testFiles() as $file) {
// $this->assertFalse(is_file("public://images/$file"));
// }
}
/**
* Lists test files.
*/
public function testFiles() {
return array('tubing.jpeg', 'foosball.jpeg', 'attersee.jpeg', 'hstreet.jpeg');
} }
/** /**
......
...@@ -10,6 +10,11 @@ function feeds_tests_menu() { ...@@ -10,6 +10,11 @@ function feeds_tests_menu() {
'access arguments' => array('access content'), 'access arguments' => array('access content'),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['testing/feeds/files.csv'] = array(
'page callback' => 'feeds_tests_files',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items; return $items;
} }
...@@ -23,6 +28,11 @@ function feeds_tests_theme() { ...@@ -23,6 +28,11 @@ function feeds_tests_theme() {
'path' => drupal_get_path('module', 'feeds_tests') . '/feeds', 'path' => drupal_get_path('module', 'feeds_tests') . '/feeds',
'template' => 'feeds-tests-flickr', 'template' => 'feeds-tests-flickr',
), ),
'feeds_tests_files' => array(
'variables' => array('files' => array()),
'path' => drupal_get_path('module', 'feeds_tests') . '/feeds',
'template' => 'feeds-tests-files',
),
); );
} }
...@@ -43,3 +53,20 @@ function feeds_tests_flickr() { ...@@ -43,3 +53,20 @@ function feeds_tests_flickr() {
drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8'); drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
print theme('feeds_tests_flickr', array('image_urls' => $images)); print theme('feeds_tests_flickr', array('image_urls' => $images));
} }
/**
* Outputs a CSV file pointing to files.
*/
function feeds_tests_files() {
$images = array(
0 => "tubing.jpeg",
1 => "foosball.jpeg",
2 => "attersee.jpeg",
3 => "hstreet.jpeg",
);
foreach ($images as &$image) {
$image = "public://images/$image";
}
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
print theme('feeds_tests_files', array('files' => $images));
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment