t('RSS import to nodes'), 'description' => t('Tests a feed configuration that is attached to a content type, uses HTTP fetcher, common syndication parser and a node processor. Repeats the same test for an importer configuration that is not attached to a content type and for a configuration that is attached to a content type and uses the file fetcher.'), 'group' => t('Feeds'), ); } /** * Set up test. */ public function setUp() { parent::setUp('feeds', 'feeds_ui', 'ctools'); $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'administer nodes', ) ) ); } /** * Test node creation, refreshing/deleting feeds and feed items. */ public function test() { // Set the teaser length to unlimited otherwise tests looking for text on // nodes will fail. $edit = array( 'teaser_length' => 0, ); $this->drupalPost('admin/content/node-settings', $edit, 'Save configuration'); // Create a feed. $this->createFeedConfiguration('Syndication', 'syndication'); $this->addMappings('syndication', array( array( 'source' => 'title', 'target' => 'title', 'unique' => FALSE, ), array( 'source' => 'description', 'target' => 'body', 'unique' => FALSE, ), array( 'source' => 'timestamp', 'target' => 'created', 'unique' => FALSE, ), array( 'source' => 'url', 'target' => 'url', 'unique' => TRUE, ), array( 'source' => 'guid', 'target' => 'guid', 'unique' => TRUE, ), ) ); $nid = $this->createFeedNode(); // Assert 10 items aggregated after creation of the node. $this->assertText('Created 10 Story nodes.'); // Navigate to feed node, there should be Feeds tabs visible. $this->drupalGet('node/'. $nid); $this->assertRaw('node/'. $nid .'/import'); $this->assertRaw('node/'. $nid .'/delete-items'); // Navigate to a non-feed node, there should be no Feeds tabs visible. $story_nid = db_result(db_query_range('SELECT nid FROM {node} WHERE type = "story"', 0, 1)); $this->drupalGet('node/'. $story_nid); $this->assertNoRaw('node/'. $story_nid .'/import'); $this->assertNoRaw('node/'. $story_nid .'/delete-items'); $this->assertEqual("Created/updated by FeedsNodeProcessor", db_result(db_query("SELECT nr.log FROM {node} n JOIN {node_revisions} nr ON n.vid = nr.vid WHERE n.nid = %d", $story_nid))); // Assert accuracy of aggregated information. $this->drupalGet('node'); $this->assertText('Open Atrium Translation Workflow: Two Way Translation Updates'); $this->assertText('Tue, 10/06/2009'); $this->assertText('A new translation process for Open Atrium & integration with Localize Drupal'); $this->assertText('Week in DC Tech: October 5th Edition'); $this->assertText('Mon, 10/05/2009'); $this->assertText('There are some great technology events happening this week'); $this->assertText('Mapping Innovation at the World Bank with Open Atrium'); $this->assertText('Fri, 10/02/2009'); $this->assertText('Open Atrium is being used as a base platform for collaboration'); $this->assertText('September GeoDC Meetup Tonight'); $this->assertText('Wed, 09/30/2009'); $this->assertText('Today is the last Wednesday of the month'); $this->assertText('Week in DC Tech: September 28th Edition'); $this->assertText('Mon, 09/28/2009'); $this->assertText('Looking to geek out this week? There are a bunch of'); $this->assertText('Open Data for Microfinance: The New MIXMarket.org'); $this->assertText('Thu, 09/24/2009'); $this->assertText('There are profiles for every country that the MIX Market is hosting.'); $this->assertText('Integrating the Siteminder Access System in an Open Atrium-based Intranet'); $this->assertText('Tue, 09/22/2009'); $this->assertText('In addition to authentication, the Siteminder system'); $this->assertText('Week in DC Tech: September 21 Edition'); $this->assertText('Mon, 09/21/2009'); $this->assertText('an interesting variety of technology events happening in Washington, DC '); $this->assertText('s Software Freedom Day: Impressions & Photos'); $this->assertText('Mon, 09/21/2009'); $this->assertText('Presenting on Features in Drupal and Open Atrium'); $this->assertText('Scaling the Open Atrium UI'); $this->assertText('Fri, 09/18/2009'); $this->assertText('The first major change is switching'); // Assert DB status. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Import again. $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); $this->assertText('There is no new content.'); // Assert DB status, there still shouldn't be more than 10 items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Enable update existing and import updated feed file. $this->setSettings('syndication', 'FeedsNodeProcessor', array('update_existing' => TRUE)); $feed_url = $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') .'/tests/feeds/developmentseed_changes.rss2'; $this->editFeedNode($nid, $feed_url); $this->drupalPost('node/' . $nid . '/import', array(), 'Import'); $this->assertText('Updated 2 Story nodes.'); // Assert accuracy of aggregated content (check 2 updates, one original). $this->drupalGet('node'); $this->assertText('Managing News Translation Workflow: Two Way Translation Updates'); $this->assertText('Presenting on Features in Drupal and Managing News'); $this->assertText('Scaling the Open Atrium UI'); // Import again. $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); $this->assertText('There is no new content.'); // Assert DB status, there still shouldn't be more than 10 items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Now delete all items. $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); $this->assertText('Deleted 10 nodes.'); // Assert DB status, now there should be no items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 0, 'Accurate number of items in database.'); // Import again, we should find new content. $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); $this->assertText('Created 10 Story nodes.'); // Assert DB status, there should be 10 again. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Login with new user with only access content permissions. $this->drupalLogin( $this->drupalCreateUser() ); // Navigate to feed node, there should be no Feeds tabs visible. $this->drupalGet('node/'. $nid); $this->assertNoRaw('node/'. $nid .'/import'); $this->assertNoRaw('node/'. $nid .'/delete-items'); // Now create a second feed configuration that is not attached to a content // type and run tests on importing/purging. // Login with sufficient permissions. $this->drupalLogin( $this->drupalCreateUser(array('administer feeds', 'administer nodes')) ); // Remove all items again so that next test can check for them. $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); // Create a feed, not attached to content type. $this->createFeedConfiguration('Syndication standalone', 'syndication_standalone'); $edit = array( 'content_type' => '', ); $this->drupalPost('admin/build/feeds/edit/syndication_standalone/settings', $edit, 'Save'); $this->addMappings('syndication_standalone', array( array( 'source' => 'title', 'target' => 'title', 'unique' => FALSE, ), array( 'source' => 'description', 'target' => 'body', 'unique' => FALSE, ), array( 'source' => 'timestamp', 'target' => 'created', 'unique' => FALSE, ), array( 'source' => 'url', 'target' => 'url', 'unique' => TRUE, ), array( 'source' => 'guid', 'target' => 'guid', 'unique' => TRUE, ), ) ); // Import, assert 10 items aggregated after creation of the node. $this->importURL('syndication_standalone'); $this->assertText('Created 10 Story nodes.'); // Assert accuracy of aggregated information. $this->drupalGet('node'); $this->assertText('Open Atrium Translation Workflow: Two Way Translation Updates'); $this->assertText('Tue, 10/06/2009'); $this->assertText('A new translation process for Open Atrium & integration with Localize Drupal'); $this->assertText('Week in DC Tech: October 5th Edition'); $this->assertText('Mon, 10/05/2009'); $this->assertText('There are some great technology events happening this week'); $this->assertText('Mapping Innovation at the World Bank with Open Atrium'); $this->assertText('Fri, 10/02/2009'); $this->assertText('Open Atrium is being used as a base platform for collaboration'); $this->assertText('September GeoDC Meetup Tonight'); $this->assertText('Wed, 09/30/2009'); $this->assertText('Today is the last Wednesday of the month'); $this->assertText('Week in DC Tech: September 28th Edition'); $this->assertText('Mon, 09/28/2009'); $this->assertText('Looking to geek out this week? There are a bunch of'); $this->assertText('Open Data for Microfinance: The New MIXMarket.org'); $this->assertText('Thu, 09/24/2009'); $this->assertText('There are profiles for every country that the MIX Market is hosting.'); $this->assertText('Integrating the Siteminder Access System in an Open Atrium-based Intranet'); $this->assertText('Tue, 09/22/2009'); $this->assertText('In addition to authentication, the Siteminder system'); $this->assertText('Week in DC Tech: September 21 Edition'); $this->assertText('Mon, 09/21/2009'); $this->assertText('an interesting variety of technology events happening in Washington, DC '); $this->assertText('s Software Freedom Day: Impressions & Photos'); $this->assertText('Mon, 09/21/2009'); $this->assertText('Presenting on Features in Drupal and Open Atrium'); $this->assertText('Scaling the Open Atrium UI'); $this->assertText('Fri, 09/18/2009'); $this->assertText('The first major change is switching'); // Assert DB status. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Import again. $this->drupalPost('import/syndication_standalone', array(), 'Import'); $this->assertText('There is no new content.'); // Assert DB status, there still shouldn't be more than 10 items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Enable update existing and import updated feed file. $this->setSettings('syndication_standalone', 'FeedsNodeProcessor', array('update_existing' => TRUE)); $feed_url = $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed_changes.rss2'; $this->importURL('syndication_standalone', $feed_url); $this->assertText('Updated 2 Story nodes.'); // Assert accuracy of aggregated information (check 2 updates, one orig). $this->drupalGet('node'); $this->assertText('Managing News Translation Workflow: Two Way Translation Updates'); $this->assertText('Presenting on Features in Drupal and Managing News'); $this->assertText('Scaling the Open Atrium UI'); // Import again. $this->drupalPost('import/syndication_standalone', array(), 'Import'); $this->assertText('There is no new content.'); // Assert DB status, there still shouldn't be more than 10 items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Now delete all items. $this->drupalPost('import/syndication_standalone/delete-items', array(), 'Delete'); $this->assertText('Deleted 10 nodes.'); // Assert DB status, now there should be no items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 0, 'Accurate number of items in database.'); // Import again, we should find new content. $this->drupalPost('import/syndication_standalone', array(), 'Import'); $this->assertText('Created 10 Story nodes.'); // Assert DB status, there should be 10 again. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Login with new user with only access content permissions. $this->drupalLogin( $this->drupalCreateUser() ); // Navigate to feed import form, access should be denied. $this->drupalGet('import/syndication_standalone'); $this->assertResponse(403); // Use File Fetcher. $this->drupalLogin( $this->drupalCreateUser(array('administer feeds', 'administer nodes')) ); $this->setPlugin('syndication', 'FeedsFileFetcher'); // Create a feed node. $edit = array( 'files[feeds]' => $this->absolutePath() .'/tests/feeds/drupalplanet.rss2', ); $this->drupalPost('node/add/page', $edit, 'Save'); $this->assertText('has been created.'); $this->assertText('Created 25 Story nodes.'); } } /** * Test aggregating a feed as data records. */ class FeedsRSStoDataTest extends FeedsWebTestCase { /** * Describe this test. */ public function getInfo() { return array( 'name' => t('RSS import to data records'), 'description' => t('Tests a feed configuration that is attached to a content type, uses common syndication parser and a node processor. Requires Data module and Views module.'), 'group' => t('Feeds'), ); } /** * Set up test. */ public function setUp() { parent::setUp('feeds', 'feeds_ui', 'ctools', 'data', 'data_ui', 'views'); $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'create page content', ) ) ); } /** * Test node creation, refreshing/deleting feeds and feed items. */ public function test() { // Create a feed. $this->createFeedConfiguration('Data feed', 'rss'); // Go to edit page and select the data processor. $edit = array( 'plugin_key' => 'FeedsDataProcessor', ); $this->drupalPost('admin/build/feeds/edit/rss/processor', $edit, 'Save'); $this->assertPlugins('rss', 'FeedsHTTPFetcher', 'FeedsSyndicationParser', 'FeedsDataProcessor'); // Go to mapping page and create a couple of mappings. $mappings = array( array( 'source' => 'guid', 'target' => 'new:text', 'unique' => TRUE, ), array( 'source' => 'url', 'target' => 'new:text', 'unique' => TRUE, ), array( 'source' => 'timestamp', 'target' => 'timestamp', // timestamp is an existing target. 'unique' => FALSE, ), array( 'source' => 'title', 'target' => 'new:varchar', 'unique' => FALSE, ), array( 'source' => 'description', 'target' => 'new:text', 'unique' => FALSE, ), ); $this->addMappings('rss', $mappings); // Verify the mapping configuration. $config = unserialize(db_result(db_query("SELECT config FROM {feeds_importer} WHERE id = 'rss'"))); $stored_mappings = $config['processor']['config']['mappings']; foreach ($mappings as $i => $mapping) { $this->assertEqual($mapping['source'], $stored_mappings[$i]['source']); // This is intentional: the target of the stored mapping should have the // same key as the source, this has to do with the fact that feeds data // creates storage as the mapping is created. $this->assertEqual($mapping['source'], $stored_mappings[$i]['target']); $this->assertEqual($mapping['unique'], $stored_mappings[$i]['unique']); } // Create standard feed node. $nid = $this->createFeedNode('rss'); // Assert 10 items aggregated after creation of the node. $this->assertText('Created 10 items.'); // Login with a user with administer data permissions and review aggregated // content. $this->drupalLogin( $this->drupalCreateUser( array( 'administer data tables', 'administer feeds', ) ) ); // Assert accuracy of aggregated information. $this->drupalGet('admin/content/data/view/feeds_data_rss'); $this->assertText('Open Atrium Translation Workflow: Two Way Translation Updates'); $this->assertText('A new translation process for Open Atrium & integration with Localize Drupal'); $this->assertText('Week in DC Tech: October 5th Edition'); $this->assertText('There are some great technology events happening this week'); $this->assertText('Mapping Innovation at the World Bank with Open Atrium'); $this->assertText('is being used as a base platform for collaboration at the World Bank because of its feature flexibility'); $this->assertText('September GeoDC Meetup Tonight'); $this->assertText('Today is the last Wednesday of the month'); $this->assertText('Week in DC Tech: September 28th Edition'); $this->assertText('Looking to geek out this week? There are a bunch of'); $this->assertText('Open Data for Microfinance: The New MIXMarket.org'); $this->assertText('There are profiles for every country that the MIX Market is hosting.'); $this->assertText('Integrating the Siteminder Access System in an Open Atrium-based Intranet'); $this->assertText('In addition to authentication, the Siteminder system'); $this->assertText('Week in DC Tech: September 21 Edition'); $this->assertText('an interesting variety of technology events happening in Washington, DC '); $this->assertText('s Software Freedom Day: Impressions & Photos'); $this->assertText('Presenting on Features in Drupal and Open Atrium'); $this->assertText('Scaling the Open Atrium UI'); $this->assertText('The first major change is switching'); // Assert DB status. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_rss}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Import again. $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); $this->assertText('There are no new items.'); // Assert DB status, there still shouldn't be more than 10 items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_rss}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // Now delete all items. $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); $this->assertText('Deleted 10 items.'); // Assert DB status, now there should be no items. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_rss}")); $this->assertEqual($count, 0, 'Accurate number of items in database.'); // Import again, we should find new content. $this->drupalPost('node/'. $nid .'/import', array(), 'Import'); $this->assertText('Created 10 items.'); // Assert DB status, there should be 10 again. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_data_rss}")); $this->assertEqual($count, 10, 'Accurate number of items in database.'); // @todo Standalone import form testing. // @todo Create a second feed and test. } } /** * Test aggregating a feed as data records. */ class FeedsCSVtoUsersTest extends FeedsWebTestCase { /** * Describe this test. */ public function getInfo() { return array( 'name' => t('CSV import to users'), 'description' => t('Tests a standalone import configuration that uses file fetcher and CSV parser to import users from a CSV file.'), 'group' => t('Feeds'), ); } /** * Set up test. */ public function setUp() { parent::setUp('feeds', 'feeds_ui', 'ctools'); $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'administer users', ) ) ); } /** * Test node creation, refreshing/deleting feeds and feed items. */ public function test() { // Create a feed. $this->createFeedConfiguration('User import', 'user_import'); // Set and configure plugins. $this->setPlugin('user_import', 'FeedsFileFetcher'); $this->setPlugin('user_import', 'FeedsCSVParser'); $this->setPlugin('user_import', 'FeedsUserProcessor'); // Go to mapping page and create a couple of mappings. $mappings = array( '0' => array( 'source' => 'name', 'target' => 'name', 'unique' => 0, ), '1' => array( 'source' => 'mail', 'target' => 'mail', 'unique' => 1, ), '2' => array( 'source' => 'since', 'target' => 'created', 'unique' => FALSE, ), ); $this->addMappings('user_import', $mappings); // Change some of the basic configuration. $edit = array( 'content_type' => '', 'import_period' => FEEDS_SCHEDULE_NEVER, ); $this->drupalPost('admin/build/feeds/edit/user_import/settings', $edit, 'Save'); // Import CSV file. $this->importFile('user_import', $this->absolutePath() .'/tests/feeds/users.csv'); // Assert result. $this->assertText('Created 4 users.'); // 1 user has an invalid email address. $this->assertText('There was 1 user that could not be imported because either their name or their email was empty or not valid. Check import data and mapping settings on User processor.'); $this->drupalGet('admin/user/user'); $this->assertText('Morticia'); $this->assertText('Fester'); $this->assertText('Gomez'); $this->assertText('Pugsley'); // @todo Test status setting, update existing and role settings. } } /** * Test cron scheduling. */ class FeedsSchedulerTestCase extends FeedsWebTestCase { /** * Describe this test. */ public function getInfo() { return array( 'name' => t('Scheduler'), 'description' => t('Tests for feeds scheduler.'), 'group' => t('Feeds'), ); } /** * Set up test. */ public function setUp() { parent::setUp('feeds', 'feeds_ui', 'ctools'); $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'administer nodes', ) ) ); $this->createFeedConfiguration(); $this->addMappings('syndication', array( array( 'source' => 'title', 'target' => 'title', 'unique' => FALSE, ), array( 'source' => 'description', 'target' => 'body', 'unique' => FALSE, ), array( 'source' => 'timestamp', 'target' => 'created', 'unique' => FALSE, ), array( 'source' => 'url', 'target' => 'url', 'unique' => TRUE, ), array( 'source' => 'guid', 'target' => 'guid', 'unique' => TRUE, ), ) ); } /** * Test scheduling on cron. */ public function testScheduling() { // Create 10 feed nodes. Turn off import on create before doing that. $edit = array( 'import_on_create' => FALSE, ); $this->drupalPost('admin/build/feeds/edit/syndication/settings', $edit, 'Save'); $this->assertText('Do not import on create'); $nids = $this->createFeedNodes(); // This implicitly tests the import_on_create node setting being 0. $this->assertTrue($nids[0] == 1 && $nids[1] == 2, 'Node ids sequential.'); // Log out and run cron twice. $this->drupalLogout(); $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); // There should be feeds_schedule_num (= 10) feeds updated now. $schedule = array(); $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_schedule} WHERE last_executed_time <> 0")); $this->assertEqual($count, 10, '10 feeds refreshed on cron.'); // There should be 100 story nodes in the database. $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'")); $this->assertEqual($count, 100, 'There are 100 story nodes aggregated.'); // Hit twice cron again. $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); // There should be feeds_schedule_num X 2 (= 20) feeds updated now. $schedule = array(); $result = db_query("SELECT feed_nid, last_executed_time, scheduled FROM {feeds_schedule} WHERE last_executed_time <> 0"); while ($row = db_fetch_object($result)) { $schedule[$row->feed_nid] = $row; } $this->assertEqual(count($schedule), 20, '20 feeds refreshed on cron.'); // There should be 200 story nodes in the database. $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1")); $this->assertEqual($count, 200, 'There are 200 story nodes aggregated.'); // There shouldn't be any items with scheduled = 1 now, if so, this would // mean they are stuck. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_schedule} WHERE scheduled = 1")); $this->assertEqual($count, 0, 'All items are unscheduled (schedule flag = 0).'); // Hit cron again twice. $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); // The import_period setting of the feed configuration is 1800, there // shouldn't be any change to the database now. $equal = TRUE; $result = db_query("SELECT feed_nid, last_executed_time, scheduled FROM {feeds_schedule} WHERE last_executed_time <> 0"); while ($row = db_fetch_object($result)) { $equal = $equal && ($row->last_executed_time == $schedule[$row->feed_nid]->last_executed_time); } $this->assertTrue($equal, 'Schedule did not change.'); // Log back in and set refreshing to as often as possible. $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'administer nodes', ) ) ); $edit = array( 'import_period' => 0, ); $this->drupalPost('admin/build/feeds/edit/syndication/settings', $edit, 'Save'); $this->assertText('Refresh: as often as possible'); // Hit cron again, 4 times now. for ($i = 0; $i < 4; $i++) { $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); } // Refresh period is set to 'as often as possible'. All scheduled times // should have changed now. // There should not be more nodes than before. $equal = FALSE; $output = ''; $result = db_query("SELECT feed_nid, last_executed_time, scheduled FROM {feeds_schedule} WHERE last_executed_time <> 0"); while ($row = db_fetch_object($result)) { $equal = $equal || ($row->last_executed_time == $schedule[$row->feed_nid]->last_executed_time); } $this->assertFalse($equal, 'Every feed schedule time changed.'); // There should be 200 story nodes in the database. $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1")); $this->assertEqual($count, 200, 'The total of 200 story nodes has not changed.'); // @todo Use debug time feature in FeedsScheduler and test behavior in future. // @todo How do I call an API function on the test system from the test script? } /** * Test batching on cron. */ function testBatching() { // Verify that there are 150 nodes total. $nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') .'/tests/feeds/many_items.rss2'); $this->assertText('Created 150 Story nodes.'); $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); $this->assertText('Deleted 150 nodes.'); // Hit cron 3 times, assert correct number of story nodes. for ($i = 0; $i < 3; $i++) { $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); // 50 == FEEDS_NODE_BATCH_SIZE $this->assertEqual(50 * ($i + 1), db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'"))); } // Delete a couple of nodes, then hit cron again. They should not be replaced // as the minimum update time is 30 minutes. $result = db_query_range("SELECT nid FROM {node} WHERE type = 'story'", 0, 2); while ($node = db_fetch_object($result)) { $this->drupalPost("node/{$node->nid}/delete", array(), 'Delete'); } $this->assertEqual(148, db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'"))); $this->drupalGet($GLOBALS['base_url'] .'/cron.php'); $this->assertEqual(148, db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'"))); } } /** * Test single feeds. */ class FeedsSyndicationParserTestCase extends FeedsWebTestCase { /** * Describe this test. */ public function getInfo() { return array( 'name' => t('Syndication parsers'), 'description' => t('Regression tests for syndication parsers Common syndication and SimplePie. Tests parsers against a set of feeds in the context of Feeds module. Requires SimplePie parser to be configured correctly.'), 'group' => t('Feeds'), ); } /** * Set up test. */ public function setUp() { parent::setUp('feeds', 'feeds_ui', 'ctools'); $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'administer nodes', ) ) ); } /** * Run tests. */ public function test() { $this->createFeedConfiguration('Syndication', 'syndication'); foreach (array('FeedsSyndicationParser', 'FeedsSimplePieParser') as $parser) { $this->setPlugin('syndication', $parser); foreach ($this->feedUrls() as $url => $assertions) { $this->createFeedNode('syndication', $url); $this->assertText('Created '. $assertions['item_count'] .' Story nodes.'); } } } /** * Return an array of test feeds. */ protected function feedUrls() { $path = $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') .'/tests/feeds/'; return array( "{$path}developmentseed.rss2" => array( 'item_count' => 10, ), "{$path}feed_without_guid.rss2" => array( 'item_count' => 10, ), ); } } /** * Test Sitemap parser. */ class FeedsSitemapParserTestCase extends FeedsWebTestCase { /** * Describe this test. */ public function getInfo() { return array( 'name' => t('Sitemap parser'), 'description' => t('Regression tests for Sitemap XML format parser.'), 'group' => t('Feeds'), ); } /** * Set up test. */ public function setUp() { parent::setUp('feeds', 'feeds_ui', 'ctools'); $this->drupalLogin( $this->drupalCreateUser( array( 'administer feeds', 'administer nodes', ) ) ); } /** * Run tests. */ public function test() { $this->createFeedConfiguration('Sitemap', 'sitemap'); $this->setPlugin('sitemap', 'FeedsSitemapParser'); $this->addMappings('sitemap', array( array( 'source' => 'changefreq', 'target' => 'title', 'unique' => FALSE, ), array( 'source' => 'priority', 'target' => 'body', 'unique' => FALSE, ), array( 'source' => 'lastmod', 'target' => 'created', 'unique' => FALSE, ), array( 'source' => 'url', 'target' => 'url', 'unique' => TRUE, ), array( 'source' => 'url', 'target' => 'guid', 'unique' => TRUE, ), ) ); $path = $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') .'/tests/feeds/'; $nid = $this->createFeedNode('sitemap', $path .'sitemap-example.xml', 'Testing Sitemap Parser'); $this->assertText('Created 5 Story nodes.'); // Assert DB status. $count = db_result(db_query("SELECT COUNT(*) FROM {feeds_node_item}")); $this->assertEqual($count, 5, 'Accurate number of items in database.'); // Check items against known content of feed. $result = db_query('SELECT * FROM {feeds_node_item} WHERE feed_nid = %d ORDER BY nid', $nid); // Check first item. $item = db_fetch_object($result); $node = node_load($item->nid); $this->assertEqual($node->title, 'monthly', 'Feed item 1 changefreq is correct.'); $this->assertEqual($node->body, '0.8', 'Feed item 1 priority is correct.'); $this->assertEqual($node->created, strtotime('2005-01-01'), 'Feed item 1 lastmod is correct.'); $this->assertEqual($node->feeds_node_item->url, 'http://www.example.com/', 'Feed item 1 url is correct.'); $this->assertEqual($node->feeds_node_item->url, $node->feeds_node_item->guid, 'Feed item 1 guid is correct.'); // Check second item. $item = db_fetch_object($result); $node = node_load($item->nid); $this->assertEqual($node->title, 'weekly', 'Feed item 2 changefreq is correct.'); $this->assertEqual($node->body, '', 'Feed item 2 priority is correct.'); // $node->created is... recently $this->assertEqual($node->feeds_node_item->url, 'http://www.example.com/catalog?item=12&desc=vacation_hawaii', 'Feed item 2 url is correct.'); $this->assertEqual($node->feeds_node_item->url, $node->feeds_node_item->guid, 'Feed item 2 guid is correct.'); // Check third item. $item = db_fetch_object($result); $node = node_load($item->nid); $this->assertEqual($node->title, 'weekly', 'Feed item 3 changefreq is correct.'); $this->assertEqual($node->body, '', 'Feed item 3 priority is correct.'); $this->assertEqual($node->created, strtotime('2004-12-23'), 'Feed item 3 lastmod is correct.'); $this->assertEqual($node->feeds_node_item->url, 'http://www.example.com/catalog?item=73&desc=vacation_new_zealand', 'Feed item 3 url is correct.'); $this->assertEqual($node->feeds_node_item->url, $node->feeds_node_item->guid, 'Feed item 3 guid is correct.'); // Check fourth item. $item = db_fetch_object($result); $node = node_load($item->nid); $this->assertEqual($node->title, '', 'Feed item 4 changefreq is correct.'); $this->assertEqual($node->body, '0.3', 'Feed item 4 priority is correct.'); $this->assertEqual($node->created, strtotime('2004-12-23T18:00:15+00:00'), 'Feed item 4 lastmod is correct.'); $this->assertEqual($node->feeds_node_item->url, 'http://www.example.com/catalog?item=74&desc=vacation_newfoundland', 'Feed item 4 url is correct.'); $this->assertEqual($node->feeds_node_item->url, $node->feeds_node_item->guid, 'Feed item 1 guid is correct.'); // Check fifth item. $item = db_fetch_object($result); $node = node_load($item->nid); $this->assertEqual($node->title, '', 'Feed item 5 changefreq is correct.'); $this->assertEqual($node->body, '', 'Feed item 5 priority is correct.'); $this->assertEqual($node->created, strtotime('2004-11-23'), 'Feed item 5 lastmod is correct.'); $this->assertEqual($node->feeds_node_item->url, 'http://www.example.com/catalog?item=83&desc=vacation_usa', 'Feed item 5 url is correct.'); $this->assertEqual($node->feeds_node_item->url, $node->feeds_node_item->guid, 'Feed item 5 guid is correct.'); // Check for more items. $item = db_fetch_object($result); $this->assertFalse($item, 'Correct number of feed items recorded.'); } }