Index: feedapi_node/tests/feedapi_cron.test
===================================================================
RCS file: feedapi_node/tests/feedapi_cron.test
diff -N feedapi_node/tests/feedapi_cron.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedapi_node/tests/feedapi_cron.test	23 Jun 2009 12:16:22 -0000
@@ -0,0 +1,49 @@
+<?php
+// $Id$
+
+require_once(dirname(__FILE__) .'/feedapi_test_case.tinc');
+
+/**
+ * Class for testing feedapi_node.
+ * It also tests FeedAPI and SimplePie parsers.
+ */
+class FeedAPICronTestsCase extends FeedAPITestCase {
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array(
+    'name' => t('FeedAPI Cron scheduling'),
+    'description' => t('Creates two feeds and see if cron respects the Minimum refresh period setting.'),
+    'group' => t('FeedAPI'),
+    );
+  }
+
+  /**
+   * Checks cron feed scheduling functionality
+   */
+  function testFeedAPICron() {
+    $this->create_type(array_pop($this->get_parsers()));
+    $this->feedapi_user();
+    $feed_urls = array();
+    $feed_urls[0] = "http://novaak.net/test_feed.rss?". $this->randomName();
+    $edit = array(
+    'feedapi[feedapi_url]' => $feed_urls[0],
+    'feedapi[refresh_time]' => 1,
+    );
+    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+    $feed_urls[1] = "http://novaak.net/test_feed_2.rss?". $this->randomName();
+    $edit = array(
+    'feedapi[feedapi_url]' => $feed_urls[1],
+    'feedapi[refresh_time]' => FEEDAPI_CRON_NEVER_REFRESH,
+    );
+    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+    $this->drupalGet('cron.php');
+    $refreshed = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} fif ON fi.nid = fif.feed_item_nid JOIN {feedapi} f ON fif.feed_nid = f.nid WHERE f.url = '%s'", $feed_urls[0]));
+    $not_refreshed = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} fif ON fi.nid = fif.feed_item_nid JOIN {feedapi} f ON fif.feed_nid = f.nid WHERE f.url = '%s'", $feed_urls[1]));
+    $this->assertTrue($refreshed > 0, 'The feed with immediate refresh setting was refreshed.');
+    $this->assertTrue($not_refreshed == 0, 'The feed with never refresh setting wasn\'t refreshed.');
+  }
+  
+}
Index: feedapi_node/tests/feedapi_node.module.test
===================================================================
RCS file: feedapi_node/tests/feedapi_node.module.test
diff -N feedapi_node/tests/feedapi_node.module.test
--- feedapi_node/tests/feedapi_node.module.test	19 Jun 2009 15:46:28 -0000	1.1.4.25
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,497 +0,0 @@
-<?php
-// $Id: feedapi_node.module.test,v 1.1.4.25 2009/06/19 15:46:28 aronnovak Exp $
-
-/**
- * Class for testing feedapi_node.
- * It also tests FeedAPI and SimplePie parsers.
- */
-class FeedAPITestsCase extends DrupalWebTestCase {
-  
-  var $info;
-
-  /**
-   * Implementation of getInfo().
-   */
-  public static function getInfo() {
-    return array(
-      'name' => t('FeedAPI Node basic functions'),
-      'description' => t('Refresh a feed and find out if it\'s okay. Uses normal node submit form and simplified too. Uses both parsers.'),
-      'group' => t('FeedAPI'),
-    );
-  }
-  
-  function setUp() {
-    parent::setUp('feedapi', 'feedapi_node', 'parser_common_syndication', 'parser_simplepie', 'upload');
-  }
-  
-  /**
-   * Login with a user who has FeedAPI rights
-   * 
-   * @param $type_edit
-   *   If TRUE, the user has the right to administer content types
-   */
-  function feedapi_user($type_edit = FALSE) {
-    $perms = array('administer feedapi', 'advanced feedapi options', 'administer nodes', "create ". $this->info->type ." content");
-    if ($type_edit == TRUE) {
-      $perms = array_merge($perms, array('administer content types', 'access administration pages'));
-    }
-    $user = $this->drupalCreateUser($perms);
-    $this->drupalGet('logout');
-    $this->drupalLogin($user);
-  }
-  
-  /**
-   * Create a new content-type for creating the feed node
-   */
-  function create_type($parser, $file_upload = FALSE) {
-    $this->info->type = 'test'. str_replace('_', '', $this->randomName());
-    $this->info->name = 'Feed'. str_replace('_', ' ', $this->randomName());
-    $this->info->description = t('Aggregates RSS or Atom feeds. Items from these feeds will be turned into nodes.');
-    $this->info->module = 'node';
-    $this->info->has_title = TRUE;
-    $this->info->title_label = t('Title');
-    $this->info->has_body = TRUE;
-    $this->info->body_label = t('Body');
-    $this->info->min_word_count = 0;
-    $this->info->custom = TRUE;
-    $type = $this->drupalCreateContentType((array) $this->info);
-    $this->assertTrue(is_object($type), 'The temporary content-type is created. The content-type name is: '. $this->info->type);
-    // Adding default FeedAPI settings
-    if ($file_upload) {
-      variable_set('feedapi_settings_'. $this->info->type, unserialize('a:4:{s:7:"enabled";s:1:"1";s:13:"upload_method";s:6:"upload";s:7:"parsers";a:1:{s:'. strlen($parser) .':"'. $parser .'";a:3:{s:7:"enabled";s:1:"1";s:6:"weight";s:1:"0";s:4:"test";s:1:"3";}}s:10:"processors";a:2:{s:12:"feedapi_node";a:4:{s:6:"weight";s:1:"0";s:12:"content_type";s:5:"story";s:9:"node_date";s:4:"feed";s:7:"enabled";s:1:"1";}s:18:"feedapi_aggregator";a:2:{s:6:"weight";s:1:"0";s:5:"block";s:1:"3";}}}'));
-    }
-    else {
-      variable_set('feedapi_settings_'. $this->info->type, unserialize('a:3:{s:7:"enabled";s:1:"1";s:7:"parsers";a:1:{s:'. strlen($parser) .':"'. $parser .'";a:3:{s:7:"enabled";s:1:"1";s:6:"weight";s:1:"0";s:4:"test";s:1:"3";}}s:10:"processors";a:2:{s:12:"feedapi_node";a:4:{s:6:"weight";s:1:"0";s:12:"content_type";s:5:"story";s:9:"node_date";s:4:"feed";s:7:"enabled";s:1:"1";}s:18:"feedapi_aggregator";a:2:{s:6:"weight";s:1:"0";s:5:"block";s:1:"3";}}}'));
-    }
-  }
-  
-  /**
-   * Returns the list of sane parsers.
-   */
-  function get_parsers() {
-    // Determine enabled and well-setup parsers
-    // @todo: the hard-wired list is suboptimal. But no way to determine the compatibility of the parser
-    $parsers_ok = array('parser_simplepie', 'parser_common_syndication');
-    foreach ($parsers_ok as $key => $parser) {
-      $status = module_invoke($parser, 'requirements', 'runtime');
-      if (isset($status[$parser]) && $status[$parser]['severity'] == REQUIREMENT_ERROR) {
-        unset($parsers_ok[$key]);
-      }
-    }
-    return $parsers_ok;
-  }
-
-  /**
-   * Add a content-type, create a feed and refresh it.
-   * Check if everything seems ok
-   * Delete the feed
-   * Check if the rubbish is purged as well.
-   * Use simplified form to create a feed
-   */
-  function testFeedAPI_Node() {
-
-    $parsers_ok = $this->get_parsers();
-    $this->assertEqual(count($parsers_ok) > 0, TRUE, 'FeedAPI has at least one parser.');
-    foreach ($parsers_ok as $parser) {
-      // Create a new content-type for creating the feed node
-      $this->create_type($parser);
-      
-      $settings = feedapi_get_settings($this->info->type);
-      $this->assertEqual($settings['parsers'][$parser]['enabled'], TRUE, $parser .' parser is enabled for the content-type '. $this->info->type);
-      
-      // Login with a user who has FeedAPI rights
-      $this->feedapi_user();
-
-      // Create the feed node
-      // Make the URL unique. It's not impossible that someone add this feed URL to the DB prior.
-      $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
-      $edit = array(
-        'feedapi[feedapi_url]' => $feed_url,
-      );
-      $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-      $this->assertText(t('Link to site'), 'The node is created.');
-
-      // Check if the entry is in the DB
-      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-      $vid = db_result(db_query_range("SELECT vid FROM {feedapi} WHERE nid = %d ORDER by vid DESC", $nid, 1, 1));
-      $this->assertEqual(is_numeric($nid), TRUE, 'The feed node is in the database');
-      $feed_node = node_load(array('nid' => $nid));
-      $this->assertEqual(is_object($feed_node->feed), TRUE, 'The feed can be loaded.');
-      
-      // Admin overview page loads and the feed can be found there with the correct number of items
-      $this->drupalGet('admin/content/feed');
-      $this->assertText('Radiovaticana.org', 'The admin overview page contains the feed title.');
-      
-      // Disable feed item expiring
-      $settings = feedapi_get_settings($this->info->type, $nid);
-      $settings['items_delete'] = FEEDAPI_NEVER_DELETE_OLD;
-      _feedapi_store_settings(array('vid' => $vid), $settings);
-
-      // Refresh the feed
-      $this->drupalGet("node/$nid/refresh");
-      $notification = t("%new new item(s) were saved. %updated existing item(s) were updated.", array("%new" => 10, "%updated" => 0));
-      $notification = str_replace('<em>', '', $notification);
-      $notification = str_replace('</em>', '', $notification);
-      $this->assertText($notification, 'The proper number of items were created');
-      
-      // Refresh fact at the admin page
-      $this->drupalGet('admin/content/feed');
-      $this->assertText('10');
-
-
-      // Check the feed items
-      $result = db_query("SELECT fi.nid FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fi.nid WHERE ff.feed_nid = %d", $nid);
-      $types = array();
-      $author_check = TRUE;
-      $item_nids = array();
-      while ($node = db_fetch_array($result)) {
-        $item_nids[] = $node['nid'];
-        $node = node_load(array('nid' => $node['nid']));
-        $types[] = $node->type;
-        // Check the length of the nodes
-        $title_size[] = strlen($node->title);
-        $body_size[] = strlen($node->body);
-        // Check the author of the nodes
-        $author_check = ($feed_node->uid == $node->uid) && $author_check;
-      }
-      $types = array_unique($types);
-      $this->assertEqual($types[0], 'story', 'The first news item is a story.');
-      $this->assertEqual(count($types), 1, 'All news items have the same type.');
-      sort($title_size);
-      sort($body_size);
-      $this->assertNotEqual($title_size[0], 0, 'All news item titles are longer than 0 character.');
-      $this->assertNotEqual($body_size[0], 0, 'All news item bodies are longer than 0 character.');
-      $this->assertTrue($author_check, 'All news items has the proper author.');
-
-      $this->drupalPost("node/$nid/purge", array(), "Yes");
-      // Remove the unwanted rubbish
-      node_delete($nid);
-
-      // Check if the news items are deleted as well
-      $item_remain = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fi.nid WHERE ff.feed_nid = %d", $nid));
-      $this->assertEqual($item_remain, 0, 'All news item database entries are deleted because of feed deletion.');
-
-      // Check if the nodes belong to the news items are really deleted
-      $node_remain = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE nid IN (%s)", implode(',', $item_nids)));
-      $this->assertEqual($node_remain, 0, 'All nodes belonging to a news item are deleted.');
-
-      // Reset node types so we get all blocks
-      node_get_types('types', NULL, TRUE);
-
-      // Generate blocks to get a simplified feed adding block for the new content-type
-      $this->drupalGet("admin/build/block");
-      _block_rehash();
-      // Disable all blocks, but remember enabled ones
-      $result = db_query("SELECT module, delta FROM {blocks} WHERE status = 1");
-      $to_disable_blocks = array();
-      while ($row = db_fetch_array($result)) {
-        $to_disable_blocks[] = $row;
-      }
-      
-      // Enable simplified form block
-      db_query("UPDATE {blocks} SET status = 0 WHERE status = 1");
-      $region = array_pop(array_keys(system_region_list(variable_get('theme_default', FALSE)))); // First region which is ok for the current theme
-      db_query("UPDATE {blocks} SET status = 1, region='%s' WHERE module = 'feedapi' AND delta = '%s'", $region, $this->info->type);
-      
-      // Check for existing block showing up
-      $this->drupalGet('node');
-      $this->assertText(t('Feed URL'), 'The block is showing up');
-
-      // Submit feed via simplified block
-      $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
-      $edit = array(
-        'url' => $feed_url,
-      );
-      $this->drupalPost('node', $edit, 'Add');
-      $this->assertText(t('Link to site'), 'The node is created via the simplified form block.');
-
-      // Check if the entry is in the DB
-      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-      $this->assertEqual(is_numeric($nid), TRUE, 'The feed node is in the database');
-
-      if (is_numeric($nid)) {
-        $values = db_fetch_array(db_query("SELECT settings, feed_type, next_refresh_time, half_done FROM {feedapi} WHERE nid = %d", $nid));
-        $sane_default = TRUE;
-        $sane_default = $sane_default || (is_array($values['settings']) && count($values['settings']) > 1);
-        $sane_default = $sane_default || ($values['feed_type'] == 'XML feed');
-        $sane_default = $sane_default || ($values['next_refresh_time'] == 0);
-        $sane_default = $sane_default || ($values['half_done'] == 0);
-        $this->assertIdentical($sane_default, TRUE, "The feed has sane default values in the database table");
-        node_delete($nid);
-      }
-
-      // Restore blocks to the user's previous settings
-      db_query("UPDATE {blocks} SET status = 0 WHERE module = 'feedapi' AND delta = '%s'", $this->info->type);
-      foreach ($to_disable_blocks as $to_enable_block) {
-        db_query("UPDATE {blocks} SET status = 1 WHERE module = '%s' AND delta ='%s'", $to_enable_block['module'], $to_enable_block['delta']);
-      }
-      
-      // Test refresh on feed creation
-      $edit = array(
-        'feedapi[feedapi_url]' => $feed_url,
-        'feedapi[refresh_on_create]' => TRUE,
-      );
-      $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-      
-      // Check if the entry is in the DB
-      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-      $this->assertEqual(is_numeric($nid), TRUE, 'The feed node is in the database');
-      
-      $this->drupalPost("node/$nid/purge", array(), "Yes");
-      // Remove the unwanted rubbish
-      node_delete($nid);
-
-      $this->drupalGet('admin/build/block');
-    }
-    menu_rebuild();
-  }
-  
-  /**
-   * Checks if the revision support works correctly
-   */
-  function testFeedAPI_Node_Revisions() {
-    $parsers_ok = $this->get_parsers();
-    // Create a new content-type for creating the feed node
-    $this->create_type(array_pop($parsers_ok));
-    // Login with a user who has FeedAPI rights
-    $this->feedapi_user();
-
-    $settings = feedapi_get_settings($this->info->type);
-    
-    // Create the initial revision, first submission
-    $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
-    $edit = array(
-      'feedapi[processors][feedapi_node][node_date]' => 'current',
-      'feedapi[feedapi_url]' => $feed_url,
-    );
-    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-    $this->assertText(t('Link to site'), 'The node is created.');
-    $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-    $vids = array();
-    // Get the current vid
-    $vids[] = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
-    
-    // Edit the node, change a setting, create a new revision
-    $edit = array(
-      'feedapi[processors][feedapi_node][node_date]' => 'feed',
-      'revision' => TRUE,
-      'log' => 'changelog blabla',
-    );
-    $this->drupalPost('node/'. $nid .'/edit', $edit, 'Save');
-    $vids[] = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
-    
-    $this->assertTrue($vids[0] != $vids[1], 'Node has two separate revisions now.');
-    $num = db_result(db_query('SELECT COUNT(*) FROM {feedapi} WHERE nid = %d', $nid));
-    $this->assertTrue($num == 2, 'Feed table contains the two revision entries.');
-    
-    $settings = array();
-    $settings[] = feedapi_get_settings(NULL, $vids[0], TRUE);
-    $settings[] = feedapi_get_settings(NULL, $vids[1], TRUE);
-    $this->assertTrue($settings[0]['processors']['feedapi_node']['node_date'] == 'current', 'The initial revision has correct setting');
-    $this->assertTrue($settings[1]['processors']['feedapi_node']['node_date'] == 'feed', 'The first revision has correct setting');
-    
-    // Do a revert to the initial revision
-    $this->drupalPost('node/'. $nid .'/revisions/'. $vids[0] .'/revert', array(), 'Revert');
-    $vids[] = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
-    $settings[] = feedapi_get_settings(NULL, $vids[2]);
-    $this->assertTrue($settings[2]['processors']['feedapi_node']['node_date'] == 'current', 'The reverted revision has correct setting.');
-    
-    $this->drupalPost("node/$nid/edit", $edit, t('Delete'));
-    $this->drupalPost("node/$nid/delete", array(), t('Delete'));
-    $num = db_result(db_query('SELECT COUNT(*) FROM {feedapi} WHERE nid = %d', $nid));
-    $this->assertTrue($num == 0, 'All revision entries were deleted from FeedAPI table');
-  }
-  
-  /**
-   * Checks if the OPML export page is basically sane.
-   */
-  function testFeedAPI_Node_Export_OPML() {
-    $parsers_ok = $this->get_parsers();
-    // Create a new content-type for creating the feed node
-    $this->create_type(array_pop($parsers_ok));
-    $this->feedapi_user();
-    $this->drupalGet('admin/content/feed/export_opml');
-    $this->assertResponse(200, 'The export OPML path returns good status code.');
-  }
-  
-  /**
-   * Checks the OPML import form.
-   */
-  function testFeedAPI_Node_Import_Form() {
-    
-    $opml = <<<EOT
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- OPML generated by UserLand Frontier v9.0 on Fri, 23 Jul 2004 23:41:33 GMT -->
-<opml version="1.1">
-	<head>
-		<title>ourFavoriteFeedsData.top100</title>
-		<dateCreated>Fri, 02 Jan 2004 12:59:58 GMT</dateCreated>
-		<dateModified>Fri, 23 Jul 2004 23:41:32 GMT</dateModified>
-		<ownerName>Dave Winer</ownerName>
-		<ownerEmail>dave@userland.com</ownerEmail>
-		<expansionState></expansionState>
-		<vertScrollState>1</vertScrollState>
-		<windowTop>20</windowTop>
-		<windowLeft>0</windowLeft>
-		<windowBottom>120</windowBottom>
-		<windowRight>147</windowRight>
-		</head>
-	<body>
-		<outline title="Scripting News" count="580" xmlUrl="http://www.scripting.com/rss.xml"/>
-		<outline title="Wired News" count="546" xmlUrl="http://www.wired.com/news_drop/netcenter/netcenter.rdf"/>
-		</body>
-	</opml>
-EOT;
-
-    $parsers = $this->get_parsers();
-    foreach ($parsers as $parser) {
-      $this->create_type($parser);
-      $this->feedapi_user();
-      $this->drupalGet('admin/content/feed/import_opml');
-      $this->assertResponse(200, 'The OPML import form is accessible.');
-      $this->assertText(t('OPML File'), 'The retrieved page contains the OPML form.');
-      $this->drupalPost('admin/content/feed/import_opml', array(), 'Import');
-      $this->assertText(t('Data could not be retrieved, invalid or empty file.'), 'The error message appears when the empty OPML import form is submitted.');
-      $opml_filename = file_directory_temp() .'/'. md5($opml);
-      file_put_contents($opml_filename, $opml);
-      $edit['files[opml]'] = $opml_filename;
-      $edit['feed_type'] = $this->info->type;
-      $edit['override_title'] = TRUE;
-      $edit['override_body'] = FALSE;
-      $this->drupalPost('admin/content/feed/import_opml', $edit, 'Import');
-      
-      $nid = db_result(db_query("SELECT n.nid FROM {node} n LEFT JOIN {feedapi} f ON n.nid = f.nid WHERE f.url = '%s' ORDER BY nid DESC", 'http://www.scripting.com/rss.xml'));
-      $node = node_load($nid);
-      $this->assertTrue(is_object($node), 'The first entry of OPML can be loaded as a node.');
-      node_delete($nid);
-      unlink($opml_filename);
-    }
-  }
-  
-  function testFeedAPI_Feed_Delete_By_UI() {
-    $parsers = $this->get_parsers();
-    foreach ($parsers as $parser) {
-      $this->create_type($parser);
-      $this->feedapi_user();
-      $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
-      $edit = array(
-        'feedapi[feedapi_url]' => $feed_url,
-      );
-      $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-      $node = db_fetch_object(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-      $this->drupalPost("node/{$node->nid}/edit", $edit, t('Delete'));
-      $this->assertText(t('This action cannot be undone.'), 'The feed node can be deleted via the user interface.');
-      $this->drupalPost("node/{$node->nid}/delete", array(), t('Delete'));
-      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-      $this->assertTrue(empty($nid), 'The feed node is deleted via the user interface.');
-    }
-  }
-  
-  /**
-   * Checks basic content-type form.
-   */
-  function testContentType_Setting_Page() {
-    $this->create_type(array_pop($this->get_parsers()));
-    $this->feedapi_user(TRUE);
-    $parsers_ok = $this->get_parsers();
-    $this->create_type(array_shift($parsers_ok));
-    $this->drupalGet('admin/content/node-type/'. $this->info->type);
-    $this->assertText(t('FeedAPI'), 'The FeedAPI group appears at content-type edit page.');
-    $this->assertText(t('Created date of item nodes'), 'FeedAPI Node settings at content-type edit page.');
-  }
-  
-  /**
-   * Checks cron feed scheduling functionality
-   */
-  function testFeedAPICron() {
-    $this->create_type(array_pop($this->get_parsers()));
-    $this->feedapi_user();
-    $feed_urls = array();
-    $feed_urls[0] = "http://novaak.net/test_feed.rss?". $this->randomName();
-    $edit = array(
-      'feedapi[feedapi_url]' => $feed_urls[0],
-      'feedapi[refresh_time]' => 1,
-    );
-    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-    $feed_urls[1] = "http://novaak.net/test_feed_2.rss?". $this->randomName();
-    $edit = array(
-      'feedapi[feedapi_url]' => $feed_urls[1],
-      'feedapi[refresh_time]' => FEEDAPI_CRON_NEVER_REFRESH,
-    );
-    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-    $this->drupalGet('cron.php');
-    $refreshed = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} fif ON fi.nid = fif.feed_item_nid JOIN {feedapi} f ON fif.feed_nid = f.nid WHERE f.url = '%s'", $feed_urls[0]));
-    $not_refreshed = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} fif ON fi.nid = fif.feed_item_nid JOIN {feedapi} f ON fif.feed_nid = f.nid WHERE f.url = '%s'", $feed_urls[1]));
-    $this->assertTrue($refreshed > 0, 'The feed with immediate refresh setting was refreshed.');
-    $this->assertTrue($not_refreshed == 0, 'The feed with never refresh setting wasn\'t refreshed.');
-  }
-  
-  /**
-   * Test the file upload form
-   */
-  function testFileUploadAbility() {
-    $this->create_type(array_pop($this->get_parsers()), TRUE);
-    $settings = feedapi_get_settings($this->info->type);
-    $this->feedapi_user();
-    $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
-    $edit = array(
-      'files[feedapi]' => drupal_get_path('module', 'feedapi_node'). '/tests/files/feed',
-    );
-    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-    $this->assertText('drupal.org', 'The feed title is on the saved node.');
-    $status = db_result(db_query('SELECT status FROM {files}'));
-    $this->assertEqual($status, FILE_STATUS_PERMANENT, 'The uploaded file is permanent');
-  }
-  
-  /**
-   * Checks if the node updates by feedapi_node do not alter basic node options
-   */
-  function testKeepNodeSettingsAtUpdate() {
-    $this->create_type(array_pop($this->get_parsers()));
-    $settings = feedapi_get_settings($this->info->type);
-    $this->feedapi_user();
-    $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
-    $edit = array(
-      'feedapi[feedapi_url]' => $feed_url,
-    );
-    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
-    $node = db_fetch_object(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
-    $this->drupalGet("node/{$node->nid}/refresh");
-    $notification = t("%new new item(s) were saved. %updated existing item(s) were updated.", array("%new" => 10, "%updated" => 0));
-    $notification = str_replace('<em>', '', $notification);
-    $notification = str_replace('</em>', '', $notification);
-    $this->assertText($notification, 'The proper number of items were created');
-    
-    // Get one item's nid and guid
-    $existing_item = db_fetch_array(db_query_range('SELECT nid, guid, url from {feedapi_node_item} fi join {feedapi_node_item_feed} fif ON fi.nid = fif.feed_item_nid WHERE fif.feed_nid = %d', $node->nid, 1, 1));
-    
-    
-    $sticky = db_result(db_query("SELECT sticky FROM {node} WHERE nid = %d", $existing_item['nid']));
-    $this->assertTrue(!$sticky, 'The sticky bit is off by default.');
-    
-    // Set the sticky to 1 on the item
-    db_query("UPDATE {node} SET sticky = 1 WHERE nid = %d", $existing_item['nid']);
-    
-    $item = new stdClass();
-    $item->nid = 
-    $item->title = $this->randomName(59);
-    $item->description = $this->randomName(666);
-    $item->options = new stdClass();
-    $item->options->guid = $existing_item['guid'];
-    $item->options->original_url = $existing_item['url'];
-    $item->options->timestamp = time();
-    module_invoke('feedapi_node', 'feedapi_item', 'update', $item, $node->nid, $settings['processors']['feedapi_node'], $existing_item['nid']);
-    
-    $sticky = db_result(db_query("SELECT sticky FROM {node} WHERE nid = %d", $existing_item['nid']));
-    $this->assertTrue($sticky, 'The sticky bit remained the same just as before the update');
-    
-    $this->drupalGet('node/'. $existing_item['nid']);
-    $this->assertText($item->title, 'The item node update was successful');
-    $this->assertText($item->description, 'The item node update was successful');
-    
-    $this->drupalGet('/');
-    $this->assertText($item->title, 'The item node really appears on the first page.');
-    
-  }
-  
-}
Index: feedapi_node/tests/feedapi_node.test
===================================================================
RCS file: feedapi_node/tests/feedapi_node.test
diff -N feedapi_node/tests/feedapi_node.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedapi_node/tests/feedapi_node.test	23 Jun 2009 12:16:22 -0000
@@ -0,0 +1,288 @@
+<?php
+// $Id$
+
+require_once(dirname(__FILE__) .'/feedapi_test_case.tinc');
+
+/**
+ * Class for testing feedapi_node.
+ * It also tests FeedAPI and SimplePie parsers.
+ */
+class FeedAPINodeTestsCase extends FeedAPITestCase {
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('FeedAPI Node basic functions'),
+      'description' => t('Refresh a feed and find out if it\'s okay. Uses normal node submit form and simplified too. Uses both parsers.'),
+      'group' => t('FeedAPI'),
+    );
+  }
+
+  /**
+   * Add a content-type, create a feed and refresh it.
+   * Check if everything seems ok
+   * Delete the feed
+   * Check if the rubbish is purged as well.
+   * Use simplified form to create a feed
+   */
+  function testFeedAPI_Node() {
+
+    $parsers_ok = $this->get_parsers();
+    $this->assertEqual(count($parsers_ok) > 0, TRUE, 'FeedAPI has at least one parser.');
+    foreach ($parsers_ok as $parser) {
+      // Create a new content-type for creating the feed node
+      $this->create_type($parser);
+      
+      $settings = feedapi_get_settings($this->info->type);
+      $this->assertEqual($settings['parsers'][$parser]['enabled'], TRUE, $parser .' parser is enabled for the content-type '. $this->info->type);
+      
+      // Login with a user who has FeedAPI rights
+      $this->feedapi_user();
+
+      // Create the feed node
+      // Make the URL unique. It's not impossible that someone add this feed URL to the DB prior.
+      $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
+      $edit = array(
+        'feedapi[feedapi_url]' => $feed_url,
+      );
+      $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+      $this->assertText(t('Link to site'), 'The node is created.');
+
+      // Check if the entry is in the DB
+      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+      $vid = db_result(db_query_range("SELECT vid FROM {feedapi} WHERE nid = %d ORDER by vid DESC", $nid, 1, 1));
+      $this->assertEqual(is_numeric($nid), TRUE, 'The feed node is in the database');
+      $feed_node = node_load(array('nid' => $nid));
+      $this->assertEqual(is_object($feed_node->feed), TRUE, 'The feed can be loaded.');
+      
+      // Admin overview page loads and the feed can be found there with the correct number of items
+      $this->drupalGet('admin/content/feed');
+      $this->assertText('Radiovaticana.org', 'The admin overview page contains the feed title.');
+      
+      // Disable feed item expiring
+      $settings = feedapi_get_settings($this->info->type, $nid);
+      $settings['items_delete'] = FEEDAPI_NEVER_DELETE_OLD;
+      _feedapi_store_settings(array('vid' => $vid), $settings);
+
+      // Refresh the feed
+      $this->drupalGet("node/$nid/refresh");
+      $notification = t("%new new item(s) were saved. %updated existing item(s) were updated.", array("%new" => 10, "%updated" => 0));
+      $notification = str_replace('<em>', '', $notification);
+      $notification = str_replace('</em>', '', $notification);
+      $this->assertText($notification, 'The proper number of items were created');
+      
+      // Refresh fact at the admin page
+      $this->drupalGet('admin/content/feed');
+      $this->assertText('10');
+
+
+      // Check the feed items
+      $result = db_query("SELECT fi.nid FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fi.nid WHERE ff.feed_nid = %d", $nid);
+      $types = array();
+      $author_check = TRUE;
+      $item_nids = array();
+      while ($node = db_fetch_array($result)) {
+        $item_nids[] = $node['nid'];
+        $node = node_load(array('nid' => $node['nid']));
+        $types[] = $node->type;
+        // Check the length of the nodes
+        $title_size[] = strlen($node->title);
+        $body_size[] = strlen($node->body);
+        // Check the author of the nodes
+        $author_check = ($feed_node->uid == $node->uid) && $author_check;
+      }
+      $types = array_unique($types);
+      $this->assertEqual($types[0], 'story', 'The first news item is a story.');
+      $this->assertEqual(count($types), 1, 'All news items have the same type.');
+      sort($title_size);
+      sort($body_size);
+      $this->assertNotEqual($title_size[0], 0, 'All news item titles are longer than 0 character.');
+      $this->assertNotEqual($body_size[0], 0, 'All news item bodies are longer than 0 character.');
+      $this->assertTrue($author_check, 'All news items has the proper author.');
+
+      $this->drupalPost("node/$nid/purge", array(), "Yes");
+      // Remove the unwanted rubbish
+      node_delete($nid);
+
+      // Check if the news items are deleted as well
+      $item_remain = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fi.nid WHERE ff.feed_nid = %d", $nid));
+      $this->assertEqual($item_remain, 0, 'All news item database entries are deleted because of feed deletion.');
+
+      // Check if the nodes belong to the news items are really deleted
+      $node_remain = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE nid IN (%s)", implode(',', $item_nids)));
+      $this->assertEqual($node_remain, 0, 'All nodes belonging to a news item are deleted.');
+
+      // Reset node types so we get all blocks
+      node_get_types('types', NULL, TRUE);
+
+      // Generate blocks to get a simplified feed adding block for the new content-type
+      $this->drupalGet("admin/build/block");
+      _block_rehash();
+      // Disable all blocks, but remember enabled ones
+      $result = db_query("SELECT module, delta FROM {blocks} WHERE status = 1");
+      $to_disable_blocks = array();
+      while ($row = db_fetch_array($result)) {
+        $to_disable_blocks[] = $row;
+      }
+      
+      // Enable simplified form block
+      db_query("UPDATE {blocks} SET status = 0 WHERE status = 1");
+      $region = array_pop(array_keys(system_region_list(variable_get('theme_default', FALSE)))); // First region which is ok for the current theme
+      db_query("UPDATE {blocks} SET status = 1, region='%s' WHERE module = 'feedapi' AND delta = '%s'", $region, $this->info->type);
+      
+      // Check for existing block showing up
+      $this->drupalGet('node');
+      $this->assertText(t('Feed URL'), 'The block is showing up');
+
+      // Submit feed via simplified block
+      $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
+      $edit = array(
+        'url' => $feed_url,
+      );
+      $this->drupalPost('node', $edit, 'Add');
+      $this->assertText(t('Link to site'), 'The node is created via the simplified form block.');
+
+      // Check if the entry is in the DB
+      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+      $this->assertEqual(is_numeric($nid), TRUE, 'The feed node is in the database');
+
+      if (is_numeric($nid)) {
+        $values = db_fetch_array(db_query("SELECT settings, feed_type, next_refresh_time, half_done FROM {feedapi} WHERE nid = %d", $nid));
+        $sane_default = TRUE;
+        $sane_default = $sane_default || (is_array($values['settings']) && count($values['settings']) > 1);
+        $sane_default = $sane_default || ($values['feed_type'] == 'XML feed');
+        $sane_default = $sane_default || ($values['next_refresh_time'] == 0);
+        $sane_default = $sane_default || ($values['half_done'] == 0);
+        $this->assertIdentical($sane_default, TRUE, "The feed has sane default values in the database table");
+        node_delete($nid);
+      }
+
+      // Restore blocks to the user's previous settings
+      db_query("UPDATE {blocks} SET status = 0 WHERE module = 'feedapi' AND delta = '%s'", $this->info->type);
+      foreach ($to_disable_blocks as $to_enable_block) {
+        db_query("UPDATE {blocks} SET status = 1 WHERE module = '%s' AND delta ='%s'", $to_enable_block['module'], $to_enable_block['delta']);
+      }
+      
+      // Test refresh on feed creation
+      $edit = array(
+        'feedapi[feedapi_url]' => $feed_url,
+        'feedapi[refresh_on_create]' => TRUE,
+      );
+      $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+      
+      // Check if the entry is in the DB
+      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+      $this->assertEqual(is_numeric($nid), TRUE, 'The feed node is in the database');
+      
+      $this->drupalPost("node/$nid/purge", array(), "Yes");
+      // Remove the unwanted rubbish
+      node_delete($nid);
+
+      $this->drupalGet('admin/build/block');
+    }
+    menu_rebuild();
+  }
+    
+  function testFeedAPI_Feed_Delete_By_UI() {
+    $parsers = $this->get_parsers();
+    foreach ($parsers as $parser) {
+      $this->create_type($parser);
+      $this->feedapi_user();
+      $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
+      $edit = array(
+        'feedapi[feedapi_url]' => $feed_url,
+      );
+      $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+      $node = db_fetch_object(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+      $this->drupalPost("node/{$node->nid}/edit", $edit, t('Delete'));
+      $this->assertText(t('This action cannot be undone.'), 'The feed node can be deleted via the user interface.');
+      $this->drupalPost("node/{$node->nid}/delete", array(), t('Delete'));
+      $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+      $this->assertTrue(empty($nid), 'The feed node is deleted via the user interface.');
+    }
+  }
+  
+  /**
+   * Checks basic content-type form.
+   */
+  function testContentType_Setting_Page() {
+    $this->create_type(array_pop($this->get_parsers()));
+    $this->feedapi_user(TRUE);
+    $parsers_ok = $this->get_parsers();
+    $this->create_type(array_shift($parsers_ok));
+    $this->drupalGet('admin/content/node-type/'. $this->info->type);
+    $this->assertText(t('FeedAPI'), 'The FeedAPI group appears at content-type edit page.');
+    $this->assertText(t('Created date of item nodes'), 'FeedAPI Node settings at content-type edit page.');
+  }
+  
+  /**
+   * Test the file upload form
+   */
+  function testFileUploadAbility() {
+    $this->create_type(array_pop($this->get_parsers()), TRUE);
+    $settings = feedapi_get_settings($this->info->type);
+    $this->feedapi_user();
+    $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
+    $edit = array(
+      'files[feedapi]' => drupal_get_path('module', 'feedapi_node'). '/tests/files/feed',
+    );
+    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+    $this->assertText('drupal.org', 'The feed title is on the saved node.');
+    $status = db_result(db_query('SELECT status FROM {files}'));
+    $this->assertEqual($status, FILE_STATUS_PERMANENT, 'The uploaded file is permanent');
+  }
+  
+  /**
+   * Checks if the node updates by feedapi_node do not alter basic node options
+   */
+  function testKeepNodeSettingsAtUpdate() {
+    $this->create_type(array_pop($this->get_parsers()));
+    $settings = feedapi_get_settings($this->info->type);
+    $this->feedapi_user();
+    $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
+    $edit = array(
+      'feedapi[feedapi_url]' => $feed_url,
+    );
+    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+    $node = db_fetch_object(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+    $this->drupalGet("node/{$node->nid}/refresh");
+    $notification = t("%new new item(s) were saved. %updated existing item(s) were updated.", array("%new" => 10, "%updated" => 0));
+    $notification = str_replace('<em>', '', $notification);
+    $notification = str_replace('</em>', '', $notification);
+    $this->assertText($notification, 'The proper number of items were created');
+    
+    // Get one item's nid and guid
+    $existing_item = db_fetch_array(db_query_range('SELECT nid, guid, url from {feedapi_node_item} fi join {feedapi_node_item_feed} fif ON fi.nid = fif.feed_item_nid WHERE fif.feed_nid = %d', $node->nid, 1, 1));
+    
+    
+    $sticky = db_result(db_query("SELECT sticky FROM {node} WHERE nid = %d", $existing_item['nid']));
+    $this->assertTrue(!$sticky, 'The sticky bit is off by default.');
+    
+    // Set the sticky to 1 on the item
+    db_query("UPDATE {node} SET sticky = 1 WHERE nid = %d", $existing_item['nid']);
+    
+    $item = new stdClass();
+    $item->nid = 
+    $item->title = $this->randomName(59);
+    $item->description = $this->randomName(666);
+    $item->options = new stdClass();
+    $item->options->guid = $existing_item['guid'];
+    $item->options->original_url = $existing_item['url'];
+    $item->options->timestamp = time();
+    module_invoke('feedapi_node', 'feedapi_item', 'update', $item, $node->nid, $settings['processors']['feedapi_node'], $existing_item['nid']);
+    
+    $sticky = db_result(db_query("SELECT sticky FROM {node} WHERE nid = %d", $existing_item['nid']));
+    $this->assertTrue($sticky, 'The sticky bit remained the same just as before the update');
+    
+    $this->drupalGet('node/'. $existing_item['nid']);
+    $this->assertText($item->title, 'The item node update was successful');
+    $this->assertText($item->description, 'The item node update was successful');
+    
+    $this->drupalGet('/');
+    $this->assertText($item->title, 'The item node really appears on the first page.');
+    
+  }
+  
+}
Index: feedapi_node/tests/feedapi_opml.test
===================================================================
RCS file: feedapi_node/tests/feedapi_opml.test
diff -N feedapi_node/tests/feedapi_opml.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedapi_node/tests/feedapi_opml.test	23 Jun 2009 12:16:22 -0000
@@ -0,0 +1,90 @@
+<?php
+// $Id$
+
+require_once(dirname(__FILE__) .'/feedapi_test_case.tinc');
+
+/**
+ * Class for testing feedapi_node.
+ * It also tests FeedAPI and SimplePie parsers.
+ */
+class FeedAPIOPMLTestsCase extends FeedAPITestCase {
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('FeedAPI OPML support'),
+      'description' => t('Tests both OPML import and export functionality.'),
+      'group' => t('FeedAPI'),
+    );
+  }
+
+  /**
+   * Checks if the OPML export page is basically sane.
+   */
+  function testFeedAPI_Node_Export_OPML() {
+    $parsers_ok = $this->get_parsers();
+    // Create a new content-type for creating the feed node
+    $this->create_type(array_pop($parsers_ok));
+    $this->feedapi_user();
+    $this->drupalGet('admin/content/feed/export_opml');
+    $this->assertResponse(200, 'The export OPML path returns good status code.');
+  }
+
+  /**
+   * Checks the OPML import form.
+   */
+  function testFeedAPI_Node_Import_Form() {
+
+    $opml = <<<EOT
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- OPML generated by UserLand Frontier v9.0 on Fri, 23 Jul 2004 23:41:33 GMT -->
+<opml version="1.1">
+	<head>
+		<title>ourFavoriteFeedsData.top100</title>
+		<dateCreated>Fri, 02 Jan 2004 12:59:58 GMT</dateCreated>
+		<dateModified>Fri, 23 Jul 2004 23:41:32 GMT</dateModified>
+		<ownerName>Dave Winer</ownerName>
+		<ownerEmail>dave@userland.com</ownerEmail>
+		<expansionState></expansionState>
+		<vertScrollState>1</vertScrollState>
+		<windowTop>20</windowTop>
+		<windowLeft>0</windowLeft>
+		<windowBottom>120</windowBottom>
+		<windowRight>147</windowRight>
+		</head>
+	<body>
+		<outline title="Scripting News" count="580" xmlUrl="http://www.scripting.com/rss.xml"/>
+		<outline title="Wired News" count="546" xmlUrl="http://www.wired.com/news_drop/netcenter/netcenter.rdf"/>
+		</body>
+	</opml>
+EOT;
+
+    $parsers = $this->get_parsers();
+    foreach ($parsers as $parser) {
+      $this->create_type($parser);
+      $this->feedapi_user();
+      $this->drupalGet('admin/content/feed/import_opml');
+      $this->assertResponse(200, 'The OPML import form is accessible.');
+      $this->assertText(t('OPML File'), 'The retrieved page contains the OPML form.');
+      $this->drupalPost('admin/content/feed/import_opml', array(), 'Import');
+      $this->assertText(t('Data could not be retrieved, invalid or empty file.'), 'The error message appears when the empty OPML import form is submitted.');
+      $opml_filename = file_directory_temp() .'/'. md5($opml);
+      file_put_contents($opml_filename, $opml);
+      $edit['files[opml]'] = $opml_filename;
+      $edit['feed_type'] = $this->info->type;
+      $edit['override_title'] = TRUE;
+      $edit['override_body'] = FALSE;
+      $this->drupalPost('admin/content/feed/import_opml', $edit, 'Import');
+
+      $nid = db_result(db_query("SELECT n.nid FROM {node} n LEFT JOIN {feedapi} f ON n.nid = f.nid WHERE f.url = '%s' ORDER BY nid DESC", 'http://www.scripting.com/rss.xml'));
+      $node = node_load($nid);
+      $this->assertTrue(is_object($node), 'The first entry of OPML can be loaded as a node.');
+      node_delete($nid);
+      unlink($opml_filename);
+    }
+  }
+
+
+}
\ No newline at end of file
Index: feedapi_node/tests/feedapi_revision.test
===================================================================
RCS file: feedapi_node/tests/feedapi_revision.test
diff -N feedapi_node/tests/feedapi_revision.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedapi_node/tests/feedapi_revision.test	23 Jun 2009 12:16:22 -0000
@@ -0,0 +1,80 @@
+<?php
+// $Id$
+
+require_once(dirname(__FILE__) .'/feedapi_test_case.tinc');
+
+/**
+ * Class for testing feedapi_node.
+ * It also tests FeedAPI and SimplePie parsers.
+ */
+class FeedAPIRevisionTestsCase extends FeedAPITestCase {
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('FeedAPI revision support'),
+      'description' => t('Creates a feed and then creates a new revision with different configuration and revert the original node / feed.'),
+      'group' => t('FeedAPI'),
+    );
+  }
+
+
+  /**
+   * Checks if the revision support works correctly
+   */
+  function testFeedAPI_Node_Revisions() {
+    $parsers_ok = $this->get_parsers();
+    // Create a new content-type for creating the feed node
+    $this->create_type(array_pop($parsers_ok));
+    // Login with a user who has FeedAPI rights
+    $this->feedapi_user();
+
+    $settings = feedapi_get_settings($this->info->type);
+
+    // Create the initial revision, first submission
+    $feed_url = "http://novaak.net/test_feed.rss?". $this->randomName();
+    $edit = array(
+    'feedapi[processors][feedapi_node][node_date]' => 'current',
+    'feedapi[feedapi_url]' => $feed_url,
+    );
+    $this->drupalPost('node/add/'. $this->info->type, $edit, 'Save');
+    $this->assertText(t('Link to site'), 'The node is created.');
+    $nid = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed_url));
+    $vids = array();
+    // Get the current vid
+    $vids[] = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
+
+    // Edit the node, change a setting, create a new revision
+    $edit = array(
+    'feedapi[processors][feedapi_node][node_date]' => 'feed',
+    'revision' => TRUE,
+    'log' => 'changelog blabla',
+    );
+    $this->drupalPost('node/'. $nid .'/edit', $edit, 'Save');
+    $vids[] = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
+
+    $this->assertTrue($vids[0] != $vids[1], 'Node has two separate revisions now.');
+    $num = db_result(db_query('SELECT COUNT(*) FROM {feedapi} WHERE nid = %d', $nid));
+    $this->assertTrue($num == 2, 'Feed table contains the two revision entries.');
+
+    $settings = array();
+    $settings[] = feedapi_get_settings(NULL, $vids[0], TRUE);
+    $settings[] = feedapi_get_settings(NULL, $vids[1], TRUE);
+    $this->assertTrue($settings[0]['processors']['feedapi_node']['node_date'] == 'current', 'The initial revision has correct setting');
+    $this->assertTrue($settings[1]['processors']['feedapi_node']['node_date'] == 'feed', 'The first revision has correct setting');
+
+    // Do a revert to the initial revision
+    $this->drupalPost('node/'. $nid .'/revisions/'. $vids[0] .'/revert', array(), 'Revert');
+    $vids[] = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid));
+    $settings[] = feedapi_get_settings(NULL, $vids[2]);
+    $this->assertTrue($settings[2]['processors']['feedapi_node']['node_date'] == 'current', 'The reverted revision has correct setting.');
+
+    $this->drupalPost("node/$nid/edit", $edit, t('Delete'));
+    $this->drupalPost("node/$nid/delete", array(), t('Delete'));
+    $num = db_result(db_query('SELECT COUNT(*) FROM {feedapi} WHERE nid = %d', $nid));
+    $this->assertTrue($num == 0, 'All revision entries were deleted from FeedAPI table');
+  }
+
+}
Index: feedapi_node/tests/feedapi_test_case.tinc
===================================================================
RCS file: feedapi_node/tests/feedapi_test_case.tinc
diff -N feedapi_node/tests/feedapi_test_case.tinc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedapi_node/tests/feedapi_test_case.tinc	23 Jun 2009 12:16:23 -0000
@@ -0,0 +1,71 @@
+<?php
+// $Id$
+
+/**
+ * Base class for FeedAPI-related tests
+ */
+class FeedAPITestCase extends DrupalWebTestCase {
+  
+  var $info;
+  
+  function setUp() {
+    parent::setUp('feedapi', 'feedapi_node', 'parser_common_syndication', 'parser_simplepie', 'upload');
+  }
+  
+  /**
+   * Login with a user who has FeedAPI rights
+   * 
+   * @param $type_edit
+   *   If TRUE, the user has the right to administer content types
+   */
+  protected function feedapi_user($type_edit = FALSE) {
+    $perms = array('administer feedapi', 'advanced feedapi options', 'administer nodes', "create ". $this->info->type ." content");
+    if ($type_edit == TRUE) {
+      $perms = array_merge($perms, array('administer content types', 'access administration pages'));
+    }
+    $user = $this->drupalCreateUser($perms);
+    $this->drupalGet('logout');
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Create a new content-type for creating the feed node
+   */
+  protected function create_type($parser, $file_upload = FALSE) {
+    $this->info->type = 'test'. str_replace('_', '', $this->randomName());
+    $this->info->name = 'Feed'. str_replace('_', ' ', $this->randomName());
+    $this->info->description = t('Aggregates RSS or Atom feeds. Items from these feeds will be turned into nodes.');
+    $this->info->module = 'node';
+    $this->info->has_title = TRUE;
+    $this->info->title_label = t('Title');
+    $this->info->has_body = TRUE;
+    $this->info->body_label = t('Body');
+    $this->info->min_word_count = 0;
+    $this->info->custom = TRUE;
+    $type = $this->drupalCreateContentType((array) $this->info);
+    $this->assertTrue(is_object($type), 'The temporary content-type is created. The content-type name is: '. $this->info->type);
+    // Adding default FeedAPI settings
+    if ($file_upload) {
+      variable_set('feedapi_settings_'. $this->info->type, unserialize('a:4:{s:7:"enabled";s:1:"1";s:13:"upload_method";s:6:"upload";s:7:"parsers";a:1:{s:'. strlen($parser) .':"'. $parser .'";a:3:{s:7:"enabled";s:1:"1";s:6:"weight";s:1:"0";s:4:"test";s:1:"3";}}s:10:"processors";a:2:{s:12:"feedapi_node";a:4:{s:6:"weight";s:1:"0";s:12:"content_type";s:5:"story";s:9:"node_date";s:4:"feed";s:7:"enabled";s:1:"1";}s:18:"feedapi_aggregator";a:2:{s:6:"weight";s:1:"0";s:5:"block";s:1:"3";}}}'));
+    }
+    else {
+      variable_set('feedapi_settings_'. $this->info->type, unserialize('a:3:{s:7:"enabled";s:1:"1";s:7:"parsers";a:1:{s:'. strlen($parser) .':"'. $parser .'";a:3:{s:7:"enabled";s:1:"1";s:6:"weight";s:1:"0";s:4:"test";s:1:"3";}}s:10:"processors";a:2:{s:12:"feedapi_node";a:4:{s:6:"weight";s:1:"0";s:12:"content_type";s:5:"story";s:9:"node_date";s:4:"feed";s:7:"enabled";s:1:"1";}s:18:"feedapi_aggregator";a:2:{s:6:"weight";s:1:"0";s:5:"block";s:1:"3";}}}'));
+    }
+  }
+
+  /**
+   * Returns the list of sane parsers.
+   */
+  protected function get_parsers() {
+    // Determine enabled and well-setup parsers
+    // @todo: the hard-wired list is suboptimal. But no way to determine the compatibility of the parser
+    $parsers_ok = array('parser_simplepie', 'parser_common_syndication');
+    foreach ($parsers_ok as $key => $parser) {
+      $status = module_invoke($parser, 'requirements', 'runtime');
+      if (isset($status[$parser]) && $status[$parser]['severity'] == REQUIREMENT_ERROR) {
+        unset($parsers_ok[$key]);
+      }
+    }
+    return $parsers_ok;
+  }
+}
