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.');
}
}