? mappers/.DS_Store
Index: plugins/FeedsNodeProcessor.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsNodeProcessor.inc,v
retrieving revision 1.24
diff -u -p -r1.24 FeedsNodeProcessor.inc
--- plugins/FeedsNodeProcessor.inc	23 Feb 2010 22:24:50 -0000	1.24
+++ plugins/FeedsNodeProcessor.inc	26 Feb 2010 22:49:06 -0000
@@ -210,6 +210,14 @@ class FeedsNodeProcessor extends FeedsPr
       $target_node->teaser = $value;
       $target_node->body = $value;
     }
+    elseif ($target_element == 'user.name' || $target_element == 'user.uid') {
+      $search_field = substr($target_element, 5);  // Remove 'user.' prefix
+      $user_record = user_load(array($search_field => $value));
+      if ($user_record !== FALSE) {
+        $target_node->uid  = $user_record->uid;
+        $target_node->name = $user_record->name;
+      }
+    }
     elseif (in_array($target_element, array('title', 'status', 'created'))) {
       $target_node->$target_element = $value;
     }
@@ -237,6 +245,14 @@ class FeedsNodeProcessor extends FeedsPr
       );
     }
     $targets += array(
+      'user.uid' => array(
+        'name' => t('User ID'),
+        'description' => t('The Drupal user id of the node author.'),
+      ),
+      'user.name' => array(
+        'name' => t('Username'),
+        'description' => t('The username of the node author. Feeds will attempt to look up the Drupal user id by this name.'),
+      ),
       'status' => array(
         'name' => t('Published status'),
         'description' => t('Whether a node is published or not. 1 stands for published, 0 for not published.'),
Index: tests/feeds_mapper_user.test
===================================================================
RCS file: tests/feeds_mapper_user.test
diff -N tests/feeds_mapper_user.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/feeds_mapper_user.test	26 Feb 2010 22:49:06 -0000
@@ -0,0 +1,155 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Test case for user field mapper mappers/user.inc.
+ */
+
+require_once(drupal_get_path('module', 'feeds') . '/tests/feeds_mapper_test.inc');
+
+/**
+ * Class for testing Feeds <em>user</em> mapper.
+ */
+class FeedsMapperUserTestCase extends FeedsMapperTestCase {
+
+  // This data must match the data in the test file user_mapper.csv
+  private $testdata = array(
+    array('username' => 'pinky', 'uid' => 4, 'title' => 'User Mapper node 1'),
+    array('username' => 'brain', 'uid' => 5, 'title' => 'User Mapper node 2'),
+  );
+
+
+  public static function getInfo() {
+    return array(
+      'name' => t('Mapper: User'),
+      'description' => t('Test Feeds Mapper support for Drupal user fields.'),
+      'group' => t('Feeds'),
+    );
+  }
+
+  /**
+   * Set up the test.
+   */
+  public function setUp() {
+    // Call parent setup with the required module.
+    parent::setUp('feeds', 'feeds_ui', 'ctools');
+
+    // Create user and login.
+    $this->drupalLogin($this->drupalCreateUser(
+        array(
+          'administer content types',
+          'administer feeds',
+          'administer nodes',
+          'administer site configuration',
+        )
+    ));
+
+    // Create the required test users
+    $test_users = array('pinky', 'brain');
+    foreach ($this->testdata as $testuser) {
+      $edit = array(
+        'name'   => $testuser['username'],
+        'mail'   => $testuser['username'] . '@example.com',
+        'pass'   => user_password(),
+        'status' => 1,
+      );
+      $account = user_save('', $edit);
+      // We can't control the assigned UID, so in addition to verifying that the user
+      // was created, we also check that the UID is in sync with the expected result
+      $this->assertTrue(!empty($account->uid) && $account->uid == $testuser['uid'], t('Test user created with name %name and uid %uid', array('%name' => $edit['name'], '%uid' => $testuser['uid'])), t('Test User Setup'));
+    }
+  }
+
+  /**
+   * Basic test for Username mapping.
+   */
+  public function testUsernameMapper() {
+    // Create content type.
+    $typename = $this->createContentType(NULL, array());
+    
+    // Create the importer
+    $importer_id = 'username_test_importer';
+    $this->createCVSImporter($importer_id, $typename);
+    $this->addMappings($importer_id, array(
+      array(
+        'source' => 'title',
+        'target' => 'title',
+      ),
+      array(
+        'source' => 'guid',
+        'target' => 'guid',
+        'unique' => TRUE,
+      ),
+      array(
+        'source' => 'username',
+        'target' => 'user.name',
+      ),
+    ));
+
+    // Import CSV file.
+    $this->importFile($importer_id, $this->absolutePath() .'/tests/feeds/user_mapper.csv');
+    $this->assertText('Created 2 '. $typename .' nodes.');
+
+    // Check import results
+    $this->validateUserMapping();
+  }
+
+  /**
+   * Basic test for UID mapping.
+   */
+  public function testUIDMapper() {
+    // Create content type.
+    $typename = $this->createContentType(NULL, array());
+    
+    // Create the importer
+    $importer_id = 'uid_test_importer';
+    $this->createCVSImporter($importer_id, $typename);
+    $this->addMappings($importer_id, array(
+      array(
+        'source' => 'title',
+        'target' => 'title',
+      ),
+      array(
+        'source' => 'guid',
+        'target' => 'guid',
+        'unique' => TRUE,
+      ),
+      array(
+        'source' => 'uid',
+        'target' => 'user.uid',
+      ),
+    ));
+
+    // Import CSV file.
+    $this->importFile($importer_id, $this->absolutePath() .'/tests/feeds/user_mapper.csv');
+    $this->assertText('Created 2 '. $typename .' nodes.');
+
+    // Check import results
+    $this->validateUserMapping();
+  }
+
+  /**
+   * Convenience method for creating a basic CVS Importer
+   */
+  protected function createCVSImporter($importer_id, $typename) {
+    // Importer common configuration
+    $this->createFeedConfiguration($importer_id, $importer_id);
+    $this->setSettings($importer_id, NULL, array('content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER));
+    $this->setPlugin($importer_id, 'FeedsFileFetcher');
+    $this->setPlugin($importer_id, 'FeedsCSVParser');
+    $this->setSettings($importer_id, 'FeedsNodeProcessor', array('content_type' => $typename));
+  }
+
+
+  /**
+   * Convenience method testing for correct user mapping in the import results
+   */
+  protected function validateUserMapping() {
+    foreach ($this->testdata as $expected_result) {
+      $target_node = node_load(array('title' => $expected_result['title']));
+      $this->assertEqual($target_node->uid, $expected_result['uid'], t('UID %uid for node %title is correct', array('%uid' => $expected_result['uid'], '%title' => $expected_result['title'])));
+      $this->assertEqual($target_node->name, $expected_result['username'], t('Username %name for node %title is correct', array('%name' => $expected_result['username'], '%title' => $expected_result['title'])));
+    }
+  }
+}
Index: tests/feeds/user_mapper.csv
===================================================================
RCS file: tests/feeds/user_mapper.csv
diff -N tests/feeds/user_mapper.csv
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/feeds/user_mapper.csv	26 Feb 2010 22:49:06 -0000
@@ -0,0 +1,3 @@
+guid,title,uid,username
+tn1,User Mapper node 1,4,pinky
+tn2,User Mapper node 2,5,brain
\ No newline at end of file
